Overview
This guide provides everything you need to integrate SAPI’s Dynamic Liquidity Market Maker (DLMM) into your protocol on Aptos move. DLMM offers advanced liquidity management with bin-based architecture and dynamic fees.Quick Start Example
See a complete integration example with pool creation, liquidity provision,
and swapping.
Core Functions
Git SourceCreate Pool
router::register_pool_with_custom_params(...) -> Object<Pool>
Creates a new pool between two tokens with specific configuration.
Parameters:
token_x:Object<Metadata>- The first tokentoken_y:Object<Metadata>- The second tokenactive_id:u32- The active id of the pairbin_step:u32- The bin step in basis point, used to calculate log(1 + binStep / 10_000)base_factor:u128- The base factor derived from base fee and bin stepfilter_period:u64- The period (in seconds) during which volatility changes are smootheddecay_period:u64- The period (in seconds) over which accumulated volatility decaysreduction_factor:u32- The factor (bps) applied to gradually reduce variable fees over timevariable_fee_control:u32- The parameter controlling sensitivity of variable fee to volatilitymax_volatility_accum:u32- The upper bound for accumulated volatility before cappingprotocol_share:u128- The portion of swap fees (in bps) allocated to the protocol
Object<Pool>
Add Liquidity
router::add_liquidity(...) -> (Object<AptosToken>, FungibleAsset, FungibleAsset)
Adds liquidity across selected bins and returns an LP NFT and refunds.
Parameters:
pool_obj:Object<Pool>- The pool objectasset_x:FungibleAsset- The X token FAasset_y:FungibleAsset- The Y token FAdelta_ids:vector<u32>- The list of bin ids to add liquidityactive_id_desired:u32- The active id that user wants to add liquidityid_slippage:u32- The number of id that are allowed to slipdistribution_x:vector<u64>- The distribution of tokenXdistribution_y:vector<u64>- The distribution of tokenYamount_x_min:u64- The min amount of token X added to liquidityamount_y_min:u64- The min amount of token Y added to liquidityto:address- The address of the recipient where postion NFT is transferred
- LP position NFT object:
Object<AptosToken> - Refunded token X:
FungibleAsset - Refunded token Y:
FungibleAsset
- Returns transferrable LP position NFT Object for tracking
Update Liquidity in Position
router::update_liquidity(...) -> (FungibleAsset, FungibleAsset)
Updates an existing position by adding more funds.
Parameters:
lp:&signer- Owner of the position NFTtoken:Object<AptosToken>- The position NFT objectasset_x:FungibleAsset- The X token FAasset_y:FungibleAsset- The Y token FAdistribution_x:vector<u64>- The distribution of tokenXdistribution_y:vector<u64>- The distribution of tokenYamount_x_min:u64- The min amount of token X added to liquidityamount_y_min:u64- The min amount of token Y added to liquidity
- Refunded token X:
FungibleAsset - Refunded token Y:
FungibleAsset
Withdraw Liquidity from Position
withdraw_liquidity(...) -> (FungibleAsset, FungibleAsset)
Withdraws a portion of liquidity from a position based on percentages.
Parameters:
lp:&signer- Owner of the position NFTtoken:Object<AptosToken>- The position NFT objectwithdraw_percentages:vector<u64>- Percentage per bin to withdrawwithdraw_token_x:bool- Whether to withdraw token Xwithdraw_token_y:bool- Whether to withdraw token Yamount_x_min:u64- The min amount of token X expected to receiveamount_y_min:u64- The min amount of token Y expected to receive
- Withdrawn token X:
FungibleAsset - Withdrawn token Y:
FungibleAsset
Remove Liquidity and Close Position
router::remove_liquidity(...) -> (FungibleAsset, FungibleAsset)
Closes the position completely and withdraws all liquidity.
Parameters:
lp:&signer- Owner of the position NFTtoken:Object<AptosToken>- The position NFT objectwithdraw_percentages:vector<u64>- Percentage per bin to withdrawamount_x_min:u64- The min amount of token X expected to receiveamount_y_min:u64- The min amount of token Y expected to receive
- All remaining token X:
FungibleAsset - All remaining token Y:
FungibleAsset
Claim Fees
router::claim_fees(...) -> (FungibleAsset, FungibleAsset)
Claims accumulated fees from a single LP position.
Parameters:
lp:&signer- Owner of the position NFTtoken:Object<AptosToken>- The position NFT object
- Claimed fees in token X:
FungibleAsset - Claimed fees in token Y:
FungibleAsset
Claim Fees Multiple
claim_fees_multiple(...)
Batch version for claiming fees from multiple LP NFT positions simultaneously.
Parameters:
lp:&signer- Owner of the position NFTtokens:vector<Object<AptosToken>>- The array of position NFT/Token to withdraw liquidity fromreceivers:vector<address>- The array of asset receivers
Swap exact token X for token Y
swap_exact_x_for_y(...) -> FungibleAsset
Performs a swap from token X to token Y with exact input amount.
Parameters:
pool_obj:Object<Pool>- The Pool Object to swap inasset_x:FungibleAsset- The asset X in to the poolamount_y_min:u64- The minimum amount of token Y expected to receive
FungibleAsset
Swap exact token Y for token X
swap_exact_y_for_x(...) -> FungibleAsset
Performs a swap from token Y to token X with exact input amount.
Parameters:
pool_obj:Object<Pool>- The Pool Object to swap inasset_y:FungibleAsset- The asset Y in to the poolamount_x_min:u64- The minimum amount of token X expected to receive
FungibleAsset
Swap token X for exact token Y
swap_x_for_exact_y(...) -> (FungibleAsset, FungibleAsset)
Performs a swap from token X to token Y with exact output amount.
Parameters:
pool_obj:Object<Pool>- The Pool Object to swap inasset_x:FungibleAsset- The asset X in to the poolamount_y_exact:u64- The exact amount of token Y to receive
- Output asset Y:
FungibleAsset - Remaining asset X:
FungibleAsset
Swap token Y for exact token X
swap_y_for_exact_x(...) -> (FungibleAsset, FungibleAsset)
Performs a swap from token Y to token X with exact output amount.
Parameters:
pool_obj:Object<Pool>- The Pool Object to swap inasset_y:FungibleAsset- The asset Y in to the poolamount_x_exact:u64- The exact amount of token X to receive
- Output asset X:
FungibleAsset - Remaining asset Y:
FungibleAsset
Example Flow
Here’s a complete example of integrating DLMM into your protocol:Step 1: Register a Pool
Step 2: Add Liquidity
Step 3: Perform Swaps
Step 4: Claim Fees
Integration Best Practices
Create Pool
Choosing Bin Steps
- Stable pairs (USDC/USDT): Use smaller bin steps (1-10 basis points)
- Volatile pairs (APT/USDT): Use larger bin steps (25-100 basis points)
- Meme tokens: Consider larger bin steps (50-200 basis points)
Fee Parameters
- Base factor: Start with 5000-10000 for most pairs
- Variable fee control: Higher values (40000+) for more dynamic fees
Liquidity Management
Monitoring Positions
- Track active bin movement relative to your positions
- Monitor impermanent loss vs fee earnings
- Consider rebalancing when price moves significantly
Testing Your Integration
Testnet Testing
- Create test pools with various configurations
- Test all liquidity and swap operations
- Verify fee calculations and distributions
Mainnet Preparation
- Audit all integration code
- Test with small amounts first
- Monitor gas costs and optimize
- Implement proper error handling and recovery