神刀安全网

The DAO Bytecode Tour for the Skeptic (Part 2)

The DAO Bytecode Tour for the Skeptic (Part 2)

This is the continuation of the DAO bytecode reading. AfterPart 1, I’ve reinforced my tools. Now the toolset can produce the non-descriptive parts of these blog posts automatically, and can analyze a sequence of multiple blocks (so that I don’t need to memorize the stack contents in between).

This time, deeper in the code, there are some surprises. Below we find that “checkProposalCode()” function tries to call another contract at address 4. Sadly however, I didn’t find any ways to empty the DAO account. At one point, I thought I found a way to force the DAO code to jump into whichever snippet, but this didn’t work out.

At the end of the day, I’m tired of the maze of control flow around variable-length byte strings in a variable-length array. To tackle this I need to automate the whole process in a bigger scale. The focus is first to draw the control flow automatically. I think this is feasible because Solidity places future jump destinations in the stack as immediate values.

I conclude the blog post before the actual content, which is just for the brave hearts. After struggling with the bytecode for a while, I have a much better sense of how the bytecode looks like given a Solidity source code. I know how to find the bytecode for a function, and how to make sense of it.

Questions & TODOs

  • Q. Why does the bytecode have a CALL to address 4 when the source code has a sha3()?
  • Q. Why is “PUSH2” sometimes used for pushing “0x02”?
  • Q. What does the Solidity compiler do with bytestrings in an array?
  • Todo: automatically draw a flow graph.
  • Todo: calculate the stack contents at the end of paths on the flow graph.
  • Todo: small representation of memory contents on the flow graph.
  • Todo: nice GUI.
  • Todo: a collection of Solidity function signatures (indexed with the SHA3 hashes).

Here comes the real content. The DAO bytecode is an important piece of work recorded in the Ethereum blockchain forever (I hope). People annotate such things. I hope the following descriptions help those who face the same task.

This is a continuation ofPart 1. I skipped snippets freely.

Position 1243 “0x5b604080516020604435600481810135601f8101849004840285018401909552848452610966948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505060a435915050600060006110c1336105ec56”

This snippet is the entry point for “newProposal()” function. This snippet was one of the entry points but I postponed it in Part 1.

JUMPDEST :: PUSH_N 0x40 :: DUP1 :: MLOAD :: PUSH_N 0x20 :: PUSH_N 0x44 :: CALLDATALOAD :: PUSH_N 0x04 :: DUP2 :: DUP2 :: ADD :: CALLDATALOAD :: PUSH_N 0x1f :: DUP2 :: ADD :: DUP5 :: SWAP1 :: DIV :: DUP5 :: MUL :: DUP6 :: ADD :: DUP5 :: ADD :: SWAP1 :: SWAP6 :: MSTORE :: DUP5 :: DUP5 :: MSTORE :: PUSH_N 0x0966 :: SWAP5 :: DUP2 :: CALLDATALOAD :: SWAP5 :: PUSH_N 0x24 :: DUP1 :: CALLDATALOAD :: SWAP6 :: SWAP4 :: SWAP5 :: PUSH_N 0x64 :: SWAP5 :: SWAP3 :: SWAP4 :: SWAP2 :: ADD :: SWAP2 :: DUP2 :: SWAP1 :: DUP5 :: ADD :: DUP4 :: DUP3 :: DUP1 :: DUP3 :: DUP5 :: CALLDATACOPY :: POP :: POP :: PUSH_N 0x40 :: DUP1 :: MLOAD :: PUSH_N 0x20 :: SWAP8 :: CALLDATALOAD :: DUP1 :: DUP11 :: ADD :: CALLDATALOAD :: PUSH_N 0x1f :: DUP2 :: ADD :: DUP11 :: SWAP1 :: DIV :: DUP11 :: MUL :: DUP4 :: ADD :: DUP11 :: ADD :: SWAP1 :: SWAP4 :: MSTORE :: DUP3 :: DUP3 :: MSTORE :: SWAP7 :: SWAP9 :: SWAP8 :: PUSH_N 0x84 :: SWAP8 :: SWAP2 :: SWAP7 :: POP :: PUSH_N 0x24 :: SWAP2 :: SWAP1 :: SWAP2 :: ADD :: SWAP5 :: POP :: SWAP1 :: SWAP3 :: POP :: DUP3 :: SWAP2 :: POP :: DUP5 :: ADD :: DUP4 :: DUP3 :: DUP1 :: DUP3 :: DUP5 :: CALLDATACOPY :: POP :: SWAP5 :: SWAP7 :: POP :: POP :: SWAP4 :: CALLDATALOAD :: SWAP4 :: POP :: POP :: PUSH_N 0xa4 :: CALLDATALOAD :: SWAP2 :: POP :: POP :: PUSH_N 0x00 :: PUSH_N 0x00 :: PUSH_N 0x10c1 :: CALLER :: PUSH_N 0x05ec :: JUMP

This snippet modifies the memory and the stack and jump to position 1516, and after a while the execution continues at position 4289.

Position 2424 “0x5b61098061070856”

JUMPDEST :: PUSH_N 0x0980 :: PUSH_N 0x0708 :: JUMP

The execution might jump here from position 569. This snippet is a preparation for calling “receiveEther()” from the default function. This snippet pushes 2432 to the stack and jumps to position 1800 (which is the main implementation of “receiveEther()”).

Position 2432 “0x5b9050”

JUMPDEST :: SWAP1 :: POP

This snippet removes the second element of the stack. The execution falls through.

If we come here as a part of “unblockMe()”, the topmost stack content becomes one, indicating success, and the execution falls through.

Position 2435 “0x5b9056”

JUMPDEST :: SWAP1 :: JUMP

This snippet removes the second element of the stack. The execution jumps to the original second element of the stack.

For instance, if we come from an external “receiveEther()” call, the stack’s first element is zero and the second element is 2406. After this snippet, the execution jumps to position 2406, with the stack’s first element being one.

If we come from the default function turned into “receiveEther()”, we jump to position 2432, fall back here, and then jump to position 2406.

If we come here from above, during “unblockMe()”, we jump to position 2406 with the topmost stack content being one, indicating success.

Position 2438 “0x5b604051808d600160a060020a031681526020018c8152602001806020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183600160a060020a0316815260200182810382528c818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610a6357”

JUMPDEST :: PUSH_N 0x40 :: MLOAD :: DUP1 :: DUP14 :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP13 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP1 :: PUSH_N 0x20 :: ADD :: DUP12 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP11 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP10 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP9 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP8 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP7 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP6 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP5 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP4 :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP3 :: DUP2 :: SUB :: DUP3 :: MSTORE :: DUP13 :: DUP2 :: DUP2 :: SLOAD :: PUSH_N 0x01 :: DUP2 :: PUSH_N 0x01 :: AND :: ISZERO :: PUSH_N 0x0100 :: MUL :: SUB :: AND :: PUSH_N 0x02 :: SWAP1 :: DIV :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: SWAP2 :: POP :: DUP1 :: SLOAD :: PUSH_N 0x01 :: DUP2 :: PUSH_N 0x01 :: AND :: ISZERO :: PUSH_N 0x0100 :: MUL :: SUB :: AND :: PUSH_N 0x02 :: SWAP1 :: DIV :: DUP1 :: ISZERO :: PUSH_N 0x0a63 :: JUMPI

This is a continuation of position 603. This changes the memory and the stack in a complicated way.

Position 2589 “0x80601f10610a3857”

DUP1 :: PUSH_N 0x1f :: LT :: PUSH_N 0x0a38 :: JUMPI

This is a continuation of the above snippet. The storage is not changed. The execution falls through or jumps to position 2616.

Position 2597 “0x610100808354040283529160200191610a6356”

PUSH_N 0x0100 :: DUP1 :: DUP4 :: SLOAD :: DIV :: MUL :: DUP4 :: MSTORE :: SWAP2 :: PUSH_N 0x20 :: ADD :: SWAP2 :: PUSH_N 0x0a63 :: JUMP

This is also a continuation of the above snippet. The storage is not changed. The execution jumps to position 2659.

Position 2616 “0x5b82019190600052602060002090”

JUMPDEST :: DUP3 :: ADD :: SWAP2 :: SWAP1 :: PUSH_N 0x00 :: MSTORE :: PUSH_N 0x20 :: PUSH_N 0x00 :: SHA3 :: SWAP1

The execution might jump here from position 2589. The storage is unchanged and the execution falls through.

Position 2630 “0x5b815481529060010190602001808311610a4657”

JUMPDEST :: DUP2 :: SLOAD :: DUP2 :: MSTORE :: SWAP1 :: PUSH_N 0x01 :: ADD :: SWAP1 :: PUSH_N 0x20 :: ADD :: DUP1 :: DUP4 :: GT :: PUSH_N 0x0a46 :: JUMPI

This is the continuation of the above snippet. The execution here might jump to position 2630 (!), or falls through. The storage is not changed.

Position 2650 “0x829003601f16820191”

DUP3 :: SWAP1 :: SUB :: PUSH_N 0x1f :: AND :: DUP3 :: ADD :: SWAP2

This snippet just changes the stack and falls through.

Position 2659 “0x5b50509d505050505050505050505050505060405180910390f3”

JUMPDEST :: POP :: POP :: SWAP14 :: POP :: POP :: POP :: POP :: POP :: POP :: POP :: POP :: POP :: POP :: POP :: POP :: POP :: POP :: PUSH_N 0x40 :: MLOAD :: DUP1 :: SWAP2 :: SUB :: SWAP1 :: RETURN

This snippet returns. The storage is not changed.

