The emergencyWithdraw function in veRAACToken fails to update the user's checkpoint when tokens are withdrawn, allowing users to retain their voting power in governance decisions even after withdrawing their tokens. This creates a potential for vote manipulation through a double-voting scenario.
The veRAACToken contract uses a checkpoint system to track users' voting power over time, which is critical for governance decisions. The emergencyWithdraw function currently has these operations:
The function correctly:
Deletes the user's lock state
Deletes the voting power points
Burns the user's veRAACToken balance
Returns the original RAAC tokens
However, it fails to update the user's checkpoint through _checkpointState.writeCheckpoint(msg.sender, 0). This is problematic because the Governance contract uses getPastVotes() (currently, it doesn't, but this is a bug reported in another submission) which reads from these checkpoints to determine voting power at specific blocks.
Users can perform an emergency withdrawal and still maintain voting power in governance decisions through their last checkpoint
A malicious user could execute an emergency withdrawal, vote on a proposal, then deposit again to effectively double their voting influence
Manual Review
Add the missing checkpoint update in the emergencyWithdraw function:
This ensures that the user's voting power is properly zeroed out in the checkpoint history when they withdraw their tokens, preventing any potential voting power manipulation.
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.