President Elector

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

Lack of Input Validation in `rankCandidates`

Description: The rankCandidates function allows users to submit an ordered list of candidate addresses without validating the uniqueness or validity of these addresses. This means that a voter can submit a list with duplicate addresses or addresses that are not valid candidates.

Impact:

  • Skewed Voting Results: Voters can unfairly influence the election by ranking the same candidate multiple times, effectively giving them more weight in the election process.

  • Invalid Candidates: Addresses that are not valid candidates can be included in the rankings, potentially disrupting the election process and results.

Proof of Concept: A voter could call the rankCandidates function with a list like [candidate1, candidate1, candidate2], which would unfairly give more weight to candidate1:

address[] memory orderedCandidates = new address[]();
orderedCandidates[0] = candidate1;
orderedCandidates[1] = candidate1; // Duplicate entry
orderedCandidates[2] = candidate2;
// Assuming `rankedChoice` is an instance of the RankedChoice contract
rankedChoice.rankCandidates(orderedCandidates);

Recommended Mitigation:

  • Uniqueness Check: Implement a mechanism to ensure that all addresses in orderedCandidates are unique. This can be done using a mapping to track the presence of each address.

  • Validity Check: Ensure that all addresses in orderedCandidates are valid candidates. This could involve maintaining a list or mapping of valid candidates and checking against it.

Example Mitigation Code

function _rankCandidates(
address[] memory orderedCandidates,
address voter
) internal {
// Checks
if (orderedCandidates.length > MAX_CANDIDATES) {
revert RankedChoice__InvalidInput();
}
if (!_isInArray(VOTERS, voter)) {
revert RankedChoice__InvalidVoter();
}
// Uniqueness and Validity Check
mapping(address => bool) memory seenCandidates;
for (uint256 i = 0; i < orderedCandidates.length; i++) {
address candidate = orderedCandidates[i];
// Check for uniqueness
if (seenCandidates[candidate]) {
revert RankedChoice__InvalidInput(); // Duplicate candidate
}
seenCandidates[candidate] = true;
// Check for validity
if (!_isInArray(s_candidateList, candidate)) {
revert RankedChoice__InvalidInput(); // Invalid candidate
}
}
// Internal Effects
s_rankings[voter][s_voteNumber] = orderedCandidates;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

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

Appeal created

inallhonesty Lead Judge about 1 year 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.