The Swan protocol calculates mean, variance and standard deviation in order to account for variability of the oracle's responses. However the way the variance is calculated doesn't account for all cases. The variance() function doesn't consider the case where the mean can be bigger than a certain score a validator provided:
From Investopedia: Variance is calculated by taking the differences between each number in the data set and the mean, squaring the differences to make them positive, and then dividing the sum of the squares by the number of values in the data set.
As can be seen from the code snippet above if a number from the data array is smaller than the calculated mean, the function will revert. This will results in the generators and validators who already performed the work to generate and validate for a certain task not getting paid. As well as the buyer agent won't be able to purchase any NFTs in the round he requested his task to be generated and validated. He already paid fees when the request() function was called, those fees will be lost. When there are more validators the chance of this issue happening increases. For example if there are only 2 validators(expected values for the score are from 0 to 1e18) if the difference between the two values provided by the validators is 2 wei, then the variance() function will revert.
After following the steps in the above mentioned gist add the following steps to the AuditorTests.t.sol file:
To run the test use: forge test -vvv --mt test_VarianceCalculationsReverts
There are a couple of impacts. This vulnerability will results in the generators and validators who already performed the work to generate and validate for a certain task not getting paid. As well as the buyer agent won't be able to purchase any NFTs in the round he requested his task to be generated and validated for. He already paid fees when the request() function was called. So validators, generators and the buyer agent all loose fees. Additionally, given the fact that the only purpose of the protocol is to allow buyer agent to buy Swan NFTs so they can proceed their simulation this vulnerability makes the whole protocol obsolete.
Manual review & Foundry
Consider checking whether the number from the data array is less than the mean, and if so subtract that number from the mean, then square the diff and add it to the sum.
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.