The server aggregates public data and stores the social layer; it never holds keys and never signs. Every transaction is built in the browser, simulated, and signed by your own wallet. BStocks never custodies funds.
Standards, math, order flow and the exact contracts this app is built against. For the plain-language version, read How it works.
The server aggregates public data and stores the social layer; it never holds keys and never signs. Every transaction is built in the browser, simulated, and signed by your own wallet. BStocks never custodies funds.
All reads batch through Multicall3 and rotate across the keyed RPCs by weight — no single account carries the traffic — with every other provider, then four public endpoints, queued behind whichever one served the call. Log sweeps skip providers that cap block ranges. Confirmations arrive in ~200 ms — Flashblocks preconfirmations today, canonical 200 ms blocks once the Denim hardfork activates; the same receipt call covers both.
On Base Account, approve + swap or approve + mint go out as a single atomic EIP-5792 batch, gas-sponsored when the paymaster allows, with ERC-8021 builder attribution on every call.
Splits and dividends update the token's multiplier; a scheduled change is announced onchain ahead of time and flagged on the stock page, because it changes how many shares a token is worth. The OracleRegistry's pause flag freezes the reference feed during the action, which the app reads but does not warn about: it never settles against that feed.
Dozens of copycat “NVDAc” tokens exist. Discovery only accepts B20s deployed by Coinbase's creator address and picks up new listings with a background scan roughly every 30 minutes.
What the pools are actually paying right now; the second source takes over when the first is down. Only pools quoted in USDC or ETH are priced from, and the figure has to agree with the reference to be the headline. A stock with no feed yet is checked against its US share price instead (Yahoo Finance, delayed, times the multiplier), labelled as a share price in the app.
Priced from traditional market data, so no pool can move it. That is why it is the check: a market price more than 20% away from a live feed is refused and this is shown instead. Marked stale after one hour without an update. Optional: a stock is listed on its supply, pool and routes, and a feed is attached when Chainlink publishes one. When the node does not answer, Coinbase's Tokenized Stocks API supplies the same round (its nav_price), age and all.
Every provider quotes at once; the route with the best net output (output minus estimated network fee) wins. Providers that fail are listed with their reasons instead of silently dropped. With best execution on, CoW Protocol's batch auction takes the trade whenever its quote is within 0.5% of the best swap: solvers compete for the order, the winner pays the gas, and a signed order cannot be front-run. The panel suggests it above $250.
The review sheet re-fetches a binding quote right before you sign, so the numbers you approve are the numbers that execute.
The whole bundle runs through an eth_simulateV1 check before the wallet opens. Approvals are exact-amount to the specific router in use — never unlimited, never to an address from the quote payload.
Deposits and withdrawals run in-app: exact approval to the venue, simulated, signed by your wallet. Morpho markets that lend USDC against a stock are listed apart and open on Morpho; one with under $10K free to borrow is marked thin.
Mint from a USD-per-share range (one token amount derives the other from the current √price), collect fees — singly or all at once — and withdraw 25–100%. Minimums sit 1% under the shown amounts; deadlines are 10 minutes.
Everything this app shows about tokenized stocks is available as an API, on the same data and the same caches the pages use — so what a caller reads cannot drift from what a visitor sees. The developer page runs every example live against this deployment.
Baskets, profiles, gift metadata and AI usage live behind row-level security. Positions and balances are always read from the chain, never mirrored.
API routes limit per hashed IP in fixed windows that survive serverless cold starts. AI features run on small models with per-wallet quotas surfaced before they run out.
No analytics wallets, no custodial keys, no secrets in the client bundle. The only privileged surface is an admin API behind a server-side token.
The site is served as a Base mini app from /.well-known/farcaster.json. There is no second build and no second codebase: the host opens the same pages, and the app tells it when it has finished loading so the splash screen comes down.
Inside the app the wallet is the one already signed in there, already on Base, and it is connected on arrival. Nothing is signed on load here either — connecting is not signing, and every trade, claim and approval is still confirmed by you.
A shared gift pool carries its own launch card, so the button opens that pool rather than the home page. Link-gated pools keep their key in the URL fragment, which never reaches a server, so those are deliberately left without one.
A mini app host embeds the page in a frame, so the site allows framing from the Base and Farcaster hosts by name and refuses everyone else — frame-ancestors rather than a blanket denial, which would have shown a blank panel instead of the app. The one exception is /embed: the widgets (a stock's buy / sell panel, and its price and chart) exist to be put on other sites, so any site may frame those pages. A widget's trade still ends in the visitor's own wallet, which the host page can neither draw over nor answer for them.
| Contract | Address · role |
|---|---|
| B20 factory | 0xB20f000000000000000000000000000000000000Deploys Coinbase Tokenized Stock (B20) tokens |
| Activation registry | 0x8453000000000000000000000000000000000001B20 activation state |
| Policy registry | 0x8453000000000000000000000000000000000002Transfer policies; approve() is not policy-gated |
| Stock OracleRegistry | 0x3f3E8cf41cdd3b1D118c16471aB0113DfDDd5CaDgetOracleParams(token) → (multiplier, paused) |
| Coinbase B20 creator | 0xe090ecbee12d4b6aee5e73ff60945f2545ef5c6fDiscovery trusts a token created by this EOA or named on Coinbase's own stock list; a matching ticker alone never counts |
| USDC | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913Quote and settlement currency, 6 decimals |
| BStocks GiftEscrow | 0x59E4C2C5AfbDae22A09566EB69f283c7f884EB23Ownerless, verified; holds claim-link gifts until claim or reclaim |
| GiftEscrow (legacy) | 0x8D9fE4b3Ab9BecbE1181d15d51FB9724561C7f55Earlier deployment; gifts locked there still claim and reclaim from it |
| BStocks GiftPool | 0x591d505C2bFa754122bBF04c0f5A601bDA8b6ed9Ownerless, verified; holds gift pools until claimed, cancelled or withdrawn |
| GiftPool (legacy) | 0xBD23ABB61D80B88DacB1Dc56DC2641e4Bfb76E10Earlier deployment; pools funded there still pay out of and withdraw from it |
| CoW GPv2Settlement | 0x9008D19f58AAbD9eD0D60971565AA8510560ab41EIP-712 domain “Gnosis Protocol” v2; settles limit orders |
| CoW VaultRelayer | 0xC92E8bdf79f0507f65a392b0ab4667716BFE0110The only spender approved for CoW orders |
| Aerodrome Slipstream position manager | 0xe1f8cd9AC4e4A65F54f38a5CdAfCA44f6dD68b53Mint / collect / withdraw; factory 0xf8f2eB49… |
| Aerodrome Slipstream (v1) position manager | 0x827922686190790b37229fd06084350E74485b72Mint / collect / withdraw; factory 0x5e7BB104… |
| Uniswap v3 position manager | 0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1Mint / collect / withdraw; factory 0x33128a8f… |
| Basenames L2 resolver | 0xC6d566A56A1aFf6508b41f6c90ff131615583BCDReverse-resolves wallet → name for profiles |
| Multicall3 | 0xcA11bde05977b3631167028862bE2a173976CA11Batched reads everywhere |
B20 stock tokens themselves all start with 0xb2… and are listed with their address on each stock page. Always verify on Basescan before interacting with a contract directly.
Prefer the simple version? The user guide covers the same ground without the internals.
Read How it works