diff --git a/EIPS/eip-8024.md b/EIPS/eip-8024.md index b9a5fa56ec91e4..8f1302d6b69eed 100644 --- a/EIPS/eip-8024.md +++ b/EIPS/eip-8024.md @@ -2,7 +2,7 @@ eip: 8024 title: Backward compatible SWAPN, DUPN, EXCHANGE description: Introduce additional instructions for manipulating the stack which allow accessing the stack at higher depths -author: Francisco Giordano (@frangio), Charles Cooper (@charles-cooper), Alex Beregszaszi (@axic) +author: Francisco Giordano (@frangio), Charles Cooper (@charles-cooper), Alex Beregszaszi (@axic), Paweł Bylica (@chfast) discussions-to: https://ethereum-magicians.org/t/eip-8024-backward-compatible-swapn-dupn-exchange/25486 status: Review type: Standards Track @@ -61,7 +61,7 @@ Formally, when `code[pc]` is one of these opcodes, the VM executes as follows: - `EXCHANGE`: 1. Charge 3 gas. 2. Let `x = code[pc + 1]`. - 3. If `79 < x < 128`, halt with exceptional failure. + 3. If `81 < x < 128`, halt with exceptional failure. 4. Let `n, m = decode_pair(x)`. 5. If `m + 1 > len(stack)`, halt with exceptional failure. 5. Swap `stack[top - n]` and `stack[top - m]`. @@ -78,14 +78,11 @@ The auxiliary functions `decode_single` and `decode_pair` are defined by the fol ```python def decode_single(x: int) -> int: assert 0 <= x <= 90 or 128 <= x <= 255 - if x <= 90: - return x + 17 - else: - return x - 20 + return (x + 145) % 256 def decode_pair(x: int) -> tuple[int, int]: - assert 0 <= x <= 79 or 128 <= x <= 255 - k = x if x <= 79 else x - 48 + assert 0 <= x <= 81 or 128 <= x <= 255 + k = x ^ 143 q, r = divmod(k, 16) if q < r: return q + 1, r + 1 @@ -98,19 +95,16 @@ Assemblers and compilers must emit a 1-byte immediate after each of these opcode ```python def encode_single(n: int) -> int: assert 17 <= n <= 235 - if n <= 107: - return n - 17 - else: - return n + 20 + return (n + 111) % 256 def encode_pair(n: int, m: int) -> int: - assert 1 <= n <= 13 and n < m <= 29 and n + m <= 30 + assert 1 <= n <= 14 and n < m <= 29 and n + m <= 30 if m <= 16: q, r = n - 1, m - 1 else: q, r = 29 - m, n - 1 k = 16 * q + r - return k if k <= 79 else k + 48 + return k ^ 143 ``` ## Rationale @@ -166,29 +160,31 @@ This has no effect on contracts that would never attempt to execute the opcodes ### Assembly/Disassembly -- `e600` is `[DUPN 17]` -- `e780` is `[SWAPN 108]` -- `e6005b` is `[DUPN 17, JUMPDEST]` +- `e680` is `[DUPN 17]` +- `e7db` is `[SWAPN 108]` +- `e6805b` is `[DUPN 17, JUMPDEST]` - `e75b` is `[INVALID_SWAPN, JUMPDEST]` - `e6605b` is `[INVALID_DUPN, PUSH1 0x5b]` - `e7610000` is `[INVALID_SWAPN, PUSH2 0x0000]` - `e65f` is `[INVALID_DUPN, PUSH0]` -- `e812` is `[EXCHANGE 2 3]` -- `e8d0` is `[EXCHANGE 1 19]` -- `e850` is `[INVALID_EXCHANGE, POP]` +- `e89d` is `[EXCHANGE 2 3]` +- `e82f` is `[EXCHANGE 1 19]` +- `e850` is `[EXCHANGE 14 16]` +- `e851` is `[EXCHANGE 14 15]` +- `e852` is `[INVALID_EXCHANGE, MSTORE]` ### Execution -- `60016000808080808080808080808080808080e600` results in 18 stack items, the top of the stack valued 1, the bottom of the stack valued 1, the rest valued 0 - - `60016000808080808080808080808080808080e6` at the end of the code is equivalent to above -- `600160008080808080808080808080808080806002e700` results in 18 stack items, the top of the stack valued 1, the bottom of the stack valued 2, the rest valued 0 - - `600160008080808080808080808080808080806002e7` at the end of the code is equivalent to above -- `600060016002e801` results in 3 stack items, from top to bottom: [2, 0, 1] -- `600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060016002e8` results in 30 stack items, the top of the stack valued 2, the bottom of the stack valued 1, the rest valued 0 +- `60016000808080808080808080808080808080e680` results in 18 stack items, the top of the stack valued 1, the bottom of the stack valued 1, the rest valued 0 +- `600160008080808080808080808080808080806002e780` results in 18 stack items, the top of the stack valued 1, the bottom of the stack valued 2, the rest valued 0 +- `600260008080808080600160008080808080808080e8` at the end of code results in 17 stack items, the bottom of the stack valued 1, the 10th stack item from the top valued 2, the rest valued 0 +- `600060016002e88e` results in 3 stack items, from top to bottom: [2, 0, 1] +- `600080808080808080808080808080808080808080808080808080808060016002e88f` results in 30 stack items, the top of the stack valued 2, the bottom of the stack valued 1, the rest valued 0 - `e75b` reverts - `600456e65b` executes successfully (`PUSH 04 JUMP INVALID_DUPN JUMPDEST`) -- `600060006000e80115` results in 3 stack items, the top of the stack valued 1, the rest valued 0 -- `6000808080808080808080808080808080e600` results in exceptional halt +- `60008080e88e15` results in 3 stack items, the top of the stack valued 1, the rest valued 0 +- `e852` reverts +- `6000808080808080808080808080808080e680` results in exceptional halt ## Security Considerations