Dria

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

Standard Deviation Calculation Underflow Causes Protocol-Wide Denial of Service

Relevant Context

The Statistics library is used to compute standard deviation as part of the task validation process. This computation is essential, and needed for finalizing task validation in the protocol.

Finding Description

The variance calculation used in the calculation of standard deviation in the Statistics library contains an arithmetic underflow vulnerability. The vulnerable code in the variance() function looks like this:

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

When calculating the difference from the mean, the code performs data[i] - mean without checking if data[i] is less than mean. In statistical calculations, it's common and expected for individual data points to be both above and below the mean. When data[i] is less than the mean, the subtraction will underflow due to Solidity's unsigned integer arithmetic.

This underflow causes the variance() function to revert, which in turn causes finalizeValidation() to fail. Since task validation is a core protocol function, this effectively renders the entire protocol unusable.

Impact Explanation

High. The vulnerability leads to a complete denial of service of the protocol's core functionality, as task validation becomes impossible when the variance calculation reverts.

Likelihood Explanation

High. Statistical distributions naturally include values both above and below the mean. It's virtually guaranteed that in any real-world dataset, some values will be below the mean, triggering the underflow condition.

Proof of Concept

  1. A task is submitted to the protocol

  2. Multiple validators submit their data points: [10, 15, 20] (the score of the validator are in the range : [0e18, 1e18])

  3. The mean is calculated as (10 + 15 + 20) / 3 = 15

  4. During variance calculation:

    • For data[0] = 10: 10 - 15 causes underflow

    • Function reverts before completing

  5. Task validation fails due to the revert

  6. Protocol becomes unusable as no tasks can be validated

Recommendation

The variance calculation should be modified to handle differences properly by using signed integer types. Here's a recommended fix:

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

Lead Judging Commences

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