President Elector

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

Uninitialized Candidate Address Allows Voting for Arbitrary Addresses, Risking Vote Manipulation and Election Integrity

Summary

The candidate's address is not initialized upon contract deployment, and there is no storage variable or method for setting it. This lack of implementation allows voters to cast their votes for any address, as there is no validation check, potentially leading to vote manipulation.

Vulnerability Details

The function RankedChoice::_rankCandidates() updates the RankedChoice::s_rankings mapping without any candidate existence checks. This absence of validation allows voters to cast their votes for arbitrary addresses, which can lead to vote manipulation.

function _rankCandidates(address[] memory orderedCandidates, address voter) internal {
// No check to verify if candidates exist
if (orderedCandidates.length > MAX_CANDIDATES) {
revert RankedChoice__InvalidInput();
}
if (!_isInArray(VOTERS, voter)) {
revert RankedChoice__InvalidVoter();
}
// Internal Effects
s_rankings[voter][s_voteNumber] = orderedCandidates;
}

Impact

The vulnerability allows voters to cast votes for arbitrary addresses, which can lead to manipulation of voting results.

PoC

In the RankedChoiceTest.t.sol file, add the following code:

...
// storage variable
// alice is not a candidate
address alice = makeAddr("alice");
...
function testVoteArbitrary() public {
orderedCandidates = [candidates[0], candidates[1], alice];
vm.prank(voters[0]);
rankedChoice.rankCandidates(orderedCandidates);
assertEq(rankedChoice.getUserCurrentVote(voters[0]), orderedCandidates);
}
...

The test will pass even though Alice is not a candidate.

Tools Used

VS Code, Manual Review

Recommendations

Introduce a storage variable for the candidate's address and implement checks to validate candidate existence before updating the RankedChoice::s_rankings mapping.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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