Summary
Unsafe sequences of integer arithmetic risk revert through integer underflow.
Vulnerability Details
In calls to finalizeValidation, the following operations can be exhibited:
((score >= _mean - _stddev) && (score <= _mean + _stddev))
https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/llm/LLMOracleCoordinator.sol#L343C20-L343C78
(generationScores[g_i] >= mean - generationDeviationFactor * stddev)
https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/llm/LLMOracleCoordinator.sol#L368C16-L368C84
Performing integer arithmetic using checked math is liable to revert from integer underflow if not carefully validated.
Let's demonstrate the existence of this vulnerability in chisel:
Welcome to Chisel! Type `!help` to show available commands.
➜ uint256 mean = 2;
➜ uint256 generationDeviationFactor = 1;
➜ uint256 stddev = 3;
➜ mean - generationDeviationFactor * stddev
Traces:
[611] 0xBd770416a3345F91E4B34576cb804a576fa48EB1::run()
└─ ← [Revert] panic: arithmetic underflow or overflow (0x11)
Impact
It is plausible that calls to finalizeValidation are liable to revert through integer underflow, resulting in the inability for the validator role to finalise vote consensus.
This materializes as denial of service to the validator role.
Tools Used
Chisel
Recommendations
Use the absolute difference between values:
- ((score >= _mean - _stddev) && (score <= _mean + _stddev))
+ ((score >= Math.abs(SafeCast.toInt256(_mean) - SafeCast.toInt256(_stddev))) && (score <= _mean + _stddev))
- (generationScores[g_i] >= mean - generationDeviationFactor * stddev)
+ (generationScores[g_i] >= Math.abs(SafeCast.toInt256(mean) - SafeCast.toInt256(generationDeviationFactor * stddev)))