Esta página fue traducida automáticamente por IA. La versión en inglés es la fuente autorizada.Ver versión en inglés →
Esta página es la referencia de instrucciones autorizada. Para código que realmente compone estas instrucciones, consulta
products/cpmm/code-demos. Para significados de códigos de error, consulta reference/error-codes.La actualización del programa 2026-09 reconstruyó CPMM en Anchor 1.0.2 / Solana 3.1.10, agregó la instrucción de administrador CollectExcessLamports, eliminó la lista blanca de mints Token-2022 codificada, y cambió lo que CreateAmmConfig escribe en protocol_owner / fund_owner. Ninguna instrucción orientada al usuario cambió sus cuentas, argumentos o matemáticas. Consulta la entrada del registro de cambios 2026-09-09.Resumen de instrucciones
Máscara de estado: el
status de cada pool es un u8 donde bit 0 = depósito deshabilitado, bit 1 = retiro deshabilitado, bit 2 = intercambio deshabilitado (PoolStatusBitIndex { Deposit, Withdraw, Swap } en el programa). Un bit claro significa que la operación está permitida; un bit establecido significa que está pausada. UpdatePoolStatus toma un u8 sin procesar y sobrescribe el valor existente.
Las siguientes secciones detallan cada una. El orden de cuentas sigue el IDL de CPMM; el SDK y el cliente Rust en raydium-cp-swap/programs/cp-swap/src/instructions coinciden con este orden.
Initialize
Crea un nuevo pool CPMM.
Argumentos
* pool_state firma solo en la ruta de keypair aleatorio; la ruta de PDA canónica se ejecuta sin que pool_state firme.
Precondiciones
- Los mints están ordenados (
token_0_mint < token_1_mintpor orden de bytes). - Ningún mint utiliza una extensión fuera de la lista de permitidos de CPMM (
TransferFeeConfig,MetadataPointer,TokenMetadata,InterestBearingConfig,ScaledUiAmount) — consultaproducts/cpmm/accounts. Un mint cuya PDASupportMintAssociated(semilla[b"support_mint", mint]) existe omite la verificación de extensión — pero debes agregar esa PDA aremaining_accounts. El programa solo escanea las cuentas que pasas y nunca carga la PDA por sí solo, por lo que confiar en el registro sin proporcionar la cuenta aún falla conNotSupportMint(6007). El orden no importa (la coincidencia es por clave); pasa una entrada por mint que necesita el bypass. Ese registro es el único bypass desde que la actualización 2026-09 eliminó la lista blanca de cuatro mints codificada. creatortiene al menosinit_amount_0einit_amount_1en las respectivas ATAs.amm_config.disable_create_pool == false.
pool_state.lp_supply = sqrt(init_amount_0 * init_amount_1)— la raíz cuadrada completa. El creador recibelp_supply − 100; las 100 unidades base bloqueadas se cuentan enlp_supplypero nunca se acuñan.- Entonces
lp_mint.supply == pool_state.lp_supply − 100durante la vida del pool. Toda la matemática de participación LP (depósito, retiro) divide porlp_supply, así que usa ese campo y no sustituyas el suministro en cadena del mint. Revierte conInitLpAmountTooLesssisqrt(...) < 100. observation_statese inicializa;observation_index = 0ypool_id = pool_state.key().- Los lamports de
create_pool_feese transfieren del creador al receptor y se sincronizan como SOL nativo (es una ATA wSOL). - La máscara de estado del pool es
0(depósito / retiro / intercambio todos habilitados). enable_creator_fee = falseycreator_fee_on = BothToken.Initializeno admite habilitar la comisión del creador — esa ruta esInitializeWithPermission.open_timese aumenta ablock_timestamp + 1si el llamador pasó un valor<= block_timestamp. Los intercambios se rechazan antes deopen_time; los depósitos y retiros funcionan inmediatamente.
reference/error-codes)
InvalidInput— mints desordenados o mints idénticos.NotSupportMint— extensión Token-2022 bloqueada.ExceededSlippage— raramente; siinit_amount_0/1resultan en cero LP debido a desajuste de decimales.
Deposit
Agrega liquidez en ambos tokens proporcional al pool.
Argumentos
Matemáticas
vault_amount_without_fee, es decir, el saldo sin procesar menos los contadores de comisiones acumuladas de protocolo, fondo y creador), no el saldo del vault sin procesar; y el límite de deslizamiento se verifica contra lo que el pagador realmente transfiere, después de que se agregue la comisión de transferencia Token-2022, no contra el movimiento bruto del vault.
Sin cambio en la proporcionalidad de k — ambos totales y lp_supply se escalan por el mismo factor.
Postcondiciones
lp_supply += lp_token_amount.vault_0 += needed_token_0(neto de cualquier comisión de transferencia Token-2022 en la entrada).vault_1 += needed_token_1(neto de cualquier comisión de transferencia Token-2022 en la entrada).
ExceededSlippage, ZeroTradingTokens, InvalidStatus si el depósito está pausado.
Withdraw
Quema tokens LP y recibe ambos tokens subyacentes prorrateados.
Argumentos
Las primeras 13 cuentas son idénticas a
Deposit, y lp_mint es escribible porque los tokens LP se queman. Withdraw además toma una 14ª cuenta, memo_program (restringida address = memo::ID) — Deposit no. Un Withdraw de 13 cuentas falla la deserialización de Anchor, por lo que el LP no puede salir.
Matemáticas
lp_supply -= lp_token_amount.- Los vaults envían
out_token_0/out_token_1(bruto; el usuario recibe neto de cualquier comisión de transferencia Token-2022).
SwapBaseInput
Intercambio de entrada exacta.
Argumentos
El orden entrada → salida es por la dirección del usuario, no por la
token_0 / token_1 canónica del pool. El programa determina cuál es el vault haciendo coincidir los mints.
Matemáticas — consulta products/cpmm/math.
Precondiciones
open_time <= now.pool_statuspermite intercambio.- Ningún mint pausado o congelado para esta autoridad.
amount_in > 0.
ExceededSlippage—amount_out < minimum_amount_out.ZeroTradingTokens— el intercambio se redondea a cero.NotApproved— el pool está pausado para intercambios medianteUpdatePoolStatus.InvalidInput— los mints no coinciden con ninguno de los mints del vault del pool.
SwapBaseOutput
Intercambio de salida exacta.
Argumentos
SwapBaseInput.
Matemáticas — curva inversa con techo, consulta products/cpmm/math.
Errores comunes — ExceededSlippage (gross_in > max_amount_in), ZeroTradingTokens, InvalidInput, NotApproved.
CollectProtocolFee
Barre las comisiones de protocolo acumuladas de los vaults al destino del protocolo.
Argumentos — ninguno.
Cuentas
Efecto
InvalidOwner (6001) si el firmante no es ni amm_config.protocol_owner ni el administrador del programa. (No hay NotApproved en esta ruta.)
CollectFundFee
Misma forma que CollectProtocolFee pero firmada por amm_config.fund_owner — o, nuevamente, el administrador del programa — y poniendo a cero los contadores fund_fees_*. Mismo InvalidOwner en un firmante incorrecto.
CollectCreatorFee
Firmada por pool_state.pool_creator. Liquida la comisión del creador acumulada y transfiere la parte del creador a las cuentas de token del creador.
Argumentos — ninguno.
Cuentas
Efecto
CollectProtocolFee. Ambos contadores ya están excluidos de la vista del vault de la curva, por lo que el precio del pool no se mueve. Derivación completa en products/cpmm/fees.
Errores comunes — NoFeeCollect cuando ambos contadores del creador son cero (verificado antes de la división), InvalidInput (6003) si la share_rate resuelta excede 1_000_000, MathOverflow (6011) si registrar la parte causaría desbordamiento en protocol_fees_token_*, y error ConstraintSeeds de Anchor si creator_fee_share no es la PDA canónica.
CollectCreatorFeePermissionless
Cualquiera puede activar la recopilación de comisiones del creador. La instrucción siempre envía la parte del creador a las cuentas de token asociadas canónicas propiedad de pool_state.pool_creator; el llamador no puede elegir otro creador o destino. Si falta alguna ATA, el pagador financia su creación.
El CollectCreatorFee original sigue siendo llamable, por lo que un creador que quiera firmar su propia recopilación aún puede.
Argumentos — ninguno.
Cuentas
Efecto — idéntico a
CollectCreatorFee arriba: la parte se resuelve desde creator_fee_share o amm_config, la parte del protocolo se registra en protocol_fees_token_{0,1}, la parte del creador se transfiere a las ATAs del creador, ambos contadores del creador se ponen a cero, y recent_epoch se actualiza. Devuelve NoFeeCollect cuando ambos contadores son cero.
UpdatePoolStatus
Pausa o reanuda operaciones individuales en un pool. El campo status es una máscara de bits:
Argumentos
La clave de administrador es una clave pública compilada en el programa (
crate::admin::ID), no la autoridad de actualización de BPF — cambiarla requiere una actualización del programa. Consulta reference/program-addresses para el valor y security/admin-and-multisig para quién la posee.
CreateAmmConfig
Crea un nuevo nivel de comisión.
Argumentos
Precondiciones
- No existe
AmmConfigcon el mismoindex. protocol_fee_rate + fund_fee_rate <= FEE_RATE_DENOMINATOR_VALUE.
Cambiado en 2026-09: los propietarios de comisiones de la nueva configuración ya no provienen del firmante.
create_amm_config ahora escribe el protocol_fee_owner::ID codificado del programa en protocol_owner y fund_fee_owner::ID en fund_owner, en lugar de copiar la clave del firmante administrador en ambos. Las direcciones están en reference/program-addresses.Consecuencias: las comisiones en una AmmConfig recién creada van a las billeteras de comisión dedicadas en lugar de la del administrador. El administrador sigue siendo un firmante aceptado para la recopilación — CollectProtocolFee / CollectFundFee aceptan amm_config.protocol_owner / fund_owner o crate::admin::ID — por lo que nada tiene que rotarse para barrer; lo que cambió es solo dónde van los ingresos por defecto. Las cuentas AmmConfig existentes no se reescriben — lo que se almacena en ellas aún rige, así que siempre lee protocol_owner / fund_owner de la cuenta en lugar de asumir ninguno de los valores. Los parámetros 3 y 4 de UpdateAmmConfig aún los rotan.UpdateAmmConfig
Cambia las tasas de comisión o la propiedad en una AmmConfig existente. Toma un param: u8 (qué campo actualizar) y un value: u64. La tabla de distribución completa:
param = 0→trade_fee_rate(afirmatrade_fee_rate + creator_fee_rate < 1_000_000)param = 1→protocol_fee_rate(afirma≤ 1_000_000y+ fund_fee_rate ≤ 1_000_000)param = 2→fund_fee_rate(afirma≤ 1_000_000y+ protocol_fee_rate ≤ 1_000_000)param = 3→protocol_owner. La nueva clave no está envalue: apéndala comoremaining_accounts[0](solo lectura está bien). No debe ser la clave pública predeterminada, y omitir la cuenta entra en pánico en ununwrap().param = 4→fund_owner. Mismo mecanismo que3.param = 5→create_pool_feeparam = 6→disable_create_pool(cualquiervaluedistinto de cero deshabilita)param = 7→creator_fee_rate(afirmacreator_fee_rate + trade_fee_rate < 1_000_000)param = 8→creator_fee_share_rate(afirma≤ 1_000_000). Agregada 2026-09-19. La parte predeterminada del protocolo de la comisión del creador en este nivel; consultaproducts/cpmm/fees. No está relacionada conprotocol_fee_rate, que divide la comisión de intercambio.
param devuelve InvalidInput.
Los cambios son firmados por el administrador y afectan cada pool vinculado a esta AmmConfig en el próximo intercambio. Sin migración; los pools simplemente leen los nuevos valores.
CreateCreatorFeeShare
Establece una parte de protocolo personalizada de la comisión del creador para un par (creator, amm_config), anulando AmmConfig.creator_fee_share_rate para cada pool que ese creador posee en ese nivel de comisión. Agregada en la actualización de comisión del creador 2026-09-19.
Argumentos
Precondiciones
share_rate <= 1_000_000, de otro modoInvalidInput(6003).- La PDA no debe existir ya — el
initde Anchor falla en una segunda llamada para el mismo par. Para cambiar una tasa, cierra la cuenta y créala de nuevo.
creator_fee_sharealmacenabump,creator,amm_configyshare_rate.- Cada
CollectCreatorFee/CollectCreatorFeePermissionlessposterior en un pool creado porcreatorbajoamm_configresuelve la parte desde esta cuenta en lugar de la configuración.
El creador del pool no es parte de esta instrucción y no la firma. La tasa se lee en el momento de la recopilación, por lo que una anulación creada después de que las comisiones ya se hayan acumulado se aplica a ese saldo acumulado también.
CloseCreatorFeeShare
Elimina la anulación. El par vuelve a AmmConfig.creator_fee_share_rate.
Argumentos — ninguno.
Cuentas
Postcondiciones
- La cuenta se cierra y sus lamports van a
owner. - Las recopilaciones para ese par resuelven la parte desde
amm_config.creator_fee_share_ratenuevamente — que es0a menos que un administrador haya establecido el parámetro8deUpdateAmmConfig.
CollectExcessLamports
Barrido de administrador de lamports que se sientan por encima del mínimo exento de renta en cuentas que CPMM controla. Agregada en la actualización 2026-09 para que el protocolo pueda reclamar el exceso de financiamiento que la reducción de renta SIMD-0437 deja en cuentas creadas antes de cada paso.
Solo se mueve el exceso. Los saldos de tokens, datos de cuentas, propietarios, estado del pool y la curva no se tocan, y la instrucción es una no-op contra una cuenta ya en su mínimo — por lo que es seguro volver a ejecutar después de cada paso de implementación.
Argumentos — ninguno.
Cuentas
Corrección de orden, 2026-09-19. El programa ahora hace dos pasadas sobre
remaining_accounts — cada CPI del programa de token primero, luego los débitos directos de PDAs propiedad de CPMM. Intercalarlos abortaba con el UnbalancedInstruction del tiempo de ejecución (“la suma de saldos de cuentas antes y después de la instrucción no coinciden”) siempre que una PDA se debitaba antes de un CPI, porque los cambios de lamports pendientes del llamador solo se vacían en cuentas que un CPI realmente lleva. Los llamadores no tienen que agrupar u ordenar la lista ellos mismos.owner de la cuenta de origen:
Porque toma una lista
remaining_accounts sin límites, el tamaño de la transacción es el límite real — la misma restricción que el barrido del lado de la billetera descrito en solana-fundamentals/rent-and-reclaimable-rent.
Errores comunes — InvalidOwner (6001, firmante incorrecto), LamportsCalculateError (6015, el viaje de ida y vuelta de wSOL no neteó a cero), e InsufficientFunds de la ruta propiedad del programa cuando una cuenta tiene menos que su propio mínimo de renta.
Sin constructor SDK. @raydium-io/raydium-sdk-v2 no envía un constructor para esta instrucción, ni tampoco el repositorio raydium-sdk-V2-demo — es una ruta de administrador. Codifícala a mano, de la manera que el barrido del lado de la billetera en solana-fundamentals/rent-and-reclaimable-rent hace para la instrucción del programa de token.
Matriz de cambio de estado
Dónde ir a continuación
products/cpmm/code-demos— ejemplos de TypeScript ejecutables para lo anterior.reference/error-codes— la tabla de errores de Anchor completa.products/cpmm/fees— el modelo de acumulación de comisiones que las instruccionesCollect*Feedrenan.

