How assets are verified
Depth is checked at a size, not as a number, and every check reports rather than edits.
Vetting happens off chain, by address, and the address is curated. Two tools do it, and neither of them edits the registry.
cd relayer
npm run verify-mints # re-check the pinned hard-grade mints
npm run sync-badges # derive provider counts from actual bindings
verify-mints reports rather than edits, because demoting a pairable out
of hard grade affects live markets. sync-badges needs --write to correct
anything.
Depth is checked at a size, not as a number
A mint's reported liquidity figure and what it can actually fill disagree often enough to matter. BRK.Bx reports $27k of liquidity and still absorbs $25,000 at 1.53% impact, which a $27k pool could not do.
So every hard entry records the price impact of a $25,000 buy and the date it was measured.
const DEPTH_USD = 25_000;
const PROBE_USD = 1_000;
const MAX_IMPACT_PCT = 10;
| Verdict | Meaning |
|---|---|
deep | routed $25,000 |
thin | routed $1,000 but not $25,000: it prices, it just cannot absorb a real fill |
dead | routed neither |
$25,000 is the size the question is actually about: a market quoted against an asset the vault has to be able to buy and sell at size. The pass mark is deliberately loose, because a 4% impact is a bad fill rather than a broken pairable; past 10% the order is moving the market rather than trading in it.
KOx is thin and SLVx is dead, and both are why their pairables' story is
told carefully. SLV was pinned to Ondo's SLVon instead and then demoted out of
hard grade entirely on 2026-08-25, when a live quote moved 89.64% on $25,000
against a reported liquidity figure of $44,066. The separate floor in the
relayer config, minAssetLiquidityUsd, sits at $20,000.
Repeated quotes on the same afternoon differ by a point or more on the thinner
mints, because the route changes under you. Several entries therefore record a
range rather than a figure: SPACEX-VAL is logged at between 0.12% and 0.91%
impact across four measurements on 2026-08-24.
Every claim carries the date it was true
Hard entries record assetLiquidityUsdAsOf with a value and a date, because an
undated depth claim goes stale silently. Across the 44 hard entries as of
2026-08-25: 25 dated 2026-08-24, 13 dated 2026-08-25, and 5 dated 2026-08-17,
summing to $68.4m. The forty-fourth is SOL, below.
One hard entry carries no assetLiquidityUsdAsOf at all: SOL, whose asset
mint is wSOL. It is the only exception, and the README's claim that "every hard
entry now carries an assetLiquidityUsdAsOf" is one entry too strong.
This is the KO lesson generalised. KO used to be the standing example of what
cannot be hard-quoted, on the grounds that the deepest mint trading as KOx was a
pump launch. A genuine Backed KOx exists at
XsaBXg8dU5cPM6ehmVctMkVqoiRG2ZjMo1cyBJ3AykQ carrying $21,609, so KO was
promoted on 2026-08-25. The old sentence was true when it was written and
wrong eight months later, and nothing in the registry would have noticed.
The rate limiter is a correctness feature
Jupiter's public endpoint rate-limits at roughly a request a second, and
verify-mints makes three per pinned mint. Without a pause it 429s halfway down
the registry and reports live mints as GONE.
That is the worst possible failure for a script whose entire output is "a human should look at this": it cries wolf, and the next person starts ignoring it. So there is a 400ms pace and an exponential retry on 429, 5xx, and network errors.
Two independent sources on every hard pairable
A hard pairable gets the oracle and a routed Jupiter quote off the real pool, so the spread gate has two genuinely independent opinions to compare.
Their spread band is deliberately loose. xStocks trade around the clock while the equity they track does not, so overnight and at weekends the token price and the last equity print genuinely diverge, and that divergence is real rather than a fault. The tight check on those is the liquidity floor, not the spread.
Preflight, which is where most entries stop
scripts/launch.ts --all --dry walks every registry entry and refuses in full
sentences, because the output is read by a person deciding what to fix. In
order:
A mismatch means the seed and the account have drifted, and nothing downstream can be trusted.
The breaker has not tripped, or governance has cleared it.
Not a policy choice: the opening reserve divides by this.
This is the one check the programs cannot make, because valuation lives
only in the registry file and never on chain.
Checks 8 and 9 are the same lesson twice, and the second one is the interesting half. An existence check is not enough: on devnet, eight xStock addresses hold plain System-Program-owned accounts, because somebody funded the vanity address and did nothing more.
Existence waves all eight through, and the launch then dies inside the token program after the launched mint has been created and paid for. The owner is the answer, since a mint is owned by the token program that issued it and nothing else can be.
Both checks happen in preflight rather than being left to the chain because
create_market derives the reward vault as an ATA over the asset mint, so a
missing or fake asset kills the transaction at a point where a refusal is no
longer free.
On devnet this refuses almost every hard entry, since the pinned mints are mainnet addresses. The exceptions are the few that exist on both clusters, wSOL and Circle's EURC, which is exactly why the two live devnet pools are quoted in those two and nothing else. The script's own comment calls the refusals the honest answer rather than a fault.
The badge is a record, not a promise
provider_count is an assertion in a JSON file and drifts from the code the
moment anyone edits either. last_source_count is written by the program from
what the relayer passed alongside the price.
When the second sits below the first, sources are down and the UI can say so.
npm run sync-badges derives the configured count from the actual bindings and
reports the drift.
peard