Skip to main content
このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →
カーブルールは、プラットフォームが「どの起動をホストするか」という質問に対する答えです。GlobalConfigはプロトコルフロアを設定します — 最低10M供給、供給の最低20%がカーブで販売される、など — これらのフロアは意図的に広く設定されているため、あらゆる種類のプラットフォームがそれに適合します。カーブルールは、プラットフォームがこれらを実際にサポートする製品の形状に絞り込む場所です。ルールは独自のPlatformCurveRuleアカウントに存在し、(プラットフォーム、GlobalConfig)ペアごとに1つです。これらはすでに設定で許可されているものを絞り込むことのみができます。ルールはプロトコル制限を広げることはできません。

メンタルモデル

外側から内側へ、3つのレベル:
2つのレベルのネストがこれを表現力豊かにします:
  • 1つのグループ内の制約はANDされます。 すべてが成立する必要があります。
  • 1つのルール内のグループはORされます。 起動は単一のグループを満たすとすぐに許可されます。
したがって、グループは1つの許可された形状であり、ルールはあなたが提供する形状のメニューです。ルールは最大10グループを保持でき、グループは最大25制約を保持できます。 覚えておく価値のある2つの境界ケース: ルールはPlatformConfig.restrict_curve_param1の場合にのみ有効になります。0の場合、プログラムはルールをまったく読みません。これはルールをロールアウトしてロールバックするために使用するスイッチでもあります。

制約

制約は(フィールド、オペレータ、値)の3つ組です。それ以上何もありません — 式もネストもありません。
範囲は2つの制約で、1つのグループ内の同じフィールドに対して:フロア用のGteと上限用のLte。同じ(フィールド、オペレータ)ペアは1つのグループ内に2回現れることはできません。これは矛盾する2つの最小値を書くことを防ぎます。

フィールド

フィールドIDは永続的です。新しいフィールドは常に追加されるだけなので、ルールアカウントがそれを保持すると、IDの意味は変わりません。
導出フィールドはルールをポータブルにするものです。SupplyTotalFundRaisingBを正確な数値に固定すると、1つの起動形状が固定されます。FundRaisingRateBを制約すると、それらの間の関係が固定され、クリエイターが任意の供給を選択できるようになります。
レートフィールドは1つのGlobalConfig内でのみ比較可能です。分母がそのコンフィグのクォートミントとそのデシマルに依存するためです。これは実際には制限ではありません:ルールは構造上1つのコンフィグにスコープされています。

9つのプレイブック

以下の各プレイブックは1つのルールです。制約は(フィールド、オペレータ、値)として記述されます。

1. 1つの標準ティア

最も単純なルール、および廃止されたカーブパラメータホワイトリストが提供した正確な動作:1つの形状、固定。 3つのいずれかで逸脱する起動はCurveParamNotMatchPlatformRuleで拒否されます。

2. 数値の代わりにバンド

バンドが存在する理由:クリエイターはあなたが快適な資金調達目標を選択でき、あなたがすべての値を列挙する必要がありません。 1つのグループ、4つの制約、クリエイターは50~200 SOLの廊下を持ちます。古いホワイトリストでは、これは許可された値ごとに1つのエントリが必要でした。10エントリの上限により、不可能でした。

3. ティアを並べて

グループはORされるため、各ティアはグループです。 順序は計算に関係し、セマンティクスには関係ありません:評価は最初に一致するグループで停止するため、最も使用されるティアを最初に配置します。

4. 卒業時評価バンド

FundRaisingRateBTotalFundRaisingB / Supply(百万分の1)です。これを制約すると、クリエイターが選択した供給に関係なく、トークンがどれほど豊かに卒業できるかが制限されます。 1e12供給と9小数点のクォートミントを使用すると、85e9 / 1e12 × 1e6 = 85_000がそのバンド内に収まります。供給を2倍にするクリエイターは、それに留まるために目標をほぼ2倍にする必要があります — これが要点です。2つの制約は、そうでなければ(供給、目標)ペアのテーブルになるものを置き換えます。

5. マイグレーションフロア

MigrateRateAは、卒業時にCPMMプールに実際に到達する供給のシェアです:Supply − TotalSellA − TotalLockedAmountを供給で割ったもの。これは卒業したプールの深さであり、ルールが存在する前にプラットフォーム側の同等物がない唯一のプロトコルノブです。 供給の最低15%がプールに到達します。クリエイターは曲線上で95%を販売し、浅い本を後に残すことはできません。
パラメータが加算されない場合 — ロック額が曲線販売後に残されたものより大きい — 導出値を計算できず、制約は閉じた状態で失敗するため、起動は黙って許可されるのではなく拒否されます。