Position 2685 “0x5b60408051600160a060020a03929092168252519081900360200190f3”

JUMPDEST :: PUSH_N 0x40 :: DUP1 :: MLOAD :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: SWAP3 :: SWAP1 :: SWAP3 :: AND :: DUP3 :: MSTORE :: MLOAD :: SWAP1 :: DUP2 :: SWAP1 :: SUB :: PUSH_N 0x20 :: ADD :: SWAP1 :: RETURN

We’ve already seen this one inPart 1.

Position 2714 “0x5b00”

JUMPDEST :: STOP

This snippet is very easy to read. It stops. This doesn’t count as an exception, but as a normal termination. This snippet is used for “return;” without any return value.

Position 2716 “0x5b604051601254601434908102939093049350600160a060020a03169183900390600081818185876185025a03f1”

JUMPDEST :: PUSH_N 0x40 :: MLOAD :: PUSH_N 0x12 :: SLOAD :: PUSH_N 0x14 :: CALLVALUE :: SWAP1 :: DUP2 :: MUL :: SWAP4 :: SWAP1 :: SWAP4 :: DIV :: SWAP4 :: POP :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: SWAP2 :: DUP4 :: SWAP1 :: SUB :: SWAP1 :: PUSH_N 0x00 :: DUP2 :: DUP2 :: DUP2 :: DUP6 :: DUP8 :: PUSH_N 0x8502 :: GAS :: SUB :: CALL

It’s still unclear from which snippet the execution comes here. This snippet makes a call. The recipient of the call is the address at storage index 18.

Position 2762 “0x50505050600160a060020a038316600081815260146020908152604080832080548601905560168054860190556013825291829020805434019055815184815291517fdbccb92686efceafb9bb7e0394df7f58f71b954061b81afb57109bf247d3d75a9281900390910190a260105460165410801590610b4c57”

POP :: POP :: POP :: POP :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: DUP4 :: AND :: PUSH_N 0x00 :: DUP2 :: DUP2 :: MSTORE :: PUSH_N 0x14 :: PUSH_N 0x20 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x40 :: DUP1 :: DUP4 :: SHA3 :: DUP1 :: SLOAD :: DUP7 :: ADD :: SWAP1 :: SSTORE :: PUSH_N 0x16 :: DUP1 :: SLOAD :: DUP7 :: ADD :: SWAP1 :: SSTORE :: PUSH_N 0x13 :: DUP3 :: MSTORE :: SWAP2 :: DUP3 :: SWAP1 :: SHA3 :: DUP1 :: SLOAD :: CALLVALUE :: ADD :: SWAP1 :: SSTORE :: DUP2 :: MLOAD :: DUP5 :: DUP2 :: MSTORE :: SWAP2 :: MLOAD :: PUSH_N 0xdbccb92686efceafb9bb7e0394df7f58f71b954061b81afb57109bf247d3d75a :: SWAP3 :: DUP2 :: SWAP1 :: SUB :: SWAP1 :: SWAP2 :: ADD :: SWAP1 :: LOG2 :: PUSH_N 0x10 :: SLOAD :: PUSH_N 0x16 :: SLOAD :: LT :: DUP1 :: ISZERO :: SWAP1 :: PUSH_N 0x0b4c :: JUMPI

This is the continuation of the previous snippet. The execution jumps to position 2892 or falls through.

Position 2964 “0x5b60019150”

JUMPDEST :: PUSH_N 0x01 :: SWAP2 :: POP

We might come here from position 10734. The execution falls through.

Position 2969 “0x5b5091905056”

JUMPDEST :: POP :: SWAP2 :: SWAP1 :: POP :: JUMP

We might jump here from position 1134. The further jump destination is taken from the stack. For instance, if we come from positions 1089, 1099, 1134 and here, we will next jump to position 2432.

Position 2975 “0x5b61000256”

JUMPDEST :: PUSH_N 0x0002 :: JUMP

Position 1956 jumps here in the “throw” case. Indeed, this snippet jumps to position 2, causing an exception.

Position 2980 “0x5b600f5442118015610bb857”

JUMPDEST :: PUSH_N 0x0f :: SLOAD :: TIMESTAMP :: GT :: DUP1 :: ISZERO :: PUSH_N 0x0bb8 :: JUMPI

This is the continuation of “refund()” from position 1226.

This snippet compares the current timestamp with a value in the storage (at index 15) and if the current time is late enough, the execution falls through. Otherwise the execution jumps to position 3000.

In any case after this snippet the first element of the stack is the result of the comparison, and the rest of the stack is the original stack at entry.

Position 2992 “0x5060115460ff1615”

POP :: PUSH_N 0x11 :: SLOAD :: PUSH_N 0xff :: AND :: ISZERO

This is the continuation of “refund()” from above.

This snippet replaces the first element of the stack with a negation of a boolean. The boolean is calculated from the storage content at index 17. I guess this represents “isFueled”.

Position 3000 “0x5b15610de357”

JUMPDEST :: ISZERO :: PUSH_N 0x0de3 :: JUMPI

Depending on the above result, the execution might jump to position 3555 (if “isFueled” is true). The stack loses the first element.

Position 3006 “0x601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1”

PUSH_N 0x12 :: PUSH_N 0x00 :: SWAP1 :: SLOAD :: SWAP1 :: PUSH_N 0x0100 :: EXP :: SWAP1 :: DIV :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0xd2cc718f :: PUSH_N 0x40 :: MLOAD :: DUP2 :: PUSH_N 0xe0 :: PUSH_N 0x02 :: EXP :: MUL :: DUP2 :: MSTORE :: PUSH_N 0x04 :: ADD :: DUP1 :: SWAP1 :: POP :: PUSH_N 0x20 :: PUSH_N 0x40 :: MLOAD :: DUP1 :: DUP4 :: SUB :: DUP2 :: PUSH_N 0x00 :: DUP8 :: PUSH_N 0x61da :: GAS :: SUB :: CALL

This is a part of “refund()”. I guess this code correponds to the call to “extraBalance.accumulatedInput()”.

Position 3078 “0x1561000257”

ISZERO :: PUSH_N 0x0002 :: JUMPI

This takes the result of the call, and if it is zero, jumps to position 2, causing an exception. This code is not explicitly in the source code, but the whole execution raises an exception if the call fails for the exceptional reasons (see the yellow paper, appendix H.2. at CALL for the conditions for x=0).

Otherwise the execution falls through. The result of the call is stored in the memory.

Position 3083 “0x50506040516012549051600160a060020a039190911631109050610cc957”

POP :: POP :: PUSH_N 0x40 :: MLOAD :: PUSH_N 0x12 :: SLOAD :: SWAP1 :: MLOAD :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: SWAP2 :: SWAP1 :: SWAP2 :: AND :: BALANCE :: LT :: SWAP1 :: POP :: PUSH_N 0x0cc9 :: JUMPI

This snippet judges the condition . If the condition holds the execution falls through. Otherwise the execution jumps to position 3273.

Position 3113 “0x6040805160125460e060020a63d2cc718f0282529151600160a060020a039290921691630221038a913091849163d2cc718f91600482810192602092919082900301816000876161da5a03f1”

PUSH_N 0x40 :: DUP1 :: MLOAD :: PUSH_N 0x12 :: SLOAD :: PUSH_N 0xe0 :: PUSH_N 0x02 :: EXP :: PUSH_N 0xd2cc718f :: MUL :: DUP3 :: MSTORE :: SWAP2 :: MLOAD :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: SWAP3 :: SWAP1 :: SWAP3 :: AND :: SWAP2 :: PUSH_N 0x0221038a :: SWAP2 :: ADDRESS :: SWAP2 :: DUP5 :: SWAP2 :: PUSH_N 0xd2cc718f :: SWAP2 :: PUSH_N 0x04 :: DUP3 :: DUP2 :: ADD :: SWAP3 :: PUSH_N 0x20 :: SWAP3 :: SWAP2 :: SWAP1 :: DUP3 :: SWAP1 :: SUB :: ADD :: DUP2 :: PUSH_N 0x00 :: DUP8 :: PUSH_N 0x61da :: GAS :: SUB :: CALL

This snippet calls the “accumulatedInput()” function again.

Position 3189 “0x1561000257”

ISZERO :: PUSH_N 0x0002 :: JUMPI

but if the call stack depth is too high or some exceptions happen, the execution jumps to position 2, causing an exception.

Position 3194 “0x505060408051805160e160020a63011081c5028252600160a060020a039490941660048201526024810193909352516044838101936020935082900301816000876161da5a03f1”

POP :: POP :: PUSH_N 0x40 :: DUP1 :: MLOAD :: DUP1 :: MLOAD :: PUSH_N 0xe1 :: PUSH_N 0x02 :: EXP :: PUSH_N 0x011081c5 :: MUL :: DUP3 :: MSTORE :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: SWAP5 :: SWAP1 :: SWAP5 :: AND :: PUSH_N 0x04 :: DUP3 :: ADD :: MSTORE :: PUSH_N 0x24 :: DUP2 :: ADD :: SWAP4 :: SWAP1 :: SWAP4 :: MSTORE :: MLOAD :: PUSH_N 0x44 :: DUP4 :: DUP2 :: ADD :: SWAP4 :: PUSH_N 0x20 :: SWAP4 :: POP :: DUP3 :: SWAP1 :: SUB :: ADD :: DUP2 :: PUSH_N 0x00 :: DUP8 :: PUSH_N 0x61da :: GAS :: SUB :: CALL

This should be the call to “extraBalance.payOut()”.

Position 3265 “0x1561000257”

ISZERO :: PUSH_N 0x0002 :: JUMPI

