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 →
Los ID de programa y las semillas de PDA para CPMM se enumeran canónicamente en reference/program-addresses. Esta página se enfoca en para qué sirve cada cuenta y qué invariantes mantiene, no en las direcciones codificadas.

Las seis cuentas de un pool CPMM

Cada pool CPMM se describe completamente mediante seis direcciones derivadas del programa (PDAs) bajo el programa CPMM, más una cuenta AmmConfig compartida a la que hace referencia. Una vez que tienes los dos mints, puedes derivar todo de forma determinista sin tocar la red. Y la configuración compartida:

Derivar un pool a partir de solo dos mints

Siempre ordena los mints antes de derivar el PDA del pool. La semilla hace hash de los dos mints en orden de bytes, no en orden de usuario. Dos pools con (A, B) y (B, A) colisionarían en la cadena — la ordenación es cómo el programa hace que el mapeo sea canónico.
El ID del pool no siempre es el PDA canónico. Initialize acepta un keypair firmante arbitrario como pool_state además del PDA anterior. Si la cuenta pasada no coincide con el PDA canónico, el programa requiere que sea un firmante — es decir, el creador pasa un keypair nuevo que firma. Esta es la defensa contra front-running: cualquier tercero que corra para agarrar el PDA canónico puede ser eludido por el creador legítimo usando un keypair aleatorio en su lugar. Los PDAs posteriores (lpMint, vault0, vault1, observation) aún se derivan de poolState.key(), por lo que permanecen únicos a cualquier dirección que se haya usado. Cuando indexas pools, siempre descubre el ID del pool desde el estado en la cadena (por ejemplo, cuentas PoolState bajo el programa CPMM), no derivando el PDA canónico — este último perderá pools con keypair aleatorio.

Diseños de cuenta

Las definiciones completas de Rust viven en la fuente raydium-cp-swap. Los campos a continuación son los que leerás desde una integración.

PoolState

Qué leer realmente:
  • lp_supply — el espejo interno del pool del suministro total del mint de LP. Úsalo para matemáticas de participación de LP; el valor debe coincidir con el suministro en la cadena del mint, pero leerlo desde PoolState evita una búsqueda de cuenta adicional.
  • protocol_fees_token{0,1}, fund_fees_token{0,1} — comisiones acumuladas aún no barridas. Estas no afectan el precio del swap; se sientan en las bóvedas hasta que se llama CollectProtocolFee / CollectFundFee.
  • status — una máscara de bits que controla si Swap, Deposit, Withdraw están permitidos. Actualizado por el administrador a través de UpdatePoolStatus. El SDK verifica esto antes de construir una transacción; si estás haciendo CPI directamente, verifica tú mismo.
  • token0_program / token1_program — el programa de token en el que hacer CPI para cada bóveda. Uno puede ser SPL Token clásico y el otro Token-2022; son independientes.
  • open_time — una marca de tiempo Unix. Los swaps antes de esta hora fallan. Los depósitos se permiten antes de open_time para que el pool pueda ser sembrado.
  • creator_fee_on / enable_creator_fee — juntos controlan si la comisión de creador opcional está activa para este pool y de qué lado del swap se cobra. enable_creator_fee == false anula completamente la ruta de comisión de creador. Cuando está habilitado, creator_fee_on selecciona: 0 = tomar comisión de cualquier token que sea la entrada del swap (BothToken); 1 = tomar comisión de token_0 solo (omitir en swaps token_1 → token_0); 2 = tomar comisión de token_1 solo. Se establece en la creación del pool a través de InitializeWithPermission; no puede cambiar después.
  • creator_fees_token_{0,1} — comisiones de creador acumuladas, barridas por CollectCreatorFee o CollectCreatorFeePermissionless. Ambas rutas anulan los contadores completos; la ruta sin permisos fija los destinatarios a los ATAs canónicos de pool_creator.

AmmConfig

Tres cosas de las que tener cuidado:
  1. trade_fee_rate y creator_fee_rate son fracciones del volumen, ambas denominadas en unidades de 1/1_000_000. 2500 significa 0.25% del volumen de comercio. protocol_fee_rate y fund_fee_rate son fracciones de la comisión de comercio (no del volumen), en el mismo denominador 1/1_000_000. La comisión de creador no es una fracción de la comisión de comercio — es su propia tasa independiente. La aritmética completa está en products/cpmm/fees.
  2. index es un u16, por lo que el hash de semilla usa 2 bytes big-endian. Un error de uno en el orden de bytes es un error de integración común.
  3. AmmConfig es inmutable a nivel de pool. Un pool apunta a un AmmConfig en la creación y nunca cambia. Los cambios de comisión se propagan porque el pool lee la configuración en cada swap — pero el pool no puede moverse entre niveles de comisión.
