Both regular and emergency operations use the same ID generation logic but are stored in separate mappings (_operations
and _emergencyActions
). This allows An operation to exist simultaneously in both mappings.
The same transaction batch to be executed twice:
Once via executeEmergencyAction
(immediately, bypassing timelock)
Again via executeBatch
(after timelock delay)
Create Colliding ID:
Proposer creates a regular operation with parameters (targets, values, calldatas, salt)
, generating ID X
.
Schedule Emergency Action:
Emergency role schedules an emergency action with the same parameters, reusing ID X
.
Execute via Emergency:
Execute via Regular:
After timelock delay:
executeEmergencyAction doesn't check regular operations and executeBatch doesn't check emergency actions
If the operation sends 100 ETH to an address:
Attacker executes it twice, draining 200 ETH instead of 100 ETH.
Foundry
Add a type discriminator to the ID hashing to prevent collisions
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.