Again if the call fails for some exceptions, the execution jumps to position 2.

Position 3270 “0x505050”

POP :: POP :: POP

This forgets something before the main body of “refund()”.

Position 3273 “0x5b33600160a060020a0316600081815260136020526040808220549051909181818185876185025a03f1”

JUMPDEST :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0x00 :: DUP2 :: DUP2 :: MSTORE :: PUSH_N 0x13 :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: DUP1 :: DUP3 :: SHA3 :: SLOAD :: SWAP1 :: MLOAD :: SWAP1 :: SWAP2 :: DUP2 :: DUP2 :: DUP2 :: DUP6 :: DUP8 :: PUSH_N 0x8502 :: GAS :: SUB :: CALL

This is the main snippet of “refund()” that sends the fund to the caller.

Position 3315 “0x9250505015610de357”

SWAP3 :: POP :: POP :: POP :: ISZERO :: PUSH_N 0x0de3 :: JUMPI

If the call stopped for an exception, the execution jumps to position 3555. Otherwise the execution falls through.

Position 3324 “0x33600160a060020a03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d6013600050600033600160a060020a03168152602001908152602001600020600050546040518082815260200191505060405180910390a26014600050600033600160a060020a0316815260200190815260200160002060005054601660008282825054039250508190555060006014600050600033600160a060020a031681526020019081526020016000206000508190555060006013600050600033600160a060020a0316815260200190815260200160002060005081905550”

CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0xbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d :: PUSH_N 0x13 :: PUSH_N 0x00 :: POP :: PUSH_N 0x00 :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: PUSH_N 0x00 :: SHA3 :: PUSH_N 0x00 :: POP :: SLOAD :: PUSH_N 0x40 :: MLOAD :: DUP1 :: DUP3 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: SWAP2 :: POP :: POP :: PUSH_N 0x40 :: MLOAD :: DUP1 :: SWAP2 :: SUB :: SWAP1 :: LOG2 :: PUSH_N 0x14 :: PUSH_N 0x00 :: POP :: PUSH_N 0x00 :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: PUSH_N 0x00 :: SHA3 :: PUSH_N 0x00 :: POP :: SLOAD :: PUSH_N 0x16 :: PUSH_N 0x00 :: DUP3 :: DUP3 :: DUP3 :: POP :: SLOAD :: SUB :: SWAP3 :: POP :: POP :: DUP2 :: SWAP1 :: SSTORE :: POP :: PUSH_N 0x00 :: PUSH_N 0x14 :: PUSH_N 0x00 :: POP :: PUSH_N 0x00 :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: PUSH_N 0x00 :: SHA3 :: PUSH_N 0x00 :: POP :: DUP2 :: SWAP1 :: SSTORE :: POP :: PUSH_N 0x00 :: PUSH_N 0x13 :: PUSH_N 0x00 :: POP :: PUSH_N 0x00 :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: PUSH_N 0x00 :: SHA3 :: PUSH_N 0x00 :: POP :: DUP2 :: SWAP1 :: SSTORE :: POP

This changes the storage and logs an event.

Position 3555 “0x5b56”

JUMPDEST :: JUMP

The jump destination is position 2714.

Position 3557 “0x5b4262054600600f60005054031115610e1357”

JUMPDEST :: TIMESTAMP :: PUSH_N 0x054600 :: PUSH_N 0x0f :: PUSH_N 0x00 :: POP :: SLOAD :: SUB :: GT :: ISZERO :: PUSH_N 0x0e13 :: JUMPI

The execution might jump here from position 895, so this snippet is a part of “divisor()”. This snippet compares the current time with the storage content at index 15 minus 345600. If the current time is late enough, the execution falls through. Otherwise the execution jumps to position 3603.

Position 3576 “0x6201518062127500600f6000505403420304601401905061098356”

PUSH_N 0x015180 :: PUSH_N 0x127500 :: PUSH_N 0x0f :: PUSH_N 0x00 :: POP :: SLOAD :: SUB :: TIMESTAMP :: SUB :: DIV :: PUSH_N 0x14 :: ADD :: SWAP1 :: POP :: PUSH_N 0x0983 :: JUMP

This snippet pushes something onto the stack and jumps to position 2435.

Position 3603 “0x5b50601e61098356”

JUMPDEST :: POP :: PUSH_N 0x1e :: PUSH_N 0x0983 :: JUMP

This snippet pushes 30 and jumps to position 2435. The execution paths after that depends on where we come from. For example, if the execution started at position 891, after position 2435, we jump to 2406.

Position 3611 “0x5b60001415610e2857”

JUMPDEST :: PUSH_N 0x00 :: EQ :: ISZERO :: PUSH_N 0x0e28 :: JUMPI

This should be a part of “vote()”. We come from positions 2071, 1516, 1542 and then here. This snippet judges if a storage value (I guess this is the Token balance of the caller) is zero. If zero, the execution falls through. Otherwise the execution jumps to position 3624.

Position 3620 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet jumps to position 2, causing an exception.

Position 3624 “0x5b6000341115610e3657”

JUMPDEST :: PUSH_N 0x00 :: CALLVALUE :: GT :: ISZERO :: PUSH_N 0x0e36 :: JUMPI

This snippet judges if the sent value is zero. If zero, the execution jumps to position 3638. Otherwise the execution falls through.

Position 3634 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet jumps to position 2, causing an exception.

Position 3638 “0x5b60008054859081101561000257”

JUMPDEST :: PUSH_N 0x00 :: DUP1 :: SLOAD :: DUP6 :: SWAP1 :: DUP2 :: LT :: ISZERO :: PUSH_N 0x0002 :: JUMPI

This snippet compares the storage content at index 0 against some user input (I guess this is the “_proposalID” argument). If the user input is small enough, the execution falls through. Otherwise the execution jumps to position 2, causing an exception.

Position 3652 “0x50600160a060020a03331681527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56e600e8602908101602052604090912054600080516020612a3683398151915291909101915060ff1680610eb057”

POP :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: CALLER :: AND :: DUP2 :: MSTORE :: PUSH_N 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56e :: PUSH_N 0x0e :: DUP7 :: MUL :: SWAP1 :: DUP2 :: ADD :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: SWAP1 :: SWAP2 :: SHA3 :: SLOAD :: PUSH_N 0x00 :: DUP1 :: MLOAD :: PUSH_N 0x20 :: PUSH_N 0x2a36 :: DUP4 :: CODECOPY :: DUP2 :: MLOAD :: SWAP2 :: MSTORE :: SWAP2 :: SWAP1 :: SWAP2 :: ADD :: SWAP2 :: POP :: PUSH_N 0xff :: AND :: DUP1 :: PUSH_N 0x0eb0 :: JUMPI

This snippet sees a boolean in the storage and the execution falls through if the boolean is false. Otherwise the execution jumps to position 3760.

Position 3743 “0x50600c810160205260406000205460ff16”

POP :: PUSH_N 0x0c :: DUP2 :: ADD :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: PUSH_N 0x00 :: SHA3 :: SLOAD :: PUSH_N 0xff :: AND

This snippet replaces the first element of the stack with another boolean from the storage.

Position 3760 “0x5b80610ebf57”

JUMPDEST :: DUP1 :: PUSH_N 0x0ebf :: JUMPI

If the top of the stack is zero, the execution falls through. Otherwise the execution jumps to position 3775.

Position 3766 “0x506003810154421015”

POP :: PUSH_N 0x03 :: DUP2 :: ADD :: SLOAD :: TIMESTAMP :: LT :: ISZERO

This snippet replaces the first element of the stack with the result of a comparison, if the current time is smaller than a value in the storage.

Position 3775 “0x5b15610ec957”

JUMPDEST :: ISZERO :: PUSH_N 0x0ec9 :: JUMPI

This snippet wraps up the if confidition . If the result is true, the execution falls through. Otherwise the execution jumps to position 3785.

Position 3781 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet jumps to position 2, causing an exception.

Position 3785 “0x5b8215610f0f57”

JUMPDEST :: DUP3 :: ISZERO :: PUSH_N 0x0f0f :: JUMPI

This snippet uses the user input pushed in the snippet at position 2071. Depending on this user input the execution might fall through or jump to position 3855.

Position 3792 “0x33600160a060020a03166000908152601460209081526040808320546009850180549091019055600b84019091529020805460ff19166001179055610f4b56”

CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x14 :: PUSH_N 0x20 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x40 :: DUP1 :: DUP4 :: SHA3 :: SLOAD :: PUSH_N 0x09 :: DUP6 :: ADD :: DUP1 :: SLOAD :: SWAP1 :: SWAP2 :: ADD :: SWAP1 :: SSTORE :: PUSH_N 0x0b :: DUP5 :: ADD :: SWAP1 :: SWAP2 :: MSTORE :: SWAP1 :: SHA3 :: DUP1 :: SLOAD :: PUSH_N 0xff :: NOT :: AND :: PUSH_N 0x01 :: OR :: SWAP1 :: SSTORE :: PUSH_N 0x0f4b :: JUMP

This snippet writes two values to the storage. I wondered why an SLOAD is necessary for writing “true” into the storage. I guess that’s because the boolean value is packed with other information into one word. After that the execution jumps to position 3915.

Position 3855 “0x5b33600160a060020a0316600090815260146020908152604080832054600a850180549091019055600c84019091529020805460ff19166001179055”

