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 →
Una regla de curva es la respuesta de una plataforma a “¿qué lanzamientos estoy dispuesto a alojar?”. GlobalConfig establece el piso del protocolo — al menos 10M de suministro, al menos 20% del suministro vendido en la curva, y así sucesivamente — y esos pisos son deliberadamente amplios para que cada tipo de plataforma quepa bajo ellos. Una regla de curva es donde tu plataforma los estrecha a la forma que tu producto realmente soporta.Las reglas viven en su propia cuenta PlatformCurveRule, una por cada par (plataforma, GlobalConfig). Solo pueden estrechar lo que la configuración ya permite; una regla nunca puede ampliar un límite del protocolo.

El modelo mental

Tres niveles, de afuera hacia adentro:
Los dos niveles de anidamiento son lo que hace esto expresivo:
  • Las restricciones dentro de un grupo están ANDadas. Todas deben cumplirse.
  • Los grupos dentro de una regla están OReados. Un lanzamiento se permite tan pronto como satisface cualquier grupo único.
Entonces un grupo es una forma permitida, y la regla es el menú de formas que ofreces. Una regla puede contener hasta 10 grupos, y un grupo hasta 25 restricciones. Hay dos casos límite que vale la pena memorizar: Una regla entra en vigor solo mientras PlatformConfig.restrict_curve_param es 1. En 0 el programa no lee las reglas en absoluto, que es también el interruptor que usas para desplegar una regla y para revertirla.

Restricciones

Una restricción es una triple (campo, operador, valor). Nada más — sin expresiones, sin anidamiento.
Un rango son dos restricciones en el mismo campo dentro de un grupo: un Gte para el piso y un Lte para el techo. El mismo par (campo, operador) no puede aparecer dos veces en un grupo, lo que te impide escribir dos mínimos contradictorios.

Campos

Los ids de campo son permanentes. Los nuevos campos solo se añaden, por lo que un id nunca cambia de significado una vez que una cuenta de regla lo contiene.
Los campos derivados son los que hacen las reglas portátiles. Fijar Supply y TotalFundRaisingB a números exactos fija una forma de lanzamiento; restringir FundRaisingRateB fija la relación entre ellos y permite que un creador elija cualquier suministro que la mantenga.
Los campos de tasa solo son comparables dentro de una GlobalConfig, porque sus denominadores dependen del mint de cotización de esa configuración y sus decimales. Esto no es una limitación en la práctica: una regla está limitada a una configuración por construcción.

Los nueve patrones

Cada patrón abajo es una regla. Las restricciones se escriben como (campo, operador, valor).

1. Un nivel estándar

La regla más simple, y el comportamiento exacto que ofrecía la lista blanca de parámetros de curva retirada: una forma, fijada. Cualquier lanzamiento que se desvíe en cualquiera de los tres es rechazado con CurveParamNotMatchPlatformRule.

2. Una banda en lugar de un número

La razón por la que existen las bandas: un creador elige un objetivo de recaudación de fondos con el que te sientes cómodo, sin que tengas que enumerar cada valor. Un grupo, cuatro restricciones, y el creador tiene un corredor de 50–200 SOL. Bajo la lista blanca anterior esto necesitaba una entrada por cada valor permitido, y el límite de diez entradas lo hacía imposible.

3. Niveles lado a lado

Los grupos están OReados, así que cada nivel es un grupo. El orden importa para el cómputo, no para la semántica: la evaluación se detiene en el primer grupo que coincide, así que pon tu nivel más usado primero.

4. Una banda de valuación de graduación

FundRaisingRateB es TotalFundRaisingB / Supply en millonésimas. Restringirlo limita cuán ricamente un token puede graduarse independientemente del suministro que el creador eligió. Con un suministro de 1e12 y un mint de cotización de 9 decimales, 85e9 / 1e12 × 1e6 = 85_000 se sitúa dentro de esa banda. Un creador que duplica el suministro debe aproximadamente duplicar el objetivo para mantenerse en ella — que es el punto. Dos restricciones reemplazan lo que de otro modo sería una tabla de pares (suministro, objetivo).

5. Un piso de migración

MigrateRateA es la parte del suministro que realmente llega al pool CPMM en la graduación: Supply − TotalSellA − TotalLockedAmount, sobre el suministro. Es la profundidad del pool graduado, y es el único control del protocolo sin equivalente del lado de la plataforma antes de que existieran las reglas. Al menos el 15% del suministro llega al pool. Un creador no puede vender el 95% en la curva y dejar un libro poco profundo atrás.
Si los parámetros no suman — una cantidad bloqueada más grande que lo que queda después de la venta de la curva — el valor derivado no puede ser computado y la restricción falla cerrada, por lo que el lanzamiento es rechazado en lugar de ser silenciosamente permitido.

6. Vesting que realmente aplicas