Una nota sobre comisiones de creador: la tasa misma (creator_fee_rate) vive en AmmConfig y se comparte entre el nivel de comisión. Si un pool en particular realmente la cobra (enable_creator_fee) y de qué lado del swap cae (creator_fee_on) viven en PoolState. La comisión de creador es independiente de la comisión de comercio — es su propia tasa, acumulada a sus propios contadores (creator_fees_token_{0,1}), y nunca reduce las participaciones de LP / protocolo / fondo de la comisión de comercio. El barrido es a través de CollectCreatorFee o el CollectCreatorFeePermissionless restringido por destino. Consulta products/cpmm/fees para la mecánica completa.

Permission

Una pequeña cuenta de control de acceso utilizada por InitializeWithPermission. El programa CPMM admite una ruta de creación de pool con permisos para que otros programas (por ejemplo, LaunchLab cuando gradúa un token a CPMM) puedan probar que tienen derecho a crear un pool contra un AmmConfig dado.
El PDA de Permission se crea a través de CreatePermissionPda por el administrador de CPMM o una autoridad creadora de PDA de permiso dedicada. Solo el administrador de CPMM puede revocarlo a través de ClosePermissionPda. Los usuarios finales no interactúan directamente con esta cuenta — es plomería para flujos entre programas. Consulta security/admin-and-multisig para el límite de rol y reference/program-addresses para direcciones canónicas.

Bóvedas y Token-2022

vault0 y vault1 son propiedad del PDA de autoridad CPMM, y su propietario de programa de token (token_program) es SPL Token o Token-2022, determinado en la creación del pool por el programa del mint. El pool maneja los dos casos de forma transparente — pasas el ID de programa de token correcto para cada lado en las cuentas de instrucción Swap / Deposit / Withdraw. CPMM aplica una lista de permitidos de extensión estricta en la creación del pool (is_supported_mint en utils/token.rs). Un mint de Token-2022 puede usarse en un pool CPMM solo si cada extensión que lleva está en esta lista:
  • TransferFeeConfig. Aplicado por el mint en cada transferencia. El pool está en el lado receptor para depósitos de SwapBaseInput y en el lado de envío para retiros. El programa calcula la cantidad neta que llega a la bóveda y establece la curva en consecuencia. Consulta algorithms/token-2022-transfer-fees.
  • MetadataPointer y TokenMetadata. Metadatos estándar en el mint. Sin efecto en las matemáticas del swap.
  • InterestBearingConfig. La cantidad de UI del mint acumula interés. La bóveda almacena cantidades brutas; la curva opera solo en cantidades brutas. Las UIs que muestran APR deben llamar a los ayudantes de Token-2022 para renderizar la cantidad de UI.
  • ScaledUiAmount. Extensión de escalado de visualización de UI. El mismo tratamiento que InterestBearingConfig — la curva usa cantidades brutas.
Cualquier otra extensión — PermanentDelegate, TransferHook, DefaultAccountState, NonTransferable, ConfidentialTransfer, Group/GroupMember, MintCloseAuthority, etc. — causa que Initialize rechace con NotSupportMint. La excepción es una pequeña lista blanca de mint codificada en el programa (un puñado de pubkeys específicas) que omite la verificación de extensión; se usa para incorporar mints específicas caso por caso. La lista de extensiones verificadas y la lista blanca de mint viven en la fuente de CP-Swap bajo programs/cp-swap/src/utils/token.rs y pueden cambiar con futuras actualizaciones del programa.

Observation

La cuenta de observación es un búfer de anillo de entradas ObservationState, cada una almacenando un block_timestamp y un precio acumulativo. En cada swap, el programa añade una nueva observación si ha pasado suficiente tiempo desde la última. Los TWAPs se calculan leyendo dos observaciones y dividiendo Δcumulative / Δtime.
El búfer de anillo está dimensionado para 100 observaciones. Cada observación es 40 bytes, por lo que el array solo es 4,000 bytes; el PDA ObservationState completo es alrededor de 4,100 bytes después de los campos circundantes y el discriminador. Dos reglas de consumidor:
  • No uses una sola observación como precio. Es un acumulativo, no un precio spot. Usa dos de ellas para calcular un TWAP.
  • Elige observaciones al menos un bloque aparte. Los swaps dentro del mismo bloque pueden no producir una nueva observación; leer de forma consecutiva puede devolver el mismo registro.
Más matemáticas en products/clmm/accounts.

Ciclo de vida de la cuenta

Los pools CPMM y sus PDAs nunca se cierran. Incluso con liquidez cero, el poolState permanece. Esto es deliberado: resembrar el mismo pool más tarde preserva su búfer de observación histórico y su derivación de PDA permanece estable.

Qué leer dónde

Fuentes: