In contracts::core::governance::proposals::Governance.sol
, the _queueProposal
function computes an operation ID using a hash of the proposal's targets, values, calldata, and description hash. If two proposals have the same targets, values, calldata, and description hash, they will generate identical operation IDs, causing a collision. This prevents the second proposal from being properly queued and executed, leading to governance deadlocks.
The issue arises in _queueProposal
, where the operation ID is calculated using the proposal's targets, values, calldatas and description hash.
In contracts::core::governance::proposals::Governance.sol#L487-L497
:
Those parameters will be used in hashOperationBatch
to generate a unique operation ID.
In contracts::core::governance::proposals::TimelockController.sol#L318-L326
:
This means two proposals with identical targets
, values
, calldatas
, and descriptionHash
will result in the same id
. The _operations
mapping in TimelockController
contract stores the operation information including its timestamp and executed status. As a result, when a second identical proposal is proposed, the operation information will be incorrect since an entry with the same ID already exists, preventing it from being properly queued and executed.
Having the same operation ID can cause a number of problems. Some of them are:
Governance Deadlock: If a proposal is queued, subsequent identical proposals cannot be queued, limiting governance flexibility.
Proposal Reusability Issue: Some proposals may need to be reintroduced with the same parameters, but the system will block them due to the collision.
Manual Review
Include a proposal-specific nonce in the hash calculation to ensure uniqueness. Alternatively, consider incorporating the unique proposalId
instead of descriptionHash
.
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.