去中心化交易所開發正式版丨去中心化交易所繫統開發技術詳細及原始碼分析

xiaofufu發表於2023-02-18

引數分析

函式  _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 的數量

    ) {

        ...

}

okenA 和 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)。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69956839/viewspace-2935839/,如需轉載,請註明出處,否則將追究法律責任。

相關文章