GlobalConfig.max_lock_rate limita el vesting desde arriba. Una regla puede poner un piso bajo él, y requerir un acantilado real. Entre el 5% y el 20% del suministro bloqueado, con al menos un acantilado de 30 días. Útil para una plataforma cuya propuesta es “sin lanzamientos de desbloqueo instantáneo”.

7. Restricción por tipo de token

BaseTokenProgram y TransferFeeEnabled son independientes, lo que importa: un mint Token-2022 sin TransferFeeConfig reporta TransferFeeEnabled = 0 igual que un mint SPL Token.

8. Un límite de tarifa de transferencia condicional

No hay operador “si”, y ninguno es necesario — dos grupos expresan la condición. Una TransferFeeConfig de tasa cero no se cuela a través del grupo 0: la extensión está presente, así que TransferFeeEnabled es 1 y solo el grupo 1 puede aceptarla.

9. Una promoción limitada en tiempo, programada por adelantado

UnixTimestamp es el tiempo de bloque del lanzamiento, así que un grupo puede llevar su propia ventana de validez. Escribes ambos grupos hoy y el cambio sucede por sí solo. No se necesita transacción en el límite. El costo es dos espacios de grupo en lugar de uno.

Restricciones de tipo de curva

Cuatro campos leen TotalSellA: TotalSellA, SellRateA, MigrateAmountA, y MigrateRateA. En una configuración de producto constante el creador suministra ese número. En una configuración de precio fijo o precio lineal la curva lo deriva en su lugar, y el valor que el programa compara es 0, lo que rechazaría cada lanzamiento. En lugar de permitirte escribir una regla que silenciosamente bloquea tu propia configuración, el programa rechaza esos cuatro campos en tiempo de escritura en una configuración que no es de producto constante, con CurveRuleFieldNotSupportedByCurve. Solo existen configuraciones de producto constante hoy, así que en la práctica no encontrarás este error.

Verifica antes de enviar

Ambas direcciones de la verificación en cadena están disponibles fuera de cadena, así que ni un creador ni una plataforma tiene que aprender una regla viendo transacciones revertidas.
Banner de versión.
  • SDK: @raydium-io/raydium-sdk-v2@0.2.42-alpha es la versión a la que se fija cada otra demostración de código en este sitio. Los dos ayudantes abajo llegan con la versión del SDK que envía soporte de regla de curva; hasta entonces, portarlos del platform_curve_rule.rs del programa o llamar al programa y leer el código de error.
  • Cluster: prueba primero en Solana devnet — ver Prueba en devnet primero.
  • ID del programa: ver reference/program-addresses
Ambos ayudantes son funciones puras. No tocan RPC, así que son seguros para ejecutar en cada pulsación de tecla en un formulario.

Antes de un lanzamiento: ¿pasarán estos parámetros?

checkLaunchAgainstCurveRule refleja la verificación de tiempo de lanzamiento del programa exactamente, incluyendo su comportamiento de falla cerrada. Ejecútalo en tu formulario de lanzamiento y puedes desactivar el botón de envío con una razón en lugar de permitir que el creador pague por una transacción revertida.
Tres cosas que el ayudante reproduce en lugar de aproximar:
  • Una cuenta de regla faltante, y una regla sin grupo, ambas pasan. También lo hace un grupo sin restricciones. Pasa rule: undefined para una cuenta inexistente; no la trates como un rechazo.
  • Los valores no computables fallan cerrados. Un suministro cero no tiene tasas, y una cantidad bloqueada más grande que lo que la venta de la curva deja no tiene cantidad de migración. actual vuelve undefined y la restricción cuenta como insatisfecha, exactamente como en cadena.
  • Se reportan todas las restricciones fallidas, no solo la primera. El programa hace cortocircuito porque solo necesita un veredicto; el ayudante recopila todo para que tu formulario pueda listar cada problema a la vez.
Lo único que no puede saber es el tiempo de bloque en el que tu transacción realmente aterrizará. Si una regla usa UnixTimestamp cerca de un límite, trata un pase como provisional.

Antes de escribir una regla: ¿es este grupo válido?

checkCurveRuleGroupWritable refleja la validación de tiempo de escritura de UpdatePlatformCurveRule — ids de restricción, la regla de (campo, operador) duplicado, ambos límites de conteo, y la restricción de tipo de curva. Ejecútalo en tu herramienta de administrador de plataforma antes de firmar.
Pasar esta verificación significa que la transacción no será rechazada por estar mal formada. No dice nada sobre si la regla es lo que pretendías — un grupo puede ser perfectamente válido y aún rechazar cada lanzamiento que tu interfaz puede producir. Eso es para lo que sirve la verificación del lado del lanzamiento anterior: después de escribir un grupo, ejecuta cada forma que tu producto ofrece a través de checkLaunchAgainstCurveRule y confirma que cada una aún encuentra un grupo.

Prueba en devnet primero

