President Elector

First Flight #24
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: medium
Valid

Denial of Service in selectPresident() Due to Inefficient Candidate List Construction

Summary

The selectPresident() function in the ranked-choice voting contract is designed to select the new president based on the ranked preferences of voters. However, there is a significant inefficiency in how the list of candidates is constructed, which can lead to gas exhaustion, especially as the number of voters and candidates increases. This inefficiency stems from the nested loop structure used to check and add candidates to the s_candidateList array.

Vulnerability Details

In the selectPresident() function, the construction of the s_candidateList array involves iterating over each voter and checking whether each candidate in their ranking has already been added to the list. The check uses a nested loop, combined with a helper function _isInArray, which likely involves its own loop to scan the array. This results in O(n^3) complexity in the worst case, which can lead to the function running out of gas when the number of voters or candidates becomes large.

for (uint256 i = 0; i < VOTERS.length; i++) {
address[] memory orderedCandidates = s_rankings[VOTERS[i]][s_voteNumber];
for (uint256 j = 0; j < orderedCandidates.length; j++) {
if (!_isInArray(s_candidateList, orderedCandidates[j])) {
s_candidateList.push(orderedCandidates[j]);
}
}
}

Impact

The inefficiency in the candidate list construction can lead to gas exhaustion, causing the selectPresident() function to fail when the number of voters and candidates grows. This can prevent the election process from completing successfully, resulting in a failure to select a new president and leaving the contract in an inconsistent state.

Scenario

  1. Suppose there are 1,000 voters, each ranking 10 candidates.

  2. Each candidate is checked against the existing s_candidateList to ensure they are not already included.

  3. As the number of voters and candidates grows, the nested loops can become computationally expensive, potentially exceeding the block gas limit and causing the transaction to revert.

Tools Used

Manual Review

Recommendations

To mitigate the risk of gas exhaustion, the construction of the s_candidateList should be optimized by using a more efficient data structure, such as a mapping, to track whether a candidate has already been added to the list.

Updates

Lead Judging Commences

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

A high number of candidates could cause an OOG

Support

FAQs

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