The Governance::castVote
function fails to check whether a proposal has been canceled before allowing votes. While it verifies the proposal's existence and voting period status, it does not account for the canceled flag. This allows users to vote on proposals that are no longer active, violating governance protocol rules.
In the castVote
function, the only checks performed are to ensure that the proposal exists, the voting window is open, and the user has not already voted. There is no verification of the proposal's cancellation status. For example, if a proposal is cancelled via the cancel()
function (which sets proposal.canceled
to true), a user can still invoke castVote
on that proposal. The function would then record the vote as if the proposal were active, despite its cancelled state.
When a proposal is canceled
via the cancel function, it sets proposal.canceled = true
the state()
function correctly returns ProposalState.Canceled
for canceled proposals However, the castVote
function only checks: Proposal existence (startTime != 0)
,Voting period timing (block.timestamp between startTime and endTime)
, Voter eligibility (has not already voted, has voting power)
Missing check for proposal.canceled
allows voting on canceled proposals if within the original voting window.
POC:
User A creates a proposal and later cancels it, setting proposal.canceled
to true.
User B then calls castVote
on the cancelled proposal.
Since there is no check for cancellation, User B's vote is accepted, leading to inaccurate vote tallies.
Votes cast on cancelled proposals may distort the final vote count and state determination, undermining the integrity of the governance process.
Manual Review
Modify the castVote
function to include a check for proposal.canceled
before allowing votes. If proposal.canceled
is true
, revert the transaction to prevent voting on cancelled proposals.
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.