sherlock-audit / 2023-01-sentiment-judging

2 stars 0 forks source link

w42d3n - GMX's latestRoundData might return stale or incorrect results #33

Closed github-actions[bot] closed 1 year ago

github-actions[bot] commented 1 year ago

w42d3n

medium

GMX's latestRoundData might return stale or incorrect results

Summary

GMX's latestRoundData() is used but there is no check if the return value indicates stale data and round completeness.

Vulnerability Detail

The GLPOracle.getEthPrice function uses GMX's latestRoundData() to get the latest price. However, there is not enough check if the return value indicates stale data.

Impact

A stale price can cause the malfunction of price oracle and the function getEthPrice() can be invalid or outdated.

If the market price of the token drops very quickly ("flash crashes"), and GMX's feed does not get updated in time, the smart contract will continue to believe the token is worth more than the market value thus affecting users (griefing).

Code Snippet

https://github.com/sherlock-audit/2023-01-sentiment/blob/main/oracle/src/gmx/GLPOracle.sol#L47-L58

    function getEthPrice() internal view returns (uint) {
        (, int answer,, uint updatedAt,) =
            ethUsdPriceFeed.latestRoundData();

        if (block.timestamp - updatedAt >= 86400)
            revert Errors.StalePrice(address(0), address(ethUsdPriceFeed));

        if (answer <= 0)
            revert Errors.NegativePrice(address(0), address(ethUsdPriceFeed));

        return uint(answer);
    }

Tool used

Manual Review

Recommendation

Consider adding checks to validate data feed:

--  (, int answer,, uint updatedAt,) = ethUsdPriceFeed.latestRoundData();
++  (uint80 roundId, int256 answer, , uint256 updatedAt, uint80 answeredInRound) = ethUsdPriceFeed.latestRoundData();
...
++  if (answeredInRound >= roundId) revert Errors.StalePrice(address(0), address(ethUsdPriceFeed));

Duplicate of #31