Alert Source Discuss
⚠️ Draft Standards Track: Core

EIP-7819: Create delegate

Add a new EVM instruction allowing contracts to create clones using EIP-7702 delegation designations

Authors Hadrien Croubois (@amxx), Danno Ferrin (@shemnon)
Created 2024-11-18
Discussion Link https://ethereum-magicians.org/t/eip-7819-create-delegate/21763
Requires EIP-7692, EIP-7702

Abstract

Introduce a new EVM instruction to EOF that allows smart contracts to create (and update) delegation accounts that match EIP-7702’s design. These accounts can be used similarly to ERC-1167 clones, with significant advantages.

Motivation

Many on-chain applications involve creating multiple instances of the same code at different locations. These applications often rely on clones, or proxies, to reduce deployment costs.

Clones, such as the one described in ERC-1167 are minimal pieces of code that contain the target address directly in the code. That makes them extremely light but prevents any form of reconfiguration (upgradability).

Upgradeable proxies differ from clones in that they read the implementation’s address from storage. This makes them more versatile but also more expensive to use.

In both cases delegating the received calls to an implementation using EVM code comes with some downsides:

  • Calldata must be copied to memory before performing the delegate call
  • Clones and proxy written in EOF do not support delegation to an implementation written in legacy EVM code, and are thus limited or possibly dangerous. This encourages the continued use of legacy EVM code.

EIP-7702 introduces a new type of object that has the expected behavior: designator. These objects are designed to be instantiated at the address of EOA’s, but the same behavior could be re-used to implement clones at the protocol level. Using designators for this use-case provides upgradeability without the need for storage lookups if the contract calling the CREATE_DELEGATE allows it. It also removes any issue related to code version incompatibilities.

Specification

A new instruction (CREATE_DELEGATE) is added to EOF at 0xf6.

This instruction is NOT added to legacy EVM.

Behavior

Executing this instruction does the following:

  1. deduct EMPTY_ACCOUNT_COST gas
  2. halt if the current frame is in static-mode
  3. pop salt, target from the operand stack
  4. calculate location as keccak256(MAGIC ++ address ++ salt)[12:]
  5. halt if the code at location is not empty and does not start with 0xEF0100 (no empty and not a designator)
  6. add EMPTY_ACCOUNT_COST - BASE_COST gas to the global refund counter if location exists in the trie.
  7. set the code of authority to be MAGIC || target, matching the delegation process defined in EIP-7702.
    • Similarly to EIP-7702, if target is 0x0000000000000000000000000000000000000000 do not write the designation. Clear the code at location and reset the location’s code hash to the empty hash 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470.
  8. push location onto the stack

The designator created at location behaves identically to those created by EIP-7702.

Parameters

Constant Value
MAGIC 0xef0100
EMPTY_ACCOUNT_COST 25000
BASE_COST 12500

Rationale

Gas cost

The execution of the CREATE_DELEGATE instruction involves fewer moving pieces than what EIP-7702 gas costs account for:

  • there is no signature recovery
  • there is no dedicated calldata that must be accounted for that is not already paid for at the transaction level
  • there is no nonce update

Therefore, the cost of executing this instruction could be lower than EIP-7702. Numbers from EIP-7702 are reused for simplicity. They are lower than CREATE or CREATE2 operations, making the use of this instruction competitive for the intended use-cases.

Backwards Compatibility

TODO

Security Considerations

Delegator upgrades & deletion

Reusing EIP-7702 behavior, including clearing the code if the target is 0, results in the ability to upgrade or even “remove” the created designator. This process is controlled (and can be restricted) by the factory (the contract that calls CREATE_DELEGATE). Some factories will add checks that prevent re-executing CREATE_DELEGATE with a salt that was already used, making the create designator immutable. Others may allow access-restricted upgrades, but prevent deletion. In any case, guarantees about the lifecycle of the designator created using CREATE_DELEGATE are provided by the contracts that call it and not by the protocol.

Delegator chaining

As documented in EIP-7702, designator chains or loops are not resolved. This means that, unlike clones, chaining is an issue. This is however something developpers are used to, as chaining proxy can result in strange behaviors, including infinite delegation loops.

Factories may want to protect against this risk by verifying that the target doesn’t contain a designator. This can be achieved using a legacy contract helper that has access to EXTCODEHASH. It could also be done using other forms of introspection such as an ACCOUNT_TYPE instruction.

Front running initialization

Unlike EIP-7702 signature, which can be included in any transaction, and can thus lead to initialization front-running if the implementation doesn’t check the authenticity of the initialization parameters, CREATE_DELEGATION is executed by a smart contract that can execute the initialization logic atomically, just after the delegation is created. This process is well-known to developers that initialize clones and proxies just after creation.

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

Hadrien Croubois (@amxx), Danno Ferrin (@shemnon), "EIP-7819: Create delegate [DRAFT]," Ethereum Improvement Proposals, no. 7819, November 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7819.