Skip to content

Commit a5bb28f

Browse files
committed
docs: V-02 said "none" and that was wrong - the whole xStock suite is here
Correcting a P0 conclusion I reported as fact. The claim was "there is no canonical xStock ERC-20 on HyperEVM". The truth is that all ten of the largest xStocks are deployed on this chain at Backed's canonical addresses, holding real supply - CRCLx 312,842 units, STRCx 108,351, NVDAx 104,729, MSTRx 66,795, GOOGLx 59,252, TSLAx 46,467. The three that can be priced from measured feeds come to ~$63M; the suite is well over $100M. They are Backed's own deployments and that is asserted, not assumed. Backed deploys deterministically, so the address is identical across chains, and the runtime bytecode hash is byte-identical on HyperEVM, Optimism and BNB. On every asset checked HyperEVM holds SEVERAL TIMES the supply of either - it is the largest EVM deployment of xStocks, not a fringe one. How the wrong answer happened, recorded in the row rather than overwritten: two searches, both empty, both empties read as absence of the asset. HyperSwap positions came back with no xStocks because xStocks have no pools - a token can be widely held and never pooled. HyperCore tokenInfo came back with every equity unlinked because xStocks are EVM-native and were never HyperCore tokens, so there is no HIP-1 record to link. Both searches answered correctly. The error was reading a derived index as a census. The tell was there and was explained away: SPYx WAS found, through a pool belonging to its wrapper, and was filed as an anomaly rather than the edge of a suite. One contradicting data point against two confident absences, and the data point lost. The check never run was eth_getCode on a published address - one RPC call, which would have settled it on day one. Recorded as Shape 7 in REVIEW-NOTES: an empty index read as an empty world. Same shape as Shape 1 and Shape 5 - a reader with no writer, an argument nobody checked - turned on the verification process itself. What does not change: they rebase, six of the ten have already moved off a 1.0 multiplier, and Backed's own docs say every EVM deployment does. Changing chain does not help; only Solana and TON keep raw balances constant. What sharpens: RebaseDetector is not a safety net catching one bad token. It refuses the entire intended quote-asset class and is the reason the allowlist is empty. Correct for balance-based accounting, and it should read as uncomfortable rather than reassuring. The doc comment now says so, and records the fix it is holding the door for - booking collateral in shares, the rebase-invariant unit these tokens already expose. V-22 is new: no xStock has a HyperSwap pool at any tier, against any pair. Holders exist; an EVM-side market between them does not. Invisible until launch day and expensive to discover then. 277 tests still green.
1 parent 7cc1e9b commit a5bb28f

3 files changed

Lines changed: 247 additions & 87 deletions

File tree

