> For the complete documentation index, see [llms.txt](https://ret2basic.gitbook.io/ctfwriteup/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ret2basic.gitbook.io/ctfwriteup/web3-ctf/more-evm-puzzles/puzzle-5.md).

# Puzzle 5

## 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:

```solidity
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](https://www.evm.codes/about) 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](https://www.evm.codes/about), which will cost gas. <mark style="color:red;">**The size is always a multiple of a word (32 bytes).**</mark>

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:

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