Live data
Where the site's figures come from. The indexer and its snapshot, fees generated versus total received, and the on-chain events behind each figure.
The charities page and the landing's headline total are rendered from a snapshot: a JSON document served by the indexer, a read-only service that follows Pons and the relay contracts. This page says what is in the snapshot, which on-chain events each figure is summed from, why the two money figures do not reconcile, and how often everything refreshes.
Outside the trust path
The indexer is a read-only view over public events; nothing on-chain and nothing in the keeper reads it. The contracts move money exactly as described in How it works whether the indexer is running, stale, wrong, or absent. Every figure the site shows can be recomputed from the explorers. The snapshot is a source of numbers for the site, not a source of truth for the relay.
The snapshot
The snapshot is one JSON document:
{
generatedAt: ISO 8601,
ethUsd: number | null,
scannedTo: { robinhood: block, base: block },
charities: [{
configId, charityAddress, receiver,
totalReceivedWei: string,
tokens: [{
address, curve, name, symbol, logo, description, socials,
launchedAt: ISO 8601, launchBlock,
feesGeneratedWei: string, graduated: boolean, ponsUrl: string | null
}]
}]
}Every charity address the registry has deployed is present, with an empty tokens list when no token points at it. Amounts are wei as decimal strings. Tokens are ordered by fees generated, descending; the site orders charities by total received, then name. scannedTo is the last block each chain had been scanned to when the snapshot was built.
Definitions
| Term | Meaning |
|---|---|
| Launched token | An ERC-20 created through the Pons v2 Launch Factory on Robinhood Chain (0x7eD598BcEf8bd9Edd8C97A195C6d13f40801EC7e). Each has a bonding curve, a pair token, a current creator fee recipient, and creator-supplied metadata. |
| Charity token | A launched token whose pair token is native ETH (the zero address) and whose current creator fee recipient is a charity address deployed by the Robinhood registry. Only charity tokens appear in the snapshot. |
| Fees generated | Per charity token: the creator fees Pons has credited to the charity address in Pons Fee Escrow from that token's curve or, after graduation, its pool. Sourced from Pons's contracts. |
| Total received | Per charity: the sum of Flushed amounts on its receiver on Base, meaning the ETH handed to donate.gg under its config ID. Sourced from the relay contracts. |
Membership follows the present. A token whose recipient moves away from a charity address leaves the snapshot; a token whose recipient moves to one after launch enters it. Credits booked while a token pointed at a charity address are kept as history but only shown while the token is a charity token.
Sources per figure
Robinhood Chain reads are against chain ID 4663, Base reads against 8453. Contract addresses are on the Contracts page unless given here.
The charity set
CharityAddressDeployed(configId, charityAddress, baseReceiver) on the Robinhood registry, scanned from the registry's deploy block. This gives the set of charity addresses and, for each, the receiver on Base its total is read from. The site joins the snapshot to its charity list for names, logos, and blurbs.
Launched tokens and membership
On the Pons factory, scanned from its deploy block 26841846:
TokenLaunched(token, curve, deployer, pairToken, launchConfigId, graduationThreshold). The event carries no recipient, so the current recipient and the pair token come from the factory'sgetLaunchedToken(token)view, read once per ETH-paired token launched at or after the registry's deploy block. Older tokens are kept from the log alone and read only if a recipient change ever points them at a charity address; no charity address existed before the registry, so nothing is missed.CreatorFeeRecipientUpdated(token, previousRecipient, newRecipient), emitted for the self-servicetransferCreatorFeeRecipientand for the Pons owner's timelocked override alike. Each one replaces the token's current recipient, so membership is always the present state.LaunchSwept(token, quoteOut, tokenOut)(andLaunchForceSwept(token)) when the curve is drained, andPoolGraduated(token, positionId, tokenAmount, pairTokenAmount)when the Uniswap v4 pool is seeded. The "graduated, still earning" badge is set fromLaunchSweptonward;getLaunchedToken'sphasecovers tokens read after the fact.
Token metadata
Name, symbol, logo, description, and socials are decoded from the launch transaction's calldata: launchToken(TokenParams, launchConfigId, pairToken), its overload with snipeTaxExemptions, launchTokenFor through the factory's launch forwarder, and the forwarder's launchAndBuy. TokenParams is (name, symbol, logo, description, socials(twitter, telegram, discord, website, farcaster), creatorFeeRecipient, creatorTaxBps, buybackEnabled, expectedEconomics, salt). When the calldata is none of those shapes (a launch through an unknown contract), the same fields are read from the token contract's name(), symbol(), logo(), description(), and socials(). The site renders the creator's logo URL as given and substitutes a neutral placeholder only when it is empty or fails to load. ponsUrl is https://www.ponsfamily.com/launchpad/<token>.
Fees generated
Curve trade events are not used. CurveBuy and CurveSell report fee and tax per trade, but the creator's share of fee depends on the curve's frozen protocol share, on whether buyback-and-lock was on at trade time, and on whether the buyback executed at sweep; it cannot be derived from the event fields alone. The figure is read where the money actually arrives instead:
Credited(recipient, depositor, amount) on Pons Fee Escrow (0xd3AFEB2a57f70eF218Aa82451c51B2fb0416Ac9e), filtered to recipient in the charity set, scanned from the registry's deploy block. Each credit is attributed to a token by its depositor:
- Before graduation the depositor is the token's bonding curve, which maps to the token directly. Pons credits the curve's creator share (the fee remainder after the protocol share and any buyback slice, plus the whole creator tax) when it sweeps the curve.
- After graduation the depositor is the Pons Meme Hook (
0xE5e702641Ea86F4ae6cC3cDaeD2B886f976Be044), which pays every pool's creator share into the same escrow. The hook emitsPoolFeesSwept(poolId, protocolAmount, buybackAmount, creatorAmount, tokensLocked)after the credit in the same transaction; the first such log after the credit names the pool, and the pool ID is matched to the token by computingkeccak256(abi.encode(PoolKey))from the pool fee and tick spacing ingetLaunchedToken. Post-graduation fees therefore keep accruing to the token; the badge only marks that curve trading has ended.
This is exact (it is the amount Pons booked to the charity address), ETH-only by construction (Credited is the native-ETH ledger; the ERC-20 ledger CreditedToken is not read, matching what the relay moves), and includes every creator-fee source, the creator tax included. A credit from a depositor that is neither a known curve nor the hook is kept but shown under no token. Because the figure counts credits rather than trades, it lags trading by one Pons sweep: minutes on a busy curve, not days.
Total received
Flushed(configId, amount) on each charity's receiver on Base, scanned from the Base registry's deploy block, with the same emitter guard the site's own reader applies: a log counts only if it was emitted by the receiver recorded for that config ID in CharityAddressDeployed. A Flushed event with the right config ID from any other contract is ignored, so a spoofed event cannot inflate a total. The FAQ on lagging totals covers what this figure does and does not include.
ETH/USD
The USD figure beside every amount is an estimate from one spot price: Coinbase's ETH-USD spot, with CoinGecko as fallback, refreshed at most once every 60 seconds. If both fail, the last value is kept and the snapshot still builds. ethUsd is null only if no price was ever fetched, in which case the site shows ETH alone.
Why generated and received do not reconcile
The two figures are labelled distinctly wherever they appear because they measure different points on the money path:
- Different sources and chains. Generated is Pons's escrow ledger on Robinhood Chain; received is the relay receivers'
Flushedevents on Base. One is per token, the other per charity. - Sweep lag. A trade becomes a credit only when Pons sweeps the curve or pool.
- The minimum bridge amount. Credits sit in Pons Fee Escrow until a charity address can claim at least 0.01 ETH, pooled across every token pointed at it. Generated grows per sweep; received grows per bridge.
- Keeper and bridge timing.
claimAndBridgeruns on the keeper's 300-second tick, Across fills in about a block, andflushfollows on a later tick. In between, the ETH is in flight and in neither figure. - Bridge fees. Received is net of the Across fee (at most the live fee cap, 0.001 ETH at launch, per bridge); generated is gross.
- Money that never passed through the escrow. ETH sent straight to a charity address, as in the example settlement, or an Across refund, is bridged and flushed but never credited, so it appears in received and not in generated.
- Membership changes. A token that moved away from a charity address takes its generated figure out of the snapshot; what it already funded stays in received.
- The 90/10 split. Received is what was handed to donate.gg in ETH. donate.gg's epoch processing then converts to USDC and pays the charity 90%, keeping 10%, on the payout side. Neither figure on the site is the USDC the charity ends up with. See Why does the charity get 90%?.
Over a long enough window, and setting aside fees, refunds, and direct transfers, the sum of generated across a charity's tokens leads received by whatever is currently below the minimum or in flight.
Refresh cadence
The indexer scans both chains every 15 seconds and the site re-reads the snapshot at most every 60 seconds, so a change on-chain reaches the page within about a minute and a half; the charities page prints the snapshot's generatedAt at the bottom.
Stale behaviour
If the snapshot cannot be fetched, the site keeps showing the last one it received rather than a blank page, the landing falls back to reading Flushed events on Base directly with the same emitter guard, and the money keeps moving regardless.