JUMPDEST :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x14 :: PUSH_N 0x20 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x40 :: DUP1 :: DUP4 :: SHA3 :: SLOAD :: PUSH_N 0x0a :: DUP6 :: ADD :: DUP1 :: SLOAD :: SWAP1 :: SWAP2 :: ADD :: SWAP1 :: SSTORE :: PUSH_N 0x0c :: DUP5 :: ADD :: SWAP1 :: SWAP2 :: MSTORE :: SWAP1 :: SHA3 :: DUP1 :: SLOAD :: PUSH_N 0xff :: NOT :: AND :: PUSH_N 0x01 :: OR :: SWAP1 :: SSTORE

This snippet is very similar to the previous one. The execution falls through.

Position 3915 “0x5b33600160a060020a03166000908152600b60205260408120541415610f7757”

JUMPDEST :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x0b :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: DUP2 :: SHA3 :: SLOAD :: EQ :: ISZERO :: PUSH_N 0x0f77 :: JUMPI

This snippet sees some storage content and judges if it’s zero. If zero, the execution falls through. Otherwise the execution jumps to position 3959.

I guess this snippet corresponds to this if-condition .

Position 3947 “0x6040600020849055610feb56”

PUSH_N 0x40 :: PUSH_N 0x00 :: SHA3 :: DUP5 :: SWAP1 :: SSTORE :: PUSH_N 0x0feb :: JUMP

This snippet changes the storage and jumps to position 4075.

Position 3959 “0x5b33600160a060020a03166000908152600b6020526040812054815481101561000257”

JUMPDEST :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x0b :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: DUP2 :: SHA3 :: SLOAD :: DUP2 :: SLOAD :: DUP2 :: LT :: ISZERO :: PUSH_N 0x0002 :: JUMPI

The execution comes from position 3915. This snippet checks the length of “proposals” array. If the array is not long enough, the execution jumps to position 2, causing an exception. Otherwise the execution falls through.

Position 3994 “0x9080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566600e909102015460038201541115610feb57”

SWAP1 :: DUP1 :: MSTORE :: PUSH_N 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566 :: PUSH_N 0x0e :: SWAP1 :: SWAP2 :: MUL :: ADD :: SLOAD :: PUSH_N 0x03 :: DUP3 :: ADD :: SLOAD :: GT :: ISZERO :: PUSH_N 0x0feb :: JUMPI

This snippet compares a storage value against a storage value. Depending on the comparison, the execution jumps to 4075 or falls through.

I guess this snippet is the if-condition here .

Position 4048 “0x33600160a060020a03166000908152600b60205260409020849055”

CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x0b :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: SWAP1 :: SHA3 :: DUP5 :: SWAP1 :: SSTORE

This snippet changes the storage and falls through.

Position 4075 “0x5b60408051848152905133600160a060020a03169186917f86abfce99b7dd908bec0169288797f85049ec73cbe046ed9de818fab3a497ae09181900360200190a3509291505056”

JUMPDEST :: PUSH_N 0x40 :: DUP1 :: MLOAD :: DUP5 :: DUP2 :: MSTORE :: SWAP1 :: MLOAD :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: SWAP2 :: DUP7 :: SWAP2 :: PUSH_N 0x86abfce99b7dd908bec0169288797f85049ec73cbe046ed9de818fab3a497ae0 :: SWAP2 :: DUP2 :: SWAP1 :: SUB :: PUSH_N 0x20 :: ADD :: SWAP1 :: LOG3 :: POP :: SWAP3 :: SWAP2 :: POP :: POP :: JUMP

An event is logged and the execution jumps to position 2406. After the jump, the top of the stack is zero.

Position 4146 “0x5b60008054879081101561000257”

JUMPDEST :: PUSH_N 0x00 :: DUP1 :: SLOAD :: DUP8 :: SWAP1 :: DUP2 :: LT :: ISZERO :: PUSH_N 0x0002 :: JUMPI

The execution comes from position 2288, which is the entry point for “checkProposalCode()”. This snippet checks the length of “proposals” array against a user input. If the user input is too large, the execution jumps to position 2, causing an exception. Otherwise the execution falls through.

Position 4160 “0x50808052600e8702600080516020612a3683398151915201905090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f1”

POP :: DUP1 :: DUP1 :: MSTORE :: PUSH_N 0x0e :: DUP8 :: MUL :: PUSH_N 0x00 :: DUP1 :: MLOAD :: PUSH_N 0x20 :: PUSH_N 0x2a36 :: DUP4 :: CODECOPY :: DUP2 :: MLOAD :: SWAP2 :: MSTORE :: ADD :: SWAP1 :: POP :: SWAP1 :: POP :: DUP5 :: DUP5 :: DUP5 :: PUSH_N 0x40 :: MLOAD :: DUP1 :: DUP5 :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0x60 :: PUSH_N 0x02 :: EXP :: MUL :: DUP2 :: MSTORE :: PUSH_N 0x14 :: ADD :: DUP4 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP3 :: DUP1 :: MLOAD :: SWAP1 :: PUSH_N 0x20 :: ADD :: SWAP1 :: DUP1 :: DUP4 :: DUP4 :: DUP3 :: SWAP1 :: PUSH_N 0x00 :: PUSH_N 0x04 :: PUSH_N 0x20 :: DUP5 :: PUSH_N 0x1f :: ADD :: DIV :: PUSH_N 0x0f :: MUL :: PUSH_N 0x03 :: ADD :: CALL

This snippet calls something at address 4 (!!!). This is very surprising.

Position 4253 “0x509050019350505050604051809103902081600501600050541491505094935050505056”

POP :: SWAP1 :: POP :: ADD :: SWAP4 :: POP :: POP :: POP :: POP :: PUSH_N 0x40 :: MLOAD :: DUP1 :: SWAP2 :: SUB :: SWAP1 :: SHA3 :: DUP2 :: PUSH_N 0x05 :: ADD :: PUSH_N 0x00 :: POP :: SLOAD :: EQ :: SWAP2 :: POP :: POP :: SWAP5 :: SWAP4 :: POP :: POP :: POP :: POP :: JUMP

This code just changes the stack and jumps to position 2406.

Position 4289 “0x5b600014156110ce57”

JUMPDEST :: PUSH_N 0x00 :: EQ :: ISZERO :: PUSH_N 0x10ce :: JUMPI

This snippet should be involved in “newProposal()”. The execution might jump to position 4302 or falls through.

If some storage content (the Token balance of the caller, I guess) is zero, the execution the execution falls through.

Position 4298 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet simply jumps to position 2, causing an exception.

Position 4302 “0x5b82801561111857”

JUMPDEST :: DUP3 :: DUP1 :: ISZERO :: PUSH_N 0x1118 :: JUMPI

The execution jumps here from position 4289. The execution might jump to position 4376 or falls through, depending on the user input (I guess “_newCureator”).

Position 4310 “0x508660001415806110e857”

POP :: DUP7 :: PUSH_N 0x00 :: EQ :: ISZERO :: DUP1 :: PUSH_N 0x10e8 :: JUMPI

The execution jumps to position 4328 or falls through.

Position 4321 “0x50845160001415”

POP :: DUP5 :: MLOAD :: PUSH_N 0x00 :: EQ :: ISZERO

This snippet just modifies the stack and falls through.

Position 4328 “0x5b8061110057”

JUMPDEST :: DUP1 :: PUSH_N 0x1100 :: JUMPI

The execution might jump to position 4352 or falls through.

Position 4334 “0x50600354600160a060020a03898116911614”

POP :: PUSH_N 0x03 :: SLOAD :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: DUP10 :: DUP2 :: AND :: SWAP2 :: AND :: EQ

This snippet compares the storage content at index 3 with some value in the stack (it’s unknown what it is because I don’t know how the execution arrives here). The result of the comparison replaces the first element of the stack.

Position 4352 “0x5b8061110b57”

JUMPDEST :: DUP1 :: PUSH_N 0x110b :: JUMPI

The execution might jump to position 4363 or falls through.

Position 4358 “0x5060003411”

POP :: PUSH_N 0x00 :: CALLVALUE :: GT

This snippet sees if the sent value is more than zero.

Position 4363 “0x5b8061111857”

JUMPDEST :: DUP1 :: PUSH_N 0x1118 :: JUMPI

If the sent value is more than zero the execution jumps to position 4376. Otherwise the execution falls through.

Position 4369 “0x5062093a808410”

POP :: PUSH_N 0x093a80 :: DUP5 :: LT

(wait till we see how arrives at position 4289)

Position 4376 “0x5b1561112257”

JUMPDEST :: ISZERO :: PUSH_N 0x1122 :: JUMPI

The execution might jump to position 4386 or falls through, depending on some user input (I guess “_newCurator”).

Position 4382 “0x61000256”

PUSH_N 0x0002 :: JUMP

The execution jumps to position 2, causing an exception.

Position 4386 “0x5b8215801561114257”

JUMPDEST :: DUP3 :: ISZERO :: DUP1 :: ISZERO :: PUSH_N 0x1142 :: JUMPI

The execution jumps to position 4418 or falls through, again depending on the user input.

Position 4395 “0x506111348861115c56”

POP :: PUSH_N 0x1134 :: DUP9 :: PUSH_N 0x115c :: JUMP

The execution jumps to position 4444.

Position 4404 “0x5b158061114257”

JUMPDEST :: ISZERO :: DUP1 :: PUSH_N 0x1142 :: JUMPI

We are currently here, after checking “isRecipientAllowed(_recipient)”. The execution might fall through or jump to position 4418.

Position 4411 “0x50621275008410”

POP :: PUSH_N 0x127500 :: DUP5 :: LT

This snippet compares a part of the user input against 1209600, which is fourteen days in seconds. The result is left on top of the stack.

Position 4418 “0x5b156111fe57”

JUMPDEST :: ISZERO :: PUSH_N 0x11fe :: JUMPI

