EIP-7997 - Deterministic Factory Predeploy

Created 2025-08-03
Status Draft
Category Core
Type Standards Track
Authors
Requires

Abstract

A minimal CREATE2 factory is inserted as a system contract in the precompile range, to enable deterministic deployments at identical addresses across EVM chains. This benefits developer experience, user experience, and security, in particular for multi-chain and cross-chain applications, including account abstraction.

Motivation

There are now a large number of EVM chains where users want to transact and developers want to deploy applications, and we can expect this number to continue to grow in line with Ethereum's rollup-centric roadmap and the general adoption of programmable blockchains.

Most applications support multiple chains and aspire to support as many as possible, and their developers widely prefer to deploy contracts at identical addresses across all chains, a setup which we will call multi-chain deterministic deployment.

This kind of deployment reduces the number of addresses that must be distributed to use the application, so that it no longer scales with the number of supported chains. This simplification has many benefits throughout the stack: interfaces and SDKs need to embed and trust fewer addresses, and other contracts that depend on them can be implemented without chain-specific customization (which in turn makes them amenable to multi-chain deployment).

This kind of deployment is also highly desirable and important for account abstraction. Without it, a user's smart contract accounts are deployed at different addresses on different chains, and each account is tied to a single chain. This limitation is difficult to explain to users and has caused loss of funds. If smart contract accounts cannot be multi-chain like EOAs, they offer downgraded UX and are more prone to error.

There is currently no native or fully robust way to perform multi-chain deterministic deployments. While CREATE2 enables deterministic deployments, the created address is computed from that of the contract that invokes the instruction, so a factory that is itself multi-chain is required for bootstrapping. Four workarounds are currently known to deploy such a factory, each with their own issues:

  1. A keyless transaction is crafted using Nick's method that can be posted permissionlessly to new chains. For this to work, the chain must support legacy transactions without EIP-155 replay protection, and the fixed gas price and gas limit must be sufficiently high, but not so high as to exceed the limits of the chain.
  2. Private keys held by some party are used to sign creation transactions for each chain as needed. This creates a dependency on that party, does not provide a hard guarantee that the factory will be available on every chain, and can also irreversibly fail if transactions are not properly parameterized.
  3. A private key is intentionally leaked so that any party can permissionlessly create an EIP-7702 signed delegation and deploy a factory from the leaked account. While this approach improves on the previous two, its reliance on ECDSA keys makes it non-quantum-resistant, and will fail once chains stop supporting ECDSA keys. Additionally, it requires EIP-7702, an orthogonal feature which is not guaranteed to spread to all chains; for example, those chains that tackle account abstraction through other means have no use for it, and arguably weaker ecosystem pressure to implement it (compared to other EIPs) given that it is a feature not directly used by applications (which instead access AA capabilities through an abstraction like EIP-5792). Lastly, there is a possibility that a future upgrade allows EIP-7702 delegations to become permanent, which breaks this scheme.
  4. Factories already deployed on other chains (by any of the previous methods) are inserted in a new chain at genesis or via a hard fork. This has not been widely adopted by chains, despite the standardization efforts of RIP-7740. Since these factories are applications deployed by users through normal means, this kind of hardcoding of accounts may be seen by chain developers as too intrusive.

This EIP aims to coordinate a widely available multi-chain CREATE2 factory without the above downsides by placing a factory in the precompile range.

Specification

Parameters

Factory Contract

Upon activation of this EIP, the account at FACTORY_ADDRESS becomes a contract that, when called, invokes the CREATE2 instruction (EIP-1014) with a salt equal to the first 32 bytes of the call's input data, init code equal to the remaining data, and value equal to the call's value. If input data is smaller than 32 bytes, the call reverts with empty return data. If creation fails (CREATE2 outputs 0), the call reverts with return data equal to that of the creation frame.

Specifically, the code of FACTORY_ADDRESS is set to 60203610602f5760003560203603806020600037600034f5806026573d600060003e3d6000fd5b60005260206000f35b60006000fd. This code implements the specification above and corresponds to the following assembly:

#pragma target "constantinople"

;; Input: salt (32 bytes) || initcode (variable size)

;; Verify input is at least 32 bytes long.
push 32
calldatasize
lt
jumpi @throw

;; Load salt.
push 0
calldataload

;; Compute initcodesize = calldatasize - 32.
push 32
calldatasize
sub

;; Copy initcode to memory at position 0.
dup1
push 32
push 0
calldatacopy

;; Invoke create2 with salt and initcode, forwarding all callvalue.
push 0
callvalue
create2

;; Check if create2 produced nonzero.
dup1
push @success
jumpi

;; Fallthrough if zero, and revert with identical returndata.
returndatasize
push 0
push 0
returndatacopy
returndatasize
push 0
revert

;; On success, return the created address.
success:
push 0
mstore
push 32
push 0
return

throw:
push 0
push 0
revert

Rationale

Precompile-range system contract

Unlike previous system contracts, this factory cannot be deployed using a normal transaction because, as explained in the Motivation section, that transaction could not be guaranteed to be valid on other chains. Since the purpose of this factory is to be available in all EVM chains that a contract could be deployed to, an irregular insertion of the code into a special address seems necessary.

The address 0x0b (0x000000000000000000000000000000000000000b) is chosen as the next lowest address after existing precompiles, on the assumption that other EVM chains would have reserved this range for future Ethereum precompiles.

Input validation

The factory reverts if the input is smaller than 32 bytes, the minimum size that contains a nonce, to provide an explicit error when the factory is not correctly invoked.

No frontrunning protection

As explained in the Security Considerations, deployments using this factory can potentially be frontrun.

A different factory could avoid this issue if it invokes CREATE2 with a salt computed from the caller address in combination with the caller-provided salt input. This prevents frontrunning, but makes deployments permissioned to a deployer account, without the ability to recover permissionless deployments across chains because of the bootstrapping problem this EIP is itself meant to solve.

A factory could also support both permissioned and permissionless deployments by making the mechanism opt-in. However, the addition of this complexity to an otherwise very simple contract was deemed unnecessary, since once the bootstrapping problem is solved, further factories with a more comprehensive set of features and security measures can be deterministically deployed across chains. We expect this to be the case.

Not a new transaction type

An alternative approach would consist of a new creation transaction type where the address of the created contract is computed in a way independent of the transaction origin. A system contract was considered a simpler approach that will be more robust to changes in the base layer in the future or across chains.

Constantinople target, avoidance of PUSH0

The system contract is written to avoid the use of newer opcodes such as PUSH0 to make it viable to be adopted by chains that don't yet support them, decoupling the decision to adopt this EIP from that of adopting other EIPs.

Test Cases

TBD

Security Considerations

Frontrunnable deployments

The deployment of contracts that read the environment (ORIGIN, NUMBER, etc.) may be frontrun and created with attacker-chosen parameters. It's recommended to use this factory to deploy fully deterministic contracts only.

Copyright

Copyright and related rights waived via CC0.