From 21735026719bf4738f29b5ab67981e76b915d001 Mon Sep 17 00:00:00 2001 From: pdobacz <5735525+pdobacz@users.noreply.github.com> Date: Fri, 31 May 2024 15:19:10 +0200 Subject: [PATCH] Update EIP-7620: Initcode mode validation Merged by EIP-Bot. --- EIPS/eip-7620.md | 23 ++++++++++++++++------- EIPS/eip-7698.md | 8 ++------ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/EIPS/eip-7620.md b/EIPS/eip-7620.md index 1a12a066209c3..538afe2721cfa 100644 --- a/EIPS/eip-7620.md +++ b/EIPS/eip-7620.md @@ -71,7 +71,7 @@ Details on each instruction follow in the next sections. - check that current call depth is below `STACK_DEPTH_LIMIT` and that caller balance is enough to transfer `value` - in case of failure return 0 on the stack, caller's nonce is not updated and gas for initcode execution is not consumed. - caller's memory slice [`input_offset`:`input_size`] is used as calldata -- execute the container in "initcode-mode" and deduct gas for execution. The 63/64th rule from [EIP-150](./eip-150.md) applies. +- execute the container and deduct gas for execution. The 63/64th rule from [EIP-150](./eip-150.md) applies. - increment `sender` account's nonce - calculate `new_address` as `keccak256(0xff || sender || salt || keccak256(initcontainer))[12:]` - an unsuccessful execution of initcode results in pushing `0` onto the stack @@ -82,8 +82,6 @@ Details on each instruction follow in the next sections. - if updated deploy container size exceeds `MAX_CODE_SIZE` instruction exceptionally aborts - set `state[new_address].code` to the updated deploy container - push `new_address` onto the stack -- `RETURN` and `STOP` are not allowed in "initcode-mode" (abort execution) -- "initcode-mode" *is not transitive* - it is only active for the frame executing the initcontainer. If another (non-create) call is made from this frame, it *is not* executed in "initcode-mode". - deduct `GAS_CODE_DEPOSIT * deployed_code_size` gas #### `RETURNCONTRACT` @@ -93,16 +91,27 @@ Details on each instruction follow in the next sections. - cost 0 gas + possible memory expansion for aux data - ends initcode frame execution and returns control to EOFCREATE/4 caller frame where `deploy_container_index` and `aux_data` are used to construct deployed contract (see above) - instruction exceptionally aborts if after the appending, data section size would overflow the maximum data section size or underflow (i.e. be less than data section size declared in the header) -- instruction exceptionally aborts if invoked not in "initcode-mode" ### Code Validation + +For terminology purposes, the following concepts are defined: + +- an "initcode" container is one which does not contain `RETURN` or `STOP` +- a "runtime" container is one which does not contain `RETURNCONTRACT` + +Note a container can be both "initcode" and "runtime" if it does not contain any of `RETURN`, `STOP` or `RETURNCONTRACT` (for instance, if its code sections terminate with `REVERT` or `INVALID`). + We extend code section validation rules (as defined in [EIP-3670](./eip-3670.md)). 1. `EOFCREATE` `initcontainer_index` must be less than `num_container_sections` -1. `EOFCREATE` the subcontainer pointed to by `initcontainer_index` must have its `len(data_section)` equal `data_size`, i.e. data section content is exactly as the size declared in the header (see [Data section lifecycle](#data-section-lifecycle)) -2. `RETURNCONTRACT` `deploy_container_index` must be less than `num_container_sections` -3. `RJUMP`, `RJUMPI` and `RJUMPV` immediate argument value (jump destination relative offset) validation: code section is invalid in case offset points to the byte directly following either `EOFCREATE` or `RETURNCONTRACT` instruction. +2. `EOFCREATE` the subcontainer pointed to by `initcontainer_index` must have its `len(data_section)` equal `data_size`, i.e. data section content is exactly as the size declared in the header (see [Data section lifecycle](#data-section-lifecycle)) +3. `EOFCREATE` the subcontainer pointed to by `initcontainer_index` must be an "initcode" subcontainer +4. `RETURNCONTRACT` `deploy_container_index` must be less than `num_container_sections` +5. `RETURNCONTRACT` the subcontainer pointed to `deploy_container_index` must be a "runtime" subcontainer +6. It is an error for a container to contain both `RETURNCONTRACT` and either of `RETURN` or `STOP` +7. It is an error for a subcontainer to never be referenced in code sections of its parent container +8. `RJUMP`, `RJUMPI` and `RJUMPV` immediate argument value (jump destination relative offset) validation: code section is invalid in case offset points to the byte directly following either `EOFCREATE` or `RETURNCONTRACT` instruction. ### Data Section Lifecycle diff --git a/EIPS/eip-7698.md b/EIPS/eip-7698.md index 5cb917d2ec995..095d1311a2dd8 100644 --- a/EIPS/eip-7698.md +++ b/EIPS/eip-7698.md @@ -35,17 +35,14 @@ In case a creation transaction (transaction with empty `to`) has `data` starting 1. Intrinsic gas cost rules and limits defined in [EIP-3860](./eip-3860.md) for creation transactions apply. The entire `data` of the transaction is used for these calculations. 2. Find the split of `data` into `initcontainer` and `calldata`: - - Parse EOF header - Find `intcontainer` size by reading all section sizes from the header and adding them up with the header size to get the full container size. - 3. Validate the `initcontainer` and all its subcontainers recursively. - - Unlike in general validation, `initcontainer` is additionally required to have `data_size` declared in the header equal to actual `data_section` size. - + - Validation includes checking that the container is an "initcode" container as defined in [EIP-7620](./eip-7620.md), that is, it does not contain `RETURN` or `STOP` 4. If EOF header parsing or full container validation fails, transaction is considered valid and failing. Gas for initcode execution is not consumed, only intrinsic creation transaction costs are charged. 5. `calldata` part of transaction `data` that follows `initcontainer` is treated as calldata to pass into the execution frame. -6. Execute the container in "initcode-mode" (see [EIP-7620](./eip-7620.md)) and deduct gas for execution. +6. Execute the container and deduct gas for execution. 1. Calculate `new_address` as `keccak256(sender || sender_nonce)[12:]` 2. A successful execution ends with initcode executing `RETURNCONTRACT{deploy_container_index}(aux_data_offset, aux_data_size)` instruction. After that: - load deploy-contract from EOF subcontainer at `deploy_container_index` in the container from which `RETURNCONTRACT` is executed, @@ -53,7 +50,6 @@ In case a creation transaction (transaction with empty `to`) has `data` starting - let `deployed_code_size` be updated deploy container size, - if `deployed_code_size > MAX_CODE_SIZE` instruction exceptionally aborts, - set `state[new_address].code` to the updated deploy container. - 3. `RETURN` and `STOP` are not allowed in "initcode-mode" (abort execution) 7. Deduct `200 * deployed_code_size` gas. ## Rationale