Habilitar restrict_curve_param en mainnet cambia lo que tus creadores pueden hacer, inmediatamente, para cada lanzamiento. Ensaya toda la secuencia en devnet antes de tocar mainnet:
  1. Crea una configuración de plataforma y una regla en devnet, y escribe los mismos grupos que tienes la intención de enviar.
  2. Ejecuta cada forma de lanzamiento que tu interfaz puede producir a través de checkLaunchAgainstCurveRule, y confirma que los veredictos son los que esperas — tanto las formas que deberían pasar como las formas que deberían ser rechazadas.
  3. Habilita restrict_curve_param, luego realmente lanza un token que debería pasar y uno que debería ser rechazado. El segundo debería fallar con CurveParamNotMatchPlatformRule (6025), no con NotEnoughRemainingAccounts (6018) — este último significa que tu constructor no está añadiendo el PDA de regla y la verificación no está siendo realmente ejercida.
  4. Solo entonces repite en mainnet, en el mismo orden.
Apunta el SDK a devnet con cluster: "devnet" cuando lo cargues, y toma el ID del programa devnet de reference/program-addresses. El paso 3 es el que vale la pena insistir. El ayudante fuera de cadena y el programa en cadena son dos implementaciones de las mismas reglas, y un lanzamiento en devnet es lo que prueba que están de acuerdo para tu regla — incluyendo que tu constructor de lanzamiento pasa la cuenta en absoluto.

Operando una regla

El gerente delegado

Editar reglas es trabajo rutinario; una clave de administrador de plataforma es generalmente un multisig. PlatformConfig.curve_rule_manager existe exactamente para eso: establécelo una vez a través de UpdatePlatformConfig::CurveRuleManager, y ese monedero caliente puede entonces crear, actualizar, eliminar, y cerrar cuentas de regla por su cuenta. El administrador de la plataforma retiene el mismo poder en paralelo, así que una clave de gerente perdida es recuperable — rótala con otra llamada de administrador. Alcance de una clave de gerente comprometida: puede aflojar o eliminar tus reglas de parámetros, y puede reclamar la renta de una cuenta de regla. No puede tocar billeteras de tarifas, vesting, la configuración de CPMM, no puede voltear restrict_curve_param, y no puede romper un límite de GlobalConfig. Trátala como una clave de configuración, no una clave de tesorería.

La renta sigue el contenido

Una cuenta de regla se crea sin grupo y se redimensiona en cada cambio, así que pagas por las reglas que realmente escribiste. Eliminar un grupo reembolsa la diferencia al firmante.

Orden de despliegue

  1. Ensaya toda la secuencia en devnet — ver Prueba en devnet primero.
  2. Crea la cuenta de regla y escribe sus grupos. Nada cambia aún — con restrict_curve_param aún en 0 el programa no las lee.
  3. Verifica la regla fuera de cadena con checkLaunchAgainstCurveRule: para cada forma de lanzamiento que tu interfaz puede producir, confirma que algún grupo la acepta.
  4. Establece restrict_curve_param a 1. Desde ese momento los lanzamientos de tus creadores son verificados.
  5. Para revertir, establécelo a 0 nuevamente. La cuenta de regla se deja intacta.
Tu constructor de lanzamiento debe añadir el PDA de regla a remaining_accounts mientras restrict_curve_param es 1. El programa requiere que la cuenta esté presente incluso cuando aún no existe, para que un creador no pueda saltarse la verificación omitiendo — una cuenta faltante es NotEnoughRemainingAccounts, no un pase. La derivación es [b"platform_curve_rule", platform_config, global_config].

Costo en tiempo de lanzamiento

La verificación se ejecuta en cada lanzamiento mientras está habilitada, así que su costo de cómputo es un impuesto por lanzamiento. Medido de extremo a extremo — derivación de PDA, el escaneo de remaining_accounts, deserialización, y evaluación: “Barato” es una lectura de campo directo como Supply; “derivado” es uno computado como MigrateRateA, que cuesta aproximadamente 223 CU por restricción contra aproximadamente 48. Incluso una regla completamente cargada de restricciones derivadas se mantiene dentro de un tercio del presupuesto predeterminado de 200 000 CU por instrucción, y una regla realista de tres grupos está bajo 6 000. Los grupos se evalúan hasta que uno coincide, así que ordenar tu nivel común primero es ahorro libre.

A dónde ir después

Fuentes:
  • raydium-launch/programs/launchpad/src/states/platform_curve_rule.rsPlatformCurveRule, CurveRuleGroup, ParamConstraint, los espacios de id de campo y operador, y CurveRuleContext::value_of.
  • raydium-launch/programs/launchpad/src/utils/platform_curve_rule.rs — la verificación de tiempo de lanzamiento.
  • raydium-launch/programs/launchpad/src/instructions/platform/create, update, remove, y close_platform_curve_rule.