skip to content

the wrapper registry

Every address the app shows, every route we build and every price we publish starts from one file in our repository: packages/registry/registry.yaml. The api serves the same data at GET /v1/registry. It lists every chain, every issuer and every wrapper we track, and for each one, where we read it. The code generates typed data from it and refuses to build if an entry doesn't validate. If the file is wrong, everything downstream is wrong, so we treat it as data with sources rather than configuration.

our verification rule#

An address goes in only if we read it from the issuer's own published list: an issuer API, a token list or a docs page that names the contract. That page goes in source, the date we checked goes in verifiedAt, and if reading the source takes a step (which page, which field), that goes in sourceNote.

If we can't find an issuer source, the address is TODO and verifiedAt is empty. The app shows that wrapper as unverified and won't route it. We don't fill a gap from a block explorer, a DEX listing or a token that happens to have the right name. A scam token with the right symbol is the most likely thing to find that way.

Where things stand today:

wrappers in the registry per chain, and how many are unverified
chainwrappersunverified
solana400
ethereum411
base11
bnb chain600
robinhood chain310
arbitrum3919
hyperevm (data only, not routed)170
all22921

All of the unverified entries are Dinari's. Dinari doesn't publish a token list we could find, so we've left them unverified rather than guess.

what each field means#

Each wrapper entry:

fieldwhat it holds
stockthe underlying ticker, one of our 20 stocks
issuerwho issues it; points at an issuer entry
symbolthe symbol the token contract reports, exactly. we don't invent symbols
chainwhere it lives; points at a chain entry
addressthe solana mint or evm contract, or TODO
decimalsthe token's decimals, as the contract reports them
venueswhere the issuer says it trades
sourcethe issuer page the address was checked against
sourceNotehow to read that source, when it isn't obvious
verifiedAtwhen we checked; empty exactly when the address is TODO
unitshow one token relates to shares of the stock, and where to read the multiplier live

Each issuer entry holds what's the same for all its wrappers: the issuing entity, the legal form in plain words, excluded and professional-only jurisdictions, the mint window (as text, and as a schedule the app can evaluate), the redemption path, a link to its terms, and its own source and verifiedAt.

units#

The units block is the newest part and the one that matters most for prices. model says how the token relates to shares:

modelmeaning
token2022-scaled-uisolana scaled ui amount: raw tokens times a multiplier on the mint
erc8056-ui-multiplierevm uiMultiplier(): raw tokens times a multiplier on the contract
rebasingbalances already adjusted; one token is one share
ondo-svalueone token is sValue shares, from ondo's oracle
plainone token is one share, no multiplier

multiplier says where to read it (which chain, contract and function), and the indexer reads every one live, at most a minute old, before converting any price.

proposing a correction#

Open a pull request against registry.yaml. In the description, link the issuer page that shows the right value. Then:

  1. Run pnpm --filter @isomer/registry generate to rebuild the typed data.
  2. Run pnpm verify. It validates every entry, checks the generated file is current and runs the tests.

We check the source ourselves before merging. A correction without an issuer source stays open until one turns up.

The repository isn't public yet. Until it is, write to hello@isomer.finance with the wrapper, the value you think is wrong, and the issuer page that shows the right one. That's all we need.