Puzzle 7

CALLDATACOPY, CREATE

Puzzle

############
# Puzzle 7 #
############

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      3B        EXTCODESIZE
0C      6001      PUSH1 01
0E      14        EQ
0F      6013      PUSH1 13
11      57        JUMPI
12      FD        REVERT
13      5B        JUMPDEST
14      00        STOP

? Enter the calldata: 

Solution

Chunk 1

00      36        CALLDATASIZE
01      6000      PUSH1 00
03      80        DUP1
04      37        CALLDATACOPY

At address 0x04, we are calling CALLDATACOPY(0, 0, 16). This function call copies 16 bytes of calldata to the very beginning of the memory.

Chunk 2

05      36        CALLDATASIZE
06      6000      PUSH1 00
08      6000      PUSH1 00
0A      F0        CREATE

At address 0x0A, we are calling CREATE(0, 0, calldata_size). This function call creates a new contract and deposits 0 wei into it. The initialization code for the new contract is at memory location 0, which is our input copied during chunk 1. The return value of CREATE is the new contract's address.

Chunk 3

0B      3B        EXTCODESIZE
0C      6001      PUSH1 01
0E      14        EQ

This chunk tests if the new contract's code size is 1.

Chunk 4

0F      6013      PUSH1 13
11      57        JUMPI
12      FD        REVERT
13      5B        JUMPDEST
14      00        STOP

If chunk 3 evaluates to true, then we are jumping to address 0x13.

Building calldata

Since the new contract's code size must be 1, we can build a minimal contract that contains only 1 0x00, which is the opcode for STOP. In other word, the runtime code for this new contract is:

0x00

Write a creation code for it:

PUSH1 0x01 // return just 1 byte
PUSH1 0x00 // runtime code, default is 0x00
RETURN

Compile in Playground:

60016000f3

Last updated