If the user input is smaller, the execution falls through. Otherwise the execution jumps to position 4606.

Position 4424 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet causes an exception.

Position 4428 “0x5b83546118e590600160a060020a0316”

JUMPDEST :: DUP4 :: SLOAD :: PUSH_N 0x18e5 :: SWAP1 :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND

It’s unknown how the execution arrives here.

Position 4444 “0x5b600160a060020a03811660009081526004602052604081205460ff16806111f157”

JUMPDEST :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: DUP2 :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x04 :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: DUP2 :: SHA3 :: SLOAD :: PUSH_N 0xff :: AND :: DUP1 :: PUSH_N 0x11f1 :: JUMPI

The execution might jump here from position 4395. Depending on a storage value, the execution might jump to position 4593 or falls through.

Position 4478 “0x50601254600160a060020a039081169083161480156111f157”

POP :: PUSH_N 0x12 :: SLOAD :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: SWAP1 :: DUP2 :: AND :: SWAP1 :: DUP4 :: AND :: EQ :: DUP1 :: ISZERO :: PUSH_N 0x11f1 :: JUMPI

This snippet compares a user input with storage content at index 18. I guess we are on this comparison . If equal, the execution falls through. Otherwise the execution jumps to position 4593.

Position 4503 “0x50601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1”

POP :: PUSH_N 0x12 :: PUSH_N 0x00 :: SWAP1 :: SLOAD :: SWAP1 :: PUSH_N 0x0100 :: EXP :: SWAP1 :: DIV :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0xd2cc718f :: PUSH_N 0x40 :: MLOAD :: DUP2 :: PUSH_N 0xe0 :: PUSH_N 0x02 :: EXP :: MUL :: DUP2 :: MSTORE :: PUSH_N 0x04 :: ADD :: DUP1 :: SWAP1 :: POP :: PUSH_N 0x20 :: PUSH_N 0x40 :: MLOAD :: DUP1 :: DUP4 :: SUB :: DUP2 :: PUSH_N 0x00 :: DUP8 :: PUSH_N 0x61da :: GAS :: SUB :: CALL

This snippet calls the address at storage index 18 (I think this is the “extraBalance” address). So, I guess the call is on this line .

Position 4576 “0x1561000257”

ISZERO :: PUSH_N 0x0002 :: JUMPI

If the call had an exception, the execution jumps to position 2, causing an exception in turn.

Position 4581 “0x505060405151600654119050”

POP :: POP :: PUSH_N 0x40 :: MLOAD :: MLOAD :: PUSH_N 0x06 :: SLOAD :: GT :: SWAP1 :: POP

This snippet compares the result of the call against the storage content at index 6 (I guess “totalRewardToken”).

Position 4593 “0x5b156129a157”

JUMPDEST :: ISZERO :: PUSH_N 0x29a1 :: JUMPI

Depending on the comparison the execution jumps to position 10657 or falls through (when the storage value is bigger).

Position 4599 “0x50600161060656”

POP :: PUSH_N 0x01 :: PUSH_N 0x0606 :: JUMP

This snippet jumps to position 1542, and then to position 4404, and then to position 4411.

Position 4606 “0x5b6249d40084111561120e57”

JUMPDEST :: PUSH_N 0x49d400 :: DUP5 :: GT :: ISZERO :: PUSH_N 0x120e :: JUMPI

The execution jumps here from position 4418. This snippet compares a user input against 4838400 (which is 8 weeks in seconds). If the user input is bigger, the execution falls through. Otherwise the execution jumps to position 4622.

Position 4618 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet jumps to position 2, causing an exception.

Position 4622 “0x5b60115460ff16158061122157”

JUMPDEST :: PUSH_N 0x11 :: SLOAD :: PUSH_N 0xff :: AND :: ISZERO :: DUP1 :: PUSH_N 0x1221 :: JUMPI

This snippet looks at the storage content at index 17. If it’s false, the execution jumps to position 4641. Otherwise the exception falls through.

I guess we are on this line .

Position 4635 “0x50600f544210”

POP :: PUSH_N 0x0f :: SLOAD :: TIMESTAMP :: LT

This line compares the current time against the storage content at index 15. The result replaces the first element of the stack.

I guess we are on this line .

Position 4641 “0x5b8061123657”

JUMPDEST :: DUP1 :: PUSH_N 0x1236 :: JUMPI

If the result is zero, the execution falls through. Otherwise the execution jumps to position 4662.

Position 4647 “0x50600c543410801561123657”

POP :: PUSH_N 0x0c :: SLOAD :: CALLVALUE :: LT :: DUP1 :: ISZERO :: PUSH_N 0x1236 :: JUMPI

This snippet compares the sent value against the storage content at index 12. If the value is small, the execution falls through. Otherwise the execution jumps to position 4662.

I guess we are on this line.

Position 4659 “0x508215”

POP :: DUP3 :: ISZERO

This just organizes the stack for the short-cutting (&&).

Position 4662 “0x5b1561124057”

JUMPDEST :: ISZERO :: PUSH_N 0x1240 :: JUMPI

This line checks some user input (I guess “_newCurator”). If it’s non-zero, the execution jumps to position 4672. Otherwise the execution falls through.

Position 4668 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet causes an exception by jumping to position 2.

Position 4672 “0x5b42844201101561124f57”

JUMPDEST :: TIMESTAMP :: DUP5 :: TIMESTAMP :: ADD :: LT :: ISZERO :: PUSH_N 0x124f :: JUMPI

This snippet checks for some overflows in an addition. If an overflow happens, the execution falls through. Otherwise the execution jumps to position 4687.

Position 4683 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet causes an exception by jumping to position 2.

Position 4687 “0x5b30600160a060020a031633600160a060020a0316141561126e57”

JUMPDEST :: ADDRESS :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: EQ :: ISZERO :: PUSH_N 0x126e :: JUMPI

This snippet compares the address of the caller and the address of this contract. If they are equal, the execution falls through. Otherwise the execution jumps to position 4718.

Position 4714 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet causes an exception by jumping to position 2 (where “JUMPDEST” instruction is not).

Position 4718 “0x5b60008054600181018083559091908280158290116112a557”

JUMPDEST :: PUSH_N 0x00 :: DUP1 :: SLOAD :: PUSH_N 0x01 :: DUP2 :: ADD :: DUP1 :: DUP4 :: SSTORE :: SWAP1 :: SWAP2 :: SWAP1 :: DUP3 :: DUP1 :: ISZERO :: DUP3 :: SWAP1 :: GT :: PUSH_N 0x12a5 :: JUMPI

This snippet seems to be testing the length of “proposals” array to see if the length overflows to zero… In such a case the execution jumps to position 4773. Otherwise the execution falls through.

Position 4743 “0x600e0281600e0283600052602060002091820191016112a5919061136a56”

PUSH_N 0x0e :: MUL :: DUP2 :: PUSH_N 0x0e :: MUL :: DUP4 :: PUSH_N 0x00 :: MSTORE :: PUSH_N 0x20 :: PUSH_N 0x00 :: SHA3 :: SWAP2 :: DUP3 :: ADD :: SWAP2 :: ADD :: PUSH_N 0x12a5 :: SWAP2 :: SWAP1 :: PUSH_N 0x136a :: JUMP

This line increments the length of “proposals” array. The execution continues at position 4970.

Position 4773 “0x5b5050600080549294509184915081101561000257”

JUMPDEST :: POP :: POP :: PUSH_N 0x00 :: DUP1 :: SLOAD :: SWAP3 :: SWAP5 :: POP :: SWAP2 :: DUP5 :: SWAP2 :: POP :: DUP2 :: LT :: ISZERO :: PUSH_N 0x0002 :: JUMPI

This line actually increments the length of “proposals” array. If the length did not increase (overflow), the execution jumps to position 2, causing an exception.

Position 4794 “0x50808052600e8302600080516020612a368339815191520190508054600160a060020a031916891781556001818101899055875160028084018054600082815260209081902096975091959481161561010002600019011691909104601f908101829004840193918b019083901061146257”

POP :: DUP1 :: DUP1 :: MSTORE :: PUSH_N 0x0e :: DUP4 :: MUL :: PUSH_N 0x00 :: DUP1 :: MLOAD :: PUSH_N 0x20 :: PUSH_N 0x2a36 :: DUP4 :: CODECOPY :: DUP2 :: MLOAD :: SWAP2 :: MSTORE :: ADD :: SWAP1 :: POP :: DUP1 :: SLOAD :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: NOT :: AND :: DUP10 :: OR :: DUP2 :: SSTORE :: PUSH_N 0x01 :: DUP2 :: DUP2 :: ADD :: DUP10 :: SWAP1 :: SSTORE :: DUP8 :: MLOAD :: PUSH_N 0x02 :: DUP1 :: DUP5 :: ADD :: DUP1 :: SLOAD :: PUSH_N 0x00 :: DUP3 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: SWAP1 :: DUP2 :: SWAP1 :: SHA3 :: SWAP7 :: SWAP8 :: POP :: SWAP2 :: SWAP6 :: SWAP5 :: DUP2 :: AND :: ISZERO :: PUSH_N 0x0100 :: MUL :: PUSH_N 0x00 :: NOT :: ADD :: AND :: SWAP2 :: SWAP1 :: SWAP2 :: DIV :: PUSH_N 0x1f :: SWAP1 :: DUP2 :: ADD :: DUP3 :: SWAP1 :: DIV :: DUP5 :: ADD :: SWAP4 :: SWAP2 :: DUP12 :: ADD :: SWAP1 :: DUP4 :: SWAP1 :: LT :: PUSH_N 0x1462 :: JUMPI

