QuantAMM

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

Each asset should have separate staleness threshold

Summary

The UpliftOnlyExample.getPoolLPTokenValue() function uses the UpdateWeightRunner.getData() function to fetch asset prices from the corresponding oracle and uses them to calculate the value of the LP token. To protect the protocol from using stale prices, a threshold mechanism has been implemented to prevent the use of outdated data. This threshold value is retrieved from the pool through QuantAMMWeightedPool.getOracleStalenessThreshold(). Tracing the function shows that there is a variable oracleStalenessThreshold that stores this value.

The problem is that this threshold is shared across all assets in the pool, even though they may have different characteristics. For example, BTC, ETH, and altcoins are more volatile than stablecoins, and their prices need to be updated more frequently. That’s why in Chainlink, each token has a Deviation Threshold (indicating the percentage price change that triggers an update) and a Heartbeat (indicating the mandatory update interval, even if the deviation threshold hasn’t been reached).

In pools with assets of very different characteristics, a large threshold must be set, which could allow stale prices for more volatile assets. Conversely, setting a lower threshold could cause issues for low-volatility assets with longer heartbeat intervals. These inconsistencies lead to incorrect calculation of the LP token price in UpliftOnlyExample, which subsequently results in incorrect calculation of uplift fees. This directly causes a loss of funds for the protocol.

Vulnerability Details

Here’s an example with the MNT token on Arbitrum and the Chainlink oracle:

https://data.chain.link/feeds/arbitrum/mainnet/mnt-usd

It can be seen that this oracle has a 10% deviation threshold and a 1-day heartbeat. This means that if it is used in a pool along with other tokens, a very high staleness threshold must be set, potentially resulting in stale prices for the other tokens.

Another example is the rETH token, which has a 2% deviation threshold, still allowing significant price deviations.

Impact

Loss of funds for the protocol or users due to incorrect uplift fee calculations.

Tools Used

Manual review

Recommendations

In UpdateWeightRunner, there is an array called ruleOracleStalenessThreshold that can be used to set individual thresholds for each asset. The code should be updated to utilize this array for setting specific thresholds for each asset.

Updates

Lead Judging Commences

n0kto Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

invalid_oracle_same_threshold_for_assets_in_pool

This is by design, staleness is a strategy aspect: it requires all data to have been updated within n minutes. No more precision needed.

Support

FAQs

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