6. 実際に実施するベスティング

GlobalConfig.max_lock_rateはベスティングを上から制限します。ルールはそれの下にフロアを置き、実際の崖を要求できます。 供給の5~20%がベストされ、最低30日間の崖があります。「インスタントアンロック起動なし」というピッチのプラットフォームに役立ちます。

7. トークンタイプゲーティング

BaseTokenProgramTransferFeeEnabledは独立しており、これは重要です:TransferFeeConfigのないToken-2022ミントは、SPL Tokenミントと同じようにTransferFeeEnabled = 0を報告します。

8. 条件付き転送手数料上限

「if」オペレータはなく、必要ありません — 2つのグループが条件を表現します。 ゼロレートTransferFeeConfigはグループ0をスリップしません:拡張が存在するため、TransferFeeEnabled1であり、グループ1のみがそれを受け入れることができます。

9. 時間制限プロモーション、事前にスケジュール

UnixTimestampは起動のブロック時間であるため、グループは独自の有効期間を持つことができます。両方のグループを今日書き、スイッチオーバーは自動的に発生します。 境界でトランザクションは必要ありません。コストは1つのグループスロットの代わりに2つです。

カーブタイプ制限

4つのフィールドがTotalSellAを読みます:TotalSellASellRateAMigrateAmountAMigrateRateA。定数積コンフィグでは、クリエイターがその数値を提供します。固定価格または線形価格コンフィグでは、曲線が代わりにそれを導出し、プログラムが比較する値は0です。これはすべての起動を拒否します。 あなたが自分のコンフィグを黙って拒否するルールを書くことを許可する代わりに、プログラムは非定数積コンフィグで書き込み時にこれら4つのフィールドを拒否し、CurveRuleFieldNotSupportedByCurveを返します。現在は定数積コンフィグのみが存在するため、実際にはこのエラーに遭遇することはありません。

送信する前にチェック

オンチェーンチェックの両方向はオフチェーンで利用可能なため、クリエイターもプラットフォームも、トランザクションが戻るのを見てルールを学ぶ必要はありません。
バージョンバナー。
  • SDK:@raydium-io/raydium-sdk-v2@0.2.42-alphaは、このサイトの他のすべてのコードデモが固定されているバージョンです。以下の2つのヘルパーは、カーブルールサポートを提供するSDKリリースで到着します。それまでは、プログラムのplatform_curve_rule.rsからそれらをポートするか、プログラムを呼び出してエラーコードを読んでください。
  • クラスタ:最初にSolana devnetでテストしてください — 最初にdevnetでテストを参照してください。
  • プログラムID:reference/program-addressesを参照してください
両方のヘルパーは純粋な関数です。RPCに触れないため、フォーム内のすべてのキーストロークで実行しても安全です。

起動前:これらのパラメータは合格しますか?

checkLaunchAgainstCurveRuleはプログラムの起動時チェックを正確に反映し、その失敗閉じた動作を含みます。起動フォームで実行すると、クリエイターが戻ったトランザクションに支払うことを許可する代わりに、理由を付けて送信ボタンを無効にできます。
ヘルパーが近似するのではなく再現する3つのこと:
  • ルールアカウントがない、ルールにグループがない、両方とも合格します。 グループに制約がない場合も同様です。存在しないアカウントの場合はrule: undefinedを渡します。それを拒否として扱わないでください。
  • 計算不可能な値は閉じた状態で失敗します。 ゼロ供給にはレートがなく、曲線販売が残したものより大きいロック額にはマイグレーション額がありません。actualundefinedで戻り、制約はオンチェーンと同じように満たされていないとカウントされます。
  • 最初だけでなく、すべての失敗した制約が報告されます。 プログラムは判定が必要なため短絡します。ヘルパーはすべてを収集するため、フォームは一度にすべての問題をリストできます。
それが知ることができない唯一のことは、トランザクションが実際に到達するブロック時間です。ルールがUnixTimestampを境界の近くで使用する場合、合格を暫定的に扱います。

ルールを書く前に:このグループは有効ですか?

checkCurveRuleGroupWritableUpdatePlatformCurveRuleの書き込み時検証を反映します — 制約ID、重複した(フィールド、オペレータ)ルール、両方のカウント制限、カーブタイプ制限。署名する前にプラットフォーム管理ツールで実行します。
このチェックに合格することは、トランザクションが不正な形式で拒否されないことを意味します。あなたが意図したルールであるかどうかについては何も言いません — グループは完全に有効でありながら、UIが生成できるすべての起動を拒否することができます。それが上記の起動側チェックの目的です:グループを書いた後、製品が提供できるすべての形状をcheckLaunchAgainstCurveRuleで実行し、各形状がまだグループを見つけることを確認します。

