code-423n4 / 2022-04-backd-findings

6 stars 4 forks source link

Chainlink's `latestRoundData` might return stale or incorrect results #140

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

Lines of code

https://github.com/code-423n4/2022-04-backd/blob/c856714a50437cb33240a5964b63687c9876275b/backd/contracts/oracles/ChainlinkUsdWrapper.sol#L64

Vulnerability details

Impact

In ChainlinkUsdWrapper.sol, latestRoundData() is used but there is no check if the return value indicates stale data. This could lead to stale prices according to the Chainlink documentation:

Proof of Concept

oracles/ChainlinkUsdWrapper.sol#L64

Check roundId, timestamp and answeredInRound.

oracles/ChainlinkOracleProvider.sol#L55

Check roundId and answeredInRound.

Tools Used

Manual review

Recommended mitigation steps

Consider adding checks for stale data. e.g

function _ethPrice() private view returns (int256) {
  (uint80 roundId, int256 answer, , uint256 timestamp, uint80 answeredInRound) = _ethOracle.latestRoundData();

  require(answer > 0, "PRICE: NEGATIVE");
  require(answeredInRound >= roundId, "PRICE: STALE PRICE"); // @audit-info add stale check
  require(timestamp != 0, "PRICE: ROUND INCOMPLETE"); // @audit-info add round incomplete check

  return answer;
}
chase-manning commented 2 years ago

Duplicate of #17