The voting system allows a proposal to succeed if the quorum is met (≥ 4% of total voting power) and forVotes > againstVotes. An attacker who accumulates at least 4% of total voting power can force quorum and manipulate the result if voter participation is low.
The voting state is determined by two conditions, if both conditions are false, the proposal Succeeds.
(1) currentQuorum >= requiredQuorum -> Quorum is met
(2) proposalVote.forVotes > proposalVote.againstVotes -> More "For" votes than "Against". The votes are the users' votingPower and calculated in castVote().
Therefore, if the attacker accumulates 4% of total voting power to force quorum and if voter turnout is low, they can control proposal outcomes by ensuring forVotes > againstVotes.
Example Attack Scenario 1:
Total Voting Power:1000
Quorum Requirement (4%): 40 votes
Attacker accumulates 41 votes and votes For.
If no one votes against or opposition votes, the proposal Succeeds.
Example Attack Scenario 2:
Total Voting Power: 1000
Quorum Requirement (4%): 40 votes
Attacker accumulates 41 votes and votes For.
If Bob and Alice both vote against with 10
Attacker's 41 votes > Bob + Alice 20 votes, the proposal Succeeds.
Voting result manipulation
Low Voter Participation Exploited: If most users are inactive, an attacker can control decision-making with minimal effort.
Manual code review
1 - Instead of just checking forVotes > againstVotes, consider adding a minimum percentage of forVotes relative to total votes cast where MIN_APPROVAL_PERCENTAGE could be set to something like 60%.
For example, 1 user votes (41) for and 1 user votes against (10), the approval percentage is 1 (for vote) / 2 (total votes) = 50% < MIN_APPROVAL_PERCENTAGE, proposalState.Defeated;
2 - Raise quorumNumerator from 4% to a higher value.
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.