Getting started
Interaction goes through the Router — one contract that composes every flow. Setup is three one-time approvals; after that, every operation is a single call.
One-time setup
- Approve Permit2 for each token you will use — the canonical Permit2 contract is the only
ERC20 pull surface:
token.approve(PERMIT2, type(uint256).max); - Authorize the Router on Permit2 per token:
permit2.approve(token, ROUTER, amount, expiration); - If you will lend or borrow, authorize the Router on the lending contract once:
lending.setAuthorization(ROUTER, true); // or gasless via setAuthorizationWithSig (EIP-712)
First swap
router.swapExactIn(poolId, tokenIn, tokenOut, assetInIdx, assetOutIdx, amountIn, minAmountOut, you, deadline);Read the quote first through the Lens — previewSwapIn(poolId, assetInIdx, assetOutIdx, amountIn) — and set minAmountOut from it. Every mutating call takes a trailing deadline.
First liquidity position
router.addLiquidity(poolId, [tokA, tokB], [amountA, amountB], minLpShares, you, deadline);You receive pool shares (ERC6909). That's the whole workflow: the position is
always in range and fees accrue into it automatically
— there is nothing further to manage. Exit with removeLiquidity, or on star pools enter and
exit single-asset with zapIn / zapOut.
Where to go next
- Simple usage — the common operations, one page.
- Advanced usage — leverage, liquidations, permissioned markets.
- Developer — programmatic integration.