Might jump to position 5218 or fall through, depending on something is larger than 31 (I guess the length of the proposal description; the Solidity compiler uses different representations depending on the length being larger than 31).

Position 4920 “0x5b5061149292915061144a56”

JUMPDEST :: POP :: PUSH_N 0x1492 :: SWAP3 :: SWAP2 :: POP :: PUSH_N 0x144a :: JUMP

This jumps to position 5194.

Position 4970 “0x5b8082111561145e57”

JUMPDEST :: DUP1 :: DUP3 :: GT :: ISZERO :: PUSH_N 0x145e :: JUMPI

This line also checks for some sort of overflow. In case of an overflow, the execution falls through. Otherwise the execution jumps to position 5214.

Position 4979 “0x8054600160a060020a03191681556000600182810182905560028084018054848255909281161561010002600019011604601f81901061143057”

DUP1 :: SLOAD :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: NOT :: AND :: DUP2 :: SSTORE :: PUSH_N 0x00 :: PUSH_N 0x01 :: DUP3 :: DUP2 :: ADD :: DUP3 :: SWAP1 :: SSTORE :: PUSH_N 0x02 :: DUP1 :: DUP5 :: ADD :: DUP1 :: SLOAD :: DUP5 :: DUP3 :: SSTORE :: SWAP1 :: SWAP3 :: DUP2 :: AND :: ISZERO :: PUSH_N 0x0100 :: MUL :: PUSH_N 0x00 :: NOT :: ADD :: AND :: DIV :: PUSH_N 0x1f :: DUP2 :: SWAP1 :: LT :: PUSH_N 0x1430 :: JUMPI

This might jump to position 5168. This snippet looks similar to the snippet at position 4794. I don’t get these. I think I should read the solidity compiler code to see the handling of array extension.

It seems like this snippet judges if the length of the byte sequence is less than 32 (thus expressible with “FixedBytesType” in the solidity source code).

Position 5214 “0x5b509056”

JUMPDEST :: POP :: SWAP1 :: JUMP

The execution might come here from position 4970. The execution jumps to position 4773.

Position 5266 “0x5b50508787866040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f1”

JUMPDEST :: POP :: POP :: DUP8 :: DUP8 :: DUP7 :: PUSH_N 0x40 :: MLOAD :: DUP1 :: DUP5 :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0x60 :: PUSH_N 0x02 :: EXP :: MUL :: DUP2 :: MSTORE :: PUSH_N 0x14 :: ADD :: DUP4 :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: DUP3 :: DUP1 :: MLOAD :: SWAP1 :: PUSH_N 0x20 :: ADD :: SWAP1 :: DUP1 :: DUP4 :: DUP4 :: DUP3 :: SWAP1 :: PUSH_N 0x00 :: PUSH_N 0x04 :: PUSH_N 0x20 :: DUP5 :: PUSH_N 0x1f :: ADD :: DIV :: PUSH_N 0x0f :: MUL :: PUSH_N 0x03 :: ADD :: CALL

This snippet makes a call to address 4. The reason is unknown.

Position 5334 “0x50905001935050505060405180910390208160050160005081905550834201816003016000508190555060018160040160006101000a81548160ff02191690830217905550828160070160006101000a81548160ff02191690830217905550821561157857”

POP :: SWAP1 :: POP :: ADD :: SWAP4 :: POP :: POP :: POP :: POP :: PUSH_N 0x40 :: MLOAD :: DUP1 :: SWAP2 :: SUB :: SWAP1 :: SHA3 :: DUP2 :: PUSH_N 0x05 :: ADD :: PUSH_N 0x00 :: POP :: DUP2 :: SWAP1 :: SSTORE :: POP :: DUP4 :: TIMESTAMP :: ADD :: DUP2 :: PUSH_N 0x03 :: ADD :: PUSH_N 0x00 :: POP :: DUP2 :: SWAP1 :: SSTORE :: POP :: PUSH_N 0x01 :: DUP2 :: PUSH_N 0x04 :: ADD :: PUSH_N 0x00 :: PUSH_N 0x0100 :: EXP :: DUP2 :: SLOAD :: DUP2 :: PUSH_N 0xff :: MUL :: NOT :: AND :: SWAP1 :: DUP4 :: MUL :: OR :: SWAP1 :: SSTORE :: POP :: DUP3 :: DUP2 :: PUSH_N 0x07 :: ADD :: PUSH_N 0x00 :: PUSH_N 0x0100 :: EXP :: DUP2 :: SLOAD :: DUP2 :: PUSH_N 0xff :: MUL :: NOT :: AND :: SWAP1 :: DUP4 :: MUL :: OR :: SWAP1 :: SSTORE :: POP :: DUP3 :: ISZERO :: PUSH_N 0x1578 :: JUMPI

This snippet looks at the user input, and jumps to position 5496 conditionally.

Position 5435 “0x6008810180546001810180835590919082801582901161157357”

PUSH_N 0x08 :: DUP2 :: ADD :: DUP1 :: SLOAD :: PUSH_N 0x01 :: DUP2 :: ADD :: DUP1 :: DUP4 :: SSTORE :: SWAP1 :: SWAP2 :: SWAP1 :: DUP3 :: DUP1 :: ISZERO :: DUP3 :: SWAP1 :: GT :: PUSH_N 0x1573 :: JUMPI

This might jump to position 5491.

Position 5461 “0x60040281600402836000526020600020918201910161157391906113fc56”

PUSH_N 0x04 :: MUL :: DUP2 :: PUSH_N 0x04 :: MUL :: DUP4 :: PUSH_N 0x00 :: MSTORE :: PUSH_N 0x20 :: PUSH_N 0x00 :: SHA3 :: SWAP2 :: DUP3 :: ADD :: SWAP2 :: ADD :: PUSH_N 0x1573 :: SWAP2 :: SWAP1 :: PUSH_N 0x13fc :: JUMP

This jumps to position 5116.

Position 5491 “0x5b50505050”

JUMPDEST :: POP :: POP :: POP :: POP

This snippet removes four elements from the stack.

Position 5496 “0x5b600d8082018054600160a060020a031916331790553460068301819055815401905560408051600160a060020a038a16815260208181018a9052918101859052608060608201818152895191830191909152885185937f5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f938d938d938a938e93929160a084019185810191908190849082908590600090600490601f850104600f02600301f1”

JUMPDEST :: PUSH_N 0x0d :: DUP1 :: DUP3 :: ADD :: DUP1 :: SLOAD :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: NOT :: AND :: CALLER :: OR :: SWAP1 :: SSTORE :: CALLVALUE :: PUSH_N 0x06 :: DUP4 :: ADD :: DUP2 :: SWAP1 :: SSTORE :: DUP2 :: SLOAD :: ADD :: SWAP1 :: SSTORE :: PUSH_N 0x40 :: DUP1 :: MLOAD :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: DUP11 :: AND :: DUP2 :: MSTORE :: PUSH_N 0x20 :: DUP2 :: DUP2 :: ADD :: DUP11 :: SWAP1 :: MSTORE :: SWAP2 :: DUP2 :: ADD :: DUP6 :: SWAP1 :: MSTORE :: PUSH_N 0x80 :: PUSH_N 0x60 :: DUP3 :: ADD :: DUP2 :: DUP2 :: MSTORE :: DUP10 :: MLOAD :: SWAP2 :: DUP4 :: ADD :: SWAP2 :: SWAP1 :: SWAP2 :: MSTORE :: DUP9 :: MLOAD :: DUP6 :: SWAP4 :: PUSH_N 0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f :: SWAP4 :: DUP14 :: SWAP4 :: DUP14 :: SWAP4 :: DUP11 :: SWAP4 :: DUP15 :: SWAP4 :: SWAP3 :: SWAP2 :: PUSH_N 0xa0 :: DUP5 :: ADD :: SWAP2 :: DUP6 :: DUP2 :: ADD :: SWAP2 :: SWAP1 :: DUP2 :: SWAP1 :: DUP5 :: SWAP1 :: DUP3 :: SWAP1 :: DUP6 :: SWAP1 :: PUSH_N 0x00 :: SWAP1 :: PUSH_N 0x04 :: SWAP1 :: PUSH_N 0x1f :: DUP6 :: ADD :: DIV :: PUSH_N 0x0f :: MUL :: PUSH_N 0x03 :: ADD :: CALL

This snippet also calls address 4.

Position 5663 “0x50905090810190601f16801561164857”

POP :: SWAP1 :: POP :: SWAP1 :: DUP2 :: ADD :: SWAP1 :: PUSH_N 0x1f :: AND :: DUP1 :: ISZERO :: PUSH_N 0x1648 :: JUMPI

This snippet judges if something is a multiple of 32. If not, the execution falls through. Otherwise the execution jumps to position 5704.

Position 5679 “0x80820380516001836020036101000a03191681526020019150”

DUP1 :: DUP3 :: SUB :: DUP1 :: MLOAD :: PUSH_N 0x01 :: DUP4 :: PUSH_N 0x20 :: SUB :: PUSH_N 0x0100 :: EXP :: SUB :: NOT :: AND :: DUP2 :: MSTORE :: PUSH_N 0x20 :: ADD :: SWAP2 :: POP

This snippet changes the stack and the memory somehow.

Position 5704 “0x5b509550505050505060405180910390a250969550505050505056”

JUMPDEST :: POP :: SWAP6 :: POP :: POP :: POP :: POP :: POP :: POP :: PUSH_N 0x40 :: MLOAD :: DUP1 :: SWAP2 :: SUB :: SWAP1 :: LOG2 :: POP :: SWAP7 :: SWAP6 :: POP :: POP :: POP :: POP :: POP :: POP :: JUMP

