Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: medium
Invalid

Rounding can lead to incorrect fee distribution among validators and generators

Summary
Rounding errors in the Statistics library can lead to incorrect fee distribution among validators and generators. The vulnerability allows some participants to receive fees when they shouldn't, while potentially excluding legitimate participants from receiving their earned fees.

Vulnerability Details
This issue happens due to rounding in the function stddev https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/libraries/Statistics.sol#L31
which is used in the function finalizeValidationhttps://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/llm/LLMOracleCoordinator.sol#L323

// In Statistics.sol
function stddev(uint256[] memory data) internal pure returns (uint256 ans, uint256 mean) {
(uint256 _variance, uint256 _mean) = variance(data);
mean = _mean;
ans = sqrt(_variance); // rounding point
}
// In LLMOracleCoordinator.sol
if ((score >= _mean - _stddev) && (score <= _mean + _stddev)) { // Vulnerable condition
innerSum += score;
innerCount++;
_increaseAllowance(validations[taskId][v_i].validator, task.validatorFee);
}


Example Scenario -
Lets assume fee for generators and validators = 100 tokens
Assuming a request has come and it wants 6 validations

// Validation scores for the responses of that request
Validator 1: 95
Validator 2: 98
Validator 3: 100
Validator 4: 100
Validator 5: 100
Validator 6: 102
Mean = 99.17 (rounds to 99)
True Standard Deviation = 2.31
Calculated Standard Deviation = 2 (due to rounding)
Acceptance Range:
- Intended: 99.17 ± 2.31 = [96.86 to 101.48]
- Actual: 99 ± 2 = [97 to 101]

The rounding error creates two issues:

-Validators scoring 96.86-97 are incorrectly excluded

-Validators scoring 101-101.48 are incorrectly included
Technical Breakdown of the Rounding Error -

// For the above scores:
diff² = [(95-99)², (98-99)², (100-99)², (100-99)², (100-99)², (102-99)²]
= [16, 1, 1, 1, 1, 9]
sum = 29
variance = 29/6 = 4.83 (rounds to 4)
Standard Deviation:
stddev = sqrt(4) = 2
// Instead of actual sqrt(4.83) ≈ 2.31
// Example with validatorFee = 100 tokens
// Intended Recipients (within true ±2.31 range):
- Validator 2 (98) - Should receive 100 tokens
- Validator 3 (100) - Should receive 100 tokens
- Validator 4 (100) - Should receive 100 tokens
- Validator 5 (100) - Should receive 100 tokens
// Actual Recipients (within rounded ±2 range):
- Validator 2 (98) - Receives 100 tokens
- Validator 3 (100) - Receives 100 tokens
- Validator 4 (100) - Receives 100 tokens
- Validator 5 (100) - Receives 100 tokens
- Validator 6 (102) - Incorrectly receives 100 tokens
Generator Reward Impact
// The incorrect standard deviation also affects generator rewards:
if (generationScores[g_i] >= mean - generationDeviationFactor * stddev) {
_increaseAllowance(responses[taskId][g_i].responder, task.generatorFee);
}


Impact
-This rounding down can create scenarios where
Users who should receive fee rewards will not
Users who should not receive fee rewards will receive them
This makes the legitimate validators who have scored appropriately miss out on rewards and the validators who have not scored so well be included in the fee rewards

Tools Used
Manual analysis

Recommendations
Implement Fixed-Point Arithmetic

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.