15,000 USDC
View results
Submission Details
Severity: medium
Valid

Chainlink price staleness checks not complete.

Summary - Vulnerability Details - Impact

In the OracleLib.sol contract's function staleCheckLatestRoundData we are not checking the staleness completely.

uint256 secondsSince = block.timestamp - updatedAt;
if (secondsSince > TIMEOUT) revert OracleLib__StalePrice();

We just validate the difference of block.timestamp - updatedAt is greater than TIMEOUT then we revert it, but we forgot to validate the updatedAt variable.

On the backend, the aggregator is using a getTimestamp mapping mapping(uint256 => uint256) public getTimestamp; which tracks the update timestamp with round id and in the updateRoundData this round id is passing to this aggregator. This means any slot which is not updated with a timestamp can return a 0 value.

If we got the 0 value then our staleness validation will be useless and the user can mint more DSC than he should get.

Suppose the ETH price was 2000 in the last round and 1000 DSC could be minted and now the price is 1800 which should mint 900 DSC, but due to stale price, user can still mint 1000 DSC.

Tools Used

Manual Review, Solodit

Recommendations

The function should have these checks;

function staleCheckLatestRoundData(
AggregatorV3Interface priceFeed
) public view returns (uint80, int256, uint256, uint256, uint80) {
// * @audit Question - are all checks complete?
(
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
) = priceFeed.latestRoundData();
if (answer <= 0) {
revert OracleLib_InvalidPrice();
}
if (updatedAt == 0) {
revert OracleLib__StalePrice();
}
// * Note: answeredInRound will be deprecated soon, because now they stop getting answer in multiple rounds, but for now I am adding this check here.
if (answeredInRound >= roundId) {
revert OracleLib__StalePrice();
}
uint256 secondsSince = block.timestamp - updatedAt;
if (secondsSince > TIMEOUT) revert OracleLib__StalePrice();
return (roundId, answer, startedAt, updatedAt, answeredInRound);
}

Support

FAQs

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