EIP-7819 SETDELEGATE opcode (SETDELEGATE instruction)

Hegota Declined for Inclusion · EVM & execution · EIP status Draft · created 2024-11-18

Adds a new EVM opcode, SETDELEGATE (0xf6), that lets a contract create and change EIP-7702-style delegation designators directly. It reuses the same code through a 23-byte delegation instead of clones or proxies.

Why it is needed

Deploying the same code to many addresses is very common onchain, and smart account wallets are the prime example. To reduce deployment cost, ERC-1167 clones or upgradeable proxies are used. Clones are lightweight but their implementation address cannot be changed, while proxies can be changed but pay the cost of reading the implementation address from storage on every call. Both need EVM code that copies the received calldata into memory and performs a delegate call. According to a Geth team survey (EthCC[9] "Not all state is equal"), 97.1% of about 50 million deployed contracts are code that has already been deployed before, and 28.6% of unique bytecode is small code under 1 KiB. Clones and proxies likely make up a large share of that, so a way is needed to handle this role at the protocol level more compactly and cheaply.

What changes

Today

After EIP-7819

Who is affected

In depth

The 10 steps of the instruction

SETDELEGATE, added at 0xf6, operates in the following order. It deducts EMPTY_ACCOUNT_COST gas and aborts if the frame is in static mode. It pops salt and target from the stack, computes location = keccak256(DESIGNATOR ++ address ++ salt)[12:], and adds location to EIP-2929's accessed_addresses. If the code at location is neither empty nor starts with 0xEF0100 (that is, it is not a delegation designator), it aborts. If location already exists in the trie, it adds EMPTY_ACCOUNT_COST - BASE_COST to the refund counter. It sets the code to DESIGNATOR ++ target, but if target is 0x0, it clears the code and restores the code hash to the empty hash. If the nonce is 0, it raises it to 1 and pushes location onto the stack. target must be exactly 20 bytes: if shorter it is left-padded with zeros, and if longer the high-order bytes are truncated. Per EIP-7702, the resulting code is exactly 23 bytes.

Gas cost and parameters

The parameters are the same as EIP-7702. DESIGNATOR is 0xef0100, EMPTY_ACCOUNT_COST is 25000, and BASE_COST is 12500. In practice it does less work than 7702. There is no signature recovery, no separate calldata beyond what was already paid at the transaction level, and, apart from the initial set to 1 in step 9, no nonce update. So the cost could be lowered further, but the 7702 values are reused for simplicity. These values are lower than the CREATE and CREATE2 costs, so they are competitive for the intended use.

Address derivation and avoiding collisions with existing addresses

location is derived from the caller address and a caller-chosen salt as keccak256(DESIGNATOR ++ address ++ salt). It gives a deterministic address like CREATE2, but it avoids collisions with existing derivation schemes by using a different preimage length of 55 bytes. The CREATE2 preimage is 85 bytes, so length alone rules out a collision. CREATE uses RLP([address, nonce]); to reach 55 bytes the nonce would have to be 32 bytes, and that encoding starts with 0xf694, which differs from 0xef0100. Even for a smaller nonce that starts with 0xef, the preimage is shorter than 55 bytes and starts with 0xef94, so it still does not overlap.

The same object as an EIP-7702 delegation designator

The delegation indicator that SETDELEGATE creates is the same object that EIP-7702 creates, and it behaves the same way. The behavior documented in 7702 applies unchanged, including CODESIZE and CODECOPY handling, precompile designation, and delegation chains, and any future EIP that changes the behavior of 7702 delegation indicators must apply here as well. This object is not a contract, so it cannot be removed with SELFDESTRUCT even if it was created in the same transaction. Deletion SHOULD be possible only by having the caller that created it run SETDELEGATE again with the same salt and a 0 target. Step 9, which raises the nonce to at least 1, ensures that the account does not return to the empty state forbidden by EIP-7523 even after its code is cleared.

Security considerations

The lifecycle guarantees of a delegation indicator are provided not by the protocol but by the factory contract that calls SETDELEGATE. A factory can make the indicator immutable by blocking re-execution of a salt that has already been used, or it can allow only access-controlled upgrades and block deletion. As with 7702, delegation chains and loops are not resolved, so a factory can defend against them by checking that the target itself has no delegation indicator. The initialization front-running problem is easier to handle than with 7702 signatures, because a smart contract can initialize atomically in the same transaction right after creating the delegation. Running SETDELEGATE several times in one transaction with the same salt while changing the target can leave one address executing as several different codes, but existing upgrade proxies that swap storage slots can already do this.

Use Cases and State Savings

The main use cases are smart accounts in wallets such as Safe, ERC-4337 compatible accounts that must be upgraded to match the entry point version, and the mass redeployment that proposals such as EIP-8141 implicitly require on the path to quantum-resistant accounts. A factory can deploy both upgradeable and non-upgradeable accounts, and it can also selectively disable upgrades for only some accounts, so upgrade logic no longer needs to live in the account code. On the state side, OpenZeppelin's ERC-1967 proxy is about 708 bytes, while a 7702 delegation is only 23 bytes. This greatly reduces state usage, and because call forwarding moves down to the protocol level, the execution cost of every call, including ERC-721 and ERC-1155 callbacks, also drops.

Status and Fork Discussion

This EIP is in Draft status, so the specification may still change. The call records show that it was accepted as a Hegota candidate (PFI) at ACDE #242 on 07.30, where it was noted that proxy account creation becomes composable and about 5 times cheaper. However, at ACDE #245 on 09.10 it was declined as a Hegota candidate (DFI) together with EIP-7851 (code-controlled EOA delegation). The reason given was that both EIPs had a client rating below 1.0 and had no champion.

Original EIP · ← EIPs