Add Liquidity
DLMM Base Function
The DLMM contract only provides two primitive methods: add_liquidity
(which generates an AddLiquidityCert
that must be repaid) and repay_add_liquidity
(which burns the AddLiquidityCert
).
/// Adds liquidity to an existing position.
///
/// This function adds liquidity to the specified bins of an existing position.
/// It handles composition fees for the active bin and updates both pool and position.
///
/// ## Type Parameters
/// - `CoinTypeA`: First token type in the pool
/// - `CoinTypeB`: Second token type in the pool
///
/// ## Parameters
/// - `pool`: Mutable reference to the pool
/// - `position`: Mutable reference to the position
/// - `bins`: Vector of bin IDs for liquidity addition
/// - `amounts_a`: Vector of token A amounts for each bin
/// - `amounts_b`: Vector of token B amounts for each bin
/// - `config`: Global configuration
/// - `versioned`: Versioned object for compatibility check
/// - `clk`: Clock for timestamp tracking
/// - `ctx`: Transaction context
///
/// ## Returns
/// - `AddLiquidityCert<CoinTypeA, CoinTypeB>`: Certificate with added amounts
///
/// ## Events Emitted
/// - `AddLiquidityEvent`: Contains position and liquidity delta information
public fun add_liquidity<CoinTypeA, CoinTypeB>(
pool: &mut Pool<CoinTypeA, CoinTypeB>,
position: &mut Position,
bins: vector<u32>,
amounts_a: vector<u64>,
amounts_b: vector<u64>,
config: &GlobalConfig,
versioned: &Versioned,
clk: &Clock,
ctx: &TxContext,
): AddLiquidityCert<CoinTypeA, CoinTypeB> {
...
}
/// Repays an add liquidity certificate.
///
/// ## Parameters
/// - `pool`: Mutable reference to the pool
/// - `position`: Mutable reference to the position
/// - `cert`: Add liquidity certificate
/// - `balance_a`: Balance of token A
/// - `balance_b`: Balance of token B
/// - `versioned`: Versioned object for compatibility check
///
/// ## Events Emitted
/// - `AddLiquidityEvent`: Contains position and liquidity delta information
public fun repay_add_liquidity<CoinTypeA, CoinTypeB>(
pool: &mut Pool<CoinTypeA, CoinTypeB>,
position: &mut Position,
cert: AddLiquidityCert<CoinTypeA, CoinTypeB>,
balance_a: Balance<CoinTypeA>,
balance_b: Balance<CoinTypeB>,
versioned: &Versioned,
) {
...
}
Add Liquidity in DLMM Router
You can either use the router contract's add liquidity method directly, or reference the DLMM router contract implementation to develop your own custom add liquidity method tailored to your specific requirements.
Contract Code
How to calculate bin id by price?Formula:
bin_id = log(price) / log(1 + bin_step/10000)
Explanation: The bin ID represents which price level (bin) a given price falls into within a geometric sequence. Each bin is
(1 + bin_step/10000)
times larger than the previous one, wherebin_step
is measured in basis points (1/10000). The logarithm calculates how many multiplicative steps are needed to reach the target price from the base price of 1.Example: If
bin_step = 20
(0.2%) andprice = 1.5
, thenbin_id = log(1.5) / log(1.002) ≈ 203
, meaning the price 1.5 is at the 203rd bin in the geometric price scale.
public fun add_liquidity<CoinTypeA, CoinTypeB>(
pool: &mut Pool<CoinTypeA, CoinTypeB>,
position: &mut Position,
coin_a: &mut Coin<CoinTypeA>,
coin_b: &mut Coin<CoinTypeB>,
bins: vector<u32>,
amounts_a: vector<u64>,
amounts_b: vector<u64>,
config: &GlobalConfig,
versioned: &Versioned,
clk: &Clock,
ctx: &mut TxContext,
) {
let add_liquidity_cert = pool::add_liquidity(
pool,
position,
bins,
amounts_a,
amounts_b,
config,
versioned,
clk,
ctx,
);
let (amount_a, amount_b) = add_liquidity_cert.amounts();
assert!(coin_a.value() >= amount_a, EAmountInNotEnough);
assert!(coin_b.value() >= amount_b, EAmountInNotEnough);
let (balance_a, balance_b) = (
coin_a.split(amount_a, ctx).into_balance(),
coin_b.split(amount_b, ctx).into_balance(),
);
pool::repay_add_liquidity(
pool,
position,
add_liquidity_cert,
balance_a,
balance_b,
versioned,
);
}
Last updated