QuantAMM

QuantAMM
49,600 OP
View results
Submission Details
Severity: low
Invalid

Oracle Price Scaling Error Inflates Pool Value and LP Token Valuation

Summary

The getPoolLPTokenValue function attempts to scale oracle prices to 18 decimals for culculations .However, the function incorrectly assumes the oracle prices lack decimal precision and blindly multiplies them by 1e18. Since oracle prices are already scaled to 1e18 from the getData functions ,this results in over-scaling. The inflated pool value impacts the calculated LP token valuation causing it to be significantly higher than it should be.

Vulnerability Details

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

In getPoolLPTokenValue function this line attempts to scale _prices[i] to 18 decimals

int256 priceScaled18 = _prices[i] * 1e18; ///@audit assumes priceScaled18 is 18 decimals

Oracle prices are fetched using the getData function:

int256[] memory prices = IUpdateWeightRunner(_updateWeightRunner).getData(poolAddress);

These prices typically have been scaled to 1e18 decimals.
as shown by the oracleWrapper and implemented in the oracle getData functions.

/// @notice Get data from oracle, to be implemented by child contracts. Needs to return data with 18 decimals
function _getData() internal view virtual returns (int216 data, uint40 timestamp) {}

The over-scaled price is used in:

poolValueInUSD += FixedPoint.mulUp(uint256(priceScaled18), poolData.balancesLiveScaled18[i]);
poolValueInUSD += FixedPoint.mulDown(uint256(priceScaled18), poolData.balancesLiveScaled18[i]);

balancesLiveScaled18[i] already assumes 18-decimal precision for prices. Using an over-scaled price inflates the pool value (poolValueInUSD) by a factor of
1e18.

The function returns

return poolValueInUSD / poolTotalSupply;

With an inflated poolValueInUSD and poolTotalSupply in 18 decimals, the final LP token value is highly overestimated .In addition the functions loops through several tokens making the impact of the bug very huge.

Impact

Inflated pool values propagate to other parts of the system leading to incorrect calculations, liquidity mismanagement and Economic exploitation

Tools Used

Manual review.

Recommendations

The prices are already scaled by a factor of 1e18.No need to rescale again.

Updates

Lead Judging Commences

n0kto Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

invalid_getPoolLPTokkenValue_price_too_scaled

Order of magnitude: Price = 1e18 (already scaled and normalized by ChainlinkOracle). PriceScaled = 1e36 PoolValueInUSD = 1e36 (mulDown) PoolTotalSupply = 1e18 PoolValueInUSD / PoolTotalSupply = 1e18. Everything seems fine here.

Support

FAQs

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

Give us feedback!