Cette page est traduite automatiquement par IA. La version anglaise fait foi.Voir la version anglaise →
Cette page est la référence d’instruction faisant autorité. Pour le code qui compose réellement ces instructions, consultez
products/cpmm/code-demos. Pour les significations des codes d’erreur, consultez reference/error-codes.La mise à niveau du programme 2026-09 a reconstruit CPMM sur Anchor 1.0.2 / Solana 3.1.10, a ajouté l’instruction admin CollectExcessLamports, a supprimé la liste blanche de mints Token-2022 codée en dur, et a modifié ce que CreateAmmConfig écrit dans protocol_owner / fund_owner. Aucune instruction orientée utilisateur n’a changé ses comptes, arguments ou mathématiques. Consultez l’entrée du journal des modifications du 2026-09-09.La mise à niveau 2026-10-30 ajoute InitializeV2 : une création de pool sans permission où le créateur choisit d’activer ou non les frais de créateur, et de quel côté. Elle est purement additive. Initialize, InitializeWithPermission et toutes les autres instructions conservent leurs discriminateurs, comptes et arguments. Consultez l’entrée du journal des modifications du 2026-10-30.Résumé des instructions
Masque de statut : le
status de chaque pool est un u8 où le bit 0 = dépôt désactivé, bit 1 = retrait désactivé, bit 2 = swap désactivé (PoolStatusBitIndex { Deposit, Withdraw, Swap } dans le programme). Un bit clair signifie que l’opération est autorisée ; un bit défini signifie qu’elle est en pause. UpdatePoolStatus prend un u8 brut et remplace la valeur existante.
Les sections suivantes détaillent chacune. L’ordre des comptes suit l’IDL CPMM ; le SDK et le client Rust dans raydium-cp-swap/programs/cp-swap/src/instructions correspondent à cet ordre.
Initialize
Créer un nouveau pool CPMM.
Arguments
* pool_state signe uniquement sur le chemin de paire aléatoire ; le chemin PDA canonique s’exécute sans que pool_state signe.
Conditions préalables
- Les mints sont triés (
token_0_mint < token_1_mintpar ordre d’octets). - Aucun mint n’utilise une extension en dehors de la liste blanche CPMM (
TransferFeeConfig,MetadataPointer,TokenMetadata,InterestBearingConfig,ScaledUiAmount) — voirproducts/cpmm/accounts. Un mint dont le PDASupportMintAssociated(seed[b"support_mint", mint]) existe ignore la vérification d’extension — mais vous devez ajouter ce PDA àremaining_accounts. Le programme ne scanne que les comptes que vous passez et ne charge jamais le PDA lui-même, donc compter sur le registre sans fournir le compte échoue quand même avecNotSupportMint(6007). L’ordre n’a pas d’importance (la correspondance se fait par clé) ; passez une entrée par mint qui a besoin du contournement. Ce registre est le seul contournement depuis que la mise à niveau 2026-09 a supprimé la liste blanche de quatre mints codée en dur. creatora au moinsinit_amount_0etinit_amount_1dans les ATAs respectifs.amm_config.disable_create_pool == false.
pool_state.lp_supply = sqrt(init_amount_0 * init_amount_1)— la racine carrée complète. Le créateur reçoitlp_supply − 100; les 100 unités de base verrouillées sont comptées danslp_supplymais jamais créées.- Donc
lp_mint.supply == pool_state.lp_supply − 100pour la durée de vie du pool. Toutes les mathématiques de part LP (dépôt, retrait) divisent parlp_supply, donc utilisez ce champ et ne substituez pas l’approvisionnement du mint en chaîne. Revient avecInitLpAmountTooLesssisqrt(...) < 100. observation_stateest initialisé ;observation_index = 0etpool_id = pool_state.key().- Les lamports
create_pool_feesont transférés du créateur au destinataire et synchronisés en SOL natif (c’est un ATA wSOL). - Le masque de statut du pool est
0(dépôt / retrait / swap tous activés). enable_creator_fee = falseetcreator_fee_on = BothToken.Initializene supporte pas l’activation des frais créateurs. UtilisezInitializeV2pour les activer sans octroi de permission.open_timeest augmenté àblock_timestamp + 1si l’appelant a passé une valeur<= block_timestamp. Les swaps sont rejetés avantopen_time; les dépôts et retraits fonctionnent immédiatement.
reference/error-codes)
InvalidInput— mints non triés, ou mints identiques.NotSupportMint— extension Token-2022 bloquée.ExceededSlippage— rarement ; siinit_amount_0/1résultent en zéro LP en raison d’une inadéquation de décimales.
InitializeV2
Créer un nouveau pool CPMM et choisir ses paramètres de frais de créateur. Ajoutée dans la mise à niveau 2026-10-30.
InitializeV2 exécute le même flux de création que Initialize. La seule différence est ce qu’elle écrit dans enable_creator_fee et creator_fee_on sur le nouveau pool. Avant cette instruction, seule InitializeWithPermission pouvait créer un pool avec les frais de créateur activés, et ce chemin nécessite un PDA Permission émis par l’admin.
Arguments
CreatorFeeOn est un enum Borsh, donc l’argument s’encode avec un octet de tag pour l’Option, plus un octet de variante quand il vaut Some :
Tout autre octet échoue à la désérialisation des arguments par Anchor avant l’exécution du handler.
Discriminateur :
initialize_v2 → [67, 153, 175, 39, 218, 16, 38, 32].
Comptes (W = inscriptible, S = signataire)
Les 19 premiers comptes sont identiques à ceux de Initialize, dans le même ordre. InitializeV2 supprime uniquement le sysvar rent final.
* pool_state signe uniquement sur le chemin de paire aléatoire.
Les remaining_accounts fonctionnent comme pour Initialize : ajoutez le PDA SupportMintAssociated pour tout mint Token-2022 qui a besoin du contournement par le registre.
Comme les 19 premiers comptes correspondent, vous pouvez adapter un builder
Initialize existant : changez le discriminateur, ajoutez les octets de creator_fee_on et supprimez rent. Si vous laissez rent, Anchor le transmet comme une entrée de remaining_accounts, et le scan support-mint l’ignore car ce n’est pas un compte détenu par CPMM. Supprimez-le quand même pour économiser l’emplacement de compte.Initialize. Il n’y a aucune vérification de permission ni nouvelle contrainte sur creator_fee_on.
Postconditions — les mêmes que pour Initialize, sauf :
enable_creator_feeetcreator_fee_onsont définis à partir de l’argument, comme dans le tableau ci-dessus.pool_creatorest toujours lecreatorsignataire. SurInitializeWithPermission, le créateur est un compte séparé, non signataire ; surInitializeV2, il ne peut pas être défini sur quelqu’un d’autre.
Activer les frais de créateur ne choisit pas leur taux. Le pool facture l’
AmmConfig.creator_fee_rate du palier de frais auquel il est lié. Sur un palier où ce taux vaut 0, un pool activé n’accumule rien. Lisez la configuration avant de choisir un palier. Le choix est aussi permanent : aucune instruction ne modifie enable_creator_fee ni creator_fee_on après la création. Voir products/cpmm/fees.creator_fees_token_{0,1}. Le créateur les collecte via CollectCreatorFee ou CollectCreatorFeePermissionless, et la part du protocole issue de la mise à niveau 2026-09-19 s’applique comme d’habitude.
Erreurs courantes — les mêmes que pour Initialize.
Deposit
Ajouter de la liquidité dans les deux tokens proportionnellement au pool.
Arguments
Mathématiques
vault_amount_without_fee, c’est-à-dire le solde brut moins les compteurs de frais de protocole, de fonds et de créateurs accumulés), pas le solde brut du vault ; et le plafond de slippage est vérifié par rapport à ce que le payeur transfère réellement, après que le frais de transfert Token-2022 soit ajouté, pas par rapport au mouvement brut du vault.
Aucun changement à la proportionnalité de k — les deux totaux et lp_supply se mettent à l’échelle par le même facteur.
Postconditions
lp_supply += lp_token_amount.vault_0 += needed_token_0(net de tout frais de transfert Token-2022 sur l’entrée).vault_1 += needed_token_1(net de tout frais de transfert Token-2022 sur l’entrée).
ExceededSlippage, ZeroTradingTokens, InvalidStatus si le dépôt est en pause.
Withdraw
Brûler les tokens LP et recevoir les deux tokens sous-jacents au prorata.
Arguments
Les 13 premiers comptes sont identiques à
Deposit, et lp_mint est inscriptible car les tokens LP sont brûlés. Withdraw prend en plus un 14e compte, memo_program (contraint address = memo::ID) — Deposit ne le fait pas. Un Withdraw à 13 comptes échoue la désérialisation Anchor, donc le LP ne peut pas sortir.
Mathématiques
lp_supply -= lp_token_amount.- Les vaults envoient
out_token_0/out_token_1(brut ; l’utilisateur reçoit net de tout frais de transfert Token-2022).
SwapBaseInput
Swap à entrée exacte.
Arguments
L’ordre entrée → sortie est par la direction de l’utilisateur, pas par le
token_0 / token_1 canonique du pool. Le programme détermine quel vault est lequel en faisant correspondre les mints.
Mathématiques — voir products/cpmm/math.
Conditions préalables
open_time <= now.pool_statusautorise le swap.- Aucun mint en pause ou gelé pour cette autorité.
amount_in > 0.
ExceededSlippage—amount_out < minimum_amount_out.ZeroTradingTokens— le commerce s’arrondit à zéro.NotApproved— le pool est en pause pour les swaps viaUpdatePoolStatus.InvalidInput— les mints ne correspondent à aucun des mints du vault du pool.
SwapBaseOutput
Swap à sortie exacte.
Arguments
SwapBaseInput.
Mathématiques — courbe inverse avec plafond, voir products/cpmm/math.
Erreurs courantes — ExceededSlippage (gross_in > max_amount_in), ZeroTradingTokens, InvalidInput, NotApproved.
CollectProtocolFee
Collecter les frais de protocole accumulés des vaults vers la destination du protocole.
Arguments — aucun.
Comptes
Effet
InvalidOwner (6001) si le signataire n’est ni amm_config.protocol_owner ni l’admin du programme. (Il n’y a pas de NotApproved sur ce chemin.)
CollectFundFee
Même forme que CollectProtocolFee mais signé par amm_config.fund_owner — ou, encore une fois, l’admin du programme — et mettant à zéro les compteurs fund_fees_*. Même InvalidOwner sur un mauvais signataire.
CollectCreatorFee
Signé par pool_state.pool_creator. Il règle les frais créateurs accumulés et transfère la part du créateur vers les comptes de tokens du créateur.
Arguments — aucun.
Comptes
Effet
CollectProtocolFee. Les deux compteurs sont déjà exclus de la vue du pool de la vault, donc le prix du pool ne bouge pas. Dérivation complète dans products/cpmm/fees.
Erreurs courantes — NoFeeCollect quand les deux compteurs de créateurs sont zéro (vérifiés avant la division), InvalidInput (6003) si le share_rate résolu dépasse 1_000_000, MathOverflow (6011) si l’enregistrement de la part déborderait protocol_fees_token_*, et l’erreur ConstraintSeeds d’Anchor si creator_fee_share n’est pas le PDA canonique.
CollectCreatorFeePermissionless
N’importe qui peut déclencher la collecte des frais créateurs. L’instruction envoie toujours la part du créateur vers les comptes de tokens associés canoniques possédés par pool_state.pool_creator ; l’appelant ne peut pas choisir un autre créateur ou destination. Si l’une des ATAs est manquante, le payeur finance sa création.
Le CollectCreatorFee original reste appelable, donc un créateur qui veut signer pour sa propre collecte peut toujours le faire.
Arguments — aucun.
Comptes
Effet — identique à
CollectCreatorFee ci-dessus : la part est résolue à partir de creator_fee_share ou amm_config, la part du protocole est enregistrée dans protocol_fees_token_{0,1}, la part du créateur est transférée vers les ATAs du créateur, les deux compteurs de créateurs sont mis à zéro, et recent_epoch est mis à jour. Retourne NoFeeCollect quand les deux compteurs sont zéro.
UpdatePoolStatus
Mettre en pause ou reprendre des opérations individuelles sur un pool. Le champ status est un masque de bits :
Arguments
La clé admin est une clé publique compilée dans le programme (
crate::admin::ID), pas l’autorité de mise à niveau BPF — la modifier nécessite une mise à niveau du programme. Consultez reference/program-addresses pour la valeur et security/admin-and-multisig pour qui la détient.
CreateAmmConfig
Créer un nouveau palier de frais.
Arguments
Conditions préalables
- Aucune
AmmConfigexistante avec le mêmeindex. protocol_fee_rate + fund_fee_rate <= FEE_RATE_DENOMINATOR_VALUE.
Modifié en 2026-09 : les propriétaires de frais de la nouvelle config ne proviennent plus du signataire.
create_amm_config écrit maintenant le protocol_fee_owner::ID codé en dur du programme dans protocol_owner et fund_fee_owner::ID dans fund_owner, au lieu de copier la clé du signataire admin dans les deux. Les adresses sont dans reference/program-addresses.Conséquences : les frais sur une nouvelle AmmConfig atterrissent dans les portefeuilles de frais dédiés plutôt que celui de l’admin. L’admin reste un signataire accepté pour la collecte — CollectProtocolFee / CollectFundFee acceptent amm_config.protocol_owner / fund_owner ou crate::admin::ID — donc rien n’a à être pivoté pour collecter ; ce qui a changé est seulement où les produits vont par défaut. Les comptes AmmConfig existants ne sont pas réécrits — tout ce qui y est stocké gouverne toujours, donc lisez toujours protocol_owner / fund_owner du compte au lieu d’assumer l’une ou l’autre valeur. Les paramètres 3 et 4 de UpdateAmmConfig les font toujours pivoter.UpdateAmmConfig
Modifier les taux de frais ou la propriété sur une AmmConfig existante. Prend un param: u8 (quel champ mettre à jour) et une value: u64. La table de dispatch complète :
param = 0→trade_fee_rate(affirmetrade_fee_rate + creator_fee_rate < 1_000_000)param = 1→protocol_fee_rate(affirme≤ 1_000_000et+ fund_fee_rate ≤ 1_000_000)param = 2→fund_fee_rate(affirme≤ 1_000_000et+ protocol_fee_rate ≤ 1_000_000)param = 3→protocol_owner. La nouvelle clé n’est pas dansvalue: ajoutez-la commeremaining_accounts[0](lecture seule est fine). Elle ne doit pas être la clé publique par défaut, et omettre le compte panique sur ununwrap().param = 4→fund_owner. Même mécanisme que3.param = 5→create_pool_feeparam = 6→disable_create_pool(toutevaluenon-zéro désactive)param = 7→creator_fee_rate(affirmecreator_fee_rate + trade_fee_rate < 1_000_000)param = 8→creator_fee_share_rate(affirme≤ 1_000_000). Ajouté 2026-09-19. La part par défaut du protocole des frais créateurs sur ce palier ; voirproducts/cpmm/fees. Elle n’est pas liée àprotocol_fee_rate, qui divise les frais commerciaux.
param retourne InvalidInput.
Les modifications sont signées par l’admin et affectent chaque pool lié à cette AmmConfig au prochain swap. Pas de migration ; les pools lisent simplement les nouvelles valeurs.
CreateCreatorFeeShare
Définir une part de protocole personnalisée des frais créateurs pour une paire (creator, amm_config), remplaçant AmmConfig.creator_fee_share_rate pour chaque pool que ce créateur possède sur ce palier de frais. Ajouté dans la mise à niveau de partage de frais créateurs 2026-09-19.
Arguments
Conditions préalables
share_rate <= 1_000_000, sinonInvalidInput(6003).- Le PDA ne doit pas déjà exister — l’
initd’Anchor échoue sur un deuxième appel pour la même paire. Pour modifier une taux, fermez le compte et recréez-le.
creator_fee_sharestockebump,creator,amm_configetshare_rate.- Chaque
CollectCreatorFee/CollectCreatorFeePermissionlessultérieur sur un pool créé parcreatorsousamm_configrésout la part à partir de ce compte au lieu de la config.
Le créateur du pool n’est pas une partie à cette instruction et ne la signe pas. La taux est lue au moment de la collecte, donc un remplacement créé après que les frais aient déjà accumulé s’applique à ce solde accumulé aussi.
CloseCreatorFeeShare
Supprimer le remplacement. La paire revient à AmmConfig.creator_fee_share_rate.
Arguments — aucun.
Comptes
Postconditions
- Le compte est fermé et ses lamports vont à
owner. - Les collectes pour cette paire résolvent la part à partir de
amm_config.creator_fee_share_rateà nouveau — qui est0sauf si un admin a défini le paramètre8deUpdateAmmConfig.
CollectExcessLamports
Collecte admin des lamports assis au-dessus du minimum exempt de loyer sur les comptes que CPMM contrôle. Ajouté dans la mise à niveau 2026-09 pour que le protocole puisse récupérer le sur-financement que la réduction de loyer SIMD-0437 laisse derrière sur les comptes créés avant chaque étape.
Seul l’excédent se déplace. Les soldes de tokens, les données de compte, les propriétaires, l’état du pool et la courbe restent inchangés, et l’instruction est un non-op par rapport à un compte déjà à son minimum — donc il est sûr de réexécuter après chaque étape de déploiement.
Arguments — aucun.
Comptes
Correction de l’ordre, 2026-09-19. Le programme fait maintenant deux passages sur
remaining_accounts — chaque CPI du programme de tokens d’abord, puis les débits directs des PDAs possédés par CPMM. Les entrelacer avortait avec le UnbalancedInstruction du runtime (« la somme des soldes de compte avant et après l’instruction ne correspondent pas ») chaque fois qu’un PDA était débité avant un CPI, car les changements de lamports en attente de l’appelant ne sont vidés dans les comptes qu’un CPI porte réellement. Les appelants n’ont pas à grouper ou trier la liste eux-mêmes.
Parce qu’il prend une liste
remaining_accounts non bornée, la taille de la transaction est la limite réelle — la même contrainte que la collecte côté portefeuille décrite dans solana-fundamentals/rent-and-reclaimable-rent.
Erreurs courantes — InvalidOwner (6001, mauvais signataire), LamportsCalculateError (6015, l’aller-retour wSOL n’a pas nettoyé à zéro), et InsufficientFunds du chemin possédé par le programme quand un compte détient moins que son propre minimum de loyer.
Pas de constructeur SDK. @raydium-io/raydium-sdk-v2 ne livre pas de constructeur pour cette instruction, et non plus le repo raydium-sdk-V2-demo — c’est un chemin admin. Encodez-la à la main, de la même façon que la collecte côté portefeuille dans solana-fundamentals/rent-and-reclaimable-rent le fait pour l’instruction du programme de tokens.
Matrice de changement d’état
Où aller ensuite
products/cpmm/code-demos— exemples TypeScript exécutables pour ce qui précède.reference/error-codes— la table d’erreur Anchor complète.products/cpmm/fees— le modèle d’accumulation de frais que les instructionsCollect*Feedrainent.

