Skip to content

Commit 7f654c5

Browse files
committed
docs: correct the USDF / launchpad-currency model
USDF is the base reserve currency ("core mint"); launchpad currencies are the user-facing tradable tokens backed by USDF reserves (like memecoins backed by USDC). The docs previously framed them as parallel holdings, understating the backing relationship. - 06: add a "Currency model" section — USDF (MintMetadata with launchpadMetadata = null) vs launchpad currencies (non-null LaunchpadMetadata: liquidityPool, coreMintVault USDF backing, price/marketCap in USDF, sellFeeBps), on-chain bonding-curve price discovery, buy/sell against USDF via SwapPurpose, and the two distinct senses of "reserves" (pool backing vs the user's USDF balance). Adds a reserve/pool/token Mermaid diagram. - glossary: rewrite USDF, launchpad token, and swap; add core mint, bonding curve, liquidity pool/coreMintVault, reserves, MintMetadata/Token. - README: reframe the overview around USDF-as-reserve / launchpad-as-circulating. - features: align cash, tokens (buy/sell vs USDF), and currency-creator rows. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JRVfsXp4HDrDMy7Pbmw9fD
1 parent 0356acf commit 7f654c5

4 files changed

Lines changed: 100 additions & 16 deletions

File tree

docs/architecture/06-payments-and-operations.md

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# 06 — Payments & operations
22

33
Flipcash is **self-custodial**: the device holds the keys, derives Solana accounts,
4-
and signs every transaction locally. This document covers key management, the
5-
account model, the auth-state machine, and how a payment is actually submitted.
4+
and signs every transaction locally. This document covers the currency model, key
5+
management, the account model, the auth-state machine, and how a payment is actually
6+
submitted.
67

78
```mermaid
89
graph TD
@@ -18,6 +19,80 @@ graph TD
1819
User --> TxController --> Stream --> Backend
1920
```
2021

22+
## Currency model: USDF & launchpad currencies
23+
24+
Flipcash has **two kinds of currency**, and the relationship between them is the
25+
heart of the product:
26+
27+
- **USDF** is the **base / reserve currency** — a USD-pegged stablecoin. In code it
28+
is the *"core mint"*: `Mint.usdf`
29+
([`libs/encryption/keys/.../Mint.kt`](../../libs/encryption/keys/src/main/kotlin/com/getcode/solana/keys/Mint.kt)),
30+
modeled as a `MintMetadata` (alias `Token`) with **`launchpadMetadata = null`**.
31+
- **Launchpad currencies** are the **user-facing, tradable tokens** — the unit people
32+
actually create, buy, sell, and share. Each is a custom on-chain currency **backed
33+
by USDF reserves**.
34+
35+
> **Mental model:** launchpad currencies are to USDF what memecoins are to USDC on
36+
> Solana. USDF is the reserve everything is priced in and backed by; launchpad
37+
> currencies are what circulates socially.
38+
39+
A launchpad currency is a `MintMetadata` whose `launchpadMetadata` is **non-null**
40+
([`services/opencode/.../model/financial/MintMetadata.kt`](../../services/opencode/src/main/kotlin/com/getcode/opencode/model/financial/MintMetadata.kt)).
41+
`LaunchpadMetadata` describes the backing and pricing:
42+
43+
| Field | Meaning |
44+
|-------|---------|
45+
| `liquidityPool` | The on-chain bonding-curve pool. |
46+
| `mintVault` | Where the launchpad token itself is locked against the pool. |
47+
| `coreMintVault` | **Where USDF is locked against the pool — the on-chain backing/reserves.** |
48+
| `currentCirculatingSupplyQuarks` | Circulating supply; drives price via the curve. |
49+
| `price`, `marketCap` | Both denominated in **USDF** (`Fiat`). |
50+
| `sellFeeBps` | Sell fee in basis points (currently 1%). |
51+
52+
```mermaid
53+
graph LR
54+
User["User USDF balance<br/>(spendable reserve)"]
55+
Pool["Liquidity pool (bonding curve)"]
56+
Core["coreMintVault<br/>(USDF backing)"]
57+
MintV["mintVault<br/>(launchpad token)"]
58+
Token["Launchpad currency<br/>price = f(supply) in USDF"]
59+
60+
User -->|buy: USDF in| Pool
61+
Pool -->|tokens out| Token
62+
Token -->|sell: tokens in, −1% fee| Pool
63+
Pool -->|USDF out| User
64+
Pool --- Core
65+
Pool --- MintV
66+
```
67+
68+
**Price discovery is deterministic and on-chain.** `price = f(currentSupply)` is
69+
computed by a discrete bonding curve
70+
([`libs/currency-math/.../curves/DiscreteBondingCurve.kt`](../../libs/currency-math/src/main/kotlin/com/flipcash/libs/currency/math/internal/curves/DiscreteBondingCurve.kt));
71+
supply updates stream in via `LaunchpadReserveStateSnapshot` and `TokenCoordinator`,
72+
which recomputes balances and appreciation as the price moves. (This is separate
73+
from the **fiat** display rates in [04 — Networking](04-networking.md), which convert
74+
USDF to the user's local currency for display.)
75+
76+
**Buying and selling always goes through USDF.** `SwapPurpose`
77+
([`apps/flipcash/core/.../tokens/TokenSwapPurpose.kt`](../../apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/tokens/TokenSwapPurpose.kt))
78+
is either `Buy(mint, fundingSource)` or `Sell(mint)`, and the swap's counter-currency
79+
is `Mint.usdf`: a buy spends USDF to mint tokens (adding USDF to the pool's
80+
`coreMintVault`), a sell burns tokens for USDF (returning USDF, minus the 1% fee).
81+
Creating a currency (`CurrencyCreatorViewModel`) seeds an **initial USDF buy**
82+
(default ~$5, from a user flag) and hands the creator a cash bill of the new token.
83+
84+
**Sending/sharing carries any token.** A cash bill (`Bill.Cash`) holds whichever
85+
`Token` is selected — a launchpad currency *or* USDF. Launchpad currencies render as
86+
a custom bill (`renderAsBill = token.address != Mint.usdf`); USDF renders as plain
87+
cash.
88+
89+
> **Two senses of "reserves" — don't conflate them.** (1) The on-chain USDF locked in
90+
> a launchpad token's `coreMintVault` is the token's **backing**. (2)
91+
> `ReservesBalanceProvider.observeReservesBalance()`
92+
> `balanceForToken(Mint.usdf)` is the **user's own USDF balance**, i.e. the spendable
93+
> reserve they buy launchpad currencies with. Both are USDF, but one is pool-side
94+
> backing and the other is the user's wallet balance.
95+
2196
## Keys & cryptography
2297

2398
The crypto primitives live under `libs/encryption/*`:

docs/architecture/README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@ architectural concern; start here, then jump to the topic you need.
1414
## What Flipcash is
1515

1616
Flipcash is a **self-custodial mobile wallet** for instant, global, private
17-
payments. Users hold **USDF** (a USD stablecoin) and **launchpad tokens** (custom
18-
on-chain currencies). The signature interaction is a **device-to-device cash
19-
bill**: one phone renders an animated circular Kik Code on screen, another phone
20-
scans it, and a peer-to-peer handshake settles the payment. The app also supports
21-
contact/username sends, on-ramp funding (Coinbase, in-app purchase), token swaps,
22-
and on-chain withdrawals.
17+
payments. Its base reserve currency is **USDF** (a USD stablecoin); on top of it,
18+
users create, buy, sell, and share **launchpad currencies** — custom on-chain tokens
19+
**backed by USDF reserves** (think memecoins backed by USDC on Solana). Launchpad
20+
currencies are the unit that circulates socially; USDF is what they're priced in and
21+
redeemable for. The signature interaction is a **device-to-device cash bill** (which
22+
can carry a launchpad currency or USDF): one phone renders an animated circular Kik
23+
Code on screen, another phone scans it, and a peer-to-peer handshake settles the
24+
payment. The app also supports contact/username sends, on-ramp funding (Coinbase,
25+
in-app purchase), buying/selling launchpad currencies against USDF, and on-chain
26+
withdrawals.
2327

2428
Under the hood it talks to **two gRPC backends** — the Flipcash service
2529
(accounts, profiles, chat, activity) and the Open Code Protocol / OCP service

docs/architecture/features/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Two recurring shapes show up in the **Pattern** column:
3232

3333
| Feature | Purpose | Screen / ViewModel | Pattern & integration |
3434
|---------|---------|--------------------|-----------------------|
35-
| **cash** | Amount entry for a device-to-device cash bill | `cash/CashScreen.kt` · `…/internal/CashScreenViewModel` | **VM-driven**; combines token + balance + rate flows, emits `PresentBill`, calls `SessionController.showBill` |
35+
| **cash** | Amount entry for a device-to-device cash bill (sends the selected token — a launchpad currency or USDF) | `cash/CashScreen.kt` · `…/internal/CashScreenViewModel` | **VM-driven**; combines token + balance + rate flows, emits `PresentBill`, calls `SessionController.showBill` |
3636
| **scanner** | Camera capture of a peer's cash bill / QR | `scanner/ScannerScreen.kt` | Screen-local; uses `:ui:scanner`, routes scans through `Router.classify` |
3737
| **direct-send** | Send to a contact / phone number | `directsend/SendFlowScreen.kt` · `…/internal/SendFlowViewModel` | **Flow**; contact list + phone gate steps |
3838
| **withdrawal** | Withdraw funds on-chain | `withdrawal/WithdrawalFlowScreen.kt` · `withdrawal/WithdrawalViewModel` | **Flow** (`AppRoute.Transfers.Withdrawal`); entry → destination → confirmation |
@@ -44,8 +44,8 @@ Two recurring shapes show up in the **Pattern** column:
4444
| Feature | Purpose | Screen / ViewModel | Pattern & integration |
4545
|---------|---------|--------------------|-----------------------|
4646
| **balance** | Wallet balance across tokens | `balance/BalanceScreen.kt` · `…/internal/BalanceViewModel` | **VM-driven**; observes token balances + exchange rates |
47-
| **tokens** | Token info, selection, and swaps | `tokens/TokenInfoScreen.kt`, `tokens/SwapFlowScreen.kt`, `tokens/TokenSelectScreen.kt` | **Flow** for swap (`FlowRouteWithResult<SwapResult>`); screen-local for info/selection |
48-
| **currency-creator** | Create a launchpad currency | `currencycreator/CurrencyCreatorFlowScreen.kt` · `…/internal/CurrencyCreatorViewModel` | **Flow**; name → icon → info → processing steps |
47+
| **tokens** | Token info (price/market cap in USDF), selection, and buy/sell swaps against USDF | `tokens/TokenInfoScreen.kt`, `tokens/SwapFlowScreen.kt`, `tokens/TokenSelectScreen.kt` | **Flow** for swap (`FlowRouteWithResult<SwapResult>`, `SwapPurpose.Buy`/`Sell`); screen-local for info/selection |
48+
| **currency-creator** | Create a launchpad currency (USDF-backed), seeded by an initial USDF buy | `currencycreator/CurrencyCreatorFlowScreen.kt` · `…/internal/CurrencyCreatorViewModel` | **Flow**; name → icon → info → processing steps |
4949

5050
## D. Profile, settings & misc
5151

docs/architecture/glossary.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@ full story.
88

99
| Term | Meaning | See |
1010
|------|---------|-----|
11-
| **USDF** | The USD-pegged stablecoin users primarily hold and transact in. | [README](README.md) |
12-
| **Launchpad token / currency** | A custom on-chain currency (governed by an on-chain bonding curve) that users can create and trade, in addition to USDF. | [06](06-payments-and-operations.md) |
13-
| **Cash bill** | The animated, circular on-screen code that represents a payment for **device-to-device** transfer — one phone shows it, another scans it. | [README](README.md), [features](features/README.md) |
11+
| **USDF** | The USD-pegged **base / reserve** stablecoin (the "core mint"). Everything is priced in and backed by USDF; it is itself sendable. In code: a `Token` with `launchpadMetadata = null`. | [06](06-payments-and-operations.md) |
12+
| **Launchpad token / currency** | The user-facing, tradable currency people **create, buy, sell, and share** — a custom on-chain token **backed by USDF reserves** and priced by an on-chain bonding curve. Like a memecoin backed by USDC. | [06](06-payments-and-operations.md) |
13+
| **Core mint** | The codebase's name for USDF — the reserve currency that launchpad currencies are denominated in and backed by. | [06](06-payments-and-operations.md) |
14+
| **Bonding curve** | The on-chain formula that sets a launchpad currency's price from its circulating supply (`price = f(supply)`, in USDF). | [06](06-payments-and-operations.md) |
15+
| **Liquidity pool / `coreMintVault`** | A launchpad currency's bonding-curve pool; its `coreMintVault` holds the **USDF reserves** backing the token (vs `mintVault`, which holds the token). | [06](06-payments-and-operations.md) |
16+
| **Reserves** | Two senses: (1) on-chain USDF backing a token in its `coreMintVault`; (2) the **user's own USDF balance** (`observeReservesBalance()`) spent to buy launchpad currencies. | [06](06-payments-and-operations.md) |
17+
| **Cash bill** | The animated, circular on-screen code that represents a payment for **device-to-device** transfer — one phone shows it, another scans it. Carries any token (a launchpad currency or USDF). | [README](README.md), [features](features/README.md) |
1418
| **Kik Code** | The scannable code format rendered as a cash bill (captured via the camera scanner). | [07](07-design-system.md) |
1519
| **On-ramp** | Funding the wallet with fiat (Coinbase) or in-app purchase. | [04](04-networking.md), [06](06-payments-and-operations.md) |
16-
| **Swap** | Exchanging one token for another (e.g. via a launchpad currency's curve). | [03](03-navigation.md), [06](06-payments-and-operations.md) |
20+
| **Swap** | Buying or selling a launchpad currency **against USDF** (`SwapPurpose.Buy`/`Sell`); sells charge a ~1% fee. | [03](03-navigation.md), [06](06-payments-and-operations.md) |
1721
| **Withdrawal** | Moving funds on-chain to an external Solana address. | [features](features/README.md) |
1822

1923
## Identity, keys & accounts
@@ -40,7 +44,8 @@ full story.
4044
| **OCP / Open Code Protocol** | The gRPC backend for transactions, intents, swaps, and exchange rates (module `:services:opencode`). | [04](04-networking.md) |
4145
| **Flipcash service** | The gRPC backend for accounts, profiles, chat, and activity (module `:services:flipcash`). | [04](04-networking.md) |
4246
| **Intent** | A signed unit of money movement (transfer, remote send/receive, withdraw, swap, distribution) submitted over the `SubmitIntent` bidirectional stream. | [04](04-networking.md), [06](06-payments-and-operations.md) |
43-
| **Mint** | A Solana token mint address (`PublicKey` subtype); identifies a token such as USDF or a launchpad currency. | [06](06-payments-and-operations.md) |
47+
| **Mint** | A Solana token mint address (`PublicKey` subtype); identifies a token such as USDF (`Mint.usdf`) or a launchpad currency. | [06](06-payments-and-operations.md) |
48+
| **MintMetadata / Token** | The model for any currency (`MintMetadata`, aliased `Token`). A non-null `launchpadMetadata` makes it a launchpad currency; `null` means it's USDF (the core mint). | [06](06-payments-and-operations.md) |
4449
| **Protobuf / proto** | The Protocol Buffers contract; generated code lives in `:definitions:*:models` and is never hand-edited. | [13](13-protobuf-and-codegen.md) |
4550
| **NotifiableError** | Marker for errors that represent bugs (not user-caused) and should alert via Bugsnag/Slack. | [14](14-error-handling.md) |
4651

0 commit comments

Comments
 (0)