DLMM Integration Guide
This guide covers the contract-level flow for Ramses DLMM pools. Start with DLMM & Liquidity Bins if bins, active IDs, or per-bin LP shares are unfamiliar.1. Discover a pool
A token pair may have multiple pools with different bin steps. Query the factory instead of assuming a single address:ignoredForRouting tells the official quoter to skip a pool. It does not delete the pool or prevent direct interaction.
For a known bin step, use:
tokenX and tokenY order controls swap direction, price, and valid liquidity composition.
2. Quote a swap
For a single pool:swapForY = true means token X is sold for token Y. A non-zero amountInLeft means the pool cannot completely fill the input.
For route discovery, DLMMQuoter.findBestPathFromAmountIn() and findBestPathFromAmountOut() compare all registered, non-ignored bin steps for each hop. The returned quote contains:
- The selected pool and bin step for every hop
Version.V2_1for each DLMM hop- Per-hop amounts and a fee fraction scaled by
1e18(1e18means 100%) - A virtual no-slippage amount for price-impact calculation
3. Execute through the router
Build a router path:V1 and V2 placeholders for path compatibility, but the current Ramses DLMM router executes Version.V2_1.
For an exact-input ERC20 swap:
4. Create a pool
Regular callers create a pool directly through:- The selected bin-step preset exists and is open
tokenYis already a whitelisted quote asset- Both token addresses are non-zero and the tokens are distinct
- The token pair and bin step do not already exist
activeIdproduces a valid price
AccessHub.createDLMMPool() route. That route can add the quote asset before creating the pool. Ordinary users should not wrap factory creation in AccessHub.execute().
Choose activeId from the intended starting price using the factory-compatible price helper. Reversing token order also reverses the price orientation.
5. Add liquidity
The router accepts:activeIdDesired and idSlippage, and calculates each destination bin as:
activeIdDesired to the active ID you just quoted and use deltaIds[i] = desiredBinAtQuote - activeIdDesired. Negative offsets are below the active bin; positive offsets are above it.
The distribution values are 1e18-scaled weights. To allocate all of a supplied token:
1e18; the unallocated amount is returned to refundTo. Over-allocation can revert and should be rejected before submission. Use an all-zero array when supplying none of that token.
Respect pool composition:
- Token Y can be assigned at or below the active bin
- Token X can be assigned at or above the active bin
- A two-sided range needs both tokens
addLiquidity() or addLiquidityNATIVE(). The router requires to == msg.sender, so the caller must receive the LP shares. Set refundTo explicitly: unused amounts go to that address, not automatically to to.
Adding an asset ratio to the active bin that differs from its existing composition performs an implicit composition swap and charges a fee. Amount minimums should account for this.
6. Remove liquidity
First authorize the router to burn the caller’s per-bin shares:7. Index positions and activity
DLMM positions are variable-length collections of per-bin balances. A practical index should keep:- One aggregate owner/pool position
- One owner/pool/bin balance row
- One pool/bin row with reserves and total supply
- Swap, deposit, withdrawal, and transfer activity
Do not treat a frontend’s bounded active-bin window as a complete ownership index. Positions can remain in bins far from the current price.
Final checks
Before submitting a transaction:- Confirm chain ID and deployed addresses.
- Confirm pool registration and token order.
- Read the current active ID, fees, and hook parameters.
- Require a complete quote.
- Set minimum amounts, ID slippage,
toequal to the caller, refund recipient, and deadline. - Simulate and estimate gas.
- Re-read state after confirmation.
