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

Incorrect Reward Distribution due to Denomination Error

Summary

reward calculation error in VotingBooth smart contract caused by a Denomination Error

Vulnerability Details

In the VotingBooth::_distributeRewards function, if the proposal passed, the rewardPerVoter calculation employed an invalid denominator, specifically using totalVotes to distribute rewards among the For voters. This resulted in unequal distribution, as the denominator considered users who voted Against the proposal as well. Consequently, this miscalculation has financial implications on both the smart contract and its users. The division of totalRewards by totalVotes caused the rewardPerVoter value to be inaccurately calculated.

Impact

  • Wrong distribution of rewards for the For Voters

  • funds get stuck forever in the smart contracts

Tools Used

Manual Review, Foundry.

POC

function testIncorrectRewardCalculation() public {
vm.prank(address(0x1));
booth.vote(true);
vm.prank(address(0x2));
booth.vote(false);
vm.prank(address(0x3));
booth.vote(true);
//two `For` Voters making the proposal pass means each voter will get 5 ethers each of the 10 ethers in the booth
// shows the FOR voter did not get all the reward out of the Booth
uint totalVotersBalance = address(0x1).balance + address(0x3).balance;
assert(totalVotersBalance < 10 ether);
// shows there are still funds stuck in the booth
assert(!booth.isActive() && address(booth).balance > 0);
}

Add the above function to VotingBoothTest.t.sol and run it with forge test --mt testIncorrectRewardCalculation -vvvvv

Recommendations

it is advised to correct the calculation logic in the VotingBooth::_distributeRewards function to use an appropriate denominator, ensuring that only relevant votes are considered in the rewardPerVoter calculation when proposal passed.

- uint256 rewardPerVoter = totalRewards / totalVotes;
+ uint256 rewardPerVoter = totalRewards / totalVotesFor;
- rewardPerVoter = Math.mulDiv(totalRewards, 1, totalVotes, Math.Rounding.Ceil);
+ rewardPerVoter = Math.mulDiv(totalRewards, 1, totalVotesFor, Math.Rounding.Ceil);
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.