code-423n4 / 2022-01-yield-findings

1 stars 0 forks source link

latestRoundData data may be stale #115

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

Handle

sirhashalot

Vulnerability details

Impact

The Chainlink latestRoundData() function is used in Cvx3CrvOracle.sol, but it is used without checking whether the data returns from the oracle is stale or not. Chainlink warns about this issue and describes how to check for it: https://docs.chain.link/docs/faq/#how-can-i-check-if-the-answer-to-a-round-is-being-carried-over-from-a-previous-round

Proof of Concept

From Cvx3CrvOracle.sol lines 120-122

(, int256 daiPrice, , , ) = DAI.latestRoundData();
(, int256 usdcPrice, , , ) = USDC.latestRoundData();
(, int256 usdtPrice, , , ) = USDT.latestRoundData();

Only the price is retrieved from the Chainlink latestRoundData() function call. This price is accepted as valid data without any checks. This can lead to using stale prices, which can be problematic in volatile market conditions. For an example of this same issue found by an audit firm, see this finding from Consensys Diligence.

Recommended Mitigation Steps

Add checks for the round ID and timestamp returned by the Chainlink latestRoundData() function. For example:

(uint80 roundID, int256 daiPrice, , uint256 timestamp, uint80 answeredInRound) = DAI.latestRoundData();
require(daiPrice > 0, "Chainlink pricefeed reporting 0"); 
require(answeredInRound >= roundID, "Chainlink price is stale");
require(timestamp != 0, "Chainlink round incomplete");
iamsahu commented 2 years ago

136