Uniswap V2的_mintFee函数解释

在 Uniswap V2 的智能合约中,_mintFee 函数用于在每次流动性变化时处理费用(fee)的分发。具体来说,这个函数会计算是否需要收取费用,并根据计算结果进行相应的处理。以下是详细的解释:

函数解释

function _mintFee(
    uint112 _reserve0,
    uint112 _reserve1
) private returns (bool feeOn) {
    // 返回手续费地址
    address feeTo = IUniswapV2Factory(factory).feeTo();
    // 判断是否有手续费地址 true表示启用了费用,否则为 false
    feeOn = feeTo != address(0);

    uint _kLast = kLast; // gas savings
    if (feeOn) {
        if (_kLast != 0) {
            // rootK 和 rootKLast 分别是当前储备量乘积和最后储备量乘积的平方根
            uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
            uint rootKLast = Math.sqrt(_kLast);
            if (rootK > rootKLast) {
                // numerator 是总供应量乘以 rootK 和 rootKLast 的差值。
                uint numerator = totalSupply.mul(rootK.sub(rootKLast));

                uint denominator = rootK.mul(5).add(rootKLast);
                uint liquidity = numerator / denominator;
                if (liquidity > 0) _mint(feeTo, liquidity);
            }
        }
    } else if (_kLast != 0) {
        kLast = 0;
    }
}

详细解释

  1. 获取手续费接收地址

    address feeTo = IUniswapV2Factory(factory).feeTo();
    feeOn = feeTo != address(0);
    
    • 调用 IUniswapV2Factory 合约中的 feeTo 函数,返回手续费接收地址。
    • 如果 feeTo 地址不为空,则启用了费用分发,feeOntrue;否则,feeOnfalse
  2. 节省 gas 费用的变量

    uint _kLast = kLast; // gas savings
    
    • kLast 保存到局部变量 _kLast 中,节省 gas 费用。
  3. 计算和分发费用

    if (feeOn) {
        if (_kLast != 0) {
            uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
            uint rootKLast = Math.sqrt(_kLast);
            if (rootK > rootKLast) {
                uint numerator = totalSupply.mul(rootK.sub(rootKLast));
                uint denominator = rootK.mul(5).add(rootKLast);
                uint liquidity = numerator / denominator;
                if (liquidity > 0) _mint(feeTo, liquidity);
            }
        }
    } else if (_kLast != 0) {
        kLast = 0;
    }
    
    • 计算 rootKrootKLast

      • rootK 是当前储备量乘积的平方根,即 sqrt(reserve0 * reserve1)
      • rootKLast 是上次储备量乘积的平方根,即 sqrt(kLast)
    • 判断 rootK 是否大于 rootKLast

      • 如果 rootK > rootKLast,表示储备量增加,需要分发费用。
    • 计算流动性(liquidity)

      • 计算 numerator(分子):totalSupply * (rootK - rootKLast)
      • 计算 denominator(分母):rootK * 5 + rootKLast
      • 流动性(liquidity)为 numerator / denominator
    • 铸造流动性代币

      • 如果计算出的流动性 liquidity > 0,则调用 _mint(feeTo, liquidity),将流动性代币铸造并发送到 feeTo 地址。
    • 处理 kLast 为 0 的情况

      • 如果没有启用费用分发并且 _kLast 不为 0,则将 kLast 重置为 0。

逻辑总结

  • feeOntruekLast 不为 0 时:
    • 计算当前储备量乘积的平方根 rootK 和上次储备量乘积的平方根 rootKLast
    • 如果 rootK 大于 rootKLast,则计算需要分发的流动性代币数量,并将其铸造发送到手续费接收地址。
  • feeOnfalsekLast 不为 0 时:
    • kLast 重置为 0,不再计算和分发费用。

这个机制确保了在手续费地址设置时,会根据流动性池的增长情况分发一定比例的流动性代币作为费用,从而激励流动性提供者和维护网络的相关方。

版权声明:
作者:lichengxin
链接:https://www.techfm.club/p/137871.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>