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

Lack of withdraw function leads to lock of ethers.

Summary

The lack of withdraw function locks the token in the contract forever.

Vulnerability Details

Consider the following scenario, there is 5 allowed voters and the threshold of voters required to trigger the reward distribution is 3. Assume the reward is 1 ether and two of the voter votes for the proposal and the other one votes against, the reward for the two for-voter will be:

1st voter: 3333333333333333333 (wei)
2nd voter: 3333333333333333334 (wei)

and the voter votes against will not get any tokens as reward. In this case, there are 3333333333333333333 wei of ether remaining in the contract. However, there is no withdraw function that can take the token out of the contract.

Simple PoC:

function testDistributeAmount() public { // Assume there are 5 allowed voters in total.
vm.prank(address(0x1));
booth.vote(true);
vm.prank(address(0x2));
booth.vote(true);
vm.prank(address(0x3));
booth.vote(false);
console2.log(address(0x1).balance); // 3333333333333333333 wei
console2.log(address(0x2).balance); // 3333333333333333334 wei
console2.log(address(0x3).balance); // 0 wei
console2.log(address(booth).balance); // 3333333333333333333 wei but fail to withdraw
}

Impact

Every voting result that totalVotesAgainst < totalVotesFor but totalVotesFor != totalVotes will have remaining tokens, and these tokens are unable to transfer to any address, thus locking in the contract.

Tools Used

Manual Review

Recommendations

At the end of the _distributeReward funciton, send the remaining ether to the s_creator or design a withdraw function.

Updates

Lead Judging Commences

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