President Elector

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

No Time Control at Initialization causing a tx revert in `selectPresident()`

Summary

The s_previousVoteEndTimeStamp is never initialized in the constructor, causing the selectPresident() function to always revert.

Vulnerability Details

Without initializing s_previousVoteEndTimeStamp, it defaults to 0. As a result, the condition in selectPresident() that checks if enough time has passed since the last vote: https://github.com/Cyfrin/2024-09-president-elector/blob/fccb8e2b6a32404b4664fa001faa334f258b4947/src/RankedChoice.sol#L61 will always evaluate to true on the first call, leading to the function reverting with the RankedChoice__NotTimeToVote error, since the previousVoteEndTimeStamp isn't initialized thus empty.

Impact

This bug prevents the president selection process from being completed successfully, as the contract will always revert on the first attempt to select a president. As a result, no new president can be chosen, disrupting the election process.

POC

Add this at your test suits:

function testSelectPresident() public {
assert(rankedChoice.getCurrentPresident() != candidates[0]);
orderedCandidates = [
candidates[0],
candidates[1],
candidates[2],
candidates[3]
];
uint256 startingIndex = 0;
uint256 endingIndex = 60;
for (uint256 i = startingIndex; i < endingIndex; i++) {
vm.prank(voters[i]);
rankedChoice.rankCandidates(orderedCandidates);
}
startingIndex = endingIndex + 1; //61
endingIndex = 100;
orderedCandidates = [
candidates[3],
candidates[1],
candidates[0],
candidates[2]
];
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[0]);
}

Tools Used

Foundry

Recommendations

Initialize s_previousVoteEndTimeStamp in the constructor, with the previous timestamp that was set after the selection of a president.

constructor(address[] memory voters, uint256 _previousVoteEndTimeStamp) EIP712("RankedChoice", "1") {
@>+ require (_previousVoteEndTimeStamp != 0, "Previous vote end timestamp cannot be zero");
+ s_previousVoteEndTimeStamp = _previousVoteEndTimeStamp;
}```
Updates

Lead Judging Commences

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

`s_previousVoteEndTimeStamp` variable not being initialized correctly

Support

FAQs

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