Skip to content

Instantly share code, notes, and snippets.

@betrisey
Last active December 4, 2023 19:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save betrisey/e13dd30bc1f723d7a6c9bfdf7b0300d8 to your computer and use it in GitHub Desktop.
Save betrisey/e13dd30bc1f723d7a6c9bfdf7b0300d8 to your computer and use it in GitHub Desktop.
Ghost - BlazCTF

Ghost - BlazCTF

6/2/2024 "Memory cannot be defined, yet it defines mankind."

Author: Robert Chen (OtterSec) @notdeghost

EVM,RE / 13 solves / 274 pts

Challenge contract

contract Challenge {
    bool public isSolved;

    constructor(address) {}

    function solve(bytes calldata secret) external {
        bytes memory data = hex"6111ec6100[...]";

        address addr;
        assembly {
            addr := create(0, add(data, 32), mload(data))
            let sz := extcodesize(addr)
            if iszero(sz) { revert(0, 0) }
        }
        (bool success,) = addr.call(secret);

        assert(success);
        isSolved = true;
    }
}

The challenge contract deploys contract and we need to find a calldata value that will make the call to that new contract succeed.

First decompilation

We first start by decompiling the bytecode of the contract. This is the output of the Dedaub decompiler with my annotations:

function 0x70d496b9(uint256 varg0, uint256 varg1, [...], uint256 varg255) public payable { 
    require(!(msg.value | (msg.data.length < 8196))); // function not payable and must have 256 uint256 arguments (4B selector + 256*32B = 8196)
    require(!(varg0 >> 8)); // checks that varg0 < 256
    MEM[64] = varg0;
    require(!(varg1 >> 8));
    MEM[96] = varg1;
    // [...]
    require(!(varg255 >> 8));
    MEM[8224] = varg255;
    
    // Initializes the rest of the memory to 0
    // (because it copies from after the end of the calldata, everything will be 0)
    CALLDATACOPY(8256, msg.data.length, 8224);
    
    // Equivalent to a loop for(v0 = 0; v0 < 256; v0++)
    v0 = v1 = 0;
    while (v0 <= uint8.max) {
        // The loop checks each argument got copied to MEM.
        // The arguments are instructions and can be 0, 1, 2.
        // Each instruction will be explained after cleaning up the code.
        if (MEM[64 + (v0 << 5)]) { // << 5 is equivalent to * 32 because each instruction is 256 bits = 32 bytes long
            require(v0 <= uint8.max); // always true because of the loop exit condition
            if (MEM[64 + (v0 << 5)] ^ 0x1) {
                require(v0 <= uint8.max); // always true
                if (!(MEM[64 + (v0 << 5)] ^ 0x2)) {
                    // branch where instruction == 2
                    require(MEM[16448] <= int8.max);
                    require(!(MEM[8256 + (MEM[16448] << 5)] + 1 >> 8)); // makes sure the value doesn't go over 255
                    MEM[8256 + (MEM[16448] << 5)] = MEM[8256 + (MEM[16448] << 5)] + 1;
                }
            } else {
                // branch where instruction == 1
                require(MEM[16448] - 2 <= MEM[16448]); // check for underflow
                MEM[16448] = MEM[16448] - 2;
            }
        } else {
            // branch where instruction == 0
            require(MEM[16448] + 3 >= MEM[16448]); // check for overflow
            MEM[16448] = MEM[16448] + 3;
        }
        v0 += 1;
        
        // "Exits" the loop when v0 == 256
        // What's in the if statement will be executed after the 256 iterations of the loop
        if (!(v0 ^ 0x100)) {
            require(!MEM[16448]);
            // Equivalent to a loop for(v2 = 0; v2 < 128; v2++)
            v2 = v3 = 0;
            while (v2 <= int8.max) {
                if (MEM[8256 + (v2 << 5)]) {
                    require(v2 <= int8.max);
                    if (MEM[8256 + (v2 << 5)] ^ 0x1) {
                        require(v2 <= int8.max);
                        if (!(MEM[8256 + (v2 << 5)] ^ 0x2)) {
                            // branch where instruction == 2
                            require(MEM[16448] <= int8.max);
                            require(!(MEM[12352 + (MEM[16448] << 5)] + 1 >> 8));
                            MEM[12352 + (MEM[16448] << 5)] = MEM[12352 + (MEM[16448] << 5)] + 1;
                        }
                        // branch where instruction == 1
                    } else {
                        require(MEM[16448] - 2 <= MEM[16448]);
                        MEM[16448] = MEM[16448] - 2;
                    }
                } else {
                    // branch where instruction == 0
                    require(MEM[16448] + 3 >= MEM[16448]);
                    MEM[16448] = MEM[16448] + 3;
                }
                v2 += 1;
                // "Exits" the loop when v2 == 128
                // What's in the if statement will be executed after the 128 iterations of the loop
                if (!(v2 ^ 0x80)) {
                    if (MEM[0x3040] ^ 0x1) {
                        v4 = v5 = 0;
                    } else if (MEM[0x3060] ^ 0x3) {
                        v4 = v6 = 0;
                    } else if (MEM[0x3080] ^ 0x3) {
                        v4 = v7 = 0;
                    } else {
                        v4 = v8 = !(MEM[0x30a0] ^ 0x7);
                    }
                    require(v4);
                    // To make v4 equal to 1, all the if / else if conditions must be false and the expression in the last else must be true
                    // so v4 = !(MEM[0x3040] ^ 0x1) && !(MEM[0x3060] ^ 0x3) && !(MEM[0x3080] ^ 0x3) && !(MEM[0x30a0] ^ 0x7)
                    // which is equivalent to v4 = MEM[0x3040] == 1 && MEM[0x3060] == 3 && MEM[0x3080] == 3 && MEM[0x30a0] == 7
                    exit;
                }
            }
            revert();
        }
    }
    revert();
}

