When a proposal has been canceled, the Governance.sol contract sets the proposal.canceled = true. However, the castVote function does not check this flag, allowing votes to be cast on proposals after they’ve been canceled. Though these votes do not resurrect or otherwise affect the proposal’s final “canceled” state, it leads to inaccurate or misleading vote tallies.
The castVote function only checks:
That the proposal exists (proposal.startTime != 0),
Voting window (startTime <= block.timestamp <= endTime),
Whether the voter already voted, and
Whether the voter has nonzero voting power.
It does not check whether proposal.canceled is true, so canceled proposals remain eligible for voting.
Code Snippet :
Misleading Vote Counts:
The on-chain record may show continuing “for” and “against” votes even though the proposal is canceled and will never proceed to execution.
User Confusion and UI Issues:
Front-end interfaces might display ongoing votes on canceled proposals, confusing token holders or making them believe the proposal might still pass.
No Direct Security Compromise:
Since a canceled proposal cannot be executed, the extra votes do not reinstate it or grant the proposer any additional power. Therefore, the severity is relatively low.
Manual review
Add a require(!proposal.canceled, "Proposal is canceled") Check:
In the castVote function, verify that the proposal is not canceled before allowing votes.
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.