Skip to main content
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.
Ambas instrucciones de recopilación de comisiones del creador cambiaron sus listas de cuentas el 2026-09-19. CollectCreatorFee gana creator_fee_share; CollectCreatorFeePermissionless gana amm_config y creator_fee_share. Ambas se añaden después de system_program, por lo que cada cuenta que un cliente existente ya pasa conserva su índice — pero las nuevas cuentas son obligatorias, así que una transacción construida contra el diseño anterior se queda corta y es rechazada con el AccountNotEnoughKeys (3005) de Anchor. Se agregan dos instrucciones de administrador — CreateCreatorFeeShare y CloseCreatorFeeShare — y UpdateAmmConfig toma un nuevo param = 8. Consulta la entrada del registro de cambios 2026-09-19.

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
Cuentas (W = escribible, S = firmante) * 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_mint por orden de bytes).
  • Ningún mint utiliza una extensión fuera de la lista de permitidos de CPMM (TransferFeeConfig, MetadataPointer, TokenMetadata, InterestBearingConfig, ScaledUiAmount) — consulta products/cpmm/accounts. Un mint cuya PDA SupportMintAssociated (semilla [b"support_mint", mint]) existe omite la verificación de extensión — pero debes agregar esa PDA a remaining_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 con NotSupportMint (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.
  • creator tiene al menos init_amount_0 e init_amount_1 en las respectivas ATAs.
  • amm_config.disable_create_pool == false.
Postcondiciones
  • pool_state.lp_supply = sqrt(init_amount_0 * init_amount_1) — la raíz cuadrada completa. El creador recibe lp_supply − 100; las 100 unidades base bloqueadas se cuentan en lp_supply pero nunca se acuñan.
  • Entonces lp_mint.supply == pool_state.lp_supply − 100 durante la vida del pool. Toda la matemática de participación LP (depósito, retiro) divide por lp_supply, así que usa ese campo y no sustituyas el suministro en cadena del mint. Revierte con InitLpAmountTooLess si sqrt(...) < 100.
  • observation_state se inicializa; observation_index = 0 y pool_id = pool_state.key().
  • Los lamports de create_pool_fee se 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 = false y creator_fee_on = BothToken. Initialize no admite habilitar la comisión del creador — esa ruta es InitializeWithPermission.
  • open_time se aumenta a block_timestamp + 1 si el llamador pasó un valor <= block_timestamp. Los intercambios se rechazan antes de open_time; los depósitos y retiros funcionan inmediatamente.
Errores comunes (lista completa en reference/error-codes)
  • InvalidInput — mints desordenados o mints idénticos.
  • NotSupportMint — extensión Token-2022 bloqueada.
  • ExceededSlippage — raramente; si init_amount_0/1 resultan en cero LP debido a desajuste de decimales.

Deposit

Agrega liquidez en ambos tokens proporcional al pool. Argumentos
Cuentas Matemáticas
Dos detalles que vale la pena precisar: la base prorrateada es el total del vault excluyendo comisiones (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).
Errores comunes — ExceededSlippage, ZeroTradingTokens, InvalidStatus si el depósito está pausado.

Withdraw

Quema tokens LP y recibe ambos tokens subyacentes prorrateados. Argumentos
Cuentas 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
Postcondiciones
  • 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
Cuentas 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_status permite intercambio.
  • Ningún mint pausado o congelado para esta autoridad.
  • amount_in > 0.
Errores comunes
  • ExceededSlippage — amount_out < minimum_amount_out.
  • ZeroTradingTokens — el intercambio se redondea a cero.
  • NotApproved — el pool está pausado para intercambios mediante UpdatePoolStatus.
  • InvalidInput — los mints no coinciden con ninguno de los mints del vault del pool.

SwapBaseOutput

Intercambio de salida exacta. Argumentos
Cuentas — igual que 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
Sin cambio en los saldos efectivos de la curva (las comisiones acumuladas ya estaban excluidas). Error común — 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
La parte del protocolo nunca sale del vault aquí — se reetiqueta como una comisión de protocolo y espera a 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
Las dos nuevas cuentas se añaden después de system_program, no se insertan. Cada cuenta desde payer hasta system_program conserva la posición que tenía antes de la actualización, por lo que la ruptura es limpia: una transacción construida contra el diseño de catorce cuentas previo a la actualización no malinterpreta un vault como una cuenta de configuración — simplemente pasa muy pocas cuentas y Anchor la rechaza con AccountNotEnoughKeys (3005) antes de que se ejecute cualquier restricción. Las cuentas siguen siendo obligatorias, así que añade ambas y actualiza el IDL; no hay ruta de compatibilidad para el diseño anterior.
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
Cuentas 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
Cuentas Precondiciones
  • No existe AmmConfig con el mismo index.
  • 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 (afirma trade_fee_rate + creator_fee_rate < 1_000_000)
  • param = 1 → protocol_fee_rate (afirma ≤ 1_000_000 y + fund_fee_rate ≤ 1_000_000)
  • param = 2 → fund_fee_rate (afirma ≤ 1_000_000 y + protocol_fee_rate ≤ 1_000_000)
  • param = 3 → protocol_owner. La nueva clave no está en value: apéndala como remaining_accounts[0] (solo lectura está bien). No debe ser la clave pública predeterminada, y omitir la cuenta entra en pánico en un unwrap().
  • param = 4 → fund_owner. Mismo mecanismo que 3.
  • param = 5 → create_pool_fee
  • param = 6 → disable_create_pool (cualquier value distinto de cero deshabilita)
  • param = 7 → creator_fee_rate (afirma creator_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; consulta products/cpmm/fees. No está relacionada con protocol_fee_rate, que divide la comisión de intercambio.
Cualquier otro 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
Cuentas Precondiciones
  • share_rate <= 1_000_000, de otro modo InvalidInput (6003).
  • La PDA no debe existir ya — el init de Anchor falla en una segunda llamada para el mismo par. Para cambiar una tasa, cierra la cuenta y créala de nuevo.
Postcondiciones
  • creator_fee_share almacena bump, creator, amm_config y share_rate.
  • Cada CollectCreatorFee / CollectCreatorFeePermissionless posterior en un pool creado por creator bajo amm_config resuelve 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_rate nuevamente — que es 0 a menos que un administrador haya establecido el parámetro 8 de UpdateAmmConfig.

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.
Cómo se maneja cada cuenta de origen El programa distribuye en el 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

Fuentes: