> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 렌트와 회수 가능한 렌트

> Solana는 SIMD-0437에 따라 5단계에 걸쳐 렌트 면제 최소값을 90% 인하합니다. 각 단계 이전에 생성된 계정은 필요한 것보다 더 많이 보유하고 있습니다. 초과분이 무엇인지, 어떤 프로그램이 반환하는지, 그리고 이를 찾아 회수하는 방법을 알아봅시다.

<Info>
  **이 페이지는 AI 자동 번역입니다. 모든 내용은 영문판을 기준으로 합니다.**

  [영문판 보기 →](/solana-fundamentals/rent-and-reclaimable-rent)
</Info>

<Info>
  렌트는 수수료가 아니라 환불 가능한 보증금입니다. SIMD-0437은 모든 계정이 보유해야 하는 보증금을 5개의 독립적으로 제어되는 단계에 걸쳐 인하합니다. 각 단계 이전에 생성된 계정은 자신이 자금을 받은 잔액을 유지하므로, 각 단계마다 자금이 초과 조성됩니다. SPL Token과 Token-2022 프로그램은 계정을 닫거나 토큰 잔액을 건드리지 않고 `WithdrawExcessLamports`를 통해 그 차이를 반환할 수 있습니다. 아무것도 만료되지 않습니다. 초과분은 이동하기로 선택할 때까지 자신의 계정에 그대로 있습니다.
</Info>

Solana 계정이 어떻게 자금을 받는지 처음 배우는 경우 먼저 [계정 모델](/ko/solana-fundamentals/account-model)을 읽으세요.

## 렌트가 실제로 무엇인지

Solana의 모든 계정은 차지하는 공간 크기에 따라 정해진 SOL 보증금을 보유합니다. 이는 소비되지 않으며, 계정이 닫힐 때 전액 반환됩니다. 공식은 다음과 같습니다:

```
minimum_balance(data_len) = (ACCOUNT_STORAGE_OVERHEAD + data_len) × lamports_per_byte
```

`ACCOUNT_STORAGE_OVERHEAD`는 페이로드와 관계없이 모든 계정이 지불하는 고정 128바이트입니다. `lamports_per_byte`는 SIMD-0437이 변경하는 네트워크 전체 상수입니다.

표준 165바이트 SPL 토큰 계정은 따라서 항상 `(128 + 165) × 6,960 = 2,039,280` 램포트의 비용이 들었습니다. 이는 지갑이 연결된 토큰 계정을 열 때마다 차감되는 약 0.00203928 SOL입니다.

## SIMD-0437이 변경하는 것

SIMD-0437은 `lamports_per_byte`를 6,960에서 696으로 줄입니다. 이는 90% 감소이며, 5개의 별도 기능 게이트를 통해 롤아웃되어 검증자가 상태 증가 효과를 한 번에 하나씩 흡수할 수 있습니다.

| 단계     | `lamports_per_byte` | 원래 값에서 감소 | 165바이트 토큰 계정의 렌트 |
| ------ | ------------------- | --------- | ---------------- |
| — (원래) | 6,960               | —         | 2,039,280 램포트    |
| 1      | 6,333               | 9%        | 1,855,569 램포트    |
| 2      | 5,080               | 27%       | 1,488,440 램포트    |
| 3      | 2,575               | 63%       | 754,475 램포트      |
| 4      | 1,322               | 81%       | 387,346 램포트      |
| 5      | 696                 | 90%       | 203,928 램포트      |

단계 1은 2026년 9월 3일 메인넷에서 활성화되었습니다. 나머지 단계는 기능 게이트가 활성화될 때 적용됩니다. 일정을 변경될 수 있는 것으로 취급하고 하드코딩하지 말고 클러스터에서 실시간 값을 읽으세요.

