> 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/evm-puzzles/puzzle-8.md).

# Puzzle 8

GAS, CALL

## Puzzle

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

## Solution

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

<figure><img src="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FiAse0yx8RqGRENoSK4Ct%2Fimage.png?alt=media&amp;token=bde0ae25-0733-4975-b107-12743fc5b8ca" alt=""><figcaption><p>GAS</p></figcaption></figure>

It just pushes remaining gas onto the stack. Next, we have another new opcode `CALL`:

<figure><img src="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FaZAZsrfJGdtOYDJSZg3L%2Fimage.png?alt=media&amp;token=cd0c8d1c-3309-4ac5-b09c-f5636541a69a" alt=""><figcaption><p>CALL</p></figcaption></figure>

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.

### Building calldata

The easiest way to fail the `CALL` is creating a new contract containing only the `REVERT` instruction. The same idea appeared in [Ethernaut "King"](https://ethernaut.openzeppelin.com/level/0x725595BA16E76ED1F6cC1e1b65A88365cC494824).

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
```
