This guide details how to pull liquidity from a Saros DLMM pool via your frontend. You can either partially decrease an existing position or close it entirely in one transaction.
Key steps:
Calculating the shares to remove
Calling the appropriate instruction
Decreasing a Position
To remove some liquidity from an existing position:
Calculate the shares to remove from each bin
Call the decrease_position instruction with these parameters
Example Code
import { PublicKey, SystemProgram } from "@solana/web3.js";
import { BN } from "@project-serum/anchor";
import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token";
// Define the shares to remove from each bin
// The number of shares must match the position width (upper_bin_id - lower_bin_id + 1)
const sharesToRemove = [
new BN(100000), // Shares to remove from bin 1
new BN(200000), // Shares to remove from bin 2
new BN(300000), // Shares to remove from bin 3
// ... and so on for each bin in the position
];
// Derive bin array PDAs
const [binArrayLowerPda] = PublicKey.findProgramAddressSync(
[Buffer.from("bin_array"), pairPda.toBuffer(), Buffer.from([0])],
program.programId
);
const [binArrayUpperPda] = PublicKey.findProgramAddressSync(
[Buffer.from("bin_array"), pairPda.toBuffer(), Buffer.from([1])],
program.programId
);
await program.methods
.decreasePosition(sharesToRemove)
.accounts({
pair: pairPda,
position: positionPda,
binArrayLower: binArrayLowerPda,
binArrayUpper: binArrayUpperPda,
tokenMintX: tokenMintX,
tokenMintY: tokenMintY,
tokenVaultX: tokenVaultXPda,
tokenVaultY: tokenVaultYPda,
userVaultX: userVaultXPda,
userVaultY: userVaultYPda,
positionTokenAccount: positionTokenAccount,
tokenProgramX: TOKEN_PROGRAM_ID,
tokenProgramY: TOKEN_PROGRAM_ID,
positionTokenProgram: TOKEN_2022_PROGRAM_ID,
user: wallet.publicKey,
})
.signers([wallet.payer])
.rpc();
To completely close a position and remove all liquidity:
When decreasing a position, you need to specify the number of shares to remove from each bin. The number of shares must match the position width (upper_bin_id - lower_bin_id + 1).
You can calculate the shares to remove based on:
The percentage of liquidity you want to remove
The current liquidity in each bin
Example Calculation
// Calculate shares to remove based on percentage
const calculateSharesToRemove = (position, percentageToRemove) => {
const positionWidth = position.upper_bin_id - position.lower_bin_id + 1;
const sharesToRemove = [];
for (let i = 0; i < positionWidth; i++) {
const currentShares = position.liquidity_shares[i];
const sharesToRemoveFromBin = currentShares.mul(new BN(percentageToRemove)).div(new BN(10000));
sharesToRemove.push(sharesToRemoveFromBin);
}
return sharesToRemove;
};
// Example: Remove 50% of liquidity from a position
const sharesToRemove = calculateSharesToRemove(position, 5000);