# EOFv1 Checklist [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.** 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)) ## Implementation | | Spec | Tests | Solidity | Vyper | Evmone + <br/>Silkworm | Geth | Besu | Nethermind | Erigon | EthereumJS | |----------|------|-------|----|----------|--------|------|------|------------|--------|------------| | EIP-3860 | ✅ | ✅ | 🚧 | ❌ | 🚧 | 🚧 | ✅ | ✅ | ✅ | ✅ | | 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` summary](https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md#readiness-checklist) - `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/1087) - [EIP-4200](https://github.com/ethereum/tests/pull/1103) - [EIP-4750](https://github.com/ethereum/tests/pull/1115) - EIP-5450 (tbd) ### Solidity - [Implementation tracking issue](https://github.com/ethereum/solidity/issues/13717) - [`eofVersion` flag to enable EOF support](https://github.com/ethereum/solidity/pull/13733) - [EIP-3540 aka basic containers](https://github.com/ethereum/solidity/pull/13772) - [EIP-4200](https://github.com/ethereum/solidity/pull/13783) - [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) - [EIP-3540 + EIP-3670](https://github.com/ethereum/evmone/pull/334) (merged) - [EIP-4200](https://github.com/ethereum/evmone/pull/389) - [EIP-4750](https://github.com/ethereum/evmone/pull/497) ### Geth - [EIP-3860](https://github.com/ethereum/go-ethereum/pull/23847) - ["Full suite" EIP-3540/EIP-3670/EIP-4200/EIP-4750](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) - [EIP-4750](https://github.com/hyperledger/besu/pull/4781) - Missing: EIP-5450 ### 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) - Missing: EIP-5450 ### 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) - Missing: EIP-5450 ### 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] **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) - [ ] **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) - [ ] **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)