> ## 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.

# Farm / Staking 계정

> FarmState, UserStake / Ledger, 보상 금고 및 권한 PDA — farm v3, v5, v6의 레이아웃 및 PDA 시드.

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

  [영문판 보기 →](/products/farm-staking/accounts)
</Info>

<Info>
  **세 개의 프로그램, 세 가지 스키마.** Farm v3, v5, v6은 각각 별개의 프로그램으로 상태 레이아웃이 다릅니다. 이 페이지에서는 각 버전을 나란히 설명합니다. 실제로는 대부분의 새 통합이 v6을 대상으로 하며, v3와 v5는 대부분의 통합자에게 읽기 전용입니다(스테이킹이 훨씬 전에 완료되었고 풀이 폐지 단계에 있습니다).
</Info>

## 계정 목록 (각 farm, 모든 버전)

| 계정                                      | 소유자                  | 목적                                             |
| --------------------------------------- | -------------------- | ---------------------------------------------- |
| `FarmState`                             | Farm 프로그램 (v3/v5/v6) | 루트 상태: 스테이킹 민트, 총 스테이킹 규모, 보상 스트림.             |
| `farm_authority`                        | Farm 프로그램            | 스테이킹 금고와 보상 금고를 소유하는 PDA.                      |
| `staking_vault`                         | SPL Token            | 스테이킹된 LP(또는 스테이킹 민트)를 보유합니다.                   |
| `reward_vault_{i}`                      | SPL Token            | 보상 스트림 `i`의 미분배 예산을 보유합니다. 스트림당 하나씩.           |
| `UserStake` (v3/v5) / `UserLedger` (v6) | Farm 프로그램            | 각 `(farm, user)` 원장: 스테이킹 금액 + 스트림당 보상 대주 스냅샷. |

SDK는 `raydium.farm.getFarmById`에서 전체 세트를 반환합니다. 임의의 제3자 farm의 경우 API 엔드포인트 `GET https://api-v3.raydium.io/main/farms/info?ids=<FARM_ID>`도 이를 반환합니다.

## `FarmState` 레이아웃 — v6

v6은 현재 버전입니다. 가장 일반적인 계정 구조를 가지고 있습니다.

```rust theme={null}
// programs/farm_v6/src/state/farm.rs (abridged)
pub struct FarmState {
    pub state: u64,                // bitfield: 0 = live, 1 = paused, ...
    pub nonce: u64,                 // bump for farm_authority
    pub creator: Pubkey,            // original creator (can add rewards / transfer admin)
    pub staking_mint: Pubkey,
    pub staking_vault: Pubkey,
    pub staking_token_program: Pubkey, // SPL Token or Token-2022
    pub lp_mint_decimals: u8,
    pub reward_period_len: u64,     // minimum duration between SetRewards edits
    pub reward_period_min: u64,
    pub total_staked: u64,
    pub reward_info_count: u8,
    pub _reserved: [u8; ...],
    pub reward_infos: [RewardInfo; 5], // up to 5 reward streams
}

pub struct RewardInfo {
    pub reward_state: u8,           // 0 = unused, 1 = running, 2 = ended
    pub open_time: u64,             // start_time
    pub end_time: u64,
    pub last_update_time: u64,
    pub emission_per_second_x64: u128, // Q64.64 fixed-point rate
    pub reward_total_emissioned: u64,   // sum of emissions so far
    pub reward_claimed: u64,            // sum paid out to stakers
    pub reward_vault: Pubkey,
    pub reward_mint: Pubkey,
    pub reward_sender: Pubkey,          // who deposited the budget; can top up
    pub reward_token_program: Pubkey,   // SPL or Token-2022
    pub reward_per_share_x64: u128,     // Q64.64 counter
}
```

통합자를 위한 주요 필드:

* **`staking_mint`, `staking_vault`** — 스테이킹되는 토큰과 보관 위치.
* **`total_staked`** — 현재 총량. APR 계산에 필요: `reward_per_second × 86400 / total_staked`.
* **`reward_infos[i].emission_per_second_x64`** — Q64.64 형식의 율. 참 초당 토큰 수를 얻으려면 `2^64`로 나눕니다.
* **`reward_infos[i].open_time` / `end_time`** — UI "X일 남음" 표시용.
* **`reward_infos[i].reward_per_share_x64`** — `UserLedger` 부채가 차감되는 카운터.

## `FarmState` 레이아웃 — v5

```rust theme={null}
pub struct FarmStateV5 {
    pub state: u64,
    pub nonce: u64,
    pub lp_vault: Pubkey,            // aka staking_vault
    pub reward_vaults: [Pubkey; 2],
    pub owner: Pubkey,
    pub reward_mints: [Pubkey; 2],
    pub reward_total_emissioned: [u64; 2],
    pub reward_claimed: [u64; 2],
    pub reward_per_second: [u64; 2],  // integer, not fixed-point
    pub reward_open_time: [u64; 2],
    pub reward_end_time: [u64; 2],
    pub reward_per_share: [u128; 2],  // Q56.8 or similar; check program source
    pub total_staked: u64,
    pub last_slot: u64,               // v5 updates per-slot on mainnet
    pub _reserved: [u8; 256],
}
```

v6과의 차이점:

