在 Uniswap V2 的智能合約中括享,_mintFee
函數(shù)用于在每次流動(dòng)性變化時(shí)處理費(fèi)用(fee)的分發(fā)。具體來說珍促,這個(gè)函數(shù)會(huì)計(jì)算是否需要收取費(fèi)用铃辖,并根據(jù)計(jì)算結(jié)果進(jìn)行相應(yīng)的處理。以下是詳細(xì)的解釋:
函數(shù)解釋
function _mintFee(
uint112 _reserve0,
uint112 _reserve1
) private returns (bool feeOn) {
// 返回手續(xù)費(fèi)地址
address feeTo = IUniswapV2Factory(factory).feeTo();
// 判斷是否有手續(xù)費(fèi)地址 true表示啟用了費(fèi)用猪叙,否則為 false
feeOn = feeTo != address(0);
uint _kLast = kLast; // gas savings
if (feeOn) {
if (_kLast != 0) {
// rootK 和 rootKLast 分別是當(dāng)前儲(chǔ)備量乘積和最后儲(chǔ)備量乘積的平方根
uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
uint rootKLast = Math.sqrt(_kLast);
if (rootK > rootKLast) {
// numerator 是總供應(yīng)量乘以 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;
}
}
詳細(xì)解釋
-
獲取手續(xù)費(fèi)接收地址:
address feeTo = IUniswapV2Factory(factory).feeTo(); feeOn = feeTo != address(0);
- 調(diào)用
IUniswapV2Factory
合約中的feeTo
函數(shù),返回手續(xù)費(fèi)接收地址穴翩。 - 如果
feeTo
地址不為空犬第,則啟用了費(fèi)用分發(fā),feeOn
為true
芒帕;否則歉嗓,feeOn
為false
。
- 調(diào)用
-
節(jié)省 gas 費(fèi)用的變量:
uint _kLast = kLast; // gas savings
- 將
kLast
保存到局部變量_kLast
中副签,節(jié)省 gas 費(fèi)用遥椿。
- 將
-
計(jì)算和分發(fā)費(fèi)用:
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; }
-
計(jì)算
rootK
和rootKLast
:-
rootK
是當(dāng)前儲(chǔ)備量乘積的平方根,即sqrt(reserve0 * reserve1)
淆储。 -
rootKLast
是上次儲(chǔ)備量乘積的平方根,即sqrt(kLast)
家浇。
-
-
判斷
rootK
是否大于rootKLast
:- 如果
rootK > rootKLast
本砰,表示儲(chǔ)備量增加,需要分發(fā)費(fèi)用钢悲。
- 如果
-
計(jì)算流動(dòng)性(liquidity):
- 計(jì)算
numerator
(分子):totalSupply * (rootK - rootKLast)
点额。 - 計(jì)算
denominator
(分母):rootK * 5 + rootKLast
。 - 流動(dòng)性(liquidity)為
numerator / denominator
莺琳。
- 計(jì)算
-
鑄造流動(dòng)性代幣:
- 如果計(jì)算出的流動(dòng)性
liquidity > 0
还棱,則調(diào)用_mint(feeTo, liquidity)
,將流動(dòng)性代幣鑄造并發(fā)送到feeTo
地址惭等。
- 如果計(jì)算出的流動(dòng)性
-
處理
kLast
為 0 的情況:- 如果沒有啟用費(fèi)用分發(fā)并且
_kLast
不為 0珍手,則將kLast
重置為 0。
- 如果沒有啟用費(fèi)用分發(fā)并且
-
計(jì)算
邏輯總結(jié)
- 當(dāng)
feeOn
為true
且kLast
不為 0 時(shí):- 計(jì)算當(dāng)前儲(chǔ)備量乘積的平方根
rootK
和上次儲(chǔ)備量乘積的平方根rootKLast
辞做。 - 如果
rootK
大于rootKLast
琳要,則計(jì)算需要分發(fā)的流動(dòng)性代幣數(shù)量,并將其鑄造發(fā)送到手續(xù)費(fèi)接收地址秤茅。
- 計(jì)算當(dāng)前儲(chǔ)備量乘積的平方根
- 當(dāng)
feeOn
為false
且kLast
不為 0 時(shí):- 將
kLast
重置為 0稚补,不再計(jì)算和分發(fā)費(fèi)用。
- 將
這個(gè)機(jī)制確保了在手續(xù)費(fèi)地址設(shè)置時(shí)框喳,會(huì)根據(jù)流動(dòng)性池的增長情況分發(fā)一定比例的流動(dòng)性代幣作為費(fèi)用课幕,從而激勵(lì)流動(dòng)性提供者和維護(hù)網(wǎng)絡(luò)的相關(guān)方厦坛。