The voting power calculation in the governance system lacks proper checkpointing, allowing users to vote multiple times by transferring tokens between addresses.
The castVote
function in the Governance contract uses getVotingPower()
without block number parameters:
This allows a malicious user to:
Vote with their current voting power
Transfer their veRAAC tokens to another address
Vote again from the new address
Potentially repeat this process multiple times
The lack of historical voting power tracking enables this double-voting attack vector.
Double voting possibility through token transfers
Manipulation of governance decisions
Undermined voting integrity
Potential for malicious proposals to pass through vote multiplication
Manual code review
Analysis of governance implementation
Review of voting power calculation mechanisms
Implement a getPriorVotingPower(address account, uint256 blockNumber)
function that returns historical voting power
Modify the castVote
function to use voting power from the proposal creation block:
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.