Dria

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

`Statistics::variance` will revert when any element in array is less than `mean` due to underflow error revert. Causes DOS in `finalizeValidation` function when all scores are not equal.

Vulnerability Details :

To calculate variance when variance function called, data[i] - mean will cause underflow error when mean is greater than any element. That means this can only work when all elements are equal otherwise every time mean will be greater and this will revert not calculating the variance properly.
We should use absolute difference instead of just subtracting. Since data[i] - mean can be positive or negative.

18: 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++) {
22: uint256 diff = data[i] - mean;//@audit mean can be more and dos,,take absolute difference
sum += diff * diff;
}
ans = sum / data.length;
}

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

Impact

Since this function is used in stddev deviation function which is used in LLMOracleCoordinator::finalizeValidation function to calculate standard deviation of scores which is very crucial function in finalizing validation process.
Due to this finalizeValidation will revert whenever all scores are not equal and their mean is between them causing the function in DOS.

POC

To run this test first run forge init --force command then forge test --mt testVariance.
This test will pass proving that variance is reverting.

pragma solidity ^0.8.25;
import {Test} from "forge-std/Test.sol";
import {Statistics} from "../contracts/libraries/Statistics.sol";
contract VarianceTest is Test {
function setUp() public {}
function testVariance() public {
uint[] memory a = new uint[]();
a[0] = 1;
a[1] = 3;
a[2] = 5;
vm.expectRevert();//Expecting revert due to underflow error when more is subtracted from less
Statistics.variance(a);
}
}

Tools Used

Foundry, Manual Review

Recommendation

Use their absolute difference by subtracting lower value from higher instead of just subtracting mean from data[i].

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.