This logs something and jumps to position 2406.

Position 8564 “0x5b30600160a060020a039081166000818152600560209081526040808320805495871680855282852080549097019096558484528390556009909152808220805494835290822080549094019093559081529055”

JUMPDEST :: ADDRESS :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: SWAP1 :: DUP2 :: AND :: PUSH_N 0x00 :: DUP2 :: DUP2 :: MSTORE :: PUSH_N 0x05 :: PUSH_N 0x20 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x40 :: DUP1 :: DUP4 :: SHA3 :: DUP1 :: SLOAD :: SWAP6 :: DUP8 :: AND :: DUP1 :: DUP6 :: MSTORE :: DUP3 :: DUP6 :: SHA3 :: DUP1 :: SLOAD :: SWAP1 :: SWAP8 :: ADD :: SWAP1 :: SWAP7 :: SSTORE :: DUP5 :: DUP5 :: MSTORE :: DUP4 :: SWAP1 :: SSTORE :: PUSH_N 0x09 :: SWAP1 :: SWAP2 :: MSTORE :: DUP1 :: DUP3 :: SHA3 :: DUP1 :: SLOAD :: SWAP5 :: DUP4 :: MSTORE :: SWAP1 :: DUP3 :: SHA3 :: DUP1 :: SLOAD :: SWAP1 :: SWAP5 :: ADD :: SWAP1 :: SWAP4 :: SSTORE :: SWAP1 :: DUP2 :: MSTORE :: SWAP1 :: SSTORE

The execution might jump here from the snippet at position 8686 (“newContract()”).

This snippet changes the storage.

Position 8648 “0x5b5056”

JUMPDEST :: POP :: JUMP

This snippet jumps to position 2714, which stops the execution.

Position 8651 “0x5b604051600160a060020a0382811691309091163190600081818185876185025a03f1”

JUMPDEST :: PUSH_N 0x40 :: MLOAD :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: DUP3 :: DUP2 :: AND :: SWAP2 :: ADDRESS :: SWAP1 :: SWAP2 :: AND :: BALANCE :: SWAP1 :: PUSH_N 0x00 :: DUP2 :: DUP2 :: DUP2 :: DUP6 :: DUP8 :: PUSH_N 0x8502 :: GAS :: SUB :: CALL

The execution jumps here from position 1499, so this snippet should be a part of “newContract()”.

This snippet makes a call to the address specified by a user input. The whole Eth balance of this contract is sent along.

Position 8686 “0x92505050151561217457”

SWAP3 :: POP :: POP :: POP :: ISZERO :: ISZERO :: PUSH_N 0x2174 :: JUMPI

If the call stopped for an exception the execution falls through. Otherwise the execution jumps to position 8564.

Position 8696 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet jumps to position 2, causing an exception.

Position 8857 “0x61000256”

PUSH_N 0x0002 :: JUMP

By the way, it’s a mystery why the instruction PUSH2 is used here instead of PUSH1. That would decrease the size of the bytecode without causing too much troubles.

Position 9351 “0x5b80156124a257”

JUMPDEST :: DUP1 :: ISZERO :: PUSH_N 0x24a2 :: JUMPI

The execution might jump here from position 1839. In that case, depending on the boolean at storage index 17, the execution might jump to position 9378 or falls through.

Position 9358 “0x506124a2338484”

POP :: PUSH_N 0x24a2 :: CALLER :: DUP5 :: DUP5

This just arranges the stack. I’m not writing the final stack contents here because my tool can remember it, and continues execution using the code that appears below.

Position 9365 “0x5b6000600061293a856105ec56”

JUMPDEST :: PUSH_N 0x00 :: PUSH_N 0x00 :: PUSH_N 0x293a :: DUP6 :: PUSH_N 0x05ec :: JUMP

This snippet reorganizes the stack and jumps to position 1516. After a while the execution resumes at position 10554.

Position 9378 “0x5b80156124be57”

JUMPDEST :: DUP1 :: ISZERO :: PUSH_N 0x24be :: JUMPI

We might jump here from position 9351. So this should be a part of “transfer()”. In that case, depending on the current time and the storage value at index 15, the execution might jump to 9406 or falls through.

I think we are on this line .

Position 9385 “0x506124be83836000600034111561261c57”

POP :: PUSH_N 0x24be :: DUP4 :: DUP4 :: PUSH_N 0x00 :: PUSH_N 0x00 :: CALLVALUE :: GT :: ISZERO :: PUSH_N 0x261c :: JUMPI

This snippet checks the sent value. If the sent value is more than zero, the execution falls through. Otherwise the execution jumps to position 9756.

Position 9402 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet jumps to position 2, causing an exception.

Position 9449 “0x5b80156124fb57”

JUMPDEST :: DUP1 :: ISZERO :: PUSH_N 0x24fb :: JUMPI

The execution might jump here from position 1073 (“transferFrom()”).

This snippet compares the current time agains the storage content at index 15, and jumps to position 9467 if the current time is not late enough.

Position 9456 “0x506124fb84848461249556”

POP :: PUSH_N 0x24fb :: DUP5 :: DUP5 :: DUP5 :: PUSH_N 0x2495 :: JUMP

This snippet changes the stack and jumps to position 9365.

Position 9467 “0x5b801561251857”

JUMPDEST :: DUP1 :: ISZERO :: PUSH_N 0x2518 :: JUMPI

The execution might come here from position 10600. In that case, the execution falls through.

Position 9474 “0x50612518848484600060003411156126c157”

POP :: PUSH_N 0x2518 :: DUP5 :: DUP5 :: DUP5 :: PUSH_N 0x00 :: PUSH_N 0x00 :: CALLVALUE :: GT :: ISZERO :: PUSH_N 0x26c1 :: JUMPI

This snippet checks the sent value and if it’s greater than zero, the execution falls through. Otherwise the execution jumps to position 9921.

Position 9492 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet jumps to position 2, causing an exception.

Position 9496 “0x5b15610b9f57”

JUMPDEST :: ISZERO :: PUSH_N 0x0b9f :: JUMPI

The execution falls through or jumps to position 2975, depending on the topmost value of the stack. If the topmost value is zero, the execution jumps to position 2975 and causes an exception. Otherwise the execution falls through.

Position 9502 “0x50600161252856”

POP :: PUSH_N 0x01 :: PUSH_N 0x2528 :: JUMP

We replace the topmost value of the stack with one and jump to position 9512.

Position 9509 “0x5b9050”

JUMPDEST :: SWAP1 :: POP

Position 9512 “0x5b939250505056”

JUMPDEST :: SWAP4 :: SWAP3 :: POP :: POP :: POP :: JUMP

This is a gadget for shuffling the stack and jumps. For instance, if we come from the sequence of positions 1038, 1051, 1067, 1073, 9449, 9456, 9365, 1516, 1542, 10554, 10600, 9467, 9474, 9921, 9957, 9994, 10001, 10006 and 10148, this jumps to position 9496, comes here again and then jumps to position 2406.

Position 9625 “0x5b600354600160a060020a0390811633909116146125b557”

JUMPDEST :: PUSH_N 0x03 :: SLOAD :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: SWAP1 :: DUP2 :: AND :: CALLER :: SWAP1 :: SWAP2 :: AND :: EQ :: PUSH_N 0x25b5 :: JUMPI

The execution jumps here from position 1547 (“changeAllowedRecipients()”). This snippet compares the caller’s address against the address at storage index 3. If they are not equal the execution falls through. If they are equal the execution jumps to position 9653.

Position 9649 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet jumps to position 2, causing an exception.

Position 9653 “0x5b600160a060020a038316600081815260046020908152604091829020805460ff191686179055815185815291517f73ad2a153c8b67991df9459024950b318a609782cee8c7eeda47b905f9baa91f9281900390910190a250600161033f56”

JUMPDEST :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: DUP4 :: AND :: PUSH_N 0x00 :: DUP2 :: DUP2 :: MSTORE :: PUSH_N 0x04 :: PUSH_N 0x20 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x40 :: SWAP2 :: DUP3 :: SWAP1 :: SHA3 :: DUP1 :: SLOAD :: PUSH_N 0xff :: NOT :: AND :: DUP7 :: OR :: SWAP1 :: SSTORE :: DUP2 :: MLOAD :: DUP6 :: DUP2 :: MSTORE :: SWAP2 :: MLOAD :: PUSH_N 0x73ad2a153c8b67991df9459024950b318a609782cee8c7eeda47b905f9baa91f :: SWAP3 :: DUP2 :: SWAP1 :: SUB :: SWAP1 :: SWAP2 :: ADD :: SWAP1 :: LOG2 :: POP :: PUSH_N 0x01 :: PUSH_N 0x033f :: JUMP

This snippet changes the storage, logs an event and jumps to position 831 with the topmost stack element being one. After that the execution jumps to position 2406.

Position 9748 “0x5b50600061098356”

JUMPDEST :: POP :: PUSH_N 0x00 :: PUSH_N 0x0983 :: JUMP

The execution comes here from position 1636 (“halveMinQuorum()”). The execution jumps to position 2435. If we come here from positions 1572, 1596, 1616 and 1636, the execution continues to position 2406 after position 2435.

Position 9756 “0x5b33600160a060020a031660009081526014602052604090205482901080159061264557”

JUMPDEST :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x14 :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: SWAP1 :: SHA3 :: SLOAD :: DUP3 :: SWAP1 :: LT :: DUP1 :: ISZERO :: SWAP1 :: PUSH_N 0x2645 :: JUMPI

