Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP 3540 Addition: EOF1 contracts can only DELEGATECALL EOF1 contracts #6359

Closed
wants to merge 5 commits into from
Closed
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion EIPS/eip-3540.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
eip: 3540
title: EOF - EVM Object Format v1
description: EOF is an extensible and versioned container format for EVM bytecode with a once-off validation at deploy time.
author: Alex Beregszaszi (@axic), Paweł Bylica (@chfast), Andrei Maiboroda (@gumb0)
author: Alex Beregszaszi (@axic), Paweł Bylica (@chfast), Andrei Maiboroda (@gumb0), Hubert Ritzdorf (@ritzdorf)
discussions-to: https://ethereum-magicians.org/t/evm-object-format-eof/5727
status: Review
type: Standards Track
Expand Down Expand Up @@ -164,6 +164,7 @@ For clarity, the *container* refers to the complete account code, while *code* r
4. `CODECOPY`/`CODESIZE`/`EXTCODECOPY`/`EXTCODESIZE`/`EXTCODEHASH` keeps operating on the entire *container*.
5. The input to `CREATE`/`CREATE2` is still the entire *container*.
6. The size limit for deployed code as specified in [EIP-170](./eip-170.md) and for initcode as specified in [EIP-3860](./eip-3860.md) is applied to the entire *container* size, not to the *code* size. This also means if initcode validation fails, it is still charged the EIP-3860 `initcode_cost`.
7. When an EOF1 contract performs a `DELEGATECALL` the target cannot be EOF0. If it is EOF0, the `DELEGATECALL` exceptionally halts. Hence, (among other things) all the gas passed to the `DELEGATECALL` is consumed and 0 is pushed onto the stack. `DELEGATECALL` from EOF1 to an empty container also fails. In case the `DELEGATECALL` fails as described here, the target address still becomes warm.

(*Remark:* Due to [EIP-4750](./eip-4750.md), `JUMP` and `JUMPI` are disabled and therefore are not discussed in relation to EOF.)

Expand Down Expand Up @@ -250,6 +251,10 @@ It is possible in the future that this data will be accessible with data-specifi

The value for `PC` is specified to start at 0 and to be within the active *code* section. We considered keeping `PC` to operate on the whole *container* and be consistent with `CODECOPY`/`EXTCODECOPY` but in the end decided otherwise. This also feels more natural and easier to implement in EVM: the new EOF EVM should only care about traversing *code* and accessing other parts of the *container* only on special occasions (e.g. in `CODECOPY` instruction).

### EOF1 contracts can only `DELEGATECALL` EOF1 contracts

Currently contracts can selfdestruct in three different ways (directly through `SELFDESTRUCT`, indirectly through `CALLCODE` and indirectly through `DELEGATECALL`). [EIP-3670](./eip-3670.md) disables the first two possibilities, however the third possibility remains. Allowing EOF1 contracts to only `DELEGATECALL` other EOF1 contracts allows the following strong statement: EOF1 contract can never be destructed. Attacks based on `SELFDESTRUCT` completely disappear for EOF1 contracts. These include destructed library contracts (e.g. Parity Multisig).

## Backwards Compatibility

This is a breaking change given that any code starting with `0xEF` was not deployable before (and resulted in exceptional abort if executed), but now some subset of such codes can be deployed and executed successfully.
Expand Down Expand Up @@ -291,6 +296,10 @@ All cases should be checked for creation transaction, `CREATE` and `CREATE2`.
- `EXTCODECOPY` can copy from target's EOF header
- `EXTCODECOPY` can copy entire target container
- Results don't differ when executed inside legacy or EOF contract
- EOF1 `DELEGATECALL`
- `DELEGATECALL` to EOF1 code succeeds
- `DELEGATECALL` to EOF0 code fails
- `DELEGATECALL` to empty container fails

## Security Considerations

Expand Down