EVM Opcode execution for calling external contracts - The PUZZLE
EVM executing opcodes

EVM Opcode execution for calling external contracts - The PUZZLE

About:-

There is a puzzle ByteCode given and the target is, it should work with normal stop execution not a revert. The puzzle is given in IMAGE : The Puzzle ByteCode and sequence of Opcode is given in IMAGE : The Puzzle Opcode

Article content
IMAGE : The Puzzle ByteCode
Article content
IMAGE : The Puzzle Opcode

Understanding The Puzzle :-

Block 1: Copy the whole calldata input in memory

Article content
Block 1

The CALLDATACOPY is like a "KIND OF" MLOAD that take the data to be stored in the memory directly from the calldata location. Those instructions are saying: take all the data from calldata and copy it to the memory starting from the memory position 0.

Block 2: Create a new contract, its code will be the equal to the calldata data

Article content
Block 2

These opcodes are just saying: create a new contract transferring 0 wei with the transaction. The code to deploy the new contract will be the one in memory that goes from offset 0 to CALLDATASIZE bytes.

So connecting Block 1 and Block 2 the result is this: use the calldata data in input to use it as the code to deploy a new contract.

Block 3: Prepare and make the CALL

Article content
Block3

All the opcodes before CALL are just preparing all the inputs needed to execute the call. After the preparation, we will execute this CALL(gas=ALL_THE_GAS_AVAILABLE, address=ADDRESS_FROM_CREATE, value: 0, argsOffset=0, argsSize=0, retOffset=0, retSize=0)

Basically, we are just calling the deployed contract with all the gas still available without any calldata arguments and without reading anything from the returned value.

After the execution of CALL the stack will have only one value. 0 if it has reverted, 1 otherwise.


Block 4: Final execution

Article content
Block4

Before the PUSH1 00 the stack has only the execution result of the CALL.

All these op codes are saying: if the CALL has reverted, jump to 1B otherwise keep going with the flow and execute REVERT (something that we don't want!).

The solution of the challenge is to not execute the REVERT opcode in position 1A is to deploy a contract that, when called, will revert. Reverting CALL will push to the stack the value 0 that will make the EQ push to the stack a 1.

By doing so, the JUMPI opcode will jump to the 1B position!

The Solutions -

The question is, which is the CALLDATA to pass to the transaction to make this?

We can make the deployed contract to just revert as soon as possible by having just the REVERT opcode.

The calldata that we need to pass will be as follows :-

// store in memory the REVERT opcode as the only "code" of the contract

PUSH1 FD

PUSH1 00

MSTORE8

// make the constructor return the stored runtime code

PUSH1 01

PUSH1 00

RETURN

Translated in bytecode, our calldata and solution to the puzzle will be 0x60FD60005360016000F3


Note: I was not able to solve it initially after after understanding the opcode in details and spending lots of time was able to solve it.


HAPPY CODING !!

To view or add a comment, sign in

More articles by Shobhit Gupta

  • RUST Effective Multithreading

    🚀 Building a ThreadPool in Rust: Understanding the Key Components and Their Real-World Use Cases Rust’s concurrency…

  • Understanding cross functional Reentrancy attack

    Smart contract security is one of the biggest impediments toward the mass adoption of the blockchain. For this reason…

  • Uninitialised Storage 'The Culprit'

    When working EVM based blockchain, storage and memory frequently used tools for different use case and at some places…

  • Strategy to transfer ether safely

    Its been 4 month journey since in living and feeling the blockchain ecosystem. It feels like an Atlantic ocean :) till…

    1 Comment
  • Technology Lover & A Programmer

    Being a tech lover and a Programmer, I love to learn new technologies. I have been involded in development more then 4…

Others also viewed

Explore content categories