Skip to main content
For builders and auditors.

Limit order matching

Limit liquidity in a bin is grouped into numbered cohorts: one is open at a time, it seals at its first fill, and fills go oldest first, pro rata inside a cohort. For the app view, see Limit bid and Limit ask. Numbers on this page are illustrative.

Where a limit order lives

A limit order sits in one bin: bin=(maturity M, rate r, kind),kind∈{limit bid, limit ask}\text{bin} = (\text{maturity } M,\ \text{rate } r,\ \text{kind}), \qquad \text{kind} \in \{\text{limit bid},\ \text{limit ask}\} A limit order is one side, one rate, one maturity. It fills once and does not re-quote. Its LP tokens do not rebase.

Cohorts

A cohort is a numbered group of liquidity inside one bin. Ids count up from #1. A cohort is not a bin; one bin holds many cohorts over its life. The rules:
  1. One open cohort per bin. New liquidity always joins the open cohort.
  2. Seal at first fill. The moment the open cohort receives any fill, it seals. No new liquidity can join it.
  3. Next id opens. As soon as cohort kk seals, cohort k+1k + 1 opens for new deposits.
A bin with cohort #1 filled, cohort #2 part-filled and cohort #3 open; fills go oldest first and pro rata within a cohort

#1 filled, #2 part-filled, #3 open. Oldest first, pro rata inside a cohort.

Fill order

Across bins at the same maturity, the best rate fills first. At the same rate, the smallest spread fills first, so Recursive bins fill before Limit bins (a limit order counts as an infinite spread). Inside a Limit bin, a taker fill of size qq is matched as follows:
  1. Oldest cohort first. Take the lowest-id cohort that still has unfilled liquidity.
  2. Pro rata inside it. Every deposit in that cohort fills by the same fraction.
  3. Spill over. If qq is larger than what that cohort has left, it fills completely and the rest moves to the next cohort.
For a cohort with deposits djd_j and total D=∑jdjD = \sum_j d_j, a fill of qc≤Dleftq_c \le D_{\text{left}} fills each deposit by: Δj  =  qc⋅djD\Delta_j \;=\; q_c \cdot \frac{d_j}{D}

Consequence: at most one part-filled sealed cohort

Because fills are oldest first, the cohorts of a bin always look like this: #1,…,#(k−1)⏟fully filled#k⏟part-filled#(k+1)⏟open\underbrace{\#1, \dots, \#(k-1)}_{\text{fully filled}}\quad \underbrace{\#k}_{\text{part-filled}}\quad \underbrace{\#(k+1)}_{\text{open}} At most one sealed cohort is part-filled at any time. This keeps the accounting small: the bin only tracks one fill fraction in progress.

Worked example

A bid bin holds three cohorts, illustrative sizes in interest-side TBT: Alice holds 150 of the 600 in #3. She is filled pro rata: 200×150/600=50200 \times 150/600 = 50, the same 33% as everyone in #3.

Crossing protection

A limit order must not meet resting liquidity on the other side. So in the form:
  • A bid at or above the best ask is switched off.
  • An ask at or below the best bid is switched off.
rbid<rbest ask,rask>rbest bidr_{\text{bid}} < r_{\text{best ask}}, \qquad r_{\text{ask}} > r_{\text{best bid}} To trade at the market, use a market order in Fixed or Leverage instead. Crossing is also rejected on-chain, not only in the form.

Settlement at sync

A fill does not move tokens into your TimeBalance at once. It is recorded in the cohort, and the proceeds land in your TimeBalance at the next sync of your position. Until then, the Dashboard shows the cohort as “Filled · settles at sync”. Makers pay no taker fee: the fill happens at exactly the bin’s rate. See How it works.

Yield while waiting

An order holds real TBT while it waits, so it earns whatever that TBT earns:
  • An ask holds the principal side [P,M)[P, M). Before PP it earns nothing, but its present value D(P)−D(M)D(P) - D(M) rises as PP approaches (at unchanged rates). From PP it earns the vault’s yield on the full amount while it waits, and its present value 1−D(M)1 - D(M) runs down to 0 at MM.
  • A bid holds the interest side [M,∞)[M, \infty). That window has not started yet, so it earns nothing until MM. Its present value D(M)D(M) rises toward 1 as MM approaches.
Yield is always calculated on what the order actually holds: the part still waiting, and the proceeds of whatever has filled.

Removing

You can remove from an open or a sealed cohort:
  • Open: nothing filled; your side comes back to your TimeBalance.
  • Sealed, part-filled: the unfilled share comes back; the filled share lands at the next sync.
  • Fully filled: nothing to remove; the fill lands at the next sync.

At maturity

