Events – How to Correctly Parse Ethereum LOG1-2-3-4 Opcodes

eventstransaction-trace

I'm trying to do some analysis of events from the opcodes of transactions, but I'm finding it very hard to understand how can I find the index_topics and the values returned by the event. For instance:

{
  pc: 1243,
  op: 'LOG2',
  gas: 95970,
  gasCost: 1381,
  depth: 2,
  stack: [
    '0xd0e30db0',
    '0x3d2',
    '0x7a250d5630b4cf539739df2c5dacb4c659f2488d',
    '0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c',
    '0x20',
    '0x60'
  ],
  memory: [
    '0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d',
    '0000000000000000000000000000000000000000000000000000000000000003',
    '0000000000000000000000000000000000000000000000000000000000000060',
    '0000000000000000000000000000000000000000000000000de0b6b3a7640000'
  ]
}

In this log, the address 0x7a250d5630b4cf539739df2c5dacb4c659f2488d (index_topic_1) deposits 1 Eth (0xde0b6b3a7640000) (data returned by the event) into WEth. The index_topic_0 is 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. So I can see that all the data that I need (except the address of the contract firing the event) is there, I'm just not sure if it's always in this order and I can trust it.

In other events I do find the returned data that I need in both the stack and in the memory, but I don't know how to confidently parse it from the memory.

Some questions I have:

  • What are the memory objects 3 and 60 in positions 1 and 2?
  • How can I find the address that fired this event? The only way I can think of is looking for the most recent CALL, STATICCALL, DELEGATECALL or CALLCODE and look for the to parameter, but it sounds like a hassle
  • How can I interpret the rest of the things on the stack? I see that the index topics are there, but in positions that don't make any sense to me (index_topic_1 in stack index = 2 and index_topic_0 in stack index = 3, and I have no idea what are the other 4 items in the stack, not sure if they are even related to the event log)

I would appreciate any type of information that you could give me about parsing this event opcodes, thanks.

Best Answer

From the Yellow paper documentation of the LOG opcodes the format is:

  • stack[0] pointer memory
  • stack[1] size memory
  • stack[2] first topic
  • stack[3] second topic & so on

From your capture the stack is reversed

  stack: [
    '0xd0e30db0',
    '0x3d2',
    '0x7a250d5630b4cf539739df2c5dacb4c659f2488d',
    '0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c',
    '0x20',
    '0x60'
  ],
  • 0x60 points to 0000000000000000000000000000000000000000000000000de0b6b3a7640000
  • 0x20 length = 32 bytes
  • first topic 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c
  • second topic 0x7a250d5630b4cf539739df2c5dacb4c659f2488d (it will be padded to 32 bytes

If I'm not wrong memory 0x0-0x3f are scratch memory used by some solidity operations.

Memory at 0x40-0x5f is a pointer to free memory. In this case free memory starts at 0x60.

Also in newer solc versions memory address at 0x60-0x7f is zeroed on purpose, and the free memory starts at 0x80.


I think you are correct that accessing current contract you have to track those opcodes.