Puzzle 5

MSIZE

Puzzle

############
# Puzzle 5 #
############

00      6020      PUSH1 20
02      36        CALLDATASIZE
03      11        GT
04      6008      PUSH1 08
06      57        JUMPI
07      FD        REVERT
08      5B        JUMPDEST
09      36        CALLDATASIZE
0A      6000      PUSH1 00
0C      6000      PUSH1 00
0E      37        CALLDATACOPY
0F      36        CALLDATASIZE
10      59        MSIZE
11      03        SUB
12      6003      PUSH1 03
14      14        EQ
15      6019      PUSH1 19
17      57        JUMPI
18      FD        REVERT
19      5B        JUMPDEST
1A      00        STOP

? Enter the calldata: 

Solution

Chunk 1

00      6020      PUSH1 20
02      36        CALLDATASIZE
03      11        GT
04      6008      PUSH1 08
06      57        JUMPI
07      FD        REVERT
08      5B        JUMPDEST

The calldata must be longer than 0x20 = 32 bytes.

Chunk 2

09      36        CALLDATASIZE
0A      6000      PUSH1 00
0C      6000      PUSH1 00
0E      37        CALLDATACOPY
0F      36        CALLDATASIZE
10      59        MSIZE
11      03        SUB
12      6003      PUSH1 03
14      14        EQ
15      6019      PUSH1 19
17      57        JUMPI
18      FD        REVERT
19      5B        JUMPDEST
1A      00        STOP

Pseudocode:

calldatacopy(0, 0, calldata_size);

if (memory_size - calldata_size == 0x03) {
    jump(0x19);
}

MSIZE gets the size of active memory in bytes. More importantly, from evm.codes:

The memory is always fully accessible. What this instruction tracks is the highest offset that was accessed in the current execution. A first write or read to a bigger offset will trigger a memory expansion, which will cost gas. The size is always a multiple of a word (32 bytes).

At address 0x0E when CALLDATACOPY is called, our calldata is copied to the memory. If our calldata is longer than 32 bytes but shorter than 64 bytes, then MSIZE will always return 64. To satisfy memory_size - calldata_size == 0x03, we can just feed 61 0x00 as calldata. In Python:

print("0x" + "00" * 61)
# 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Last updated