Dria

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

Underflow in Standard Deviation Range Check in `LLMOracleCoordinator.finalizeValidation()` Causes Validation Failures

Summary

In LLMOracleCoordinator.finalizeValidation(), the calculation _mean - _stddev can underflow when comparing validator scores against the standard deviation range, causing the validation process to revert and tasks to remain incomplete.

Vulnerability Details

function finalizeValidation(uint256 taskId) private {
TaskRequest storage task = requests[taskId];
// compute score for each generation
for (uint256 g_i = 0; g_i < task.parameters.numGenerations; g_i++) {
// get the scores for this generation, i.e. the g_i-th element of each validation
uint256[] memory scores = new uint256[]();
for (uint256 v_i = 0; v_i < task.parameters.numValidations; v_i++) {
scores[v_i] = validations[taskId][v_i].scores[g_i];
}
// compute the mean and standard deviation
(uint256 _stddev, uint256 _mean) = Statistics.stddev(scores);
// compute the score for this generation as the "inner-mean"
// and send rewards to validators that are within the range
uint256 innerSum = 0;
uint256 innerCount = 0;
for (uint256 v_i = 0; v_i < task.parameters.numValidations; ++v_i) {
uint256 score = scores[v_i];
@ if ((score >= _mean - _stddev) && (score <= _mean + _stddev)) {
innerSum += score;
innerCount++;
// send validation fee to the validator
_increaseAllowance(validations[taskId][v_i].validator, task.validatorFee);
}
}
// set score for this generation as the average of inner scores
uint256 inner_score = innerCount == 0 ? 0 : innerSum / innerCount;
responses[taskId][g_i].score = inner_score;
}

The issue occurs because both _mean and _stddev are uint256, and if the standard deviation is larger than the mean, the subtraction will revert due to Solidity 0.8.x's checked arithmetic.
Example scenario that triggers the revert:

// Validator scores
scores = [10, 20, 150]
// Results in:
_mean = 60
_stddev = 63.77 // High due to spread
// When checking range:
_mean - _stddev = 60 - 63.77 = REVERT

This scenario is quite possible with:

High variance in validator scores
Scores near zero
Outlier scores

Impact

The impact is high because:

Generator fees are locked until validation completes

Validator fees are locked until validation completes

Since validation cannot complete, these funds become permanently locked

Tools Used

Manual Review

Recommendations

Make sure _mean > _stddev, otherwise use _stddev - _mean

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Underflow in `LLMOracleCoordinator::validate`

Support

FAQs

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