Dria

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

Unhandled Reversion in Variance Calculation

Summary

The Statistics::variance will revert when an element in data is less than the computed mean, due to unchecked subtraction.

Vulnerability Details

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

In the variance function, mean is calculated using the avg function, which takes the average of all elements in the data array. If mean is greater than one or more elements in data, calculating diff as data[i] - mean will cause underflow, as uint256 cannot represent negative values.

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

The variance function is used in stddev function to compute the standard deviation of the data.
And the stddev function is used in finalizeValidation

Impact

The impact is that when LLMOracleCoordinator::finalizeValidation is called, unless the scores are all identical, the function will revert because of the variance function. Which leads to an incomplete validation task.

function finalizeValidation(uint256 taskId) private {
TaskRequest storage task = requests[taskId];
// compute score for each generation
for (uint256 g_i = 0; g_i < task.parameters.numGenerations; g_i++) {
//......
// compute the mean and standard deviation
@> (uint256 _stddev, uint256 _mean) = Statistics.stddev(scores);
//..........
}

Tools Used

Manual review.

Recommendations

Use absolute difference to prevent reversion:

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;
+ uint256 diff = data[i] > mean ? data[i] - mean : mean - data[i];
sum += diff * diff;
}
ans = sum / data.length;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 9 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.