President Elector

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

Zero Voters on Initialization prevents the election from ever occurring

Summary

The constructor does not check if the voters array is non-empty or has zero addresses, allowing a malicious president to initialize the contract with no voters.

Vulnerability Details

Zero Address Inclusion:
The constructor does not check if any of the voters or candidates in the lists are the zero address (0x0). Allowing zero addresses in the election process can lead to unintended behavior, such as invalid votes or corrupted election rounds, since 0x0 is not a valid address for voting.

Empty Voter List:
A malicious president can deploy the contract with an empty voters array, which would result in no votes being cast during voter rankings, effectively making the initial president permanent.
If an empty voter list is passed, it can lead to undefined behavior, such as the voting process not functioning properly or the recursion terminating prematurely.

Impact

Protocol Instability: The voting process is central to the protocol. If the list of voters is empty at initialization, it could prevent the election from occurring at all. This halts the core functionality of the protocol.

Invalid Votes: Allowing 0x0 addresses could enable invalid votes to be tallied, which would compromise the fairness of the election process

POC

Add this to your test suit:

address[] voters;
address[] candidates;
uint256 constant MAX_VOTERS = 100;
uint256 constant MAX_CANDIDATES = 4;
uint256 constant VOTERS_ADDRESS_MODIFIER = 100;
uint256 constant CANDIDATES_ADDRESS_MODIFIER = 200;
RankedChoice rankedChoice;
address[] orderedCandidates;
function setUp() public {
/* for (uint256 i = 0; i < MAX_VOTERS; i++) {
voters.push(address(uint160(i + VOTERS_ADDRESS_MODIFIER)));
}*/
rankedChoice = new RankedChoice(voters);
for (uint256 i = 0; i < MAX_CANDIDATES; i++) {
candidates.push(address(uint160(i + CANDIDATES_ADDRESS_MODIFIER)));
}
}
function testVote() public {
orderedCandidates = [
candidates[0],
candidates[1],
candidates[2],
candidates[3]
];
vm.prank(voters[0]);
rankedChoice.rankCandidates(orderedCandidates);
assertEq(rankedChoice.getUserCurrentVote(voters[0]), orderedCandidates);
}

Tools Used

Manual code review & Unit tests.

Recommendations

Add a check in the constructor to ensure the voters array is not empty and has no duplicate addresses

constructor(address[] memory voters) EIP712("RankedChoice", "1") {
@>++ uint256 votersLength = voters.length;
+ require(votersLength > 0, "No voters added");
+ for (i=0; i<votersLength ; i++){
+ require(voterList[i] != address(0), "Voter cannot be zero address");
+ VOTERS.push(voters[i]);
}
- VOTERS = voters;
i_presidentalDuration = 1460 days;
s_currentPresident = msg.sender;
s_voteNumber = 0;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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