How a coil works
Skein deploys no contract. A lot is one order on Seaport 1.6, which was on Robinhood Chain long before this site was, and over which Skein holds no privilege of any kind. Everything below is what the page builds, byte for byte, and what was run against it.
What a lot is
A lot is a Seaport order that offers one ERC-20 item per stock and asks for one item of USDG, paid to the seller. Its order type is PARTIAL_OPEN, so anybody may fill any fraction of it, and its zone, zone hash and conduit key are all zero — nothing is routed through a conduit, and no third party can gate a fill.
A bid is the same order the other way round: USDG is offered and the stocks are asked for, paid to the bidder. Seaport makes the filler provide consideration items, so a bid needs nothing of the bidder's but the dollars.
Why a fraction always divides
Seaport multiplies every amount in an order by the buyer's numerator and divides by the denominator, and it reverts unless every division is exact. A basket stated as totals would therefore fail for some fractions and not others — and which ones depends on each stock's decimals, so it would fail unpredictably, per basket.
Skein states a basket per unit and offers 1,000 units of it. Every amount in the order is then a multiple of the denominator, so every numerator divides exactly, for every strand, always. The smallest slice is 1/1,000 of the coil.
The units are not stored anywhere by Seaport. The page reads them back out of the order: the greatest common divisor of every amount in it. That is why a lot published by somebody else, in software that is not this one, can still be read and filled here.
Rounding, and which way it goes
Turning dollars and weights into whole per-unit amounts always rounds down. A coil is therefore worth at most the dollars its seller asked for, never more, and the page prints the shortfall. A seller is never asked to deliver a share they did not agree to. A strand that would round to nothing is refused, not silently dropped — a basket quietly missing a stock is the bug that looks like a feature.
The board
There is no server and no database. The board is Seaport's own OrderValidated log, read back 14 days' worth of blocks and then checked against the chain at one block: Seaport's order status, the seller's counter, and every strand's balance and allowance. Two things the board does that are easy to get wrong:
- Cancelled is checked first. Seaport clears an order's
isValidatedflag when it is cancelled, so a cancelled lot also reads as "Seaport has never seen this" — and saying that about a lot its seller has just taken down is a lie the page would have no way of noticing. - A lot is only as fillable as its thinnest strand. If the seller has sold one of the twelve elsewhere, the board says how much of the lot can still be delivered and which strand is the limit, instead of letting a buyer find out from a revert.
The node refuses a log query that is too heavy in more than one way — exceeds limit and log query timed out — and only the first of those looks like a size problem. The reader halves its range on either and widens again once the node answers.
One thing Seaport does that surprised us
Asking for more units than are left does not revert. Seaport reduces the numerator to whatever remains and fills that. The fuzzer found this: the invariant that had been written asserted a revert, which was a belief about the chain rather than a fact about it. What is actually true, and what is now asserted, is that no more than the remainder ever moves and the buyer pays for no more than they get.
Pricing a lot against the pools
Every lot on the board is shown next to what its shares are worth at Robinhood's own price feed — the oracle a Morpho market lending real USDG against that stock actually names — as a premium or a discount in basis points. The landing page also publishes what the Uniswap pools would charge for the same shares, at four sizes, measured in one block.
That measurement is not flattering everywhere and the whole table is published. For the big names the pools cost almost nothing at any size we measured: the showcase basket costs 0.07% at $25,000, and you should use them. A lot earns its keep on thin names and on size — the 8 dearest stocks here cost 13.26% at $25,000, and at $100,000 the pools refuse 11 of the 44 outright.
What it costs
Gas, and nothing else. Skein takes no fee and there is no fee item in any order it writes — an order that pays anybody but its seller is refused by the reader, on Skein's own lots and on strangers' alike.
- Publishing a 12-strand lot: 874,049 gas, about $0.15.
- Filling a quarter of it: 859,570 gas, about $0.15.
- Taking it down: 51,043 gas, about $0.0088.
At 0.0660 gwei and ETH at $2,624, taken from Robinhood's own "ETH / USD" feed on this chain after checking that the feed says that is what it is. Publishing gas is the live node's own estimate and was measured again on a fork; the two agree. This chain is Arbitrum Nitro, so a parent-chain share is charged on top; the measured estimate and live receipts agree that it is a share rather than nothing.
Which stocks can be strands
This chain carries counterfeits of every real name, so nothing here starts from a name. At one pinned block every token answered symbol, name and decimals; every v3 pool is the one Uniswap's own factory returns for that pair and fee; every v4 pool id is the hash of a hookless USDG key and is initialised; and every price is the oracle a Morpho market lending the real USDG against that token names.
A stock is a strand only if $1,000 fills within 3% of that price in both directions. A basket you can sell into but not buy out of is half a market, and the comparison the site makes needs both sides. Pools above a 5% fee are dropped: this chain carries v4 pools at 50%, 80% and 90% that hold liquidity and quote happily, and a lot priced against one of those would look like a bargain against nothing.
What was run against it
- 16/16 properties on the real chain (
tools/props.mjs): oneeth_calleach at block 67,805,274, no contract deployed. Each refusal is classified by Seaport's own error, and each has a control in the same call proving the identical call succeeds when the guard is removed. - 3/3 fuzz seeds clean, 9/9 planted breaks caught (
tools/fuzz.mjs): publishes, fills, part-fills, take-downs, counter bumps, moved shares and revoked approvals in random order on a fork, invariants after every step, judged against a clean baseline run of the same seed. - 29/29 deliberate breaks caught (
tools/sabotage.mjs): one line changed at a time injs/order.js,js/coil.jsand the board reader, each break caught by the check named for it, and 1 declared survivors with the reason written down. - 23/23 through the real pages in a real browser (
tools/e2e.mjs): a lot built and published from one wallet, found on the board by another, part-filled, and every strand's arrival read out of the transfer logs — against a fork, under the deployed Content-Security-Policy.
Every number on this site is derived from files in data/ by one tool, and the build fails rather than print a figure nobody computed. Every sweep carries a control that must fail: the page-capture tool is pointed at a blank page and must read flat, the palette sweep is given a deliberately unreadable pair, the address check asks USDG to be Seaport, and the sabotage sweep runs the real modules first and refuses to grade anything against a control that is not clean.
Not audited. Seaport has been audited by others; this site's use of it has not been audited by anyone.
Addresses
| What | Address |
|---|---|
| Seaport 1.6 — every lot is one of its orders | 0x0000000000000068F116a894984e2DB1123eB395 |
| USDG — Global Dollar, what a lot is priced in | 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168 |
| Morpho Blue — where the price feeds are named | 0x9D53d5E3bd5E8d4Cbfa6DB1ca238AEA02E651010 |
| Uniswap Universal Router — read, never called | 0x8876789976dEcBfCbBbe364623C63652db8C0904 |
| Uniswap v3 factory | 0x1f7d7550B1b028f7571E69A784071F0205FD2EfA |
| Uniswap v4 PoolManager | 0x8366a39CC670B4001A1121B8F6A443A643e40951 |
| Uniswap v4 StateView | 0xF3334192D15450CdD385c8B70e03f9A6bD9E673b |
| QuoterV2 (v3) | 0x33e885eD0Ec9bF04EcfB19341582aADCb4c8A9E7 |
| Quoter (v4) | 0x8Dc178eFB8111BB0973Dd9d722ebeFF267c98F94 |
| Multicall3 | 0xcA11bde05977b3631167028862bE2a173976CA11 |
What is not built
- No order book and no matching: a lot sits until somebody fills it or the seller takes it down.
- No alerts. Nothing tells a seller that their lot has been part-filled, or a buyer that a coil they wanted has appeared.
- No native ETH — a lot is priced in USDG and nothing else.
- At most 12 strands in one lot, and no lot under $25.00.
- No live pool comparison inside the app: the board prices each lot against Robinhood's feed, and the pool comparison is published as a measured table on the landing page rather than recomputed per lot in the browser.