The truncation of the lpTokenDepositValueChange variable to zero in the onAfterRemoveLiquidity function can lead to an incorrect fee calculation. Specifically, users may pay more fees than they should because the fallback minimum withdrawal fee (minWithdrawalFeeBps) is applied instead of a fee based on the uplift in pool value.
In onAfterRemoveLiquidity function localData.lpTokenDepositValueChange is calculated as follows;
Solidity performs division using integer arithmetic, which discards any fractional part of the result. If the numerator (difference between localData.lpTokenDepositValueNow and localData.lpTokenDepositValue) is significantly smaller than the denominator (localData.lpTokenDepositValue), the result will be 0 instead of the actual fractional value.
Example
localData.lpTokenDepositValueNow = 1005
localData.lpTokenDepositValue = 1000
` localData.lpTokenDepositValueChange = (1005-1000)/1000= 0.005
Using integer division, the result will be truncated to 0.
The truncated value of lpTokenDepositValueChange is used in fee calculation
Since lpTokenDepositValueChange is truncated to 0, even when there is a small uplift, the calculation defaults to
This results in the user paying more than the actual uplift-adjusted fee.
Scenario
localData.lpTokenDepositValueNow = 1005
localData.lpTokenDepositValue = 1000
Uplift Fee Bps: 50 (0.5%)
minWithdrawalFeeBps: 20 (0.2%)
Expected lpTokenDepositValueChange: (1005-1000)/1000= 0.005
Expected Fee Calculation:
feePerLP = 0.005×(50×10^18)/10000=2.5×10^13
Actual (Truncated) Fee Calculation:
Truncated lpTokenDepositValueChange = 0
feePerLP = (20 * 10^18) / 10000 = 2 * 10^15
When the pool value has increased only slightly (a small uplift), truncating lpTokenDepositValueChange to zero results in users paying the minimum withdrawal fee (minWithdrawalFeeBps). This fee is often higher than the fee calculated based on the actual uplift percentage therefore users wil pay more than they should for withdrawing liquidity.
In addition to cases where a small positive lpTokenDepositValueChange is truncated to zero, the following scenarios also result in users paying the minimum withdrawal fee (minWithdrawalFeeBps), which may be higher than they should pay:
If the pool value has decreased since the user's deposit (lpTokenDepositValueChange < 0), the calculation defaults to the minimum withdrawal fee. This leads to overcharging users when the reduced value does not justify such a high fee.
Users who experience no change in pool value since their deposit still pay the minimum withdrawal fee, even though no actual gain or loss occurred. This creates a situation where users incur fees disproportionate to the economic reality of their withdrawal.
Manual Review
To avoid truncation, scale values before performing division
Likelihood: High, every call to the function (withdraw) Impact: Low/Medium, uplift fees will be applied only when the price of one asset is doubled but fixed fees will still be collected.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.