流动性addLiquidity源码分析,同时结合部署和使用进行分析 [ 2 ]
部署和使用博客
https://blog.csdn.net/weixin_43458715/article/details/141711985
添加流动性函数分析
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
在本例子中,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 再次添加流动性
从源码可以看出后续添加的公式是:
其中
t
o
t
a
l
S
u
p
p
l
y
=
70710678118654752440
,
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=70710678118654752440, amount0=80*10^{18}, amount1 = 60*10^{18}, reserve0=100*10^{18},reserve1=50*10^{18}
totalSupply=70710678118654752440,amount0=80∗1018,amount1=60∗1018,reserve0=100∗1018,reserve1=50∗1018
代入公式可得
L
P
=
m
i
n
(
56568542494923801952
,
84852813742385702928
)
=
56568542494923801952
LP={min(56568542494923801952 , 84852813742385702928) =56568542494923801952}
LP=min(56568542494923801952,84852813742385702928)=56568542494923801952
因此owner 的 LP 代币数量
=
70710678118654751440
+
56568542494923801952
=
127279220613578553392
=70710678118654751440+56568542494923801952=127279220613578553392
=70710678118654751440+56568542494923801952=127279220613578553392
对比终端输出
遇到的问题: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函数的有问题