diff --git a/EIPS/eip-7069.md b/EIPS/eip-7069.md index 1795943aeacc86..76ed48f905a9d8 100644 --- a/EIPS/eip-7069.md +++ b/EIPS/eip-7069.md @@ -8,12 +8,12 @@ status: Draft type: Standards Track category: Core created: 2023-05-05 -requires: 150, 211, 214, 2929 +requires: 150, 211, 214, 2929, 3540 --- ## Abstract -Introduce three new call instructions, `EXTCALL`, `EXTDELEGATECALL` and `EXTSTATICCALL`, with simplified semantics. Introduce another instruction, `RETURNDATALOAD` for loading a word from return data into stack. The existing call instructions remain unchanged. +Introduce three new call instructions, `EXTCALL`, `EXTDELEGATECALL` and `EXTSTATICCALL`, with simplified semantics. Introduce another instruction, `RETURNDATALOAD` for loading a word from return data into stack. Modify the behavior of `RETURNDATACOPY` instruction executed within EOF formatted code (as defined by [EIP-3540](./eip-3540.md)). The existing `*CALL` instructions remain unchanged. The new instructions do not allow specifying a gas limit, but rather rely on the "63/64th rule" ([EIP-150](./eip-150.md)) to limit gas. An important improvement is the rules around the "stipend" are simplified, and callers do not need to perform special calculation whether the value is sent or not. @@ -86,8 +86,16 @@ Execution semantics of `RETURNDATALOAD`: 1. Charge `G_verylow` (3) gas 2. Pop 1 item from the stack, to be referred to as `offset` -3. If `offset + 32 > len(returndata buffer)`, halt with exceptional failure. -4. Push 1 item onto the stack, the 32-byte word read from the returndata buffer starting at `offset`. +3. Push 1 item onto the stack, the 32-byte word read from the returndata buffer starting at `offset`. +4. If `offset + 32 > len(returndata buffer)`, the result is zero-padded. + +In case this EIP is included as part of the greater EOF upgrade, execution semantics of `RETURNDATACOPY` in EOF formatted code ([EIP-3540](./eip-3540.md)) is modified as follows: + +1. Assume the 3 arguments popped from stack are `destOffset`, `offset` and `size`. +2. If `offset + size > len(returndata buffer)` **do not** halt with exceptional failure, but instead set the `offset + size - len(returndata buffer)` memory bytes after the copied ones to zero. +3. Gas charged for memory copying remains `3 * num_words(size)`, regardless of the number of bytes actually copied or set to zero. + +Execution of `RETURNDATACOPY` which is not in EOF formatted code (i.e. is in legacy code) is not changed. @@ -186,6 +194,14 @@ Smart contract developers should not rely on the operation reverting when such a There is an alternative scenario where, in case this EIP is included as part of the greater EOF upgrade, the four new instructions are **additionally** available in legacy EVM. There is, however, a preference to limit changes to legacy EVM in the fork where EOF is included as well as in subsequent ones. +### `RETURNDATALOAD` and `RETURNDATACOPY` padding behavior + +This EIP initially proposed keeping the halt-on-OOB behavior of legacy `RETURNDATACOPY`. This makes compilers optimizations harder, because unnecessary `RETURNDATA*` instructions cannot be optimized out without change to code semantics. + +It could be that only `RETURNDATALOAD` is given the padding behavior, but that would make it confusingly inconsistent with the closely related `RETURNDATACOPY` instruction. + +There also was the alternative to have `RETURNDATACOPY2` introduced with the padding behavior, available in EOF only, at the same time banning `RETURNDATACOPY` in EOF. This has been rejected in order to avoid multiplying opcodes, and also as suboptimal from the point of view of compiler implementation. + ## Backwards Compatibility No existing instructions are changed and so we do not think any backwards compatibility issues can occur.