<Note>
  SIMD-0437은 SIMD-0194에 의존하며, 이는 렌트 면제 임계값을 폐기하여 "기능 활성화 시 렌트 매개변수를 설정할 때 불필요한 부동소수점 연산을 피합니다". 실제로 `Rent` 시스바는 이제 `lamports_per_byte_year = 6,333`과 `exemption_threshold = 1.0`을 전달하며, 6,960을 생성한 이전의 `3,480 × 2` 분할 대신입니다. 이 두 필드를 직접 곱하지 마세요. `getMinimumBalanceForRentExemption`을 호출하고 클러스터가 답하도록 하세요.
</Note>

## 기존 계정이 너무 많이 보유하는 이유

상수를 낮추면 계정이 *필요로 하는* 것이 변합니다. 계정이 *가진* 것은 변하지 않습니다. 6,960 램포트/바이트로 자금을 받은 계정은 단계 1이 활성화된 후에도 그 잔액을 유지하므로, 초과 자금은:

```
excess = (128 + data_len) × (old_rate − new_rate)
```

단계 1 이후 165바이트 SPL 토큰 계정의 경우 이는 `293 × (6,960 − 6,333) = 183,711` 램포트, 즉 계정당 약 0.000184 SOL입니다. 확장을 포함하는 Token-2022 계정은 더 크므로 비례적으로 더 많이 보유합니다. 182바이트 계정은 `310 × 627 = 194,370` 램포트만큼 초과 자금이 조성됩니다.

개별적으로는 무시할 수 있는 양입니다. 수년에 걸쳐 수백 개의 토큰과 상호작용한 지갑은 이의 의미 있는 배수를 보유하고 있으며, 단계 5까지 각 165바이트 계정은 최소값 위에 1,835,352 램포트(약 0.00184 SOL)를 보유합니다.

## 초과분을 반환할 수 있는 계정

프로그램 소유 계정의 초과 램포트는 해당 프로그램에서만 이동할 수 있습니다. 계정을 닫지 않고 렌트를 회수할 수 있는지 여부는 전적으로 어떤 프로그램이 소유하는지에 따라 달라집니다.

<CardGroup cols={2}>
  <Card title="SPL Token과 Token-2022" icon="circle-check">
    둘 다 `WithdrawExcessLamports`를 노출합니다. 계정은 열린 상태로 유지되고, 토큰 잔액을 유지하며, 단순히 현재 최소값으로 떨어집니다.
  </Card>

  <Card title="그 외 모든 것" icon="circle-xmark">
    동등한 명령어가 없습니다. 렌트는 계정이 닫힐 때만 해제됩니다. 이는 자체 전제 조건이 있는 파괴적인 작업이며, 렌트 스윕이 아닙니다.
  </Card>
</CardGroup>

구체적으로, Raydium 사용자가 보유하는 계정 유형의 경우:

| 계정                   | 소유자                                           | 제자리에서 초과분을 반환할 수 있나요?                                     |
| -------------------- | --------------------------------------------- | --------------------------------------------------------- |
| SPL 토큰 계정            | `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA` | 예 — `WithdrawExcessLamports`                              |
| Token-2022 토큰 계정     | `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb` | 예 — `WithdrawExcessLamports`                              |
| 래핑된 SOL (네이티브) 토큰 계정 | 토큰 프로그램 중 하나                                  | 아니오 — 아래 참조                                               |
| CLMM 포지션             | Raydium CLMM                                  | 아니오 — 포지션이 닫힐 때 렌트 반환                                     |
| OpenBook v1 오픈 오더    | OpenBook v1                                   | 아니오 — `CloseOpenOrders`만 가능                               |
| OpenBook v2 오픈 오더    | OpenBook v2                                   | 아니오 — `close_open_orders_account`만 가능                     |
| 스테이크 계정              | 스테이크 프로그램                                     | 아니오 — SIMD-0490이 `rent_exempt_reserve`를 2,282,880 램포트로 고정 |

