EVM Puzzle 5 solution

StErMi
3 min readJun 16, 2022
Ryoji Iwata Unsplash

This is Part 5 of the “Let’s play EVM Puzzles” series, where I will explain how to solve each puzzle challenge.

EVM Puzzles is a project developed by Franco Victorio (@fvictorio_nan) that is a perfect fit if you are in the process of learning how the Ethereum EVM works, and you want to apply some of the knowledge you have just acquired.

EVM Puzzle 5

00      34          CALLVALUE
01 80 DUP1
02 02 MUL
03 610100 PUSH2 0100
06 14 EQ
07 600C PUSH1 0C
09 57 JUMPI
0A FD REVERT
0B FD REVERT
0C 5B JUMPDEST
0D 00 STOP
0E FD REVERT
0F FD REVERT

This challenge is a little different compared to the previous one. Instead of using JUMP it uses the opcode JUMPI.

The JUMPI instruction may alter the program counter, thus breaking the linear path of the execution to another point in the deployed code. It is used to implement functionalities like loops and conditions.

When the JUMPI is executed, it pops 2 values from the Stack. The first value will be the new Program Counter to jump to (as always, it must be a valid JUMPDEST instruction). The second value instead is a boolean flag (0 or 1) to evaluate to know whether it must jump or not.
If the value is 1 it will jump; otherwise it will continue to the next instruction.

Let’s review each opcode before the JUMPI:

  • CALLVALUE push in the stack the `msg.value` in `wei` passed along the transaction
  • DUP1: duplicate the first value in the stack and push it to the first position of the stack
  • MUL: pop the first two values of the stack and multiply them. The result is pushed back to the stack
  • PUSH2: push 2 bytes input into the stack
  • EQ: pop 2 values from the stack, if those are equal push 1 to the stack, otherwise push 0.
  • PUSH1: push 1 byte input into the stack

Let’s review the stack after each operation

CALLVALUE is executed

| Stack Position  | Stack Value   |
| ------------- | ------------- |
| #0 | X |

DUP1 is executed

| Stack Position  | Stack Value   |
| ------------- | ------------- |
| #0 | X |
| #1 | X |

MUL is executed

| Stack Position  | Stack Value   |
| ------------- | ------------- |
| #0 | X * X |

PUSH2 0100 is executed

| Stack Position  | Stack Value   |
| ------------- | ------------- |
| #0 | 0x0100 |
| #1 | X * X |

EQ is executed

| Stack Position  | Stack Value         |
| ------------- | ------------- |
| #0 | 1 if X*X === 0x0100 |

PUSH 0C is executed

| Stack Position  | Stack Value         |
| ------------- | ------------- |
| #0 | 0x0C |
| #1 | 1 if X*X === 0x0100 |

When at this point we execute the JUMPI the EVM will jump to the position 0x0c where the correct JUMPDEST op is only if X*X is equal to 0x0100.

When at this point we execute the `JUMPI` the EVM will jump to the position 0x0c where the correct `JUMPDEST` op is only if `X*X` is equal to `0x0100`.

Solution

In decimal 0x0100 is equal to 256 so the answer for the challenge is to find the correct value of CALLVALUE for which CALLDATA * 2 === 256.

In this case, the solution will be 16.

Here’s the link to the solution of Puzzle 5 on EVM Codes website to simulate it.

--

--

StErMi

#web3 dev + auditor | @SpearbitDAO security researcher, @yAcademyDAO resident auditor, @developer_dao #459, @TheSecureum bootcamp-0, @code4rena warden