Skip to main content
Many protocols deploy one contract per market: a DEX factory creates a pool per token pair, a lending protocol a vault per asset. To index their events you need the list of child contracts, and the list keeps growing. The pattern:
  1. Read the factory’s creation events to learn the child addresses.
  2. Put the children in a set.
  3. Read the children’s events with that set.
  4. As new children appear, create a bigger set with basedOn pointing at the previous one.

Example: Uniswap V3 pools

The factory emits PoolCreated(address indexed token0, address indexed token1, uint24 indexed fee, int24 tickSpacing, address pool). The pool’s address is the last 32-byte word of data. With the Python client:

Backfill

Walk the chain in chunks. In each chunk, first learn the pools created in it, then read swaps of every pool known so far:
Reading the pools created in a chunk before that chunk’s swaps matters: a pool can be created and swapped in within the same chunk.

Why sets and basedOn

  • The pool list grows to tens of thousands of addresses. As a set, it’s uploaded once per growth step instead of on every request.
  • With basedOn, the server works out where the new set’s addresses appear incrementally instead of from scratch, so growing a large set stays fast.
  • A set’s id is a hash of its values. Re-creating the same set after a restart returns the same id, so restarts need no bookkeeping.

Restarting

Persist pools (or rebuild it by re-reading PoolCreated from the start; it’s a small query) and the block you reached. Then create the set again (same values, same id) and continue.
If you only need recent history, filtering on the event alone can be simpler: topic0 = Swap without an address matches the swaps of every Uniswap V3 pool, plus any other contract that emits an identical event. Keep address in the output and drop unknown ones client-side.