래핑된 SOL 계정은 유일한 토큰 프로그램 예외입니다. 이들의 램포트 잔액 *은* 토큰 잔액이므로, 두 프로그램 모두 `TokenError::NativeNotSupported`로 거부합니다. Token-2022는 그 경우를 위해 `UnwrapLamports`(판별자 45)를 추가했습니다. `@solana/spl-token`은 0.4.15부터 `createUnwrapLamportsInstruction`을 제공합니다. 렌트 스윕에서 네이티브 계정을 건너뛰고 의도적으로 처리하세요.

## `WithdrawExcessLamports` 명령어

두 토큰 프로그램의 명령어 열거형에서 판별자 **38**입니다. `spl-token-interface`에서:

```rust theme={null}
/// This instruction is to be used to rescue SOL sent to any TokenProgram
/// owned account by sending them to any other account, leaving behind only
/// lamports for rent exemption.
///
/// 0. `[writable]` Source Account owned by the token program
/// 1. `[writable]` Destination account
/// 2. `[signer]` Authority
/// 3. `..3+M` `[signer]` M signer accounts
WithdrawExcessLamports,
```

세 가지 속성이 지갑의 모든 계정에 대해 안전하게 실행할 수 있게 합니다:

* **금액을 받지 않습니다.** 프로그램이 `source.lamports − rent.minimum_balance(source.data_len())`을 직접 계산하므로, 계정을 현재 최소값 아래로 가져갈 수 없으며, 나중의 단계가 활성화될 때도 올바르게 유지됩니다.
* **아무것도 닫지 않습니다.** 계정은 데이터, 소유자, 토큰 잔액을 유지합니다.
* **멱등성입니다.** 이미 최소값에 있는 계정에 대해 실행하면 0 램포트를 이동하고 성공합니다.

동결된 토큰 계정도 여전히 적격입니다. 동결은 토큰 이동을 제한하지만 램포트는 제한하지 않습니다.

### 명령어 구축

`@solana/spl-token`은 이에 대한 빌더를 내보내지 않습니다. 0.4.15 기준으로 열거형 항목은 여전히 주석 처리되어 있습니다:

```ts theme={null}
// packages/spl-token/src/instructions/types.ts
export enum TokenInstruction {
    // ...
    TransferHookExtension = 36,
    // ConfidentialTransferFeeExtension = 37,
    // WithdrawalExcessLamports = 38,   // ← not exposed
    MetadataPointerExtension = 39,
    // ...
}
```

직접 인코딩하세요. 페이로드는 단일 판별자 바이트입니다:

```ts theme={null}
import { PublicKey, TransactionInstruction } from "@solana/web3.js";

export function createWithdrawExcessLamportsInstruction(params: {
  source: PublicKey;        // the token account holding excess lamports
  destination: PublicKey;   // where the excess goes — usually the wallet itself
  authority: PublicKey;     // owner of `source`, or the multisig account
  multiSigners?: PublicKey[];
  programId: PublicKey;     // TOKEN_PROGRAM_ID or TOKEN_2022_PROGRAM_ID
}): TransactionInstruction {
  const { source, destination, authority, multiSigners = [], programId } = params;
  return new TransactionInstruction({
    programId,
    keys: [
      { pubkey: source, isSigner: false, isWritable: true },
      { pubkey: destination, isSigner: false, isWritable: true },
      { pubkey: authority, isSigner: !multiSigners.length, isWritable: false },
      ...multiSigners.map((pubkey) => ({ pubkey, isSigner: true, isWritable: false })),
    ],
    data: Buffer.from([38]),
  });
}
```

각 계정의 자신의 `programId`를 전달하세요. SPL Token과 Token-2022 명령어는 트랜잭션을 공유할 수 있지만, 각각은 소스 계정을 소유한 프로그램으로 주소 지정되어야 합니다.

메인넷에서 측정한 결과, 명령어는 SPL Token 프로그램에서 270 컴퓨트 유닛, Token-2022에서 1,414 컴퓨트 유닛의 비용이 듭니다. 어느 쪽이든 무시할 수 있습니다. 실제 제약은 컴퓨트가 아니라 트랜잭션 크기입니다.

## 회수 가능한 계정 찾기

