From 1419119a41e156e1bf519c85f922681175a6d7c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Cuesta=20Ca=C3=B1ada?= Date: Mon, 11 Aug 2025 10:18:26 +0100 Subject: [PATCH 1/7] nonceless execution draft --- governance/nonceless-execution.md | 68 +++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 governance/nonceless-execution.md diff --git a/governance/nonceless-execution.md b/governance/nonceless-execution.md new file mode 100644 index 000000000..f85effe1a --- /dev/null +++ b/governance/nonceless-execution.md @@ -0,0 +1,68 @@ +# Nonceless Execution + +| | | +| ------------------ | -------------------------------------------------- | +| Author | _Author Name_ | +| Created at | _YYYY-MM-DD_ | +| Initial Reviewers | _Reviewer Name 1, Reviewer Name 2_ | +| Need Approval From | _Reviewer Name_ | +| Status | _Draft / In Review / Implementing transactions / Final_ | + +## Purpose + +Let governance multisigs execute approved transactions without being blocked by a single global nonce. Allow independent transactions to run in any order while keeping the same signature thresholds and replay protection. + +## Summary + +We add a Safe-compatible module that enables unordered execution. Instead of one nonce that forces everything to run in sequence, each approved transaction has its own identifier. Once it has enough signatures, it can be executed in any order. Signature thresholds stay the same. Executions are public and cannot be replayed. + +## Problem Statement + Context + +- Nonce contention: a single stuck transaction can block unrelated work. +- Operational latency: urgent changes wait behind unrelated items in the queue. +- Throughput: we need to run unrelated transactions at the same time without extra coordination. + +## Proposed Solution + +Introduce a Safe module that allows unordered execution of approved transactions: +- Unordered execution: transactions do not compete on a global nonce; each executes as soon as it is fully approved. +- Threshold-preserving: existing signature thresholds and signer sets continue to apply. +- Replay safety: each transaction is uniquely identified and cannot be executed more than once. +- Auditability: authorized transactions and executions are visible on-chain and traceable to their approvals. + +## Scope + +- Enable unordered execution for governance multisigs. +- Preserve existing thresholds, ownership, and incident response processes. + +## Non-goals + +- Changing thresholds or governance ownership models. +- Adding new signing tools or UIs. +- Redesigning incident response. + +## Success Criteria + +- Liveness: independent approved transactions can execute without waiting on others. +- Safety: no increase in unauthorized execution risk; replay attempts are rejected. +- Usability: no extra steps for signers; current approval workflows still work. +- Observability: clear on-chain signals for monitoring and post-mortems. + +## Resource Usage + +- On-chain: similar cost to current multisig execution, with small module overhead. +- Operational: less coordination overhead; faster handling of urgent items. + +## Alternatives Considered + +- Status quo (nonce ordering): no implementation effort, but it negatively impacts operations and UX due to the coordination and planning required. + +## Risks & Uncertainties + +- Unexpected effects due to unordered changes. + - Mitigation: review, simulation, change windows, and clear runbooks. + +## References + +- Nonceless execution module (Safe-compatible): [UnorderedExecutionModule.sol](https://github.com/ethereum-optimism/optimism/blob/28f44ab50b01fb59f875c7b85d216cdce713b6dd/packages/contracts-bedrock/src/safe/UnorderedExecutionModule.sol#L1) +- Slides overview: [Nonceless Execution (Google Slides)](https://docs.google.com/presentation/d/1utbGigIbMRA7JGcKZ9ZcUgMCdIPpLDJSwWmxNF9hBJM/edit?slide=id.g3734216eca8_4_32#slide=id.g3734216eca8_4_32) \ No newline at end of file From b65b9ee805376d359a2f2ceb6da5bfa4d89cbfee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Cuesta=20Ca=C3=B1ada?= Date: Tue, 12 Aug 2025 08:33:28 +0100 Subject: [PATCH 2/7] Replaced some AI content with RFC content --- governance/nonceless-execution.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/governance/nonceless-execution.md b/governance/nonceless-execution.md index f85effe1a..5373c1051 100644 --- a/governance/nonceless-execution.md +++ b/governance/nonceless-execution.md @@ -2,9 +2,11 @@ | | | | ------------------ | -------------------------------------------------- | -| Author | _Author Name_ | +| Author | Alberto Cuesta Cañada | | Created at | _YYYY-MM-DD_ | -| Initial Reviewers | _Reviewer Name 1, Reviewer Name 2_ | +| Initial Reviewers | [ ] John Mardlin | +| | [ ] Kelvin Fichter | +| | [ ] Matt Solomon | | Need Approval From | _Reviewer Name_ | | Status | _Draft / In Review / Implementing transactions / Final_ | @@ -17,10 +19,8 @@ Let governance multisigs execute approved transactions without being blocked by We add a Safe-compatible module that enables unordered execution. Instead of one nonce that forces everything to run in sequence, each approved transaction has its own identifier. Once it has enough signatures, it can be executed in any order. Signature thresholds stay the same. Executions are public and cannot be replayed. ## Problem Statement + Context - -- Nonce contention: a single stuck transaction can block unrelated work. -- Operational latency: urgent changes wait behind unrelated items in the queue. -- Throughput: we need to run unrelated transactions at the same time without extra coordination. +Transaction ordering is a huge hassle that sucks up our time, and causes delays and rework. + ## Proposed Solution @@ -59,10 +59,12 @@ Introduce a Safe module that allows unordered execution of approved transactions ## Risks & Uncertainties +- Although this has very little impact on signing flows, it does significantly change transaction execution (and approval with nested safes). Hard to say how heavily it would impact on the superchain-ops repo. +- Is this something that can be adopted piecemeal, ie. could we manage with safes that do and do not use this module? I think we could likely autodetect when a Safe supports nonceless execution, but more branches is still harder to maintain. - Unexpected effects due to unordered changes. - - Mitigation: review, simulation, change windows, and clear runbooks. ## References +- [Unordered Execution of Safe Transactions](https://www.notion.so/oplabs/Unordered-execution-of-Safe-transactions-20ef153ee1628054ade1e7e8beeadfef#20ef153ee162800689d1cd1268c85f91) - Nonceless execution module (Safe-compatible): [UnorderedExecutionModule.sol](https://github.com/ethereum-optimism/optimism/blob/28f44ab50b01fb59f875c7b85d216cdce713b6dd/packages/contracts-bedrock/src/safe/UnorderedExecutionModule.sol#L1) -- Slides overview: [Nonceless Execution (Google Slides)](https://docs.google.com/presentation/d/1utbGigIbMRA7JGcKZ9ZcUgMCdIPpLDJSwWmxNF9hBJM/edit?slide=id.g3734216eca8_4_32#slide=id.g3734216eca8_4_32) \ No newline at end of file +- [Nonceless Execution Overview (Google Slides)](https://docs.google.com/presentation/d/1utbGigIbMRA7JGcKZ9ZcUgMCdIPpLDJSwWmxNF9hBJM/edit?slide=id.g3734216eca8_4_32#slide=id.g3734216eca8_4_32) \ No newline at end of file From 72df7fb3a5b64d7b816dafcbedc2a5fef5d3a949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Cuesta=20Ca=C3=B1ada?= Date: Tue, 12 Aug 2025 10:08:53 +0100 Subject: [PATCH 3/7] Updated index box, removed success criteria --- governance/nonceless-execution.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/governance/nonceless-execution.md b/governance/nonceless-execution.md index 5373c1051..7ec9059e6 100644 --- a/governance/nonceless-execution.md +++ b/governance/nonceless-execution.md @@ -3,12 +3,12 @@ | | | | ------------------ | -------------------------------------------------- | | Author | Alberto Cuesta Cañada | -| Created at | _YYYY-MM-DD_ | +| Created at | 2025-08-12 | | Initial Reviewers | [ ] John Mardlin | | | [ ] Kelvin Fichter | | | [ ] Matt Solomon | | Need Approval From | _Reviewer Name_ | -| Status | _Draft / In Review / Implementing transactions / Final_ | +| Status | Draft | ## Purpose @@ -41,13 +41,6 @@ Introduce a Safe module that allows unordered execution of approved transactions - Adding new signing tools or UIs. - Redesigning incident response. -## Success Criteria - -- Liveness: independent approved transactions can execute without waiting on others. -- Safety: no increase in unauthorized execution risk; replay attempts are rejected. -- Usability: no extra steps for signers; current approval workflows still work. -- Observability: clear on-chain signals for monitoring and post-mortems. - ## Resource Usage - On-chain: similar cost to current multisig execution, with small module overhead. From d17d9eaa0614387c9b9039ea1323ec690ebd7069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Cuesta=20Ca=C3=B1ada?= Date: Tue, 12 Aug 2025 10:14:24 +0100 Subject: [PATCH 4/7] A bit more flowier text --- governance/nonceless-execution.md | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/governance/nonceless-execution.md b/governance/nonceless-execution.md index 7ec9059e6..ffb144a78 100644 --- a/governance/nonceless-execution.md +++ b/governance/nonceless-execution.md @@ -19,16 +19,12 @@ Let governance multisigs execute approved transactions without being blocked by We add a Safe-compatible module that enables unordered execution. Instead of one nonce that forces everything to run in sequence, each approved transaction has its own identifier. Once it has enough signatures, it can be executed in any order. Signature thresholds stay the same. Executions are public and cannot be replayed. ## Problem Statement + Context -Transaction ordering is a huge hassle that sucks up our time, and causes delays and rework. - + +Transaction ordering is a huge hassle that sucks up our time and causes delays and rework. When governance needs to execute multiple independent transactions, they get stuck waiting for each one to complete before the next can begin. This creates unnecessary bottlenecks where urgent fixes wait behind routine updates, and coordination overhead grows with every additional transaction in the queue. ## Proposed Solution -Introduce a Safe module that allows unordered execution of approved transactions: -- Unordered execution: transactions do not compete on a global nonce; each executes as soon as it is fully approved. -- Threshold-preserving: existing signature thresholds and signer sets continue to apply. -- Replay safety: each transaction is uniquely identified and cannot be executed more than once. -- Auditability: authorized transactions and executions are visible on-chain and traceable to their approvals. +Introduce a Safe module that allows unordered execution of approved transactions. Transactions do not compete on a global nonce and each executes as soon as it is fully approved. Existing signature thresholds and signer sets continue to apply. Each transaction is uniquely identified and cannot be executed more than once, while authorized transactions and executions remain visible on-chain and traceable to their approvals. ## Scope @@ -37,18 +33,15 @@ Introduce a Safe module that allows unordered execution of approved transactions ## Non-goals -- Changing thresholds or governance ownership models. -- Adding new signing tools or UIs. -- Redesigning incident response. +This change does not involve changing thresholds or governance ownership models, adding new signing tools or UIs, or redesigning incident response. ## Resource Usage -- On-chain: similar cost to current multisig execution, with small module overhead. -- Operational: less coordination overhead; faster handling of urgent items. +On-chain costs are similar to current multisig execution with small module overhead. Operationally, this reduces coordination overhead and enables faster handling of urgent items. ## Alternatives Considered -- Status quo (nonce ordering): no implementation effort, but it negatively impacts operations and UX due to the coordination and planning required. +The status quo of nonce ordering requires no implementation effort but negatively impacts operations and UX due to the coordination and planning required. ## Risks & Uncertainties From 479d58c8837873ef168fad7c497dd5b349ece762 Mon Sep 17 00:00:00 2001 From: alcueca Date: Wed, 13 Aug 2025 12:27:56 +0100 Subject: [PATCH 5/7] Redrafted following the example in the Liveness module. --- governance/nonceless-execution.md | 35 ++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/governance/nonceless-execution.md b/governance/nonceless-execution.md index ffb144a78..2d2fe34fd 100644 --- a/governance/nonceless-execution.md +++ b/governance/nonceless-execution.md @@ -10,26 +10,40 @@ | Need Approval From | _Reviewer Name_ | | Status | Draft | -## Purpose +## Problem Statement + Context -Let governance multisigs execute approved transactions without being blocked by a single global nonce. Allow independent transactions to run in any order while keeping the same signature thresholds and replay protection. +Safe accounts maintain a single, monotonically increasing `nonce` that is included in the EIP-712 typed data each owner signs and is checked during `execTransaction`. The contract only accepts execution for the current nonce; upon success it increments the nonce by 1. This enforces a single global queue: at any time exactly one nonce is executable. Owners may propose alternate transactions for that same nonce as replacements, but nothing with a future nonce can be executed until the current one is finalized. If execution reverts, the nonce is unchanged and the queue remains blocked. This ordering provides replay protection and simple reasoning, but it also couples otherwise independent actions and makes execution latency of one item the bottleneck for all others. -## Summary +Operationally, this single-queue design turns independent governance actions into a serialized pipeline: urgent remediations can be blocked behind planned items, execution failures stall the queue, and coordination and development costs grow as we scale. -We add a Safe-compatible module that enables unordered execution. Instead of one nonce that forces everything to run in sequence, each approved transaction has its own identifier. Once it has enough signatures, it can be executed in any order. Signature thresholds stay the same. Executions are public and cannot be replayed. +## Customer Description -## Problem Statement + Context +The customers for this design doc are any participants in the multisig accounts that would utilize this module, as well as any 3rd parties who rely on the security properties of these accounts. -Transaction ordering is a huge hassle that sucks up our time and causes delays and rework. When governance needs to execute multiple independent transactions, they get stuck waiting for each one to complete before the next can begin. This creates unnecessary bottlenecks where urgent fixes wait behind routine updates, and coordination overhead grows with every additional transaction in the queue. +### Customer Reviewers +- Coinbase (potentially impacted 3rd party) +- Uniswap (potentially impacted 3rd party) +- Security Council +- Optimism Foundation + +## Requirements and Constraints +- Enable unordered execution securely. +- Transaction executions are public. +- Avoid replay of executed transactions. +- Keep code as minimal as possible to avoid complex logic in Safe modules. +- Reduce mental overhead for Safe owners and multisig leads. ## Proposed Solution -Introduce a Safe module that allows unordered execution of approved transactions. Transactions do not compete on a global nonce and each executes as soon as it is fully approved. Existing signature thresholds and signer sets continue to apply. Each transaction is uniquely identified and cannot be executed more than once, while authorized transactions and executions remain visible on-chain and traceable to their approvals. +### Singleton +NoncelessExecutionModule is a singleton that exists at a known address on all chains and has no constructor parameters. Any Safe on any network can choose to enable the module within the Safe. No configuration is required. + +### Nonceless Module Execution +Normal owner-signed executions use `execTransaction(...)`, which include the Safe’s nonce in the EIP-712 digest owners sign. This function requires the current nonce and increments it on success, with the purpose of providing replay protection and enforcing a single global ordering. -## Scope +Module execution bypass this interface and can execute anything at anytime, without touching the nonce. We take advantage of this by building an alternative replay protection mechanism in the module and using the Safe logic to handle signature verification. Signers should be able to sign transaction using any of the usual means. -- Enable unordered execution for governance multisigs. -- Preserve existing thresholds, ownership, and incident response processes. +For replay protection we would use a bytes32 hash, rather than a uint256 value. Any hash can be executed at any time as long as it has the required signatures, and it hasn't been used before. Executed hashes would be stored in the module to enable replay protection. ## Non-goals @@ -45,6 +59,7 @@ The status quo of nonce ordering requires no implementation effort but negativel ## Risks & Uncertainties +- The computed transaction hashes need to not collide with an already used nonce. Using keccak256 hashes should be enought to avoid that. - Although this has very little impact on signing flows, it does significantly change transaction execution (and approval with nested safes). Hard to say how heavily it would impact on the superchain-ops repo. - Is this something that can be adopted piecemeal, ie. could we manage with safes that do and do not use this module? I think we could likely autodetect when a Safe supports nonceless execution, but more branches is still harder to maintain. - Unexpected effects due to unordered changes. From 212786afa1a060435d7b2be14809d07c3d5a5f3c Mon Sep 17 00:00:00 2001 From: alcueca Date: Wed, 13 Aug 2025 13:02:45 +0100 Subject: [PATCH 6/7] minor tweaks to the proposed solution, for clarity --- governance/nonceless-execution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/governance/nonceless-execution.md b/governance/nonceless-execution.md index 2d2fe34fd..cbddcd164 100644 --- a/governance/nonceless-execution.md +++ b/governance/nonceless-execution.md @@ -41,9 +41,9 @@ NoncelessExecutionModule is a singleton that exists at a known address on all ch ### Nonceless Module Execution Normal owner-signed executions use `execTransaction(...)`, which include the Safe’s nonce in the EIP-712 digest owners sign. This function requires the current nonce and increments it on success, with the purpose of providing replay protection and enforcing a single global ordering. -Module execution bypass this interface and can execute anything at anytime, without touching the nonce. We take advantage of this by building an alternative replay protection mechanism in the module and using the Safe logic to handle signature verification. Signers should be able to sign transaction using any of the usual means. +Module execution uses `execTransactionFromModule(...)` and doesn't use nonces. We use this function to an alternative execution pathway in the module with a custom replay protection mechanism. We still use the Safe logic to handle signature verification, signers should be able to sign transaction using any of the usual means. -For replay protection we would use a bytes32 hash, rather than a uint256 value. Any hash can be executed at any time as long as it has the required signatures, and it hasn't been used before. Executed hashes would be stored in the module to enable replay protection. +For replay protection we would use and store a bytes32 hash for each transaction, rather than a uint256 value. Any hash can be executed at any time as long as it has the required signatures, and it hasn't been used before. ## Non-goals From 4da26955266ce5070b39f1f4ce12012c88db3a26 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 14 Aug 2025 09:49:18 -0400 Subject: [PATCH 7/7] Update nonceless execution design with clearer implementation details - Enhanced module execution explanation with hash-once mechanism details - Added optional transaction ordering section with prerequisite support --- governance/nonceless-execution.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/governance/nonceless-execution.md b/governance/nonceless-execution.md index cbddcd164..68a0f6962 100644 --- a/governance/nonceless-execution.md +++ b/governance/nonceless-execution.md @@ -36,14 +36,30 @@ The customers for this design doc are any participants in the multisig accounts ## Proposed Solution ### Singleton -NoncelessExecutionModule is a singleton that exists at a known address on all chains and has no constructor parameters. Any Safe on any network can choose to enable the module within the Safe. No configuration is required. +The `NoncelessExecutionModule` (alternatively `UnorderedExecutionModule`, the name is important to get right for clarity) is a singleton that exists at a known address on all chains and has no constructor parameters. Any Safe on any network can choose to enable the module within the Safe. No configuration is required. ### Nonceless Module Execution Normal owner-signed executions use `execTransaction(...)`, which include the Safe’s nonce in the EIP-712 digest owners sign. This function requires the current nonce and increments it on success, with the purpose of providing replay protection and enforcing a single global ordering. -Module execution uses `execTransactionFromModule(...)` and doesn't use nonces. We use this function to an alternative execution pathway in the module with a custom replay protection mechanism. We still use the Safe logic to handle signature verification, signers should be able to sign transaction using any of the usual means. +Module execution uses `execTransactionFromModule(...)` and doesn't use nonces. We use this function to an alternative execution pathway in the module with a custom replay protection mechanism. The module leverages Safe's existing signature verification through `checkSignatures()`. Signers sign the same transaction hash they would for a normal Safe transaction, which includes the Safe's domain separator. The key difference is that instead of using the Safe's sequential nonce, the module uses the calculated hash-once value as the nonce parameter in `getTransactionHash()`. This means signers can use any existing Safe signing tools and workflows - they're signing a standard Safe transaction, just with a different nonce derivation. -For replay protection we would use and store a bytes32 hash for each transaction, rather than a uint256 value. Any hash can be executed at any time as long as it has the required signatures, and it hasn't been used before. +For replay protection, the module uses a hash-once mechanism instead of sequential nonces (i.e. number-once): + +1. **Hash Calculation**: `hashOnce = keccak256(abi.encode(hashOnceInputs))` where `hashOnceInputs` contains the `prevHashOnce` and `mixHash` fields +2. **Transaction Hash**: This `hashOnce` value is cast to `uint256` and used as the nonce parameter in Safe's `getTransactionHash()` function to generate the final transaction hash that signers sign +3. **Storage**: The resulting transaction hash is stored in `executedTransactions` mapping to prevent replay + +Any hash can be executed at any time as long as it has the required signatures and hasn't been used before. + +### Optional transaction ordering + +The module supports optional transaction dependencies through a prerequisite mechanism. When creating a transaction, signers can specify that it should only execute after a specific previous transaction has completed. + +This is implemented using the `HashOnceInputs` struct with the following fields: +- `prevHashOnce`: Set to zero for independent transactions, or to the transaction hash of a required predecessor +- `mixHash`: Additional entropy to ensure hash uniqueness + +When `prevHashOnce` is non-zero, the module validates that the referenced transaction has already been executed before proceeding. This enables controlled sequencing when needed (e.g., multi-step upgrades) while preserving unordered execution for independent operations. ## Non-goals @@ -59,7 +75,7 @@ The status quo of nonce ordering requires no implementation effort but negativel ## Risks & Uncertainties -- The computed transaction hashes need to not collide with an already used nonce. Using keccak256 hashes should be enought to avoid that. +- The computed transaction hashes need to not collide with an already used nonce. Using keccak256 hashes should be enough to avoid that. - Although this has very little impact on signing flows, it does significantly change transaction execution (and approval with nested safes). Hard to say how heavily it would impact on the superchain-ops repo. - Is this something that can be adopted piecemeal, ie. could we manage with safes that do and do not use this module? I think we could likely autodetect when a Safe supports nonceless execution, but more branches is still harder to maintain. - Unexpected effects due to unordered changes. @@ -67,5 +83,4 @@ The status quo of nonce ordering requires no implementation effort but negativel ## References - [Unordered Execution of Safe Transactions](https://www.notion.so/oplabs/Unordered-execution-of-Safe-transactions-20ef153ee1628054ade1e7e8beeadfef#20ef153ee162800689d1cd1268c85f91) -- Nonceless execution module (Safe-compatible): [UnorderedExecutionModule.sol](https://github.com/ethereum-optimism/optimism/blob/28f44ab50b01fb59f875c7b85d216cdce713b6dd/packages/contracts-bedrock/src/safe/UnorderedExecutionModule.sol#L1) -- [Nonceless Execution Overview (Google Slides)](https://docs.google.com/presentation/d/1utbGigIbMRA7JGcKZ9ZcUgMCdIPpLDJSwWmxNF9hBJM/edit?slide=id.g3734216eca8_4_32#slide=id.g3734216eca8_4_32) \ No newline at end of file +- Nonceless execution module (Safe-compatible): [UnorderedExecutionModule.sol](https://github.com/ethereum-optimism/optimism/blob/safer-safes/nonceless/packages/contracts-bedrock/src/safe/UnorderedExecutionModule.sol)