Add EIP: SETCODEFROM Code Reuse Instruction#11800
Conversation
File
|
| @@ -0,0 +1,163 @@ | |||
| --- | |||
There was a problem hiding this comment.
| --- | |
| --- | |
| eip: 8298 |
Assigning next sequential EIP/ERC/RIP number.
Numbers are assigned by editors & associates.
Please also update the filename.
| title: SETCODEFROM Code Reuse Instruction | ||
| description: Adds an instruction that sets an account's code hash from an existing deployed contract. | ||
| author: TBD | ||
| discussions-to: TBD |
There was a problem hiding this comment.
Please add discussions topic on Eth Magicians using the template: https://ethereum-magicians.org/c/eips/5
There was a problem hiding this comment.
The discussion link is added in 2e6cfef after setting up a new thread in the forum.
|
There are issues with the design you proposed:
|
jochem-brouwer
left a comment
There was a problem hiding this comment.
Some minor comments (I left some ideas about the content on Ethereum Magicians)
| eip: 8298 | ||
| title: SETCODEFROM Code Reuse Instruction | ||
| description: Adds an instruction that sets an account's code hash from an existing deployed contract. | ||
| author: TBD |
There was a problem hiding this comment.
Authors have to be added 😄 👍
There was a problem hiding this comment.
Thanks for the reminder. Added myself for now as the current draft author to address the author-field blocker. I’m checking with the potential co-authors and can update the field once they confirm whether they want to be listed.
|
|
||
| First, it improves code reuse and deployment economics. Deploying many contracts with identical runtime code is expensive, especially when contract deployment is repriced more closely to state growth, for example under [EIP-8037](./eip-8037.md). Contract creation can initialize per-instance storage, then adopt shared deployed code without paying code-deposit gas for identical runtime code. Existing contracts can also adopt a new shared implementation through their own upgrade logic. | ||
|
|
||
| Second, it provides an account migration path for disabling ECDSA-based EOA transaction authority. Migration code can store account-specific wallet state, including PQ wallet state, then adopt regular wallet code. After that update, account control is through the installed wallet code rather than ECDSA transaction origination. This is because the account now has regular deployed code, not an EIP-7702 delegation indicator, so ECDSA-authenticated transactions remain invalid under EIP-3607. EIP-7702 authorization processing can no longer redelegate the account because the authority code check only accepts empty code or an existing delegation indicator. The account can still upgrade through upgrade logic in the installed code, for example by calling `SETCODEFROM` again or by using other methods. Protocol-level ECDSA transaction origination remains permanently disabled. |
There was a problem hiding this comment.
Please define the abbreviations before us, so likely Post-Quantum (PQ) here
There was a problem hiding this comment.
Thanks for pointing this out. Addressed in 6501ed4.
CPerezz
left a comment
There was a problem hiding this comment.
EIP-7702’s Rationale deliberately kept EXTCODEHASH from following delegations because “a change of codehash is only possible in the presence of SELFDESTRUCT”. We should probably pay a mention to that.
EIP-6913 (SETCODE, Withdrawn) banned replacement under DELEGATECALL specifically so “code not containing SETCODE can be safely assumed immutable”; we make the opposite choice (needed for the 7702-migration path) and never cite 6913 which we should likely do?
| ## Security Considerations | ||
|
|
||
| `SETCODEFROM` can change the code used by later executions of an account. Contracts that expose this instruction must restrict access to trusted control paths, because a successful call can permanently change account behavior if the transaction does not revert. | ||
|
|
||
| The source restriction requires valid regular deployed code under the active fork, e.g. code that does not use the `0xEF` prefix reserved by [EIP-3541](./eip-3541.md) and used by [EIP-7702](./eip-7702.md) delegation indicators. It also excludes empty code and precompiles. This prevents `SETCODEFROM` from bypassing deployed-code validity rules or treating precompile behavior as deployed code. | ||
|
|
||
| Protocol-level ECDSA transaction origination is disabled once the account has regular deployed code, meaning code that is not an EIP-7702 delegation indicator. Contracts that verify ECDSA signatures directly through `ecRecover` may still recover that address. This affects signature-based authorization such as `permit`. A companion `ecRecover` change, such as [EIP-8151](./eip-8151.md), can reject recovered addresses whose account code is regular deployed code rather than an EIP-7702 delegation indicator, and return 32 zero bytes. | ||
|
|
||
| Because the current frame keeps executing already-loaded code, implementations must clearly separate the executing code for the current frame from the account code visible to later calls. Re-entrant calls after a successful `SETCODEFROM` observe the updated code. |
There was a problem hiding this comment.
This changes EIP-7702’s risk model: today a bad delegate is recoverable by redelegating; with SETCODEFROM reachable from a delegate, the worst case becomes permanent, irreversible loss of key authority. Security Considerations should state this model change explicitly, and the spec should consider mitigations for silent triggering.
My suggestion:
Require the indicator→regular-code transition to present a fresh ECDSA-signed commitment by the EOA key over source.codeHash (analogous to 7702’s front-running-initialization mitigation) so a delegate can’t convert the account without an explicit key-signed approval of the exact template.
We can price the opcode higher (due to the ECDSA verification). But it buys us a lot of security for the end-user.
There was a problem hiding this comment.
As we already discussed, and also left a comment here, on the ECDSA commitment requirement: I think this is worth discussing, but I'm not fully convinced it should be mandatory. Once an account moves into a 7702-style smart-wallet model, the EOA key may be intentionally de-emphasized, poorly retained, or even generated-and-destroyed for synthetic accounts. In that model, the code path should be able to become the authority.
In my view, users should migrate their normal wallet usage to the smart-account flow before burning or de-emphasizing the private key. Once they do that, the wallet code is the authority they rely on, so requiring another fresh ECDSA approval from the old key may not fit such a security model.
There was a problem hiding this comment.
This changes EIP-7702’s risk model: today a bad delegate is recoverable by redelegating
The other EIP this is generalising does exactly the same thing and kills the ECDSA use as tx originator (in a more complicated way) is intentional https://eips.ethereum.org/EIPS/eip-7851
CPerezz
left a comment
There was a problem hiding this comment.
The general clause says a valid SETCODEFROM “sets the current account’s codeHash… and pushes 1”; the Contract Creation section says adoption is recorded and applied at initcode completion.
The divergence: mid-initcode EXTCODEHASH(self) (source hash vs EMPTYCODEHASH), and whether an external CALL to the under-construction account executes adopted code against half-initialized storage. We should specify that.
Addressed your comments on Magician in commit: 6501ed4. Currently I use the runtime-only design for now because it keeps contract creation semantics simple. This is slightly more expensive than supporting |
Nice catch. I guess this is resolved by removing |
|
The commit 5e58ca4 (as a parent of f9a7b07) contains errors. |
Thanks for pointing this out. These are real concerns. I documented them in the security section and cited 6913 (I was not aware of this EIP before and also focused solely on the raw spec draft). The core distinction here is that Related commit for reviewing: 5e58ca4. |
22c04a5 to
5f601b4
Compare
|
Thanks for the considerable feedback! The CI has passed, and comments are best effort addressed (though still has a lot of improvement space but I think it's ready for a draft), thus opening the PR. |
|
Hi @abcoathup @jochem-brouwer could you take another look at this Add EIP PR? Thanks! |
During the ACDE call, @benaadams raised a useful idea to combine the goals of EIP-7851 and EIP-8058. This PR is submitted as a draft to sketch an initial specification for that combined direction and make the design easier to review concretely. It is kept in Draft for now, and can be opened for broader discussion once the relevant authors have completed their review.