Cette page est traduite automatiquement par IA. La version anglaise fait foi.Voir la version anglaise →
Une règle de courbe est la réponse d’une plateforme à la question « quels lancements suis-je prêt à héberger ? ».
GlobalConfig définit le plancher du protocole — au moins 10M de supply, au moins 20% de la supply vendue sur la courbe, et ainsi de suite — et ces planchers sont volontairement larges pour que chaque type de plateforme s’y inscrive. Une règle de courbe est l’endroit où votre plateforme les affine à la forme que votre produit supporte réellement.Les règles vivent dans leur propre compte PlatformCurveRule, un par paire (plateforme, GlobalConfig). Elles ne peuvent que restreindre ce que la config autorise déjà ; une règle ne peut jamais élargir une limite du protocole.Le modèle mental
Trois niveaux, de l’extérieur vers l’intérieur :- Les contraintes à l’intérieur d’un groupe sont combinées avec ET. Toutes doivent être satisfaites.
- Les groupes à l’intérieur d’une règle sont combinés avec OU. Un lancement est autorisé dès qu’il satisfait un seul groupe.
Une règle ne prend effet que si
PlatformConfig.restrict_curve_param est 1. À 0, le programme ne lit pas du tout les règles, ce qui est aussi le commutateur que vous utilisez pour déployer une règle et pour la revenir en arrière.
Contraintes
Une contrainte est un triplet(champ, opérateur, valeur). Rien d’autre — pas d’expressions, pas d’imbrication.
Gte pour le plancher et une Lte pour le plafond. La même paire (champ, opérateur) ne peut pas apparaître deux fois dans un groupe, ce qui vous empêche d’écrire deux minimums contradictoires.
Champs
Les identifiants de champ sont permanents. Les nouveaux champs ne sont jamais qu’ajoutés, donc un identifiant ne change jamais de signification une fois qu’un compte de règle le contient.
Les champs dérivés sont ceux qui rendent les règles portables. Épingler
Supply et TotalFundRaisingB à des nombres exacts fixe une forme de lancement ; contraindre FundRaisingRateB fixe la relation entre eux et permet à un créateur de choisir n’importe quelle supply qui la maintient.
Les neuf modèles
Chaque modèle ci-dessous est une règle. Les contraintes sont écrites comme(champ, opérateur, valeur).
1. Un palier standard
La règle la plus simple, et le comportement exact que la liste blanche de paramètres de courbe retirée offrait : une forme, épinglée.
Tout lancement qui s’écarte dans l’un des trois est rejeté avec
CurveParamNotMatchPlatformRule.
2. Une bande au lieu d’un nombre
La raison pour laquelle les bandes existent : un créateur choisit une cible de levée de fonds avec laquelle vous êtes à l’aise, sans que vous énumériez chaque valeur.
Un groupe, quatre contraintes, et le créateur a un corridor de 50–200 SOL. Sous l’ancienne liste blanche, cela nécessitait une entrée par valeur autorisée, et le plafond de dix entrées le rendait impossible.
3. Paliers côte à côte
Les groupes sont combinés avec OU, donc chaque palier est un groupe.
L’ordre importe pour le calcul, pas pour la sémantique : l’évaluation s’arrête au premier groupe qui correspond, donc mettez votre palier le plus utilisé en premier.
4. Une bande de valorisation à la graduation
FundRaisingRateB est TotalFundRaisingB / Supply en millionièmes. La contraindre plafonne la richesse avec laquelle un token peut se diplômer indépendamment de la supply que le créateur a choisie.
Avec une supply de 1e12 et un mint de quote à 9 décimales,
85e9 / 1e12 × 1e6 = 85_000 se situe à l’intérieur de cette bande. Un créateur qui double la supply doit à peu près doubler la cible pour rester dedans — c’est le point. Deux contraintes remplacent ce qui serait autrement un tableau de paires (supply, cible).
5. Un plancher de migration
MigrateRateA est la part de la supply qui atterrit réellement dans le pool CPMM à la graduation : Supply − TotalSellA − TotalLockedAmount, divisé par la supply. C’est la profondeur du pool diplômé, et c’est le seul bouton du protocole sans équivalent côté plateforme avant que les règles n’existent.
Au moins 15% de la supply atteint le pool. Un créateur ne peut pas vendre 95% sur la courbe et laisser un carnet peu profond derrière.
Si les paramètres ne s’additionnent pas — un montant verrouillé plus grand que ce qui reste après la vente de courbe — la valeur dérivée ne peut pas être calculée et la contrainte échoue fermée, donc le lancement est rejeté plutôt que silencieusement autorisé.
6. Vesting que vous appliquez réellement
GlobalConfig.max_lock_rate plafonne le vesting par le haut. Une règle peut mettre un plancher dessous, et exiger une vraie falaise.
Entre 5% et 20% de la supply verrouillée, avec au moins une falaise de 30 jours. Utile pour une plateforme dont le pitch est « pas de lancements avec déverrouillage instantané ».
7. Gating par type de token
BaseTokenProgram et TransferFeeEnabled sont indépendants, ce qui importe : un mint Token-2022 sans TransferFeeConfig rapporte TransferFeeEnabled = 0 tout comme un mint SPL Token le fait.
8. Un plafond de frais de transfert conditionnel
Il n’y a pas d’opérateur « si », et aucun n’est nécessaire — deux groupes expriment la condition.
Une
TransferFeeConfig à taux zéro ne glisse pas à travers le groupe 0 : l’extension est présente, donc TransferFeeEnabled est 1 et seul le groupe 1 peut l’accepter.
9. Une promo limitée dans le temps, programmée à l’avance
UnixTimestamp est l’heure de bloc du lancement, donc un groupe peut porter sa propre fenêtre de validité. Vous écrivez les deux groupes aujourd’hui et le basculement se fait tout seul.
Aucune transaction n’est nécessaire à la limite. Le coût est deux emplacements de groupe au lieu d’un.
Restrictions de type de courbe
Quatre champs lisentTotalSellA : TotalSellA, SellRateA, MigrateAmountA, et MigrateRateA. Sur une config de produit constant, le créateur fournit ce nombre. Sur une config de prix fixe ou de prix linéaire, la courbe le dérive à la place, et la valeur que le programme compare est 0, ce qui rejetterait chaque lancement.
Plutôt que de vous laisser écrire une règle qui bloque silencieusement votre propre config, le programme refuse ces quatre champs au moment de l’écriture sur une config non-produit-constant, avec CurveRuleFieldNotSupportedByCurve. Seules les configs de produit constant existent aujourd’hui, donc en pratique vous ne rencontrerez pas cette erreur.
Vérifier avant d’envoyer
Les deux directions de la vérification on-chain sont disponibles hors-chain, donc ni un créateur ni une plateforme n’a besoin d’apprendre une règle en regardant les transactions revenir.Banneau de version.
- SDK :
@raydium-io/raydium-sdk-v2@0.2.42-alphaest la version à laquelle tous les autres démos de code sur ce site sont épinglés. Les deux assistants ci-dessous arrivent avec la version du SDK qui expédie le support des règles de courbe ; jusqu’à alors, portez-les depuis leplatform_curve_rule.rsdu programme ou appelez le programme et lisez le code d’erreur. - Cluster : testez d’abord sur Solana
devnet— voir Testez d’abord sur devnet. - ID du programme : voir
reference/program-addresses
Avant un lancement : ces paramètres passeront-ils ?
checkLaunchAgainstCurveRule reflète exactement la vérification du programme au moment du lancement, y compris son comportement d’échec fermé. Exécutez-le dans votre formulaire de lancement et vous pouvez désactiver le bouton d’envoi avec une raison au lieu de laisser le créateur payer pour une transaction annulée.
- Un compte de règle manquant, et une règle sans groupe, passent tous les deux. Tout comme un groupe sans contrainte. Passez
rule: undefinedpour un compte inexistant ; ne le traitez pas comme un rejet. - Les valeurs non calculables échouent fermées. Une supply zéro n’a pas de taux, et un montant verrouillé plus grand que ce que la vente de courbe laisse n’a pas de montant de migration.
actualrevientundefinedet la contrainte compte comme non satisfaite, exactement comme on-chain. - Toutes les contraintes défaillantes sont rapportées, pas seulement la première. Le programme court-circuite parce qu’il n’a besoin que d’un verdict ; l’assistant collecte tout pour que votre formulaire puisse lister chaque problème à la fois.
UnixTimestamp près d’une limite, traitez un passage comme provisoire.
Avant d’écrire une règle : ce groupe est-il valide ?
checkCurveRuleGroupWritable reflète la validation au moment de l’écriture de UpdatePlatformCurveRule — les ids de contrainte, la règle de (champ, opérateur) dupliqué, les deux limites de comptage, et la restriction de type de courbe. Exécutez-le dans votre outil d’administration de plateforme avant de signer.
Passer cette vérification signifie que la transaction ne sera pas rejetée pour être mal formée. Cela ne dit rien sur le fait que la règle est ce que vous aviez l’intention — un groupe peut être parfaitement valide et toujours rejeter chaque lancement que votre UI peut produire. C’est ce que la vérification du côté du lancement ci-dessus est pour : après avoir écrit un groupe, exécutez chaque forme que votre produit offre à travers
checkLaunchAgainstCurveRule et confirmez que chacune trouve toujours un groupe.Testez d’abord sur devnet
Activerrestrict_curve_param sur mainnet change ce que vos créateurs peuvent faire, immédiatement, pour chaque lancement. Répétez la séquence entière sur devnet avant de toucher mainnet :
- Créez une config de plateforme et une règle sur devnet, et écrivez les mêmes groupes que vous avez l’intention d’expédier.
- Exécutez chaque forme de lancement que votre UI peut produire à travers
checkLaunchAgainstCurveRule, et confirmez que les verdicts sont ceux que vous attendez — à la fois les formes qui devraient passer et les formes qui devraient être rejetées. - Activez
restrict_curve_param, puis lancez réellement un token qui devrait passer et un qui devrait être rejeté. Le second devrait échouer avecCurveParamNotMatchPlatformRule(6025), pas avecNotEnoughRemainingAccounts(6018) — ce dernier signifie que votre builder n’ajoute pas le PDA de règle et la vérification n’est pas réellement exercée. - Seulement alors répétez sur mainnet, dans le même ordre.
cluster: "devnet" quand vous le chargez, et prenez l’ID du programme devnet depuis reference/program-addresses.
L’étape 3 est celle sur laquelle il vaut la peine d’insister. L’assistant hors-chain et le programme on-chain sont deux implémentations des mêmes règles, et un lancement devnet est ce qui prouve qu’ils s’accordent pour votre règle — y compris que votre constructeur de lancement passe le compte du tout.
Exploiter une règle
Le gestionnaire délégué
Éditer les règles est un travail de routine ; une clé d’administrateur de plateforme est généralement un multisig.PlatformConfig.curve_rule_manager existe exactement pour cela : définissez-le une fois via UpdatePlatformConfig::CurveRuleManager, et ce portefeuille chaud peut alors créer, mettre à jour, supprimer et fermer les comptes de règle par lui-même. L’administrateur de la plateforme conserve le même pouvoir en parallèle, donc une clé de gestionnaire perdue est récupérable — faites-la tourner avec un autre appel d’administrateur.
Portée d’une clé de gestionnaire compromise : elle peut assouplir ou supprimer vos règles de paramètres, et elle peut réclamer le loyer d’un compte de règle. Elle ne peut pas toucher aux portefeuilles de frais, au vesting, à la config CPMM, ne peut pas basculer restrict_curve_param, et ne peut pas casser une limite GlobalConfig. Traitez-la comme une clé de configuration, pas une clé de trésorerie.
Le loyer suit le contenu
Un compte de règle est créé sans groupe et redimensionné à chaque changement, donc vous payez pour les règles que vous avez réellement écrites. Supprimer un groupe rembourse la différence au signataire.Ordre de déploiement
- Répétez la séquence entière sur devnet — voir Testez d’abord sur devnet.
- Créez le compte de règle et écrivez ses groupes. Rien ne change encore — avec
restrict_curve_paramtoujours à0, le programme ne les lit pas. - Vérifiez la règle hors-chain avec
checkLaunchAgainstCurveRule: pour chaque forme de lancement que votre UI peut produire, confirmez qu’un groupe l’accepte. - Définissez
restrict_curve_paramà1. À partir de ce moment, les lancements de vos créateurs sont vérifiés. - Pour revenir en arrière, définissez-le à
0à nouveau. Le compte de règle est laissé intact.
Coût au moment du lancement
La vérification s’exécute à chaque lancement tandis qu’elle est activée, donc son coût de calcul est une taxe par lancement. Mesuré de bout en bout — dérivation PDA, l’analyseremaining_accounts, désérialisation, et évaluation :
« Bon marché » est une lecture de champ direct comme
Supply ; « dérivé » est un champ calculé comme MigrateRateA, qui coûte environ 223 CU par contrainte contre environ 48. Même une règle complètement chargée de contraintes dérivées reste à l’intérieur d’un tiers du budget par instruction par défaut de 200 000 CU, et une règle réaliste de trois groupes est sous 6 000. Les groupes sont évalués jusqu’à ce qu’un corresponde, donc mettre votre palier commun en premier est une économie gratuite.
Où aller ensuite
products/launchlab/platform-config— les champsPlatformConfigqui gating et délèguent les règles.products/launchlab/global-config— les planchers du protocole qu’une règle affine.products/launchlab/instructions— les quatre instructions de règle et leurs comptes.products/launchlab/accounts—PlatformCurveRuledans l’inventaire des comptes.sdk-api/typescript-sdk— la surface du SDK où vivent les deux assistants de vérification.reference/changelog/2026-08-31-launchlab-platform-curve-rules— ce qui a remplacé la liste blanche de paramètres de courbe, et ce que les décodeurs doivent changer.
raydium-launch/programs/launchpad/src/states/platform_curve_rule.rs—PlatformCurveRule,CurveRuleGroup,ParamConstraint, les espaces d’id de champ et d’opérateur, etCurveRuleContext::value_of.raydium-launch/programs/launchpad/src/utils/platform_curve_rule.rs— la vérification au moment du lancement.raydium-launch/programs/launchpad/src/instructions/platform/—create,update,remove, etclose_platform_curve_rule.

