This EIP introduces a new opcode, PAY
, taking two stack parameters, addr
and val
, that transfers val
wei to the address addr
without calling any of its functions.
Currently, to send ether to an address requires you to call into that address, which transfers execution context to that address, which creates several issues:
CALL
and EXTCALL
opcodes will execute code on the recipient, which is unintended when wanting to send ether and which could lead to unintentional operations. The code execution also has to be paid for in gas, even when the intention is to only send ether, which is thus an unnecessary waste of gas.Having a dedicated opcode for ether transfers solves all of these issues, and would be a useful addition to the EVM.
Constant | Definition |
---|---|
WARM_STORAGE_READ_COST |
EIP-2929 |
COLD_ACCOUNT_ACCESS_COST |
EIP-2929 |
GAS_NEW_ACCOUNT |
EELS |
GAS_CALL_VALUE |
EELS |
A new opcode is introduced: PAY
(0xfc
), which:
addr
then val
.addr
has any of the high 12 bytes set to a non-zero value (i.e. it does not contain a 20-byte address).addr
as warm (adding addr
to accessed_addresses
).val
wei from the current address to the address addr
, only if the current address has a balance greater than or equal to val
.1
on the stack if the PAY
operation was successful, or 0
if it failed.0
return value.The gas cost for PAY
is the sum of the following:
addr
in accessed_addresses
?WARM_STORAGE_READ_COST
;COLD_ACCOUNT_ACCESS_COST
.addr
exist or is val
zero?GAS_NEW_ACCOUNT
.val
zero?GAS_CALL_VALUE
.PAY
cannot be implemented on networks with empty accounts (see EIP-7523).
The order of arguments mimics that of CALL
, which pops addr
before val
. Beyond consistency, though, this ordering aids validators pattern-matching MEV opportunities, so PAY
always appears immediately after COINBASE
.
The halting behavior is designed to allow for Address Space Extension.
If the high bytes were truncated, as in CALL
, contracts could depend on the truncating behavior.
If the address space were extended beyond 20 bytes, PAY
would either not be able to target those accounts, or code expecting truncation could send ether to the wrong address.
Because this behavior may be changed, contracts should not rely on this halting behavior and use methods designated to intentionally halt (such as the INVALID
opcode).
This change requires a hard fork.
Existing contracts should not rely on their balance being under their control, since it is already possible to send ether to an address without calling it, by using the SELFDESTRUCT
opcode (somewhat restricted in EIP-6780).
It is also possible to involuntarily fund an account with priority fees sent to a block.coinbase
.
However, this opcode does make this process cheaper and easier. It thus does not break an invariant.
Copyright and related rights waived via CC0.