mcpField
C
configurator

configurator

github.com/uniswap開発2361.1k 回インストール2 日前に更新
リポジトリ

configurator について

Continuous Clearing Auction(CCA)のスマートコントラクト設定を行う Claude Code 向けスキルです。質問をまとめて収集・検証し、値を計算して、MCP ツールで供給スケジュールを生成できます。

主な機能

  1. 01質問をまとめたパラメーター収集
  2. 02アドレス・チェーン・数値の検証
  3. 03オークション時間と Q96 価格の計算
  4. 04供給スケジュールの生成
  5. 05設定 JSON と概要の出力

活用シーン

  1. 01トークンオークションの設定
  2. 02オークション供給スケジュールの生成
  3. 03既存設定の確認やデプロイ

MCP 対応

MCP サーバーが稼働している場合、オークションとプレセールのブロック数を指定して `cca-supply-schedule__generate_supply_schedule` ツールを呼び出します。ツールが使えない場合の Python による代替方法も記載されています。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/uniswap/uniswap-ai --skill configurator

インストール後、Claude Code で/configuratorを入力して読み込まれたか確認します。

詳細

CCA の設定

公平で透明性の高いトークン配布のため、Continuous Clearing Auction(CCA)スマートコントラクトのパラメーターを設定します。

ランタイムの互換性: このスキルでは、対話型プロンプトに AskUserQuestion を使用します。実行環境で AskUserQuestion が利用できない場合は、自然言語での会話を通じて同じパラメーターを収集してください。

Claude Code への指示

ユーザーがこのスキルを呼び出したら、AskUserQuestion を使った一括対話型フォーム設定フローを案内します。ユーザーとのやり取りを最小限に抑えるため、パラメーターはまとめて収集してください。

一括対話型フォームのルール
  1. 質問をまとめる - 1 回の AskUserQuestion 呼び出しで最大 4 つの質問をします
  2. 直接入力を許可する - カスタム値が必要なフィールド(アドレス、数値)については、以下のようにします。
    • 「まだありません」または「今回はスキップ」の選択肢を用意します
    • 「その他」の選択肢(自動で用意されます)を使って、カスタム値を直接入力できるようにします
    • 「X はありますか?」と単独で質問することは絶対にしないでください
  3. 回答を保存する - 収集したすべての値を設定オブジェクトに記録します
  4. 収集後に検証する - 各バッチの後、次に進む前にすべての入力を検証します
  5. 進捗を表示する - 各バッチの後、収集済みのパラメーターと残りのパラメーターを表示します
入力検証ルール

