How a deal works
Parley lets two people swap Robinhood Chain stock tokens and dollars (USDG) directly: one makes a deal that names the other, the other accepts, and every item on both sides moves in that one transaction. It is a web page that builds transactions for your wallet to send. It deploys no contract, holds nothing and charges no fee: every deal is an ordinary order in Seaport 1.6, the audited exchange protocol behind OpenSea, which was already live on Robinhood Chain.
Every transaction comes from one module, js/deal.js, and the tests run that same file against the live chain. What is tested is what is sent.
The order
A deal is a Seaport order with these fields:
- offerer — the maker. offer — one to four ERC-20 items the maker gives: Robinhood stock tokens or USDG, each a fixed amount (
startAmount = endAmount). - consideration — one to four items the other side gives, every one paid to the maker.
- orderType =
FULL_RESTRICTED(2): the whole deal or none of it, and restricted to its zone. - zone = the other person's wallet address. That is the lock (next section).
- startTime / endTime — a minute ago, and the expiry the maker chose (one hour to thirty days). No conduit, no zone hash, no fee.
Amounts are what you typed: shares for a stock, converted to the token's raw units with its own uiMultiplier (Robinhood's stock tokens scale for splits and dividends) and rounded down, so a deal never promises more than you typed; dollars for USDG (6 decimals).
The lock
Seaport checks a restricted order's zone before any transfer, unless the caller is the zone itself. When anyone else tries to fill it, Seaport calls authorizeOrder on the zone and requires a magic value back. A person's wallet has no code to answer with, so Seaport refuses with InvalidRestrictedOrder. The named person calls Seaport themselves, is the zone, and is let through.
So a deal can be accepted by exactly one wallet, and there is no list, contract or server that says so — only the order's own zone field, which the maker signs into the order by posting it. The private property checks it on the live chain, and checks the control: the same terms without the lock let the stranger straight in.
Seaport also lets the zone cancel the order. For Parley that means the named person can decline a deal on chain.
Post, accept, cancel
Post
The maker calls Seaport.validate([order]). Seaport skips the signature when the caller is the offerer, marks the order valid, and emits OrderValidated with every field of the order. That event is the deal's only record: the link carries the order's hash and the block it was posted in, and the page reads that one block back. The Your deals page reads every OrderValidated from Seaport since Parley went live and keeps the ones naming your wallet.
Accept
The named person calls Seaport.fulfillOrder(order, 0). Seaport pulls every consideration item from them to the maker and every offer item from the maker to them, in one transaction. If either wallet is short of anything, or has not approved it, the whole transaction reverts and nothing moves.
Cancel or decline
Either the maker or the named person calls Seaport.cancel([order]). Anyone else is refused with CannotCancelOrder. A maker who bumps their Seaport counter (incrementCounter) cancels every order they ever made at once; the page recomputes each deal's hash under the current counter and shows those as cancelled too.
A deal expires at exactly its endTime: Seaport accepts it while startTime ≤ now < endTime. The page uses the chain's clock, not yours.
Approvals
Seaport pulls tokens at the moment a deal is accepted, so both people approve Seaport for what they give. Parley asks for exactly the amount — never an unlimited approval — with one exception worth knowing: an approval replaces the previous one, so when you post a second deal giving the same stock, Parley approves what both deals need together. Otherwise accepting either deal would use up the allowance and leave the other unacceptable. The allowance property proves both halves of that on the live chain.
Prices
A deal can be any price the two of you agree. Parley only shows what each side is worth so you both know. Stocks are valued at Robinhood's own Chainlink-style price feed for that stock (26 of the 42 have one), per share times the token's multiplier; a stock without a feed, or whose feed is more than four days old, is valued at its deepest Uniswap pool's mid price, and the page says which. USDG is a dollar.
What the pools charge
The reason to trade directly. For every stock, what it costs to sell (and to buy) a given dollar amount through its cheapest Uniswap v3 fee tier, measured with Uniswap's own QuoterV2 against that pool's own mid price, at block 75,883,037, 29 Sep 2026. "—" means the pools cannot fill that size at all.
| Stock | Sell $1k | Sell $10k | Sell $25k | Sell $100k |
|---|---|---|---|---|
| NVDA | 5 | 6 | 7 | 14 |
| SPCX | 5 | 8 | 13 | 36 |
| CRCL | 31 | 42 | 61 | 166 |
| MU | 31 | 42 | 60 | 158 |
| QQQ | 5 | 8 | 12 | 33 |
| GOOGL | 5 | 9 | 16 | 59 |
| USO | 30 | 33 | 38 | 64 |
| COST | 31 | 40 | 54 | 126 |
| MSFT | 31 | 36 | 45 | 92 |
| AMZN | 30 | 34 | 39 | 76 |
| AMC | 38 | 113 | 255 | 769 |
| MSTR | 103 | 126 | 174 | 435 |
Show all 42 stocks
| GLD | 5 | 9 | 16 | 56 |
| HIMS | 30 | 33 | 38 | 165 |
| SPY | 5 | 9 | 15 | 66 |
| LLY | 6 | 17 | 35 | 129 |
| TSLA | 19 | 45 | 70 | 234 |
| DJT | 102 | 117 | 147 | 337 |
| META | 31 | 44 | 64 | 237 |
| SGOV | 5 | 6 | 7 | 15 |
| DELL | 103 | 134 | 194 | 577 |
| AAPL | 6 | 13 | 29 | 219 |
| AVGO | 40 | 126 | 266 | 1000 |
| INTC | 33 | 63 | 115 | 495 |
| AMD | 34 | 69 | 136 | 524 |
| RDDT | 102 | 124 | 159 | 387 |
| TSM | 108 | 179 | 281 | 1258 |
| NET | 33 | 62 | 109 | 2302 |
| GME | 7 | 29 | 62 | 276 |
| MRNA | 38 | 109 | 224 | 2634 |
| SLV | 33 | 60 | 133 | 4084 |
| QUBT | 36 | 103 | 232 | 4326 |
| PLTR | 32 | 66 | 148 | 4641 |
| NFLX | 33 | 60 | 132 | — |
| SNDK | 119 | 324 | 753 | — |
| ASML | 156 | 396 | 703 | — |
| TTWO | 34 | 72 | 215 | — |
| RBLX | 37 | 129 | 1252 | — |
| JNJ | 35 | 86 | 2246 | — |
| RIVN | 81 | 242 | 2566 | — |
| USAR | 73 | — | — | — |
| NU | 75 | — | — | — |
Costs are in basis points (1 bp = 0.01%) and include the pool's fee and the price impact of the size. A direct Parley deal pays neither; it pays gas, and the price is whatever the two of you agreed.
How it is tested
The property suite (tools/test.mjs) runs js/deal.js — the page's own builder, reader, approvals, status and prices — against Robinhood Chain's live state through eth_simulateV1, with three wallets funded by state override: a maker, the person the deal names, and a stranger. Nothing is broadcast. Expected values are computed in the test from raw balances, Transfer logs, Seaport's own answers and the feeds read directly, never by asking the module.
The last run: 10/10 properties and 159 checks passed against live state at block 75,904,363 (29 Sep 2026).
| Property | What the last run showed | Checks |
|---|---|---|
| seaport | version 1.6; byte-identical to 3 other chains' Seaport outside the chain id and domain separator | 14 |
| swap | 10.5 AAPL + 2 TSLA for 3 NVDA + $150.25: all four items moved to the unit, in 267,511 gas | 27 |
| private | a stranger is refused with InvalidRestrictedOrder; the same terms without the lock let them in; the named person gets in | 11 |
| cancel | a stranger gets CannotCancelOrder; the maker cancels and the counterparty declines; cancelled, declined and counter-voided deals are refused and read as cancelled | 22 |
| expiry | open one second before endTime; expired, and refused with InvalidTime, at exactly endTime | 8 |
| once | the second accept is refused with OrderAlreadyFilled, even with allowance and stock to spare | 7 |
| allowance | the second approval is sized for both deals and both are accepted; without that, the first is refused (ERC20InsufficientAllowance) | 18 |
| ready | a short counterparty and an emptied maker are both named by the page and both refused by the chain | 19 |
| reader | 11 dishonest shapes are hidden, 7 bad deals are never built, links round-trip | 21 |
| prices | 4 stocks priced from Robinhood's feeds, 3 from their pools, each equal to a reading taken here; a deal's two sides sum exactly | 12 |
Then a sabotage sweep (tools/sabotage.mjs) plants 26 bugs, one at a time, in a copy of js/deal.js — a lock naming the wrong person, an order anyone can fill, shares rounded up, an approval that forgets another deal, a cancelled deal read as open, a feed price used per raw unit — and requires the property named for each one to fail. 26/26 were caught.
The browser run: 8/8 journeys (41 checks) clicked through the real pages in Chrome with three test wallets — a maker, the person the deal names and a stranger — against a private copy of the live chain (29 Sep 2026).
Addresses
Every contract Parley calls. None is Parley's.
Seaport's runtime on Robinhood Chain is compared byte for byte with the same address on Ethereum by the seaport property: identical except the two immutables it is built with (the chain id and the EIP-712 domain separator).
Risks
- A deal is a promise to Seaport, not escrow. Your stocks stay in your wallet until acceptance. If you move them away or lower the approval, the deal simply cannot be accepted until you put them back — both pages say so.
- The price is yours. Parley shows each side at Robinhood's prices, but it does not stop either of you agreeing a bad deal. Read both sides before you post or accept.
- Approvals outlast deals. Cancelling a deal does not lower the approval you gave Seaport for it. Lower it from your wallet if you do not intend to post again.
- Seaport and the stock tokens. Parley relies on Seaport 1.6 and Robinhood's token contracts behaving as they do today. Robinhood can pause its stock tokens, block addresses and scale balances; a paused token cannot be traded here either.
- Not audited as a product. Parley's own code is a web page; it has not been audited. Its tests are published above, including the bugs they were built to catch.