> For the complete documentation index, see [llms.txt](https://docs.familio.trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.familio.trade/the-product/trading.md).

# Trading

Only the head and co-pilots trade. Members do not pick coins. Every fill is one on-chain swap the whole family shares.

## Where you trade

**On the family page.** If you are the head or a co-pilot, a collapsed **trade** bar sits on `/f/<handle>` — tap to expand buy/sell, notes and turbo. No need to open Manage first.

**In Manage.** **Manage → trade** is the same panel with the full layout (bags column, strays, rules). Use whichever is closer when a play is live.

Both paths call the same `swap` logic and respect `tradingLocked`.

## Quote pairs

Each family is quoted in **ETH** (WETH under the hood; you send and usually receive native ETH) or **USDG**. Buys are quote → token. Sells are token → quote. A swap that is not that pair reverts (`NotQuotePair`). You cannot trade TOKEN\_A → TOKEN\_B directly; sell to quote, then buy.

ETH-quoted families are what the create wizard opens today (founding ETH in the same transaction). USDG is an allowed quote at the factory.

## Venues

The app quotes each hop on every venue the vault can reach and takes the **best fill**:

| Venue                                 | How the vault calls it                                                                                                                                    |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Uniswap v3                            | SwapRouter02 `exactInputSingle`, quoted across fee tiers 1% / 0.3% / 0.05% / 0.01%                                                                        |
| Uniswap Universal Router              | Same pools; pulls via Permit2. Allow-listed at the factory.                                                                                               |
| Uniswap v3, two pools                 | SwapRouter02 `exactInput` through USDG, for tokens whose only pool is USDG-quoted                                                                         |
| Uniswap v2                            | SwapRouter02 `swapExactTokensForTokens` (it bundles the v2 router), quoted from pair reserves at 0.30%. Tokens whose only liquidity is a classic v2 pair. |
| Pons bonding curve                    | `PonsAdapter.curveBuy` / `curveSell` while an ETH launch is still on its curve                                                                            |
| Graduated Pons (Uniswap v4)           | `PonsAdapter.swapV4` against the PoolManager directly                                                                                                     |
| Pons launch paired with a Stock Token | `PonsAdapter.buyVia` / `sellVia`: WETH ↔ pair token on Uniswap v3, then the curve or v4 pool                                                              |

`PonsAdapter` is a stateless allow-listed "router". Vaults hold WETH; ETH-quoted Pons curves and v4 pools are native ETH, so the adapter wraps and unwraps at the edges, pulls only from `msg.sender`, and pays only `msg.sender`. It never keeps a balance. The vault's delta checks still apply on top.

### Tokens paired with a stock

Most memecoins on Robinhood Chain are launched against a **Stock Token** (GME, NVDA, AMC, MSFT…) rather than ETH: the pool holds the stock and the meme, and there is no ETH pool at all. Any wallet or bot that "buys with ETH" is really doing two swaps. The family does the same, in **one transaction**:

1. the vault hands WETH to `PonsAdapter.buyVia`;
2. the adapter swaps WETH → stock token on Uniswap v3 (directly, or through the deep WETH/USDG pool — whichever fills better);
3. the adapter spends the stock token on the token's Pons curve or v4 pool and the meme lands in the trust.

Selling is the mirror image (`sellVia`). The stock token exists only inside the adapter for the duration of the call; the trust ends up with the meme, not the stock, and pays no extra bookkeeping for the hop. The adapter checks the route starts at WETH and ends at the pair token the Pons factory has on record, so calldata cannot steer it anywhere else. A family that *wants* the stock itself just buys it directly: WETH → GME is an ordinary Uniswap v3 swap.

The trade panel tags these tokens `paired with gme` and the quote line shows the hop (`pons · uniswap v3 · via usdg → gme`). Two pools means two fees (the v3 tier plus the Pons hook or curve fee) and a little more price impact than an ETH launch; the expected output shown already includes both.

Pons v2 launches trade on a per-token bonding curve until they graduate into a Uniswap v4 pool `(pair, token, fee 0, tickSpacing 200, PonsV2MemeHook)` — the pair being ETH or the stock token. A 1% hook fee is taken on the output side after graduation. During the first seconds of a launch a **snipe tax** (keyed on the recipient — the vault) can apply; the trade UI warns and you can wait it out.

Without `PonsAdapter` configured, Pons tokens only route if a Uniswap v3 pool exists. If the trade panel says "no route", it tells you why: usually the pair token has no ETH or USDG pool yet, or the launch is between its curve and its pool.

## Slippage and min-out

Every swap has `minOut`. The UI quotes, then sends with a buffer the head picks on the trade tab: 1%, 5%, 10%, 15% (default — where Trojan, Axiom and Photon sit), 25%, 50%, or off. The choice is remembered per family in that browser. If the fill lands further under the quote than that, the transaction reverts and nothing moves. "Off" removes the price floor only; the vault still rejects any swap that returns nothing. Join legs use a fixed 1.5% plus `minShares` on the mint.

Slippage is not tax. Pons creator tax, curve fee, snipe tax and v4 hook fees are all inside the quoted number already (the curve math is reproduced to the wei; graduated pools are quoted through the v4 Quoter, which runs the hook). The buffer only covers price movement between quote and fill: other buyers hitting the same curve, a thin stock-token pool moving under a multi-hop route. Robinhood Chain has a single sequencer and no public mempool, so classic sandwich attacks are not the concern; a hot launch moving several percent a block is. Widen the buffer there, or expect reverts (you lose gas, nothing else).

## Market cap and charts

The `mc` next to a bag is the spot figure Dexscreener reports for the token's deepest pool (pool price × supply), so it is the same number a head sees on their screener. While a Pons token is still on its curve there is no pool to screen; the app then derives an mc from the bag's own mark, which runs a few percent under spot on a taxed token because it is an exit price. "in at $…" is always the family's entry price × supply.

Every bag, and any CA pasted into the buy tab, carries a chart link: the Pons launchpad page while the token is on its curve, the Dexscreener pair once it has graduated (or for anything that never went through Pons).

### The chart in the app

The token's chart is also drawn inside familio, with the family's own trades on it.

* **Where.** Crew see it next to the buy/sell card (the right column on the manage page, above the card in the family-page trade island); it follows whatever is about to be traded: the pasted CA on buy, the picked bag on sell. Members see it on the family page under the bags, one chip per bag plus recently sold tokens; tapping a bag bubble switches it.
* **Dots.** Every buy the family made is a hot dot, every sell a rose dot, placed on the bar the fill landed in at the fill price (clipped into that bar's range; several fills in one bar collapse into a dot with a count). The family's face is pinned above every dot (hot ring for a buy, rose for a sell, a count when fills stacked in one bar), so an entry or exit is found at a glance on a busy chart. Hovering the face or the bar shows "robinhood bought 80.2k DCA for 0.013 eth at mc $400k", who did it and the thesis. A dashed line marks the family's average entry while it holds. The dot appears the moment a fill confirms, with a short ring, and the newest fill is also written out under the chart ("robinhood bought 1.10m KORE for 0.00919 eth at mc $20.7k · 8m ago · by …") so nobody has to hover to read their own numbers.
* **Share card.** The `card` chip on the chart (crew and members) opens the share sheet with a 1200×630 card of this chart: candles, the family's dots with its face above them, the entry line, "family in" vs "now" and the move since entry, framed as a family card. The link is `/c/<family>/<token>` and its preview on X/Telegram is the same card, drawn at share time (`/api/og/chart/…`); the timeframe follows the one being viewed, or the tightest one that holds every trade, and a squeezed or scrolled chart shares exactly the window on screen (`?from=&to=` ride on the link). The sheet's `copy card` puts the picture on the clipboard and `save card` downloads it, both from the pixels already drawn — no second render. Outsiders of a private family get the market without the dots and "where the family got in is for the people riding in it."
* **Axis.** Low caps are read in market cap, so the axis shows mc whenever the supply is known; the `mc` / `price` chip switches it. Timeframes: 1m, 5m, 15m, 1h, 4h, 1d, remembered per browser.
* **Source.** Candles come from GeckoTerminal's Robinhood Chain feed (USD, priced in the token even on stock-paired pools) via `/api/v1/chart`, cached in the worker and at the edge (5–60s by timeframe), refreshed every 10s on the 1m chart and every 15s otherwise while the tab is visible. Dexscreener or GeckoTerminal picks the pool. GeckoTerminal publishes a bar one to three minutes after the chain and revises it afterwards, so once the pool's venue is known (Uniswap v2, v3 or v4, including graduated Pons pools) the newest bars are rebuilt from the pool's own `Swap` logs on every tick: a fill shows on the chart within seconds, ahead of the screeners. The last bar's price is also the mc every bag row on the page prints, so the chart and the rows agree with each other; "in at" is the family's entry and does not move. Pons launches have a second source: Pons's own market feed (15-second last-trade points for the curve and the graduated Pons pool), which we bucket into bars — first choice while the token is on its curve, the fallback when GeckoTerminal rate-limits us. The footer says "data by pons" when that is what you are looking at. Pons's fine feeds only look back an hour, so bars from earlier polls are kept per (pool, timeframe) in the worker and the edge cache and put back in front of each new window while the two meet; the 1m chart grows to its full 300 bars instead of always starting an hour ago. A token nobody indexes yet shows an empty state with the Pons/Dexscreener link.
* **Worth, live.** Under the chart: what the family's bag of this token is worth at the price on the chart (usd and quote, and the move on the family's entry), and for a connected member, what their slice of that bag is worth — both move with the bars, no hover needed.
* **Token links.** A token's own website, X, Telegram and Discord sit as small icons next to the chart link — on the chart header, the bag bubble and the trade tab's token rows. Dexscreener's token profile is the first source (teams fix their links there once they get serious after migrating); the Pons launch metadata (`getTokenInfo().socials`, on-chain) fills whatever it lacks and is the only source while the token is still on its curve. Cached in `family_tokens.links`, re-checked by the indexer every few hours.
* **Handling.** Scroll or pinch to squeeze time, drag either axis to squeeze it, or scroll with the pointer over the price axis to flatten or stretch the bars (double-click the axis to reset), and pull the handle under the chart to make it taller (remembered; double-click puts it back). Polls only append or revise the newest bars, so a squeezed or scrolled chart stays where you left it; until you touch the time axis the bars keep filling the chart when its box changes size.
* **Snap.** The camera chip copies the chart exactly as it is on screen — the window you scrolled to, the squeeze you set, the dots — as a png with a one-line header (token, mc or price, move, timeframe, family), to the clipboard, or as a download where the browser will not take images on the clipboard. The `card` is the designed share picture; the snap is the raw view for a quick paste into a chat.
* **Privacy.** Dots follow the feed's rule: an outsider looking at a private family gets the market chart without the family's trades.
* **Not there on purpose.** No indicators, no drawing tools. Charts are rendered with TradingView's Lightweight Charts, credited under the chart.

## Scaling in and out

Every press of the button is one `swap`. There is no built-in order splitting: a head who wants to scale into a position buys again with the size slider, and scales out the same way. Sells are uncapped per transaction; buys respect the family's single-buy cap.

## Thesis notes

`swap` and `distribute` take a `noteHash`. The head (or co-pilot) can also `pinNote`. The text lives off-chain (`family_notes`); only the hash is on-chain. The indexer stitches them back together for the feed and Telegram. Pinning is the "this is the current thesis" slot on the family page.

## Holder-fee rewards and airdrops

Third parties can push value at the vault (Pons-style holder-fee distributors, airdrops, router dust). The vault does not reject them.

* **Native ETH** is wrapped to WETH in `receive()`. On a WETH-quoted family that ETH becomes **pool quote**, shared by every member. On a USDG-quoted family it becomes a WETH bag the head can track or sell. A distributor that uses a 2300-gas `transfer()` cannot wrap; that call fails cleanly instead of stranding ETH.
* **ERC-20s** land as growth of a bag the vault already tracks, or as **strays** (untracked balances). Pushed WETH is deliberately *not* auto-tracked: 1 wei must not be able to add a bag and reshape the join ratio.

The head can **track** a stray (`trackToken`) so new joiners mirror it and every `leave` pays it, or **sell** it to quote (the whole proceeds count as profit). Members already own a pro-rata claim: `leaveWith(..., extra)` pays the stray out even if it was never tracked. The leave drawer does this automatically when it can.

`receive` emits `NativeReceived`. The indexer also watches ERC-20 `Transfer` into the vault in transactions where the vault itself emitted nothing, and records those as airdrops on the feed and in Telegram.

## Blocked tokens

The factory has a block list, and it is empty: Stock Tokens, the memes paired with them, and the stock rewards they pay out are all tradeable. If the UI ever says a token is blocked, the treasury has switched it off for a reason (exploit, legal order); no family can trade it until it is switched back on.

## Turbo mode (popup-free trading)

For heads and co-pilots who want to trade without a wallet popup every time. **Turbo is optional.** Normal trading still works — each buy or sell asks your wallet to sign.

### Who can arm it

The **head** or any **co-pilot**, from the trade panel. The vault provides a dedicated session-key mechanism via `setSessionKey(key, on)`, arming a browser key that trades on your behalf. Because it acts as the trader's own hand rather than adding a new crew member, the crew lock does not apply — turbo can be armed on any family, locked crew or not. (Families created on the previous contract version still use the legacy co-pilot key method and need an open crew.)

### How it works

1. The browser generates a **session key** (a fresh wallet) and stores it locally for this vault + your wallet.
2. You sign **twice** with your real wallet: once to arm the session key via `setSessionKey`, once to send it a little gas (0.002–0.01 ETH, pick a chip).
3. From then on, buys and sells in turbo mode are signed **locally** by the session key — no wallet popups until you turn turbo off or the key runs out of gas.

Top up gas from the same panel if a trade fails with "out of gas".

### What the session key can and cannot do

A session key can **only call `swap`**. It cannot distribute, change locks, pin notes, add co-pilots, or arm further keys, and it can never withdraw member funds. Swaps are attributed directly to the key's owner (the `Swapped.by` event field records you, not the key). The key is powerless the moment its owner stops being head or co-pilot. The head can revoke any trader's session key; owners can always revoke their own. The private key never leaves your browser; familio never sees it.

**The trade-off:** anyone with access to **this browser** while turbo is on can trade for the family — same as leaving your unlocked wallet on the desk. Turbo is for a machine you control, not a shared computer.

### Turning it off

**Turn off turbo** sweeps remaining gas from the session key back to your wallet (signed locally), then revokes the key via `setSessionKey(..., false)`. Trades go back to asking your wallet every time.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.familio.trade/the-product/trading.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
