QuantAMM

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

Incorrect deposit value update in afterUpdate

Summary

In the UpliftOnlyExample contract, users can exploit the afterUpdate function to pay less fee on liquidity pool value increases. The issue arises because the lpTokenDepositValue, used to calculate withdrawal fees, is updated to the current pool value during token transfers instead of retaining the original deposit value. This allows users to transfer LP tokens to a new account after value increases and withdraw liquidity without incurring the correct fees.

Vulnerability Details

The afterUpdate function handles LP token transfers between accounts and updates the lpTokenDepositValue. Current implementation calculates new deposit value and updates lpTokenDepositValue erasing the the first deposit value. This design flaw enables users to evade fees by transferring their LP tokens after the pool value has increased. The original deposit value is lost and user pay less fee with new calculated deposit.

function afterUpdate(address _from, address _to, uint256 _tokenID) public {
int256[] memory prices = IUpdateWeightRunner(_updateWeightRunner).getData(poolAddress);
uint256 lpTokenDepositValueNow = getPoolLPTokenValue(prices, poolAddress, MULDIRECTION.MULDOWN);
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;

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

Impact

Users can pay less fee on value increases by transferring LP tokens to a new account and remove liquidity

Tools Used

Recommendations

Modify the afterUpdate function to preserve the original lpTokenDepositValue during token transfers.

// Preserve the original deposit value
- feeDataArray[tokenIdIndex].lpTokenDepositValue = lpTokenDepositValueNow;
+ feeDataArray[tokenIdIndex].lpTokenDepositValue = feeDataArray[tokenIdIndex].lpTokenDepositValue;
Updates

Lead Judging Commences

n0kto Lead Judge 7 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.