1

I am trying to get the Event data from LOG3 but the data sometimes on stack5 and sometimes on stack6, can anyone help?

for example, transfer amount = 1 of both two transfer functions, take a look at LOG3 opcode stacks.

event Transfer(address indexed from, address indexed to, uint256 value);


function transfer1(address to, uint tokens) public returns (bool success) {
    emit Transfer(msg.sender, to, tokens);
    return true;
}

function transfer2() public returns (bool success){
    uint256 amount = 1;
    emit Transfer(msg.sender, msg.sender, amount);
    return true;
}

Transfer Amount data located at position 5 at LOG3 Struct Log of transfer1:

[ "0x0000000000000000000000000000000000000000000000000000000000000080", "0x0000000000000000000000000000000000000000000000000000000000000020", "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4", "0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x000000000000000000000000000000000000000000000000000000000000004e", "0x000000000000000000000000000000000000000000000000000000002e687de1" ]

Transfer Amount data located at position 6 at LOG3 Struct Log of transfer2:

[ "0x0000000000000000000000000000000000000000000000000000000000000080", "0x0000000000000000000000000000000000000000000000000000000000000020", "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4", "0x000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c", "0x000000000000000000000000000000000000000000000000000000000000006a", "0x00000000000000000000000000000000000000000000000000000000a9059cbb" ]

How can I know which position to take? Thanks.

4
  • Can you show some code and explain a bit more on the context of your question ?
    – hroussille
    Commented Apr 25, 2022 at 7:48
  • I have added more details, thanks!
    – T.Z.
    Commented Apr 25, 2022 at 12:09
  • Thanks, can you also add the event definition ? (if there is no indexed parameter, it will compile to a log1, the only topic being the event itself)
    – hroussille
    Commented Apr 25, 2022 at 12:55
  • I have added it, it's the standard erc20 Transfer event, thus transferfrom and transferto are indexed (stack3-4), but I cannot locate the transfer value(event data), but on tenderly/remix debugger they could identify it, so I must missed something, thanks!
    – T.Z.
    Commented Apr 25, 2022 at 13:18

1 Answer 1

0

Okay so I think I understand your issue now, it's not a problem with solidity, it seems to me like you are misinterpreting the stack at those two points of execution.

The LOG3 opcode (and LOGX in general) take the following inputs from the stack :

  • 0x00 - OFFSET : in memory of the data)
  • 0x20 - LENGTH : in memory of the data)
  • 0x40 - TOPIC 0 : keccak256("Transfer(address,address,uint256)")
  • 0x60 - TOPIC 1 : address indexed from
  • 0x80 - TOPIC 2 : address indexed to

Therefore, only the first 5 slots in the stack are relevant for you at this point, anything else is for the rest of the execution but doesn't concern the LOGX opcode.

You will find the rest of the data (i.e., value) at MEMORY[OFFSET:OFFSET + LENGTH] and indeed in both cases the value 1 is encoded there on 32 bytes.

Indexed parameters are placed in the topic section, which non indexed parameters are placed in the data section, so from and to are included in the topic section (stack 3 & 4) while value is the only one written to the data section, that's why the memory length is only 0x20 (only one ABI encoded parameter).

I hope that answers your question.

3
  • So in order to find the value it should be: MEMORY[0x80+0x20] right? But in Remix I see the value is at 0x90, could you tell me how to find the right value? I am not familiar with EVM at all... Thanks a lot for your answer!
    – T.Z.
    Commented Apr 25, 2022 at 14:21
  • The indexed parameters will be encoded as "topics" as long as they fit the 32 bytes slot. To get the value in your specific case you need to read LENGTH bytes (32 / 0x20) starting a OFFSET (0x80). You see it at 0x90 because it's only a 1, so the only bit that is set is the lower bit of the lower 16 bytes. But the whole value is still 32 bytes long, starting at 0x80. What you need to read is MEMORY[0x80, 0x80+0x20]. Tell me if anything is left unclear.
    – hroussille
    Commented Apr 25, 2022 at 14:28
  • Ah got it! You just saved my day, much appreciate your help!
    – T.Z.
    Commented Apr 25, 2022 at 14:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.