mcpField
C
configurator

configurator

github.com/uniswap开发2361.1k 次安装2 天前更新
代码仓库

关于 configurator

面向 Claude Code 的技能,用于交互式配置 Continuous Clearing Auction(CCA)智能合约参数。它会分批收集并验证输入、计算拍卖数值,并可通过 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. 批量提问 - 使用一次 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-9]+\.?[0-9]*$
  • RPC 端点 URL:优先使用 可用的公共 RPC 表中的公共端点。但无论自定义端点通过何种方式提供,在进入 获取区块编号 中的 curl 命令之前,都必须使用 https:// 协议,且不得包含下方规则列出的任何元字符或空白字符。“它是用户提供的,不是表格里的”不构成豁免理由。
  • 拒绝任何包含 Shell 元字符或空白字符的输入:;、|、&、$、`、(、)、>、<、\、'、"、空格、制表符、换行符。$(...) 和反引号即使在双引号内也会执行命令,而空格会将一个值拆成多个 curl 标志,因此绝不能安全地将它们插入命令。中止操作,并指出哪个值中的哪个字符未通过检查;不要删除违规字符后继续。
  • 绝不要未经验证就将原始用户输入传递给 Shell 命令,并且在展示给用户的任何命令中,始终使用双引号括起插入的值。

未通过任意一项检查的值也绝不会写入配置文件。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:代币地址

  • 提示:“要拍卖的代币是什么?”
  • 选项:“代币尚未部署”(占位符)、自定义地址(通过“其他”)
  • 验证:必须为以 0x 开头的 42 个字符
  • 存储:token

问题 3:总供应量

  • 提示:“要拍卖多少代币?”
  • 选项:“1 亿个代币(18 位小数)”、“10 亿个代币(18 位小数)”、“100 亿个代币(18 位小数)”、自定义(通过“其他”)
  • 验证:必须 <= 1e30 wei
  • 存储:totalSupply

问题 4:货币

  • 提示:“竞拍者应使用什么货币?”
  • 选项:“ETH(原生)”、“[网络] 上的 USDC”、“[网络] 上的 USDT”、自定义 ERC20(通过“其他”)
  • 验证:必须为以 0x 开头的 42 个字符或 address(0)
  • 存储:currency

**收集后:**验证所有输入,并显示基本配置摘要。


批次 3:时间与定价(4 个问题)

问题 1:拍卖时长

  • 提示:“拍卖应持续多久?”
  • 选项:“1 天”、“2 天”、“3 天”、“7 天”、自定义区块数(通过“其他”)
  • 根据网络区块时间计算区块数
  • 存储:auctionBlocks

问题 2:预竞拍期

  • 提示:“是否包含预竞拍期?(期间不会售出代币)”
  • 选项:“无预竞拍期(0 个区块)”、“12 小时”、“1 天”、自定义区块数(通过“其他”)
  • 根据网络区块时间计算区块数
  • 存储:prebidBlocks

问题 3:底价

  • 提示:“起始底价是多少?(每个代币对应的货币数量比例)”
  • 选项:“0.10x(1:1 比例的 10%)”、“0.01x(1:1 比例的 1%)”、“0.001x(1:1 比例的 0.1%)”、自定义比例(通过“其他”)
  • 计算 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%”、自定义百分比(通过“其他”)
  • 计算:tickSpacing = int(floorPrice * percentage)
  • **关键:**向下取整底价,使其能被刻度间距整除:
    • roundedFloorPrice = (floorPrice // tickSpacing) * tickSpacing
    • 验证:roundedFloorPrice % tickSpacing == 0 必须为 true
  • 验证:刻度间距必须至少为底价的 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)
  • “查看部署说明”(建议使用部署器技能)
  • “修改配置”
  • “退出”(直接结束;用户可以从 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 工具生成供应计划(如果服务未运行,则提供设置说明)
  • 尽量减少交互轮次 —— 每批尽可能多地收集参数
特定网络常量

将这些内容保存起来以便快速查阅:

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(连续清算拍卖)是一种新颖的拍卖机制,可将统一价格拍卖推广到连续时间。它在启动初始流动性时实现公平的价格发现,同时消除时机博弈并鼓励早期参与。

主要特性:

  • 公平的价格发现:持续清算,不存在时机博弈
  • 透明的分配:按预定计划释放供应量
  • 灵活的配置:可自定义拍卖参数和计划
  • 多链支持:在 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:每个区块 12s
  • Unichain、Base、Arbitrum:每个区块 2s
定价参数
参数类型说明
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
舍入底价(关键)

**底价 MUST 能被 tick 间距整除。**向下取整以确保可以整除:

# 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 ✓

警告:将 tick 间距设置得过小会导致拍卖的 Gas 效率极低,并可能引发 DoS 攻击。


供应计划配置

了解 MPS(毫基点)

供应计划使用 MPS = 1e7(1,000 万),其中每个单位代表千分之一个基点。

供应计划定义了代币随时间的发行速率。每个步骤包含:

  • mps:每个区块释放的代币数量(以 mps 为单位)
  • blockDelta:此速率适用的区块数
标准计划生成器

此插件包含一个 MCP 服务,可使用具有以下特性的归一化凸曲线生成供应计划:

  • 12 个步骤(默认值,可配置),用于逐步释放
  • 每个步骤释放相同数量的代币(逐步释放 70% 时,每步为 5.8333%)
  • 区块持续时间递减(凸曲线特性)
  • 较大的最后一个区块获得剩余代币(约 30%,可配置为 20%–40%)
  • 总量:释放的供应量始终恰好为 10,000,000 MPS,通过对每个步骤计算 sum(mps * blockDelta) 得出。mps 是每个区块的释放速率,而非每个步骤的 释放量,因此单独累加 mps 列不会得到 10,000,000。

使用 MCP 工具 generate_supply_schedule 生成此标准分布:

MCP 工具调用:

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

该算法会自动计算:

  1. 每个步骤释放相同数量的代币(例如,12 个步骤且逐步释放 70% 时,每步为 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 结构体。编码过程会将每个 {mps, blockDelta} 元素打包为一个 uint64。

编码算法

对于供应计划中的每个元素:

  1. 创建 uint64(64 位 / 8 字节),其中:
    • 前 24 位:mps 值(左侧填充)
    • 接下来的 40 位:blockDelta 值(左侧填充)
  2. 通过 encodePacked 将所有 uint64 打包在一起(拼接字节)
  3. 返回带 0x 前缀的十六进制字节字符串
编码公式
// 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 工具

使用 MCP 工具 encode_supply_schedule 对供应计划进行编码:

输入:

{
  "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 函数。


获取当前区块编号

使用公共 RPC 获取当前区块,以配置 startBlock:

可用的公共 RPC
网络RPC URL
主网https://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"
}

将十六进制转换为十进制,即可得到区块编号。


验证规则

生成配置前,请确保:

  1. 区块约束:startBlock < endBlock <= claimBlock
  2. 有效地址:所有地址均为有效的以太坊地址(0x + 40 个十六进制字符)
  3. 非负值:所有数值均 >= 0
  4. 底价对齐:底价必须是价格刻度间距的倍数
  5. 价格刻度间距:至少为底价的 1 个基点(建议为 1%、10%)
  6. 供应计划:最后一个区块售出大量代币(约 30% 以上)
  7. 总供应量上限:最大为 1e30 wei(1 万亿个 18 位小数代币)
  8. 不支持 FoT 代币:不支持转账收费代币
  9. 最少小数位数:请勿使用小数位数少于 6 的代币

其他资源

评论

支持 Markdown