最初にdevnetでテスト

メインネットでrestrict_curve_paramを有効にすると、クリエイターが何をできるかが即座に変わり、すべての起動に対して変わります。メインネットに触れる前に、devnet上でシーケンス全体をリハーサルしてください:
  1. devnetでプラットフォームコンフィグとルールを作成し、出荷する予定の同じグループを書きます。
  2. UIが生成できるすべての起動形状をcheckLaunchAgainstCurveRuleで実行し、判定が期待したものであることを確認します — 合格すべき形状と拒否すべき形状の両方。
  3. restrict_curve_paramを有効にしてから、合格すべきトークンと拒否すべきトークンを実際に起動します。2番目はCurveParamNotMatchPlatformRule(6025)で失敗する必要があります。NotEnoughRemainingAccounts(6018)ではなく — 後者はビルダーがルールPDAを追加していないことを意味し、チェックが実際に実行されていません。
  4. その後のみメインネットで同じ順序で繰り返します。
ステップ3は主張する価値があります。オフチェーンヘルパーとオンチェーンプログラムは同じルールの2つの実装であり、devnet起動はあなたのルールに対して同意することを証明します — ビルダーがアカウントをすべて渡すことを含めて。

ルールの運用

委任されたマネージャー

ルールの編集は日常的な作業です。プラットフォーム管理キーは通常マルチシグです。PlatformConfig.curve_rule_managerはまさにそのために存在します:UpdatePlatformConfig::CurveRuleManagerを通じて一度設定すると、そのホットウォレットはルールアカウントを独自に作成、更新、削除、クローズできます。プラットフォーム管理者は並行して同じ権限を保持するため、失われたマネージャーキーは回復可能です — 別の管理者呼び出しで回転させます。 侵害されたマネージャーキーのスコープ:パラメータルールを緩和または削除でき、ルールアカウントのレントを回収できます。手数料ウォレット、ベスティング、CPMMコンフィグに触れることはできず、restrict_curve_paramをフリップすることはできず、GlobalConfig制限を破ることはできません。これを設定キーとして扱い、財務キーではありません。

レントはコンテンツに従う

ルールアカウントはグループを保持せずに作成され、変更のたびにサイズ変更されるため、実際に書いたルールに対して支払います。グループを削除すると、差分が署名者に払い戻されます。

ロールアウト順序

  1. devnet上でシーケンス全体をリハーサルしてください — 最初にdevnetでテストを参照してください。
  2. ルールアカウントを作成し、グループを書きます。まだ何も変わりません — restrict_curve_paramがまだ0の場合、プログラムはそれらを読みません。
  3. checkLaunchAgainstCurveRuleでルールをオフチェーンでチェックします:UIが生成できるすべての起動形状について、何らかのグループがそれを受け入れることを確認します。
  4. restrict_curve_param1に設定します。その時点からクリエイターの起動がチェックされます。
  5. ロールバックするには、再度0に設定します。ルールアカウントはそのまま残ります。
起動ビルダーはrestrict_curve_param1の間、ルールPDAをremaining_accountsに追加する必要があります。プログラムはアカウントが存在しない場合でも存在することを要求するため、クリエイターはそれを省略してチェックをスキップできません — 欠落しているアカウントはNotEnoughRemainingAccountsであり、合格ではありません。導出は[b"platform_curve_rule", platform_config, global_config]です。

起動時のコスト

チェックは有効な間、すべての起動で実行されるため、その計算コストは起動ごとの税です。エンドツーエンドで測定 — PDA導出、remaining_accountsスキャン、逆シリアル化、評価: 「安い」はSupplyのような直接フィールド読み取りです。「導出」はMigrateRateAのような計算されたもので、制約ごとに約223 CUのコストがかかり、約48と比較されます。導出制約の完全に読み込まれたルールでも、デフォルトの200 000 CU/命令予算の3分の1以内に留まり、現実的な3グループルールは6 000未満です。グループは1つが一致するまで評価されるため、一般的なティアを最初に配置することは無料の節約です。

次に進む場所

ソース:
  • raydium-launch/programs/launchpad/src/states/platform_curve_rule.rsPlatformCurveRuleCurveRuleGroupParamConstraint、フィールドとオペレータIDスペース、CurveRuleContext::value_of
  • raydium-launch/programs/launchpad/src/utils/platform_curve_rule.rs — 起動時チェック。
  • raydium-launch/programs/launchpad/src/instructions/platform/createupdateremoveclose_platform_curve_rule