Skip to content

Commit

Permalink
Update EIP-7069: add returndataload opcode
Browse files Browse the repository at this point in the history
Merged by EIP-Bot.
  • Loading branch information
charles-cooper authored Feb 1, 2024
1 parent a9f7ddb commit aabe10e
Showing 1 changed file with 16 additions and 8 deletions.
24 changes: 16 additions & 8 deletions EIPS/eip-7069.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
eip: 7069
title: Revamped CALL instructions
description: Introduce CALL2, DELEGATECALL2 and STATICCALL2 with simplified semantics
author: Alex Beregszaszi (@axic), Paweł Bylica (@chfast), Danno Ferrin (@shemnon), Andrei Maiboroda (@gumb0)
author: Alex Beregszaszi (@axic), Paweł Bylica (@chfast), Danno Ferrin (@shemnon), Andrei Maiboroda (@gumb0), Charles Cooper (@charles-cooper)
discussions-to: https://ethereum-magicians.org/t/eip-revamped-call-instructions/14432
status: Draft
type: Standards Track
Expand All @@ -13,11 +13,11 @@ requires: 150, 211, 214, 2929

## Abstract

Introduce three new call instructions, `CALL2`, `DELEGATECALL2` and `STATICCALL2`, with simplified semantics. The existing call instructions remain unchanged.
Introduce three new call instructions, `CALL2`, `DELEGATECALL2` and `STATICCALL2`, with simplified semantics. Introduce another instruction, `RETURNDATALOAD` for loading a word from return data into stack. 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.

Furthermore, the obsolete functionality of specifying output buffer address is removed in favor of using `RETURNDATACOPY` instead.
Furthermore, the obsolete functionality of specifying output buffer address is removed in favor of using `RETURNDATACOPY` instead. For cases which would previously `*CALL` output into a buffer and then `MLOAD` from the buffer, `RETURNDATALOAD` is provided instead.

Lastly, instead of returning a boolean for execution status, an extensible list of status codes is returned: `0` for success, `1` for revert, `2` for failure.

Expand All @@ -35,7 +35,7 @@ It is important to note that starting Solidity 0.4.21, the compiler already pass

Besides the above, this change introduces a convenience feature of returning more detailed status codes: success (0), revert (1), failure (2). This moves from the boolean option to codes, which are extensible in the future.

Lastly, the introduction of the `RETURNDATA*` instructions ([EIP-211](./eip-211.md)) has obsoleted the output parameters of calls, in a large number of cases rendering them unused. Using the output buffers have caused "bugs" in the past: in the case of [ERC-20](./eip-20.md), conflicting implementations caused a lot of trouble, where some would return something, while others would not. With relying on `RETURNDATA*` instructions this is implicitly clarified.
Lastly, the introduction of the `RETURNDATA*` instructions ([EIP-211](./eip-211.md)) has obsoleted the output parameters of calls, in a large number of cases rendering them unused. Using the output buffers have caused "bugs" in the past: in the case of [ERC-20](./eip-20.md), conflicting implementations caused a lot of trouble, where some would return something, while others would not. With relying on `RETURNDATA*` instructions this is implicitly clarified. This proposal also adds the "missing" `RETURNDATALOAD` instruction to round out returndata buffer access instructions.

## Specification

Expand All @@ -48,13 +48,14 @@ Lastly, the introduction of the `RETURNDATA*` instructions ([EIP-211](./eip-211.
| MIN_RETAINED_GAS | 5000 | |
| MIN_CALLEE_GAS | 2300 | |

We introduce three new instructions:
We introduce four new instructions:

- `CALL2` (`0xf8`) with arguments `(target_address, input_offset, input_size, value)`
- `DELEGATECALL2` (`0xf9`) with arguments `(target_address, input_offset, input_size)`
- `STATICCALL2` (`0xfb`) with arguments `(target_address, input_offset, input_size)`
- `RETURNDATALOAD` (`0xf7`) with argument `offset`

Execution semantics:
Execution semantics of `*CALL2`:

1. Charge `WARM_STORAGE_READ_COST` (100) gas.
2. Pop required arguments from stack, fail with error on stack underflow.
Expand All @@ -75,6 +76,13 @@ Execution semantics:
11c. `2` if the call has failed.
11. Gas not used by the callee is returned to the caller.

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`.

<!-- *TODO:* Clarify which side (caller/callee) is gas deducted from and where an error originates from. -->

<!-- *TODO:* Mention gas refunds? -->
Expand Down Expand Up @@ -113,7 +121,7 @@ We have changed the ruleset:

### Output buffers

The functionality of specifying output buffer address is removed, because it is added complexity and in a large number of cases implementers prefer to use `RETURNDATACOPY` instead. Even if they rely on the output buffer (like in the case of Vyper), they would still check the length with `RETURNDATASIZE`. In Solidity one exception is the case when the expected return size is known (i.e. non-dynamic return values), in this case Solidity still uses the output buffer.
The functionality of specifying output buffer address is removed, because it is added complexity and in a large number of cases implementers prefer to use `RETURNDATACOPY` instead. Even if they rely on the output buffer (like in the case of Vyper), they would still check the length with `RETURNDATASIZE`. In Solidity one exception is the case when the expected return size is known (i.e. non-dynamic return values), in this case Solidity still uses the output buffer. For these cases, `RETURNDATALOAD` is introduced, which simplifies the workflow of copying returndata into a (known) output buffer and using `MLOAD` from there; instead, `RETURNDATALOAD` can be used directly.

### Status codes

Expand All @@ -127,7 +135,7 @@ The order of parameters has been changed to move the `value` field to be the las

### Opcode encoding

Instead of introducing three new opcodes we have discussed a version with an immediate configuration byte (flags). There are two main disadvantages to this:
Instead of introducing three new `*CALL2` opcodes we have discussed a version with an immediate configuration byte (flags). There are two main disadvantages to this:

1. Some combination of flags may not be useful/be invalid, and this increases the testing/implementation surface.
2. The instruction could take variable number of stack items (i.e. `value` for `CALL2`) would be a brand new concept no other instruction has.
Expand Down

0 comments on commit aabe10e

Please sign in to comment.