Previously, getTVL counted the balance of TokenisableRange and multiplied it by the LP value.
After reconstruction, getTVL obtains the balance of token0 and token1 through getTokenAmounts and multiplies the token value.
The problem is that when calculating the balance of tokens through getTokenAmounts, there is an extra fee part, which causes the balance and TVL to be overestimated.
This results in:
The getAdjustedBaseFee depends on getReserves, resulting in inaccurate baseFee calculations
Users who deposit and withdraw before can get additional funds, who deposit later will get less tokens and have to suffer losses.
The impact on getAdjustedBaseFee is clear, res0 calculates more fee0 * amount / totalSupply(), res1 calculates more fee1 * amount / totalSupply(), which will affect the result of baseFee.
We mainly look at the second point:
When the first user deposits, LP is 0, so there is no problem. LP will be minted after depositing. At this time, TVL calculation includes fee, which is overvalued.
The second user deposits, TVL is overvalued, so depositing tokens of the same value can only mint less than the first amount of tokens.
As the second user deposits, the number of LP is further pushed up, the fee is also higher, and TVL is further overvalued. At this time, the first user to withdraw money will receive additional funds.
Additional
(uint u0, uint u1) = getTokenAmounts(missingLiq);
uint val0 = u0 * ORACLE.getAssetPrice(address(TOKEN0.token)) / 10**TOKEN0.decimals;
uint val1 = u1 * ORACLE.getAssetPrice(address(TOKEN1.token)) / 10**TOKEN1.decimals;
// missing liquidity has no value, or underlying amount is 1 or less (meaning some 1 unit rounding error on low decimal tokens)
if (missingLiqValue == 0 || (u0 <= 1 && u1 <= 1)){
lpAmt = expectedAmount;
}
In TokenisableRange.depositExactly, getTokenAmounts is also used instead of getTokenAmountsExcludingFees.
I am not sure whether it is intentionally designed and needs to be reviewed by the sponsor.
Tools Used
Manual review
Recommended Mitigation Steps
Use getTokenAmountsExcludingFees instead of getTokenAmounts
Lines of code
https://github.com/GoodEntry-io/ge/blob/c7c7de57902e11e66c8186d93c5bb511b53a45b8/contracts/GeVault.sol#L423 https://github.com/GoodEntry-io/ge/blob/c7c7de57902e11e66c8186d93c5bb511b53a45b8/contracts/TokenisableRange.sol#L353-L354
Vulnerability details
Impact
Previously, getTVL counted the balance of TokenisableRange and multiplied it by the LP value. After reconstruction, getTVL obtains the balance of token0 and token1 through getTokenAmounts and multiplies the token value. The problem is that when calculating the balance of tokens through getTokenAmounts, there is an extra fee part, which causes the balance and TVL to be overestimated. This results in:
Proof of Concept
The impact on getAdjustedBaseFee is clear, res0 calculates more
fee0 * amount / totalSupply()
, res1 calculates morefee1 * amount / totalSupply()
, which will affect the result of baseFee. We mainly look at the second point:Additional
In
TokenisableRange.depositExactly
,getTokenAmounts
is also used instead ofgetTokenAmountsExcludingFees
. I am not sure whether it is intentionally designed and needs to be reviewed by the sponsor.Tools Used
Manual review
Recommended Mitigation Steps
Use getTokenAmountsExcludingFees instead of getTokenAmounts
Assessed type
Context