QuantAMM

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

`_getData` - Stale Oracle Data Can Be Accepted When There Are No Backups

Title

_getData - Stale Oracle Data Can Be Accepted When There Are No Backups

Summary

In the _getData function of the UpdateWeightRunner contract, stale oracle data can be accepted when no backup oracles are configured. This can result in potentially incorrect weight adjustments based on outdated information.

Vulnerability Details

The _getData function retrieves oracle data for a pool. If the primary oracle returns stale data, and no backup oracles are configured, the function fails to revert and instead uses the stale data.

Here's the implementation of _getData function:

function _getData(address _pool, bool internalCall) private view returns (int256[] memory outputData) {
...
for (uint i; i < oracleLength; ) {
// Asset is base asset
OracleData memory oracleResult;
oracleResult = _getOracleData(OracleWrapper(optimisedOracles[i]));
if (oracleResult.timestamp > block.timestamp - oracleStalenessThreshold) {
outputData[i] = oracleResult.data;
} else {
unchecked {
numAssetOracles = poolBackupOracles[_pool][i].length;
}
for (uint j = 1 /*0 already done via optimised poolOracles*/; j < numAssetOracles; ) {
oracleResult = _getOracleData(
// poolBackupOracles[_pool][asset][oracle]
OracleWrapper(poolBackupOracles[_pool][i][j])
);
if (oracleResult.timestamp > block.timestamp - oracleStalenessThreshold) {
// Oracle has fresh values
break;
} else if (j == numAssetOracles - 1) {
// All oracle results for this data point are stale. Should rarely happen in practice with proper backup oracles.
>> revert("No fresh oracle values available");
}
unchecked {
++j;
}
}
outputData[i] = oracleResult.data;
}
unchecked {
++i;
}
}
}

When no backup oracles are configured, the for loop used for fallback validation is skipped, and the function does not revert. As a result, stale data from the primary oracle is used, even though it does not meet the freshness threshold.

Impact

  • Incorrect weight calculations: Using stale data may lead to inaccurate or inefficient weight updates.

  • Economic vulnerability: Pools may become misaligned with market prices, exposing them to manipulation or inefficiencies.

  • Security risks: If an oracle is intentionally manipulated to provide stale data, the pool could suffer financial loss.

Tools Used

Manual Review

Recommendations

  1. Add a Revert Condition When No Backups Exist
    Modify the _getData function to ensure it reverts if the primary oracle provides stale data and no backup oracles are configured. For example:

  2. Encourage Backup Oracle Configuration
    Update pool deployment documentation to recommend configuring backup oracles for every pool to avoid reliance on a single data source.

  3. Introduce a Monitoring Mechanism
    Develop a monitoring system to detect and alert administrators if pools are operating without backup oracles, ensuring prompt corrective action.
    These measures will significantly reduce the risk of stale data being used in weight calculations, preserving the integrity and security of the protocol.

Updates

Lead Judging Commences

n0kto Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

invalid_stale_price_when_no_backup_oracles_set

Cyfrin audit: 7.2.4 Stale Oracle prices accepted when no backup oracles available

Support

FAQs

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