https://github.com/Cyfrin/2024-09-president-elector/blob/main/src/RankedChoice.sol#L60
https://github.com/Cyfrin/2024-09-president-elector/blob/main/src/RankedChoice.sol#L98
The selectPresident** function makes iteration over the voters array and candidates array which can lead to "Out of Gas" revert and eventually denial of service.
The rankChoice::selectPresident and rankChoice::_selectPresident functions make iteration over the voters array and candidates array. Due to the nature of such arrays which can be very large for both voters and candidates, iterating over such arrays can exceed current block's gas limit and leads to "Out of Gas" error. Eventually, this will break the "selectPresident" functionality as it will always revert and make the contract useless.
In addition, the "_rankcandidates" function uses the "_isInArray" function to check if the voter is within the voters list or not. If the Voters array is big, then this can lead to Gas Limit DoS preventing users from voting.
The following code snippets can lead to Dos:
1- The _isInArray(VOTERS, voter) function call inside "_rankCandidates" if the VOTERS array is very big:
2- Nested loop inside selectPresident function:
3- Nested loop inside _selectPresident::
4- Other loops inside _selectPresident:
The main impact of this issue is a Denial of Service (DoS) which breaks the selectPresident function. This prevents the contract from selecting the winning candidate as the president after the end of the voting duration.
Manual Code Review and Foundry Unit Test
To mitigate the risk of a denial-of-service attack due to an unbounded loop, consider the following approaches:
Batch Processing: Implement batch processing to distribute rewards in smaller batches over multiple transactions. This would prevent the function from exceeding the block gas limit.
Mappings: Use mappings instead of arrays whenever possible.
Gas Limit Checks: Introduce a check for the gas limit before the loop execution and halt the operation if the number of claimants is too large to process in a single transaction.
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.