Skip to content
This repository was archived by the owner on Sep 24, 2023. It is now read-only.

Latest commit

 

History

History
55 lines (35 loc) · 1.46 KB

File metadata and controls

55 lines (35 loc) · 1.46 KB

koxuan

medium

Chainlink oracle can return stale prices

Summary

In _setPricesFromPriceFeeds, latestRoundData is used to fetch prices from Chainlink. However, the result is not validated and stale data can be returned.

Vulnerability Detail

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);
            }

Impact

Chainlink may return stale prices.

Code Snippet

https://github.com/sherlock-audit/2023-02-gmx/blob/main/gmx-synthetics/contracts/oracle/Oracle.sol#L569-L586

Tool used

Manual Review

Recommendation

Recommend checking for stale prices

require(answeredInRound >= roundID, "stale price");
require(timestamp > 0, "round has not completed");