Skip to content

Bug: indexed dynamic event parameters decoded from raw topic bytes instead of keccak hash #53

Description

@e-fu

Per the Solidity ABI spec, indexed parameters of dynamic types (string, bytes, T[], tuples, structs) are stored in log topics as keccak256(value), not as their raw ABI encoding.

This is about event topic decoding, not the encoding path (distinct from the encoding concern in #17).

ABI.Event.decode_event/4 (lib/abi/event.ex:111-118) zips indexed_types_full with topics and calls TypeDecoder.decode_raw/3 on each topic regardless of whether the type is dynamic. ABI.FunctionSelector.is_dynamic?/1 exists (function_selector.ex:459-466) but isn't consulted here.

For :string / :bytes / T[] indexed params, the decoder expects length-prefixed ABI data (type_decoder.ex:235-243) — attempting to decode a bare 32-byte keccak hash as ABI data can raise or produce invalid values.

Example:

event Named(string indexed name, uint256 value);
// emit Named("alice", 42);

The first indexed param arrives in topics as keccak256("alice"). It should surface as that opaque 32-byte hash (unrecoverable to the original string), not as a decoded value.

Suggested fix: check is_dynamic?/1 in the indexed loop; return the raw topic bytes (or another explicit opaque wrapper) for dynamic indexed params, with a doc note that the original value is not recoverable from the topic alone.

Happy to send a PR if this direction works.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions