Skip to main content

Documentation Index

Fetch the complete documentation index at: https://sapi-7869507e.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Overview

This guide provides everything you need to integrate SAPI’s Dynamic Liquidity Market Maker (DLMM) into your protocol on Aptos. 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

Initialization

initialize(user: &signer, max_protocol_fee: u128)

Initializes the protocol. Must be called once by the deployer/admin. Parameters:
  • user: Signer account
  • max_protocol_fee: Maximum allowed protocol fee (u128)
This function must be called exactly once during protocol deployment.

Pool Management

register_pool(...) -> Object

Creates a new pool between two tokens with specific configuration. Parameters:
  • token_x, token_y: Object references for the token pair
  • active_bin_id: u32 - Starting active bin identifier
  • bin_step: u32 - Price difference between consecutive bins
  • base_factor: u128 - Base fee multiplier
  • protocol_share: u128 - Protocol fee percentage
  • filter_period: u64 - Time filter for volatility calculations
  • decay_period: u64 - Volatility decay time period
  • reduction_factor: u128 - Fee reduction factor
  • variable_fee_control: u128 - Dynamic fee control parameter
  • max_volatility_accum: u128 - Maximum volatility accumulator value
Returns: Pool object reference

Liquidity Operations

add_liquidity(...) -> (Object, FungibleAsset, FungibleAsset)

Adds liquidity across selected bins and returns an LP NFT and refunds. Features:
  • Handles slippage and bin adjustments automatically
  • Returns LP position NFT for tracking
  • Provides refunds for unused tokens
Returns:
  • LP position NFT object
  • Refunded token X
  • Refunded token Y

update_liquidity(...) -> (FungibleAsset, FungibleAsset)

Updates an existing position by adding more funds or adjusting bin allocations. Returns:
  • Refunded token X
  • Refunded token Y

withdraw_liquidity(...) -> (FungibleAsset, FungibleAsset)

Withdraws a portion of liquidity from a position based on percentages. Returns:
  • Withdrawn token X
  • Withdrawn token Y

remove_liquidity(...) -> (FungibleAsset, FungibleAsset)

Closes the position completely and withdraws all liquidity. Returns:
  • All remaining token X
  • All remaining token Y

Fee Management

claim_fees(...) -> (FungibleAsset, FungibleAsset)

Claims accumulated fees from a single LP position. Returns:
  • Claimed fees in token X
  • Claimed fees in token Y

claim_fees_multiple(...)

Batch version for claiming fees from multiple LP NFT positions simultaneously.

Trading Functions

swap_exact_x_for_y(...) -> FungibleAsset

Performs a swap from token X to token Y with exact input amount. Features:
  • Asserts minimum output amount
  • Handles multi-bin swaps automatically
  • Applies dynamic fees
Returns: Output token Y amount

swap_exact_y_for_x(...) -> FungibleAsset

Performs a swap from token Y to token X with exact input amount. Returns: Output token X amount

Error Codes

Understanding common error codes for debugging:
CodeErrorDescription
0EEXCEED_MAX_BIN_IDBin ID exceeds maximum allowed value
1EACTIVE_BIN_OUT_OF_SLIPPAGEActive bin moved outside slippage tolerance
2ELIQ_BELOW_DESIREDLiquidity amount below desired minimum
3EBIN_ID_TOO_SMALL_FOR_DIFFBin ID too small for the requested difference
4ENOT_POSITION_OWNERCaller is not the owner of the LP position
5EINSUFFICIENT_OUTPUT_AMOUNTSwap output below minimum required
6EINVALID_LENGTHInvalid array length in batch operations

Example Flow

Here’s a complete example of integrating DLMM into your protocol:

Step 1: Register a Pool

// Create APT/USDC pool with 25 basis points bin step
let pool = register_pool(
    apt_token,           // token_x
    usdc_token,          // token_y
    8388608,             // active_bin_id (starting price)
    25,                  // bin_step (0.25%)
    5000,                // base_factor
    1000,                // protocol_share (10%)
    1,                   // filter_period (1 second)
    5,                   // decay_period (5 seconds)
    5000,                // reduction_factor
    40000,               // variable_fee_control
    350000               // max_volatility_accum
);

Step 2: Add Liquidity

// Add liquidity with curve distribution
let (lp_nft, refund_x, refund_y) = add_liquidity(
    pool,
    user_signer,
    apt_amount,          // Amount of APT to deposit
    usdc_amount,         // Amount of USDC to deposit
    bin_ids,             // Array of bin IDs to provide liquidity
    amounts,             // Corresponding amounts for each bin
    min_apt_amount,      // Minimum APT to actually use
    min_usdc_amount,     // Minimum USDC to actually use
    deadline             // Transaction deadline
);

Step 3: Perform Swaps

// Swap exact APT for USDC
let usdc_out = swap_exact_x_for_y(
    pool,
    apt_amount,          // Exact APT input
    min_usdc_out,        // Minimum USDC output
    user_signer
);

Step 4: Claim Fees

// Claim accumulated trading fees
let (fee_x, fee_y) = claim_fees(
    lp_nft,              // LP position NFT
    user_signer
);

Integration Best Practices

Pool Configuration

Choosing Bin Steps

  • Stable pairs (USDC/USDT): Use smaller bin steps (1-10 basis points)
  • Volatile pairs (APT/ETH): 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
  • Protocol share: Typically 5-20% of total fees
  • 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

Gas Optimization

  • Use batch operations (claim_fees_multiple) when possible
  • Combine liquidity updates with fee claims
  • Plan bin selections to minimize cross-bin complexity

Error Handling

// Example error handling pattern
public fun safe_add_liquidity(...) {
    let result = add_liquidity(...);

    // Handle common errors
    if (error_code == ELIQ_BELOW_DESIRED) {
        // Adjust amounts and retry
    } else if (error_code == EACTIVE_BIN_OUT_OF_SLIPPAGE) {
        // Update bin selection based on current price
    }

    result
}

Router Integration

SAPI provides router integration for seamless multi-hop swaps and advanced routing:
use sapi_swap::router;

// Multi-hop swap through DLMM pools
let output = router::swap_exact_input_multihop(
    pools,               // Array of pool objects
    input_amount,        // Exact input amount
    min_output_amount,   // Minimum acceptable output
    user_signer
);

Testing Your Integration

Local Testing

  1. Deploy DLMM contracts to local testnet
  2. Create test pools with various configurations
  3. Test all liquidity and swap operations
  4. Verify fee calculations and distributions

Mainnet Preparation

  1. Audit all integration code
  2. Test with small amounts first
  3. Monitor gas costs and optimize
  4. Implement proper error handling and recovery

Support

Contact Integration Team

Get direct support for your integration project.

Next Steps

After completing your integration: