The voting system relies on reaching a quorum to distribute the rewards to the voters or to return the funds back to the owner when the proposal gets defeated. The quorum and the vote outcome requirements can be circumvented when the creator submits a list of voters that contains duplicate entries.
When the creator deploys the contract, the list of voters gets registered by iterating over an array of addresses allowList
passed as a parameter to the constructor. There is a check to avoid setting address(0)
as a voter, but it's missing a check whether the address already got allowed.
The described issue compromises the outcome of the vote. Here are the steps to reproduce:
The creator submits a list with 5 entries but the first two are the same address.
The requirement for an odd number of real voters is already bypassed.
With a list containing 5 entries, a quorum of 3 voters "for" is expected for the proposal to pass. However, if the duplicate address plus one more address, both vote "for", it doesn't matter how the other voters vote. It suffices one more vote to call the voting process completed and to distribute the rewards.
In case the duplicate address + one more address vote "for", and the other two vote "against", 1/3 of the rewards get stuck in the voting contract and cannot be distributed.
Furthermore, all the variables are private, which further obfuscates the voting process by making it difficult for the participants to verify all the rules are followed rigorously.
Slither
Add an additional check after https://github.com/Cyfrin/2023-12-Voting-Booth/blob/a3241b1c530529a4f739f9462f720e8561ad45ca/src/VotingBooth.sol#L104
Make all variables public
to guarantee a transparent setup.
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.