Dria

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

Incorrect variance calculation in `Statistics.sol::variance` when data points are below the average can result in transaction failures

Vulnerability Details:

In Statistics.sol::variance the variance calculation may incorrectly revert if any data points are below the average (mean). This happens because when you subtract the average (mean) from a smaller number, you get a negative result.

However, since we’re using unsigned integers (which can’t be negative), the program tries to use a negative value, causing it to fail.

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

This is because Solidity reverts (or stops) the transaction whenever an unsigned integer (like uint256) tries to go negative.

Impact:

Failed Transactions
The variance function will fail entirely (reverting the transaction) if any element in the dataset is smaller than the mean. This is problematic for datasets where values may naturally be lower than the average, preventing it from calculating valid variance.

IMPACT : HIGH

LIKELIHOOD : LOW

POC:

  1. Set up an Array with Values and a Calculated Mean:

  • Create an array of unsigned integers, data = [6, 8, 3].

  1. Calculate the mean of this array, which will be a value greater than some of the numbers in data:
    mean = (6 + 8 + 3) / 3 = 5.

  2. Attempt to Compute the Difference Between Each Array Element and the Mean:
    Loop through each value in the array. For each element, compute the difference as diff = data[i] - mean.

where the Issue occurs:
In this case:
For data[0] = 6, diff = 6 - 5 = 1 (no issue).
For data[1] = 8, diff = 8 - 5 = 3 (no issue).
when
For data[2] = 3, diff = 3 - 5.
Here, 3 - 5 results in -2, but Solidity doesn’t allow negative numbers for uint256, ultimately resulting in a revert.

Tools Used:

Super Mind and School Maths combo

Recommendations

Using absolute differences when calculating variance will allow the function to run smoothly, even when some data elements are smaller than the mean. Like the below one can also solve the issue :

- uint256 diff = data[i] - mean;
+ uint256 diff = data[i] > mean ? data[i] - mean : mean - data[i];
Updates

Lead Judging Commences

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