QuantAMM

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

Wrong calculation of lpTokenDepositValueChange in UpliftOnlyExample::onAfterRemoveLiquidity leads to loos of fees for protocol and pool owner

Summary

In UpliftOnlyExample::onAfterRemoveLiquidity, lpTokenDepositValueChange the calcul of lpTokenDepositValueChangeis wrong and will not track properly the % value change of the pool token. This will impact the protocol and owner of the pool fees as the value need to at least grow 100% to result in one tick (return 1) where it should return 100. When lower than 100 it returns 0, incurring no fees (or just the minimum) for the protocol.

We can see here that feePerLP depend on the value of lpTokenDepositValueChange. It will derive the value of feeAmount, feePercentage, exitFee, accruedQuantAMMFees which will be transferred to protocol here

Vulnerability Details

Let's take the calcul of lpTokenDepositValueChange and feePerLP and input them in Remix

function checkValue(uint256 lpTokenDepositValueNow, uint256 lpTokenDepositValue) public pure returns(int256 lpTokenDepositValueChange) {
lpTokenDepositValueChange =
(int256(lpTokenDepositValueNow) - int256(lpTokenDepositValue)) /
int256(lpTokenDepositValue);
}
function checkFeePerLP(int256 lpTokenDepositValueChange, int256 upliftFeeBps) public pure returns(uint256 feePerLP) {
feePerLP =
(uint256(lpTokenDepositValueChange) * (uint256(upliftFeeBps) * 1e18)) /
10000;
}

Take as example value :

  1. Pooltoken when depositing : lpTokenDepositValue = 110 (can be 100e18 it result in same)

  2. Pooltoken when withdrawing : lpTokenDepositValueNow = 200, meaning a growth of 81%

With those value, lpTokenDepositValueChange = (200 - 110) / 110 = 0 because solidity will round down. Same result with 1e18 values.

Meaning when the pool token grow 81%, no fees are charged to users when they withdraw from the pool.

For a value of 100 to 200 it will give 1, and we can see in the calcul of feePerLP that it should calculate per bips upliftFeeBps. WIth a value of 1% (upliftFeeBps = 100) it will result in a fees of 0.01 (10000000000000000 wei), on a earning of 100, where it should result of 1.

Impact

Loss of considerable fees for the protocol (quantammAdmin) and the pool owner, which expects more revenue from maintaining his pool. This decentivize pool manager to continue maintaining quantamm pools and the protocol is expecting those funds to finance itself.
This issue will happen on all deployed quantamm pool and need no outside manipulation to happens.

Tools Used

Manual Review

Recommendations

Calculate properly lpTokenDepositValue.

int256(localData.lpTokenDepositValue);
localData.lpTokenDepositValueChange =
++ (int256(localData.lpTokenDepositValueNow) - int256(localData.lpTokenDepositValue)) * 100 /
-- (int256(localData.lpTokenDepositValueNow) - int256(localData.lpTokenDepositValue)) /
int256(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.