하드코딩된 비율에서 초과분을 도출하지 마세요. 클러스터에 각 계정이 지금 필요로 하는 것을 물어보세요. 그러면 같은 코드가 5개 단계 모두를 통해 계속 작동합니다:

```ts theme={null}
const [tokenResp, token2022Resp] = await Promise.all([
  connection.getTokenAccountsByOwner(owner, { programId: TOKEN_PROGRAM_ID }),
  connection.getTokenAccountsByOwner(owner, { programId: TOKEN_2022_PROGRAM_ID }),
]);
const raw = [...tokenResp.value, ...token2022Resp.value];

// one lookup per distinct account size — a wallet normally has two or three
const spaces = Array.from(new Set(raw.map(({ account }) => account.data.length)));
const minimums = new Map(
  await Promise.all(
    spaces.map(async (space) => [space, await connection.getMinimumBalanceForRentExemption(space)] as const),
  ),
);

const reclaimable = raw.filter(({ account }) => {
  // wrapped SOL carries its token balance as lamports — both programs refuse it.
  // The `is_native` COption tag sits at offset 109 in the token account layout,
  // which Token-2022 preserves before its extension data.
  if (account.data.readUInt32LE(109) === 1) return false;
  return account.lamports > minimums.get(account.data.length)!;
});
```

`getMinimumBalanceForRentExemption(0)`은 유용한 부채널입니다. 정확히 `128 × lamports_per_byte`를 반환하므로, 128로 나누면 `Rent` 시스바를 파싱하지 않고도 클러스터가 어느 롤아웃 단계에 있는지 알 수 있습니다.

## 배치: 한 트랜잭션에 몇 개가 들어가나요

각 `WithdrawExcessLamports` 명령어는 하나의 고유한 쓰기 가능 계정 키(컴파일된 메시지에서 32바이트)와 약 7바이트의 명령어 인코딩을 기여합니다. 목적지, 권한, 수수료 지불자는 모두 같은 지갑이므로, 그들 사이에 하나의 키만 비용이 듭니다.

1,232바이트 트랜잭션 제한에 대해, 컴퓨트 예산 명령어와 블록해시를 계산하면 대략 26개의 명령어가 들어갑니다. **트랜잭션당 20개**가 안전한 작동 수이며, 이것이 Raydium 자체 구현이 사용하는 것입니다. 회수 가능한 계정이 116개인 지갑은 따라서 6개의 트랜잭션으로 스윕하며, 각각 5,000 램포트 기본 수수료입니다.

경제학을 주목하세요. 수수료는 계정당이 아니라 트랜잭션당 청구됩니다. 더 적은 계정을 회수해도 비용이 덜 들지 않으므로, 부분 스윕은 추가 왕복을 정당화하기 위해 거의 가치가 없습니다.

## Raydium을 통한 회수

