DittoETH

Ditto
DeFiFoundryOracle
55,000 USDC
View results
Submission Details
Severity: medium
Invalid

Chainlink oracle data feed is not sufficiently validated and can return stale price

Summary

There is no freshness check on the timestamp of the prices fetched from the Chainlink oracle, so old prices may be used if OCR was unable to push an update in time. Add a staleness threshold number of seconds configuration parameter, and ensure that the price fetched is from within that time range.

Vulnerability Details

Chainlink's latestRoundData is used here to retrieve price feed data; however, there is insufficient protection against price staleness.

https://github.com/Cyfrin/2023-09-ditto/blob/main/contracts/libraries/LibOracle.sol#L25-L32C

(
uint80 baseRoundID,
int256 basePrice,
/*uint256 baseStartedAt*/
,
uint256 baseTimeStamp,
/*uint80 baseAnsweredInRound*/
) = baseOracle.latestRoundData();
...
(
uint80 roundID,
int256 price,
/*uint256 startedAt*/
,
uint256 timeStamp,
/*uint80 answeredInRound*/
) = oracle.latestRoundData();

Return arguments other than basePrice are necessary to determine the validity of the returned price, as it is possible for an outdated price to be received. See here for reasons why a price feed might stop updating.

Impact

There is no check if the return value indicates stale data.This could lead to stale prices according to the Chainlink documentation:

https://docs.chain.link/docs/historical-price-data/#historical-rounds
https://docs.chain.link/docs/faq/#how-can-i-check-if-the-answer-to-a-round-is-being-carried-over-from-a-previous-round

Tools Used

Manual Review

Recommendations

Add a check for the returned value from latestRoundData.

Updates

Lead Judging Commences

0xnevi Lead Judge
almost 2 years ago
0xnevi Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Chainlink round completeness

Support

FAQs

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