Uniswap |
您所在的位置:网站首页 › 区块链lp销毁 › Uniswap |
_addLiquidity
代码速浏览 function _addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin ) internal virtual returns (uint amountA, uint amountB) { if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) { IUniswapV2Factory(factory).createPair(tokenA, tokenB); } (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB); if (reserveA == 0 && reserveB == 0) { (amountA, amountB) = (amountADesired, amountBDesired); } else { uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB); if (amountBOptimal ;= amountBDesired) { require(amountBOptimal >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT'); (amountA, amountB) = (amountADesired, amountBOptimal); } else { uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA); assert(amountAOptimal ;= amountADesired); require(amountAOptimal >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT'); (amountA, amountB) = (amountAOptimal, amountBDesired); } } }参数分析 函数 _addLiquidity 的入参有6个,出参有2个,对应的解释如下: function _addLiquidity( address tokenA, // 添加流动性 tokenA 的地址 address tokenB, // 添加流动性 tokenB 的地址 uint amountADesired, // 期望添加 tokenA 的数量 uint amountBDesired, // 期望添加 tokenB 的数量 uint amountAMin, // 添加 tokenA 的最小数量 uint amountBMin // 添加 tokenB 的最小数量 ) internal virtual returns ( uint amountA, // 实际添加 tokenA 的数量 uint amountB // 实际添加 tokenB 的数量 ) { ... }tokenA 和 tokenB 很好理解,但是为什么要有 amountADesired、amountADesired、amountAMin、amountBMin 呢?实际上因为用户在区块链上添加流动性并不是实时完成的,因此会因为其他用户的操作产生数据偏差,因此需要在这里指定一个为 tokenA 和 tokenB 添加流动性的数值范围。在添加流动性的过程中,首先会根据 amountADesired 计算出实际要添加的 amountB,如果 amountB 大于 amountBDesired 就换成根据 amountBDesired 计算出实际要添加的 amountA。 实现分析 ... { // 如果 tokenA,tokenB 的流动池不存在,就创建流动池 if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) { IUniswapV2Factory(factory).createPair(tokenA, tokenB); } // 获取 tokenA,tokenB 的目前库存数量 (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB); if (reserveA == 0 && reserveB == 0) { // 如果库存数量为0,也就是新建 tokenA,tokenB 的流动池,那么实际添加的amountA, amountB 就是 amountADesired 和 amountBDesired (amountA, amountB) = (amountADesired, amountBDesired); } else { // reserveA*reserveB/amountADesired,算出实际要添加的 tokenB 数量 amountBOptimal uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB); if (amountBOptimal ;= amountBDesired) { // 如果 amountBMin ;= amountBOptimal ;= amountBDesired,amountA 和 amountB 就是 amountADesired 和 amountBOptimal require(amountBOptimal >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT'); (amountA, amountB) = (amountADesired, amountBOptimal); } else { // reserveA*reserveB/amountBDesired,算出实际要添加的 tokenA 数量 amountAOptimal uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA); // 如果 amountAMin ;= amountAOptimal ;= amountADesired,amountA 和 amountB 就是 amountAOptimal 和 amountBDesired assert(amountAOptimal ;= amountADesired); require(amountAOptimal >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT'); (amountA, amountB) = (amountAOptimal, amountBDesired); } } }总结 在实际上,计算出来的 mountA 和 mountB 只需要满足这个公式:(amountAMin = mountA && amountBMin ;= mountB ;= amountBDesired) || (amountAMin ;= mountA ;= amountADesired && mountB = amountBDesired)。 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |