流动性addLiquidity源码分析,同时结合部署和使用进行分析 [ 2 ]
部署和使用博客
添加流动性函数分析
用户调用 addLiquidity 函数
- 进入_addLiquidity()函数,获取铸造流动性所需要的tokenA的数量、tokenB的数量
- 将tokenA的数量、tokenB的数量转给pair合约
- mint流动性给用户
1、进入_addLiquidity()函数,获取铸造流动性所需要的tokenA的数量、tokenB的数量
_addLiquidity()函数
1.1 先调用getReserves函数获取tokenA和tokenB的reserve
1.2 再调用quote函数,根据 amountADesired 用户希望添加的tokenA金额参数计算出tokenB的需要的数量
quote()函数
公式为:
a
m
o
u
n
t
B
=
(
a
m
o
u
n
t
A
×
r
e
s
e
r
v
e
B
)
÷
r
e
s
e
r
v
e
A
{amountB = {(amountA \times reserveB) \div reserveA}}
amountB=(amountA×reserveB)÷reserveA
1.3 比较amountOptimal和amountDesired的大小,来决定amountA和amountB
原因:铸造流动币,需要amountA和amountB的比例与reserveA和reserveB的比例一致。
例如: reserveA = 10000 TokenA 和 reserveB = 20000 TokenB
条件1:用户打算存入amountDesired A= 1000,amountDesired B=2200
条件2:用户打算存入amountDesired A= 1200,amountDesired B=2000
根据比例原则,条件1和条件2下都是 amountA=1000,amountB=2000
2、将调用者的amountA个tokenA和amountB个tokenB转移给pair合约
3、调用pair合约的mint函数铸造Liquidity币
3.1 首次添加流动性
从源码可以看出首次添加的公式是:
L
i
q
u
i
d
i
t
y
=
t
o
k
e
n
0
A
m
o
u
n
t
×
t
o
k
e
n
1
A
m
o
u
n
t
−
m
i
n
Liquidity={\sqrt{token0Amount \times token1Amount}}-min
Liquidity=token0Amount×token1Amount−min
而min=1000
在本例子中,
step1、首次添加token0Amount数量为50个,token1Amount数量为100个,单位是18
因此
L
P
=
50
∗
1
0
18
×
100
∗
1
0
18
−
1000
=
70710678118654751440
LP={\sqrt{50*10^{18}\times100*10^{18}}}-1000 =70710678118654751440
LP=50∗1018×100∗1018−1000=70710678118654751440
owner 持有的 LP 代币数量:70710678118654751440
对比终端输出
3.2 再次添加流动性
从源码可以看出后续添加的公式是:
step2、用户再次添加:amountA数量为80个,amountB数量为60个,忽略单位
而系统会根据比例计算真实的添加数量:
amount0:80个,amount1:40个 (比例是库存reserveA和reserveB的比)
其中
t
o
t
a
l
S
u
p
p
l
y
=
70.71
∗
1
0
18
,
a
m
o
u
n
t
0
=
80
∗
1
0
18
,
a
m
o
u
n
t
1
=
60
∗
1
0
18
,
r
e
s
e
r
v
e
0
=
100
∗
1
0
18
,
r
e
s
e
r
v
e
1
=
50
∗
1
0
18
totalSupply=70.71*10^{18}, amount0=80*10^{18}, amount1 = 60*10^{18}, reserve0=100*10^{18},reserve1=50*10^{18}
totalSupply=70.71∗1018,amount0=80∗1018,amount1=60∗1018,reserve0=100∗1018,reserve1=50∗1018
代入公式可得
L
P
=
m
i
n
(
56.56
∗
1
0
18
,
56.56
∗
1
0
18
)
=
56.56
∗
1
0
18
LP={min(56.56*10^{18} , 56.56*10^{18}) =56.56*10^{18}}
LP=min(56.56∗1018,56.56∗1018)=56.56∗1018
因此owner 的 LP 代币数量
=
70.71
∗
1
0
18
+
56.56
∗
1
0
18
=
127.27
∗
1
0
18
=70.71*10^{18}+56.56*10^{18}=127.27*10^{18}
=70.71∗1018+56.56∗1018=127.27∗1018
对比终端输出
遇到的问题:Error: Transaction reverted: function call to a non-contract account
解决方法:
用address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB);
替代address pair = IUniswapV2Factory(factory).getPair(tokenA, tokenB);
错误分析:
通过排查发现是pairFor函数的有问题