The function castVote
suffers from a Time-of-Check to Time-of-Use (TOCTOU) issue related to the retrieval of voting power. The function calls _veToken.getVotingPower(msg.sender)
at the time of voting, but this value may change before the vote is finalized, leading to inconsistent or unfair voting results.
The contract fetches the voter's voting power (weight = _veToken.getVotingPower(msg.sender)
) at the time of vote submission.
However, _veToken.getVotingPower(msg.sender)
is a dynamic value that may fluctuate due to token transfers, staking, delegation, or any governance mechanism affecting voting power.
This introduces a Time-of-Check to Time-of-Use (TOCTOU) problem where:
A voter may temporarily inflate their voting power, cast a vote, and then transfer or unstake tokens.
A malicious entity may borrow tokens (flash loans), cast a vote with high power, and return the borrowed tokens before the proposal ends.
Voting power may be reduced unexpectedly due to another protocol mechanism, affecting the vote's accuracy.
Double Voting: This allows double voting, where one entity can vote multiple times using different accounts.
Vote Manipulation: A user can transfer tokens to another address and vote again, effectively amplifying their voting power.
Unfair Governance Decisions: The final vote may not reflect the true state of governance token holders at the time of the vote.
Manual Review
Use Voting Power Snapshots:
Instead of checking _veToken.getVotingPower(msg.sender)
at the time of voting, take a snapshot of voting power at the start of the proposal or beginning of the voting period.
Add code givenb below to veRAACToken.sol :
This ensures that a voter's power is fixed when the proposal starts, preventing 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.