@@ -15,6 +15,82 @@ timezone: UTC+8
1515## Notes
1616
1717<!-- Content_START -->
18+ # 2025-08-20
19+
20+ ## Uniswap v2里的swap操作
21+
22+ ### uniswap v2的关键合约结构
23+ ```
24+ v2-core/ #其中一个github仓库
25+ ├── UniswapV2Factory.sol
26+ └── UniswapV2Pair.sol
27+
28+ v2-periphery/ #另一个github仓库
29+ └── UniswapV2Router02.sol
30+ ```
31+ #### 1.用户想要完成一次ERC20代币(如DAI->USDT)的交换涉及的步骤:
32+ 前端和UniswapV2Router02.sol进行交互,路由合约(Router02)去找到想要交换的两种ERC20代币的Pair完成交换。
33+ 简单理解成:
34+ ```
35+ 用户→UniswapV2Router02.sol→Pair[DAI/USDT]
36+ ```
37+ ① swapExactTokensForTokens/swapTokensForExactTokens:根据用户需要,会先调用路由合约(Router02)的这个方法
38+
39+ ② transferFrom:用户的钱给Pair
40+
41+ ③ swap:根据AMM的公式,在Pair内部完成一个交换
42+
43+ ④ transfer:在Pair完成交换之后,将币转给用户
44+
45+ #### 2.用户想要完成多个TOKEN的的交换(如DAI->USDT->MKR)涉及的步骤:
46+ ① swapExactTokensForTokens/swapTokensForExactTokens:根据用户需要,会先调用路由合约(Router02)的这个方法
47+
48+ ② transferFrom:用户的钱给Pair
49+
50+ ③ swap:通过路由合约,进行两次交换,第一次是DAI->USDT,第二次是USDT->MKR
51+
52+ ④ transfer:在Pair完成交换之后,将币转给用户
53+
54+ ## Uniswap v2里的手续费机制
55+ #### 1.为什么随着交易产生越来越多,流动性会越来越大?
56+ - 这是因为每笔交易会收取0.3的手续费。
57+ - 手续费不会被提取,而是直接保留在流动性池中。
58+ - 手续费增加了池中代币的总储备量。
59+
60+ #### 2.如何让LP(Liquidity provider)受益于手续费?
61+ - 手续费收益按LP在池中所占份额进行分配,持有的LP token代表其在池中的份额。
62+ - 由于手续费增加在了流动性池中,LP会按照份额比例分配同样比例的手续费。
63+
64+ #### 3.protocol fee:在LP手续费中分一杯羹(1/6)
65+ ~~~ javascript
66+ // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k)
67+ function _mintFee (uint112 _reserve0 , uint112 _reserve1 ) private returns (bool feeOn) {
68+ address feeTo = IUniswapV2Factory (factory).feeTo ();
69+ feeOn = feeTo != address (0 );
70+ uint _kLast = kLast; // gas savings
71+ if (feeOn) {
72+ if (_kLast != 0 ) {
73+ uint rootK = Math .sqrt (uint (_reserve0).mul (_reserve1));
74+ uint rootKLast = Math .sqrt (_kLast);
75+ if (rootK > rootKLast) {
76+ uint numerator = totalSupply .mul (rootK .sub (rootKLast));
77+ uint denominator = rootK .mul (5 ).add (rootKLast);
78+ uint liquidity = numerator / denominator;
79+ if (liquidity > 0 ) _mint (feeTo, liquidity);
80+ }
81+ }
82+ } else if (_kLast != 0 ) {
83+ kLast = 0 ;
84+ }
85+ }
86+ ~~~
87+ 其中feeOn是控制是否开启收取protocol fee的一个开关,它是由feeTo决定的:
88+ ~~~ javascript
89+ address feeTo = IUniswapV2Factory (factory).feeTo ();
90+ feeOn = feeTo != address (0 );
91+ ~~~
92+ 也就是说当交易的contract的feeTo地址为零的时候,则让feeOn处于关闭状态。
93+
1894# 2025-08-18
1995
2096学习并总结了一些uniswap v2的内容:
0 commit comments