Summary
On ChainlinkPriceOracle.sol, we are using latestRoundData, but there is no check if the return value indicates stale data.
Vulnerability Details
function distributeAssets(ILiquidationPoolManager.Asset[] memory _assets, uint256 _collateralRate, uint256 _hundredPC) external payable {
consolidatePendingStakes();
(,int256 priceEurUsd,,,) = Chainlink.AggregatorV3Interface(eurUsd).latestRoundData();
uint256 stakeTotal = getStakeTotal();
uint256 burnEuros;
uint256 nativePurchased;
for (uint256 j = 0; j < holders.length; j++) {
Position memory _position = positions[holders[j]];
uint256 _positionStake = stake(_position);
if (_positionStake > 0) {
for (uint256 i = 0; i < _assets.length; i++) {
ILiquidationPoolManager.Asset memory asset = _assets[i];
if (asset.amount > 0) {
(,int256 assetPriceUsd,,,) = Chainlink.AggregatorV3Interface(asset.token.clAddr).latestRoundData();
...
https://docs.chain.link/data-feeds/historical-data
Impact
Return of wrong price feeds.
Tools Used
Manual Review
Recommendations
Consider adding missing checks for stale data.
(uint80 roundId, int256 priceEurUsd, , uint256 updatedAt, uint80 answeredInRound) = Chainlink.AggregatorV3Interface(eurUsd).latestRoundData();
require(updatedAt > 0, "Round is not complete");
require(roundId>= 0, "Malfunction");
require(answeredInRound >= roundID, "Stale price");