contracts/src/lib/RebaseDetector.sol

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,42 @@ pragma solidity 0.8.28;
2626
* "Backed Token Implementation", so this is the real issuer's design and not one
2727
* venue's wrapper.
2828
*
29+
* THIS IS THE WHOLE ASSET CLASS, NOT ONE BAD TOKEN
30+
* ------------------------------------------------
31+
* All ten of the largest xStocks are deployed on this chain running byte-identical
32+
* code, and six have already moved off a 1.0 multiplier:
33+
*
34+
* STRCx 1.0808929977 SPYx 1.0057145603 QQQx 1.0027250297
35+
* GOOGLx 1.0023772501 NVDAx 1.0009180758 MUx 1.0004015986
36+
*
37+
* So this library is not a safety net catching one unsuitable asset. **It refuses
38+
* the entire intended quote-asset class, and it is why the allowlist is empty.**
39+
* That is correct for the accounting as it stands, and it should be uncomfortable
40+
* rather than reassuring.
41+
*
42+
* Changing chain does not help. Backed's developer documentation states that on
43+
* every EVM chain their tokens "implement the ERC-20 standard with rebasing
44+
* logic"; only Solana and TON keep raw balances constant, and neither runs this
45+
* codebase.
46+
*
47+
* THE FIX THIS IS HOLDING THE DOOR FOR
48+
* ------------------------------------
49+
* These tokens expose `sharesOf(address)`, and shares are the rebase-invariant
50+
* unit: `balanceOf = sharesOf × multiplier`. A market that booked collateral in
51+
* SHARES would be neutral to the multiplier in both directions — claims scale
52+
* together, dividends accrue to whoever holds the claim, and a reverse split
53+
* cannot make it insolvent.
54+
*
55+
* That is an accounting change rather than a workaround, and it is the shape any
56+
* real answer takes. Until it exists, refusing is the honest behaviour: the
57+
* alternative is a market that looks fine for months and then cannot pay.
58+
*
2959
* WHAT WOULD HAPPEN WITHOUT THIS CHECK
3060
* ------------------------------------
61+
* Every multiplier measured so far has drifted UPWARD, because dividends accrue
62+
* into it, and a rising multiplier leaves the market holding more than its books
63+
* owe. Surplus, not insolvency. The danger is the other direction.
64+
*
3165
* A reverse split lowers the multiplier. Every holder's balance shrinks, and so
3266
* does the market's — while `curveCollateral` does not move, because no transfer
3367
* occurred and no event fired. The market becomes **insolvent against its own

docs/REVIEW-NOTES.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,48 @@ deterministically through the same handler the fuzzer drives.
356356

357357
---
358358

359+
## Shape 7 — an empty index read as an empty world
360+
361+
Every shape above is a defect in the code. This one is a defect in the *verification*, and it
362+
produced a wrong P0 conclusion that was written into the ledger and reported as fact.
363+
364+
**The claim:** "there is no canonical xStock ERC-20 on HyperEVM."
365+
366+
**The truth:** all ten of the largest xStocks are deployed there, at Backed's canonical
367+
addresses, running byte-identical code to Optimism and BNB — and HyperEVM holds *more* supply
368+
than either. Over $100M of assets.
369+
370+
**How the wrong answer was reached.** Two searches, both empty, both empties read as absence of
371+
the thing itself:
372+
373+
| Searched | Came back | What empty actually meant |
374+
|---|---|---|
375+
| HyperSwap V3 positions, sampled for their token pairs | no xStocks | xStocks have **no pools**. A token can be widely held and never pooled. |
376+
| HyperCore `tokenInfo.evmContract`, 400 HIP-1 indices | every equity `address(0)` | xStocks are **EVM-native**. They were never HyperCore tokens, so there is no HIP-1 record to link. Wrong table. |
377+
378+
Neither search was wrong. Both were answered correctly. The error was reading a **derived
379+
index** as a **census**: a pool registry indexes what trades, a HIP-1 table indexes what was
380+
bridged from Core, and neither is a list of what exists.
381+
382+
The tell was there and was explained away. `SPYx` *was* found — through a pool belonging to its
383+
wrapper — and was treated as an anomaly rather than as the edge of a suite. One contradicting
384+
data point against two confident absences, and the data point lost.
385+
386+
**The check never run was the cheapest one available.** Take a published address, call
387+
`eth_getCode`. One RPC call. It would have answered the row on day one and refuted the
388+
conclusion in seconds.
389+
390+
**Why this belongs in a document about code defects.** It is the same shape as Shape 1 and
391+
Shape 5 — a reader with no writer, an argument nobody checked — turned on the process that is
392+
supposed to catch them. An absence is evidence only if you know the index would have contained
393+
the thing. Both indices here were guaranteed *not* to contain it, for reasons that were
394+
knowable before the search.
395+
396+
The correction is recorded inside V-02 rather than replacing the wrong text, because a ledger
397+
that silently repairs itself teaches nobody anything.
398+
399+
---
400+
359401
## What is deliberately not implemented
360402

361403
These are not placeholders. They are recorded refusals, and each names the

0 commit comments

Comments
 (0)