Methodology

How pegproof produces its numbers, and what it does not claim. Everything here is verifiable against Robinhood Chain itself.

What is observed

Tokenized-stock contracts issued on Robinhood Chain (chain ID 4663). For each tracked token the collector reads contract event logs and a small number of eth_call reads directly from the chain. No figure comes from a private feed, an issuer API or any other off-chain source: every figure published is derived from on-chain state that anyone can re-read. The token page also shows the multiplier Robinhood publishes next to the on-chain one, as a comparison only (see Multiplier from a second source).

Several chains are involved and they are easy to confuse: the tokens and every figure about them live on Robinhood Chain; Base and Arbitrum One appear only as the networks on which the paid /api/v1/* routes accept their x402 payments in USDC. Nothing published here is read from either of them.

Three platform addresses anchor the issuance picture:

The two emission addresses are copies of the same contract, and the same account makes the mints to both, so the second is treated as the issuer's: both are known treasuries for every token that uses one.

Event classification

Every ingested log is classified into one kind. Four of them are issuance-relevant and are the only ones carried into the aggregated buckets:

kindmeaning
mintsupply created from the zero address
burnsupply destroyed to the zero address
issuetransfer out of a known treasury or the emission address
redeemtransfer into the redemption address

transfer — ordinary wallet-to-wallet movement — is deliberately ignored by the buckets and by the size detector. Secondary trading is not issuance, and counting it would make every active token look anomalous.

Aggregation

Events are grouped into fixed buckets of 36,000 blocks, which is about one hour at Robinhood Chain's nominal ~0.1 s block time. Buckets are keyed by block height, not wall-clock time, so the series never depends on a node's clock. Exact bucket edges are published with the data rather than being left for a reader to re-derive.

Full-history reconciliation

About once an hour (a check is skipped while the previous one is less than 55 minutes old), every token that has a balance snapshot has its entire event history re-added and compared with the total supply of the newest snapshot the ledger has reached: the newest snapshot at or below the token's ledger watermark. Snapshots are usually taken ahead of the ledger, so this can be an earlier snapshot than the one behind the figures at the top of the token page. The token page names that snapshot's block, N, and states the comparison as being with the supply at block N. The sum is every mint minus every burn in the ledger up to and including block N; the ledger reaches back to the contract's deployment once the token's history is backfilled. Whole buckets below the bucket that holds block N come from the aggregated buckets, and only buckets that contain at least one mint or burn are read, which is exact because every other bucket adds zero to the sum. The mints and burns from the first block of that bucket through block N are read event by event. Amounts are summed as exact integers in raw token units, never in floating point and never by the database. Each token is then published in one of three states:

Daily series

Each token's chart is rebuilt once per UTC day from the same buckets, on the first hourly check after a balance snapshot has been taken that day, which fixes the day's first block. A day's point is the supply at the last bucket edge before that day's first block, and the block is published with the point, so every point is an exact ledger figure at a stated block, never an interpolation. A token gets no point for a day until the ledger has been ingested up to that block, and none before its first mint or burn.

The first block of each day before the collector started recording day boundaries was read once from the chain. After that, each day uses the lowest snapshot block seen on that day's first hourly check, so it can fall slightly after midnight.

Shares use the multiplier observed that day. A day without an observation keeps the most recent earlier one, and a multiplier that is not a plain non-negative integer counts as not observed. Before a token's first observed multiplier, the earliest observed multiplier is used, and the chart says from which day it was observed. With no multiplier ever observed, the line shows token supply. USD points exist only for days with an unpaused on-chain price.

The full daily list is built first. The home page's sparklines are the last 30 points of it, taken before any thinning. A series longer than 400 points then keeps every k-th day, counted back from the newest, so the newest is always kept and pages stay small. On a token's charts, unresolved ledger gaps are drawn as hatched bands and never bridged; the home page's sparklines are not gap-aware.

Status, in three independent axes

A single "healthy / unhealthy" badge would hide exactly the cases that matter, so published status is always three separate facts:

  1. state_as_of_block / state_as_of_time — when the balance figures were last measured. null means not measured yet, and the pages say so rather than rendering a blank cell.
  2. ledger_coverage_24h / ledger_coverage_7d — complete, partial or gap, describing how fully the event ledger covers that window. The ledger is compared with the chain head the collector last observed, not with its own ingestion cursor, so an ingester that has stalled cannot report itself complete. complete is allowed 36,000 blocks (about one hour) of lag behind that head and degrades to partial beyond it. A tick that could not read the chain head reports partial as well, since a ledger that could not be compared with the chain is never called complete. gap means an unresolved interruption overlaps the window and takes precedence over both.
  3. flags — open flags, if any (see below).

These can disagree, and when they do the disagreement is the information: fresh balances with a gap ledger means the snapshot is current but the history behind it is not.

How the collector itself has run is published at /status: its ticks per UTC day, how many were ok and how many could not finish, and the integrity incidents opened each day, from the first day with a recorded tick.

Flags

flagmeaningcloses
r0a_divergence, r0b_divergencethe R0 check found the event ledger and the re-read chain state disagree for this tokenonly with a written reason (see Closing incidents)
rebaselinea gap in the ledger was declared, or the token's emission or redemption addresses changed in the registry, so balances before and after it are not comparedwhen the token's next balance snapshot starts a fresh baseline
collector_errorthe latest read of this token failed on pegproof's side; nothing is known to be wrong with the tokenby itself, at the next successful read

A dashboard reading older than two hours is banner-marked stale. That threshold is on the age of the measurement, never on whether the collector believes itself healthy.

Detectors

Six rules run over newly-ingested events. They report what was observed, not who did it: an "unexplained" event is one this project cannot yet account for.

rulewhat it looks for
R0 (r0a/r0b)divergence between the event ledger and independently re-read chain state — an integrity check on the collector itself, not on the issuer
R1an issuance, redemption, mint or burn whose size is far outside that token's own history
R2a mint or burn outside the known emission/redemption address sets
R3an outflow from a known treasury to an address this token has never transacted with
R4a decrease in the multiplier between consecutive same-era snapshots
R5an address receiving 3 or more mints inside a rolling window — a treasury-candidate signal

R1 calibration

R1 is the rule most able to produce noise, so its thresholds are stated rather than tuned privately:

R3 is capped at 50 qualifying events per tick, so one busy token cannot exhaust the database budget and silently starve the others.

Market calendar

Sessions run 20:00 ET the previous day to 20:00 ET, Monday to Friday. NYSE holidays erase the whole session, including a holiday's Sunday-evening start. The calendar is a pure function of the tick timestamp — it never reads a wall clock — so the same inputs always classify the same way.

Market state is published alongside the data because it changes what a quiet period means: no issuance at 03:00 on a Sunday is expected, the same silence mid-session is not.

Prices

USD figures are estimates and are always labelled as such. The price is read on-chain from the token's Chainlink Data Feed on Robinhood Chain, at the same block as the supply it multiplies. The feed for each token is verified on-chain when the feed list is built (description() must name that ticker), and only verified feeds are used. Nothing is read from an off-chain price source.

Supply changes over 7 and 30 days are computed on raw total_supply, so a multiplier adjustment moves no percentage — only minting and burning do. A token counts as grown or shrunk when its 7-day change exceeds 0.5 percent either way, and as flat otherwise. A token with less than 7 days of history, or with no supply at either end, is not counted at all rather than counted as 0%.

Weekly reports

A market week closes at 20:00 ET on the last trading session of the week. That is normally Friday. When Friday is an NYSE holiday (Good Friday, for example), the week closes at the previous trading day's close, and the report names that day. About an hour after the close, once the ledger is complete for every token, the week's report is frozen. A report is frozen only from a site snapshot built after the close, and it records the block and time that snapshot was read at. It contains the headline, totals, movers and every token's figures. If the ledger is still incomplete 40 hours after the close (around midday Sunday ET after a normal Friday close), the report is frozen anyway and says that its ledger is incomplete. A frozen report is never edited. A correction would be published as a new report naming the one it corrects, and the original stays readable.

Closing incidents

An R0 divergence is never closed automatically: it is closed only with a written reason, recorded with the closure. A rebaseline closes when the token's next balance snapshot starts a fresh baseline, since from then on nothing is compared across it. A collector_error is not an integrity incident: it is pegproof's own read failing, and it closes at the next successful read. The original detection record is never deleted or edited.

Registry and look-alikes

The tracked tokens come from the pegproof registry (github.com/xplowdie/rwa-registry). Its starting list is Robinhood's platform listing on rwa.xyz, and every address on it is checked on Robinhood Chain with eth_getCode. A ticker comes from a curated mapping or from the contract table on docs.robinhood.com, otherwise from the contract's own symbol(); a display label is never taken as a ticker.

A look-alike is another contract on Robinhood Chain that presents itself as a registry token: its symbol() is exactly the registry ticker, and its name() is the ticker or contains the company's name or "Robinhood". A contract whose name carries another tokenized-stock issuer is never called a look-alike, since it may be that issuer's own product. Candidates are found through DEX listings, read on-chain and reviewed by a person before they are added. A contract that only resembles a registry token (another symbol, or a name alone) is catalogued as unclassified, not as a look-alike. A token page lists the look-alikes the registry links to it. A contract deployed after the last registry build appears only once the registry is rebuilt, so a page without look-alikes does not mean none exists.

Other issuers' lists

Some issuers publish their own contract lists for Robinhood Chain. pegproof keeps a dated copy of such a list (today Ondo Global Markets', from docs.ondo.finance/addresses, copied 2026-10-28) and checks each listed address on-chain: it has contract code, and name() and symbol() return what the list says. These tokens are not in the registry and pegproof does not check their supply; the address lookup and their pages say which issuer lists them. The one exception to the rule above: a contract whose name() and symbol() are exactly those of an address on such a list, but which is not on the list itself, is a look-alike of that issuer's token. The copy is dated, so a token the issuer added later is unknown here until the copy is renewed.

Multiplier from a second source

Once a UTC day the collector reads the token list Robinhood publishes (the data behind the contract table on docs.robinhood.com) and stores, for every registry token, the current multiplier and any pending multiplier it lists. The token page compares that current value with the latest on-chain uiMultiplier(). When the two differ by at most one part in a million of the on-chain value, the page says they match. Otherwise it shows both values and the day of the check, and does not count it as a finding: the list and the contract can be out of step for a while around a corporate action, and every figure on the page uses the on-chain value. A pending multiplier is shown as information only. A token the list does not carry, or one without an observed on-chain multiplier, gets no comparison.

What this project does not claim

Verifying independently

Every token page shows the exact eth_calls behind its figures, so any reader can re-run them against a public Robinhood Chain RPC and compare.