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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions