DeFiHardhatOracleProxyUpdates
100,000 USDC
View results
Submission Details
Severity: low
Invalid

'roundId' can be 0.

Summary

When we are going through the loop we are not checking whether roundid is zero or not.

Vulnerability Details

function getEthUsdTwap(uint256 lookback) internal view returns (uint256 price) {
    // First, try to get current decimal precision:
    uint8 decimals;
    try priceAggregator.decimals() returns (uint8 _decimals) {
        // If call to Chainlink succeeds, record the current decimal precision
        decimals = _decimals;
    } catch {
        // If call to Chainlink aggregator reverts, return a price of 0 indicating failure
        return 0;
    }

    // Secondly, try to get latest price data:
    try priceAggregator.latestRoundData() returns (
        uint80 roundId,
        int256 answer,
        uint256 /* startedAt */,
        uint256 timestamp,
        uint80 /* answeredInRound */
    ) {
        // Check for an invalid roundId that is 0
        if (roundId == 0) return 0;
        if (checkForInvalidTimestampOrAnswer(timestamp, answer, block.timestamp)) {
            return 0;
        }

        uint256 endTimestamp = block.timestamp.sub(lookback);
        // Check if last round was more than `lookback` ago.
        if (timestamp <= endTimestamp) {
            return uint256(answer).mul(PRECISION).div(10 ** decimals);
        } else {
            uint256 cumulativePrice;
            uint256 lastTimestamp = block.timestamp;
            // Loop through previous rounds and compute cumulative sum until
            // a round at least `lookback` seconds ago is reached.
            while (timestamp > endTimestamp) {
                cumulativePrice = cumulativePrice.add(
                    uint256(answer).mul(lastTimestamp.sub(timestamp))
                );
                roundId -= 1;
                try priceAggregator.getRoundData(roundId) returns (
                    uint80 /* roundId */,
                    int256 _answer,
                    uint256 /* startedAt */,
                    uint256 _timestamp,
                    uint80 /* answeredInRound */
                ) {
                    if (checkForInvalidTimestampOrAnswer(_timestamp, _answer, timestamp)) {
                        return 0;
                    }
                    lastTimestamp = timestamp;
                    timestamp = _timestamp;
                    answer = _answer;
                } catch {
                    // If call to Chainlink aggregator reverts, return a price of 0 indicating failure
                    return 0;
                }
            }
            cumulativePrice = cumulativePrice.add(
                uint256(answer).mul(lastTimestamp.sub(endTimestamp))
            );
            return cumulativePrice.mul(PRECISION).div(10 ** decimals).div(lookback);
        }
    } catch {
        // If call to Chainlink aggregator reverts, return a price of 0 indicating failure
        return 0;
    }
}

Impact

we are taking the value of invalid roundid.

Tools Used

Recommendations

check for roundid==0.

Updates

Lead Judging Commences

giovannidisiena Lead Judge
about 1 year ago
giovannidisiena Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Lack of quality
Assigned finding tags:

Informational/Invalid

Unchecked round ID

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.