The current implementation of the VotingBooth contract contains a flaw in the reward distribution logic, resulting in a lower than expected payout and the potential for remaining funds to become trapped within the contract. The documentation specifies that, upon a proposal's success, all rewards should be distributed to those who voted in favor. However, this is not the case in the current implementation.
The issue becomes apparent when there is a mix of votes for and against a proposal. If all votes are in favor of the proposal, the reward calculation is accurate.
The flawed reward distribution is calculated in the VotingBooth::_distributeRewards()
function. If a proposal passes with a mix of votes, the rewardPerVoter
is calculated inaccurately. The current implementation divides the total rewards by the total number of votes (uint256 rewardPerVoter = totalRewards / totalVotes;
), which results in a smaller payout as it should only be distributed to those who voted in favor.
For instance, consider the following scenario:
Contract total reward = 10 ether
Valid voters: 10 users
Votes for the proposal: 4 users
Votes against the proposal: 2 users
The current contract will distribute: totalRewards/totalVotes = 10/6 = 1.666 eth
to the 4 voters in favor, totaling 6.666 eth. The remaining balance will be trapped in the VotingBooth contract.
This flaw leads to incorrect payouts and the potential for funds to be permanently stuck in the contract, which is a high-impact issue.
Manual review
To correct this issue, the payout reward calculation for a successful proposal should divide by totalVotesFor
instead of totalVotes
.
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.