* **초당 단위 아님, 슬롯 단위.** v5의 업데이트 루프는 실시간 시계가 아닌 슬롯 단위로 실행됩니다. SDK는 UI용으로 이를 "초당"으로 정규화하지만 온체인 단위는 슬롯입니다.
* **정수 발행률.** `reward_per_second`는 `u64`입니다. 이는 최소 표현 가능 율을 초당 1 단위로 제한하며, 이는 9자리 민트의 저배출 스트림에는 너무 거친 단위입니다. v6은 Q64.64 율로 이를 해결했습니다.
* **`reward_sender` 없음.** v5에서는 소유자가 암묵적 발신자이며, 오직 `owner`만 보충할 수 있습니다.

## `FarmState` 레이아웃 — v3

```rust theme={null}
pub struct FarmStateV3 {
    pub state: u64,
    pub nonce: u64,
    pub lp_vault: Pubkey,
    pub reward_vault: Pubkey,          // single reward
    pub owner: Pubkey,
    pub reward_mint: Pubkey,
    pub reward_total_emissioned: u64,
    pub reward_claimed: u64,
    pub reward_per_slot: u64,
    pub reward_per_share: u128,
    pub total_staked: u64,
    pub last_slot: u64,
    pub _reserved: [u8; 256],
}
```

단일 보상. 슬롯 기반. 가장 오래된 프로그램 세대로, v5보다 이전의 RAY-USDC 및 SOL-USDC farm을 유지하기 위해 계속 사용됩니다.

## `UserLedger` (v6) / `UserStake` (v5/v3)

사용자별 상태, `(farm, user)` 쌍당 하나의 계정. 시드된 PDA:

```ts theme={null}
// v6
const [ledgerPda] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer(), user.toBuffer(), Buffer.from("user_stake_info_v2")],
  FARM_V6_PROGRAM_ID,
);

// v5
const [stakePda] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer(), user.toBuffer(), Buffer.from("user_stake_info")],
  FARM_V5_PROGRAM_ID,
);

// v3
const [stakePda] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer(), user.toBuffer(), Buffer.from("staker_info")],
  FARM_V3_PROGRAM_ID,
);
```

(시드 문자열은 SDK에서 실제로 사용되는 값이며, 프로그램 버전은 역사적으로 이를 변경해왔습니다. 보안이 중요한 경우 v6 소스에서 확인하세요.)

```rust theme={null}
// v6
pub struct UserLedger {
    pub version: u64,
    pub farm_id: Pubkey,
    pub owner: Pubkey,
    pub deposited: u64,                          // current stake
    pub reward_debts: [u128; 5],                 // snapshot of reward_per_share_x64 × deposited
}
```

스트림별 부채는 개요에 설명된 회계 오프셋입니다:

```
pending_for_stream_i = deposited × reward_per_share_x64[i] / 2^64  − reward_debts[i]
```

각 `Deposit`, `Withdraw`, 또는 `Harvest` 후, 부채는 현재 `deposited × reward_per_share_x64[i] / 2^64`로 재설정됩니다.

## 권한 PDA

```ts theme={null}
// v6
const [farmAuthorityV6] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer()],
  FARM_V6_PROGRAM_ID,
);

// v5
const [farmAuthorityV5] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer()],
  FARM_V5_PROGRAM_ID,
);

// v3
const [farmAuthorityV3] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer()],
  FARM_V3_PROGRAM_ID,
);
```

세 버전 모두 단일 시드로 farm당 farm 권한을 파생합니다. 이 PDA는 스테이킹 금고와 각 보상 금고의 권한입니다. farm이 수행하는 모든 전송에 서명합니다.

## 금고

스테이킹 및 보상 금고는 `owner`가 farm 권한 PDA인 표준 SPL Token 계정입니다. 주소는 `FarmState`에 저장됩니다 — 다시 파생하지 마세요, 상태에서 읽으세요. 동결 권한은 v5/v6의 스테이킹 민트에서 비활성화되어야 합니다(프로그램이 확인합니다).

Token-2022 참고:

* **v3**: SPL Token만 해당.
* **v5**: SPL Token만 해당.
* **v6**: `staking_token_program` / `reward_token_program` 필드를 기반으로 스테이킹 및 보상 민트 모두에서 Token-2022를 지원합니다. Token-2022 보상 민트의 전송 수수료는 발행 시 청구됩니다(금고 → 사용자).

## 관찰 및 APR

Farm은 온체인에 APR을 저장하지 않습니다. 계산하려면:

```
annualized_rewards_value_usd = reward_per_second × 86400 × 365 × reward_usd_price
tvl_usd                     = total_staked / 10^decimals × staking_mint_usd_price
apr                         = annualized_rewards_value_usd / tvl_usd
```

소비자는 일반적으로 LP가 속한 풀에서 `staking_mint_usd_price`를 가져옵니다(`api-v3.raydium.io/pools/info/ids` 경유) 그리고 `reward_usd_price`를 임의의 가격 오라클에서 가져옵니다.

## 다음 단계

* [`products/farm-staking/instructions`](/ko/products/farm-staking/instructions) — 버전별 명령어 참조.
* [`products/farm-staking/code-demos`](/ko/products/farm-staking/code-demos) — SDK를 통한 스테이킹, 수확 및 farm 생성.
* [`reference/program-addresses`](/ko/reference/program-addresses) — 세 프로그램 ID 모두.

출처:

* [Raydium SDK v2 `Farm` 모듈](https://github.com/raydium-io/raydium-sdk-V2)
* Farm v6 프로그램 소스는 현재 독립 실행형 리포지토리로 공개되지 않으며, IDL은 `raydium-io/raydium-sdk-V2`의 SDK에 번들되어 있습니다(`src/raydium/farm/` 아래).
