Three confirmed findings in the explorer/graph indexer:
- MEDIUM: handleInitializeV4/handleSwapV4 seeded AMM pools/tokens/swaps from
ANY emitting contract, so any contract could emit lookalike V4 events to
create phantom pools/tokens and inflate the explorer's public TVL/volume
aggregates. Gate both to the canonical 0x9999 PoolManager (idx.isPoolManager),
mirroring handleDEXFill. The now-always-true inner Market guard in
handleInitializeV4 is de-nested (one path).
- LOW (DoS): unguarded fixed-offset slices (token0[:8], l.Address[:8]) panic on
a short/malformed RPC log, and the poll goroutine had no recover() -> one bad
log crashed graphd. Route those symbol slices through the length-checked
shortAddr helper, and wrap each poll in pollGuarded() which recovers any panic
into an error so the loop continues.
- LOW (query-DoS): resolvers/dex parseLimit had no max cap. Clamp <1 -> 100 and
cap min(limit, 1000), matching every other resolver namespace.
Tests:
- TestHandleV4_RejectsNonPoolManager: rogue Initialize/Swap seeds nothing; the
same event from 0x9999 is honored.
- TestPoll_MalformedLogDoesNotCrash: malformed logs don't panic processLog, and
pollGuarded converts a poll panic into an error.
- TestParseLimit_Caps: default 100, floor 1->100, hard cap 1000.