President Elector

First Flight #24
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Invalid

Gas limit DoS as voter is able to vote for the same candidate in multiple rounds

Summary

A voter is able to vote for the same candidate in multiple rounds, leading to a Denial of Service (DoS) attack when the selectPresident function is called.

Vulnerability Details

The vulnerability lies in L108-L22 of the contract.

Because users can input arbitrary addresses to be saved in s_rankings (L172), duplicate addresses can be used. This results in inefficient computation that would raise the gas required to execute the selectPresident function, resulting in a DoS attack.

Proof Of Concept

Working test case

function testSameVoteMultipleRounds() public {
// 20 votes for candidates[0] in first round
// candidates[0] will lose after first round but being allowed to vote for repeated candidates in future rounds will lead to wasted computation
orderedCandidates = [
candidates[0],
candidates[0],
candidates[0],
candidates[0],
candidates[0],
candidates[0],
candidates[0],
candidates[0],
candidates[0],
candidates[0]
];
uint256 startingIndex = 0;
uint256 endingIndex = 20;
for (uint256 i = startingIndex; i < endingIndex; i++) {
vm.prank(voters[i]);
rankedChoice.rankCandidates(orderedCandidates);
}
// 50 votes for candidates[1] in first round
startingIndex = endingIndex;
endingIndex = 70;
orderedCandidates = [candidates[1], candidates[0], candidates[2]];
for (uint256 i = startingIndex; i < endingIndex; i++) {
vm.prank(voters[i]);
rankedChoice.rankCandidates(orderedCandidates);
}
// 30 votes for candidates[2] in first round
startingIndex = endingIndex;
endingIndex = 100;
orderedCandidates = [candidates[2], candidates[1], candidates[0]];
for (uint256 i = startingIndex; i < endingIndex; i++) {
vm.prank(voters[i]);
rankedChoice.rankCandidates(orderedCandidates);
}
vm.warp(block.timestamp + rankedChoice.getDuration());
rankedChoice.selectPresident();
assertEq(rankedChoice.getCurrentPresident(), candidates[1]);
}

Impact

This would raise the gas required to execute the selectPresident function. In the worst case, it would cause a DoS due to inefficient computation.

Tools Used

Foundry, manual review

Recommended Mitigation

Check and eliminate duplicate addresses in the _rankCandidates function before saving it to s_rankings.

Updates

Lead Judging Commences

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

rankCandidates() allows duplicate votes inside the `orderedCandidates` array

Appeal created

inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

rankCandidates() allows duplicate votes inside the `orderedCandidates` array

Support

FAQs

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