QuantAMM

QuantAMM
49,600 OP
View results
Submission Details
Severity: medium
Valid

Users will pay minWithdrawalFee instead of upliftFee even if there is an increase in their deposit value

Summary

Users will pay minWithdrawalFee instead of upliftFee even if there is an increase in their deposit value in most cases. They will only pay upliftFeewhen their deposit value doubles.

Vulnerability Details

Look at the following in onAfterRemoveLiquidity:

localData.lpTokenDepositValueChange =
(int256(localData.lpTokenDepositValueNow) - int256(localData.lpTokenDepositValue)) /
int256(localData.lpTokenDepositValue);
uint256 feePerLP;
// if the pool has increased in value since the deposit, the fee is calculated based on the deposit value
if (localData.lpTokenDepositValueChange > 0) {
feePerLP =
(uint256(localData.lpTokenDepositValueChange) * (uint256(feeDataArray[i].upliftFeeBps) * 1e18)) /
10000;
}
// if the pool has decreased in value since the deposit, the fee is calculated based on the base value - see wp
else {
//in most cases this should be a normal swap fee amount.
//there always myst be at least the swap fee amount to avoid deposit/withdraw attack surgace.
feePerLP = (uint256(minWithdrawalFeeBps) * 1e18) / 10000;
}

The vulnerable part here is this calculation:

localData.lpTokenDepositValueChange =
(int256(localData.lpTokenDepositValueNow) - int256(localData.lpTokenDepositValue)) /
int256(localData.lpTokenDepositValue);

This ratio will always likely be 0.

Let's say that lpTokenDepositValueNowfor a token is 700, lpTokenDepositValue was 500 when the deposit was first made. Then,

lpTokenDepositValueChange = (700 - 500) / 500 = 200 / 500 = 0 (in solidity)

If lpTokenDepositValueChangeis 0, then the user will always pay a minimal withdrawal fee, instead of the uplift fee, even when the deposit has increased in value.

They will only pay an uplift fee if the lpTokenDepositValuehas doubled or more than doubled in value.

Impact

The protocol loses revenue that it earns through fees.

Tools Used

Manual review

Recommendations

Use div from the Math library as it multiplies with 1e18 before dividing:

localData.lpTokenDepositValueChange =
(int256(localData.lpTokenDepositValueNow) - int256(localData.lpTokenDepositValue)).div(localData.lpTokenDepositValue)
Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_onAfterRemoveLiquidity_lpTokenDepositValueChange_rounding_error_100%_minimum

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.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!