diff --git a/EIPS/eip-3074.md b/EIPS/eip-3074.md index 4414d473..1997e085 100644 --- a/EIPS/eip-3074.md +++ b/EIPS/eip-3074.md @@ -38,9 +38,9 @@ With the extraordinary growth of tokens on Ethereum, it has become common for EO | Constant | Value | | ---------------- | ------ | -| `TYPE` | `0x03` | +| `MAGIC` | `0x03` | -`TYPE` is an [EIP-2718](./eip-2718.md) transaction type reserved for EIP-3074 signatures to prevent signature collisions. +`MAGIC` is used for EIP-3074 signatures to prevent signature collisions with other signing formats. ### Context Variables @@ -67,13 +67,13 @@ A new opcode `AUTH` shall be created at `0xf6`. It shall take four stack element #### Output -| Stack | Value | -| ---------- | ------------------- | +| Stack | Value | +| ---------- | -------------| | `top - 0` | `authorized` | #### Behavior -The arguments (`yParity`, `r`, `s`) are interpreted as an ECDSA signature on the secp256k1 curve over the message `keccak256(TYPE || paddedInvokerAddress || commit)`, where: +The arguments (`yParity`, `r`, `s`) are interpreted as an ECDSA signature on the secp256k1 curve over the message `keccak256(MAGIC || paddedInvokerAddress || commit)`, where: - `paddedInvokerAddress` is the address of the contract executing `AUTH`, left-padded with zeroes to a total of 32 bytes (ex. `0x000000000000000000000000AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`). - `commit`, one of the arguments passed into `AUTH`, is a 32-byte value that can be used to commit to specific additional validity conditions in the invoker's pre-processing logic (e.g. a nonce for replay protection). @@ -88,7 +88,7 @@ The gas cost for `AUTH` is `3000`. This is the same cost as for the `ecrecover` ### `AUTHCALL` (`0xf7`) -A new opcode `AUTHCALL` shall be created at `0xf7`. It shall take seven stack elements and return one stack element. It matches the behavior of the existing `CALL` (`0xF1`) instruction, except where noted below. +A new opcode `AUTHCALL` shall be created at `0xf7`. It shall take eight stack elements and return one stack element. It matches the behavior of the existing `CALL` (`0xF1`) instruction, except where noted below. #### Input @@ -97,10 +97,11 @@ A new opcode `AUTHCALL` shall be created at `0xf7`. It shall take seven stack el | `top - 0` | `gas` | | `top - 1` | `addr` | | `top - 2` | `value` | -| `top - 3` | `argsOffset` | -| `top - 4` | `argsLength` | -| `top - 5` | `retOffset` | -| `top - 6` | `retLength` | +| `top - 3` | `valueExt` | +| `top - 4` | `argsOffset` | +| `top - 5` | `argsLength` | +| `top - 6` | `retOffset` | +| `top - 7` | `retLength` | #### Output @@ -115,7 +116,7 @@ A new opcode `AUTHCALL` shall be created at `0xf7`. It shall take seven stack el - If `authorized` is unset, execution is considered invalid and must exit the current execution frame immediately (in the same way as a stack underflow or invalid jump). - Otherwise, the caller address for the call is set to `authorized`. -The call value is deducted from the balance of the executing contract. It is not paid by the `authorized`. +The parameter `value` is deducted from the balance of the executing contract. It is not paid by `authorized`. The parameter `valueExt` must be zero, otherwise the instruction must exit the current execution frame immediately. In the future, this restriction may be relaxed to externally transfer value out of the `authorized` account. `AUTHCALL` must increase the call depth by one. `AUTHCALL` must not increase the call depth by two as if it first called into the authorized account and then into the target. @@ -131,13 +132,9 @@ As with `CALL`, the gas cost for the opcode itself (both the static and the dyna ## Rationale -### Throwing for Unset `authorized` During `AUTHCALL` +### Throwing for Unset `authorized` or Invalid `valueExt` During `AUTHCALL` -A well-behaved contract should never reach an `AUTHCALL` without having successfully set `authorized` beforehand. The safest behavior, therefore, is to exit the current frame of execution immediately. This is especially important in the context of transaction sponsoring / relaying, which is expected to be one of the main use cases for this EIP. In a sponsored transaction, the inability to distinguish between a sponsee-attributable fault (like a failing sub-call) and a sponsor-attributable fault (like a failing `AUTH`) is especially dangerous and should be prevented because it charges unfair fees to the sponsee. - -### Reserving an [EIP-2718](./eip-2718.md) Transaction Type - -While clients should never interpret EIP-3074 signed messages as transactions, reserving an [EIP-2718](./eip-2718.md) transaction type reduces the likelihood of this occurring by accident. +A well-behaved contract should never reach an `AUTHCALL` without having successfully set `authorized` beforehand. Similarly, it should never set `valueExt` to be non-zero. The safest behavior, therefore, is to exit the current frame of execution immediately. This is especially important in the context of transaction sponsoring / relaying, which is expected to be one of the main use cases for this EIP. In a sponsored transaction, the inability to distinguish between a sponsee-attributable fault (like a failing sub-call) and a sponsor-attributable fault (like a failing `AUTH`) is especially dangerous and should be prevented because it charges unfair fees to the sponsee. ### Another Sponsored Transaction EIP @@ -204,7 +201,7 @@ Any non-zero `value` passed into an `AUTHCALL` is deducted from the invoker's ba * Transaction pools expect transactions for a given EOA to only turn invalid when other transactions from the same EOA are included into a block, increasing its nonce and (possibly) decreasing its balance. Deducting `value` from the `authorized` account would make transaction invalidation an unpredictable side effect of any smart contract execution. * Similarly, miners rely on the ability to statically pick a set of valid transactions from their transaction pool to include into a new block. Deducting `value` from the `authorized` account would break this ability, increasing the overhead and thus the time for block creation. -At the same time, the ability to directly take ether out of the `authorized` account is an important piece of functionality and thus an desired future addition via an additional opcode similar to `AUTHCALL`. The prerequisite for that would be to find satisfying mitigations to the transaction invalidation concerns outlined above. One potential avenue for that could be the addition of account access lists similar to EIP-2930, used to signal accounts whose balance can be reduced as a side effect of the transaction (without on their own constituting authorization to do so). +At the same time, the ability to directly take ether out of the `authorized` account is an important piece of functionality and thus an desired future addition via an additional opcode similar to `AUTHCALL`. For this reason, it is included as `valueExt`, an operand of `AUTHCALL` and may activated in a future fork. The prerequisite for that would be to find satisfying mitigations to the transaction invalidation concerns outlined above. One potential avenue for that could be the addition of account access lists similar to EIP-2930, used to signal accounts whose balance can be reduced as a side effect of the transaction (without on their own constituting authorization to do so). ## Backwards Compatibility