Cleaned up decompilation

We improve the readability by transforming the while loops into for loops, removing the unnecessary statements and reordering the if statements based on the previous annotations. Here is the result:

function 0x70d496b9(uint256 varg0, uint256 varg1, [...], uint256 varg255) public payable { 
    MEM[64] = varg0;
    MEM[96] = varg1;
    // [...]
    MEM[8224] = varg255;
    
    CALLDATACOPY(8256, msg.data.length, 8224);
    
    for (uint i = 0; i < 256; i++) {
        uint256 instruction = MEM[64 + (i * 32)];
        if (instruction == 0) {
            MEM[16448] += 3;
        } else if (instruction == 1) {
            MEM[16448] -= 2;
        } else if (instruction == 2) {
            MEM[8256 + (MEM[16448] * 32)] += 1;
        }
    }

    require(MEM[16448] == 0);

    for (uint i = 0; i < 128; i++) {
        uint256 instruction = MEM[8256 + (i * 32)];
        if (instruction == 0) {
            MEM[16448] += 3;
        } else if (instruction == 1) {
            MEM[16448] -= 2;
        } else if (instruction == 2) {
            MEM[12352 + (MEM[16448] * 32)] += 1;
        }
    }
         
    require(MEM[12352] == 1 && MEM[12384] == 3 && MEM[12416] == 3 && MEM[12448] == 7);
}

Understanding the contract

The major steps are as follows:

  1. The first loop goes over the instructions we provide as argument and modifies the memory starting at MEM[8256]
  2. The second loop similarly goes over the instructions that start at MEM[8256] and modifies the memory starting at MEM[12352]
  3. Finally the memory starting at MEM[12352] must be [1, 3, 3, 7]

The instructions are similar for both loops, MEM[16448] is the offset in the memory where we want to write.

  • Instruction 0 will increase the offset by 3
  • Instruction 1 will decrease the offset by 2
  • Instruction 3 will increment the memory at the address MEM[start_write + offset]

Solution

We will build our solution backwards from the end. First, we will find the instructions that write [1, 3, 3, 7] to the final location. And then find the instructions to give as argument that will write the previously constructed instructions.

Writing 1337

Here are the steps:

  1. Increment the current offset to write the first number (1)
  2. Increase the offset by 3, increment the value 7 times to write the number (7)
  3. Decrease the offset by 2, increment the value 3 times to write the 2nd number (3)
  4. Increase the offset by 3, decrease it by 2 to point to the 3rd number and increment it 3 times to get the 3rd number (3)

Here are the instructions that perform the described steps:

