Cette page est traduite automatiquement par IA. La version anglaise fait foi.Voir la version anglaise →
L’ID du programme et les seeds des PDAs pour CPMM sont listés de manière canonique dans
reference/program-addresses. Cette page se concentre sur ce que chaque compte fait et les invariants qu’il maintient, non sur les adresses codées en dur.Les six comptes d’un pool CPMM
Chaque pool CPMM est entièrement décrit par six adresses dérivées du programme (PDAs) sous le programme CPMM, plus un compteAmmConfig partagé qu’il référence. Une fois que vous avez les deux mints, vous pouvez dériver tout de manière déterministe sans toucher au réseau.
Et la config partagée :
Dériver un pool à partir de rien d’autre que deux mints
L’ID du pool n’est pas toujours le PDA canonique.
Initialize accepte une paire de clés signataire arbitraire comme pool_state en plus du PDA ci-dessus. Si le compte passé ne correspond pas au PDA canonique, le programme exige qu’il soit un signataire — c’est-à-dire que le créateur passe une paire de clés fraîche qu’il signe. C’est la défense contre le front-running : tout tiers qui court pour saisir le PDA canonique peut être contourné par le créateur légitime en utilisant une paire de clés aléatoire à la place. Les PDAs en aval (lpMint, vault0, vault1, observation) sont toujours dérivés de poolState.key(), donc ils restent uniques à l’adresse utilisée. Quand vous indexez les pools, découvrez toujours l’ID du pool à partir de l’état on-chain (par exemple, les comptes PoolState sous le programme CPMM), pas en dérivant le PDA canonique — ce dernier manquera les pools avec paire aléatoire.Layouts des comptes
Les définitions Rust complètes vivent dans la sourceraydium-cp-swap. Les champs ci-dessous sont ceux que vous lirez lors d’une intégration.
PoolState
lp_supply— le miroir interne du pool de la supply totale du mint LP. Utilisez-le pour les mathématiques de part LP ; la valeur devrait correspondre à la supply on-chain du mint, mais la lire depuisPoolStateévite une récupération de compte supplémentaire.protocol_fees_token{0,1},fund_fees_token{0,1}— frais accumulés non encore balayés. Ceux-ci n’affectent pas le prix du swap ; ils restent dans les vaults jusqu’à ce queCollectProtocolFee/CollectFundFeesoit appelé.status— un bitmask contrôlant siSwap,Deposit,Withdrawsont autorisés. Mis à jour par l’admin viaUpdatePoolStatus. Le SDK vérifie cela avant de construire une transaction ; si vous faites du CPI directement, vérifiez-le vous-même.token0_program/token1_program— le programme de token sur lequel faire du CPI pour chaque vault. L’un peut être le SPL Token classique et l’autre Token-2022 ; ils sont indépendants.open_time— un timestamp Unix. Les swaps avant cette heure échouent. Les dépôts sont autorisés avantopen_timepour que le pool puisse être amorcé.creator_fee_on/enable_creator_fee— ensemble contrôlent si le frais de créateur optionnel est actif pour ce pool et de quel côté du swap il est collecté.enable_creator_fee == falseannule entièrement le chemin des frais de créateur. Quand activé,creator_fee_onsélectionne :0= prélever le frais sur le token qui est l’entrée du swap (BothToken) ;1= prélever le frais surtoken_0uniquement (ignorer sur les swapstoken_1 → token_0) ;2= prélever le frais surtoken_1uniquement. Défini à la création du pool viaInitializeWithPermission; ne peut pas changer plus tard.creator_fees_token_{0,1}— frais de créateur accumulés, balayés parCollectCreatorFeeouCollectCreatorFeePermissionless. Les deux chemins remettent les compteurs à zéro ; le chemin sans permission fixe les destinataires aux ATAs canoniques depool_creator.
AmmConfig
trade_fee_rateetcreator_fee_ratesont des fractions du volume, tous deux dénominés en unités de1/1_000_000.2500signifie 0,25 % du volume du trade.protocol_fee_rateetfund_fee_ratesont des fractions du frais de trading (pas du volume), avec le même dénominateur1/1_000_000. Le frais de créateur n’est pas une fraction du frais de trading — c’est son propre taux indépendant. L’arithmétique complète est dansproducts/cpmm/fees.indexest unu16, donc le seed hash utilise 2 octets big-endian. Une erreur d’ordre d’octets est un bug d’intégration courant.AmmConfigest immuable au niveau du pool. Un pool pointe vers unAmmConfigà la création et ne change jamais. Les changements de frais se propagent parce que le pool lit la config à chaque swap — mais le pool ne peut pas être déplacé entre les tiers de frais.
creator_fee_rate) vit sur AmmConfig et est partagé entre le tier de frais. Si un pool particulier le facture réellement (enable_creator_fee) et de quel côté du swap il atterrit (creator_fee_on) vivent sur PoolState. Le frais de créateur est indépendant du frais de trading — c’est son propre taux, accumulé à ses propres compteurs (creator_fees_token_{0,1}), et ne réduit jamais les parts LP / protocole / fonds du frais de trading. Le balayage se fait via CollectCreatorFee ou le CollectCreatorFeePermissionless contraint par destination. Voir products/cpmm/fees pour la mécanique complète.
Permission
Un petit compte de contrôle d’accès utilisé par InitializeWithPermission. Le programme CPMM supporte un chemin de création de pool avec permission pour que d’autres programmes (par exemple LaunchLab lors de la graduation d’un token vers CPMM) puissent prouver qu’ils sont autorisés à créer un pool contre un AmmConfig donné.
CreatePermissionPda par soit l’admin CPMM soit une autorité créatrice de PDA de permission dédiée. Seul l’admin CPMM peut le révoquer via ClosePermissionPda. Les utilisateurs finaux n’interagissent pas directement avec ce compte — c’est de la plomberie pour les flux cross-program. Voir security/admin-and-multisig pour la limite de rôle et reference/program-addresses pour les adresses canoniques.
Vaults et Token-2022
vault0 et vault1 sont propriété du PDA d’autorité CPMM, et leur propriétaire de programme de token (token_program) est soit SPL Token soit Token-2022, déterminé à la création du pool par le programme du mint. Le pool gère les deux cas de manière transparente — vous passez le bon ID de programme de token pour chaque côté dans les comptes d’instruction Swap / Deposit / Withdraw.
CPMM applique une stricte liste d’autorisation d’extensions à la création du pool (is_supported_mint dans utils/token.rs). Un mint Token-2022 peut être utilisé dans un pool CPMM seulement si chaque extension qu’il porte est sur cette liste :
TransferFeeConfig. Appliqué par le mint à chaque transfert. Le pool est du côté récepteur pour les dépôtsSwapBaseInputet du côté envoyeur pour les retraits. Le programme calcule le montant net atterrissant dans le vault et définit la courbe en conséquence. Voiralgorithms/token-2022-transfer-fees.MetadataPointeretTokenMetadata. Métadonnées standard on-mint. Aucun effet sur les mathématiques du swap.InterestBearingConfig. Le montant UI du mint accumule des intérêts. Le vault stocke les montants bruts ; la courbe opère uniquement sur les montants bruts. Les UIs qui affichent l’APR doivent appeler les helpers Token-2022 pour rendre le montant UI.ScaledUiAmount. Extension de mise à l’échelle d’affichage UI. Même traitement queInterestBearingConfig— la courbe utilise les montants bruts.
PermanentDelegate, TransferHook, DefaultAccountState, NonTransferable, ConfidentialTransfer, Group/GroupMember, MintCloseAuthority, etc. — cause à Initialize de rejeter avec NotSupportMint. L’exception est une petite liste blanche de mints codée en dur dans le programme (une poignée de pubkeys spécifiques) qui contourne la vérification d’extension ; elle est utilisée pour intégrer des mints spécifiques au cas par cas.
La liste d’extensions vérifiées et la liste blanche de mints vivent dans la source CP-Swap sous programs/cp-swap/src/utils/token.rs et peuvent changer avec les futures mises à niveau du programme.
Observation
Le compte d’observation est un ring buffer d’entréesObservationState, chacune stockant un block_timestamp et un prix cumulatif. À chaque swap, le programme ajoute une nouvelle observation si suffisamment de temps s’est écoulé depuis la dernière. Les TWAPs sont calculés en lisant deux observations et en divisant Δcumulative / Δtime.
ObservationState complet fait environ 4 100 octets après les champs environnants et le discriminateur.
Deux règles pour les consommateurs :
- N’utilisez pas une seule observation comme prix. C’est un cumulatif, pas un prix spot. Utilisez deux d’entre elles pour calculer un TWAP.
- Choisissez des observations au moins un bloc à part. Les swaps dans le même bloc peuvent ne pas produire une nouvelle observation ; la lecture dos-à-dos peut retourner le même enregistrement.
products/clmm/accounts.
Cycle de vie des comptes
Les pools CPMM et leurs PDAs ne sont jamais fermés. Même à liquidité zéro, le
poolState reste. C’est délibéré : réamorcer le même pool plus tard préserve son buffer d’observations historiques et sa dérivation PDA reste stable.
Quoi lire où
- Listes de comptes d’instruction (lesquels des comptes ci-dessus sont writable/signer pour chaque instruction) :
products/cpmm/instructions. - Sémantique d’accumulation de frais :
products/cpmm/fees. - Mathématiques du swap / règle de mise à jour d’observation :
products/cpmm/math. - Seeds canoniques / IDs de programme :
reference/program-addresses.

