Uniswap

您所在的位置:网站首页 区块链lp销毁 Uniswap

Uniswap

#Uniswap| 来源: 网络整理| 查看: 265

_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