DittoETH

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

ChainLink does not have enough checks for stale price

Summary

lack of checks can cause stale chainlink price

Vulnerability Details

Chainlink recommends using their data feeds along with some controls to prevent mismatches with the retrieved data. Along some recommendations, the feed can include circuit breakers (for extreme price events), contract update delays (to ensure that the injected data into the protocol is fresh enough), manual kill-switches (to cease connection in case of found bug or vulnerability in an upstream contract), monitoring (control the deviation of the data) and soak testing (of the price feeds).

The lastRoundData() interface parameters according to Chainlink are the following:

function latestRoundData() external view
returns (
uint80 roundId, // The round ID.
int256 answer, // The price.
uint256 startedAt, // Timestamp of when the round started.
uint256 updatedAt, // Timestamp of when the round was updated.
uint80 answeredInRound // The round ID of the round in which the answer was computed.
)

here is the code from LibOracle.sol contract

function getOraclePrice(address asset) internal view returns (uint256) {
AppStorage storage s = appStorage();
AggregatorV3Interface baseOracle = AggregatorV3Interface(s.baseOracle);
uint256 protocolPrice = getPrice(asset);
// prettier-ignore
(
uint80 baseRoundID,
int256 basePrice,
/*uint256 baseStartedAt*/ //@audit some checks missing
,
uint256 baseTimeStamp,
/*uint80 baseAnsweredInRound*/
) = baseOracle.latestRoundData();

you can see that in the above code some of the return statements are commented out which should be instead used to verify the price stalelessness.

Impact

Stale Price could occur.

Tools Used

Manual Review

Recommendations

As ChainLink recommends

Your application should track the latestTimestamp variable or use the updatedAt value from the latestRoundData() function to make sure that the latest answer is recent enough for your application to use it. If your application detects that the reported answer is not updated within the heartbeat or within time limits that you determine are acceptable for your application, pause operation or switch to an alternate operation mode while identifying the cause of the delay.

During periods of low volatility, the heartbeat triggers updates to the latest answer. Some heartbeats are configured to last several hours, so your application should check the timestamp and verify that the latest answer is recent enough for your application.

Updates

Lead Judging Commences

0xnevi Lead Judge
over 1 year ago
0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

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