The variance function in the Statistics library calculates the variance of a dataset but is vulnerable to an underflow issue. This underflow can occur when an element in the dataset is smaller than the calculated mean, causing the function to revert. This issue extends to the LLMOracleCoordinator contract’s finalizeValidation function, which relies on the stddev function (a wrapper around variance). When finalizeValidation attempts to process data where elements are below the mean, it triggers a revert due to the underflow in variance. This revert halts the task validation process and could lead to a Denial of Service (DoS) condition, preventing task completion and disrupting user interactions with the platform.
The core issue lies within the variance function in the Statistics library. Here’s a closer look at how this underflow vulnerability arises:
The variance function calculates the variance by first computing the mean of the dataset. Then, for each element in the dataset, it calculates diff = data[i] - mean and squares this difference to accumulate the sum of squared deviations. However, if data[i] is less than mean, this subtraction results in a negative value, which underflows in Solidity, causing the function to revert.
Consider the following dataset:
The function first calculates the mean as:
The function then iterates over data, calculating diff = data[i] - mean:
For data[0] = 10, the calculation diff = 10 - 25 results in a negative value, which causes an underflow in Solidity’s uint256 arithmetic, triggering a revert.
This vulnerability limits the usability of the variance function, as it reverts whenever any value in the dataset is below the mean. Consequently, any functions or contracts relying on variance to process data with values below the mean will fail, potentially leading to broader system issues.
The underflow vulnerability in variance directly impacts the LLMOracleCoordinator contract, specifically in the finalizeValidation function, which uses stddev (and therefore variance) to compute the standard deviation of validation scores. Here’s how this issue propagates to finalizeValidation:
Code Context in finalizeValidation:
The finalizeValidation function calls stddev to compute the standard deviation of validation scores for each generation. The stddev function internally calls variance, and any underflow in variance due to scores being below the mean will cause stddev to revert. This revert in turn halts the finalizeValidation function, preventing the task’s validation from completing.
Suppose finalizeValidation is processing a task with a set of scores [10, 20, 30, 40]. When stddev is called with these scores, the following steps occur:
stddev calls variance to compute the variance of the scores.
In variance, the mean is calculated as 25.
As variance iterates over the scores, it encounters the first score, 10, which is less than the mean (25). The calculation 10 - 25 causes an underflow, reverting the variance function and, consequently, stddev and finalizeValidation.
Since finalizeValidation reverts when an underflow occurs, it prevents task validation from completing and causes DOS. The finalizeValidation function cannot complete the validation for the task, which means that the task cannot proceed to completion, nor can rewards or other outcomes be distributed. Validators and participants may waste gas fees on transactions that revert due to this underflow, increasing costs and discouraging participation. In a high-stakes or economically incentivized platform, this DoS issue could have significant financial repercussions.
Manual Review
To address this issue, modify the variance function to prevent underflow by using the absolute difference between each value and the mean, ensuring that diff is always non-negative. Here’s the modified variance function:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.