How Brim works
A Brim order is an ordinary Uniswap v3 liquidity position, placed so that it holds only one token: only your shares for a sell, only your dollars (USDG) for a buy. It sits in a narrow band of prices on the far side of today's price, in that stock's deepest Uniswap pool on Robinhood Chain.
A position like that is a limit order the pool fills for you. As traders push the price through the band, the pool swaps your shares for their dollars, at the band's prices, and charges them its fee, which it pays to you. When the price has passed the whole band, you hold only dollars.
Brim deploys no contract and holds nothing. It is a page that builds two transactions to Uniswap's own NonfungiblePositionManager and reads the results back from the chain.
The band
Uniswap pools price in ticks: each tick is 0.01% from the next, and a position's edges must sit on the pool's tick spacing. The spacing depends on the pool's fee: 10 ticks (0.10%) for a 0.05% pool, 60 ticks (0.60%) for 0.3%, 200 ticks (2.02%) for 1%.
- Sell at $P: the band's lower edge is the first edge at or above $P, and it is one spacing wide. Every share sells between those edges, so at $P or better.
- Buy at $P: the band's upper edge is the last edge at or below $P. Every dollar buys between those edges, so at $P or better.
- Spread: the band runs from your first price to your second, and sells (or buys) evenly as the price crosses it.
Stock tokens on Robinhood Chain are scaled: a token's uiMultiplier turns raw units into shares. Brim prices everything per share, as your broker would, and converts both ways exactly.
Placing: one transaction
NonfungiblePositionManager.multicall([
// your EIP-2612 permit, for exactly this order
selfPermitIfNecessary(token, amount, deadline, v, r, s),
// one of the two amounts is zero; the minimums are 99.9%
mint({ token0, token1, fee, tickLower, tickUpper,
amount0Desired, amount1Desired, amount0Min, amount1Min,
recipient: you, deadline: in fifteen minutes })
])
Every Robinhood stock token and USDG accept EIP-2612 permits, so there is no separate approval. Before asking you to sign, the page checks that the permit's domain hashes to the token's own DOMAIN_SEPARATOR.
If the price has already reached your band when the transaction lands, the position would need both tokens; with one of them zero, Uniswap computes zero liquidity and the pool refuses to mint. So an order is never turned into a trade at a worse price: it is simply not placed, and nothing moves.
Filling
Nothing needs to happen for an order to fill. Robinhood Chain's stock pools trade constantly — thousands of swaps a day in the deepest ones — as arbitrage keeps them in line with the market. Any swap that moves the price through your band trades against your position.
The page shows how much has filled by reading the position's liquidity and the pool's current price: below the band an order is waiting, inside it filling, past it filled.
Closing: one more
NonfungiblePositionManager.multicall([
decreaseLiquidity({ tokenId, liquidity: all, … }),
// the principal and every fee, to you
collect({ tokenId, recipient: you, amount0Max: max, amount1Max: max }),
// the empty NFT
burn(tokenId)
])
Only the wallet that owns the position NFT (or one it approved) can do this; the position manager refuses anyone else. Closing a waiting order is a cancel: everything you put in comes back.
The catch: close a filled order
A position lives in the pool until you close it. If the price passes your whole band and then falls all the way back through it, the same mechanism runs in reverse and buys your shares back — also at your prices, and also paying you the fee. You would be where you started, a little richer by the fees, but not sold.
So once an order reads filled, close it. The app marks filled orders at the top of your list, and the close is one transaction.
Fees
Brim takes nothing. Every trade through your band pays the pool's fee (0.05%, 0.3% or 1%), shared between the positions active at that price in proportion to their liquidity. Some pools pass a share of that fee to Uniswap's protocol; what reaches you is what the position manager's collect returns, which the app reads and shows before you close.
Gas on Robinhood Chain costs a fraction of a cent for each of the two transactions.
What can go wrong
- The price never gets there. Nothing happens; close the order and everything comes back.
- It fills, then comes back. See the catch: close filled orders.
- The pool, not the market. Orders fill at the Uniswap pool's price. If a pool drifts away from the real market, it fills when the pool gets there. The app shows Robinhood's own price beside the pool's and warns you when your price is on the wrong side of it.
- The market is shut. Outside US trading hours the pools barely move, so orders mostly fill while the market is open.
- The token itself. Robinhood can pause a stock token or block an address. A paused token cannot move in or out of a pool, so a close would wait until it is unpaused.
- Uniswap. Brim's orders are only as safe as Uniswap v3's contracts. The position manager and factory on Robinhood Chain are byte-for-byte the code Uniswap deployed on Base, apart from the 20-byte addresses compiled into them (checked by comparing both chains' bytecode). That code is audited, has no owner who can change it, and has run for years on other chains.
Addresses
Everything Brim talks to was already on Robinhood Chain (chain id 4663). Each one is checked by what it answers on chain, not by a name on an explorer.
Every stock's token and pool: Markets (scanned at block 75,940,168, 29 Sep 2026).
Tests
The file that builds your order, js/brim.js, is the file the tests run. Each property places real orders from test wallets on a private copy of the live chain (eth_simulateV1 over Robinhood Chain's current state, nothing broadcast), moves the pool's price through them by trading, closes them, and checks every amount against the test's own arithmetic, to the unit.
The last run: 8/8 properties and 2,354 checks passed against live state at block 75,984,294 (29 Sep 2026).
| Property | What it proved | Checks |
|---|---|---|
| sell | NVDA (stock is token1) sold at avg $230.87 ≥ $230.64 +$0.0433 fee; SPCX (token0) at $151.21 ≥ $151.07 +$0.0284 fee | 46 |
| buy | NVDA bought at avg $224.95 ≤ $225.17 +$0.1502 fee; GOOGL (token0) at $336.78 ≤ $337.09 +$0.1502 fee | 46 |
| wide | TSLA 60-tick grid: 6 steps from $358.56 to $371.71; half-way it read 50.2% filled (test: 50.2%) and closed into both tokens | 9 |
| guard | sells below and buys above today's price are refused by the page; NVDA: refused on chain (execution reverted); SPCX: refused on chain (execution reverted) | 14 |
| permit | USDG and NVDA permits verified on chain; 0 unit(s) of rounding left approved; a mis-domained permit is refused | 9 |
| late | refused after the deadline by Uniswap's own check: "Transaction too old" | 4 |
| price | 42 pools: price per share, tick ↔ price and shares ↔ raw units agree with the test's own arithmetic (both orientations, live multipliers) | 168 |
| grid | 672 bands across 42 markets start (sell) or end (buy) within one grid step of the price, on the right side of it | 2,058 |
Then a sabotage sweep plants 17 bugs, one at a time, in a copy of js/brim.js — a band on the wrong side of the price, a price read upside down, a permit for the wrong amount, an order that never burns — and requires the property named for each one to fail. 17/17 were caught.
The browser run: 6/6 journeys (26 checks) clicked through the real pages in Chrome with a test wallet, against a private copy of the live chain (29 Sep 2026).