이 페이지는 AI 자동 번역입니다. 모든 내용은 영문판을 기준으로 합니다.영문판 보기 →
CPMM의 프로그램 ID와 PDA 시드는
reference/program-addresses에 정식으로 나열되어 있습니다. 이 페이지는 각 계정의 용도와 유지되는 불변성에 중점을 두며, 하드코딩된 주소는 다루지 않습니다.CPMM 풀의 6개 계정
모든 CPMM 풀은 CPMM 프로그램 아래의 6개 프로그램 파생 주소(PDA)와 이를 참조하는 1개의 공유AmmConfig 계정으로 완전히 설명됩니다. 두 개의 mint만 있으면 네트워크에 접근하지 않고도 모든 것을 결정론적으로 파생할 수 있습니다.
그리고 공유 설정:
두 개의 mint만으로 풀 파생하기
풀 ID가 항상 정식 PDA는 아닙니다.
Initialize는 위의 PDA 외에도 pool_state로 임의의 서명자 키페어를 허용합니다. 전달된 계정이 정식 PDA와 일치하지 않으면 프로그램은 이를 서명자로 요구합니다 — 즉, 생성자가 자신이 서명한 새로운 키페어를 전달합니다. 이것이 프론트런 방어입니다: 정식 PDA를 차지하려고 경쟁하는 제3자는 정당한 생성자가 대신 임의의 키페어를 사용하여 우회할 수 있습니다. 다운스트림 PDA(lpMint, vault0, vault1, observation)는 여전히 poolState.key()에서 파생되므로 사용된 주소에 관계없이 고유합니다. 풀을 인덱싱할 때 정식 PDA를 파생하여 풀 ID를 발견하지 말고 항상 온체인 상태에서 발견하세요(예: CPMM 프로그램 아래의 PoolState 계정) — 후자는 임의 키페어 풀을 놓칠 것입니다.계정 레이아웃
전체 Rust 정의는raydium-cp-swap 소스에 있습니다. 아래의 필드는 통합에서 읽을 필드입니다.
PoolState
lp_supply— LP mint의 총 공급량을 반영하는 풀의 내부 미러입니다. LP 공유 계산에 사용하세요. 값은 mint의 온체인 공급량과 일치해야 하지만PoolState에서 읽으면 추가 계정 페치를 피할 수 있습니다.protocol_fees_token{0,1},fund_fees_token{0,1}— 아직 수거되지 않은 누적된 수수료입니다. 이들은 스왑 가격에 영향을 주지 않습니다.CollectProtocolFee/CollectFundFee가 호출될 때까지 vault에 있습니다.status—Swap,Deposit,Withdraw가 허용되는지 제어하는 비트마스크입니다.UpdatePoolStatus를 통해 관리자가 업데이트합니다. SDK는 트랜잭션을 구축하기 전에 이를 확인합니다. 직접 CPI하는 경우 직접 확인하세요.token0_program/token1_program— 각 vault에 대해 CPI할 토큰 프로그램입니다. 하나는 클래식 SPL Token이고 다른 하나는 Token-2022일 수 있습니다. 이들은 독립적입니다.open_time— Unix 타임스탬프입니다. 이 시간 이전의 스왑은 실패합니다. 풀을 시드할 수 있도록open_time이전의 예치는 허용됩니다.creator_fee_on/enable_creator_fee— 함께 이 풀에 대해 선택적 생성자 수수료가 활성화되어 있는지 여부와 스왑의 어느 쪽에서 수거되는지를 제어합니다.enable_creator_fee == false는 생성자 수수료 경로를 완전히 0으로 만듭니다. 활성화되면creator_fee_on은 다음을 선택합니다:0= 스왑 입력인 토큰에서 수수료를 가져옵니다(BothToken);1=token_0에서만 수수료를 가져옵니다(token_1 → token_0스왑에서 건너뜁니다);2=token_1에서만 수수료를 가져옵니다.InitializeWithPermission을 통해 풀 생성 시 설정됩니다. 나중에 변경할 수 없습니다.creator_fees_token_{0,1}— 누적된 생성자 수수료이며CollectCreatorFee또는CollectCreatorFeePermissionless로 수거됩니다. 두 경로 모두 전체 카운터를 0으로 만듭니다. 무허가 경로는 수신자를pool_creator의 정식 ATA로 고정합니다.
AmmConfig
trade_fee_rate와creator_fee_rate는 거래량의 분수이며, 둘 다1/1_000_000단위로 표시됩니다.2500은 거래량의 0.25%를 의미합니다.protocol_fee_rate와fund_fee_rate는 거래 수수료의 분수(거래량이 아님)이며, 동일한1/1_000_000분모를 사용합니다. 생성자 수수료는 거래 수수료의 분수가 아닙니다 — 이는 자체 독립적인 비율입니다. 전체 산술은products/cpmm/fees에 있습니다.- **
index는u16**이므로 시드 해시는 2바이트 빅엔디안을 사용합니다. 바이트 순서의 오프바이원은 일반적인 통합 버그입니다. AmmConfig는 풀 수준에서 불변입니다. 풀은 생성 시 하나의AmmConfig를 가리키며 절대 전환하지 않습니다. 수수료 변경은 풀이 각 스왑에서 설정을 읽기 때문에 전파됩니다 — 하지만 풀은 수수료 계층 간에 이동할 수 없습니다.
creator_fee_rate)는 AmmConfig에 있으며 수수료 계층 전체에서 공유됩니다. 특정 풀이 실제로 이를 청구하는지(enable_creator_fee)와 스왑의 어느 쪽에 착지하는지(creator_fee_on)는 PoolState에 있습니다. 생성자 수수료는 거래 수수료와 독립적입니다 — 이는 자체 비율이며, 자체 카운터(creator_fees_token_{0,1})에 누적되며, LP / 프로토콜 / 펀드 거래 수수료 공유를 절대 줄이지 않습니다. 수거는 CollectCreatorFee 또는 대상 제약 CollectCreatorFeePermissionless를 통해 수행됩니다. 전체 메커니즘은 products/cpmm/fees를 참조하세요.
Permission
InitializeWithPermission에서 사용되는 작은 접근 제어 계정입니다. CPMM 프로그램은 다른 프로그램(예: 토큰을 CPMM으로 졸업할 때 LaunchLab)이 주어진 AmmConfig에 대해 풀을 생성할 자격이 있음을 증명할 수 있도록 허가된 풀 생성 경로를 지원합니다.
CreatePermissionPda를 통해 생성됩니다. CPMM 관리자만 ClosePermissionPda를 통해 이를 취소할 수 있습니다. 최종 사용자는 이 계정과 직접 상호작용하지 않습니다 — 이는 크로스 프로그램 흐름을 위한 배관입니다. 역할 경계는 security/admin-and-multisig를 참조하고 정식 주소는 reference/program-addresses를 참조하세요.
Vault 및 Token-2022
vault0과 vault1은 CPMM authority PDA가 소유하며, 이들의 토큰 프로그램 소유자(token_program)는 풀 생성 시 mint의 프로그램에 의해 결정되는 SPL Token 또는 Token-2022입니다. 풀은 두 경우를 투명하게 처리합니다 — Swap / Deposit / Withdraw 명령어 계정에서 각 쪽에 올바른 토큰 프로그램 ID를 전달합니다.
CPMM은 풀 생성 시 엄격한 확장 허용 목록을 적용합니다(utils/token.rs의 is_supported_mint). Token-2022 mint는 모든 확장이 이 목록에 있는 경우에만 CPMM 풀에서 사용할 수 있습니다:
TransferFeeConfig. 모든 전송에서 mint에 의해 적용됩니다. 풀은SwapBaseInput예치의 수신 쪽이고 출금의 송신 쪽입니다. 프로그램은 vault에 착지하는 순 금액을 계산하고 곡선을 그에 따라 설정합니다.algorithms/token-2022-transfer-fees를 참조하세요.MetadataPointer및TokenMetadata. mint의 표준 온체인 메타데이터입니다. 스왑 수학에 영향을 주지 않습니다.InterestBearingConfig. mint의 UI 금액이 이자를 누적합니다. vault는 원시 금액을 저장합니다. 곡선은 원시 금액에서만 작동합니다. APR을 표시하는 UI는 Token-2022 헬퍼를 호출하여 UI 금액을 렌더링해야 합니다.ScaledUiAmount. UI 표시 스케일링 확장입니다.InterestBearingConfig와 동일한 처리 — 곡선은 원시 금액을 사용합니다.
PermanentDelegate, TransferHook, DefaultAccountState, NonTransferable, ConfidentialTransfer, Group/GroupMember, MintCloseAuthority 등 — 은 Initialize가 NotSupportMint로 거부하게 합니다. 예외는 프로그램의 작은 하드코딩된 mint 화이트리스트(몇 가지 특정 pubkey)로, 확장 확인을 우회합니다. 이는 특정 mint를 경우별로 온보드하는 데 사용됩니다.
검증된 확장 목록과 mint 화이트리스트는 programs/cp-swap/src/utils/token.rs 아래의 CP-Swap 소스에 있으며 향후 프로그램 업그레이드로 변경될 수 있습니다.
Observation
observation 계정은ObservationState 항목의 ring buffer이며, 각각 block_timestamp와 누적 가격을 저장합니다. 모든 스왑에서 프로그램은 마지막 항목 이후 충분한 시간이 경과한 경우 새로운 observation을 추가합니다. TWAP는 두 observation을 읽고 Δcumulative / Δtime을 나누어 계산됩니다.
ObservationState PDA는 주변 필드와 discriminator 이후 약 4,100바이트입니다.
두 가지 소비자 규칙:
- 단일 observation을 가격으로 사용하지 마세요. 이는 누적이지 현물 가격이 아닙니다. TWAP를 계산하려면 두 개를 사용하세요.
- 최소한 한 블록 떨어진 observation을 선택하세요. 동일한 블록 내의 스왑은 새로운 observation을 생성하지 않을 수 있습니다. 연속으로 읽으면 동일한 레코드를 반환할 수 있습니다.
products/clmm/accounts를 참조하세요.
계정 생명주기
CPMM 풀과 그 PDA는 절대 닫히지 않습니다. 유동성이 0이어도
poolState는 남아 있습니다. 이는 의도적입니다: 나중에 동일한 풀을 다시 시드하면 역사적 observation buffer를 보존하고 PDA 파생은 안정적으로 유지됩니다.
어디서 무엇을 읽을지
- 명령어 계정 목록(각 명령어에 대해 위의 어느 것이 쓰기 가능/서명자인지):
products/cpmm/instructions. - 수수료 누적 의미론:
products/cpmm/fees. - 스왑 수학 / observation 업데이트 규칙:
products/cpmm/math. - 정식 시드 / 프로그램 ID:
reference/program-addresses.

