Dria

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

Statistics Library Underflow in Variance Calculation Causes Oracle Validation System to Fail

Summary

The Statistics.variance() function will revert in most practical cases due to an arithmetic underflow when calculating differences between values and their mean. Since Solidity 0.8+ includes checked arithmetic, any subtraction where data[i] < mean will revert. This vulnerability effectively breaks the oracle validation system which relies on this statistical calculation.

Vulnerability Details

The variance function in Statistics.sol uses unchecked arithmetic to calculate the difference between each value and the mean.
This can lead to underflows when the value is less than the mean.

The variance function is used in Statistics.stddev() which is called in LLMOracleCoordinator::finalizeValidation() to calculate the standard deviation of the oracle responses and determine the validation score.

Where the oracles.validators calls LLMOracleCoordinator.validate() to validate the oracle responses.

In Statistics.sol:

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;
}
function stddev(uint256[] memory data) internal pure returns (uint256 ans, uint256 mean) {
@> (uint256 _variance, uint256 _mean) = variance(data);
mean = _mean;
ans = sqrt(_variance);
}

This function is used in LLMOracleCoordinator.sol for validating oracle responses:

function finalizeValidation(uint256 taskId) private {
// ...
@> (uint256 _stddev, uint256 _mean) = Statistics.stddev(scores);
// This calls variance() internally which will likely revert
// ...
}
function validate(uint256 taskId, uint256 nonce, uint256[] calldata scores, bytes calldata metadata) {
// ...
if (isCompleted) {
task.status = TaskStatus.Completed;
emit StatusUpdate(taskId, task.protocol, TaskStatus.PendingValidation, TaskStatus.Completed);
// finalize validation scores
@> finalizeValidation(taskId);
}
// ...
}

Impact

HIGH. The vulnerability:

  • Breaks the entire oracle validation system

  • Prevents calculation of validation scores

  • Makes it impossible to determine valid oracle responses

  • Affects all operations that depend on statistical validation

Attack Path:

  1. Oracle nodes submit responses

  2. Validation attempt is made

  3. Variance calculation reverts due to underflow

  4. Validation fails

  5. No responses can be processed

  6. Protocol becomes unusable

Tools Used

  • Manual Review

Proof of Concept

Consider this simple example that will fail:

uint256[] memory scores = new uint256[]();
scores[0] = 100;
scores[1] = 0;
// mean = (100 + 0) / 2 = 50
// When i = 1:
// diff = scores[1] - mean
// diff = 0 - 50 -> Reverts due to underflow

Recommendations

Replace the current implementation with a safe version that handles values below mean:

function variance(uint256[] memory data) internal pure returns (uint256 ans, uint256 mean) {
require(data.length > 0, "Empty array");
mean = avg(data);
uint256 sum = 0;
for (uint256 i = 0; i < data.length; i++) {
// Safe difference calculation
uint256 diff = data[i] >= mean ?
data[i] - mean :
mean - data[i];
// Check multiplication overflow
require(diff <= type(uint256).max / diff, "Variance overflow");
sum += diff * diff;
}
ans = sum / data.length;
}

References

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year 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.