The Governance
contract has inconsistent checks for when voting ends, potentially excluding valid votes cast in the last second of the voting period.
There is a discrepancy between how the castVote() function and state() function, which is used to check if the proposal should be queued or executed. determine when voting ends:
In castVote(), voting is considered ended when:
While in state(), voting is considered ended when:
This means that votes cast exactly at block.timestamp == proposal.endTime
will be rejected by castVote() but the proposal will still be considered active according to state().
Votes cast in the last second of the voting period (when block.timestamp == proposal.endTime
) will be rejected even though they should be valid according to the proposal state. This could affect the outcome of close votes where every vote matters, potentially causing proposals to fail or pass incorrectly.
A proposal is created with endTime = block.timestamp + 7 days
When block.timestamp == proposal.endTime
:
castVote()
considers the proposal still Active
But state()
- for ended
Critical votes cast at this exact timestamp are lost
The proposal outcome could be different from what it should be if these votes were counted
Fix the check in state()
to be consistent with castVote()
:
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.