The execution might jump here from position 9385. I think now we are on this line . This snippet compares some value on the stack against a value in the storage. If the storage content is smaller, the execution jumps to position 9797. Otherwise the execution falls through.

Position 9792 “0x5060008211”

POP :: PUSH_N 0x00 :: DUP3 :: GT

This line compares the same value against zero.

Position 9797 “0x5b156126b957”

JUMPDEST :: ISZERO :: PUSH_N 0x26b9 :: JUMPI

If the value is more than zero, the execution falls through. Otherwise the execution jumps to position 9913.

Position 9803 “0x600160a060020a03338116600081815260146020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161033f56”

PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: CALLER :: DUP2 :: AND :: PUSH_N 0x00 :: DUP2 :: DUP2 :: MSTORE :: PUSH_N 0x14 :: PUSH_N 0x20 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x40 :: DUP1 :: DUP4 :: SHA3 :: DUP1 :: SLOAD :: DUP9 :: SWAP1 :: SUB :: SWAP1 :: SSTORE :: SWAP4 :: DUP8 :: AND :: DUP1 :: DUP4 :: MSTORE :: SWAP2 :: DUP5 :: SWAP1 :: SHA3 :: DUP1 :: SLOAD :: DUP8 :: ADD :: SWAP1 :: SSTORE :: DUP4 :: MLOAD :: DUP7 :: DUP2 :: MSTORE :: SWAP4 :: MLOAD :: SWAP2 :: SWAP4 :: PUSH_N 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef :: SWAP3 :: SWAP1 :: DUP2 :: SWAP1 :: SUB :: SWAP1 :: SWAP2 :: ADD :: SWAP1 :: LOG3 :: POP :: PUSH_N 0x01 :: PUSH_N 0x033f :: JUMP

This snippet changes the storage, logs an event and jumps to position 831, and then to position 9406, position 9412, and then position 831 again.

I think I need to understand how internal function calls are translated.

Position 9913 “0x5b50600061033f56”

JUMPDEST :: POP :: PUSH_N 0x00 :: PUSH_N 0x033f :: JUMP

This snippet jumps to position 831 and then to position 9406, and then to position 2975, causing an exception.

Position 9921 “0x5b600160a060020a03841660009081526014602052604090205482901080159061270a57”

JUMPDEST :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: DUP5 :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x14 :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: SWAP1 :: SHA3 :: SLOAD :: DUP3 :: SWAP1 :: LT :: DUP1 :: ISZERO :: SWAP1 :: PUSH_N 0x270a :: JUMPI

The execution might jump to 9994 or fall through. The condition is rather complicated. I guess we are still in the condition checking lines .

Position 9957 “0x50601560209081526040600081812033600160a060020a0316825290925290205482901015”

POP :: PUSH_N 0x15 :: PUSH_N 0x20 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x40 :: PUSH_N 0x00 :: DUP2 :: DUP2 :: SHA3 :: CALLER :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: AND :: DUP3 :: MSTORE :: SWAP1 :: SWAP3 :: MSTORE :: SWAP1 :: SHA3 :: SLOAD :: DUP3 :: SWAP1 :: LT :: ISZERO

This snippet also compares some storage value. The result replaces the first element of the stack.

Position 9994 “0x5b801561271657”

JUMPDEST :: DUP1 :: ISZERO :: PUSH_N 0x2716 :: JUMPI

Depending on the result of the comparison, the execution might jump to 10006 or falls through.

Position 10001 “0x5060008211”

POP :: PUSH_N 0x00 :: DUP3 :: GT

This snippet just compares the user input with zero. The result replaces the first element of the stack.

Position 10006 “0x5b156127a457”

JUMPDEST :: ISZERO :: PUSH_N 0x27a4 :: JUMPI

Depending on the pushed result, the execution might jump to position 10148.

Position 10148 “0x5b50600061252856”

JUMPDEST :: POP :: PUSH_N 0x00 :: PUSH_N 0x2528 :: JUMP

This jumps to position 9512 with zero at the top of the stack.

Position 10156 “0x5b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f1”

JUMPDEST :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: DUP4 :: DUP2 :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x0a :: PUSH_N 0x20 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x40 :: DUP1 :: DUP4 :: SHA3 :: SLOAD :: PUSH_N 0x16 :: SLOAD :: PUSH_N 0x07 :: SLOAD :: DUP4 :: MLOAD :: PUSH_N 0xe0 :: PUSH_N 0x02 :: EXP :: PUSH_N 0xd2cc718f :: MUL :: DUP2 :: MSTORE :: SWAP4 :: MLOAD :: SWAP3 :: SWAP7 :: SWAP2 :: SWAP6 :: SWAP2 :: AND :: SWAP4 :: PUSH_N 0xd2cc718f :: SWAP4 :: PUSH_N 0x04 :: DUP2 :: DUP2 :: ADD :: SWAP5 :: SWAP3 :: SWAP4 :: SWAP2 :: DUP4 :: SWAP1 :: SUB :: ADD :: SWAP1 :: DUP3 :: SWAP1 :: DUP8 :: PUSH_N 0x61da :: GAS :: SUB :: CALL

The execution jumps here from position 2156 (“transferFromWithoutReward()”). This snippet calls the address at storage index 7.

Position 10245 “0x1561000257”

ISZERO :: PUSH_N 0x0002 :: JUMPI

If the call above causes an exception, the execution jumps to position 2, causing an exception in turn.

Position 10250 “0x505060405151905061281a866105ec56”

POP :: POP :: PUSH_N 0x40 :: MLOAD :: MLOAD :: SWAP1 :: POP :: PUSH_N 0x281a :: DUP7 :: PUSH_N 0x05ec :: JUMP

This snippet jumps to position 1516, but eventually the execution continues at position 10266.

Position 10266 “0x5b0204101561282757”

JUMPDEST :: MUL :: DIV :: LT :: ISZERO :: PUSH_N 0x2827 :: JUMPI

This snippet compares values from the storage and jumps to position 10279 conditionally.

Position 10275 “0x61000256”

PUSH_N 0x0002 :: JUMP

This snippet jumps to position 2, causing an exception.

Position 10373 “0x5050604051519050612895866105ec56”

POP :: POP :: PUSH_N 0x40 :: MLOAD :: MLOAD :: SWAP1 :: POP :: PUSH_N 0x2895 :: DUP7 :: PUSH_N 0x05ec :: JUMP

Position 10554 “0x5b600160a060020a0386166000908152600a602052604090205480850291909104915081111561296857”

JUMPDEST :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: DUP7 :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x0a :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: SWAP1 :: SHA3 :: SLOAD :: DUP1 :: DUP6 :: MUL :: SWAP2 :: SWAP1 :: SWAP2 :: DIV :: SWAP2 :: POP :: DUP2 :: GT :: ISZERO :: PUSH_N 0x2968 :: JUMPI

The execution might come here, following a sequence of positions 1067, 1073, 9449, 9456, 9365, 1516 and 1542. Then the snippet compares values in the storage and conditionally jumps to position 10600.

Position 10596 “0x61000256”

PUSH_N 0x0002 :: JUMP

The execution jumps to position 2, causing an exception.

Position 10600 “0x5b600160a060020a038581166000908152600a6020526040808220805485900390559186168152208054820190556001915050939250505056”

JUMPDEST :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: DUP6 :: DUP2 :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x0a :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: DUP1 :: DUP3 :: SHA3 :: DUP1 :: SLOAD :: DUP6 :: SWAP1 :: SUB :: SWAP1 :: SSTORE :: SWAP2 :: DUP7 :: AND :: DUP2 :: MSTORE :: SHA3 :: DUP1 :: SLOAD :: DUP3 :: ADD :: SWAP1 :: SSTORE :: PUSH_N 0x01 :: SWAP2 :: POP :: POP :: SWAP4 :: SWAP3 :: POP :: POP :: POP :: JUMP

This changes the storage and jumps to position 9467.

Position 10699 “0x5b600160a060020a0383166000908152600b6020526040812054815481101561000257”

JUMPDEST :: PUSH_N 0x01 :: PUSH_N 0xa0 :: PUSH_N 0x02 :: EXP :: SUB :: DUP4 :: AND :: PUSH_N 0x00 :: SWAP1 :: DUP2 :: MSTORE :: PUSH_N 0x0b :: PUSH_N 0x20 :: MSTORE :: PUSH_N 0x40 :: DUP2 :: SHA3 :: SLOAD :: DUP2 :: SLOAD :: DUP2 :: LT :: ISZERO :: PUSH_N 0x0002 :: JUMPI

The execution might jump here from position 1099 (“isblocked()”).

This snippet checks the length of the “proposals” array and if the check fails the execution jumps to position 2, causing an exception.

Position 10734 “0x818052600e02600080516020612a368339815191520190506003810154909150421115610b9457”

DUP2 :: DUP1 :: MSTORE :: PUSH_N 0x0e :: MUL :: PUSH_N 0x00 :: DUP1 :: MLOAD :: PUSH_N 0x20 :: PUSH_N 0x2a36 :: DUP4 :: CODECOPY :: DUP2 :: MLOAD :: SWAP2 :: MSTORE :: ADD :: SWAP1 :: POP :: PUSH_N 0x03 :: DUP2 :: ADD :: SLOAD :: SWAP1 :: SWAP2 :: POP :: TIMESTAMP :: GT :: ISZERO :: PUSH_N 0x0b94 :: JUMPI

This snippet compares the current time with some storage content. If the current time is late enough, the execution falls through. Otherwise the execution jumps to position 2964.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » The DAO Bytecode Tour for the Skeptic (Part 2)

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址