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

Mishandling of voter rewards distribution

Summary

A vulnerability in the VotingBooth smart contract causes part of the rewards funding to be irrecoverable.

Vulnerability Details

When a reward distribution is triggered and the proposals passes, the following code is executed.

// Set reward amount to give **ONLY** to each of "For" voters
uint256 rewardPerVoter = totalRewards / totalVotes;
// Rewards are distributed between `totalVotesFor` addresses
for (uint256 i; i < totalVotesFor; ++i) {
if (i == totalVotesFor - 1) {
rewardPerVoter = Math.mulDiv(totalRewards, 1, totalVotes, Math.Rounding.Ceil);
}
_sendEth(s_votersFor[i], rewardPerVoter);
}

Here, the reward per individual "For" voters, declared as rewardPerVoter, is assigned to the total of rewards divided by the total of votes.
This is wrong, since the total rewards to give to the "For" voters should be divided by the number of "For" voters, not the total of voters, which would also split taking "Against" voters in consideration.

The error is also hinted by the code block that follows, which properly sends individual rewards to totalVotersFor addresses.

The only situation where this contract executes successfully is the one where all the addresses that voted before reaching quorum are "For" voters.

Impact

High. The vulnerability causes loss of funds and underwhelming rewards for proposal voters.

Tools Used

None.

Recommendations

Replace line 192:

uint256 rewardPerVoter = totalRewards / totalVotes;

with the following line:

uint256 rewardPerVoter = totalRewards / totalVotesFor;

fixes the vulnerability.

Updates

Lead Judging Commences

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