Skip to main content
이 페이지는 AI 자동 번역입니다. 모든 내용은 영문판을 기준으로 합니다.영문판 보기 →
CPMM의 프로그램 ID와 PDA 시드는 reference/program-addresses에 정식으로 나열되어 있습니다. 이 페이지는 각 계정의 용도와 유지되는 불변성에 중점을 두며, 하드코딩된 주소는 다루지 않습니다.

CPMM 풀의 6개 계정

모든 CPMM 풀은 CPMM 프로그램 아래의 6개 프로그램 파생 주소(PDA)와 이를 참조하는 1개의 공유 AmmConfig 계정으로 완전히 설명됩니다. 두 개의 mint만 있으면 네트워크에 접근하지 않고도 모든 것을 결정론적으로 파생할 수 있습니다. 그리고 공유 설정:

두 개의 mint만으로 풀 파생하기

풀 PDA를 파생하기 전에 항상 mint를 정렬하세요. 시드는 사용자 순서가 아닌 바이트 순서로 두 mint를 해시합니다. (A, B)(B, A)를 가진 두 풀은 온체인에서 충돌할 것입니다 — 정렬은 프로그램이 매핑을 정식으로 만드는 방법입니다.
풀 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에 있습니다.
  • statusSwap, 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

주의할 세 가지:
  1. trade_fee_ratecreator_fee_rate는 거래량의 분수이며, 둘 다 1/1_000_000 단위로 표시됩니다. 2500은 거래량의 0.25%를 의미합니다. protocol_fee_ratefund_fee_rate거래 수수료의 분수(거래량이 아님)이며, 동일한 1/1_000_000 분모를 사용합니다. 생성자 수수료는 거래 수수료의 분수가 아닙니다 — 이는 자체 독립적인 비율입니다. 전체 산술은 products/cpmm/fees에 있습니다.
  2. **indexu16**이므로 시드 해시는 2바이트 빅엔디안을 사용합니다. 바이트 순서의 오프바이원은 일반적인 통합 버그입니다.
  3. 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에 대해 풀을 생성할 자격이 있음을 증명할 수 있도록 허가된 풀 생성 경로를 지원합니다.
Permission PDA는 CPMM 관리자 또는 전용 permission-PDA 생성자 권한에 의해 CreatePermissionPda를 통해 생성됩니다. CPMM 관리자만 ClosePermissionPda를 통해 이를 취소할 수 있습니다. 최종 사용자는 이 계정과 직접 상호작용하지 않습니다 — 이는 크로스 프로그램 흐름을 위한 배관입니다. 역할 경계는 security/admin-and-multisig를 참조하고 정식 주소는 reference/program-addresses를 참조하세요.

Vault 및 Token-2022

vault0vault1은 CPMM authority PDA가 소유하며, 이들의 토큰 프로그램 소유자(token_program)는 풀 생성 시 mint의 프로그램에 의해 결정되는 SPL Token 또는 Token-2022입니다. 풀은 두 경우를 투명하게 처리합니다 — Swap / Deposit / Withdraw 명령어 계정에서 각 쪽에 올바른 토큰 프로그램 ID를 전달합니다. CPMM은 풀 생성 시 엄격한 확장 허용 목록을 적용합니다(utils/token.rsis_supported_mint). Token-2022 mint는 모든 확장이 이 목록에 있는 경우에만 CPMM 풀에서 사용할 수 있습니다:
  • TransferFeeConfig. 모든 전송에서 mint에 의해 적용됩니다. 풀은 SwapBaseInput 예치의 수신 쪽이고 출금의 송신 쪽입니다. 프로그램은 vault에 착지하는 금액을 계산하고 곡선을 그에 따라 설정합니다. algorithms/token-2022-transfer-fees를 참조하세요.
  • MetadataPointerTokenMetadata. mint의 표준 온체인 메타데이터입니다. 스왑 수학에 영향을 주지 않습니다.
  • InterestBearingConfig. mint의 UI 금액이 이자를 누적합니다. vault는 원시 금액을 저장합니다. 곡선은 원시 금액에서만 작동합니다. APR을 표시하는 UI는 Token-2022 헬퍼를 호출하여 UI 금액을 렌더링해야 합니다.
  • ScaledUiAmount. UI 표시 스케일링 확장입니다. InterestBearingConfig와 동일한 처리 — 곡선은 원시 금액을 사용합니다.
다른 확장 — PermanentDelegate, TransferHook, DefaultAccountState, NonTransferable, ConfidentialTransfer, Group/GroupMember, MintCloseAuthority 등 — 은 InitializeNotSupportMint로 거부하게 합니다. 예외는 프로그램의 작은 하드코딩된 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을 나누어 계산됩니다.
ring buffer는 100개의 observation을 위해 크기가 지정됩니다. 각 observation은 40바이트이므로 배열 자체는 4,000바이트입니다. 전체 ObservationState PDA는 주변 필드와 discriminator 이후 약 4,100바이트입니다. 두 가지 소비자 규칙:
  • 단일 observation을 가격으로 사용하지 마세요. 이는 누적이지 현물 가격이 아닙니다. TWAP를 계산하려면 두 개를 사용하세요.
  • 최소한 한 블록 떨어진 observation을 선택하세요. 동일한 블록 내의 스왑은 새로운 observation을 생성하지 않을 수 있습니다. 연속으로 읽으면 동일한 레코드를 반환할 수 있습니다.
더 많은 수학은 products/clmm/accounts를 참조하세요.

계정 생명주기

CPMM 풀과 그 PDA는 절대 닫히지 않습니다. 유동성이 0이어도 poolState는 남아 있습니다. 이는 의도적입니다: 나중에 동일한 풀을 다시 시드하면 역사적 observation buffer를 보존하고 PDA 파생은 안정적으로 유지됩니다.

어디서 무엇을 읽을지

출처: