EVM Puzzle 3 solution
This is Part 3 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 3
00 36 CALLDATASIZE 01 56 JUMP 02 FD REVERT 03 FD REVERT 04 5B JUMPDEST 05 00 STOP
The problem is similar to the [[Puzzle 1]] and [[Puzzle 2]] challenges where we need to find a way to have in the EVM Stack the correct value when the
JUMP opcode is executed. We need to have into the stack the value
4 in order to land in a valid
In this puzzle we have only one opcode before the
- CALLDATASIZE push the byte size of the calldata
To solve this challenge it's important to understand what the
From Chapter 13 - The Ethereum Virtual Machine
The call data region is the data that is sent with a transaction. In the case of contract creation, it would be the constructor code. This region is immutable and can be read with the instructions CALLDATALOAD, CALLDATASIZE, and CALLDATACOPY.
Instead from OpenZeppelin blog post "Deconstructing a Solidity Contract — Part III: The Function Selector" the
calldata is explained like:
As explained in Solidity’s documentation ABI specification, the calldata is an encoded chunk of hexadecimal numbers that contains information about what function of the contract we want to call, and it’s arguments or data. Simply put, it consists of a “function id”, which is generated by hashing the function’s signature (truncated to the first leading four bytes) followed by the packed arguments data.
If for example we want to interact with a Contract to withdraw
10 WETH we would call the contract's function that have this signature:
withdraw(uint256). The calldata value for that call would be
0x2e1a7d4d0000000000000000000000000000000000000000000000008ac7230489e80000 which the 4 first bytes represents the function signature, the other 32 would represent the uint256 parameter value passed to it.
Just try to print this in your Solidity contract to reproduce it:
abi.encodeWithSignature("withdraw(uint256)", 10 ether);
The solution in this challenge is pretty easy, we just need to pass 4 bytes input value in order to make the
JUMP op to jump to the
For example we could pass the 4 bytes that represent the signature of the function we have used in the example above. In this case we would pass
0x2e1a7d4d to solve the challenge.
Here's the link to the solution of Puzzle 3 on EVM Codes website to simulate it.