Table of contents
Opcode-specific error handling
Issues and fixes for opcode specific error handling.
EVM and its feature upgrades are designed and developed by different people, with different understanding of how the system works. Overtime, inconsistencies in error handling appear. They create confusions for implementors. As a result, when account versioning is deployed, it may also be good to fix those inconsistencies once and for all.
Check Arithmetic Overflow
Proposals: EIP-1051
This cleans up the long-standing issue that arithmetic opcodes in EVM silently warps when overflowing. This has turned out to be a security issue, with known exploit happened in the past.
Consistent copy-to-memory behavior
Some opcodes requires copying data into EVM memory. Overtime, inconsistent behavior appears. Some opcodes will panic if the offset of the data is out of range, while some other opcodes will silently assume that the data is zero. This specification attempts to make it consistent, by changing all opcodes to panic.
Specification
Change the behavior of the following opcodes:
-
In
CALLDATALOAD
, ifstack(0) + 32
overflows or is greater than the length of call data, return unrecoverable error. -
In
CALLDATACOPY
, ifstack(1) + stack(2)
overflows or is greater than the legnth of call data, return unrecoverable error. -
In
CODECOPY
, ifstack(1) + stack(2)
overflows or is greater than the length of code, return unrecoverable error. -
In
EXTCODECOPY
, ifstack(2) + stack(3)
overflows or is greater than the length of external code, return unrecoverable error.
Interactions
This assumes that we have a forward-compatible EVM that is deployed to support unrecoverable error, such as 39-UNGAS.
Explicit memory growth
Current EVM silently grows memory, whenever a higher region is
accessed. While this design does not have apparent downside, it
slightly complicates analysis of a program and implementation of EVM,
in that the total memory used is implicit. In this specification, we
explore ways to use new opcodes GROWMEMORY
to make memory growth
explicit.
Specification
Add opcode GROWMEMORY
(0xfd
). It pops one item target
from the
stack. The instruction charges G_BASE
and then sets the total
available memory size to target
. It then charge gas cost according
to current rules for memory cost. If target
is smaller than the
current memory size, the instruction will shrink the memory, but will
not refund any gas. If the gas cost charge fails, return out-of-gas
error.
Remove checks and charges of memory gas for the following opcodes. Add an additional check for each of them in relation with current memory size, and return unrecoverable error if the check fails.
-
For
SHA3
,RETURN
,REVERT
,LOG
, checkstack(0) + stack(1) ⇐ memory_len
. -
For
CODECOPY
,CALLDATACOPY
,RETURNDATACOPY
, checkstack(0)
.
stack(2) ⇐ memory_len -
For
EXTCODECOPY
, checkstack(1) + stack(3) ⇐ memory_len
. -
For
MLOAD
,MSTORE
, checkstack(0) + 32 ⇐ memory_len
. -
For
MSTORE8
, checkstack(0) + 1 ⇐ memory_len
. -
For
CREATE
,CREATE2
, checkstack(1) + stack(2) ⇐ memory_len
. -
For
CALL
,CALLCODE
, checkstack(3) + stack(4) ⇐ memory_len
andstack(5) + stack(6) ⇐ memory_len
. -
For
DELEGATECALL
,STATICCALL
, checkstack(2) + stack(3) ⇐ memory_len
andstack(5) + stack(6) ⇐ memory_len
.
Interaction
Note that after 39-UNGAS, out-of-gas error will be an unrecoverable error.