이 페이지는 AI 자동 번역입니다. 모든 내용은 영문판을 기준으로 합니다.영문판 보기 →
지시사항 요약
| 판별자 이름 | 서명자 | 동작 |
|---|---|---|
Initialize | 풀 생성자 | 두 개의 민트와 AmmConfig에서 새로운 CPMM 풀을 생성합니다. 누구나 호출할 수 있습니다(퍼미션리스). 새 풀에서 enable_creator_fee = false로 고정합니다. pool_state 계정은 정규 PDA 또는 새로운 무작위 키페어일 수 있습니다(Initialize 계정 참고). |
InitializeWithPermission | 지불자 + Permission PDA 보유자 | Initialize의 퍼미션 제어 변형입니다. 호출자(payer)는 자신의 공개키에서 파생된 Permission PDA를 소유해야 합니다. 풀 생성을 제한해야 하는 플랫폼에서 사용됩니다(예: LaunchLab 졸업). 호출자가 creator_fee_on(BothToken / OnlyToken0 / OnlyToken1)을 지정할 수 있으며, 새 풀에서 enable_creator_fee = true로 강제합니다. pool_state의 creator 필드는 지불자가 아닌 별도로 전달된 creator 계정으로 설정됩니다. pool_state에 대해 Initialize와 동일한 정규 PDA 또는 무작위 키페어 유연성이 있습니다. |
Deposit | LP | 두 토큰 모두에서 유동성을 추가합니다; LP 토큰을 받습니다. |
Withdraw | LP | LP 토큰을 소각합니다; 기초 토큰을 비례적으로 받습니다. |
SwapBaseInput | 스왑 수행자 | 정확한 입력 스왑(amount_in 입력, 최소 minimum_amount_out 출력). |
SwapBaseOutput | 스왑 수행자 | 정확한 출력 스왑(최대 maximum_amount_in 입력, amount_out 출력). |
CollectProtocolFee | protocol_owner(AmmConfig에서) | 금고에서 축적된 프로토콜 수수료를 수집합니다. |
CollectFundFee | fund_owner(AmmConfig에서) | 금고에서 축적된 펀드 수수료를 수집합니다. |
CollectCreatorFee | pool_creator | 축적된 생성자 수수료를 수집합니다(생성자 수수료가 활성화된 경우). |
UpdatePoolStatus | admin | 비트마스크를 통해 풀의 특정 작업을 일시 중지/재개합니다. |
UpdateAmmConfig | admin | AmmConfig의 수수료율 또는 프로토콜/펀드 소유자를 변경합니다. |
CreateAmmConfig | admin | 새로운 수수료 계층(새로운 AmmConfig 계정)을 생성합니다. |
CreatePermissionPda | admin | 특정 권한이 InitializeWithPermission을 호출할 수 있도록 하는 Permission PDA를 발급합니다. |
ClosePermissionPda | admin | 이전에 발급된 Permission PDA를 취소합니다. |
status는 u8이며, 비트 0 = 입금 비활성화, 비트 1 = 출금 비활성화, 비트 2 = 스왑 비활성화입니다(PoolStatusBitIndex { Deposit, Withdraw, Swap }). 클리어 비트는 작업이 허용됨을 의미하고, 설정 비트는 일시 중지됨을 의미합니다. UpdatePoolStatus는 원시 u8을 받고 기존 값을 덮어씁니다.
다음 섹션에서는 각각을 자세히 설명합니다. 계정 순서는 CPMM IDL을 따르며, SDK와 raydium-cp-swap/programs/cp-swap/src/instructions의 Rust 클라이언트가 이 순서와 일치합니다.
Initialize
새로운 CPMM 풀을 생성합니다.
인수
| # | 이름 | W | S | 설명 |
|---|---|---|---|---|
| 1 | creator | W | S | 렌트 지불; pool_state.pool_creator로 기록됨. |
| 2 | amm_config | 선택된 수수료 계층. | ||
| 3 | authority | CPMM 전역 권한 PDA. | ||
| 4 | pool_state | W | S* | 여기서 init됨. 정규 PDA ["pool", amm_config, token_0_mint, token_1_mint] 또는 새로운 무작위 키페어. 정규 PDA가 아닐 때, 프로그램은 pool_state가 서명하도록 요구합니다(require_eq!(pool_account_info.is_signer, true)). 무작위 키페어 경로를 통해 생성자가 정규 PDA에 대한 프론트러닝 시도를 회피할 수 있습니다. 다운스트림 PDA(lp_mint, vault, observation_state)는 어느 경우든 pool_state.key()에서 파생됩니다. |
| 5 | token_0_mint | 정렬됨: token_0_mint < token_1_mint. | ||
| 6 | token_1_mint | |||
| 7 | lp_mint | W | 여기서 init됨. 권한이 authority로 설정됨. | |
| 8 | creator_token_0 | W | init_amount_0에 대한 소스 ATA. | |
| 9 | creator_token_1 | W | init_amount_1에 대한 소스 ATA. | |
| 10 | creator_lp_token | W | LP의 목적지(누락된 경우 생성됨). | |
| 11 | token_0_vault | W | 여기서 init됨. authority가 소유. | |
| 12 | token_1_vault | W | ||
| 13 | create_pool_fee | W | 생성자가 지불하는 create_pool_fee에 대한 목적지 ATA. | |
| 14 | observation_state | W | 여기서 init됨. | |
| 15 | token_program | SPL Token (LP 민트용). | ||
| 16 | token_0_program | SPL Token 또는 Token-2022. | ||
| 17 | token_1_program | SPL Token 또는 Token-2022. | ||
| 18 | associated_token_program | |||
| 19 | system_program | |||
| 20 | rent |
* pool_state는 무작위 키페어 경로에서만 서명하며, 정규 PDA 경로는 pool_state 서명 없이 실행됩니다.
전제 조건
- 민트는 정렬됩니다(바이트 순서로
token_0_mint < token_1_mint). - 두 민트 모두 CPMM 허용 목록 외의 확장 프로그램을 사용하지 않습니다(
TransferFeeConfig,MetadataPointer,TokenMetadata,InterestBearingConfig,ScaledUiAmount) —products/cpmm/accounts참고. 프로그램 내의 작은 민트별 허용 목록은 케이별 온보딩을 우회합니다. creator는 각 ATA에 최소init_amount_0과init_amount_1이 있습니다.amm_config.disable_create_pool == false.
pool_state는lp_supply = sqrt(init_amount_0 * init_amount_1) − LOCKED_LP로 존재합니다.LOCKED_LP(LP 토큰 100 라마포)의 LP 스타터는 풀에서 영구적으로 잠깁니다 —pool_state.lp_supply는liquidity − 100을 기록하는 동안100LP 단위는 순환 외부에 남아있어 풀이 완전히 비워지는 것과 0으로 나누는 것을 방지합니다.observation_state가 초기화됩니다;observation_index = 0이고pool_id = pool_state.key().create_pool_fee라마포는 생성자에서 수신자로 전송되고 네이티브 SOL로 동기화됩니다(wSOL ATA입니다).- 풀의 상태 비트마스크는
0입니다(입금 / 출금 / 스왑 모두 활성화). enable_creator_fee = false이고creator_fee_on = BothToken.Initialize는 생성자 수수료 활성화를 지원하지 않습니다 — 그 경로는InitializeWithPermission입니다.open_time은 호출자가<= block_timestamp값을 전달한 경우block_timestamp + 1로 범프됩니다. 스왑은open_time전에 거부됩니다; 입금 및 출금은 즉시 작동합니다.
reference/error-codes에서)
InvalidInput— 민트가 정렬되지 않았거나 동일한 민트.NotSupportMint— 차단된 Token-2022 확장.ExceededSlippage— 드문 경우;init_amount_0/1이 소수점 자릿수 불일치로 인해 0 LP를 초래하는 경우.
Deposit
풀에 비례하여 두 토큰 모두에서 유동성을 추가합니다.
인수
| # | 이름 | W | S |
|---|---|---|---|
| 1 | owner | S | |
| 2 | authority | ||
| 3 | pool_state | W | |
| 4 | owner_lp_token | W | |
| 5 | token_0_account | W | |
| 6 | token_1_account | W | |
| 7 | token_0_vault | W | |
| 8 | token_1_vault | W | |
| 9 | token_program | ||
| 10 | token_program_2022 | ||
| 11 | vault_0_mint | ||
| 12 | vault_1_mint | ||
| 13 | lp_mint | W |
k의 비례성에는 변화가 없습니다 — 금고와 lp_supply 모두 동일한 계수로 확장됩니다.
사후 조건
lp_supply += lp_token_amount.vault_0 += needed_token_0(입력 시 Token-2022 이전 수수료 순).vault_1 += needed_token_1(입력 시 Token-2022 이전 수수료 순).
ExceededSlippage, ZeroTradingTokens, 입금이 일시 중지된 경우 InvalidStatus.
Withdraw
LP 토큰을 소각하고 기초 토큰을 비례적으로 받습니다.
인수
| # | 이름 | W | S |
|---|---|---|---|
| 1 | owner | S | |
| 2 | authority | ||
| 3 | pool_state | W | |
| 4 | owner_lp_token | W | |
| 5 | token_0_account | W | |
| 6 | token_1_account | W | |
| 7 | token_0_vault | W | |
| 8 | token_1_vault | W | |
| 9 | token_program | ||
| 10 | token_program_2022 | ||
| 11 | vault_0_mint | ||
| 12 | vault_1_mint | ||
| 13 | lp_mint | W |
Deposit과 동일합니다; lp_mint는 LP 토큰이 소각되기 때문에 쓰기 가능합니다.)
수학
lp_supply -= lp_token_amount.- 금고는
out_token_0/out_token_1을 전송합니다(총액; 사용자는 Token-2022 이전 수수료 순으로 받음).
SwapBaseInput
정확한 입력 스왑.
인수
| # | 이름 | W | S |
|---|---|---|---|
| 1 | payer | S | |
| 2 | authority | ||
| 3 | amm_config | ||
| 4 | pool_state | W | |
| 5 | input_token_account | W | |
| 6 | output_token_account | W | |
| 7 | input_vault | W | |
| 8 | output_vault | W | |
| 9 | input_token_program | ||
| 10 | output_token_program | ||
| 11 | input_token_mint | ||
| 12 | output_token_mint | ||
| 13 | observation_state | W |
token_0 / token_1이 아닌 사용자의 방향 입력 → 출력입니다. 프로그램은 민트를 일치시켜 어느 금고가 어느 것인지 파악합니다.
수학 — products/cpmm/math 참고.
전제 조건
open_time <= now.pool_status가 스왑을 허용함.- 이 권한에 대해 두 민트 모두 일시 중지되거나 동결되지 않음.
amount_in > 0.
ExceededSlippage—amount_out < minimum_amount_out.ZeroTradingTokens— 거래가 0으로 반올림됨.NotApproved— 풀이UpdatePoolStatus를 통해 스왑에 대해 일시 중지됨.InvalidInput— 민트가 풀의 금고 민트 중 하나와도 일치하지 않음.
SwapBaseOutput
정확한 출력 스왑.
인수
SwapBaseInput과 동일합니다.
수학 — 역 곡선과 함께 천정, products/cpmm/math 참고.
일반적인 오류 — ExceededSlippage(gross_in > max_amount_in), ZeroTradingTokens, InvalidInput, NotApproved.
CollectProtocolFee
금고에서 프로토콜 목적지로 축적된 프로토콜 수수료를 수집합니다.
인수 — 없음.
계정
| # | 이름 | W | S | |
|---|---|---|---|---|
| 1 | owner | S | amm_config.protocol_owner와 일치해야 함. | |
| 2 | authority | |||
| 3 | pool_state | W | ||
| 4 | amm_config | |||
| 5 | token_0_vault | W | ||
| 6 | token_1_vault | W | ||
| 7 | vault_0_mint | |||
| 8 | vault_1_mint | |||
| 9 | recipient_token_0_account | W | ||
| 10 | recipient_token_1_account | W | ||
| 11 | token_program | |||
| 12 | token_program_2022 |
protocol_owner이 아닌 경우 NotApproved.
CollectFundFee
CollectProtocolFee와 동일한 형태이지만 fund_owner가 서명하고 fund_fees_* 카운터를 0으로 설정합니다.
CollectCreatorFee
마찬가지로 동일한 형태이며 pool_state.pool_creator가 서명합니다. 풀이 0이 아닌 생성자 수수료율로 초기화된 경우에만 이전을 내보냅니다.
UpdatePoolStatus
풀의 개별 작업을 일시 중지하거나 재개합니다. status 필드는 비트마스크입니다:
| 비트 | 플래그 | 설정 시 효과 |
|---|---|---|
| 0 | DEPOSIT_DISABLED | Deposit가 NotApproved로 거부됨. |
| 1 | WITHDRAW_DISABLED | Withdraw가 거부됨. |
| 2 | SWAP_DISABLED | SwapBaseInput / SwapBaseOutput이 거부됨. |
| # | 이름 | W | S | |
|---|---|---|---|---|
| 1 | authority | S | CPMM 프로그램의 관리 키와 일치해야 함. | |
| 2 | pool_state | W |
security/admin-and-multisig 참고.
CreateAmmConfig
새로운 수수료 계층을 생성합니다.
인수
| # | 이름 | W | S | |
|---|---|---|---|---|
| 1 | owner | W | S | 관리자. |
| 2 | amm_config | W | 여기서 init됨. | |
| 3 | system_program |
- 동일한
index를 가진 기존AmmConfig가 없습니다. protocol_fee_rate + fund_fee_rate <= FEE_RATE_DENOMINATOR_VALUE.
UpdateAmmConfig
기존 AmmConfig의 수수료율 또는 소유권을 변경합니다. param: u8(어느 필드를 업데이트할지 판별자)과 value: u64를 사용합니다. 매개변수당 값 의미론은 소스에 있습니다; 일반적으로:
param = 0→trade_fee_rateparam = 1→protocol_fee_rateparam = 2→fund_fee_rateparam = 3→new_protocol_owner(Pubkey 바이트를 재해석으로 전달)param = 4→new_fund_ownerparam = 5→create_pool_feeparam = 6→disable_create_pool
AmmConfig에 바인드된 모든 풀에 영향을 줍니다. 마이그레이션 없음; 풀은 단순히 새 값을 읽습니다.
상태 변경 매트릭스
| 지시사항 | lp_supply | 금고 잔액 | 축적 수수료 필드 | observation |
|---|---|---|---|---|
Initialize | + init LP | + init_amount_{0,1} | 0 | init |
InitializeWithPermission | + init LP | + init_amount_{0,1} | 0 | init |
Deposit | + | + 둘 다 | — | — |
Withdraw | − | − 둘 다 | — | — |
SwapBaseInput | — | + in, − out | + trade_fee를 프로토콜/펀드로 분할; 활성화된 경우 + creator_fee | + (간격 경과 시) |
SwapBaseOutput | — | + in, − out | + trade_fee를 프로토콜/펀드로 분할; 활성화된 경우 + creator_fee | + (간격 경과 시) |
CollectProtocolFee | — | − (프로토콜 버킷별) | protocol_* → 0 | — |
CollectFundFee | — | − (펀드 버킷별) | fund_* → 0 | — |
CollectCreatorFee | — | − (생성자 버킷별) | creator_* → 0 | — |
UpdatePoolStatus | — | — | — | — |
다음 단계
products/cpmm/code-demos— 위의 실행 가능한 TypeScript 샘플.reference/error-codes— 완전한 Anchor 오류 테이블.products/cpmm/fees—CollectProtocolFee/CollectFundFee/CollectCreatorFee가 수집하는 수수료 축적 모델.