At maturity the bin stops quoting. An unfilled bid’s interest side becomes plain TimeBalance, TBT[Now,∞)\text{TBT}[\text{Now}, \infty), and keeps earning base yield. An unfilled ask’s principal side has run out at MM: it earned the vault’s yield over [P,M)[P, M) and nothing of it remains. There is no forced exit.

Recursive LP mechanics

A recursive bin holds both sides of one maturity and quotes a bid and an ask, with ask = bid × k; every round trip earns the spread, until maturity. For the app view, see Recursive. Numbers on this page are illustrative.

A two-sided bin

A recursive bin is (M, rbid, recursive)(M,\ r_{\text{bid}},\ \text{recursive}). It holds both sides of maturity MM: Unlike a limit order, the bin does not stop after a fill. Whatever a taker hands over becomes inventory on the other side, ready to be quoted back.

Multiplicative spread

The ask is the bid times a factor kk: rask=rbid⋅k,kmin⁡≤k≤kmax⁡r_{\text{ask}} = r_{\text{bid}} \cdot k, \qquad k_{\min} \le k \le k_{\max} On the tick grid this is a fixed number of ticks: k=1.0001Δk = 1.0001^{\Delta} for a spread of Δ\Delta ticks. A spread set this way means the same relative width at a 4% rate as at a 20% rate. kmin⁡k_{\min} and kmax⁡k_{\max} are set when the market is created, so each market can choose its own.
A bid below the market rate and an ask above it; a fill one way and then back earns the spread

Bid below, ask above. A round trip earns the gap.

The ratio of the two sides

A bin holds some amount of each side. Call them II (interest side) and QQ (principal side).
  • The first LP sets the ratio. In an empty bin, the first deposit fixes I:QI : Q. The form allows one side to stay at 100%.
  • Later LPs deposit at the current ratio. Typing one side gives the other.
  • Only trades move the ratio. A Fixed fill moves the bin toward the principal side; a Leverage fill moves it back.
Adding or removing liquidity never changes the ratio. Removing gives you your share of both sides as they stand, which can lean toward one side after recent fills.

A round trip earns the spread

Take one period of length tt (in years) and a fill of xx principal-side TBT.
  1. A Fixed taker fills the bid. The bin gives x rbid tx\,r_{\text{bid}}\,t interest side and takes xx principal side.
  2. A Leverage taker fills the ask. The bin gives the xx principal side back and takes x rask tx\,r_{\text{ask}}\,t interest side.
The principal side is back where it started. The interest side has grown by: ΔI  =  x (rask−rbid) t  =  x rbid (k−1) t\Delta I \;=\; x\,(r_{\text{ask}} - r_{\text{bid}})\,t \;=\; x\,r_{\text{bid}}\,(k - 1)\,t The round trip can run in either order. Makers pay no taker fee, so the bin keeps the full spread; the taker fee is charged on top, to the taker. Example. Bid 5%, k=1.05k = 1.05 so ask 5.25%, a 15-day period, x=10,000x = 10{,}000: ΔI=10,000×0.25%×15365≈1.03 USDS of interest side\Delta I = 10{,}000 \times 0.25\% \times \tfrac{15}{365} \approx 1.03 \text{ USDS of interest side} Each further round trip earns the same again.

Inventory risk

Between round trips, the bin carries whatever side it was last filled into. If rates move and the trip does not come back, the bin keeps that side:
  • After a bid fill, it holds more principal side: leverage over the period.
  • After an ask fill, it holds more interest side: a fixed rate.
See Risks and security.

Rebasing LP tokens

Recursive LP tokens rebase. They are a share of a bin whose contents change with every fill and earn yield over time. The bin’s yield stays inside the LP tokens. your share=your LP tokenstotal LP tokens×(I,Q)\text{your share} = \frac{\text{your LP tokens}}{\text{total LP tokens}} \times (I, Q) The LP token balance rebases on every swap against the bin.

LP sync

LP tokens and the bin sync together, on their own clock. An LP sync over the stretch from the last LP sync to Now pays two flat amounts from Now → ∞:
  1. More LP tokens: the bin’s yield, kept inside the bin.
  2. Base TBT into your TimeBalance.
Your TimeBalance then syncs on its own and adds its own flat amount on top. Both are net of the 5% performance fee.

At maturity

At MM the bin stops quoting. By invariant 4, the interest side TBT[M,∞)\text{TBT}[M, \infty) becomes TBT[Now,∞)\text{TBT}[\text{Now}, \infty): plain TimeBalance. It keeps earning the vault’s base yield. The principal side TBT[P,M)\text{TBT}[P, M) has run out; its yield over the period was paid through LP sync. There is no forced exit and nothing to do on the day.

Limit vs recursive, side by side

Last modified on November 3, 2026