Uniswapv2流动性addLiquidity源码分析,结合公式和部署结果进行分析 [addLiquidity] [ 2 ]

流动性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=501018×1001018 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=801018,amount1=601018,reserve0=1001018reserve1=501018
代入公式可得
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函数的有问题
在这里插入图片描述

在这里插入图片描述

可以看出,错误是UniswapV2Library合约中的pairFor函数所获得的合约地址与UniswapV2Factory合约中createPair函数所创造的合约地址不一致导致的。

在这里插入图片描述

Uniswap V2 的 TransferHelper 类库是一个简化了 Uniswap V2 合约交互的工具类。它通常包含了一些预编写的函数,用于执行常见的交易操作,如转账、兑换、添加流动性等,封装了底层调用的复杂性和细节,使得开发者可以更方便地与 Uniswap V2 接口进行交互,而无需直接编写 Solidity 代码。 在还原这个类库时,你可能会遇到以下步骤: 1. **了解API**:首先,你需要熟悉 Uniswap V2 Router 的官方 API,特别是与转账和交易相关的函数,比如 `exchange()` 和 `addLiquidity()`。 2. **创建类结构**:根据需求,创建一个名为 `TransferHelper` 的类,包含私有变量来存储合约地址和其他必要信息,以及公开的辅助方法。 ```solidity import "https://github.com/uniswap/v2-core/contracts/interfaces/IUniswapV2Router01.sol"; contract TransferHelper { address private uniswapRouter; constructor(address _routerAddress) { uniswapRouter = _routerAddress; } function transferTokens( address from, address to, uint amount, uint[] memory path ) internal { IUniswapV2Router01(router).transfer(from, to, amount, path); } ... 其他方法,例如 exchange, addLiquidity 等 } ``` 3. **封装函数**:将 `exchange` 和 `addLiquidity` 等底层函数调用包装成友好的方法,提供易于使用的参数,并处理错误和验证。 4. **文档注释**:为每个方法添加清晰的注释,说明输入参数的意义,可能出现的异常情况以及返回值。 5. **单元测试**:编写测试用例来验证类库的功能是否正常工作。 还原这个类库的主要目的是为了提高开发者的生产力,通过简洁易用的接口访问复杂的 Uniswap V2 功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值