QuantAMM

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

A malicious owner can alter the fee amount paid by updating the value of `lpTokenDepositValue` in the `afterUpdate` function of the `UpliftOnlyExample` contract.

Summary

A user can change the amount of fee they pay by modifying the value of lpTokenDepositValue in the afterUpdate function. Altering the lpTokenDepositValue will consequently change the fee.

Vulnerability Details

The bug occurs when the owner of the NFT transfers it to another account, but effectively to themselves.

When the ower transfer the NFT, the value of lpTokenDepositValueis changed to current value.

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/pool-hooks/contracts/hooks-quantamm/UpliftOnlyExample.sol#L609

if (tokenIdIndexFound) {
if (_to != address(0)) {
// Update the deposit value to the current value of the pool in base currency (e.g. USD) and the block index to the current block number
//vault.transferLPTokens(_from, _to, feeDataArray[i].amount);
@>> feeDataArray[tokenIdIndex].lpTokenDepositValue = lpTokenDepositValueNow;
feeDataArray[tokenIdIndex].blockTimestampDeposit = uint32(block.number);
feeDataArray[tokenIdIndex].upliftFeeBps = upliftFeeBps;

By checking the value of lpTokenDepositValue , the owner can transfer the NFT to themself when the price is highest, or any price benifiting the owner causing them to pay the minimum fee or a significantly reduced fee.

calculation of fee in the `onAfterRemoveLiquidity` :-

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/pool-hooks/contracts/hooks-quantamm/UpliftOnlyExample.sol#L474

localData.lpTokenDepositValue = feeDataArray[i].lpTokenDepositValue;
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;
}

Impact

The owner of an NFT can manipulate the fee they pay significantly. If the owner sends the NFT to themselves at a very high LP token value, and the value drops slightly, they will only be charged the minimum fee.

Tools Used

Manual review

Recommendations

In my opinion:

  1. Avoid updating the value of lpTokenDepositValue.

  2. Alternatively, calculate the fee using the old value of lpTokenDepositValue to prevent manipulation.

Updates

Lead Judging Commences

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

finding_afterUpdate_bypass_fee_collection_updating_the_deposited_value

Likelihood: High, any transfer will trigger the bug. Impact: High, will update lpTokenDepositValue to the new current value without taking fees on profit.

Support

FAQs

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

Give us feedback!