The veRAACToken::recordVote
function is permissionless and takes an address voter
as an input parameter. The issue with the current code is that the function doesn't validate if the voter
parameter matches the actual msg.sender
. This allows an attacker to arbitrarily vote on behalf of other users.
Picture the following scenario, we have 1000 veRAACToken
token holders. The top 10 holders (whales) hold 60% of the supply.
A malicious user can keep track of their addresses and when a new governance proposal comes up, the attacker can vote on behalf of these 10 token holders and make any proposal either pass or be rejected.
When the legitimate token holder attempts to vote, their transaction will be reverted because the bool flag _hasVotedOnProposal[voter][proposalId]
will already be set to true
for their address
.
Root cause
Lack of access controls on the veRAACToken::recordVote
function.
A user can arbitrarily vote on behalf of any other token holder and can singlehandedly make a proposal pass or be rejected if they target the wallets with the highest voting power first.
Not needed
Manual review
Add a check and make sure that the address voter
param matches the actual msg.sender
or if the intended design of the protocol is to allow voting via delegates, consider adding a whitelist mechanism where a veRAACToken
token holder can whitelist another address to vote on their behalf and then add checks to see if msg.sender
is whitelisted and can vote on behalf of the address voter
.
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.