EIP-7702 Implementation and Specification
Abstract
The Viridian network upgrade, introduced by Morph last October, represents a coordinated protocol and infrastructure update across both the Morph Hoodi Testnet and Morph Mainnet. As part of this upgrade, Morph implemented EIP-7702, enabling Externally Owned Accounts to delegate execution to existing contract code while remaining EOAs at the protocol level. This capability allows EOAs to temporarily operate with smart contract–like behavior through delegated execution, processed within a single typed transaction. Alongside EIP-7702, the Viridian update includes upgrades to the Morph node binary and the underlying go-ethereum client, ensuring network consistency and compatibility while introducing the new execution model.
Motivation
Morph implements EIP-7702 to enhance EOAs, the default account type for most users. While smart contract wallets offer richer functionality, they involve deployment costs, complex onboarding, and ecosystem dependencies. By directly enhancing EOAs, common UX improvements can be adopted across applications without requiring users to switch to new account formats.
The following capabilities are central to the motivation:
- Batching: Users often need to perform sequences of operations that must happen together. For example, approving a token and immediately spending it. Today this usually needs separate transactions. Delegated code allows these sequences to be executed in one go, improving both convenience and safety.
- Sponsorship: Many applications want to cover transaction fees for their users or route fees through a dedicated payer. With delegated code, an operator can manage fees while actions still occur under the user’s account.
- Privilege de-escalation: Users may want to grant limited capabilities to specific tools or sub-keys. Examples include allowing interaction with only one dapp, spending limits, rate limits, or permitting actions on specific assets but not others. Delegated execution makes it possible to enforce restricted behavior at runtime without giving full control of the account.
These upgrades aim to push EOA functionality closer to smart account features without introducing a second UX ecosystem.
Specification
Parameters
| Parameter | Value |
|---|---|
| SET_CODE_TX_TYPE | 0x04 |
| MAGIC | 0x05 |
| PER_AUTH_BASE_COST | 12500 |
| PER_EMPTY_ACCOUNT_COST | 25000 |
Transaction Format: Set Code Transaction
A new EIP-2718 typed transaction is introduced. Its type is SET_CODE_TX_TYPE and its payload is the RLP encoding of:
rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit,
destination, value, data, access_list, authorization_list, signature_y_parity,
signature_r, signature_s])
authorization_list = [[chain_id, address, nonce, y_parity, r, s], ...]
The standard fields mirror the semantics defined by EIP-4844. The destination must not be empty.
The signature signs over: keccak256(SET_CODE_TX_TYPE || TransactionPayload)
The authorization_list contains tuples specifying which contract code each signer wants their EOA to execute. A transaction with an empty authorization_list is treated as invalid.
Each field in every authorization entry must satisfy:
assert auth.chain_id < 2**256
assert auth.nonce < 2**64
assert len(auth.address) == 20
assert auth.y_parity < 2**8
assert auth.r < 2**256
assert auth.s < 2**256
For this transaction type, the EIP-2718 receipt payload is structured as:
rlp([status, cumulative_transaction_gas_used, logs_bloom, logs]).
Behavior
Before executing the transaction’s main call [chain_id, address, nonce, y_parity, r, s], the system processes each authorization entry in sequence:
- Verify the chain ID is either zero or matches the local chain.
- Confirm the nonce is within the allowed range.
- Recover the signer’s address using ecrecover(msg, y_parity, r, s).
- Here, msg is calculated as keccak(MAGIC || rlp([chain_id, address, nonce])).
- Confirm that s is within the allowed range according to EIP-2 (s ≤ secp256k1n/2).
- Add the recovered address to accessed_addresses as defined in EIP-2929.
- Ensure the code of the recovered account is either empty or already delegated.
- Verify that the signer’s on-chain nonce matches the expected value (auth_nonce).
- If the account is not empty, add PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST to the global gas refund counter.
- Assign the delegation indicator to the account’s code using 0xef0100 || address.
- If address is 0x000…000, clear the account’s code by resetting the code hash to the empty code hash 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470.
- Increment the signer’s nonce.
If any authorization entry fails one of these steps, skip it and continue with the next. When multiple entries refer to the same authority, the last valid entry determines the delegation target.
Delegation markers are not reverted even if the main transaction reverts.
Delegation Marker Semantics
Delegation indicators rely on the reserved opcode 0xef (per EIP-3541) to mark code that should be treated differently from standard EOA code. When an account contains a delegation indicator, all execution operations follow the pointer to the referenced address, running that code in the context of the original account. For instance, a CALL will execute the code at the pointed-to address while maintaining the authority of the delegating account.
When an account has a delegation marker, any execution entry point that would normally load code from that account instead loads code from the referenced target. This applies to:
- CALL
- CALLCODE
- DELEGATECALL
- STATICCALL
- Transactions directed to the delegated account
When reading code, only the CODESIZE and CODECOPY instructions are impacted. They act on the code of the account that is actually running, rather than the delegated code. For instance, during delegated execution, EXTCODESIZE would return 23 (the length of 0xef0100 || address), while CODESIZE reflects the size of the code at the executing account’s address. This means that under delegation, CODESIZE and CODECOPY yield different results than EXTCODESIZE and EXTCODECOPY called on the authority account.
Precompile Interaction
If a delegation marker points to a precompile address, the system treats the code as empty. Calls succeed with no effect as long as sufficient gas is provided.
Delegation Chains
If the target address itself has a delegation marker, clients must stop at the first level and not follow the chain further. Only the immediate target is used.
Gas Usage
Intrinsic gas follows EIP-2930 rules:
21000 + 16 * nonzero calldata byte
+ 4 * zero calldata byte
+ 1900 * per storage key in the access list
+ 2400 * per address in the access list
Additionally:
+ PER_EMPTY_ACCOUNT_COST * number_of_authorizations
Delegations are charged upfront. If the delegated account already exists, a refund is applied during processing.
Accessing cold accounts through delegation resolution adds the standard EIP-2929 cold read cost.
Transaction Origination Rules
Accounts with a correct delegation marker may still originate transactions. Accounts with any other arbitrary code may not. If a transaction’s destination holds a delegation marker, the target of the delegation is added to the accessed addresses for gas accounting.
Rationale
Design Goals
The aim is to provide EOA enhancements that improve UX across the ecosystem without creating a second class of wallet types. Delegation markers give EOAs a programmable pathway while keeping their lifecycle simple.
Persistent Delegation
Early designs considered temporary delegation during a transaction, but this encouraged treating the system as a scripting environment. Persistent delegation creates a healthier boundary between EOAs and smart account features, reducing misuse and fragmentation.
No Initcode Support
Running initcode introduces a separate execution mode and significantly complicates validation, tooling, and transaction propagation. Using existing contract deployments as templates avoids these issues and reduces calldata overhead.
Template-Based Code Selection
Referencing deployed code with an address is much more efficient than embedding bytecode directly. Embedding code would also allow ad hoc execution paths that are difficult to audit and incompatible with long term account abstraction plans.
Wallet and Application Safety
Wallets should not naively expose UIs that allow arbitrary authorization signing. The delegated code has complete access to the account’s state and tokens, so wallet implementations must validate the intent behind each authorization step.
Forward Compatibility
The design aligns with smart account ecosystems such as ERC-4337 by allowing EOAs to point at wallet logic that already exists. This supports long term convergence toward a unified account model without premature protocol commitments.
Self Sponsoring
Allowing the originating account to set its own code enables users to try delegation without relying on external actors. This slightly alters some common assumptions around execution context but does not break legitimate use cases.
Cost Model
The chosen gas values reflect the cost of transporting, validating, and applying each delegation entry. The PER_EMPTY_ACCOUNT_COST accounts for the cost of initializing an account. PER_AUTH_BASE_COST approximates the cumulative steps required to process an entry.
Handling Clear Operations
When delegation is directed to the zero address, the system fully clears code instead of writing a marker. This aligns execution semantics with normal EOAs and avoids repeated cold account penalties.
Instruction Set
Morph implements the instruction set without banning operations such as SSTORE or contract creation. This approach preserves existing UX patterns for both EOAs and smart contract wallets, aligning with the original design goals of EIP-7702.
Security Considerations
Morph’s implementation of EIP-7702 follows the standard execution and delegation model, inheriting its associated security considerations. Key points for developers and operators include:
- Delegate contract safety: Delegated code has full authority over the EOA. Delegate contracts should validate nonces, value, gas, and calldata to prevent replay attacks, unintended transfers, or denial-of-service.
- Initialization and front-running: Delegation does not run initcode or pre-set storage. Delegate contracts should require explicit authorization from the EOA for any setup parameters to prevent front-running.
- Storage and delegation updates: Changing delegated code is sensitive; overlapping storage layouts can cause corruption. Use storage isolation or reset account state before switching delegation targets.
- Execution context: Delegation may affect tx.origin checks and reentrancy protections. Applications should avoid assumptions about the execution context of delegated EOAs.
- Sponsored transactions and relayers: Relayers face risks if authorizations are invalidated or funds removed before reimbursement. Safeguards such as bonding, rate limits, or reputation systems are recommended.
- Transaction propagation: Delegated EOAs can be invoked during transaction execution, potentially invalidating pending transactions or causing multiple nonce increments. Clients should limit concurrent pending transactions and design mempool handling accordingly.
Backwards Compatibility
Morph’s implementation of EIP-7702 preserves standard EOA behavior for accounts that do not enable delegation. For accounts that opt into delegation, some common EOA assumptions no longer strictly apply:
- Account balances are no longer affected only by transactions sent directly from the account.
- When delegation is active, external calls into the account may execute delegated logic that changes the balance.
- Account nonces are no longer guaranteed to change only after transaction completion.
- Delegated execution may perform contract creation during execution, which can increment the nonce.
- The execution model no longer guarantees that tx.origin equals msg.sender only at the top-level call.
- Delegated logic may initiate multiple calls within a single transaction.
These changes result from the EIP-7702 delegation model and should be considered by applications, wallets, and tooling interacting with delegated EOAs on Morph.
Slowmist Audit report
We commissioned SlowMist to conduct a full security audit of Morph’s EIP-7702 implementation, initiated on October 10, 2025. The audit assessed the upgrade’s robustness and adherence to security best practices and was executed according to an agreed scope and testing plan tailored for this implementation.
SlowMist performed a comprehensive assessment using a white-box–led methodology designed to closely simulate real-world attack conditions. The evaluation combined black box testing, grey box testing, and white box testing techniques. The audit also incorporated analysis informed by known blockchain security vulnerabilities, alongside exploratory testing for previously unknown or emerging attack vectors.
The full audit findings and methodology are available in the official SlowMist report: Access the SlowMist EIP-7702 Audit Report