# The price curve

The network's position counts the dollars that entered it, in {{unitUsd}} units. MLX per unit starts at {{genesisRate}} and halves at every doubling ({{doublingUsd}}), so the network price starts at {{genesisPrice}} and doubles each time. The protocol buys and sells MLX along this curve.

All of it is in `lib/chain/curve.ts`. The ledger's `swap` and `buy_node` handlers in `lib/chain/ledger.ts` apply it, and `lib/chain/walletpay.ts` plans a seat paid from the wallet.

## Supply

The supply is fixed at 10,000,000,000 MLX (`TOTAL_SUPPLY`), divisible to 6 decimals (`DECIMALS`). On the ledger, amounts are integers in base units, written as strings. All MLX was created at genesis in the five protocol accounts shown in the [overview](/protocol/overview#mlx-and-usdc). The curve creates no MLX. Spot buys are filled from `treasury.mlx`.

## Position

The position `u` is `stats.units` on the ledger: how many $100 units have entered the network.

| Event | Position |
| --- | --- |
| A seat is bought | moves forward by 50% of the seat's units (all of them before 29 Oct 2026, `seatCurveUnits`) |
| A seat is granted (Builder program) | doesn't move |
| A spot buy of `D` dollars | moves forward by `D / unit` |
| A spot sale | moves back by the units that would have minted that MLX, never below 0 |
| A seat paid partly with MLX | moves back by the sale, then forward by the seat |

The current position, price and halving progress are in `/api/curve`:

```endpoint try
GET /api/curve
```

## Rate and price

```text
D_k = length of doubling k             (DOUBLINGS, doublingLength)
b_k = D_0 + … + D_(k−1)                where doubling k starts (halvingAt)
k   = the doubling u is in             (epochOf)

rate(u)  = G · 2^−(k + (u − b_k) / D_k)    MLX per unit at position u
priceAt(u) = unit / rate(u)                dollars per MLX

unit = $100                      (UNIT_USD)
G = 10,000 MLX per unit       (GENESIS_RATE)
```

Doublings lengthen (curve v2, 29 Oct 2026): 200,000 ($20 million), then 300,000 ($30 million), then 400,000 ($40 million), then 500,000 ($50 million) for every doubling after. The rate halves once per doubling, smoothly, not in steps, and the price is continuous at every boundary. The network price starts at $0.01 and doubles every doubling. The first doubling is the same as before v2, and the network had not left it, so earlier transactions replay unchanged.

## The integral

A span of units `[u, u + m)` is worth the exact integral of the rate over it (`grant`):

```text
within doubling k:
grant(u, m) = (G · 2^−k · D_k / ln 2) · (2^(−(u − b_k) / D_k) − 2^(−(u + m − b_k) / D_k))
```

A span that crosses a boundary is summed doubling by doubling.

The integral is additive, so `grant(u, a) + grant(u + a, b) = grant(u, a + b)`: buying in one piece or many gets the same MLX. One pass along the whole curve is worth at most `G · H / ln 2` MLX (`CURVE_TOTAL`, also `curveTotal` in `/api/curve`). Because sales move the position back, a stretch of the curve can be paid again after a sale.

Dedicated seats bought before `SEAT_REWARD_END_AT` were paid `grant(u, units)` up front. Seats bought since are paid nothing up front. They still move the position, and so the price. See [Dedicated seats](/protocol/seats#what-a-seat-pays-up-front).

## Spot buys and sells

The protocol is the counterparty. It fills every spot order on the curve, from `treasury.mlx` (the `swap` transaction).

**Buy** with `D` dollars of USDC (or legacy USDT) at position `u`:

```text
m   = D / unit
MLX = grant(u, m) / (1 + buyPremium)          (buyQuote)
u  → u + m
```

**Sell** `X` MLX at position `u`:

```text
K   = G · 2^−k · D_k / ln 2                  within doubling k
a   = b_k − D_k · log2(2^(−(u − b_k) / D_k) + X / K)   the position where the curve would have paid exactly X
                                              (a sale that reaches b_k continues into doubling k − 1; never below 0)
USDC = unit · (u − a) · (1 − sellDiscount)    (sellQuote)
u  → a
```

Past position 0 the curve has nothing left to unwind, so a sale is paid only for the units that are there.

The defaults are a buy premium of 3% and a sell discount of 20% (`BUY_PREMIUM`, `SELL_DISCOUNT`). The live values can differ: they are set by the operator and published in `/api/stats` as `market`. Read them there, never from this page.

The ledger refuses a fill when:

- the amount is under its minimum (`SPOT_MIN_UNITS` in `lib/chain/spot.ts`);
- the treasury doesn't hold enough MLX for a buy, or enough USDC for a sale;
- the output is below the `minOut` the wallet signed (its slippage guard);
- a sale asks for more than the wallet's unlocked MLX. Locked MLX can't be sold.

Outputs are rounded down to whole base units. Spot-bought MLX is never locked.

To get the exact quote the ledger would fill right now, with its `minOut`:

```endpoint
GET /api/market/quote
```

| Parameter | Type | Notes |
| --- | --- | --- |
| `side` | `buy` or `sell` | required |
| `amount` | integer string | what goes in, in base units: USDC (or USDT) for a buy, MLX for a sale |
| `stable` | `USDC` or `USDT` | the coin a buy pays with; USDC when left out |
| `account` | wallet name | optional: also checks that wallet's balance |

See [Market](/network/market).

## Paying from the wallet

`buy_node` with `pay: "WALLET"` pays for a seat from the whole wallet (`planWalletPay` in `lib/chain/walletpay.ts`):

1. USDC first.
2. Then USDT, if any is left from before.
3. Then the fewest unlocked MLX that sell for the rest at the spot sell price (`mlxForUsd`).

The sale and the seat settle in one step. The MLX goes to `treasury.mlx`, and the dollars it fetches go straight to the seat, so no sell-side liquidity is drawn. The position moves back by the sale's units, then forward by the seat's units. The seat's record carries `sold: { mlx, usd }`.

The wallet runs the same plan in the browser and signs `maxMlx`: its quote plus a small margin (`maxMlxFor`). If the price moved and the plan needs more MLX than that, the ledger refuses with "The MLX price moved beyond your limit".

## Reading it

| What | Where |
| --- | --- |
| Position, price, next halving, seat rates | `GET /api/curve` |
| Live spread (`market`), position (`stats.units`), treasury liquidity | `GET /api/stats` |
| An exact quote | `GET /api/market/quote` |
| Supply and allocation | `GET /api/supply` |
