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;
}
}
详细解释
-
获取手续费接收地址:
address feeTo = IUniswapV2Factory(factory).feeTo(); feeOn = feeTo != address(0);
- 调用
IUniswapV2Factory
合约中的feeTo
函数,返回手续费接收地址。 - 如果
feeTo
地址不为空,则启用了费用分发,feeOn
为true
;否则,feeOn
为false
。
- 调用
-
节省 gas 费用的变量:
uint _kLast = kLast; // gas savings
- 将
kLast
保存到局部变量_kLast
中,节省 gas 费用。
- 将
-
计算和分发费用:
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; }
-
计算
rootK
和rootKLast
:-
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。
- 如果没有启用费用分发并且
-
计算
逻辑总结
- 当
feeOn
为true
且kLast
不为 0 时:- 计算当前储备量乘积的平方根
rootK
和上次储备量乘积的平方根rootKLast
。 - 如果
rootK
大于rootKLast
,则计算需要分发的流动性代币数量,并将其铸造发送到手续费接收地址。
- 计算当前储备量乘积的平方根
- 当
feeOn
为false
且kLast
不为 0 时:- 将
kLast
重置为 0,不再计算和分发费用。
- 将
这个机制确保了在手续费地址设置时,会根据流动性池的增长情况分发一定比例的流动性代币作为费用,从而激励流动性提供者和维护网络的相关方。
版权声明:
作者:lichengxin
链接:https://www.techfm.club/p/137871.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。
THE END
二维码
共有 0 条评论