The contract assigns proposal IDs using a simple incrementing counter:
This approach does not uniquely identify proposals based on their content, making the system vulnerable to proposal ID reuse if _proposalCount is reset due to a storage corruption, contract upgrade, or administrative mistake. If a previously defeated or canceled proposal (e.g., proposalId = 42) is later assigned the same ID due to an unintended reset, the system may treat it as an already-approved proposal and allow it to be executed with altered content. An attacker can exploit this by forcing a malicious proposal under a previously accepted ID, effectively bypassing the governance process and executing transactions (e.g., treasury withdrawals, parameter changes) without requiring a new vote.
Replay attacks allow malicious proposals to be executed under old, previously approved proposal IDs, enabling unauthorized fund transfers or governance manipulation.
Proposal IDs should be generated using a hash of proposal content (e.g., keccak256(abi.encode(targets, values, calldatas, description, block.timestamp))) to ensure uniqueness and prevent ID reuse.
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.