Built on Robinhood Chain

Pawl

The catch that stops it running back.

A stop-loss for tokenized stocks. Name the price you would rather be in dollars than in the stock, sign it once, and from then on anybody in the world may sell for you — but only once Robinhood's own price feed says you are there. Your shares never leave your wallet until they sell, and you can take the order down whenever you like.

Shares stay in your wallet No keeper, no server Cancel on chain
0.27% median below your trigger, over 19,545 simulated stops
2,765 bytes of contract, holding 0 storage slots
21/21 properties, run on chain at block 67,804,468
The reason this exists

A pool can hold a limit order. It cannot hold a stop.

This is not a gap in the tooling. It is a property of what a pool is, and it is why this chain has limit orders and no stops.

1

A limit order sells into strength

"Sell my Apple at $360" when Apple is $335. Put one tick of liquidity at $360, all of it in shares, and the pool hands them out as the price climbs through. That works. It is what a Uniswap v3 position is.

2

A stop sells into weakness

"Sell my Apple at $300" when Apple is $335. You want out if it falls. The price has to go down through your number, not up.

3

The pool fills it immediately

Park that as a one-tick band and it is already on the wrong side: the market is at $335, your shares are offered at $300, and the first person to look takes them. You did not set a stop. You gave away 10%.

4

Something has to say "not yet"

A pool has no way to refuse. Pawl's whole contribution is one small contract that can: it reads the price feed, and until the price is at or below your number it refuses to let your order be filled at all.

The measurement this product rests on

The feed prints when the price moves, not when the clock ticks.

That is the difference between a stop that works on a chain and one that is a day late. It is also not something to take on trust, so here is the number.

Every feed moves about the same distance between prints

34 of Robinhood's 35 stock feeds on this chain, every round of each over 30 days (Sep 20, 2026).

CRCL — the busiest

45.6 prints a day, a median of 4.5 minutes apart.

Median move between prints: 55.9 bp.

SPY — the quietest

1.3 prints a day, a median of 14 hours apart.

Median move between prints: 50.6 bp.

Across all of them

One prints 36 times as often as the other. Their per-feed median moves span 50.6 to 57.4 bp.

Only 1.3% of all moves are under half that, and 0.8% are under 10 bp.

A feed driven by a clock would show small moves constantly and a median that rose with the stock's volatility. These show almost nothing under a quarter of a percent and the same median everywhere, which is what a deviation threshold looks like: the feed prints when the price has travelled about 0.54%, and otherwise it says nothing. That is why a stop on this chain is worth setting — the gate opens fastest exactly when the market is moving, which is when a stop matters.

The one that does not fit

Evidence against the paragraph above, which is the reason to trust the rest of it.

SGOV is a cash-like fund. It moves a median of 1.0 bp between prints, not 54.2, and it prints 0.8 times a day on a 24-hour heartbeat instead. It never travels far enough to trip the threshold, so the threshold never fires.

That sharpens the claim rather than denting it: the rule is a threshold, not a metronome. It also means a stop on something that barely moves can be a day behind, and the app says so on the feeds where it is true — it offers a staleness bound built from each feed's own measured behaviour rather than one number for all of them.

The honest number

Your stop fills below where you set it. Here is how far.

Nothing on a chain can fill at your number, because the chain only learns the price when the feed prints one. Pawl's gate opens at the first print at or below your trigger — which is somewhere under it.

Replayed over 19,545 stops

Every print of every feed over 30 days treated as a moment to arm a stop, at 2%, 5%, 10% below the price, then walked forward to the print that opened the gate.

Typical

26.9 bp

below your trigger, median. On $10,000 that is about $27.

Bad day

235 bp

the 99th percentile — 2.4%, or $235 on the same position. The worst in the whole replay was 6.1%.

It does not depend on depth

25.7 bp at a 2% stop, 26.9 bp at 5%, 26.8 bp at 10%.

The cost is set by the feed's threshold, not by where you put your stop.

