00 Abstract
When you trade a tokenized equity, the interface tells you what you received. That figure is a report, a claim produced by the same system that executed the trade.
Assay discards the report and reconstructs the fill independently from finalized chain state. What left the wallet, what entered it, what the venue kept, and what the network charged. The result is deterministic, so anyone re-running it against the same transaction lands on the same number. That makes it checkable rather than trusted.
The name is literal. An assay determines what a metal is actually made of, as opposed to what a seller claims. Assay offices have refused to take sellers at their word since the 1300s. You bring the silver, they test it themselves, and only then is it struck. A fill is an alloy of the same kind. You were promised a thousand parts, and the chain says how many arrived.
01 The problem
Robinhood Chain (chain ID 4663) is an Arbitrum Orbit L2 that went to public mainnet on 1 July 2026, carrying tokenized equities, ETFs, and other real-world assets. Standard Ethereum tooling deploys without modification, and a permissionless venue ecosystem of AMMs, aggregators and routers arrived with it.
On any such venue, the number you are shown after a trade is computed and displayed by the venue's own interface. Between the price you were quoted and the tokens that actually settled, several things happen that the interface has no obligation to surface pre-trade:
- Venue fees, sometimes disclosed, sometimes folded into the rate.
- Pool slippage, rarely shown before you sign.
- Routing through intermediaries, each taking a cut.
- Gas, paid separately in ETH and absent from the token summary entirely.
The interface's event logs are no better as a source of truth, because they are written by the same contract whose behaviour you are trying to verify. To know what actually happened, you cannot ask the venue. You have to rebuild it from the chain.
02 Method
Assay reconstructs a fill in four steps. None involve interpretation.
- Confirm settlement. Fetch the transaction and its receipt. A transaction that has not finalized is a rumour, not a fill. A reverted transaction has no settlement to reconstruct.
- Read the transfers. Collect every ERC-20
Transferevent emitted by the token contracts themselves, topic0xddf252ad…, ignoring whatever the venue said about its own work. - Net against the wallet. Sum the transfers where the wallet is sender or recipient. Incoming minus outgoing, per token. That net delta is what moved, and no interface gets a vote in it.
- Compute fineness. If the amount you were promised is supplied, divide what arrived by what was owed, in parts per thousand. Assay offices round down, because you never receive credit for purity you do not have, and Assay does the same.
Gas is accounted separately: gasUsed × effectiveGasPrice, read directly from the receipt, reported in ETH and labelled as a network cost rather than something the venue kept.
All arithmetic is exact, in arbitrary-precision integers. Display values are truncated. The computed figures never are.
03 Fineness
Millesimal fineness is the real standard for precious metal. Sterling silver is 925 fine, or 925 parts silver per thousand. Assay applies the same scale to a fill.
| Fineness | Grade | Meaning |
|---|---|---|
| 999+ | Fine | What you were promised is what arrived. |
| 925+ | Sterling | A normal fill with normal costs. |
| 750+ | Below sterling | Something took a real bite. |
| under 750 | Below standard | An assay office would break the piece rather than mark it. Assay refuses the stamp. |
A struck assay produces a hallmark, a row of punch marks in the manner of a real silver hallmark, carrying the assayer, the fineness, the office, and the block it settled in. The mark is not a badge of approval. It is a record of what the test found, refusal included.
04 Architecture
The bench is a single static client. There is no backend, no account system, and no server that sees the transactions you assay on it. The Assay Agent, the optional watcher described in section 04a, is the exception, and it is the only one.
- Reconstruction runs entirely in the browser against a JSON-RPC endpoint.
- Permalinks (
/tx/0x…) do not store a result. They re-run the assay from the chain when opened, so a shared link verifies itself in front of its reader. - The ledger, your history of struck assays, lives in your browser's local storage and nowhere else.
- Wallet assay (
/wallet/0x…) reconstructs recent fills for an address by reading its transfer logs over a block window viaeth_getLogs.
For production, the client points at a proxied provider endpoint on the project's own domain. This carries higher rate limits than the public RPC and, by being reached through the project's domain rather than the chain's public hostname, is unaffected by the DNS interception some networks apply to the latter.
04a The Assay Agent, and what it costs
Everything above describes the bench, and remains true of it. The Assay Agent is a separate, opt-in watcher that assays transactions as they settle and explains them on Telegram. It cannot work the way the bench does, and the difference is worth stating rather than burying.
- It needs a server. To send you a message about a wallet, something has to be running when the transaction settles. That is a persistent process, not a static file.
- It holds a join the bench refuses to make. A Telegram chat id against a set of on-chain addresses. That pair is the deanonymising link the bench never creates, and it is the real cost of the feature.
- It keeps a history. What each account struck, so a dashboard can differ between accounts. That is a record of your activity which did not previously exist anywhere.
- It publishes a little. A front-page feed carries a display name taken from Telegram, the ticker, what arrived against what was promised, and the grade, for accounts that have not opted out. It carries no address and no transaction hash. Those columns are not selected, rather than selected and filtered.
Nobody is running a hosted agent. The code is in the repository and the intended deployment is your own. Where a claim in this paper says no server, read it as a claim about the bench. Where it matters, this section is the correction.
The arithmetic is not duplicated. The agent reconstructs with a literal port of the browser's method, using the same Transfer topic, the same netting, the same BigInt fineness with the same truncation, and the same grade thresholds, pinned against the client's own outputs by test. A language model writes the sentences of each notice and is given the figures already computed. It is instructed, in the system prompt and again in the output schema, never to compute, re-derive, round or convert any of them. Every notice carries a permalink, which re-runs the assay from the chain in front of whoever opens it.
05 What Assay verifies, and what it does not
Honesty about the boundary is part of the method.
What it catches
A venue claiming one output while the token moved another. Because the venue contract and the token contract are different contracts, the venue cannot forge the token's own transfer record. This is the common and important case.
What it does not catch
Step ii trusts each token contract to report its own transfers, which is a weaker guarantee than diffing raw account balances at block N−1 and N. A malicious token that misreports its transfers would defeat it. True balance-diffing requires an archive node, which the public RPC does not serve. It is on the roadmap, not in the current build.
The floor is not the quote
Assay reads the floor you signed (amountOutMin) from classic Uniswap-style routers, from Uniswap V3's single-hop call, and from an aggregator that publishes no ABI at all (0xb300…, selector 0x810c705b). The floor is a real, cryptographically committed promise, but it is weaker than the quote the interface displayed, and the two must not be confused. The floor therefore never feeds fineness. Fineness still requires the promised figure, supplied by you until a venue's own ABI makes the quote readable.
The aggregator's swap facet is unverified and its ABI is published nowhere. The selector appears in no public signature database, and it is cryptographically not any known LI.FI GenericSwap signature. Its calldata layout was therefore established by observation, and tools/selectors.mjs --scan re-establishes it on demand rather than asking you to take the figure on trust. Across a 5,790-block window carrying 14,971 recognised fills from 770 distinct wallets, word 4 named the token that actually arrived in 136 of 136 aggregator swaps, and word 5 never exceeded the amount that arrived in 136 of 136. The same run put Uniswap V3's exactInputSingle at 4,833 of 4,833 on both checks. Confirming the selector at all needs one more step, because the aggregator is an EIP-2535 diamond whose own bytecode is 180 bytes of dispatcher. The standard's facetAddress(bytes4) resolves it to the facet that implements it, and the selector is found there.
Because that layout is inferred rather than published, Assay re-checks it at runtime against what the reconstruction independently found. If the token encoded in the calldata is not the token that actually arrived, or the floor exceeds it, the number is withheld and said to be withheld. A router Assay does not recognise is named, not guessed at.
06 Roadmap
Stated as future work, not as done.
- Quote decoders. Read the figure the interface actually quoted, not merely the floor beneath it, so fineness becomes automatic. This needs each venue's own ABI. The floor is what can be read without one.
- State diffing. Reconstruct from balance deltas at block N−1 vs N, via an archive node, closing the malicious-token gap.
- Drift. Track whether a stock token's on-chain price tracks the reference asset it represents, and by how much, over time.
- Wallet history indexer. A stateful service so the wallet view reflects full history rather than a fixed recent window.
07 On a token
The token launched on pons, a launchpad on this same chain, so a fill in it can be assayed with this very tool. Two figures follow and both were read off the contract rather than supplied by anyone: the ticker is ASSAY, from symbol(), and the total supply is 1,000,000,000, from totalSupply() at 18 decimals. Anyone can re-read both at that address and get the same answer, which is the only reason they appear here. This section still contains no distribution table and no staking schedule. Those are not withheld for suspense. They do not exist, and inventing them is precisely how a project becomes uncheckable.
The contract is 0xd0aCca90Cd14CE1C9554C968aF3c11e46C1FE61b, on pons.
If a token is introduced, this whitepaper commits to two constraints:
- Utility is tied only to features that have shipped. A token cannot grant access to reconstruction quality, decoders, or history that the roadmap has not yet delivered. Selling access to unbuilt functionality is the failure mode Assay exists to expose in others.
- No fabricated traction. Any figure this project publishes, whether holders, volume or usage, must be one a reader can reconstruct from the chain, by the same method the product itself uses. A claim the product's own tooling would contradict does not get made.
The tokenomics, if and when they exist, will be published as real, consistent, and on-chain-verifiable numbers, or not at all.
08 Status
| Component | State |
|---|---|
| Reconstruction | Working |
| Gas accounting | Working |
| Fineness | Working |
| Wallet assay | Working |
| Permalink | Working |
| Local ledger | Working |
| Router readout (floor) | Working |
| Quote decoders | Not built |
| State diffing (archive) | Not built |
| Drift | Not built |
| Token | None exists |
| Assay Agent | Code ships |
| Telegram notices | Code ships |
| Accounts and dashboard | Working |
| Public feed | Code ships |
| Hosted agent | Not running |
| Multi-chain | Not built |
The working components ship in the client and can be run by anyone against the live chain. The rest are blank because they are blank.
09 Why the name
A trading interface asks for trust. An assay office refuses to give it and tests the metal instead. That refusal, show me, don't tell me, is the entire product, and the reason a fill and a bar of silver are, for Assay's purposes, the same object. Something whose true content can be measured, and therefore should be, rather than taken on the word of whoever handed it to you.
Claimed ≠ actual.