sherlock-audit / 2024-03-arrakis-judging

2 stars 2 forks source link

unix515 - Chainlink's latestRoundData() might return stale or incorrect results. #24

Closed sherlock-admin2 closed 3 months ago

sherlock-admin2 commented 3 months ago

unix515

medium

Chainlink's latestRoundData() might return stale or incorrect results.

Summary

HOTOracle#_getOraclePriceUSD() might return zero price.

Vulnerability Detail

  1. Chainlink's AggregatorV3InterfacelatestRoundData() is used to fetch the price feed data and returns the following informations. Chainlink API Reference#latestRoundData()

    • roundId: The round ID.
    • answer: The data that this specific feed provides. Depending on the feed you selected, this answer provides asset prices, reserves, NFT floor prices, and other types of data.
    • startedAt: Timestamp of when the round started.
    • updatedAt: Timestamp of when the round was updated.
    • answeredInRound: Deprecated - Previously used when answers could take multiple rounds to be computed.
  2. HOTOracle#_getOraclePriceUSD() are missing the following verifications for the return values of latestRoundData().

    • Does not check if oraclePriceUSDInt <= 0.
    • SafeCast#uint256 does not filter oraclePriceUSDInt == 0.
//<---------------- HOTOracle.sol
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();
    }
    //<----------------- @audit -- No oraclePriceUSDInt verification logic

    oraclePriceUSD = oraclePriceUSDInt.toUint256();
}

//<---------------- SafeCast.sol
function toUint256(int256 value) internal pure returns (uint256) {
    require(value >= 0, "SafeCast: value must be positive");
    return uint256(value);
}

Impact

HOTOracle#_getOraclePriceUSD() might return zero price and it will break the accounting in the protocol.

Code Snippet

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

Tool used

Manual Review

Recommendation

Please update HOTOracle#_getOraclePriceUSD() as follows.

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

++  require(oraclePriceUSDInt > 0, "Chainlink answer reporing 0");

    oraclePriceUSD = oraclePriceUSDInt.toUint256();
}