2 // MEM[386] = 1
0 // MEM[389]
2 // MEM[389] = 1
2 // MEM[389] = 2
2 // MEM[389] = 3
2 // MEM[389] = 4
2 // MEM[389] = 5
2 // MEM[389] = 6
2 // MEM[389] = 7
1 // MEM[387]
2 // MEM[387] = 1
2 // MEM[387] = 2
2 // MEM[387] = 3
0 // MEM[390]
1 // MEM[388]
2 // MEM[388] = 1
2 // MEM[388] = 2
2 // MEM[388] = 3

Writing the instructions that write 1337

To write n, we need to call the increment instruction (2) n times. After writing a number, we increase the offset by 1 using a both 0 and 1 instructions (+3 -2 = +1).

These are the resulting instructions:

2,2, 0,1, // 2
     0,1, // 0
2,2, 0,1, // 2
2,2, 0,1, // 2
2,2, 0,1, // 2
2,2, 0,1, // 2
2,2, 0,1, // 2
2,2, 0,1, // 2
2,2, 0,1, // 2
2,   0,1, // 1
2,2, 0,1, // 2
2,2, 0,1, // 2
2,2, 0,1, // 2
     0,1, // 0
2,   0,1, // 1
2,2, 0,1, // 2
2,2, 0,1, // 2
2,2, 0,1  // 2

There are 2 additional constraints:

  1. After the first loop, the offset value (MEM[16448]) must be 0.
  2. The input must contain 256 instructions but we currently only have 66 instructions.

We have written 18 values so the offset value is 18. Therefore we can add 9 times the instruction 2 to decrease the offset to 0.

We initially had 66 instructions and 9 more instructions to decrease the offset so 75 total. Finally, we need to add 256-75=181 increment instructions (instruction 2). We put the extra increment instructions before resetting the offset to 0 so it does not overwrite our values.

So we add this to the previous instructions:

[2]*181 + [1]*9

Final solution

The selector of the function is 0x70d496b9 and each argument/instruction is 32 bytes long so the calldata is as follows:

0x70d496b9
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001

After calling the contract with the solution, we get the flag: blaz{gh0st_w1th_th3_sh3ll_81c9aj}

Python implementation

While solving the challenge, I implemented it in Python to make sure each step was correct:

instructions = [
    2,2, 0,1,
         0,1,
    2,2, 0,1,
    2,2, 0,1,
    2,2, 0,1,
    2,2, 0,1,
    2,2, 0,1,
    2,2, 0,1,
    2,2, 0,1,
    2,   0,1,
    2,2, 0,1,
    2,2, 0,1,
    2,2, 0,1,
         0,1,
    2,   0,1,
    2,2, 0,1,
    2,2, 0,1,
    2,2, 0,1
] + ([2]*181) + ([1]*9)

# encode each instruction as uint256 number and return as hexstring
print("0x70d496b9" + "".join(["0"*63 + str(instr) for instr in instructions]))

# 2 used, 256 args, 257 initialized to 0
# All the indexes are divided by 32 as MEM directly contains the uint256 values instead of being an array of bytes like in Solidity
MEM = [0, 0] + instructions + [0] * 257

for i in range(256):
    if MEM[2 + i] == 0:
        MEM[514] += 3
    elif MEM[2 + i] == 1:
        MEM[514] -= 2
    elif MEM[2 + i] == 2:
        MEM[258 + MEM[514]] += 1

new_instructions = [
    2, # MEM[386] = 1
    0, # MEM[389]
    2, # MEM[389] = 1
    2, # MEM[389] = 2
    2, # MEM[389] = 3
    2, # MEM[389] = 4
    2, # MEM[389] = 5
    2, # MEM[389] = 6
    2, # MEM[389] = 7
    1, # MEM[387]
    2, # MEM[387] = 1
    2, # MEM[387] = 2
    2, # MEM[387] = 3
    0, # MEM[390]
    1, # MEM[388]
    2, # MEM[388] = 1
    2, # MEM[388] = 2
    2, # MEM[388] = 3
]
# MEM[258:258 + len(new_instructions)] = new_instructions
assert(MEM[258:258 + len(new_instructions)] == new_instructions)
assert(MEM[514] == 0)

for i in range(128):
    if MEM[258 + i] == 0:
        MEM[514] += 3
    elif MEM[258 + i] == 1:
        MEM[514] -= 2
    elif MEM[258 + i] == 2:
        MEM[386 + MEM[514]] += 1

assert(MEM[386] == 1 and MEM[387] == 3 and MEM[388] == 3 and MEM[389] == 7)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment