diff --git a/EIPS/eip-5920.md b/EIPS/eip-5920.md index ac2f307b295e8..ba7a1ac496ef9 100644 --- a/EIPS/eip-5920.md +++ b/EIPS/eip-5920.md @@ -2,13 +2,13 @@ eip: 5920 title: PAY opcode description: Introduces a new opcode, PAY, to send ether to an address without calling any of its functions -author: Gavin John (@Pandapip1), Zainan Victor Zhou (@xinbenlv) +author: Gavin John (@Pandapip1), Zainan Victor Zhou (@xinbenlv), Sam Wilson (@SamWilsn) discussions-to: https://ethereum-magicians.org/t/eip-5920-pay-opcode/11717 status: Review type: Standards Track category: Core created: 2022-03-14 -requires: 2929 +requires: 2929, 7523 --- ## Abstract @@ -25,26 +25,47 @@ Currently, to send ether to an address requires you to call into that address, w ## Specification -| Parameter | Value | -| ------------------- | ------- | -| `PAY_OPCODE` | `0xf9` | +### Constants -A new opcode is introduced: `PAY` (`PAY_OPCODE`), which: +| Constant | Definition | +| -------------------------- | ------------------------- | +| `WARM_STORAGE_READ_COST` | [EIP-2929](./eip-2929.md) | +| `COLD_ACCOUNT_ACCESS_COST` | [EIP-2929](./eip-2929.md) | +| `GAS_NEW_ACCOUNT` | [EELS][gna] | +| `GAS_CALL_VALUE` | [EELS][gcv] | + +[gna]: https://github.com/ethereum/execution-specs/blob/4d953035fb0cceda7cf21d71b2ab7a9a6f4632f0/src/ethereum/frontier/vm/gas.py#L52 +[gcv]: https://github.com/ethereum/execution-specs/blob/4d953035fb0cceda7cf21d71b2ab7a9a6f4632f0/src/ethereum/frontier/vm/gas.py#L53 + +### Behavior + +A new opcode is introduced: `PAY` (`0xf9`), which: - Pops two values from the stack: `addr` then `val`. -- Transfers `val` wei from the executing address to the address `addr`, even if `addr` is the zero address. +- Transfers `val` wei from the current target address to the address `addr`. +- Marks `addr` as warm (adding `addr` to `accessed_addresses`.) -The base cost of this opcode is the additional cost of having a nonzero `msg.value` in a `CALL` opcode (currently `9000`). If `addr` is not the zero address, the [EIP-2929](./eip-2929.md) account access costs for `addr` (but NOT the current account) are also incurred: 100 gas for a warm account, 2600 gas for a cold account, and 25000 gas for a new account. If any of these costs are changed, the pricing for the `PAY` opcode must also be changed. +### Gas Cost -## Rationale +The gas cost for `PAY` is the sum of the following: + +- Is `addr` in `accessed_addresses`? + - If yes, `WARM_STORAGE_READ_COST`; + - Otherwise, `COLD_ACCOUNT_ACCESS_COST`. +- Does `addr` exist or is `val` zero? + - If yes to either, zero; + - Otherwise, `GAS_NEW_ACCOUNT`. +- Is `val` zero? + - If yes, zero; + - Otherwise, `GAS_CALL_VALUE`. -### Gas pricing +`PAY` cannot be implemented on networks with empty accounts (see [EIP-7523](./eip-7523.md).) -The additional nonzero `msg.value` cost of the `CALL` should equal the cost of transferring ether. Therefore, that is the base cost of this opcode. Additionally, the access costs for the receiving account make sense, since the account needs to be accessed. However, it is reasonable to assume that optimized execution clients have the data for the executing contract cached. +## Rationale ### Argument order -The order of arguments mimicks 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 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`. ## Backwards Compatibility