koxuan
medium
In _setPricesFromPriceFeeds, latestRoundData is used to fetch prices from Chainlink. However, the result is not validated and stale data can be returned.
In _setPricesFromPriceFeeds, notice that roundID, timestamp and answeredInRound are commented and unused. The only validation done is to check that price is more than 0. Stale data can be returned from Chainlink and used.
IPriceFeed priceFeed = getPriceFeed(dataStore, token);
(
/* uint80 roundID */,
int256 _price,
/* uint256 startedAt */,
/* uint256 timestamp */,
/* uint80 answeredInRound */
) = priceFeed.latestRoundData();
uint256 price = SafeCast.toUint256(_price);
uint256 precision = getPriceFeedMultiplier(dataStore, token);
price = price * precision / Precision.FLOAT_PRECISION;
if (price == 0) {
revert EmptyFeedPrice(token);
}Chainlink may return stale prices.
Manual Review
Recommend checking for stale prices
require(answeredInRound >= roundID, "stale price");
require(timestamp > 0, "round has not completed");