✅
Puzzle 8
GAS, CALL
############
# Puzzle 8 #
############
00 36 CALLDATASIZE
01 6000 PUSH1 00
03 80 DUP1
04 37 CALLDATACOPY
05 36 CALLDATASIZE
06 6000 PUSH1 00
08 6000 PUSH1 00
0A F0 CREATE
0B 6000 PUSH1 00
0D 80 DUP1
0E 80 DUP1
0F 80 DUP1
10 80 DUP1
11 94 SWAP5
12 5A GAS
13 F1 CALL
14 6000 PUSH1 00
16 14 EQ
17 601B PUSH1 1B
19 57 JUMPI
1A FD REVERT
1B 5B JUMPDEST
1C 00 STOP
? Enter the calldata:
00 36 CALLDATASIZE
01 6000 PUSH1 00
03 80 DUP1
04 37 CALLDATACOPY
Equivalent to
CALLDATACOPY(0, 0, calldata_size)
.05 36 CALLDATASIZE
06 6000 PUSH1 00
08 6000 PUSH1 00
0A F0 CREATE
Equivalent to
CREATE(0, 0, calldata_size)
. Again, this means create a new contract and deposits 0 wei into it. The initialization code is at memory offset 0 and the length is the size of calldata.0B 6000 PUSH1 00
0D 80 DUP1
0E 80 DUP1
0F 80 DUP1
10 80 DUP1
11 94 SWAP5
12 5A GAS
13 F1 CALL
This chunk pushes 5
0x00
onto the stack and swap the topmost element with the bottommost element. Recall that the bottommost element is the result of CREATE(0, 0, calldata_size)
, which is the new contract's address. Now new contract's address is at the top of the stack, following 5 0x00
underneath it.After that we encounter a new opcode
GAS
:
GAS
It just pushes remaining gas onto the stack. Next, we have another new opcode
CALL
:
CALL
Now this is equivalent to
CALL(remaining_gas, new_contract_address, 0, 0, 0, 0, 0)
. Basically it will just call the new contract with the remaining gas and the argument is empty. This call will push 1 onto the stack if it was successful, otherwise it will push 0 onto the stack. We shall call it result
.14 6000 PUSH1 00
16 14 EQ
17 601B PUSH1 1B
19 57 JUMPI
1A FD REVERT
1B 5B JUMPDEST
1C 00 STOP
If
result == 0
, the control flow will goto address 0x1B
, which is our destination. In other words, we want CALL(remaining_gas, new_contract_address, 0, 0, 0, 0, 0)
fail.The easiest way to fail the
CALL
is creating a new contract containing only the REVERT
instruction. The same idea appeared in Ethernaut "King".Just modify the calldata from previous level:
PUSH1 0xFD // opcode of REVERT
PUSH1 0x00 // memory offset 0
MSTORE8
PUSH1 0x01 // return just 1 byte
PUSH1 0x00 // memory offset 0
RETURN
Bytecode:
60fd60005360016000f3
Last modified 1d ago