Add Liquidity
Add tokens to a liquidity position in Ferra pools.
Methods
1. Add Liquidity by Amount
Specify exact liquidity amount to add:
import { clmmMainnet, initFerraSDK } from '@ferra-labs/clmm'
// Initialize SDK
const sdk = initFerraSDK({
...clmmMainnet,
network: 'beta',
fullNodeUrl: 'https://...',
wallet: '0x...'
})
const poolId = "0x17f11b892f27ba3797c7d0b15164c7873294ce3df44e287efc195c126b0afec6"
const pool = sdk.Pool.getPool(poolId)
const curSqrtPrice = new BN(pool.current_sqrt_price)
const tick_lower_index = -220
const tick_upper_index = 200
const slippageTolerance = new Percentage(new BN(5), new BN(100))
const totalAmount = '10'
const tokenPriceA = '0.2'
const tokenPriceB = '1'
const coinAmounts = ClmmPoolUtil.estCoinAmountsFromTotalAmount(
tick_lower_index,
tick_upper_index,
curSqrtPrice,
totalAmount,
tokenPriceA,
tokenPriceB
)
const amountA = toDecimalsAmount(coinAmounts.amountA.toFixed(6, Decimal.ROUND_UP).toString(), 6)
const amountB = toDecimalsAmount(coinAmounts.amountB.toFixed(6, Decimal.ROUND_UP).toString(), 6)
const tokenAmounts = {
coinA: new BN(amountA),
coinB: new BN(amountB),
}
const liquidity = ClmmPoolUtil.estimateLiquidityFromcoinAmounts(curSqrtPrice, tick_lower_index, tick_upper_index, tokenAmounts)
console.log('liquidity: ', liquidity.toString())
const { tokenMaxA, tokenMaxB } = adjustForCoinSlippage(tokenAmounts, slippageTolerance, true)
const addLiquidityPayloadParams: AddLiquidityParams = {
coinTypeA: pool.coinTypeA,
coinTypeB: pool.coinTypeB,
pool_id: pool.poolAddress,
tick_lower: tick_lower_index.toString(),
tick_upper: tick_upper_index.toString(),
delta_liquidity: liquidity.toString(),
max_amount_a: tokenMaxA.toString(),
max_amount_b: tokenMaxB.toString(),
pos_id: '',
rewarder_coin_types: [],
collect_fee: false,
}
const payload = await sdk.Position.createAddLiquidityPayload(addLiquidityPayloadParams)
printTransaction(payload)
const transferTxn = await sdk.fullClient.sendTransaction(sendKeypair, payload)
console.log('createAddLiquidityPayload: ', transferTxn)
2. Add Liquidity Fixed Token
Fix one token amount, calculate the other:
import { clmmMainnet, initFerraSDK } from '@ferra-labs/clmm'
// Initialize SDK
const sdk = initFerraSDK({
...clmmMainnet,
network: 'beta',
fullNodeUrl: 'https://...',
wallet: '0x...'
})
const poolId = '0x17f11b892f27ba3797c7d0b15164c7873294ce3df44e287efc195c126b0afec6'
const pool = sdk.Pool.getPool(poolId)
const lowerTick = TickMath.getPrevInitializableTickIndex(
new BN(pool.current_tick_index).toNumber(),
new BN(pool.tickSpacing).toNumber()
)
const upperTick = TickMath.getNextInitializableTickIndex(
new BN(pool.current_tick_index).toNumber(),
new BN(pool.tickSpacing).toNumber()
)
const coinAmount = new BN(100)
const fix_amount_a = true
const slippage = 0.01
const curSqrtPrice = new BN(pool.current_sqrt_price)
const liquidityInput = ClmmPoolUtil.estLiquidityAndcoinAmountFromOneAmounts(
lowerTick,
upperTick,
coinAmount,
fix_amount_a,
true,
slippage,
curSqrtPrice
)
const amount_a = fix_amount_a ? coinAmount.toNumber() : liquidityInput.tokenMaxA.toNumber()
const amount_b = fix_amount_a ? liquidityInput.tokenMaxB.toNumber() : coinAmount.toNumber()
const addLiquidityPayloadParams: AddLiquidityFixTokenParams = {
coinTypeA: pool.coinTypeA,
coinTypeB: pool.coinTypeB,
pool_id: pool.poolAddress,
tick_lower: lowerTick.toString(),
tick_upper: upperTick.toString(),
fix_amount_a,
amount_a,
amount_b,
slippage,
is_open: true,
rewarder_coin_types: [],
collect_fee: false,
pos_id: '',
}
const tx = await sdk.Position.createAddLiquidityFixTokenPayload(addLiquidityPayloadParams, {
slippage: slippage,
curSqrtPrice: curSqrtPrice,
})
const result = await sdk.fullClient.signAndExecuteTransaction({
transaction: tx,
signer: keypair
})
Important Notes
SDK automatically collects fees before adding liquidity
Excess tokens are returned to sender
Position must exist before adding liquidity
Cannot change position's tick range
Last updated