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

Calculation of `VotingPool::rewardPerVoter` is wrong leading to native assets getting stuck in the contract

Description: The calculation of the VotingPool::rewardPerVoter is done incorrectly. As per the documentation the rewards are to be distributed to the For voters.

But when calculating the rewardPerVoter in Line: 192, it divides the rewards by totalVotes and not by totalForVotes.

uint256 rewardPerVoter = totalRewards / totalVotes;

Further down the code in Line: 2 the rewards are distributed to the voters who voted For the proposal.

_sendEth(s_votersFor[i], rewardPerVoter);

Impact: This results in significant amounts of the rewards being stuck in the contract forever and doesn't go to the users who voted For the proposal.

Proof of Concept:

  1. Proposal is created with 5 allowed voters

  2. Voters 1 and 2 vote For the proposal

  3. Voter 3 votes Against the proposal.

  4. Quorum is reached and rewards are calculated incorrectly

  5. Instead of Voters 1 and 2 getting half of the rewards each, they only get 1/3rd each. While the other 1/3rd is stuck in the contract forever.

Proof of Code
function testRewardsGetStuck() external {
deal(address(this), ETH_REWARD);
booth = new VotingBooth{value: ETH_REWARD}(voters);
vm.prank(address(0x1));
booth.vote(true);
vm.prank(address(0x2));
booth.vote(true);
vm.prank(address(0x3));
booth.vote(false);
assert(address(booth).balance > 0);
}

Recommended Mitigation:

- uint256 rewardPerVoter = totalRewards / totalVotes;
+ uint256 rewardPerVoter = totalRewards / totalForVotes;
Updates

Lead Judging Commences

0xnevi Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

VotingBooth._distributeRewards(): Incorrect computation of rewardPerVoter

Support

FAQs

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