[raydium.io/reclaim-rent](https://raydium.io/reclaim-rent) 페이지는 연결된 지갑의 SPL Token과 Token-2022 계정을 스캔하고, 프로그램별로 분할된 총액을 표시하며, 배치 트랜잭션에서 모든 것을 스윕합니다. 스캔은 읽기 전용입니다. **모든 렌트 회수**를 누를 때까지 서명이 없습니다.

페이지는 의도적으로 토큰 계정만 다룹니다. 계정을 닫음으로써만 렌트를 해제할 수 있는 계정 유형은 사용 불가능으로 나열되지 않고 제외됩니다. 계정을 닫는 것은 다른 파괴적인 작업이기 때문입니다.

## SDK 데모에서 회수

<Info>
  **버전 배너.** 데모는 Solana mainnet-beta에 대해 `@raydium-io/raydium-sdk-v2@0.2.42-alpha`를 대상으로 하며, 2026년 9월에 검증되었습니다. `WithdrawExcessLamports`는 수동으로 인코딩되며 SDK 버전과 무관합니다. SDK는 트랜잭션 구축과 배치에만 사용됩니다.
</Info>

[`raydium-sdk-V2-demo/src/rent`](https://github.com/raydium-io/raydium-sdk-V2-demo/tree/master/src/rent)의 두 스크립트:

```bash theme={null}
# read-only: what can this wallet reclaim, and what would it be worth after all five steps
yarn dev src/rent/checkReclaimableRent.ts
yarn dev src/rent/checkReclaimableRent.ts <any wallet address>

# build, simulate (DRY_RUN = true by default), then send the batched sweep
yarn dev src/rent/reclaimRent.ts
```

`reclaimRent.ts`는 트랜잭션당 20개 계정으로 배치하고 모든 배치에 한 번에 서명합니다:

```ts theme={null}
const batches = chunk(report.accounts, ACCOUNTS_PER_TX);

const builtTxs = await Promise.all(
  batches.map(async (batch) => {
    const builder = new TxBuilder({
      connection,
      feePayer: owner.publicKey,
      cluster: raydium.cluster,
      owner: raydium.owner,
    });
    builder.addInstruction({
      instructions: batch.map((account) =>
        createWithdrawExcessLamportsInstruction({
          source: account.pubkey,
          destination: owner.publicKey,
          authority: owner.publicKey,
          programId: account.programId,
        }),
      ),
    });
    return builder.versionBuild({ txVersion });
  }),
);

// versionMultiBuild puts the calling builder's transaction first and appends
// extraPreBuildData after it, so batch 1 drives and batches 2..n follow in order
const [firstTx, ...restTxs] = builtTxs;
const { execute } = await firstTx.builder.versionMultiBuild({ txVersion, extraPreBuildData: restTxs });
const { txIds } = await execute({ sequentially: true });
```

전송하기 전에 시뮬레이션하세요. `accounts.addresses`를 사용한 `simulateTransaction`은 실행 후 램포트 잔액을 반환하며, 이는 산술이 클러스터가 실제로 수행할 것과 일치하는지 확인하는 가장 저렴한 방법입니다.

## 지금 회수할지 기다릴지?

둘 다 괜찮으며, 어느 쪽이든 차이는 작습니다:

* **초과분은 어디로도 가지 않습니다.** 자신의 계정에 그대로 있습니다. 아무것도 만료되지 않고, 아무것도 스윕되지 않으며, 마감일이 없습니다.
* **기다리면 복합됩니다.** 각 단계는 같은 계정에서 더 많이 해제하며, 단계 5 이후 한 번의 스윕은 오늘 한 번의 스윕과 같은 수수료가 듭니다.
* **지금 회수해도 나중 단계를 포기하지 않습니다.** 오늘 스윕한 계정은 단순히 현재 최소값에 있습니다. 다음 단계가 다시 초과 자금을 조성하고 다시 스윕할 수 있습니다.

초기 회수의 유일한 실제 비용은 기본 수수료이며, 기다리는 유일한 실제 비용은 램포트가 좀 더 오래 고정되어 있다는 것입니다.

## 추가 읽을거리

<CardGroup cols={2}>
  <Card title="SIMD-0437" icon="file-code" href="https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0437-incremental-rent-reduction.md">
    제안 자체 — 5개의 기능 게이트와 감소를 단계적으로 진행하는 근거입니다.
  </Card>

  <Card title="감소된 렌트" icon="book" href="https://solana.com/upgrades/reduced-rent">
    Solana의 롤아웃 페이지: 현재 단계, 일정, 새 계정에 대한 변경 사항입니다.
  </Card>

  <Card title="렌트 감소: 데이터 기반 분석" icon="chart-line" href="https://solana.com/news/rent-reduction-deep-dive">
    경제학과 단계적 롤아웃이 관리하도록 설계된 상태 증가 위험입니다.
  </Card>

  <Card title="계정 모델" icon="database" href="/ko/solana-fundamentals/account-model">
    Solana 계정이 어떻게 자금을 받고, 소유되고, 닫히는지 — 위의 모든 것에 대한 배경입니다.
  </Card>
</CardGroup>