上記のルール 4 では、各バッチの後に検証するよう指定しています。検証とは、以下の内容を指します。ほとんどの値は、以下に示す選択肢から選んで指定されますが、いずれの値も自由入力で指定されることがあります。AskUserQuestion が各質問で提供する「その他」の選択肢を使う場合や、上記のランタイム互換性の代替手段が適用され、AskUserQuestion が利用できない環境で通常の会話を通じて指定する場合です。カスタム RPC エンドポイントがその最もわかりやすい例です。Network の質問には名前付きネットワークが表示され、エンドポイントの入力欄はありませんが、パブリックエンドポイントを選ばないユーザーは、「その他」または会話を通じてエンドポイントを指定します。設定ファイルに書き込む前、または curl コマンドに埋め込む前に、以下のチェックに照らしてすべての値を検証してください。例外を探してはいけません。このスキルが提示した選択肢のいずれかと実際に一致する値は、すべてのチェックにそのまま合格します。また、会話による代替手段では、そもそも値がどこから来たのかを確認する方法がありません。

  • Ethereum アドレス(token、currency、tokensRecipient、fundsRecipient、validationHook):^0x[a-fA-F0-9]{40}$ に一致する必要があります。一致しない場合は拒否します
  • Chain ID:サポート対象のチェーン一覧(1、130、1301、8453、42161、11155111)に含まれている必要があります
  • 数値(供給量、価格、ブロック、MPS、ブロック差分):0 以上で、^[0-9]+\.?[0-9]*$ に一致する必要があります
  • RPC エンドポイント URL:利用可能なパブリック RPC の表にあるパブリックエンドポイントを優先してください。ただし、カスタムエンドポイントは、どのような方法で指定された場合でも、ブロック番号の取得に記載された curl コマンドに渡す前に、https:// スキームを使用し、以下のルールにあるメタ文字や空白を含まない必要があります。「ユーザーが指定した値で、表に載っていない」というのは例外になりません
  • 拒否する入力:シェルのメタ文字または空白を含む入力。対象は ;、|、&、$、`、(、)、>、<、\、'、"、スペース、タブ、改行です。$(...) とバッククォートは二重引用符の内側でもコマンドを実行し、スペースは 1 つの値を複数の curl フラグに分割するため、どちらも埋め込みに使うことは決して安全ではありません。問題のある文字を取り除いて処理を続けるのではなく、処理を中止し、どの値のどの文字が原因で失敗したかを報告してください
  • 検証せずに生のユーザー入力をシェルコマンドに渡すことは絶対にしないでください。ユーザーに提示するコマンドでは、埋め込む値を必ず二重引用符で囲んでください

いずれかのチェックに失敗した値は、設定ファイルにも書き込みません。deployer スキルはそのファイルを読み取り、各フィールドを forge および cast コマンドに埋め込みます。したがって、ここで検証されていない値を保存すると、そこでコマンドインジェクションが発生します。

設定フロー

以下のバッチに分けてパラメーターを収集します。

バッチ 1:タスクの選択(1 問)

質問 1:タスクの種類

  • プロンプト:「CCA で何を行いますか?」
  • 選択肢:「オークションパラメーターを設定する」、「供給スケジュールのみを生成する」、「既存の設定を確認する」、「既存の設定をデプロイする」

収集後:「オークションパラメーターを設定する」以外を選択した場合は、該当するセクションに進みます。


バッチ 2:基本設定(4 問)

質問 1:ネットワーク

  • プロンプト:「デプロイ先のネットワークを選択してください。」
  • 選択肢:「Ethereum Mainnet」、「Unichain (Mainnet)」、「Unichain Sepolia (Testnet)」、「Base」、「Arbitrum」、「Sepolia」
  • 保存:選択した通貨に応じた chainId、blockTime、rpcUrl、currencyDecimals

質問 2:トークンアドレス

  • プロンプト:「オークションにかけるトークンは何ですか?」
  • 選択肢:「トークンはまだデプロイされていない」(プレースホルダー)、カスタムアドレス(「Other」から指定)
  • 検証:42 文字で、0x から始まる必要があります
  • 保存:token

質問 3:総供給量

  • プロンプト:「オークションにかけるトークン数はいくつですか?」
  • 選択肢:「1 億トークン(18 桁の小数)」、「10 億トークン(18 桁の小数)」、「100 億トークン(18 桁の小数)」、カスタム(「Other」から指定)
  • 検証:1e30 wei 以下である必要があります
  • 保存:totalSupply

質問 4:通貨

  • プロンプト:「入札者が使用する通貨は何ですか?」
  • 選択肢:「ETH(ネイティブ)」、「[network] 上の USDC」、「[network] 上の USDT」、カスタム ERC20(「Other」から指定)
  • 検証:42 文字で 0x から始まるか、address(0) である必要があります
  • 保存:currency

**収集後:**すべての入力を検証し、基本設定の概要を表示します。


バッチ 3:タイミングと価格設定(4 問)

質問 1:オークション期間

  • プロンプト:「オークションの実施期間はどのくらいですか?」
  • 選択肢:「1 日」、「2 日」、「3 日」、「7 日」、カスタムのブロック数(「Other」から指定)
  • ネットワークのブロック時間に基づいてブロック数を計算します
  • 保存:auctionBlocks

質問 2:プレ入札期間

  • プロンプト:「プレ入札期間を設けますか?(この期間中はトークンを販売しません)」
  • 選択肢:「プレ入札期間なし(0 ブロック)」、「12 時間」、「1 日」、カスタムのブロック数(「Other」から指定)
  • ネットワークのブロック時間に基づいてブロック数を計算します
  • 保存:prebidBlocks

質問 3:最低価格

  • プロンプト:「開始時の最低価格はいくらですか?(トークン 1 枚あたりの通貨の比率)」
  • 選択肢:「0.10x(1:1 の比率の 10%)」、「0.01x(1:1 の比率の 1%)」、「0.001x(1:1 の比率の 0.1%)」、カスタム比率(「Other」から指定)
  • 小数桁の差を考慮して Q96 値を計算します:Q96 * ratio / 10^(tokenDecimals - currencyDecimals)
  • USDC(小数 6 桁)と 18 桁の小数のトークンの場合:Q96 * ratio / 10^12
  • ネイティブ ETH(小数 18 桁)と 18 桁の小数のトークンの場合:Q96 * ratio / 10^0 = Q96 * ratio
  • 保存:floorPriceRatio、floorPrice(Q96)、tokenDecimals、currencyDecimals

質問 4:ティック間隔

  • プロンプト:「最低価格に対する割合で、ティック間隔を指定してください。」
  • 選択肢:「最低価格の 1%(推奨)」、「最低価格の 10%」、「最低価格の 0.1%」、カスタムの割合(「Other」から指定)
  • 計算:tickSpacing = int(floorPrice * percentage)
  • 重要:ティック間隔で割り切れるよう、最低価格を切り下げます:
    • roundedFloorPrice = (floorPrice // tickSpacing) * tickSpacing
    • 確認:roundedFloorPrice % tickSpacing == 0 が真である必要があります
  • 検証:ティック間隔は最低価格の 1 ベーシスポイント以上である必要があります
  • 保存:tickSpacingPercentage、tickSpacing(Q96)、roundedFloorPrice

**収集後:**入力を検証し、最低価格が割り切れることを確認し、Q96 値を計算して表示し、タイミングの概要を表示します。


バッチ 4:受取先と開始(4 つの質問)

質問 1:トークンの受取先

  • プロンプト:「売れ残ったトークンの送付先はどこですか?」
  • 選択肢:「資金の受取先と同じ」、カスタムアドレス(「その他」経由)
  • 検証:0x で始まる 42 文字である必要があります
  • 保存先:tokensRecipient

質問 2:資金の受取先

  • プロンプト:「調達した資金の送付先はどこですか?」
  • 選択肢:「トークンの受取先と同じ」、カスタムアドレス(「その他」経由)
  • 検証:0x で始まる 42 文字である必要があります
  • 保存先:fundsRecipient

質問 3:開始時刻

  • プロンプト:「オークションはいつ開始しますか?」
  • 選択肢:「1 時間後」、「6 時間後」、「24 時間後」、カスタムブロック番号(「その他」経由)
  • RPC から現在のブロック番号を取得して計算します
  • 保存先:startBlock
  • 計算:endBlock = startBlock + prebidBlocks + auctionBlocks、claimBlock = endBlock

質問 4:必要な最低資金額

  • プロンプト:「卒業に必要な最低調達通貨額を設定しますか?」
  • 選択肢:「最低額なし(0)」、「100 ETH」、「1000 ETH」、wei 単位のカスタム金額(「その他」経由)
  • 保存先:requiredCurrencyRaised

収集後: アドレスを検証し、RPC から現在のブロック番号を取得して、ブロックのタイムライン全体を計算します。


バッチ 5:オプションのフック(1 つの質問)

質問 1:検証フック

  • プロンプト:「検証フックコントラクトを使用しますか?」
  • 選択肢:「検証フックなし」、カスタムフックアドレス(「その他」経由)
  • 検証:指定する場合は、0x で始まる 42 文字である必要があります
  • 保存先:validationHook

収集後: 指定されている場合は、フックアドレスを検証します。


ステップ 6:供給スケジュールを生成する

MCP サーバーが起動していない場合は、起動手順を提示します。

# Navigate to MCP server directory
cd packages/plugins/uniswap-cca/mcp-server/supply-schedule

# Run setup script (first time only)
chmod +x setup.sh
./setup.sh

# Start the MCP server
python3 server.py

MCP サーバーが起動したら、収集したパラメーターを指定して cca-supply-schedule__generate_supply_schedule MCP ツールを呼び出します。このツールは JSON オブジェクトを受け取ります。

{
  "auction_blocks": 86400,
  "prebid_blocks": 0
}

値を、ユーザーから収集した実際の auctionBlocks と prebidBlocks に置き換えます。

MCP ツールを利用できない場合は、フォールバックの Python アルゴリズムを直接使用します(「供給スケジュールの設定」セクションを参照)。

保存先:supplySchedule

ステップ 7:設定を生成して表示する

すべてのパラメーターを収集し、供給スケジュールを生成したら、CLI 出力に完全な JSON 設定を表示します。

{
  "[chainId]": {
    "token": "...",
    "totalSupply": ...,
    "currency": "...",
    "tokensRecipient": "...",
    "fundsRecipient": "...",
    "startBlock": ...,
    "endBlock": ...,
    "claimBlock": ...,
    "tickSpacing": ...,
    "validationHook": "...",
    "floorPrice": ...,
    "requiredCurrencyRaised": ...,
    "supplySchedule": [...]
  }
}

ファイルを自動的に作成しないでください。 JSON をコピーするか、保存するファイルパスを指定するか、ユーザーに選んでもらいます。

ステップ 8:概要を表示する

次の項目を含む、包括的で整形された概要をユーザーに表示します。

  • ネットワークとチェーン ID
  • トークンと通貨の詳細
  • ブロックのタイムライン(開始、終了、請求)と人間が読みやすい時刻
  • 価格設定(下限価格、ティック間隔)の Q96 形式と比率形式
  • 受取先(トークン、資金)
  • 供給スケジュールの概要(フェーズの合計数、最終ブロックの割合)
  • 検証チェックリスト(すべての検証ルールの合格/不合格)
ステップ 9:次の手順

次に何をするか、ユーザーに尋ねます。

  • 「ファイルに保存」(ファイルパスを尋ねます。デフォルト:script/auction-config.json)
  • 「デプロイ手順を表示」(deployer スキルの使用を提案します)
  • 「設定を変更」
  • 「終了」(そのまま終了します。ユーザーは CLI 出力から JSON をコピーできます)
重要な注意事項
  • バッチ単位で検証する — 各バッチの収集後に、すべての入力を検証します
  • 開始/終了ブロックの計算時には、 RPC から現在のブロック番号を取得します
  • Q96 値を正しく計算する — 下限価格とティック間隔について:
    • 重要: 小数点以下の桁数の違いを考慮します:Q96 * ratio / 10^(tokenDecimals - currencyDecimals)
    • USDC はすべてのネットワークで小数点以下 6 桁です。小数点以下 18 桁のトークンの場合は 10^12 で割ります
    • ネイティブ ETH は小数点以下 18 桁です。小数点以下 18 桁のトークンの場合、調整は不要です
  • 下限価格を丸めて、ティック間隔で割り切れるようにする:
    • roundedFloorPrice = (floorPrice // tickSpacing) * tickSpacing
    • 必ず確認すること: roundedFloorPrice % tickSpacing == 0
  • 供給スケジュールの生成には MCP ツールを使用する(起動していない場合はセットアップ手順を提示します)
  • やり取りの回数を最小限にする — 1 回のバッチで、可能な限り多くのパラメーターを収集します
ネットワーク固有の定数

すぐ参照できるように保存します。

const NETWORKS = {
  1: {
    name: 'Mainnet',
    blockTime: 12,
    rpc: 'https://ethereum-rpc.publicnode.com',
    usdc: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  },
  130: {
    name: 'Unichain',
    blockTime: 1,
    rpc: 'https://mainnet.unichain.org',
    usdc: '0x078D782b760474a361dDA0AF3839290b0EF57AD6',
  },
  1301: {
    name: 'Unichain Sepolia (Testnet)',
    blockTime: 2,
    rpc: 'https://sepolia.unichain.org',
    usdc: '0x078D782b760474a361dDA0AF3839290b0EF57AD6',
  },
  8453: {
    name: 'Base',
    blockTime: 2,
    rpc: 'https://mainnet.base.org',
    usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
  },
  42161: {
    name: 'Arbitrum',
    blockTime: 2,
    rpc: 'https://arb1.arbitrum.io/rpc',
    usdc: '0xaf88d065e77c8cc2239327c5edb3a432268e5831',
  },
  11155111: {
    name: 'Sepolia',
    blockTime: 12,
    rpc: 'https://ethereum-sepolia-rpc.publicnode.com',
    usdc: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',
  },
};

// Q96 = 2^96 (JavaScript BigInt notation)
const Q96 = 79228162514264337593543950336n;

Python での同等の設定:

# Q96 = 2**96
Q96 = 79228162514264337593543950336

概要

CCA(Continuous Clearing Auction)は、一様価格オークションを連続時間に一般化した新しいオークション方式です。タイミングをめぐる駆け引きをなくし、早期参加を促しながら、初期流動性の立ち上げに向けた公正な価格発見を実現します。

主な機能:

  • 公正な価格発見:タイミングをめぐる駆け引きのない連続清算
  • 透明性の高い分配:あらかじめ定められたスケジュールに従って供給を放出
  • 柔軟な設定:オークションのパラメーターとスケジュールをカスタマイズ可能
  • マルチチェーン対応:EVM チェーン全体への標準デプロイ
  • ファクトリーによるデプロイ:CREATE2 による一貫したアドレス

クイックガイド

タスク...使用するセクション
オークションのパラメーターを設定する設定ガイド
供給スケジュールを生成する供給スケジュールの設定
オークションの仕組みを理解する技術概要

設定ガイド

オークションのパラメーター

CCA オークションは、AuctionParameters 構造体で設定します。

struct AuctionParameters {
    address currency;              // Token to raise funds in (address(0) for ETH)
    address tokensRecipient;       // Address to receive leftover tokens
    address fundsRecipient;        // Address to receive all raised funds
    uint64 startBlock;             // Block when auction starts
    uint64 endBlock;               // Block when auction ends
    uint64 claimBlock;             // Block when tokens can be claimed
    uint256 tickSpacing;           // Fixed granularity for prices (Q96)
    address validationHook;        // Optional hook (use 0x0 if none)
    uint256 floorPrice;            // Starting floor price (Q96)
    uint128 requiredCurrencyRaised; // Minimum funds to graduate
    bytes auctionStepsData;        // Packed supply issuance schedule
}
設定ファイルの形式

JSON 設定ファイル(例:script/auction-config.json)を作成します。

{
  "1": {
    "token": "0x...",
    "totalSupply": 1e29,
    "currency": "0x0000000000000000000000000000000000000000",
    "tokensRecipient": "0x...",
    "fundsRecipient": "0x...",
    "startBlock": 24321000,
    "endBlock": 24327001,
    "claimBlock": 24327001,
    "tickSpacing": 79228162514264337593543950,
    "validationHook": "0x0000000000000000000000000000000000000000",
    "floorPrice": 7922816251426433759354395000,
    "requiredCurrencyRaised": 0,
    "supplySchedule": [
      { "mps": 1000, "blockDelta": 6000 },
      { "mps": 4000000, "blockDelta": 1 }
    ]
  }
}
パラメーターの詳細
基本設定
パラメーター型説明
tokenaddressオークションにかけるトークン
totalSupplynumberオークションにかけるトークンの総量(wei/最小単位)
currencyaddress購入に使用するトークン(USDC など)、または ETH の場合は address(0)
tokensRecipientaddress売れ残ったトークンの送付先
fundsRecipientaddress調達した資金の送付先
ブロック設定
パラメーター型説明制約
startBlocknumberオークションの開始時点startBlock < endBlock
endBlocknumberオークションの終了時点endBlock <= claimBlock
claimBlocknumberトークンを請求できる時点claimBlock >= endBlock

ネットワークごとのブロック時間:

  • Mainnet、Sepolia:1 ブロックあたり 12 秒
  • Unichain、Base、Arbitrum:1 ブロックあたり 2 秒
価格設定パラメーター
パラメーター型説明
floorPricenumber最低価格(Q96 形式)
tickSpacingnumber価格ティックの増分(Q96 形式)
validationHookaddress任意の検証コントラクト(指定しない場合は 0x0 を使用)
requiredCurrencyRaisednumber必要な最低調達額(最低額を設定しない場合は 0)
供給スケジュール
パラメーター型説明
supplySchedulearray{mps, blockDelta} オブジェクトの配列

価格の計算(Q96 形式)

CCA では、価格を高精度で計算するために Q96 固定小数点形式を使用します。基準値 2^96(79228162514264337593543950336)は、1:1 の価格比を表します。

最低価格の計算

重要:トークンと通貨の小数桁数の違いを考慮してください。

# Base value for 1:1 ratio
Q96 = 79228162514264337593543950336

# Formula: Q96 * (human price ratio) / 10^(token_decimals - currency_decimals)

# Example 1: USDC (6 decimals) per 18-decimal token at $0.10 ratio
token_decimals = 18
currency_decimals = 6  # USDC has 6 decimals
decimal_adjustment = 10 ** (token_decimals - currency_decimals)  # 10^12

floorPrice = Q96 * 0.1 / decimal_adjustment
# Result: 7922816251426433759354395 (approximately)

# Example 2: Native ETH (18 decimals) per 18-decimal token at 0.1 ratio
token_decimals = 18
currency_decimals = 18  # Native ETH has 18 decimals
decimal_adjustment = 10 ** (18 - 18)  # 10^0 = 1

floorPrice = Q96 * 0.1 / 1
# Result: 7922816251426433759354395034

重要なポイント: USDC はすべてのネットワークで小数桁数が 6 桁です。そのため、USDC と小数桁数が 18 桁のトークンを使用する場合は、10^12 で割る必要があります。

ティック幅の計算

ティック幅は、入札を配置できる価格を決定します。最低でも最低価格の 1 ベーシスポイントを選択してください。 1% または 10% も妥当です。

# Example: 1% of floor price
tickSpacing = int(floorPrice * 0.01)

# For floorPrice = 7922816251426433759354395000
# Result: 79228162514264337593543950
下限価格の丸め(重大)

下限価格はティック間隔で割り切れる必要があります。 正確に割り切れるように切り捨てます。

# Calculate tick spacing first
tickSpacing = int(floorPrice * 0.01)  # 1% of floor price

# Round floor price DOWN to be evenly divisible
roundedFloorPrice = (floorPrice // tickSpacing) * tickSpacing

# VERIFY divisibility (must be True)
assert roundedFloorPrice % tickSpacing == 0, "Floor price must be divisible by tick spacing!"

例:

Q96 = 79228162514264337593543950336
raw_floor_price = int(Q96 * 0.0001)  # 0.0001 ETH per token
# Result: 7922816251426434139029504

tick_spacing = int(raw_floor_price * 0.01)  # 1%
# Result: 79228162514264350785536

rounded_floor_price = (raw_floor_price // tick_spacing) * tick_spacing
# Result: 7843588088912170727768064

# Verify: 7843588088912170727768064 / 79228162514264350785536 = 99 (exact)
# Remainder: 0 ✓

警告:ティック間隔を小さく設定しすぎると、オークションのガス効率が極端に悪くなり、DoS 攻撃につながる可能性があります。


供給スケジュールの設定

MPS(ミリベーシスポイント)について

供給スケジュールでは MPS = 1e7(1,000 万)を使用します。各単位は 1 ベーシスポイントの 1000 分の 1 を表します。

供給スケジュールは、時間の経過に伴うトークン発行率を定義します。各ステップには次の値が含まれます。

  • mps:ブロックごとにリリースされるトークン数(mps 単位)
  • blockDelta:このレートが適用されるブロック数
標準スケジュール生成ツール

このプラグインには、次の特性を持つ正規化された凸曲線を使用して供給スケジュールを生成する MCP サーバーが含まれています。

  • 12 ステップ(デフォルト、変更可能)で段階的にリリース
  • ステップごとのトークン量は均等(段階的リリースが 70% の場合は 5.8333%)
  • ブロック期間は減少(凸曲線の特性)
  • 最終ブロックには残りのトークン(約 30%、変更可能な範囲は 20~40%)が割り当てられます
  • 合計:リリースされる供給量は、各ステップについて sum(mps * blockDelta) を計算した値が常にちょうど 10,000,000 MPS になります。mps はブロックごとのリリース率であり、ステップごとの量ではないため、mps 列だけを合計しても 10,000,000 にはなりません。

generate_supply_schedule MCP ツールを使用して、この標準分布を生成します。

MCP ツールの呼び出し:

{
  "auction_blocks": 86400,
  "prebid_blocks": 0
}

このアルゴリズムでは、次の値が自動的に計算されます。

  1. ステップごとの均等なトークン量(例:段階的リリースが 70% の場合、12 ステップでそれぞれ 5.8333%)
  2. 正規化曲線 C(t) = t^α(デフォルト α = 1.2)に基づく時間境界
  3. 時間とともに減少するブロック期間(凸曲線の特性)
  4. sum(mps * blockDelta) がちょうど 10,000,000 MPS になるようにする最終ブロックの調整
例:Base での 2 日間のオークション

Base は 2 秒間隔でブロックを生成するため、2 日間は 86400 ブロックです。

generate_supply_schedule を次のように呼び出します。

{
  "auction_blocks": 86400,
  "prebid_blocks": 0
}

出力(正規化された凸分布):

{
  "schedule": [
    { "mps": 54, "blockDelta": 10894 },
    { "mps": 68, "blockDelta": 8517 },
    { "mps": 75, "blockDelta": 7803 },
    { "mps": 79, "blockDelta": 7373 },
    { "mps": 83, "blockDelta": 7068 },
    { "mps": 85, "blockDelta": 6835 },
    { "mps": 88, "blockDelta": 6647 },
    { "mps": 90, "blockDelta": 6490 },
    { "mps": 92, "blockDelta": 6356 },
    { "mps": 94, "blockDelta": 6238 },
    { "mps": 95, "blockDelta": 6136 },
    { "mps": 97, "blockDelta": 6043 },
    { "mps": 2988006, "blockDelta": 1 }
  ],
  "auction_blocks": 86400,
  "prebid_blocks": 0,
  "total_phases": 13,
  "summary": {
    "total_mps": 10000000,
    "target_mps": 10000000,
    "final_block_mps": 2988006,
    "final_block_percentage": 29.88,
    "num_steps": 12,
    "alpha": 1.2,
    "main_supply_pct": 70.0,
    "step_tokens_pct": 5.8333
  }
}

注:

  • ブロック期間は減少します:10894 → 8517 → 7803 → ... → 6043
  • ステップごとのトークン量はおおむね均等です(それぞれ約 5.8333%)
  • 最終ブロックには全トークンの 29.88% が含まれます
  • sum(mps * blockDelta) はちょうど 10,000,000 MPS です(mps 列だけの合計はかなり小さくなります)
例:事前入札期間がある場合

トークンがリリースされない事前入札期間(mps=0)を追加します。事前入札期間はスケジュールの先頭に追加されます。

generate_supply_schedule を次のように呼び出します。

{
  "auction_blocks": 86400,
  "prebid_blocks": 43200
}

出力:

{
  "schedule": [
    { "mps": 0, "blockDelta": 43200 },
    { "mps": 54, "blockDelta": 10894 },
    { "mps": 68, "blockDelta": 8517 },
    ...
    { "mps": 2988006, "blockDelta": 1 }
  ],
  "auction_blocks": 86400,
  "prebid_blocks": 43200,
  "total_phases": 14,
  "summary": {
    "total_mps": 10000000,
    "target_mps": 10000000,
    "final_block_mps": 2988006,
    "final_block_percentage": 29.88,
    "num_steps": 12,
    "alpha": 1.2,
    "main_supply_pct": 70.0,
    "step_tokens_pct": 5.8333
  }
}

**注:**事前入札フェーズは mps: 0 として先頭に追加されるだけです。オークション部分では、引き続き同じ正規化された凸分布が使用されます。

カスタムスケジュール

独自の分布を設定する場合は、スケジュールを手動で定義します。

{
  "supplySchedule": [
    { "mps": 100, "blockDelta": 5000 },
    { "mps": 200, "blockDelta": 5000 },
    { "mps": 500, "blockDelta": 4400 }
  ]
}

重要:価格操作を防ぐため、最終ブロックでは大量のトークン(通常 30% 以上)を販売する必要があります。


オンチェーンデプロイ用の供給スケジュールのエンコード

供給スケジュールを生成した後、オンチェーンの AuctionParameters 構造体用に bytes 形式へエンコードする必要があります。このエンコードでは、各 {mps, blockDelta} 要素を uint64 にまとめます。

エンコードアルゴリズム

供給スケジュールの各要素について、次の処理を行います。

  1. 次の値を含む uint64(64 ビット/8 バイト)を作成します。
    • 最初の 24 ビット:mps 値(左側をパディング)
    • 次の 40 ビット:blockDelta 値(左側をパディング)
  2. encodePacked を使用してすべての uint64 をまとめます(バイト列を連結)
  3. 0x プレフィックス付きの 16 進 bytes 文字列として返します
エンコード式
// Solidity equivalent
uint64 packed = (uint64(mps) << 40) | uint64(blockDelta);
bytes memory auctionStepsData = abi.encodePacked(packed1, packed2, ...);
値の制約
  • mps:24 ビットに収まる必要があります(最大値:16,777,215)
  • blockDelta:40 ビットに収まる必要があります(最大値:1,099,511,627,775)
MCP ツールの使用

供給スケジュールをエンコードするには、encode_supply_schedule MCP ツールを使用します。

入力:

{
  "schedule": [
    { "mps": 0, "blockDelta": 43200 },
    { "mps": 54, "blockDelta": 10894 },
    { "mps": 68, "blockDelta": 8517 }
  ]
}

出力:

{
  "encoded": "0x0000000000a8c00000003600002aa60000004400002145...",
  "length_bytes": 112,
  "num_elements": 14
}
手動エンコードの例(Python)
def encode_supply_schedule(schedule):
    """Encode supply schedule to bytes."""
    encoded_bytes = b''

    for item in schedule:
        mps = item['mps']
        block_delta = item['blockDelta']

        # Validate bounds
        assert mps < 2**24, f"mps {mps} exceeds 24-bit max"
        assert block_delta < 2**40, f"blockDelta {block_delta} exceeds 40-bit max"

        # Pack into uint64: mps (24 bits) << 40 | blockDelta (40 bits)
        packed = (mps << 40) | block_delta

        # Convert to 8 bytes (big-endian)
        encoded_bytes += packed.to_bytes(8, byteorder='big')

    return '0x' + encoded_bytes.hex()

# Example
schedule = [
    {"mps": 0, "blockDelta": 43200},
    {"mps": 54, "blockDelta": 10894}
]
encoded = encode_supply_schedule(schedule)
print(encoded)  # 0x0000000000a8c00000003600002aa6
設定フローとの統合

コンフィギュレータースキルを使用する場合:

  1. generate_supply_schedule MCP ツールでスケジュールを生成します
  2. encode_supply_schedule MCP ツールでスケジュールをエンコードします
  3. エンコードされたバイト列を最終的な設定出力に含めます
  4. auctionStepsData パラメーターとしてデプロイスクリプトに渡します

エンコードされたバイト列は、configData パラメーターの一部として Factory の initializeDistribution 関数に渡されます。


現在のブロック番号の取得

startBlock の設定に使用する現在のブロックを取得するには、パブリック RPC を使用します。

利用可能なパブリック RPC
ネットワークRPC URL
Mainnethttps://ethereum-rpc.publicnode.com
Unichainhttps://unichain-rpc.publicnode.com
Basehttps://mainnet.base.org
Arbitrumhttps://arb1.arbitrum.io/rpc
Sepoliahttps://ethereum-sepolia-rpc.publicnode.com
ブロック番号の取得
curl -X POST "https://mainnet.base.org" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_blockNumber",
    "params": [],
    "id": 1
  }'

レスポンス:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x123abc"
}

ブロック番号を得るには、16 進数を 10 進数に変換します。


検証ルール

設定を生成する前に、次の点を確認してください。

  1. ブロック制約:startBlock < endBlock <= claimBlock
  2. 有効なアドレス:すべてのアドレスが有効な Ethereum アドレス(0x + 40 桁の 16 進数)であること
  3. 負でない値:すべての数値が >= 0 であること
  4. フロア価格の整合性:フロア価格がティック間隔の倍数であること
  5. ティック間隔:フロア価格の少なくとも 1 ベーシスポイント(1%、10%を推奨)
  6. 供給スケジュール:最後のブロックで相当量のトークン(約 30%以上)が販売されること
  7. 総供給量の上限:最大 1e30 wei(18 桁の小数を持つ 1 兆トークン)
  8. FoT トークン不可:転送時手数料のあるトークンはサポートされていません
  9. 最小小数桁数:小数桁数が 6 未満のトークンは使用しないでください

追加リソース

コメント