Tutorial About Api

Understanding the source code

Panoramix - the decompiler behind Eveem.org - is still a work in progress.
It has issues with loops and dynamic-length objects. Also, a bit, around displaying storage properly. Some of the code it produces may be outright wrong, and no amount of head-scratching will help you get it.

Mask(size, offset, value)
Means "take 'size' number of bits, 'offset' from the right".

Mask(8, 16, 0x123456) == 0x4.
Mask(255, 0, _param) == _param with a last bit set to 0
Mask(251, 5, _param) == _param modulo 32

CallData (cd[xxx])
Mask(32,0,cd[0]) == 4 bytes function identifier
cd[32+4], cd[64+4], cd[92+4]... == first, second and third... parameter

Dynamic length paremeters (strings, byte arrays) have a pointer as their parameter, so:
cd[cd[36]+4], or cd[_param1+4] mean "data at the place pointed by cd[36]/_param1"

cd[_param+4] == _param.length
cd[_param+4+32+32*x] == _param[x]

cd[cd[_param+4+32+32*x]+4+32+32*y] == _param[x][y]

Obviously, a good decompiler would parse this correctly.

storX == obvious
storX[pos] == obvious

storX[pos].off == Mask(*, off, storageX[pos])
(* is described in storage definitions on top of the output)

You will see this when dealing with structs usually, e,.g.:
all refer to the same storage location (stor6[_id]), just different bit position.

Sometimes the code accesses the same location, but using different masks.
stor6.0.uint256 = 0x123456
stor6.0.uint8 = 0xaa

After the two above calls: 0x1234aa == stor6.0.256

Yes, I know it's confusing, and not always perfect.

Another exercise here:
stor2.0.160 = addr(caller)
stor2.160.8 = bool(call.value>0)
After these two operations in stor2 there will be:
- the address of the caller (first 160 bits)
- either 0 or 1 depending on call.value (next 8 bits)
- the last 88 bits untouched

Whenever you see memory operations, it means Panoramix was uncertain as to what was going on in the code. Hopefully, the outputted function will make still some sense to you, but often it may not, and it may be completly incorrect.

Having said all that:
mem[var1 + (Mask(251, 0, stor8[addr(_owner)].0.251) << 5) + 256] = mem[var1 + 192]

means - "write to a memory" at position "var1" plus Mask(251, 0, stor8[_owner])*32 + 256 stuff from mem[var1 + 192].

Around 50% of the time spent working on Panoramix, I spent trying to make these memcalls disappear.