이 페이지는 AI 자동 번역입니다. 모든 내용은 영문판을 기준으로 합니다.영문판 보기 →
Farm 명령어는 버전별로 다릅니다. v6의 Deposit은 v5 farm에서 호출할 수 없으며 그 반대도 마찬가지입니다. SDK는 farm의 프로그램 소유자를 읽어 버전을 판단합니다. 온체인 CPI의 경우 처음부터 올바른 프로그램 ID를 선택해야 합니다.
명령어 목록
| 목적 | v3 | v5 | v6 |
|---|
| Farm 생성 | CreateFarm | CreateFarm | CreateFarm |
| 사용자 ledger 추가 (암시적일 수 있음) | CreateUserLedger | CreateAssociatedLedger | Deposit에서 암시적 |
| 스테이크 | Deposit | Deposit | Deposit |
| 언스테이크 | Withdraw | Withdraw | Withdraw |
| 리워드만 청구 | N/A (Deposit 0 사용) | N/A (Deposit 0 사용) | Harvest |
| 생성 후 리워드 스트림 추가 | N/A | AddReward | AddReward |
| 기존 리워드 스트림 편집 | N/A | SetRewards | SetRewards |
| end_time 이후 리워드 재시작 | N/A | RestartRewards | RestartRewards |
| 미청구 리워드 예산 인출 (관리자) | N/A | WithdrawReward | WithdrawReward |
v3 및 v5에서 스테이크를 변경하지 않고 리워드를 청구하는 표준적인 방법은 amount = 0으로 Deposit을 호출하는 것입니다. 프로그램은 이를 순수 정산으로 처리합니다. v6에서는 명확성을 위해 명시적 Harvest를 도입했습니다.
SDK는 이 모든 것을 raydium.farm.deposit({ ... }) 등 뒤에서 추상화합니다. 다음 섹션에서는 수동으로 명령어를 구성해야 하는 통합자 (애그리게이터, 모니터링 도구, SDK 확장)를 위해 기본 계정 목록을 문서화합니다.
CreateFarm (v6)
새로운 v6 farm을 시작합니다.
인자
reward_info_count: u8 // 생성 시 리워드 스트림 수 (1..=5)
reward_infos: [
{
open_time: u64,
end_time: u64,
emission_per_second_x64: u128, // Q64.64
mint: Pubkey, // reward mint
token_program: Pubkey, // SPL 또는 Token-2022
}
]
계정 (요약, reward_info_count = 1의 경우)
| # | 이름 | W | S | 설명 |
|---|
| 1 | creator | W | S | 렌트 지불, farm 소유. |
| 2 | farm_state | W | | 새로운 FarmState 계정. |
| 3 | farm_authority | | | PDA [farm_id]. |
| 4 | staking_mint | | | |
| 5 | staking_vault | W | | authority의 ATA 또는 PDA vault로 생성. |
| 6 | staking_token_program | | | |
| 7 | reward_mint | | | |
| 8 | reward_vault | W | | 초기 예산을 수신합니다. |
| 9 | reward_token_program | | | |
| 10 | reward_sender_ata | W | | Creator의 reward mint에 대한 ATA; 이 명령어로 소모됨. |
| 11 | system_program | | | |
| 12 | token_program | | | |
| 13 | associated_token_program | | | |
| 14 | rent | | | |
사전조건
open_time > now, end_time > open_time.
creator ATA가 최소 emission_per_second_x64 × (end_time − open_time) / 2^64 개의 reward mint를 보유합니다.
staking_mint는 동결 권한이 없거나 동결 권한이 비활성화되어 있습니다.
사후조건
FarmState 초기화, total_staked = 0.
- 리워드 vault가 전체 스트림 예산으로 펀딩됨.
- Creator의 reward ATA가 해당 금액만큼 소모됨.
Deposit (v6)
스테이킹 민트의 amount를 스테이크합니다.
인자
계정
| # | 이름 | W | S |
|---|
| 1 | user | W | S |
| 2 | user_ledger | W | |
| 3 | farm_state | W | |
| 4 | farm_authority | | |
| 5 | staking_vault | W | |
| 6 | user_staking_ata | W | |
| 7..(7+n) | reward_vault_{i} | W | |
| … | user_reward_ata_{i} | W | |
| last−2 | system_program | | |
| last−1 | token_program | | |
| last | associated_token_program | | |
user_ledger가 존재하지 않으면 SDK는 CreateAccount 스타일의 ix를 앞에 추가합니다. v6 프로그램은 시스템 프로그램 계정이 주어지면 이를 지연 생성할 수도 있습니다. 남은 계정 패턴: 각 활성 리워드마다 (reward_vault, user_reward_ata)를 추가하여 정산이 지급될 수 있도록 합니다.
효과
- 각 활성 리워드 스트림에 대해 지연 업데이트 공식을 사용하여
reward_per_share_x64[i]을 새로고칩니다.
pending_i = user_ledger.deposited × reward_per_share_x64[i] / 2^64 − user_ledger.reward_debts[i]를 계산합니다.
reward_vault_{i}에서 user_reward_ata_{i}로 pending_i를 전송합니다.
user_staking_ata에서 staking_vault로 amount 스테이킹 민트를 전송합니다.
user_ledger.deposited += amount를 업데이트하고 reward_debts[i]를 다시 스냅샷합니다.
farm_state.total_staked += amount를 업데이트합니다.
사전조건
- 실제 스테이크의 경우
amount > 0 (v6은 amount = 0을 금지합니다 — 청구만의 경우 Harvest 사용).
user_staking_ata가 최소 amount를 보유합니다.
- 각 활성 리워드 vault가 이 사용자에게 빚진 pending 이상을 보유합니다.
Withdraw (v6)
amount를 언스테이크합니다.
인자
계정 — Deposit과 동일합니다.
효과 — Deposit과 동일한 정산을 수행한 후 스테이킹 민트를 사용자에게로 돌립니다: staking_vault → user_staking_ata. total_staked와 user_ledger.deposited 모두 감소합니다.
사전조건
amount ≤ user_ledger.deposited.
- Farm이 일시 중지되지 않았습니다.
Harvest (v6)
스테이크를 변경하지 않고 pending 리워드를 청구합니다.
인자 — 없음.
계정 — Deposit과 동일, 스테이킹 측 이동 없음.
효과 — reward_per_share_x64[i]을 새로고치고 pending_i를 지급하며 reward_debts[i]을 다시 스냅샷합니다. total_staked 또는 deposited에 변화 없음.
AddReward (v5/v6)
미사용 슬롯이 있는 기존 farm에 새로운 리워드 스트림을 추가합니다.
인자
reward_info: {
open_time: u64,
end_time: u64,
emission_per_second_x64: u128,
mint: Pubkey,
token_program: Pubkey,
}
사전조건
- 빈 슬롯이 존재합니다 (v6에서는
reward_info_count < 5, v5에서는 < 2).
open_time ≥ now (미래일 수 있음) 또는 open_time < now는 프로그램 버전이 허용하는 경우에만 가능합니다 — v6은 허용, v5는 허용하지 않음.
사후조건
- 새로운 스트림이 인덱스
reward_info_count에서 초기화되고 reward_info_count++됩니다.
- 리워드 vault가 호출자의 ATA에서 전체 스트림 예산으로 크레딧됩니다.
일반 오류 — 민트가 기존 슬롯과 충돌하면 RewardAlreadyExists.
SetRewards (v5/v6)
기존 리워드 스트림을 연장하거나 충전합니다. 민트를 변경할 수 없습니다. end_time을 단축할 수 없습니다. 실행 중인 경우 emission_per_second_x64를 낮출 수 없습니다.
인자
reward_index: u8
new_open_time: u64,
new_end_time: u64,
new_emission_per_second_x64: u128,
사전조건
- 스트림이 여전히 실행 중입니다 (
reward_state == 1).
new_end_time ≥ current end_time.
- 필요한 추가 예산
(new_emission × new_duration − already_emissioned)이 발신자의 ATA에 있고 명령어로 리워드 vault로 전송됩니다.
v5에서는 동등한 호출이 더 작은 인자 세트를 가진 SetRewards입니다 (활성 스트림에 대한 초당 변경 없음).
RestartRewards (v5/v6)
end_time이 지난 후 스트림을 재시작합니다. 개념적으로 이미 슬롯이 있는 민트에 대한 AddReward와 동일합니다.
인자 — 해당 인덱스에서 AddReward와 동일한 형태.
사전조건
reward_state == 2 (종료됨).
- 호출자는 슬롯의
reward_sender (v6) 또는 farm owner (v5).
WithdrawReward (v5/v6)
스트림이 종료되고 모든 스테이커가 청구할 기회를 가진 후 미청구 리워드 vault 잔액의 관리자 청소입니다.
인자
사전조건
- 스트림이 종료됨 (
reward_state == 2).
reward_total_emissioned == reward_claimed + vault_balance (현재 빚진 것이 없음).
효과 — 나머지를 reward_sender_ata로 이동합니다. 프로그램은 스테이커가 여전히 pending 청구가 있는 동안 인출하는 것을 방지하지 않습니다. 관리자는 지연 스테이커 대신에 먼저 청구하거나 청구하도록 해야 합니다. 조기에 청소하면 사용자가 미청구 리워드에 접근할 수 없습니다. 이를 조기에 호출하지 마세요.
v5 변형
Deposit / Withdraw는 v6과 동일한 형태이지만 최대 2개의 리워드 슬롯을 사용하고 reward_per_share는 u128입니다 (다른 기수를 가진 고정소수점).
CreateAssociatedLedger는 첫 Deposit 전에 필수 별도 호출입니다. v6은 이를 병합했습니다.
AddReward는 사용 가능하고 Harvest는 불가능합니다 (Deposit 0 사용).
v3 변형
- 단일 리워드 스트림.
AddReward 없음, 두 번째 슬롯 없음.
Deposit 0이 청구하는 유일한 방법입니다.
- 첫
Deposit 전에 CreateUserLedger를 호출해야 합니다.
상태 변화 매트릭스
| 명령어 | total_staked | user.deposited | reward_per_share | 리워드 vault |
|---|
CreateFarm | 0 | — | 0 | creator로 펀딩됨 |
Deposit(n) | +n | +n | 새로고쳐짐 | −pending (지급됨) |
Withdraw(n) | −n | −n | 새로고쳐짐 | −pending |
Harvest | — | — | 새로고쳐짐 | −pending |
AddReward | — | — | — | +new budget |
SetRewards | — | — | — | +delta budget |
RestartRewards | — | — | — | +budget |
WithdrawReward | — | — | — | −remainder |
다음 단계
출처: