President Elector

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

Lack of Zero Address Check in `rankCandidates` and `rankCandidatesBySig` Allows Invalid Candidate Entries

Summary

The rankCandidates and rankCandidatesBySig functions do not validate whether the candidates being ranked include the zero address (0x0000000000000000000000000000000000000000). The zero address is not a valid candidate and should not be allowed in the voting process. If a voter includes the zero address in their ranking, it could corrupt the election results by counting an invalid candidate.

Vulnerability Details

Both the rankCandidates and rankCandidatesBySig functions allow voters to submit a list of candidates without verifying if any of the addresses in the orderedCandidates array are the zero address. In Ethereum, the zero address is often used as a default or placeholder and is not a valid candidate address. Including the zero address in the voting process could corrupt the tally and lead to invalid election results.

Currently, the contract lacks the necessary checks to prevent the zero address from being ranked, which could allow voters to inadvertently or maliciously cast votes for an invalid candidate. Since the zero address has no associated entity, its inclusion could disrupt the accuracy and fairness of the election process.

Impact

Allowing the zero address to be ranked as a candidate could lead to incorrect vote tallies and potentially corrupt election results. This vulnerability poses a risk to the integrity of the ranked-choice voting process, as the zero address could be counted as a legitimate candidate.

Tools Used

Manual code review.

Recommendations

Add Zero Address Validation with Custom Error: Implement a check in both the rankCandidates and rankCandidatesBySig functions to ensure that no addresses in the orderedCandidates array are the zero address (0x0000000000000000000000000000000000000000). If any zero addresses are detected, the transaction should revert with a custom error.

Example for rankCandidates:

error RankedChoice__InvalidCandidate(); // Define a custom error
function rankCandidates(address[] memory orderedCandidates) external {
for (uint256 i = 0; i < orderedCandidates.length; i++) {
if (orderedCandidates[i] == address(0)) {
revert RankedChoice__InvalidCandidate(); // Revert using the custom error
}
}
_rankCandidates(orderedCandidates, msg.sender);
}

Example for rankCandidatesBySig:

function rankCandidatesBySig(
address[] memory orderedCandidates,
bytes memory signature
) external {
for (uint256 i = 0; i < orderedCandidates.length; i++) {
if (orderedCandidates[i] == address(0)) {
revert RankedChoice__InvalidCandidate(); // Revert using the custom error
}
}
bytes32 structHash = keccak256(abi.encode(TYPEHASH, orderedCandidates));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSA.recover(hash, signature);
_rankCandidates(orderedCandidates, signer);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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