sherlock-audit / 2024-03-arrakis-judging

2 stars 2 forks source link

No check if the Arbitrum Sequencer is down in `HOTOracle.sol:_getOraclePriceUSD()` and not verifying if `answeredInRound` value with the `roundID` #95

Closed sherlock-admin4 closed 4 months ago

sherlock-admin4 commented 4 months ago

No check if the Arbitrum Sequencer is down in HOTOracle.sol:_getOraclePriceUSD() and not verifying if answeredInRound value with the roundID

Low/Info issue submitted by rekxor

Summary

Chainlink recommends that all Optimistic L2 oracles consult the Sequencer Uptime Feed to ensure that the sequencer is live before trusting the data returned by the oracle. This check is implemented in ArbiChainlinkOracle.sol, but is skipped in HOTOracle.sol. Also it doesn't verify the value of answeredInRound with roundID returned from chainlink.

Vulnerability Detail

When utilizing Chainlink in L2 chains like Arbitrum, it's important to ensure that the prices provided are not falsely perceived as fresh, even when the sequencer is down.

Impact

If sequencer has not been available and the price is not the real one, this can result in using stale price.

Code Snippet

   function _getOraclePriceUSD(
        AggregatorV3Interface feed,
        uint32 maxOracleUpdateDuration
    ) internal view returns (uint256 oraclePriceUSD) {
        (, int256 oraclePriceUSDInt, , uint256 updatedAt, ) = feed.latestRoundData();

        if (block.timestamp - updatedAt > maxOracleUpdateDuration) {
            revert HOTOracle___getOraclePriceUSD_stalePrice();
        }

        oraclePriceUSD = oraclePriceUSDInt.toUint256();
    }

https://github.com/sherlock-audit/2024-03-arrakis/blob/main/valantis-hot/src/HOTOracle.sol#L138-L149

Tool used

Manual Review

Recommendation

  1. L2 Sequencer down issue: https://docs.chain.link/data-feeds/l2-sequencer-feeds#example-code

  2. Verifying roundID:

   {
  // For verifying answeredInRound and current roundID from the chainlink aggregator.
    (uint80 roundID , int256 oraclePriceUSDInt, , uint256 updatedAt, uint80 answeredInRound ) = feed.latestRoundData();
    if(answeredInRound < roundID) {
        revert HOTOracle___getOraclePriceUSD_stalePrice();
     // ...//
    }