Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: medium
Valid

Issues with Chainlink oracle’s return data validation

Summary

There are problems with the validation of the return data of the Chainlink oracle.

Vulnerability Details

Chainlink oracles are used to compute the price of a collateral token throughout the protocol. When validating the Oracle's return data, the returned price is compared to the price of the previous round.

However, there are a few issues with the validation:

  • The increase of the currentRoundId value may not be statically increasing across rounds. The only requirement is that the roundID increases monotonically.

  • The updatedAt value in the Oracle response is never checked, so potentially stale data could come from the priceAggregator contract.

  • The roundId and answeredInRound values in the oracle response are not checked for equality, which could indicate that the answer returned by the oracle is fresh.

contracts/oracles/ChainlinkARBOracle.sol
function _badChainlinkResponse(ChainlinkResponse memory response) internal view returns (bool) {
// Check for response call reverted
@> if (!response.success) { return true; }
// Check for an invalid roundId that is 0
@> if (response.roundId == 0) { return true; }
// Check for an invalid timeStamp that is 0, or in the future
@> if (response.timestamp == 0 || response.timestamp > block.timestamp) { return true; }
// Check for non-positive price
@> if (response.answer == 0) { return true; }
return false;
}

Impact

Exploit Scenario:

The Chainlink oracle attempts to compare the current returned price to the price in the previous roundID. However, because the roundID did not increase by one of the prior round to the current round, the request fails, and the price oracle returns a failure. A stale price is then used by the protocol.

Tools Used

Manual Review

Recommendations

In the short term, have the code validate that the timestamp value is greater than 0 to ensure that the data is fresh. Also, have the code check that the roundID and answeredInRound values are equal to ensure that the returned answer is not stale. Lastly, check that the timestamp value is not decreasing from round to round.

Long term, carefully investigate oracle integrations for potential footguns to conform to correct API usage.

The Historical-Price-Feed-Data Project

Updates

Lead Judging Commences

hans Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

Chainlink round id is not monotonic

Impact: HIGH Likelihood: Equal to how often the round id is not monotonic. https://docs.chain.link/data-feeds/historical-data#solidity

Support

FAQs

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