# 유동성 제거하기

### 개요 (Overview)

이 가이드는 프론트엔드에서 Saros DLMM 풀에서 유동성을 제거하는 방법을 설명합니다. 기존 포지션을 부분적으로 줄이거나, 한 번의 트랜잭션으로 완전히 종료할 수 있습니다.

핵심 단계 (Key steps):

1. 제거할 지분(shares) 계산
2. 적절한 인스트럭션 호출

### 포지션 줄이기 (Decreasing a Position)

기존 포지션에서 일부 유동성을 제거하려면:

1. 각 빈(Bin)에서 제거할 지분(shares)을 계산
2. 이 매개변수를 사용하여 `decrease_position` 인스트럭션 호출

#### **예시 코드 (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();

```

### 포지션 종료하기 (Closing a Position)

포지션을 완전히 종료하고 모든 유동성을 제거하려면:

1. &#x20;`close_position` 인스트럭션을 호출

#### 예시 코드 (Example Code)

```
import { PublicKey, SystemProgram } from "@solana/web3.js";
import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token";

// 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
  .closePosition()
  .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();

```

### 제거할 지분 계산하기 (Calculating Shares to Remove)

포지션을 줄일 때는 각 빈(Bin)에서 제거할 지분(shares) 수를 지정해야 합니다. 지분 수는 포지션의 폭(width)과 일치해야 합니다:(upper\_bin\_id - lower\_bin\_id + 1).

제거할 지분은 다음 기준에 따라 계산할 수 있습니다:

* 제거하려는 유동성의 퍼센티지
* 각 빈의 현재 유동성

#### **예시 수식식**

```
// 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);
```

* **Width:** 포지션 내 빈(Bin)의 개수
* **liquidity\_shares**: 각 빈의 기존 지분
* **percentageToRemove**: 제거할 비율 (예: 5000 = 50%)
