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

Contrary to what was intended there's still dust stuck in the contract

Summary

The comments specify that if at the last voter round up to avoid leaving dust; this means that the last voter can get 1 wei more than the rest. This implies that there shouldn't be any dust left in the contract. This is false.

Vulnerability Details

Rounding up at the last voter is not sufficient to prevent dust remaining stuck in the contract.
Please copy the code below in a new test file:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;
import {VotingBooth} from "../src/VotingBooth.sol";
import {Test} from "forge-std/Test.sol";
contract MyFuzzFoundry is Test {
// contracts required for test
VotingBooth booth;
function setUp() public virtual {}
function testHappyCase(uint256 x, uint256 amount) public {
vm.assume(x <= 9);
vm.assume(x >= 3);
vm.assume(x % 2 == 1);
vm.assume(amount > 1 ether);
address[] memory participants = new address[](x);
address participant;
for (uint160 i = 1; i < x + 1; i++) {
participant = address(i);
participants[i - 1] = participant;
}
uint256 catchedLenght = participants.length;
assertEq(participants.length, x);
vm.assume(amount >= 1 ether);
deal(address(this), amount);
booth = new VotingBooth{value: amount}(participants);
uint256 requiredToPass = catchedLenght / 2 + 1;
for (uint j; j < requiredToPass; ++j) {
vm.prank(participants[j]);
booth.vote(true);
}
assertEq(booth.isActive(), false);
assertEq(address(booth).balance, 0);
}
}

Run it using the following command:

forge test --mt testHappyCase -vvv

Relevant part of result:

├─ [292] VotingBooth::isActive() [staticcall]
│ └─ ← false
├─ emit log(val: "Error: a == b not satisfied [uint]")
├─ emit log_named_uint(key: " Left", val: 1)
├─ emit log_named_uint(key: " Right", val: 0)
├─ [0] VM::store(VM: [0x7109709ECfa91a80626fF3989D68f67F5b1DD12D], 0x6661696c65640000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000001)
│ └─ ← ()
└─ ← ()
Test result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 68.91ms
Ran 1 test suites: 0 tests passed, 1 failed, 0 skipped (1 total tests)
Failing tests:
Encountered 1 failing test in test/MyFuzzFoundry.t.sol:MyFuzzFoundry
[FAIL. Reason: assertion failed; counterexample: calldata=0x7e6cbe250000000000000000000000000000000000000000000000000000000000000005bfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff args=[5, 86844066927987146567678238756515930889952488499230423029593188005934847229951 [8.684e76]]] testHappyCase(uint256,uint256) (runs: 270, μ: 777433, ~: 783174)

Impact

Code doesn't work as intended. There's dust after the reward distribution.

Tools Used

Manual review + Forge testing

Recommendations

Update the code to send all the remaining balance in the last transfer of the for loop inside the _distributeRewards function.

Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

VotingBooth._distributeRewards(): Dust amount can still remain in contract

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.