# EOFv1 Checklist ###### tags: `EOF` [toc] ## TLDR All EIPs listed here are marked *Considered For Inclusion (CFI)*. EIP-3860 is a prerequisite for proper gas charging, and the complete suite of EOF EIPs provide the following benefits/changes: - Clear container format, with validation at deploy time - Introducing validation removes runtime overhead and risk - Efficient static relative jumps (`RJUMP`, `RJUMPI`) - These are significantly cheaper (50-80% off) than current branching instructions, and also easier to analyse/optimise - Efficient switch-table jump (`RJUMPV`) - This enables brand new use cases (efficient algebraic data types / sum types) and optimises many existing ones (including ABI dispatch, which is part of every contract) - Function sections ("subroutines") to cover the dynamic jump needs (`CALLF`, `JUMPF`, `RETF`) - Removal of inefficient dynamic jumps (`JUMP`, `JUMPI`) - This also allows for removal of the `JUMPDEST` opcode and jumpdest-analysis, and deploy-time analysis of stack properties - It also allows introductions of features which were previously rejected due to lack of versioning, a good example is [EIP-663](https://eips.ethereum.org/EIPS/eip-663) or ["EVMMAX"](https://ethereum-magicians.org/t/evm384-feedback-and-discussion/4533) - Validation of stack properties at deploy time (among others, stack underflow becomes impossible) - The version field (combined with validation) allows for soft and hard feature rollouts - It also allows for various chains (L2s) to introduce features, while keeping cross-chain compatibility -- it will be easy to tell what chain a code is made for ## Specs There is a ["Unified Specification"](https://notes.ethereum.org/@ipsilon/eof1-unified-specification) which can help understand these changes, but the normative specifications are below: - 📃[EIP-3860](https://eips.ethereum.org/EIPS/eip-3860): Limit and meter initcode *(EOF prerequisite)* [_history_](https://github.com/ethereum/EIPs/commits/master/EIPS/eip-3860.md) - 📃[EIP-3540](https://eips.ethereum.org/EIPS/eip-3540): EOF - EVM Object Format v1 [_history_](https://github.com/ethereum/EIPs/commits/master/EIPS/eip-3540.md) - 📃[EIP-3670](https://eips.ethereum.org/EIPS/eip-3670): EOF - Code Validation [_history_](https://github.com/ethereum/EIPs/commits/master/EIPS/eip-3670.md) - 📃[EIP-4200](https://eips.ethereum.org/EIPS/eip-4200): EOF - Static relative jumps [_history_](https://github.com/ethereum/EIPs/commits/master/EIPS/eip-4200.md) - 📃[EIP-4750](https://eips.ethereum.org/EIPS/eip-4750): EOF - Functions [_history_](https://github.com/ethereum/EIPs/commits/master/EIPS/eip-4750.md) - 📃[EIP-5450](https://eips.ethereum.org/EIPS/eip-5450): EOF - Stack Validation [_history_](https://github.com/ethereum/EIPs/commits/master/EIPS/eip-5450.md) - 📃[EIP-6206](https://eips.ethereum.org/EIPS/eip-6206): EOF - JUMPF instruction [_history_](https://github.com/ethereum/EIPs/commits/master/EIPS/eip-6026.md) *Specification freeze (in terms of additions) expected by 8th December 2022.* Note: EOFv1 is mostly frozen. **The roll out plan (including EOFv1, EOFv1.1 and EOFv2) can be found [here](https://notes.ethereum.org/@ipsilon/BJujV7-Tj).** **The design space for EOFv2 (aka contract creation) is [here](https://notes.ethereum.org/@ipsilon/eof2-design-space).** Shorthands: - "Small EOF": EIP-3540 + EIP-3670 - "Full (Suite) EOF": EIP-3540 + EIP-3670 + EIP-4200 + EIP-4750 + EIP-5450 ## Meetings - [EOF Breakout Meeting 1](https://github.com/ethereum/pm/issues/653), Nov 04, 2022 ([notes](https://notes.ethereum.org/@timbeiko/eof-breakout)) - [EOF Breakout Meeting 2](https://github.com/ethereum/pm/issues/666), Nov 18, 2022 ([notes](https://hackmd.io/@poojaranjan/EOFBreakOutNotes#EOF-Breakout-Meeting-2)) - [EOF Breakout Meeting 3](https://github.com/ethereum/pm/issues/677), Dec 2, 2022 ([notes](https://hackmd.io/@poojaranjan/EOFBreakOutNotes#EOF-Breakout-Meeting-3)) - [EOF Breakout Meeting 4](https://github.com/ethereum/pm/issues/690), Dec 15, 2022 ([notes](https://hackmd.io/@poojaranjan/EOFBreakOutNotes#-Notes-4)) - [EOF Breakout Meeting 5](https://github.com/ethereum/pm/issues/692), Jan 2, 2023 ([notes](https://hackmd.io/@poojaranjan/EOFBreakOutNotes#-Notes-5)) - [EOF Implementers Call 6](https://github.com/ethereum/pm/issues/705), Jan 11, 2023 ([notes](https://hackmd.io/@poojaranjan/EOFBreakOutNotes#-Notes-6)) - [EOF Implementers Call 7](https://github.com/ethereum/pm/issues/712), Feb 8, 2023 ([notes](https://hackmd.io/@poojaranjan/EOFBreakOutNotes#-Notes-7)) - [EOF Implementers Call 8](https://github.com/ethereum/pm/issues/728), Feb 22, 2023 ## Implementation | | Spec | Tests | Solidity | Vyper | Evmone + <br/>Silkworm | Geth | Besu | Nethermind | Erigon | EthereumJS | |----------|------|-------|----|----------|--------|------|------|------------|--------|------------| | EIP-3860 | ✅ | ✅ | 🚧 | N/A | 🚧 | 🚧 | ✅ | ✅ | ✅ | ✅ | | EIP-3540 | ✅ | ✅ | 🚧 | 🚧 | ✅ | 🚧 | ✅ | 🚧 | 🚧 | ✅ | | EIP-3670 | ✅ | ✅ | N/A | N/A | ✅ | 🚧 | ✅ | 🚧 | 🚧 | ✅ | | EIP-4200 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | ✅ | 🚧 | 🚧 | 🚧 | | EIP-4750 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | ✅ | 🚧 | 🚧 | 🚧 | | EIP-5450 | 🚧 | 🚧 | N/A | N/A | 🚧 | 🚧 | ✅ | 🚧 | 🚧 | ❌ | Legend: - ✅ -- Done/Merged - 🚧 -- Work in Progress (PR exists) - ❌ -- Unknown (no PR exists) ### Specification / Tests - [`ipsilon/eof` python specs](https://github.com/ipsilon/eof) - ~~[`ethereum/execution-specs` Shanghai summary](https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md#readiness-checklist)~~ - [`ethereum/execution-specs` Cancun summary](https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md) - `ethereum/tests` - [EIP-3860: Opcode tests](https://github.com/ethereum/tests/pull/990) (merged) - [EIP-3860: Transaction tests](https://github.com/ethereum/tests/pull/1012) (merged) - [EIP-3860: Spec change update](https://github.com/ethereum/tests/pull/1105) (merged) - [EIP-3540](https://github.com/ethereum/tests/pull/847) (merged) - [EIP-3670](https://github.com/ethereum/tests/pull/1135) (merged) - [EIP-4200](https://github.com/ethereum/tests/pull/1103) (in progress) - [EIP-4750](https://github.com/ethereum/tests/pull/1115) (in progress) - [EIP-5450](https://github.com/ethereum/tests/pull/1163) (in progress) ### Solidity - [Implementation tracking issue](https://github.com/ethereum/solidity/issues/13717) - [`eofVersion` flag to enable EOF support](https://github.com/ethereum/solidity/pull/13733) (merged) - [EIP-3540 aka basic containers](https://github.com/ethereum/solidity/pull/13772) (superseded) - [EIP-4200](https://github.com/ethereum/solidity/pull/13783) (superseded) - [Full Unified Spec PR](https://github.com/ethereum/solidity/pull/13825) ### Vyper - [Working branch - all EIPs](https://github.com/ETCCooperative/vyper/tree/feature/eof-support) ### Evmone - [EIP-3860](https://github.com/ethereum/evmone/pull/525) (superseded) - [EIP-3860](https://github.com/ethereum/evmone/pull/545) (merged) - [EIP-3540 + EIP-3670](https://github.com/ethereum/evmone/pull/334) (merged) - [EIP-4200](https://github.com/ethereum/evmone/pull/389) (superseded) - [EIP-4750](https://github.com/ethereum/evmone/pull/497) (superseded) - [Full Unified Spec PR](https://github.com/ethereum/evmone/pull/563) ### Geth - [EIP-3860](https://github.com/ethereum/go-ethereum/pull/23847) (merged) - ["Full suite" EIP-3540/EIP-3670/EIP-4200/EIP-4750/EIP-5450](https://github.com/ethereum/go-ethereum/pull/26133) - ~~Branch only: [EIP-5450](https://github.com/lightclient/go-ethereum/tree/eof-5450)~~ ### Besu - [EIP-3860](https://github.com/hyperledger/besu/pull/4726) (merged) - ["Small EOF" - EIP-3540/EIP-3670](https://github.com/hyperledger/besu/pull/4644) (merged) - [EIP-4200](https://github.com/hyperledger/besu/pull/4760) (merged) - [EIP-4750](https://github.com/hyperledger/besu/pull/4781) (merged) - [EIP-5450](https://github.com/hyperledger/besu/pull/4805) (merged) ### Nethermind - [EIP-3860](https://github.com/NethermindEth/nethermind/pull/4740) (merged) - [EIP-3540](https://github.com/NethermindEth/nethermind/pull/4608) - [EIP-3670](https://github.com/NethermindEth/nethermind/pull/4609) - [EIP-4200](https://github.com/NethermindEth/nethermind/pull/4864) - [EIP-4750](https://github.com/NethermindEth/nethermind/pull/4865) - [EIP-5450](https://github.com/NethermindEth/nethermind/pull/4950) ### Erigon - [EIP-3855](https://github.com/ledgerwatch/erigon/pull/5256) (merged) - [EIP-3860](https://github.com/ledgerwatch/erigon/pull/5892) (merged) - ~~["Full suite" EIP-3540/EIP-3670/EIP-4200/EIP-4750](https://github.com/ledgerwatch/erigon/pull/6215)~~ - [Full Unified Spec PR](https://github.com/ledgerwatch/erigon/pull/6382) ### EthereumJS - [EIP-3860](https://github.com/ethereumjs/ethereumjs-monorepo/pull/1619) (merged) - [EIP-3540](https://github.com/ethereumjs/ethereumjs-monorepo/pull/1719) (merged) - [EIP-3670](https://github.com/ethereumjs/ethereumjs-monorepo/pull/1743) (merged) - ["Big EOF": EIP-4200/EIP-4750/EIP-5450](https://github.com/ethereumjs/ethereumjs-monorepo/pull/2453) ## Spec-level Open Issues - [x] **General** - [x] Rename all EOF EIPs to have "EOF -" prefix. [EIPs#5849](https://github.com/ethereum/EIPs/pull/5849) [EIPs#6007](https://github.com/ethereum/EIPs/pull/6007) - EIP-3540 renamed to "EOF - EVM Object Format v1" - EIP-4200 renamed to "EOF - Static relative jumps". With some concerns that this EIP is strictly EOF related the rename has been done for visibility. - [ ] Consider the `0xe0 - 0xef` opcode space for all new opcodes. - [ ] Consider merging EIP-3670 + EIP-5450 into a single specification, condition on EIP-5450 being accepted. - [ ] **EIP-3540**: EOF - EVM Object Format v1 - [x] Move generic contract creation rules from EIP-3670. [EIPs#5907](https://github.com/ethereum/EIPs/pull/5907) - [x] Forbid EOF → legacy contract creation. [EIPs#6052](https://github.com/ethereum/EIPs/pull/6052) - [x] Clarify that overall code size limit of EIP-170 / EIP-3860 still applies to the whole EOF container [EIPs#6067](https://github.com/ethereum/EIPs/pull/6067) https://github.com/ethereum/tests/pull/847#issuecomment-1289657858 - [x] ~~Consider create transaction with invalid EOF initcode invalid (cannot be included in a block). [discord#evm](https://discord.com/channels/595666850260713488/706868829900505180/1044915035216039986)~~ - Decided it was [not important](https://discord.com/channels/595666850260713488/706868829900505180/1047578802185838702) enough to retain this invariant. - Makes it consistent with `CREATE` behavior - The validity check can be performed on the tx alone (no state access needed) - If broadcast, malicious peer is identifiable - [lightclient response against](https://discord.com/channels/595666850260713488/706868829900505180/1047575105670217800) - [x] Make data section mandatory - [ ] **NEW** Account for constructor arguments during on-chain contract creation - Constructor arguments can by dynamically sized and are appended to (the data section of) creation code - The current container format requires adjusting the size field for the data section on appending such arguments - This would have to happen before every ``CREATE`` or ``CREATE2`` call on chain and involves significant overhead. - Furthermore, for ``CREATE2``, people want to calculate the predicted address in user-code, which would involve not only compilers, but also smart contract authors having to account for the adjustment of the data section size. - Possible solutions: - skip the data section size and make the data section open ended - allow additional data after the (still sized) data section only for init code - [x] Clarify nonce behavior for CREATE [EIPs#6328](https://github.com/ethereum/EIPs/pull/6328) - [x] **EIP-3670**: EOF - Code Validation - [x] Reject (their opcodes must not be used in EOF code) `CALLCODE` and `SELFDESTRUCT` [EIPs#5894](https://github.com/ethereum/EIPs/pull/5894) In case the [EIP-4758](https://eips.ethereum.org/EIPS/eip-4758) is activated for legacy code we should reconsider adding the same instruction to EOF or keep `SELFDESTRUCT` fully deactivated. If something aking to [EIP-6046](https://github.com/ethereum/EIPs/pull/6046) is accepted, then keep `SELFEDESTRUCT` deactivated. - [x] Do not require the last instruction to be terminating. [EIPs#6053](https://github.com/ethereum/EIPs/pull/6053) - [x] **EIP-4200**: EOF - Static relative jumps - [x] ~~Calculate offset from the *current* instruction position (not the *next* one (+3 bytes)).~~ - [x] Properly specify `RJUMPV` [EIPs#6056](https://github.com/ethereum/EIPs/pull/6056), [EIPs#6078](https://github.com/ethereum/EIPs/pull/6078) - [ ] Add `Security Considerations` section. - [x] Clarify `PC` status: [EIPs#6111](https://github.com/ethereum/EIPs/pull/6111) - [x] Allow RJUMPV table sizes of up to 256 [EIPs#6546](https://github.com/ethereum/EIPs/pull/6546) - Agreed. - [ ] **EIP-4750**: EOF - Functions - [x] Set `CALLF` and `RETF` opcode numbers [EIPs#5921](https://github.com/ethereum/EIPs/pull/5921) - [x] Set gas cost for `CALLF` and `RETF`. [EIPs#5888](https://github.com/ethereum/EIPs/pull/5888) - [x] Redefine code section header to be array of code section sizes. [EIPs#5928](https://github.com/ethereum/EIPs/pull/5928) [Discord#evm](https://discord.com/channels/595666850260713488/706868829900505180/1041659610865606706) - [x] Clarify: "If data stack has less than `caller_stack_height + types[code_section_index].outputs`, execution results in exceptional halt." What happens if the stack height is larger than the number? (Option to always require exactly `caller_stack_height + types[code_section_index].outputs` items, no more) [EIPs#6080](https://github.com/ethereum/EIPs/pull/6080) - [x] ~~Change the spec of `RETF` to clean up the stack for user (i.e. leave only the top stack items in number of function outputs). This requires `memmove` of the top stack items.~~ - [x] ~~Limit number of functions to 256 (single-byte immediate for `CALLF`)~~ [EIPs#6061](https://github.com/ethereum/EIPs/pull/6061) - [x] Reject `JUMP`, `JUMPI` and `JUMPDEST`. [EIPs#6044](https://github.com/ethereum/EIPs/pull/6044) - [x] Replace `JUMPDEST` with `NOP`. [EIPs#6044](https://github.com/ethereum/EIPs/pull/6044) - [x] **NEW** Reject `PC`. [EIPs#6209](https://github.com/ethereum/EIPs/pull/6209) - [x] Reassign EOF section ids to be in order (01: type, 02: code, 03: data). - [x] Make type section mandatory - [x] Clarify that 1024 data stack limit still applies. [EIPs#6063](https://github.com/ethereum/EIPs/pull/6063) - [x] [Container specification discussion](https://notes.ethereum.org/@lightclient/rJ0nTvKIj) - [x] Specify `JUMPF` [EIPs#6023](https://github.com/ethereum/EIPs/pull/6023) - [ ] Add `Security Considerations` section. - [x] Move to `Review` status. [EIPs#6079](https://github.com/ethereum/EIPs/pull/6079) - [x] Agree on [Type section flags](https://notes.ethereum.org/@ipsilon/SJbHuChTj) - Agreement is not having a dedicated flags field, but using `0x81` in `num_outputs` to denote "non-returning" functions. - [ ] **EIP-5450**: EOF - Stack Validation - [x] Lift the requirement to clean the stack for terminating instructions (`STOP`, `RETURN`, etc). For `RETF` see above. [EIPs#6080](https://github.com/ethereum/EIPs/pull/6080) - [x] Lift the requirement of the last instruction to be terminating (if unreachable). This is one less check to have in the implementation. - Stack validation ensures that execution is terminated properly. - [x] ~~Consider~~Prototype "single-pass" verification algorithm. [Discord#evm](https://discord.com/channels/595666850260713488/706868829900505180/1041845239322779679) - [x] Put function `max_stack_height` in the type section. - [x] New algorithm: [EIPs#5993](https://github.com/ethereum/EIPs/pull/5993) - [x] Simplify `JUMPF` via stack validation [EIPs#6101](https://github.com/ethereum/EIPs/pull/6101) - [ ] Add `Security Considerations` section. - [x] Move to `Review` status. [EIPs#6079](https://github.com/ethereum/EIPs/pull/6079) - [ ] **NEW** Consider check to be `<= max_stack_height` declared. - [x] Gas costs overview - `JUMP` (8) - `JUMPI` (10) - `RJUMP` (2) - load 2 bytes of immediate (with rotate) - fancy PC update - `RJUMPI` (4) - stack underflow check - pop value and compare with zero (+2) - `RJUMP` - `RJUMPV` (4) - stack underflow check - pop value, compare immediate value and read offset (+2) - `RJUMP` - `RETF` (3) - works similar to `RJUMP` except pops jump target from the call stack - (assuming no stack memmove) - `CALLF` (5) - load 1 byte of immediate the function index - lookup the function code start in the lookup table - push current PC to the call stack - in basic form no stack overflow/underflow checks - in advanced form stack overflow check - fancy PC update - `JUMPF` (4) ## Updates ### March 8th - Agreed to merge https://github.com/ethereum/EIPs/pull/6546 - Agreed to merge https://github.com/ethereum/EIPs/pull/6328 - Agreed that no `flags` field is introduced and `0x81` is used to denote non-returning functions