Exotic Navy Elephant
Medium
Chainlink price feeds usually update the price of an asset once it deviates a certain percentage. For example the ETH/USD price feed updates on 0.5% change of price. If there is no change for 1 hour, the price feed updates again - this is called heartbeat: https://data.chain.link/feeds/ethereum/mainnet/eth-usd.
This was not implemented to prevent stale prices.
The implementation does not check for stale prices.
(, int256 price_, , , ) = oracle.latestRoundData(); //@audit
// If the token is ETH
if (underlying == assetAddress[IBorrowing.AssetName.ETH]) {
// Return Exchange rate as 1 and ETH price with 2 decimals
return (1 ether, uint128((uint256(price_) / 1e6)));
} else {
(, uint128 ethPrice) = _price(assetAddress[IBorrowing.AssetName.ETH]);
// Return Exchange rate and ETH price with 2 decimals
return (uint128(uint256(price_)), ethPrice);
}
No response
No response
No response
Outdated prices are returned providing inaccurate old prices to users.
No response
Introduce a new parameter that could be passed alongside the oracle which refers to the heartbeat of that oracle, so that updatedAt
could be compared with that value.
E.g
+ ( , int price, , uint256 updatedAt, ) = oracle.latestRoundData();
+ require(price > 0, "Invalid price");
+ require(answeredInRound >= roundId, "Stale price data");
+ // Timestamp validation to ensure freshness
+ require(block.timestamp - updatedAt <= MAX_DELAY, "Stale price data"); //MAX_DELAY specify for each address