diff --git a/EIPS/eip-7761.md b/EIPS/eip-7761.md index ecd40558d67aa..d42f574a7ee55 100644 --- a/EIPS/eip-7761.md +++ b/EIPS/eip-7761.md @@ -1,7 +1,7 @@ --- eip: 7761 -title: ISCONTRACT instruction -description: Introduce ISCONTRACT instruction to replace the EXTCODESIZE > 0 check in EOF +title: HASCODE instruction +description: Introduce HASCODE instruction to replace the EXTCODESIZE > 0 check in EOF author: Andrei Maiboroda (@gumb0), Piotr Dobaczewski (@pdobacz), Danno Ferrin (@shemnon) discussions-to: https://ethereum-magicians.org/t/eip-7761-is-contract-instruction/20936 status: Draft @@ -13,7 +13,7 @@ requires: 3540, 7692 ## Abstract -Allow EOF contracts to discriminate between EOAs (Externally Owned Accounts) and contract accounts by introducing an `ISCONTRACT` instruction. +Allow EOF contracts to discriminate between EOAs (Externally Owned Accounts) and contract accounts by introducing an `HASCODE` instruction. ## Motivation @@ -22,7 +22,7 @@ EOFv1 as scoped in [EIP-7692](./eip-7692.md) removes code introspection capabili - `safeTransfers` to EOAs succeed - `safeTransfers` to contract accounts call an `onERC721Received` (`onERC1155Received`) on them and expect to get a special magic return value, otherwise the transfer reverts (on the assumption that such a receipient may not be able to interact with the token) -`ISCONTRACT` is aimed to fill this gap and bring back the possibility to easily implement ERC-721 and ERC-1155 standard contracts in EOF. +`HASCODE` is aimed to fill this gap and bring back the possibility to easily implement ERC-721 and ERC-1155 standard contracts in EOF. ## Specification @@ -34,13 +34,13 @@ EOFv1 as scoped in [EIP-7692](./eip-7692.md) removes code introspection capabili | `GAS_COLD_ACCOUNT_ACCESS` | Defined as `2600` in the [Ethereum Execution Layer Specs](https://github.com/ethereum/execution-specs/blob/fcd12750edd4443a91f138728689a1d0a503a7c1/src/ethereum/cancun/vm/gas.py#L64) | | `GAS_WARM_ACCESS` | Defined as `100` in the [Ethereum Execution Layer Specs](https://github.com/ethereum/execution-specs/blob/fcd12750edd4443a91f138728689a1d0a503a7c1/src/ethereum/cancun/vm/gas.py#L65) | -We introduce a new EOFv1 instruction on the block number `FORK_BLKNUM`: `ISCONTRACT` (`0xe9`) +We introduce a new EOFv1 instruction on the block number `FORK_BLKNUM`: `HASCODE` (`0xe9`) EOF code which contains this instruction before `FORK_BLKNUM` is considered invalid. Beginning with block `FORK_BLKNUM` `0xe9` is added to the set of valid EOFv1 instructions. ### Execution Semantics -#### `ISCONTRACT` +#### `HASCODE` - deduct `GAS_WARM_ACCESS` gas - pop 1 argument `target_address` from the stack @@ -48,7 +48,7 @@ EOF code which contains this instruction before `FORK_BLKNUM` is considered inva - deduct `GAS_COLD_ACCOUNT_ACCESS - GAS_WARM_ACCESS` if `target_address` is not in `accessed_addresses` and add `target_address` to `accessed_addresses` - push `1` onto the stack if `target_address.code` is not empty, `0` otherwise -If `target_address.code` contains an [EIP-7702](./eip-7702.md) delegation, the result of `ISCONTRACT` should follow the delegation and return a result according to the delegation designator account. Additional gas costs and rules concering `accessed_addresses` apply as specified in EIP-7702 for code reading instructions like `EXTCODESIZE`. +If `target_address.code` contains an [EIP-7702](./eip-7702.md) delegation, the result of `HASCODE` should follow the delegation and return a result according to the delegation designator account. Additional gas costs and rules concering `accessed_addresses` apply as specified in EIP-7702 for code reading instructions like `EXTCODESIZE`. If `target_address` points to an account with a contract mid-creation, it behaves aligned with similar instructions like `EXTCODESIZE` and returns `0`. @@ -64,15 +64,15 @@ There have been other solutions proposed to alleviate the problems related to la 4. `EXT*CALL` setting a new `callstatus` register (+ a new `CALLSTATUS` instruction) 5. Reenable `EXTCODESIZE` in EOF, keeping its behavior same as in legacy -`ISCONTRACT` has been chosen as the most elegant and minimal solution satisfying the requirements at hand and still able to be introduced in EOFv1. +`HASCODE` has been chosen as the most elegant and minimal solution satisfying the requirements at hand and still able to be introduced in EOFv1. -### Reuse the `0x3b` (`EXTCODESIZE`) opcode for `ISCONTRACT` +### Reuse the `0x3b` (`EXTCODESIZE`) opcode for `HASCODE` -A new opcode is prefered by a general policy to not reuse opcodes. Also `ISCONTRACT` can be rolled out in legacy EVM if desired. +A new opcode is prefered by a general policy to not reuse opcodes. Also `HASCODE` can be rolled out in legacy EVM if desired. ### Keep code introspection banned -Removing code introspection is one of the tenets of EOF and `ISCONTRACT` would be an exception from the principle. Without `ISCONTRACT`, ERC-721 and ERC-1155 standard implementations have to resort to either: +Removing code introspection is one of the tenets of EOF and `HASCODE` would be an exception from the principle. Without `HASCODE`, ERC-721 and ERC-1155 standard implementations have to resort to either: 1. Leveraging a "booster contract" which would be legacy and would call `EXTCODESIZE` for them. This has been deemed inelegant and inconvenient from the point of view of library implementers, requiring them to hard code an address of such a contract (with the usual address-related problems arising on different EVM chains) 2. Continuing to use legacy EVM themselves. This is sub-optimal, since EVM compilers are likely to at some point deprecate legacy EVM as compilation target @@ -84,19 +84,19 @@ TBD - can someone verbalize it? ### Relation to [EIP-7702](./eip-7702.md) "Set EOA account code" -After [EIP-7702](./eip-7702.md) is activated, the discrimination between EOAs and contract accounts using `EXTCODESIZE` (or `ISCONTRACT`) has an edge case: Whenever an EOA sets its code to a contract account which does not respond as expected to an `onERC721Received` (`onERC1155Received`) callback, transfers to it will revert, despite the recipient being able to interact with the token. This has been deemed unlikely to be a problem, as for the intended real-world uses of EIP-7702, those callbacks will be implemented by designator codes. +After [EIP-7702](./eip-7702.md) is activated, the discrimination between EOAs and contract accounts using `EXTCODESIZE` (or `HASCODE`) has an edge case: Whenever an EOA sets its code to a contract account which does not respond as expected to an `onERC721Received` (`onERC1155Received`) callback, transfers to it will revert, despite the recipient being able to interact with the token. This has been deemed unlikely to be a problem, as for the intended real-world uses of EIP-7702, those callbacks will be implemented by designator codes. ### Including safe guarding against proxy bricking In parallel to the ERC-721 / ERC-1155 problem, another potential risk has been brought to attention. Since EOFv1 prohibits `EXTDELEGATECALL` targetting legacy contracts, there exists a scenario where an EOF proxy contract accidentally upgrades its implementation to a legacy EVM one. Since reverting this or upgrading again (using current proxy standards) requires the implementation contract to be called, it would effectively render the contract unusable. -One potential solution to this would be to have a generalized `CONTRACT_KIND` instruction instead of `ISCONTRACT` which would further discriminate the account into legacy or EOFv1 with a `0` / `1` / `2` return value, thereby providing means for an additional safeguard against such a scenario. +One potential solution to this would be to have a generalized `CONTRACT_KIND` instruction instead of `HASCODE` which would further discriminate the account into legacy or EOFv1 with a `0` / `1` / `2` return value, thereby providing means for an additional safeguard against such a scenario. This problem is potentially solvable on the application layer (proxy upgrade would include a direct check of the implementation contract being `EXTDELEGATECALL`-able) or even by re-enabling `EXTDELEGATECALL` to a legacy target in a future EVM upgrade. ## Backwards Compatibility -`ISCONTRACT` at `0xe9` can be introduced in a backwards compatible manner into EOFv1 (no bump to version), because `0xe9` has been rejected by EOF validation before `FORK_BLKNUM` and there are no EOF contracts on-chain with a `0xe9` which would have their behavior altered. +`HASCODE` at `0xe9` can be introduced in a backwards compatible manner into EOFv1 (no bump to version), because `0xe9` has been rejected by EOF validation before `FORK_BLKNUM` and there are no EOF contracts on-chain with a `0xe9` which would have their behavior altered. ## Security Considerations