From b8dcd6ed136b769db26deb43d9d53615a54f835c Mon Sep 17 00:00:00 2001 From: igorroncevic <57319163+igorroncevic@users.noreply.github.com> Date: Fri, 22 May 2026 17:19:17 +0200 Subject: [PATCH 1/8] docs: add docs --- .../tutorials/arbitrate/solver/driver.md | 10 +- .../cow-protocol/tutorials/solvers/onboard.md | 2 + .../tutorials/solvers/solver-7702-delegate.md | 292 ++++++++++++++++++ 3 files changed, 300 insertions(+), 4 deletions(-) create mode 100644 docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md diff --git a/docs/cow-protocol/tutorials/arbitrate/solver/driver.md b/docs/cow-protocol/tutorials/arbitrate/solver/driver.md index 3d9aba264..206af8f11 100644 --- a/docs/cow-protocol/tutorials/arbitrate/solver/driver.md +++ b/docs/cow-protocol/tutorials/arbitrate/solver/driver.md @@ -53,9 +53,10 @@ The auctions sent to the driver by the autopilot only contain the bare minimum o But usually a solver engine requires more information than that so the driver pre-processes the auction before forwarding it to the solver engine. We also want to reduce the overall workload of a solver engine, since it's usually expensive to match an order (in terms of time, RPC requests, API calls, etc.). That process includes: -* fetching additional metadata (e.g. token decimals) -* discarding orders that can definitely not be settled (e.g. user is missing balances) -* very basic prioritization of remaining orders (e.g. orders below or close to the market price are most likely to settle) + +- fetching additional metadata (e.g. token decimals) +- discarding orders that can definitely not be settled (e.g. user is missing balances) +- very basic prioritization of remaining orders (e.g. orders below or close to the market price are most likely to settle) ### Fetching liquidity @@ -92,11 +93,12 @@ The driver can be configured to use different submission strategies which it dyn If the settlement does not expose any MEV (e.g. it executes all trades without AMMs) it's safe and most efficient to directly submit to the public mempool. However, if a settlement exposes MEV the driver would submit to an MEV-protected RPC like [MEVBlocker](https://mevblocker.io). +Solvers that need parallel settlement submission can use [Solver7702Delegate](../../solvers/solver-7702-delegate.md). It keeps the existing solver EOA as the settlement caller while auxiliary EOAs provide additional nonce lanes if the main solver EOA has pending transactions. + ### Flash Loans The user is able to create a flash loan order's hint by attaching to the `appData` the specified metadata. The autopilot reads the order and cuts it into a [fair combinatorial batch auction](../../../concepts/introduction/fair-combinatorial-auction). Then the driver fetches the `appData` by calling the orderbook with `GET /v1/app_data/` for every order and caches them in memory. The driver should include the flash loan information into the batch auction's order before sending it to the solver(s). - ```mermaid sequenceDiagram actor User diff --git a/docs/cow-protocol/tutorials/solvers/onboard.md b/docs/cow-protocol/tutorials/solvers/onboard.md index 6c3aae561..eb41b5b4a 100644 --- a/docs/cow-protocol/tutorials/solvers/onboard.md +++ b/docs/cow-protocol/tutorials/solvers/onboard.md @@ -48,6 +48,8 @@ The first step to joining the solver competition is to set up a solver. We have API specification: +Solvers that need parallel settlement submission can use [Solver7702Delegate](./solver-7702-delegate.md) to keep their existing solver EOA while adding extra submission nonce lanes. + ## 3. Joining the shadow (test) competition Once you have a solver running locally you can join the shadow competition to start testing your solver using CoW Protocol's order flow. diff --git a/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md new file mode 100644 index 000000000..8d82b91ee --- /dev/null +++ b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md @@ -0,0 +1,292 @@ +--- +sidebar_position: 11 +--- + +# Using Solver7702Delegate for parallel settlement submission + +`Solver7702Delegate` is an ERC-7702 delegation target for CoW Protocol solvers. It lets a solver keep using its existing allowlisted solver EOA, while extra submission EOAs send settlement transactions through that solver EOA. + +The main use case is parallel settlement submission. A single EOA has one nonce lane. If settlement `B` uses nonce `101`, it has to wait for the nonce of settlement `A` with nonce `100` to be mined. With `Solver7702Delegate`, each auxiliary EOA has its own nonce lane, but the settlement contract still sees the solver EOA as `msg.sender`. + +## Why use it? + +Without ERC-7702, a solver that wants parallel submission would need one of these options: + +- allowlist several solver EOAs; +- migrate to a smart contract solver account; +- keep using one EOA and accept one nonce lane. + +`Solver7702Delegate` keeps the current solver identity. The solver EOA delegates execution to the delegate contract, and a fixed set of auxiliary EOAs can call through it. + +```text +auxiliary EOA 1 -> solver EOA running Solver7702Delegate -> GPv2Settlement +auxiliary EOA 2 -> solver EOA running Solver7702Delegate -> GPv2Settlement +auxiliary EOA 3 -> solver EOA running Solver7702Delegate -> GPv2Settlement +``` + +Inside the delegate: + +```text +msg.sender = auxiliary EOA +address(this) = solver EOA +``` + +Inside `GPv2Settlement`: + +```text +msg.sender = solver EOA +``` + +This keeps settlement authorization tied to the solver EOA. + +## Call shape + +Normal settlement submission: + +```text +from = solver EOA +to = GPv2Settlement +data = GPv2Settlement.settle(...) +``` + +ERC-7702 settlement submission: + +```text +from = auxiliary EOA +to = solver EOA +data = bytes20(target) || targetCalldata +``` + +For a settlement: + +```text +target = GPv2Settlement +targetCalldata = GPv2Settlement.settle(...) +``` + +The calldata format is packed on purpose: + +```solidity +abi.encodePacked(bytes20(target), targetCalldata) +``` + +Do not use this format: + +```solidity +abi.encode(target, targetCalldata) +``` + +The first 20 bytes are parsed as the target address. The remaining bytes are forwarded as calldata. Return data and revert data are bubbled back as-is. + +## Contract model + +`Solver7702Delegate` has no normal public methods. Its interface is the constructor and `fallback()`: + +```solidity +constructor(address[5] memory approvedCallers); +fallback() external payable; +``` + +A fixed number of approved callers is set in the constructor. They are embedded into the deployed bytecode, not stored in contract storage. This keeps the hot path small and avoids mutable admin logic. + +If calldata is shorter than 20 bytes, the fallback accepts ETH and returns. Otherwise, it checks that `msg.sender` is one of the approved callers, parses the target address from the first 20 bytes, and calls the target from the solver EOA context. + +Only `CALL` is supported. `DELEGATECALL` is not supported, because the delegate already runs in the solver EOA context through ERC-7702. + +There are no events. This keeps gas lower for the submission path. + +## Setup + +The exact setup depends on whether you use the reference driver or your own driver. + +At a high level: + +1. Choose a number of auxiliary EOAs up to the limit defined in `Solver7702Delegate`. +2. Deploy `Solver7702Delegate` with those auxiliary EOAs as approved callers. +3. Have the solver EOA sign an ERC-7702 authorization pointing to the delegate. +4. Submit a transaction that includes that authorization. +5. Verify that the solver EOA now delegates to the expected delegate. +6. Configure the driver to use the auxiliary EOAs for delegated submission. + +If you use the reference driver, configure extra submission accounts for the solver. The driver treats these as EIP-7702 submission accounts and sets up the delegate and delegation during startup when the accounts are available as signers. + +```toml +[[solver]] +name = "my-solver" +endpoint = "https://solver.example" +account = "" +max-solutions-to-propose = 2 +submission-accounts = [ + "", + "", + ... +] +``` + +The solver `account` must be able to sign the ERC-7702 authorization. Submission accounts must also be signer-backed, not address-only config. + +When `submission-accounts` is set, the reference driver: + +- requires every submission account to be a signer; +- supports up to the number of submission accounts defined in `Solver7702Delegate`; +- pads unused approved caller slots with the zero address; +- deploys the delegate through [Arachnid's deterministic CREATE2 deployer](https://github.com/Arachnid/deterministic-deployment-proxy) with zero salt; +- reuses the same delegate deployment if the expected code is already present (using CREATE2 and the same constructor arguments); + +If `max-solutions-to-propose` is greater than `1`, `submission-accounts` must be configured. The driver refuses to start otherwise, because proposing multiple solutions needs parallel submission lanes. + +If you run a custom driver, it must: + +- deploy the delegate with the expected caller set; +- create the ERC-7702 authorization for the solver EOA; +- submit the authorization transaction; +- route delegated settlements with `to = solver EOA`; +- encode delegated calldata as `bytes20(target) || targetCalldata`; +- simulate the exact transaction shape before sending it. + +The reference driver sends the delegation setup as an inert zero-value transaction from the solver EOA to the zero address with the ERC-7702 authorization attached. It does not combine delegation setup with delegate deployment, because a reverted transaction can still leave the ERC-7702 authorization applied. + +## Verification + +Before using delegated submission, verify both pieces: + +1. The solver EOA delegates to the expected delegate. +2. The delegate bytecode matches the expected caller set. + +For ERC-7702, delegated account code has this shape: + +```text +0xef0100 || delegateAddress +``` + +So the solver EOA code should be 23 bytes: + +```text +0xef0100<20-byte delegate address> +``` + +The delegate bytecode must also be checked. Because approved callers are immutable constructor values, each solver's deployed runtime bytecode can be different. Do not only check that the delegate address has code. Compute the expected runtime bytecode from: + +- the official `Solver7702Delegate` artifact; +- the compiler settings; +- the approved caller addresses. + +Then compare that expected runtime bytecode, or its hash, with `eth_getCode(delegateAddress)`. + +## How the driver should submit + +Prefer direct submission when the solver EOA is idle: + +```text +from = solver EOA +to = GPv2Settlement +data = settle(...) +``` + +Use delegated submission when the solver EOA already has a pending transaction and parallel submission is useful: + +```text +from = auxiliary EOA +to = solver EOA +data = bytes20(GPv2Settlement) || settle(...) +``` + +Each auxiliary EOA has its own nonce lane. Do not send more than one transaction from the same auxiliary EOA unless you intentionally want nonce ordering for that account. + +The driver should simulate the same transaction shape it will submit. For delegated submission, that means simulating with: + +- `from = auxiliary EOA`; +- `to = solver EOA`; +- `data = bytes20(target) || targetCalldata`; +- the solver EOA already delegated to the expected `Solver7702Delegate`. + +## Funding + +Auxiliary EOAs pay gas. The delegate does not fund them. + +If an auxiliary EOA is underfunded: + +- skip it; +- alert the operator; +- use another idle funded account; +- fall back to direct submission if that is safe; +- otherwise wait. + +## Replacing callers + +Approved callers cannot be changed on an existing delegate. To replace any auxiliary EOA: + +1. Deploy a new `Solver7702Delegate` with the new caller set. +2. Have the solver EOA sign a new ERC-7702 authorization to the new delegate. +3. Submit the replacement authorization transaction. +4. Verify the solver EOA code is `0xef0100 || newDelegate`. +5. Verify the new delegate runtime bytecode matches the new caller set. +6. Update driver config and monitoring. +7. Treat the old delegate as deprecated. + +The old delegate remains on-chain, but it has no power unless the solver EOA delegates to it. + +## Revoking delegation + +To clear ERC-7702 delegation: + +1. Have the solver EOA sign an ERC-7702 authorization to the zero address. +2. Submit a transaction with that authorization. +3. Verify that the solver EOA no longer has delegated code. +4. Disable delegated submission in the driver. +5. Fall back to direct solver EOA submission. + +Revocation is useful when auxiliary submission is no longer needed, or when the caller set cannot be safely replaced immediately. + +## Compromised auxiliary key response + +Treat a compromised auxiliary EOA as severe. An approved auxiliary EOA can trigger arbitrary calls from the solver EOA context until it is removed. + +Recommended response: + +1. Disable ERC-7702 submission for that solver. +2. Consider disabling the solver while you assess the risk. +3. Deploy a new `Solver7702Delegate` without the compromised caller. +4. Have the solver EOA authorize the new delegate. +5. Verify delegation and delegate bytecode. +6. Move funds and revoke approvals from the solver EOA if needed. +7. Mark the old delegate/config as deprecated in monitoring. + +If replacement cannot be done quickly, clear the solver EOA delegation and use direct submission only. + +## Warnings + +Approved auxiliary EOAs are trusted hot keys. They can cause arbitrary calls from the solver EOA context. That includes token transfers, approvals, protocol interactions, and ETH transfers if the solver EOA holds funds. + +Use these safeguards: + +- do not share auxiliary EOAs across solvers; +- keep solver EOA funds and approvals minimal; +- monitor auxiliary keys and delegated calls; +- rotate callers immediately if a key is compromised; +- only enable this on chains and infrastructure that support ERC-7702 transaction authorization handling; +- fall back to direct solver EOA submission when ERC-7702 is not supported. + +`Solver7702Delegate` does not implement ERC-721 or ERC-1155 receiver functions. It is meant for settlement submission, not for receiving NFTs. + +## FAQ + +### How many auxiliary EOAs are supported? + +Version 1 supports up to five immutable approved caller slots. + +### Can the delegate call only `GPv2Settlement`? + +No. It supports arbitrary targets. The driver should normally use `GPv2Settlement` as the target for settlement submissions. + +### Can an auxiliary EOA drain funds? + +The contract does not prevent that. Approved auxiliary EOAs are trusted execution keys. Keep funds and approvals on the solver EOA as small as possible. + +### What happens when all auxiliary EOAs are busy? + +The driver should wait or queue until one lane is idle. It should not reuse the same auxiliary EOA unless nonce ordering is intended. + +### Should direct submission still be used? + +Yes. Direct submission is cheaper and simpler when the solver EOA is idle. Delegated submission is useful when parallel settlement submission adds value. From becef2464528d4e96496423bfb5485245c3c4747 Mon Sep 17 00:00:00 2001 From: igorroncevic <57319163+igorroncevic@users.noreply.github.com> Date: Mon, 25 May 2026 11:13:34 +0200 Subject: [PATCH 2/8] docs: clarify 7702 self-broadcast auth nonce --- docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md index 8d82b91ee..836cf4ede 100644 --- a/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md +++ b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md @@ -140,12 +140,15 @@ If you run a custom driver, it must: - deploy the delegate with the expected caller set; - create the ERC-7702 authorization for the solver EOA; - submit the authorization transaction; +- sign the authorization for the next nonce if the solver EOA also sends the authorization transaction; - route delegated settlements with `to = solver EOA`; - encode delegated calldata as `bytes20(target) || targetCalldata`; - simulate the exact transaction shape before sending it. The reference driver sends the delegation setup as an inert zero-value transaction from the solver EOA to the zero address with the ERC-7702 authorization attached. It does not combine delegation setup with delegate deployment, because a reverted transaction can still leave the ERC-7702 authorization applied. +With Foundry, this means using `cast wallet sign-auth --self-broadcast` when the solver EOA submits its own authorization transaction. Do not use `--self-broadcast` when a different funded EOA submits that transaction. + ## Verification Before using delegated submission, verify both pieces: From 0f1937921b403191aecaa05e04ec3b630f006640 Mon Sep 17 00:00:00 2001 From: igorroncevic <57319163+igorroncevic@users.noreply.github.com> Date: Mon, 25 May 2026 17:02:33 +0200 Subject: [PATCH 3/8] docs: address solver driver wording --- docs/cow-protocol/tutorials/arbitrate/solver/driver.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cow-protocol/tutorials/arbitrate/solver/driver.md b/docs/cow-protocol/tutorials/arbitrate/solver/driver.md index 206af8f11..530672471 100644 --- a/docs/cow-protocol/tutorials/arbitrate/solver/driver.md +++ b/docs/cow-protocol/tutorials/arbitrate/solver/driver.md @@ -55,7 +55,7 @@ We also want to reduce the overall workload of a solver engine, since it's usual That process includes: - fetching additional metadata (e.g. token decimals) -- discarding orders that can definitely not be settled (e.g. user is missing balances) +- discarding orders that cannot be settled (e.g. user is missing balances) - very basic prioritization of remaining orders (e.g. orders below or close to the market price are most likely to settle) ### Fetching liquidity From a3aa8ac9c6b467e69adae75e4a14890e4ba91a05 Mon Sep 17 00:00:00 2001 From: igorroncevic <57319163+igorroncevic@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:16:09 +0200 Subject: [PATCH 4/8] update README.md --- .../tutorials/arbitrate/solver/driver.md | 2 +- .../cow-protocol/tutorials/solvers/onboard.md | 2 +- .../tutorials/solvers/solver-7702-delegate.md | 334 ++++++------------ 3 files changed, 103 insertions(+), 235 deletions(-) diff --git a/docs/cow-protocol/tutorials/arbitrate/solver/driver.md b/docs/cow-protocol/tutorials/arbitrate/solver/driver.md index 530672471..3e920f58a 100644 --- a/docs/cow-protocol/tutorials/arbitrate/solver/driver.md +++ b/docs/cow-protocol/tutorials/arbitrate/solver/driver.md @@ -93,7 +93,7 @@ The driver can be configured to use different submission strategies which it dyn If the settlement does not expose any MEV (e.g. it executes all trades without AMMs) it's safe and most efficient to directly submit to the public mempool. However, if a settlement exposes MEV the driver would submit to an MEV-protected RPC like [MEVBlocker](https://mevblocker.io). -Solvers that need parallel settlement submission can use [Solver7702Delegate](../../solvers/solver-7702-delegate.md). It keeps the existing solver EOA as the settlement caller while auxiliary EOAs provide additional nonce lanes if the main solver EOA has pending transactions. +Solvers that expect real settlement volume should set up [Solver7702Delegate](../../solvers/solver-7702-delegate.md) early. It keeps the existing solver EOA as the settlement caller while auxiliary EOAs provide additional nonce lanes when the solver EOA has pending transactions. ### Flash Loans diff --git a/docs/cow-protocol/tutorials/solvers/onboard.md b/docs/cow-protocol/tutorials/solvers/onboard.md index eb41b5b4a..5fe9d1578 100644 --- a/docs/cow-protocol/tutorials/solvers/onboard.md +++ b/docs/cow-protocol/tutorials/solvers/onboard.md @@ -48,7 +48,7 @@ The first step to joining the solver competition is to set up a solver. We have API specification: -Solvers that need parallel settlement submission can use [Solver7702Delegate](./solver-7702-delegate.md) to keep their existing solver EOA while adding extra submission nonce lanes. +Solvers that expect real settlement volume should set up [Solver7702Delegate](./solver-7702-delegate.md) early. It keeps the existing solver EOA while adding extra submission nonce lanes for parallel settlement submission. ## 3. Joining the shadow (test) competition diff --git a/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md index 836cf4ede..ac8f72bfe 100644 --- a/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md +++ b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md @@ -4,292 +4,160 @@ sidebar_position: 11 # Using Solver7702Delegate for parallel settlement submission -`Solver7702Delegate` is an ERC-7702 delegation target for CoW Protocol solvers. It lets a solver keep using its existing allowlisted solver EOA, while extra submission EOAs send settlement transactions through that solver EOA. +`Solver7702Delegate` lets a solver keep its existing allowlisted solver EOA while using auxiliary EOAs as extra submission nonce lanes. -The main use case is parallel settlement submission. A single EOA has one nonce lane. If settlement `B` uses nonce `101`, it has to wait for the nonce of settlement `A` with nonce `100` to be mined. With `Solver7702Delegate`, each auxiliary EOA has its own nonce lane, but the settlement contract still sees the solver EOA as `msg.sender`. +This is strongly recommended for solvers that expect real volume. With one EOA, a pending settlement can block every later settlement behind the same nonce lane. With `Solver7702Delegate`, auxiliary EOAs can submit in parallel, while `GPv2Settlement` still sees the solver EOA as `msg.sender`. -## Why use it? +## Reference driver setup -Without ERC-7702, a solver that wants parallel submission would need one of these options: - -- allowlist several solver EOAs; -- migrate to a smart contract solver account; -- keep using one EOA and accept one nonce lane. - -`Solver7702Delegate` keeps the current solver identity. The solver EOA delegates execution to the delegate contract, and a fixed set of auxiliary EOAs can call through it. - -```text -auxiliary EOA 1 -> solver EOA running Solver7702Delegate -> GPv2Settlement -auxiliary EOA 2 -> solver EOA running Solver7702Delegate -> GPv2Settlement -auxiliary EOA 3 -> solver EOA running Solver7702Delegate -> GPv2Settlement -``` - -Inside the delegate: - -```text -msg.sender = auxiliary EOA -address(this) = solver EOA -``` - -Inside `GPv2Settlement`: - -```text -msg.sender = solver EOA -``` - -This keeps settlement authorization tied to the solver EOA. - -## Call shape - -Normal settlement submission: - -```text -from = solver EOA -to = GPv2Settlement -data = GPv2Settlement.settle(...) -``` - -ERC-7702 settlement submission: - -```text -from = auxiliary EOA -to = solver EOA -data = bytes20(target) || targetCalldata -``` - -For a settlement: - -```text -target = GPv2Settlement -targetCalldata = GPv2Settlement.settle(...) -``` - -The calldata format is packed on purpose: - -```solidity -abi.encodePacked(bytes20(target), targetCalldata) -``` - -Do not use this format: - -```solidity -abi.encode(target, targetCalldata) -``` - -The first 20 bytes are parsed as the target address. The remaining bytes are forwarded as calldata. Return data and revert data are bubbled back as-is. - -## Contract model - -`Solver7702Delegate` has no normal public methods. Its interface is the constructor and `fallback()`: - -```solidity -constructor(address[5] memory approvedCallers); -fallback() external payable; -``` - -A fixed number of approved callers is set in the constructor. They are embedded into the deployed bytecode, not stored in contract storage. This keeps the hot path small and avoids mutable admin logic. - -If calldata is shorter than 20 bytes, the fallback accepts ETH and returns. Otherwise, it checks that `msg.sender` is one of the approved callers, parses the target address from the first 20 bytes, and calls the target from the solver EOA context. - -Only `CALL` is supported. `DELEGATECALL` is not supported, because the delegate already runs in the solver EOA context through ERC-7702. - -There are no events. This keeps gas lower for the submission path. - -## Setup - -The exact setup depends on whether you use the reference driver or your own driver. - -At a high level: - -1. Choose a number of auxiliary EOAs up to the limit defined in `Solver7702Delegate`. -2. Deploy `Solver7702Delegate` with those auxiliary EOAs as approved callers. -3. Have the solver EOA sign an ERC-7702 authorization pointing to the delegate. -4. Submit a transaction that includes that authorization. -5. Verify that the solver EOA now delegates to the expected delegate. -6. Configure the driver to use the auxiliary EOAs for delegated submission. - -If you use the reference driver, configure extra submission accounts for the solver. The driver treats these as EIP-7702 submission accounts and sets up the delegate and delegation during startup when the accounts are available as signers. +If you use the reference driver, add `submission-accounts` to the solver entry in your driver config. This is the main setup path for most solvers. ```toml [[solver]] name = "my-solver" endpoint = "https://solver.example" account = "" -max-solutions-to-propose = 2 +max-solutions-to-propose = 6 # solver EOA + N auxiliary EOAs submission-accounts = [ "", "", - ... + "", + "", + "" ] ``` -The solver `account` must be able to sign the ERC-7702 authorization. Submission accounts must also be signer-backed, not address-only config. - -When `submission-accounts` is set, the reference driver: +The solver `account` must be able to sign the ERC-7702 authorization. Each `submission-accounts` entry must also be signer with a private key, not just an address. -- requires every submission account to be a signer; -- supports up to the number of submission accounts defined in `Solver7702Delegate`; -- pads unused approved caller slots with the zero address; -- deploys the delegate through [Arachnid's deterministic CREATE2 deployer](https://github.com/Arachnid/deterministic-deployment-proxy) with zero salt; -- reuses the same delegate deployment if the expected code is already present (using CREATE2 and the same constructor arguments); +Fund each auxiliary EOA with native token for gas, as they will be used to submit transactions separately from the solver EOA. -If `max-solutions-to-propose` is greater than `1`, `submission-accounts` must be configured. The driver refuses to start otherwise, because proposing multiple solutions needs parallel submission lanes. +When `submission-accounts` is configured, the reference driver: -If you run a custom driver, it must: +- sets up `Solver7702Delegate` during startup when the required signers are available; +- uses the auxiliary accounts as extra settlement nonce lanes, when solver EOA is busy; +- reuses the expected delegate deployment when the same code is already present; +- refuses to start with `max-solutions-to-propose > 1` unless submission accounts are configured. -- deploy the delegate with the expected caller set; -- create the ERC-7702 authorization for the solver EOA; -- submit the authorization transaction; -- sign the authorization for the next nonce if the solver EOA also sends the authorization transaction; -- route delegated settlements with `to = solver EOA`; -- encode delegated calldata as `bytes20(target) || targetCalldata`; -- simulate the exact transaction shape before sending it. +## What changes when submitting -The reference driver sends the delegation setup as an inert zero-value transaction from the solver EOA to the zero address with the ERC-7702 authorization attached. It does not combine delegation setup with delegate deployment, because a reverted transaction can still leave the ERC-7702 authorization applied. +Direct submission should still be used when the solver EOA is free. Delegated submission is useful when the solver EOA already has a pending transaction and another settlement should be submitted without waiting for that nonce. -With Foundry, this means using `cast wallet sign-auth --self-broadcast` when the solver EOA submits its own authorization transaction. Do not use `--self-broadcast` when a different funded EOA submits that transaction. +```mermaid +flowchart LR + SolverEOA{"Solver EOA"} + DirectTx["tx.from = solver EOA
tx.to = GPv2Settlement
tx.data = settle(...)"] + AuxEOAs{"Auxiliary EOAs
0...N"} + DelegatedTx["tx.from = auxiliary EOA
tx.to = solver EOA
tx.data = bytes20(target)
+ targetCalldata"] + DelegatedSolver["Solver EOA running
Solver7702Delegate"] + TargetCall["target = GPv2Settlement
targetCalldata = settle(...)"] + Settlement["GPv2Settlement"] -## Verification + SolverEOA --> DirectTx --> Settlement + AuxEOAs --> DelegatedTx --> DelegatedSolver --> TargetCall --> Settlement -Before using delegated submission, verify both pieces: - -1. The solver EOA delegates to the expected delegate. -2. The delegate bytecode matches the expected caller set. - -For ERC-7702, delegated account code has this shape: - -```text -0xef0100 || delegateAddress + classDef eoa fill:#fff3bf,stroke:#b08900,color:#1f2937 + classDef tx fill:#f3f0ff,stroke:#7048e8,color:#1f2937 + classDef contract fill:#1864ab,stroke:#0b3558,stroke-width:3px,color:#ffffff,font-weight:bold + class SolverEOA,AuxEOAs eoa + class DirectTx,DelegatedTx,TargetCall tx + class DelegatedSolver,Settlement contract ``` -So the solver EOA code should be 23 bytes: - -```text -0xef0100<20-byte delegate address> -``` +Inside the delegate, `msg.sender` is the auxiliary EOA and `address(this)` is the solver EOA. Inside `GPv2Settlement`, `msg.sender` is still the solver EOA. -The delegate bytecode must also be checked. Because approved callers are immutable constructor values, each solver's deployed runtime bytecode can be different. Do not only check that the delegate address has code. Compute the expected runtime bytecode from: +The calldata format is packed on purpose. Use `abi.encodePacked(bytes20(target), targetCalldata)`. Do not use `abi.encode(target, targetCalldata)`. -- the official `Solver7702Delegate` artifact; -- the compiler settings; -- the approved caller addresses. +## Verification -Then compare that expected runtime bytecode, or its hash, with `eth_getCode(delegateAddress)`. +Before using delegated submission, verify both pieces: -## How the driver should submit +1. The solver EOA delegates to the expected delegate. +2. The delegate bytecode matches the expected approved caller set. -Prefer direct submission when the solver EOA is idle: +Check the solver EOA code: -```text -from = solver EOA -to = GPv2Settlement -data = settle(...) +```shell +cast code --rpc-url ``` -Use delegated submission when the solver EOA already has a pending transaction and parallel submission is useful: +For ERC-7702, delegated account code has this shape: ```text -from = auxiliary EOA -to = solver EOA -data = bytes20(GPv2Settlement) || settle(...) +0xef0100 || delegateAddress ``` -Each auxiliary EOA has its own nonce lane. Do not send more than one transaction from the same auxiliary EOA unless you intentionally want nonce ordering for that account. - -The driver should simulate the same transaction shape it will submit. For delegated submission, that means simulating with: - -- `from = auxiliary EOA`; -- `to = solver EOA`; -- `data = bytes20(target) || targetCalldata`; -- the solver EOA already delegated to the expected `Solver7702Delegate`. - -## Funding - -Auxiliary EOAs pay gas. The delegate does not fund them. - -If an auxiliary EOA is underfunded: - -- skip it; -- alert the operator; -- use another idle funded account; -- fall back to direct submission if that is safe; -- otherwise wait. - -## Replacing callers - -Approved callers cannot be changed on an existing delegate. To replace any auxiliary EOA: - -1. Deploy a new `Solver7702Delegate` with the new caller set. -2. Have the solver EOA sign a new ERC-7702 authorization to the new delegate. -3. Submit the replacement authorization transaction. -4. Verify the solver EOA code is `0xef0100 || newDelegate`. -5. Verify the new delegate runtime bytecode matches the new caller set. -6. Update driver config and monitoring. -7. Treat the old delegate as deprecated. +The delegate bytecode check matters because approved callers are immutable constructor values. Do not only check that the delegate address has code. -The old delegate remains on-chain, but it has no power unless the solver EOA delegates to it. +## Manual cast commands -## Revoking delegation +Most solvers should use the reference driver setup above. Use these commands only if you are setting up delegation manually and/or building a custom driver. -To clear ERC-7702 delegation: +**To authorize a delegate when the solver EOA sends its own authorization transaction, sign with `--self-broadcast`**: -1. Have the solver EOA sign an ERC-7702 authorization to the zero address. -2. Submit a transaction with that authorization. -3. Verify that the solver EOA no longer has delegated code. -4. Disable delegated submission in the driver. -5. Fall back to direct solver EOA submission. +```shell +cast wallet sign-auth \ + --private-key \ + --rpc-url \ + --chain \ + --self-broadcast -Revocation is useful when auxiliary submission is no longer needed, or when the caller set cannot be safely replaced immediately. - -## Compromised auxiliary key response - -Treat a compromised auxiliary EOA as severe. An approved auxiliary EOA can trigger arbitrary calls from the solver EOA context until it is removed. - -Recommended response: - -1. Disable ERC-7702 submission for that solver. -2. Consider disabling the solver while you assess the risk. -3. Deploy a new `Solver7702Delegate` without the compromised caller. -4. Have the solver EOA authorize the new delegate. -5. Verify delegation and delegate bytecode. -6. Move funds and revoke approvals from the solver EOA if needed. -7. Mark the old delegate/config as deprecated in monitoring. - -If replacement cannot be done quickly, clear the solver EOA delegation and use direct submission only. - -## Warnings - -Approved auxiliary EOAs are trusted hot keys. They can cause arbitrary calls from the solver EOA context. That includes token transfers, approvals, protocol interactions, and ETH transfers if the solver EOA holds funds. +cast send 0x0000000000000000000000000000000000000000 \ + --auth \ + --private-key \ + --rpc-url \ + --chain +``` -Use these safeguards: +**If a different funded account sends either transaction, do not use `--self-broadcast` when signing.** The solver EOA signs the authorization, but the funded account pays gas and submits the transaction: -- do not share auxiliary EOAs across solvers; -- keep solver EOA funds and approvals minimal; -- monitor auxiliary keys and delegated calls; -- rotate callers immediately if a key is compromised; -- only enable this on chains and infrastructure that support ERC-7702 transaction authorization handling; -- fall back to direct solver EOA submission when ERC-7702 is not supported. +```shell +cast wallet sign-auth \ + --private-key \ + --rpc-url \ + --chain -`Solver7702Delegate` does not implement ERC-721 or ERC-1155 receiver functions. It is meant for settlement submission, not for receiving NFTs. +cast send 0x0000000000000000000000000000000000000000 \ + --auth \ + --private-key \ + --rpc-url \ + --chain +``` -## FAQ +To revoke delegation, sign an authorization to the zero address: -### How many auxiliary EOAs are supported? +```shell +cast wallet sign-auth 0x0000000000000000000000000000000000000000 \ + --private-key \ + --rpc-url \ + --chain \ + --self-broadcast -Version 1 supports up to five immutable approved caller slots. +cast send 0x0000000000000000000000000000000000000000 \ + --auth \ + --private-key \ + --rpc-url \ + --chain +``` -### Can the delegate call only `GPv2Settlement`? +## Custom driver requirements -No. It supports arbitrary targets. The driver should normally use `GPv2Settlement` as the target for settlement submissions. +If you do not use the reference driver, your driver must: -### Can an auxiliary EOA drain funds? +- deploy `Solver7702Delegate` for the approved auxiliary caller set; +- have the solver EOA delegate to the deployed `Solver7702Delegate`; +- route delegated settlement transactions with `from = auxiliary EOA` and `to = solver EOA` (if solver EOA is busy); +- encode delegated calldata as `bytes20(target) || targetCalldata`. -The contract does not prevent that. Approved auxiliary EOAs are trusted execution keys. Keep funds and approvals on the solver EOA as small as possible. +## Capabilities and limits -### What happens when all auxiliary EOAs are busy? +- Version 1 supports up to five immutable approved caller slots. +- Approved auxiliary EOAs are trusted hot keys. They can trigger arbitrary calls as the solver EOA. +- Changing authorized auxiliary accounts requires redeploying the delegate and re-delegating the solver EOA. +- The delegate can call arbitrary targets. The driver should normally use `GPv2Settlement` for settlement submissions. +- Use this only on chains and infrastructure that support ERC-7702 transaction authorization handling. -The driver should wait or queue until one lane is idle. It should not reuse the same auxiliary EOA unless nonce ordering is intended. +Keep solver EOA funds and approvals minimal, do not share auxiliary EOAs across solvers, and rotate callers immediately if an auxiliary key is compromised. -### Should direct submission still be used? +## More details -Yes. Direct submission is cheaper and simpler when the solver EOA is idle. Delegated submission is useful when parallel settlement submission adds value. +For exact manual deployment, authorization, revocation, bytecode verification, and operational procedures, use the [`Solver7702Delegate` README](https://github.com/cowprotocol/solver-7702-delegate). From d313bd42915ed39e485f22a6875ee90eb8c4d584 Mon Sep 17 00:00:00 2001 From: igorroncevic <57319163+igorroncevic@users.noreply.github.com> Date: Thu, 18 Jun 2026 13:14:25 +0200 Subject: [PATCH 5/8] simplify --- .../tutorials/solvers/solver-7702-delegate.md | 123 ++++-------------- 1 file changed, 25 insertions(+), 98 deletions(-) diff --git a/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md index ac8f72bfe..5cc317ff3 100644 --- a/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md +++ b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md @@ -1,23 +1,30 @@ --- sidebar_position: 11 +description: Configure Solver7702Delegate and ERC-7702 auxiliary accounts for parallel settlement submission. +keywords: + - Solver7702Delegate + - solver 7702 delegate + - ERC-7702 + - EIP-7702 + - parallel settlement submission --- -# Using Solver7702Delegate for parallel settlement submission +# Parallel Settlement Submission -`Solver7702Delegate` lets a solver keep its existing allowlisted solver EOA while using auxiliary EOAs as extra submission nonce lanes. +`Solver7702Delegate` lets a solver keep its existing allowlisted EOA and use auxiliary EOAs as additional nonce lanes for settlement submission. -This is strongly recommended for solvers that expect real volume. With one EOA, a pending settlement can block every later settlement behind the same nonce lane. With `Solver7702Delegate`, auxiliary EOAs can submit in parallel, while `GPv2Settlement` still sees the solver EOA as `msg.sender`. +Solvers expecting production volume should set this up early. With one EOA, a pending transaction can block every settlement behind it. Auxiliary EOAs can submit in parallel, while `GPv2Settlement` still sees the solver EOA as `msg.sender`. ## Reference driver setup -If you use the reference driver, add `submission-accounts` to the solver entry in your driver config. This is the main setup path for most solvers. +If you use the reference driver, add `submission-accounts` to the solver entry in your driver config. This is all most solvers need to configure. ```toml [[solver]] name = "my-solver" endpoint = "https://solver.example" account = "" -max-solutions-to-propose = 6 # solver EOA + N auxiliary EOAs +max-solutions-to-propose = 6 # solver EOA + 5 auxiliary EOAs submission-accounts = [ "", "", @@ -27,28 +34,23 @@ submission-accounts = [ ] ``` -The solver `account` must be able to sign the ERC-7702 authorization. Each `submission-accounts` entry must also be signer with a private key, not just an address. +The solver `account` must be able to sign the ERC-7702 authorization. Each `submission-accounts` entry must also include signing credentials, not only an address. -Fund each auxiliary EOA with native token for gas, as they will be used to submit transactions separately from the solver EOA. +Fund each auxiliary EOA with the chain's native token so it can pay gas. -When `submission-accounts` is configured, the reference driver: - -- sets up `Solver7702Delegate` during startup when the required signers are available; -- uses the auxiliary accounts as extra settlement nonce lanes, when solver EOA is busy; -- reuses the expected delegate deployment when the same code is already present; -- refuses to start with `max-solutions-to-propose > 1` unless submission accounts are configured. +At startup, the reference driver deploys `Solver7702Delegate` at the expected CREATE2 address, or reuses the existing deployment at that address. When the solver EOA is busy, it uses the auxiliary accounts to submit settlements through separate nonce lanes. ## What changes when submitting -Direct submission should still be used when the solver EOA is free. Delegated submission is useful when the solver EOA already has a pending transaction and another settlement should be submitted without waiting for that nonce. +When the solver EOA is free, it submits directly to `GPv2Settlement`. If it already has a pending transaction, an auxiliary EOA can submit to the solver EOA instead. The solver EOA runs `Solver7702Delegate`, which forwards the call to `GPv2Settlement`. ```mermaid flowchart LR SolverEOA{"Solver EOA"} - DirectTx["tx.from = solver EOA
tx.to = GPv2Settlement
tx.data = settle(...)"] + DirectTx["tx.data = settle(...)"] AuxEOAs{"Auxiliary EOAs
0...N"} - DelegatedTx["tx.from = auxiliary EOA
tx.to = solver EOA
tx.data = bytes20(target)
+ targetCalldata"] - DelegatedSolver["Solver EOA running
Solver7702Delegate"] + DelegatedTx["tx.data = bytes20(target)
|| targetCalldata"] + DelegatedSolver["Solver EOA
delegated to Solver7702Delegate"] TargetCall["target = GPv2Settlement
targetCalldata = settle(...)"] Settlement["GPv2Settlement"] @@ -63,101 +65,26 @@ flowchart LR class DelegatedSolver,Settlement contract ``` -Inside the delegate, `msg.sender` is the auxiliary EOA and `address(this)` is the solver EOA. Inside `GPv2Settlement`, `msg.sender` is still the solver EOA. - The calldata format is packed on purpose. Use `abi.encodePacked(bytes20(target), targetCalldata)`. Do not use `abi.encode(target, targetCalldata)`. ## Verification -Before using delegated submission, verify both pieces: - -1. The solver EOA delegates to the expected delegate. -2. The delegate bytecode matches the expected approved caller set. - -Check the solver EOA code: +First, check that the solver EOA points to the expected delegate: ```shell cast code --rpc-url ``` -For ERC-7702, delegated account code has this shape: +For ERC-7702, the code has this form: ```text -0xef0100 || delegateAddress -``` - -The delegate bytecode check matters because approved callers are immutable constructor values. Do not only check that the delegate address has code. - -## Manual cast commands - -Most solvers should use the reference driver setup above. Use these commands only if you are setting up delegation manually and/or building a custom driver. - -**To authorize a delegate when the solver EOA sends its own authorization transaction, sign with `--self-broadcast`**: - -```shell -cast wallet sign-auth \ - --private-key \ - --rpc-url \ - --chain \ - --self-broadcast - -cast send 0x0000000000000000000000000000000000000000 \ - --auth \ - --private-key \ - --rpc-url \ - --chain +0xef0100 || delegate_address ``` -**If a different funded account sends either transaction, do not use `--self-broadcast` when signing.** The solver EOA signs the authorization, but the funded account pays gas and submits the transaction: - -```shell -cast wallet sign-auth \ - --private-key \ - --rpc-url \ - --chain - -cast send 0x0000000000000000000000000000000000000000 \ - --auth \ - --private-key \ - --rpc-url \ - --chain -``` - -To revoke delegation, sign an authorization to the zero address: - -```shell -cast wallet sign-auth 0x0000000000000000000000000000000000000000 \ - --private-key \ - --rpc-url \ - --chain \ - --self-broadcast - -cast send 0x0000000000000000000000000000000000000000 \ - --auth \ - --private-key \ - --rpc-url \ - --chain -``` - -## Custom driver requirements - -If you do not use the reference driver, your driver must: - -- deploy `Solver7702Delegate` for the approved auxiliary caller set; -- have the solver EOA delegate to the deployed `Solver7702Delegate`; -- route delegated settlement transactions with `from = auxiliary EOA` and `to = solver EOA` (if solver EOA is busy); -- encode delegated calldata as `bytes20(target) || targetCalldata`. - -## Capabilities and limits - -- Version 1 supports up to five immutable approved caller slots. -- Approved auxiliary EOAs are trusted hot keys. They can trigger arbitrary calls as the solver EOA. -- Changing authorized auxiliary accounts requires redeploying the delegate and re-delegating the solver EOA. -- The delegate can call arbitrary targets. The driver should normally use `GPv2Settlement` for settlement submissions. -- Use this only on chains and infrastructure that support ERC-7702 transaction authorization handling. +On a block explorer, the solver EOA may not have a normal contract code view. Confirm that its **Delegated to** banner points to the expected address, then open that address and verify its source as `Solver7702Delegate`. -Keep solver EOA funds and approvals minimal, do not share auxiliary EOAs across solvers, and rotate callers immediately if an auxiliary key is compromised. +See the README's [verification steps](https://github.com/cowprotocol/solver-7702-delegate#verify-delegation) for details. ## More details -For exact manual deployment, authorization, revocation, bytecode verification, and operational procedures, use the [`Solver7702Delegate` README](https://github.com/cowprotocol/solver-7702-delegate). +For manual deployment, authorization, revocation, verification, and operational details, use the [`Solver7702Delegate` README](https://github.com/cowprotocol/solver-7702-delegate#usage). From f29c474b46855fbfcfbc1ade546a40b0e1fbe267 Mon Sep 17 00:00:00 2001 From: igorroncevic <57319163+igorroncevic@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:11:36 +0200 Subject: [PATCH 6/8] Address solver 7702 docs review feedback --- docs/cow-protocol/tutorials/arbitrate/solver/driver.md | 2 +- docs/cow-protocol/tutorials/solvers/onboard.md | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/cow-protocol/tutorials/arbitrate/solver/driver.md b/docs/cow-protocol/tutorials/arbitrate/solver/driver.md index 3e920f58a..057793960 100644 --- a/docs/cow-protocol/tutorials/arbitrate/solver/driver.md +++ b/docs/cow-protocol/tutorials/arbitrate/solver/driver.md @@ -93,7 +93,7 @@ The driver can be configured to use different submission strategies which it dyn If the settlement does not expose any MEV (e.g. it executes all trades without AMMs) it's safe and most efficient to directly submit to the public mempool. However, if a settlement exposes MEV the driver would submit to an MEV-protected RPC like [MEVBlocker](https://mevblocker.io). -Solvers that expect real settlement volume should set up [Solver7702Delegate](../../solvers/solver-7702-delegate.md) early. It keeps the existing solver EOA as the settlement caller while auxiliary EOAs provide additional nonce lanes when the solver EOA has pending transactions. +Production solvers using the reference driver should configure [Solver7702Delegate](../../solvers/solver-7702-delegate.md) during initial driver setup. A single pending solver EOA transaction can delay later settlements; auxiliary EOAs provide additional nonce lanes while `GPv2Settlement` still sees the solver EOA as the settlement caller. ### Flash Loans diff --git a/docs/cow-protocol/tutorials/solvers/onboard.md b/docs/cow-protocol/tutorials/solvers/onboard.md index 5fe9d1578..6c3aae561 100644 --- a/docs/cow-protocol/tutorials/solvers/onboard.md +++ b/docs/cow-protocol/tutorials/solvers/onboard.md @@ -48,8 +48,6 @@ The first step to joining the solver competition is to set up a solver. We have API specification: -Solvers that expect real settlement volume should set up [Solver7702Delegate](./solver-7702-delegate.md) early. It keeps the existing solver EOA while adding extra submission nonce lanes for parallel settlement submission. - ## 3. Joining the shadow (test) competition Once you have a solver running locally you can join the shadow competition to start testing your solver using CoW Protocol's order flow. From df2a17cbd54ea3255c76909c6c918e7dd0c9b391 Mon Sep 17 00:00:00 2001 From: igorroncevic <57319163+igorroncevic@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:14:34 +0200 Subject: [PATCH 7/8] Document solver 7702 account risks --- .../tutorials/solvers/solver-7702-delegate.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md index 5cc317ff3..697af3fca 100644 --- a/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md +++ b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md @@ -38,6 +38,14 @@ The solver `account` must be able to sign the ERC-7702 authorization. Each `subm Fund each auxiliary EOA with the chain's native token so it can pay gas. +:::warning + +Treat auxiliary EOAs as operationally sensitive accounts. Any approved auxiliary EOA can submit settlements through the solver EOA while the delegation is active. Keep their keys in the same security setup as the solver EOA, monitor their native-token balances, and make sure the team responsible for the solver EOA is also responsible for these accounts. + +If an auxiliary key is compromised, rotate the delegation by configuring a new approved caller set and re-delegating from the solver EOA. + +::: + At startup, the reference driver deploys `Solver7702Delegate` at the expected CREATE2 address, or reuses the existing deployment at that address. When the solver EOA is busy, it uses the auxiliary accounts to submit settlements through separate nonce lanes. ## What changes when submitting From 36d4c4bba69fcc5afb247975c3d16432d46abd27 Mon Sep 17 00:00:00 2001 From: igorroncevic <57319163+igorroncevic@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:18:23 +0200 Subject: [PATCH 8/8] Move solver 7702 risk warning --- .../tutorials/solvers/solver-7702-delegate.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md index 697af3fca..73f7b651d 100644 --- a/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md +++ b/docs/cow-protocol/tutorials/solvers/solver-7702-delegate.md @@ -15,6 +15,14 @@ keywords: Solvers expecting production volume should set this up early. With one EOA, a pending transaction can block every settlement behind it. Auxiliary EOAs can submit in parallel, while `GPv2Settlement` still sees the solver EOA as `msg.sender`. +:::warning + +Treat auxiliary EOAs as operationally sensitive accounts. Any approved auxiliary EOA can submit settlements through the solver EOA while the delegation is active. Keep their keys in the same security setup as the solver EOA, monitor their native-token balances, and make sure the team responsible for the solver EOA is also responsible for these accounts. + +If an auxiliary key is compromised, rotate the delegation by configuring a new approved caller set and re-delegating from the solver EOA. + +::: + ## Reference driver setup If you use the reference driver, add `submission-accounts` to the solver entry in your driver config. This is all most solvers need to configure. @@ -38,14 +46,6 @@ The solver `account` must be able to sign the ERC-7702 authorization. Each `subm Fund each auxiliary EOA with the chain's native token so it can pay gas. -:::warning - -Treat auxiliary EOAs as operationally sensitive accounts. Any approved auxiliary EOA can submit settlements through the solver EOA while the delegation is active. Keep their keys in the same security setup as the solver EOA, monitor their native-token balances, and make sure the team responsible for the solver EOA is also responsible for these accounts. - -If an auxiliary key is compromised, rotate the delegation by configuring a new approved caller set and re-delegating from the solver EOA. - -::: - At startup, the reference driver deploys `Solver7702Delegate` at the expected CREATE2 address, or reuses the existing deployment at that address. When the solver EOA is busy, it uses the auxiliary accounts to submit settlements through separate nonce lanes. ## What changes when submitting