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 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 if 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 themsg.value
inwei
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.
- PUSH: 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
.
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.