Each caper's profile page has a buy/sell panel against the curve. Slippage is implicit in the curve shape: every trade nudges circulation along the price curve, so large trades pay (or receive) progressively worse marginal prices the further they push toward fully sold. The Max button computes the exact gateway-decimal string for your full balance, so rounding matches what the ledger accepts.
The curve vault is permanent — tokens you sell return to the inventory vault and become available to the next buyer. There is no external liquidity provider and no separate AMM pool.
How a trade moves the vaults
Every caper holds two vaults behind its curve. A buy moves your XRD into the curve vault (the reserve that backs the token) and hands you tokens out of the inventory vault. A sell reverses both: your tokens go back into the inventory vault, and the curve vault pays you the XRD the curve's closed-form integral says you're owed at the current circulation. Because there is a single curve in both directions — no separate buy and sell curve, no bid–ask spread — the price you sell at is exactly the price the next buyer would have paid to reach that point. Selling pays the configured 0.5% trade fee – a stored field the protocol admin can rewrite anywhere in [0, 10%] through update_fees, not a constant, so read it live rather than off this page (see the FAQ) – to the base $XRD caper's treasury, which its own members claim at the canonical vote weight on exit rather than as a flat pro-rata split (and against a fixed 24bn denominator, since XRD's supply cannot be read on-ledger); buying pays its own 0.5% into the caper you buy (see Raising funds).
The two directions are not symmetric
The curve's cumulative-reserve function X(s) = K·N·[ln((1+√s)/(1−√s)) − 2√s] has a closed form, so a sell prices out exactly: the payout is X(s_before) − X(s_after), two evaluations and a subtraction, with no approximation in it anywhere. A buy is the inverse problem — given an amount of XRD, find the circulation that consumes it — and that inverse has no closed form. The contract solves it numerically instead, with a Newton iteration capped at 16 steps against a tolerance of 0.0000001 XRD.
The convergence test is deliberately one-sided. The loop breaks only when the residual sits at or below zero and no further from it than the tolerance, so an accepted answer always consumes slightly less XRD than was paid, never more. Rounding falls to the curve rather than the buyer, and a mint can come up short but cannot run over.
That asymmetry is not a rounding footnote — it has already produced a real defect. Newton's method on a convex function approaches the root from above, and the seed the solver starts from lands far above the true answer for a small payment on a mature curve: at half the supply sold, a 100 XRD buy seeds at s ≈ 0.649 against a true s ≈ 0.5000007. In that region the one-sided break can never fire, so the iteration has to reach the root inside its 16 steps or stop early and over-mint. An earlier version damped every step to at most one halving toward the domain floor, which was slow enough to exhaust the budget while still above the root. The damping was replaced with a hard floor, and the case is now pinned by a regression test named for it, tokens_bought_converges_for_small_payments_on_mature_curve, sweeping four circulation levels against payments from 0.01 to 10,000 XRD.
A round trip cannot pay out more than it took in
Because a single curve serves both directions, buying and immediately selling the same tokens returns the curve to exactly the point it started from. The question that matters for a numerically-solved buy is whether that round trip can ever hand back more XRD than it consumed. It cannot, and the contract pins it rather than assuming it: roundtrip_buy_then_sell_does_not_overshoot buys at four circulation levels, sells the same tokens straight back, and asserts the signed difference never exceeds 0.000001 XRD of dust in the seller's favour.
That bound holds before the trade fee, which then takes its 0.5% off the payout, so a real round trip always ends down. An instant buy-and-sell is the cheapest probe anyone can run at a solver that approximates in one direction, and the guarantee is that it extracts nothing.
Swapping and exiting
Two variants build on the same primitive. A swap sells one caper's token and buys another in a single transaction — you never touch XRD in between — letting you rotate a position from one caper to another directly. And beyond selling on the curve, holders have a second way out: the exit right lets you burn your tokens to redeem a participation-weighted share of the caper's treasury, sized by the same vote weight (t·v)/(V·T) that governs a ballot and consuming both your governance tokens and your vote tokens — a claim on the accumulated fees and investments, separate from the curve reserve. Between the curve and the exit, a caper holder is never locked in — though the two routes are open on different terms. The curve will always buy your tokens back. The exit asserts a non-empty vote-token bucket before it pays anything, so it is available only to holders who have voted at least once (leaving a caper).
What a swap actually costs
A swap looks like one action and is priced as two. The contract sells your tokens against the origin caper's curve, takes the sell-leg fee out of the proceeds, then hands the net XRD into a buy on the destination caper's curve — which charges its own fee off that amount as gross. Both legs fire, in different directions and into different treasuries:
- Sell leg, 0.5% — out of the XRD the origin curve pays, into the root
$XRDcaper's treasury. - Buy leg, 0.5% — off the XRD arriving at the destination curve, into that caper's own treasury.
Because the second fee is charged on what the first left behind, the two compound rather than add: the combined bite is 1 − 0.995² ≈ 0.9975%, not 0.5%. On top of that you walk two curves, down the origin's and up the destination's, and on a young destination caper the founder slice applies to the buy leg exactly as it would to a direct purchase. A swap saves you holding XRD in between and a second signature; it is a convenience, not a discount.
A sale nobody placed
Not every sale on a caper's feed comes from a holder. A caper's treasury can hold other capers' tokens — an INVEST proposal buys them on the target's curve — and a DIVEST proposal runs that trade backwards. Execution withdraws the voted-on amount of the target's token from this treasury, sells it into that caper's curve, and deposits the XRD back into this treasury, entirely inside the contract's own call frame, so the tokens never reach the worktop for an executor to skim.
From the receiving curve's side it is an ordinary sale in every observable respect: the same single curve, the same closed-form payout, the same 0.5% sell-leg fee into the root $XRD caper's treasury, and the same SellToken event on the trade feed carrying no divest-specific field. A holder watching the chart cannot tell one from a retail exit — the identifying record is the ProposalExecutedDivest event on the selling caper, not anything on the curve that absorbed the sale. Price impact is likewise unexceptional: a divest walks the curve down exactly as a same-size holder sale would.
Two guards matter to anyone pricing around it. The trade is frozen at settlement — execution withdraws exactly the amount the winning option named, and aborts outright if the treasury's holding has fallen below it since, because filling a smaller trade than the one that passed would break the frozen-winner contract. And $XRD is refused by name as a divest target, for the same reason it cannot be sold at all: it has no curve to sell into.
Read off execute_proposal_divest and sell_token_raw in contracts/logic/src/lib.rs, and treasury_withdraw / treasury_deposit on the state tier.
The one caper you cannot trade
The protocol's root $XRD caper — the one native XRD holders migrate into, and the one that collects every sell-leg fee in the system — has no bonding curve at all. All three trading entry points refuse it by name rather than failing incidentally: a buy is told to use migration instead, a sell is refused because governance tokens are non-salable, and a swap rejects $XRD as either side of the pair.
So the members whose treasury accrues the sell-side churn of every other caper have no curve to sell on themselves. The way in is migration from native XRD; the way out is the exit, which redeems a treasury share at the canonical vote weight (t·v)/(V·T). It is the same reason $XRD is the one caper whose exit divides by a fixed 24bn constant rather than a live float: XRD's on-ledger supply is untracked, and there is no curve to read a circulation off.
Everything above is read off buy_token_raw, sell_token_raw, swap, compute_tokens_bought_inner and compute_xrd_received in contracts/logic/src/lib.rs, and the vault and solvency invariants off buy_apply and sell_apply in contracts/core/src/caper_dao.rs.
Price impact, and how it compares to an AMM
A caper's price is a deterministic function of how many tokens are in circulation, so the cost of a trade is knowable before you sign it rather than discovered on execution — exactly for a sell, which prices off the curve's closed-form integral, and to within 0.0000001 XRD for a buy, which inverts that same integral numerically (see The two directions are not symmetric above). That is a different liquidity model from a constant-product AMM such as Uniswap, where price emerges from a reserve ratio (x·y=k) maintained by external liquidity providers. Three practical consequences follow:
- No liquidity to pull. The curve reserve is a permanent inventory vault owned by the caper, not third-party LP deposits that can be withdrawn — so depth never vanishes and there is no impermanent-loss risk borne by outside providers.
- No bid–ask spread. A single curve serves both directions, so the price you sell at is exactly the price the next buyer pays to reach that point — the only wedge is the 0.5% trade fee, not a market-maker's spread.
- Predictable slippage. Large orders still walk the curve and pay progressively worse marginal prices, but that impact is a fixed property of the curve shape rather than a function of who happens to be providing liquidity that block.
The comparison runs deeper than price impact. A constant-product pool quotes from a closed-form formula, a Curve or Balancer pool cannot, and a caper's buy side cannot either – so all three reach for a different numerical method to produce a number a trader can sign. Numerical pricing in AMMs and bonding curves reads those methods out of the deployed source of each.