EIP-7819: Create delegate
Add a new EVM instruction allowing contracts to create clones using EIP-7702 delegation designations
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:
- deduct
EMPTY_ACCOUNT_COST
gas - halt if the current frame is in
static-mode
- pop
salt
,target
from the operand stack - calculate
location
askeccak256(MAGIC ++ address ++ salt)[12:]
- halt if the code at
location
is not empty and does not start with0xEF0100
(no empty and not a designator) - add
EMPTY_ACCOUNT_COST - BASE_COST
gas to the global refund counter iflocation
exists in the trie. - set the code of
authority
to beMAGIC || target
, matching the delegation process defined in EIP-7702.- Similarly to EIP-7702, if
target
is0x0000000000000000000000000000000000000000
do not write the designation. Clear the code atlocation
and reset thelocation
's code hash to the empty hash0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
.
- Similarly to EIP-7702, if
- 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
Copyright and related rights waived via CC0.