QuantAMM

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

Using the Same `oracleStalenessThreshold` for Multiple Assets in a QuantAMMWeightedPool May Cause DOS or Insufficient Staleness Checks

Summary

The staleness check for oracles in the UpdateWeightRunner::_getData function uses a single oracleStalenessThreshold for all assets in a pool. Since there is no restriction on the types of tokens that can exist in a QuantAMMWeightedPool, assets with significantly different update frequencies (heartbeats) may be pooled together. For example, on Ethereum mainnet, Chainlink feeds for BTC, ETH, and COMP have a 3600-second heartbeat, whereas tokens like AAVE and 1inch use an 86400-second heartbeat. These differences may cause either frequent unexpected transaction reverts (denial of service) or the use of outdated prices due to insufficient staleness checks.

Vulnerability Details

The _getData function retrieves the oracleStalenessThreshold from the pool contract and applies it uniformly to all oracles in the pool:

function _getData(address _pool, bool internalCall) private view returns (int256[] memory outputData) {
require(internalCall || (approvedPoolActions[_pool] & MASK_POOL_GET_DATA > 0), "Not allowed to get data");
address[] memory optimisedOracles = poolOracles[_pool];
uint oracleLength = optimisedOracles.length;
outputData = new int256[](oracleLength);
@> uint oracleStalenessThreshold = IQuantAMMWeightedPool(_pool).getOracleStalenessThreshold();
for (uint i; i < oracleLength; ) {
OracleData memory oracleResult = _getOracleData(OracleWrapper(optimisedOracles[i]));
@> if (oracleResult.timestamp > block.timestamp - oracleStalenessThreshold) {
outputData[i] = oracleResult.data;
}
// Further processing...
}
}

In this setup:

  1. A single oracleStalenessThreshold is applied to all assets in the pool.

  2. Tokens with shorter heartbeats may experience frequent staleness rejections, causing transactions to revert.

  3. Tokens with longer heartbeats may allow outdated prices to pass the staleness check, increasing the risk of mispricing or exploitation.

Impact

  • Denial of Service (DOS): Regular transaction reverts for pools containing assets with shorter heartbeats due to mismatched staleness thresholds.

  • Inaccurate Pricing: Stale data may be used for assets with longer heartbeats, potentially leading to financial exploitation or mispricing.

Tools Used

Manual Review

Recommendations

Introduce a parameter for each oracle representing its specific heartbeat. This parameter should be passed during the oracle registration process and stored alongside the oracle address. Modify the _getData function to use the oracle-specific heartbeat for staleness checks.

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.