sherlock-audit / 2023-01-sentiment-judging

2 stars 0 forks source link

Madalad - ChainLink's `latestRoundData` might return stale or incorrect results #12

Closed github-actions[bot] closed 1 year ago

github-actions[bot] commented 1 year ago

Madalad

medium

ChainLink's latestRoundData might return stale or incorrect results

Summary

In GLPOracle we are using a call to latestRoundData, however there are not sufficient checks in place to prevent stale data from being used.

Vulnerability Detail

In getEthPrice, roundId is not checked against answeredInRound. According to ChainLink documentation, this may result in stale prices, even though updatedAt is checked.

https://docs.chain.link/docs/historical-price-data/#historical-rounds

Impact

A stale price would potentially lead to assets being mispriced and risk profiles being miscalculated, preventing the protocol from working as intended.

Code Snippet

https://github.com/sentimentxyz/oracle/blob/rage-jr/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

Update getEthPrice to include an extra check for stale price:

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

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

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

    return uint(answer);
}

Duplicate of #31