Traderjoedex Liquidity Book: how price bins work
LFJ, formerly Trader Joe, uses Liquidity Book to divide a token pair's liquidity into bins with fixed exchange rates. A swap can execute at one bin's price while enough output liquidity remains there. If that liquidity is exhausted and input remains, execution continues at another available bin's price.
LFJ has announced a withdrawal-only transition for Liquidity Book on Monad, with existing positions remaining withdrawable. The same update describes its separate POE PropAMM as remaining operational on that network.
How is a bin's price determined?
Each Liquidity Book pair, called an
LBPair
, has an active bin ID and a
binStep
. The active bin identifies the price currently used for swaps. The bin step measures the increase in price between consecutive bins in basis points, so it determines the spacing of the pair's price levels.
The V2.2 bin-price relation connects a bin's ID to its price:
price = (1 + binStep / 10000) ** (binId - 8388608)
humanPrice = price * 10 ** (decimalsX - decimalsY)
The second line adjusts the mathematical price ratio for token decimals and expresses one token X in token Y. Token X and token Y are the assets in the pair's own ordering. The same bin ID can therefore represent different human-readable prices when the bin step or token decimals differ.
Several pools can contain the same two tokens with different bin steps. Their price spacing and liquidity distributions can differ, so the token pair alone does not identify a particular Liquidity Book pool.
What changes when a swap crosses bins?
A fixed exchange rate within a bin limits price impact within that bin. Crossing into another bin changes the rate applied to the remaining input. Swap fees still apply, and the variable fee can increase as a trade crosses more bins.
For a standard token-to-token exact-input swap through one
Liquidity Book
pair, the V2.2
LBRouter
implementation follows this order:
| Stage | Contract behavior |
|---|---|
| Transfer the input | The router transfers the input tokens from the caller to the selected pair before calling its swap function. |
| Start at the active bin | The pair begins with the active bin and the exchange rate associated with its ID. |
| Use the bin's liquidity | The swap exchanges input against available output at that bin's price. Fees are calculated on the amount traded in the bin. |
| Advance when necessary | If the bin's available output is exhausted while input remains, execution moves to the next nonempty bin in the swap direction. That bin's price applies. If no further bin is available while input remains, the V2.2 pair reverts the swap. |
| Deliver output and enforce the limit |
The pair sends the accumulated output to the designated recipient. The router reverts the transaction if the output is below
amountOutMin
, undoing the swap's transfers.
|
At pair level, a
getSwapOut()
simulation returns
amountInLeft
alongside the output and fee. A nonzero remainder identifies input that available liquidity could not exchange. The returned output therefore does not establish that the entire proposed input can be swapped.
How does bin placement change a liquidity position?
Liquidity above the current active bin consists of token X, while liquidity below it consists of token Y. The active bin can contain both assets. A position's placement determines where its liquidity can participate in swaps and which assets back its bin holdings as the active price moves.
For deposits,
deltaIds
selects bins relative to the active bin at execution. Positive offsets select bins above it and negative offsets select bins below it. The
distributionX
and
distributionY
parameters allocate the supplied assets across those bins; adding X below the active bin or Y above it causes a revert.
Because the active bin can move before a deposit executes,
activeIdDesired
and
idSlippage
define the acceptable movement in bin IDs. The V2.2 router reverts the deposit if the active bin ID at execution differs from the desired ID by more than the allowed tolerance.
Liquidity removal instead specifies absolute bin IDs and the amounts of
LBToken
to burn in each bin. Those amounts represent liquidity shares. The underlying token amounts depend on each selected bin's reserves and the share being removed.
Which router version manages the position?
Liquidity-management compatibility depends on the pair version. V2.0 positions require the V2.0 router for removal, V2.1 positions require the V2.1 router and the V2.2 router's liquidity functions target V2.2 pairs. An unchanged application binary interface does not establish compatibility between these versions.
Swap routing has a different scope: the V2.2 router supports paths through several pool versions. Its ability to use an older pool in a swap path does not extend its liquidity-management functions to that pool.
Which bins contribute fees or incentive rewards?
Swap fees are calculated per bin and, after any configured protocol share is deducted, distributed proportionally to liquidity providers in the bins used by the trade. Spreading a position across several bins therefore changes where that position can participate in trading and accrue those fees.
V2.2 also introduced hooks and
LBHooksRewarders
. These rewarders can base incentive rewards on the time that liquidity spends within a defined range around the active bin. That configured range is a separate reward condition from the fees generated by swaps through a bin.