Skip to main content
In a Sauce program, swap with @sauce/router’s function for the venue (uniswapV2, uniswapV3, uniswapV4, curve, balancerV2, …; Slipstream, PancakeSwap V3 and Algebra pools through uniswapV3), with a minimum output and, where the pool takes one, a price limit (the @sauce/router reference; several pools under one limit, the distributed swap).
Liquidity Book DEX with variable-width bins for concentrated liquidity. Uses discrete price bins instead of continuous curves, allowing LPs to concentrate liquidity at specific price points. Native to Avalanche with expansion to Arbitrum and BSC.

What it offers

  • swap: Swap exact input tokens via Liquidity Book path routing

Notes

  • Path is a structured tuple {pairBinSteps, versions, tokenPath}, NOT a simple address array like Uniswap V2
  • Bin steps define price granularity: smaller bin steps = finer price precision but more gas, larger = coarser but cheaper
  • Common bin steps: 1, 2, 5, 10, 15, 20, 25 basis points
  • addLiquidity is complex: specify distribution across bins using deltaIds (relative bin offsets from active bin), distributionX and distributionY (percentage allocations per bin)
  • activeIdDesired: The bin ID you expect to be active; idSlippage: max deviation from desired active ID
  • Each LB pair is uniquely identified by (tokenX, tokenY, binStep)
  • Input token must be ERC20-approved to the LB Router
  • From a Pot program, @sauce/router swaps at an LB pair directly, with no router and no approval: traderJoeLB(pair, tokenIn, tokenOut, amountIn, tokenX, tokenY, minOut, recipient) reverts unless tokenIn and tokenOut are the pair’s X and Y, transfers the input to the pair and calls swap(swapForY, to) with swapForY = tokenIn == tokenX, returning the received lane of the packed amountsOut (X low, Y high). The pair spends the whole input or reverts LBPair__OutOfLiquidity, and a wrong swapForY reverts LBPair__InsufficientAmountIn. tryTraderJoeLB asks getSwapOut first and pushes only when nothing would be left over, returning 0 otherwise. The traderJoeLBSwap action is the same call

Its names in a program

On BNB Chain, TraderJoe is a namespace: its contracts need no import.

Deployments

ABI

Where a line says what an address it returns is, a program that calls the function through its namespace calls that contract’s methods on the result directly: <Namespace>.<Contract>.<function>(...).<method>(...). A token’s methods are the ERC-20 functions, and its writes are SafeERC20.

LBFactoryABI

import LBFactoryABI from "./protocols/trader-joe/LBFactoryABI.json"; Speaks for: lbFactory.
  • getLBPairInformation(address tokenA, address tokenB, uint256 binStep) view returns ((uint16 binStep, address LBPair, bool createdByOwner, bool ignoredForRouting) lbPairInformation): LBPair is a TraderJoe.LBPair

LBPairABI

import LBPairABI from "./protocols/trader-joe/LBPairABI.json";
  • getTokenX() pure returns (address tokenX): the address is a token
  • getTokenY() pure returns (address tokenY): the address is a token
  • getBinStep() pure returns (uint16)
  • getActiveId() view returns (uint24 activeId)
  • getReserves() view returns (uint128 reserveX, uint128 reserveY)
  • getBin(uint24 id) view returns (uint128 binReserveX, uint128 binReserveY)
  • getPriceFromId(uint24 id) pure returns (uint256 price)
  • getSwapIn(uint128 amountOut, bool swapForY) view returns (uint128 amountIn, uint128 amountOutLeft, uint128 fee)
  • getSwapOut(uint128 amountIn, bool swapForY) view returns (uint128 amountInLeft, uint128 amountOut, uint128 fee)
  • swap(bool swapForY, address to) returns (bytes32 amountsOut)

LBRouterABI

import LBRouterABI from "./protocols/trader-joe/LBRouterABI.json"; Speaks for: lbRouter.
  • swapExactTokensForTokens(uint256 amountIn, uint256 amountOutMin, (uint256[] pairBinSteps, uint8[] versions, address[] tokenPath) path, address to, uint256 deadline) returns (uint256 amountOut)
  • swapTokensForExactTokens(uint256 amountOut, uint256 amountInMax, (uint256[] pairBinSteps, uint8[] versions, address[] tokenPath) path, address to, uint256 deadline) returns (uint256[] amountsIn)
  • addLiquidity((address tokenX, address tokenY, uint256 binStep, uint256 amountX, uint256 amountY, uint256 amountXMin, uint256 amountYMin, uint256 activeIdDesired, uint256 idSlippage, int256[] deltaIds, uint256[] distributionX, uint256[] distributionY, address to, address refundTo, uint256 deadline) liquidityParameters) returns (uint256 amountXAdded, uint256 amountYAdded, uint256 amountXLeft, uint256 amountYLeft, uint256[] depositIds, uint256[] liquidityMinted)

Next steps