Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Invalid

When the `allowList` contains 3 different addresses, `_distributeRewards()` is called by submitting 1 true and 1 false vote

Summary

The vote() function logic is flawed. When the allowList contains 3 different addresses, _distributeRewards() is called by submitting 1 true and 1 false vote. In a real-life scenario, it would be up to the third voter to decide whether or not the vote passes.

Vulnerability Details

When there are 3 different voters, quorum is already reached when there are 2 submitted votes:

2 * 100 / allowListLength = 66.67 (which is >= 51).

This can be tested with this snippet:

function testFail_OneForOneAgainstVote() public {
vm.prank(address(0x1));
booth.vote(true);
vm.prank(address(0x2));
booth.vote(false);
//isActive() should still return true after casting 1 true and 1 false vote
//the contract balance should not be paid out yet
assert(booth.isActive() && address(booth).balance > 0);
}

Impact

s_votingComplete is set to true, so further votes are impossible.
The function _distributeRewards() is then called, returning the contract balance of 1 ether to the s_creator. This happens because the totalVotesAgainst >= totalVotesFor condition is met (1 vote for, 1 vote against). This behaviour is not expected when using the contract.

Tools Used

Foundry

Recommendations

This problem can be fixed by implementing an additional safety check on line 156, for example:

if (totalCurrentVotes * 100 / s_totalAllowedVoters >= MIN_QUORUM && s_votersAgainst.length != s_votersFor.length) {
...
}
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

VotingBooth.vote: In certain scenarios, proposal can pass when for and against votes are equal

0xtheblackpanther Auditor
over 1 year ago
0xnevi Lead Judge
over 1 year ago
0xnevi Lead Judge over 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.