DeFiFoundry
60,000 USDC
View results
Submission Details
Severity: low
Valid

Chainlink can return stale Price.

Summary

The current implementation and checks for price data is not stringent enough and could lead to chainlink returning stale prices

Vulnerability Details

getPrice which is a function used in Querying the provided Chainlink Price Feed for the margin collateral oracle price is susceptible to returning stale prices due the roundId comparison against the previous answeredInRound not being checked.

It is very essential to ensure that the prices returned from chainlink are not data from previous round Ids in order not to receive stale prices.

Impact

Chainlink can return stale prices

POC

function getPrice(
IAggregatorV3 priceFeed,
uint32 priceFeedHeartbeatSeconds,
IAggregatorV3 sequencerUptimeFeed
)
internal
view
returns (UD60x18 price)
{
...
try priceFeed.latestRoundData() returns (uint80, int256 answer, uint256, uint256 updatedAt, uint80) {
if (block.timestamp - updatedAt > priceFeedHeartbeatSeconds) {
revert Errors.OraclePriceFeedHeartbeat(address(priceFeed));
}
//@audit chainlink might return stale price, not checking the roundId
IOffchainAggregator aggregator = IOffchainAggregator(priceFeed.aggregator());
int192 minAnswer = aggregator.minAnswer();
int192 maxAnswer = aggregator.maxAnswer();
if (answer <= minAnswer || answer >= maxAnswer) {
revert Errors.OraclePriceFeedOutOfRange(address(priceFeed));
}
price = ud60x18(answer.toUint256() * 10 ** (Constants.SYSTEM_DECIMALS - priceDecimals));
} catch {
revert Errors.InvalidOracleReturn();
}
}

Tools Used

Manual review

Recommendations

Compare and ascertain that the latest roundId is different from the previous answeredInRound.

+ require(answeredInRound >= roundId, "Stale price");
Updates

Lead Judging Commences

inallhonesty Lead Judge
11 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Appeal created

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

In `ChainlinkUtil::getPrice` function, skipping `roundId` check

Support

FAQs

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