The median is about half the feed's own threshold, which is exactly what it should be if a trigger lands anywhere inside the move that crosses it. The tail is the part worth reading twice: a gap is a gap, and on the worst day in the replay a stop opened 6.1% below its number. A stop is not a floor. It is an instruction that gets carried out at the first moment the chain can see.

The median silence before a fill — the time the price spent under your trigger with nothing on chain able to see it — was 12 minutes, and 2.4 hours at the ninetieth percentile.

What is ours and what is not

One contract. No storage, no owner, no keeper.

Seaport does the trade

Your stop is an ordinary Seaport 1.6 order — Seaport was already on this chain, was not deployed by us, and is what holds your approval, moves both sides in one transaction and lets you cancel.

Publishing it writes the whole order into Seaport's own event log. That log is the board. There is no server in this product and nothing to keep running.

0x0000…B395

Pawl adds a gate

A Seaport order may name a zone: a contract Seaport calls before and after a fill, which can refuse. Pawl's zone reads Robinhood's feed and refuses unless the price is at or below your trigger.

It is 2,765 bytes — 11.3% of what a contract may be — with 0 storage slots, no owner and no upgrade path. Your terms travel inside the 32 bytes Seaport already signs, so your signature covers them: change the trigger and the signature stops verifying.

0xc7a3…DC39

What it cannot do, in plain words

  • It cannot make anyone buy. A stop is an offer. If nobody wants your shares at your price, nothing happens — and the app measures what a filler would have to make before it suggests a price.
  • It cannot reach a price between two prints. See the number above.
  • It cannot stop Robinhood pausing a stock. Robinhood holds a pause, a blocklist and a burn on every one of these tokens. That is true of everything on this chain.
  • It has not been audited. It is 2,765 bytes and the whole of it is on the docs page. Read it. What we have instead of an audit is below, including what it failed.
  • It is not yet on chain. The address is fixed by the bytecode, so anyone can put it there and everyone can check it is the same contract. The app will offer you the transaction and tell you what it costs.
Instead of an audit

Everything here was run against the real chain.

Not a testnet and not a mock. Each property is one eth_call whose code executes against the real Seaport, the real tokens and Robinhood's real feeds, and writes nothing.

21/21

Properties, on chain

462 assertions at block 67,804,468. Real fills refused above the trigger and executed below it, with a control that the same order with no gate goes through — so the refusal is the gate and not something else.

27/27

Deliberate breaks, each caught by the property named for it

The gate inverted, the staleness check deleted, the terms read one bit out, the order built without a zone. Credit goes to the property that was looking for it — "the suite went red" is how one wrong check takes credit for everything.

6/8

Breaks caught by the fuzz

16 random sequences of real fills, 140 of them landing, with 9 invariants checked after every operation. 2 breaks survived it; both are below.

What the checks missed

The interesting half. A clean sweep usually means the sweep is not looking.

  • Three subtle breaks were invisible to 18 properties. When the first sweep came back with everything caught, three more breaks were written to be hard — a staleness bound off by one, a missing guard against a feed stamped in the future, and a scale reported wrong. Replayed against the suite as it then was, 3/3 of them were seen by nothing at all. Three new properties were written for them, which is the only honest response to a survivor.
  • The fuzz found a real defect in the product, not the tests. Seaport only accepts a partial fill whose fraction divides every amount exactly, and the shares offered and the dollars asked were almost always coprime — so a stop advertised as partly fillable could in practice only be taken whole. Every seed landed exactly four fills and all four came from the scripted coda. Both amounts are now rounded to a grid so a stop can be taken 1% at a time, and the fills per seed doubled.
  • Two breaks the fuzz genuinely cannot see, each declared with its reason and each caught by a property instead: a zone that waves the first of Seaport's two calls through (the transaction reverts atomically, so no balance ever differs), and a page that asks full price (nobody would fill it, but the fuzz's fillers are not economic actors). The declaration is checked against the sweep, so it cannot be a story.

Set the price you would rather be in dollars.

Your shares stay where they are. The order is public, the gate is 2,765 bytes of code that holds nothing, and you can take it down at any time.