How Lark pays
Lark pays people in dollars (USDG) — or in a stock they choose — from the tokenized stocks in your wallet on Robinhood Chain. It is a web page that builds one transaction for your wallet to sign. It deploys no contract, holds nothing, and charges no fee: the only contract you call is Uniswap's SwapRouter02, which was already on the chain.
Every number on the page comes from one module, js/pay.js, and the tests run that same file against the live chain. What is tested is what is signed.
The transaction
A payment is one call to SwapRouter02.multicall(deadline, steps). The steps, in order:
selfPermit(token, value, deadline, v, r, s)— one for each token you pay from. Robinhood's stock tokens and USDG accept EIP-2612 permits (their domain isname, version1, chain 4663; Lark checks it against each token's ownDOMAIN_SEPARATORbefore asking you to sign). The permit lets the router take at mostvalue, and expires with the transaction.- For each person, in turn:
pull(USDG, x)for the part paid from your own dollars;exactOutputSingle(stock → USDG)for each stock slice: sell exactly enough to raise y dollars, spending at most its quote plus 0.5%;sweepToken(USDG, amount, them)to hand over exactly their amount — orexactInputSingle(USDG → stock)withamountIn = 0(the router's own balance), to buy the stock they asked for straight into their wallet, with a minimum of its quote less 0.5%.
Each person's dollars are gathered and handed over before the next person's are, so the router holds nothing between people and nothing afterwards. A single sale paying one person in dollars is sent straight to them. A single person paid in dollars from dollars is a plain USDG.transfer, with no router and no signature.
If any sale would cost more than its limit, any purchase would return less than its minimum, a permit is short, or fifteen minutes have passed, the router reverts and nothing moves.
Where the money comes from
With use my dollars first on, the USDG in your wallet pays first. The rest is split across the stocks you tick in proportion to what each is worth at its pool's price, so paying someone leaves the mix of your portfolio as it was. The arithmetic is in integers: the pieces add up to the amount owed to the unit (a millionth of a dollar), and a rounding remainder goes to the largest holding.
At most 97% of any holding's value is sold, which leaves room for the price to move between the quote and the transaction. A slice under $1 is not worth its gas: it is dropped and the others re-spread. If what you hold cannot cover the payment, the page says by exactly how much.
A stock that pays several people is sold in several slices, one after another. Each slice is quoted as the difference between two cumulative quotes, so the second slice pays the price the first one left behind. The fee tier (0.05%, 0.3% or 1%) is chosen once per stock, as the cheapest for the whole amount.
Limits and guards
- Slippage. Each sale may spend at most its quote plus 0.5%; each purchase must return at least its quote less 0.5%. The permits cover exactly those limits, so after a payment the router is left approved for at most the unused 0.5%.
- Robinhood's price. Robinhood publishes a price feed for 26 of the 42 stocks. Every sale and purchase is priced against it before you sign. More than 3% worse than a fresh feed is refused, naming the stock. When the market is shut the feed stops, and after 20 hours a difference only warns.
- Deadline. The transaction and every permit expire fifteen minutes after they are built, measured by the chain's own clock.
- Size. Up to 8 people and 28 steps in one transaction (a Robinhood Chain block holds 32M gas; a swap takes up to ~250k).
- Who you can pay. The page refuses a token or a Uniswap contract as a recipient: money sent there is lost.
Requests and receipts
A request is a link: /pay?to=0x…&usd=42.50&get=NVDA¬e=Dinner. It holds the address, the amount (dollars and cents), what to be paid in and a note of up to 80 characters. Nothing is stored anywhere; whoever has the link can read those four things. Opening it fixes the address and the amount; the payer chooses what to pay from.
A receipt is /receipt?tx=0x…. It fetches the transaction and its logs from Robinhood Chain and shows who received what — read from the Transfer logs to the recipients the calldata names — and what left the payer's wallet.
How it is tested
The property suite (tools/test.mjs) runs the page's own js/pay.js against live Robinhood Chain state with eth_simulateV1: test wallets are funded by state override and hold real keys, so every permit is a real signature the token verifies on chain. Nothing is broadcast. Expected values are computed in the test, from balances, pool prices and Transfer logs — never by asking the module under test.
The last run: 13/13 properties and 65,729 checks passed against live state at block 75,855,589 (29 Sep 2026).
| Property | What the last run showed | Checks |
|---|---|---|
| exact | $123.45 arrived to the unit, paid by 2 permits and one transaction; the router kept nothing | 59 |
| mix | $250 from four stocks; the heaviest weight moved 0.003 points | 3 |
| cash | $25 of cash then $35.02 of NVDA paid $60.00 exactly | 4 |
| stock | $40.00 bought 0.113143 raw TSLA straight into their wallet | 8 |
| many | three people ($45.67, $12.34, $60 as AAPL) in one transaction, 858,172 gas | 5 |
| permit | every permit is spent to within its 0.5% slippage room; an unpicked stock is never touched | 7 |
| direct | $99.99 moved in one ERC-20 transfer | 4 |
| limit | a seller dumping a quarter of RBLX's pool first made the payment revert ("STF"); nothing moved | 7 |
| late | fifteen minutes and one second later it reverts (Transaction too old) | 3 |
| guard | refused at 6% from a fresh feed, warned when the feed is 3 days old, silent at 2% | 6 |
| short | short by exactly $1.00 at one dollar over capacity; covered at capacity | 2 |
| split | 3,000 random wallets and payments: every split exact to the unit | 65,615 |
| links | links round-trip; bad addresses, sub-cent and negative amounts are refused; a mis-domained permit is refused | 6 |
Then a sabotage sweep plants 18 bugs, one at a time, in a copy of js/pay.js — a sale that may spend without limit, a permit for the wrong amount, pieces that do not add up, a price read upside down — and requires the property named for each one to fail. 18/18 were caught.
The browser run: 7/7 journeys (31 checks) clicked through the real pages in Chrome with a test wallet, against a private copy of the live chain (29 Sep 2026).
Addresses
Every contract Lark talks to was already on Robinhood Chain (chain id 4663), written and audited by its own authors.
Stocks
Every Robinhood stock token Lark can pay from or pay in, deepest pool first: each has a USDG pool on Uniswap v3. From a scan at block 75,808,765, 29 Sep 2026. Prices are the deepest pool's; the page re-reads them live.
| Stock | Price | Pool fee |
|---|---|---|
| NVDA | $229.88 | 0.05% |
| SPCX | $148.86 | 0.05% |
| USO | $145.53 | 0.30% |
| CRCL | $84.28 | 0.30% |
| MU | $1068.49 | 0.30% |
| QQQ | $736.40 | 0.05% |
| GOOGL | $339.09 | 0.05% |
| COST | $920.11 | 0.30% |
| MSFT | $509.24 | 0.30% |
| AMC | $3.04 | 0.30% |
| MSTR | $153.99 | 1.00% |
| HIMS | $28.78 | 0.30% |
Show all 42 stocks
| AMZN | $246.38 | 0.30% |
| GLD | $380.82 | 0.05% |
| DJT | $9.20 | 1.00% |
| TSLA | $353.66 | 0.30% |
| SPY | $763.22 | 0.05% |
| LLY | $1177.53 | 0.05% |
| SGOV | $100.62 | 0.05% |
| DELL | $544.66 | 1.00% |
| AVGO | $357.88 | 0.30% |
| AMD | $613.67 | 0.30% |
| AAPL | $331.19 | 0.05% |
| INTC | $116.31 | 0.30% |
| META | $719.81 | 0.30% |
| RDDT | $143.98 | 1.00% |
| TSM | $453.28 | 1.00% |
| NET | $352.05 | 0.30% |
| QUBT | $8.60 | 0.30% |
| MRNA | $199.12 | 0.30% |
| PLTR | $185.89 | 0.30% |
| GME | $23.37 | 0.05% |
| SLV | $55.04 | 0.30% |
| NFLX | $70.60 | 0.30% |
| SNDK | $1720.13 | 1.00% |
| ASML | $1819.74 | 1.00% |
| TTWO | $202.43 | 0.30% |
| RBLX | $41.75 | 0.30% |
| JNJ | $266.60 | 0.30% |
| USAR | $14.08 | 0.30% |
| RIVN | $15.07 | 0.30% |
| NU | $12.41 | 0.30% |
Risks
- Paying from a stock is selling it. The price can be worse than you expect in a thin pool; the review shows the cost of selling before you sign.
- A payment to the wrong address cannot be undone. Check it; the page shows an avatar drawn from the address to make a typo easier to spot.
- Robinhood can pause a stock token, and a paused token cannot be sold. The transaction would then revert and nothing would move.
- Lark is not audited. It deploys nothing, but the page that builds your transaction is new code. Read how it is tested.