Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: high
Valid

DoS in LLMOracleCoordinator caused by underflow in variance calculation in Statistics library

Summary

The Statistics library used in the LLMOracleCoordinator contract has a flaw in its variance function (called by stddev function), where calculating data[i] - mean can cause an underflow if mean exceeds individual data values. Since this stddev function is called in finalizeValidation, this issue results in an unresolvable underflow exception, effectively blocking the finalizeValidation process.

Vulnerability Details

In the Statistics library:

  • The variance function calculates the squared difference (data[i] - mean)^2 to compute the variance:

    https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/libraries/Statistics.sol#L18

    function variance(uint256[] memory data) internal pure returns (uint256 ans, uint256 mean) {
    mean = avg(data);
    uint256 sum = 0;
    for (uint256 i = 0; i < data.length; i++) {
    uint256 diff = data[i] - mean;
    sum += diff * diff;
    }
    ans = sum / data.length;
    }

    If any of data[i] is smaller than mean, the subtraction will result in an underflow, reverting the transaction due to the nature of Solidity >= 0.8.0, for example:
    data[] = [1, 3, 5], mean = 3
    diff = data[0] - mean = 1 - 3 -> UNDERFLOW (revert)

In the LLMOracleCoordinator contract:

Impact

The underflow in variance calculation causes a Denial of Service (DoS), as it permanently prevents task finalization. This failure impacts: users and validators because The LLMOracleCoordinator contract cannot complete validation of tasks which requires validation.

Tools Used

Manual Review

Recommendations

Modify the variance function to calculate the absolute difference diff = mean > data[i] ? mean - data[i] : data[i] - mean, ensuring that the difference is always non-negative:

function variance(uint256[] memory data) internal pure returns (uint256 ans, uint256 mean) {
mean = avg(data);
uint256 sum = 0;
for (uint256 i = 0; i < data.length; i++) {
uint256 diff = mean > data[i] ? mean - data[i] : data[i] - mean;
sum += diff * diff;
}
ans = sum / data.length;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Underflow in computing variance

Support

FAQs

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