The _distributeRewards function is designed to incentivize voters who support a proposal by rewarding only the for voters. However, there is an issue in the implementation where the rewardPerVoter is calculated using the totalVotes variable instead of totalVotesFor. Consequently, the average rewardPerVoter is computed considering all votes, but the rewards are distributed exclusively to the for voters, leaving an unallocated remainder for the against voters.
For every against voter the rewards will be stuck in the protocol forever.
Proof of Concept:
Setup:
Create a Voting Booth with 5 addresses.
Set the ETH_REWARD to 10 ETH.
Voting:
3 addresses participate in the vote (2 votes for, 1 vote against).
Distribution Calculation:
As the quorum is reached, rewards are set to be distributed.
Calculate rewardPerVoter: ETH_REWARD / totalVotes = 10 ETH / 3 = 3.333.. ETH.
Incorrect Distribution:
The 2 addresses that voted for the proposal receive a total of 6.666.. ETH.
However, 3.333.. ETH remains undistributed, causing funds to be stuck in the protocol.
Using testVotePassesAndMoneyIsSent in VotingBooth.t.sol we set one of the booth.vote() to false.
The test will not pass, because address(booth).balance != 0.
Manual Review and Foundry
In order to distribute the whole ETH_REWARD to the for voters, we should use totalVotesFor instead of totalVotes to calculate the rewardPerVoter.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.