NASDANK Docs
Open app
Build/Onchain events

Onchain events

The logs a launch, a trade and a fee collection emit — and the one structural fact about them that makes indexing NASDANK different from indexing a single-contract protocol.

TokenLaunched has several shapes

Every launcher emits an event named TokenLaunched, but the launchers are separate deployments with different feature sets, so the signatures differ between generations. There is no single ABI that decodes them all.

Four of the deployed signatures, to show the spread
 0 
TokenLaunched(address,address,bytes32,uint256,address,address,string,string,string,
              uint256,uint160,int24,int24,uint16,uint24,uint16,uint256,uint256)

 1 
TokenLaunched(address,address,address,uint256,address,string,string,string,
              uint24,uint8,bool,uint256,uint160,int24,int24,uint256,uint256,uint256)

 2 
TokenLaunched(address,address,address,address,address,string,string,string,
              uint16,uint256,uint256,uint256,uint256,uint256,uint32,uint64,uint256,uint256)

 3 
TokenLaunched(address,address,bytes32,address,uint256,address,address,string,string,string,
              uint256,uint160,int24,int24,uint16,uint24,uint16,uint256,uint256)
The first three indexed parameters are stable

Across every generation, the first three indexed parameters carry the same three things. That is the invariant to build on: you can identify the token, the creator and the pool or pool id from the topics alone, without knowing which launcher emitted the log.

Decoding strategy

  1. Group logs by emitting addressThe address field of the log tells you which launcher, and therefore which ABI to apply. This is more reliable than trying signatures until one parses.
  2. Read the topics for identityToken, creator and pool come out of the indexed parameters regardless of generation.
  3. Apply the launcher's own ABI for the restFee, tick range, supply, treasury and the feature-specific fields live in the data and need the right ABI.
A missing field silently corrupts every later field

ABI decoding is positional. An ABI that omits one field — a projectTreasury, say — does not fail; it shifts everything after it and produces plausible garbage. If a decoded record looks almost right, suspect the ABI before suspecting the chain.

V2 signatures here are historical

NASDANK no longer launches on V2. The V2 shapes below are kept because a handful of coins were launched on it before the tier was retired, and an indexer covering full history still has to decode them.

Trading

Trading emits the venue's own events, not ours. There is no NASDANK trade event, because trading does not go through NASDANK.

VenueEventEmitted by
V2Swap(address,uint256,uint256,uint256,uint256,address)The pair
V3Swap(address,address,int256,int256,uint160,uint128,int24)The pool
V4Swap(bytes32,address,int128,int128,uint160,uint128,int24,uint24)The PoolManager, keyed by pool id
V4 swaps are all emitted by one contract

On V4 there is no per-pool contract. Every swap on every V4 pool on the chain comes out of the singleton PoolManager, distinguished by the id topic. Indexing "your" pool means filtering on that pool id — you cannot subscribe to a pool address.

Fee collection

FeesCollected is emitted by the locker or hook when fees are pulled and split. It carries both legs and both recipients, which is what makes conservation checkable: for a given collection, the creator amount plus the treasury amount must equal the collected amount, on every leg.

Reward-paying launches additionally distinguish two payout events, and the distinction is user-visible:

  • DividendClaimed — the holder called claim themselves.
  • DividendPushed — a keeper paid the holder without them doing anything.

An interface that flattens these into one says "you claimed this" about money that simply arrived, which is a different statement. Keep them apart.

Vesting

VestingCreated is emitted per schedule.

The beneficiary is in the data, not in a topic

You cannot filter VestingCreated by recipient at the RPC. The logs must be pulled from the contract's deploy block and filtered client-side. Getting the fromBlock right is the whole job — start too late and a recipient's schedule is invisible, which reads to them as "I have nothing to claim".

Log-fetching limits on Robinhood Chain

eth_getLogs hard-refuses anything matching over 10,000 logs

And it times out on dense ranges well before that. Crucially, density is not predictable from range width — a busy thousand-block window can exceed the cap while a quiet million-block window does not. No fixed window size is safe.

The correct pattern is: attempt the range, and on failure split it in half and recurse. A catch => [] here is not a fallback — it turns "the RPC refused" into "there are no results", and a holder-set query that returns empty is indistinguishable from a coin with no holders. That exact bug once suppressed payouts for about fourteen hours.

Split-and-recurse, the pattern that actually works
async function getLogsSafe(client, filter, from, to) {
  try {
    return await client.getLogs({ ...filter, fromBlock: from, toBlock: to });
  } catch (err) {
     0 
    if (to - from <= 1n) throw err;
    const mid = from + (to - from) / 2n;
    const [a, b] = await Promise.all([
      getLogsSafe(client, filter, from, mid),
      getLogsSafe(client, filter, mid + 1n, to),
    ]);
    return [...a, ...b];
  }
}

If you are running your own Ponder indexer

A topic filter can cost more than the firehose

Filtering a V4 pool id at the indexer level creates one RPC cache fragment per topic value, and those fragments are never merged. Measured against a real deployment, the "efficient" filtered version cost roughly thirteen times the unfiltered firehose it was meant to replace. Index broadly and filter in your handler.

Ponder's schema stamp includes resolved config

Changing an environment variable changes the build id, which changes the schema stamp, which can make a running instance refuse to reuse its existing tables. Plan for that before editing env vars on a live indexer.

Indexer API covers the served surface if you would rather not run one.

© NASDANK Not affiliated with Robinhood Markets, Inc. Risk disclosures nasdank.fun