748f71da3f395611b7cf06e65e456e7144805614
WTFX 核心智能合约系统设计与实战开发指南
项目名称:WTFX (原 WTFPred / WTF Market)
核心定位:基于 Bonding Curve(多结果联动幂律 LDA 曲线)的高频预测市场协议,支持内盘快速发射与毕业后无缝转入现货/订单簿。
设计语言:Solidity^0.8.29/Cancun EVM/Arbitrum Nitro
目录
- 系统整体架构与核心组件
- 经济模型与核心数学机制
- 分档位治理体系与单市场覆盖
- 完整生命周期与业务流程
- 目录结构与代码组织
- 编译、部署与测试指南 (Robinhood Chain & 本地)
- 关键接口速查与开发示例
1. 系统整体架构与核心组件
WTFX 采用模块化解耦与可升级代理架构(Upgradeable Proxy Pattern),核心由三大支柱构成:
┌────────────────────────┐
│ WTFX 用户 / 交易者 │
└───────────┬────────────┘
│ (Mint/Redeem/Claim/Transfer)
▼
┌─────────────────────────────────────────────────────────────┐
│ WTFMarketV2.sol │
│ - ERC-6909 多代币标准(每个结果选项一个 TokenId: 1, 2, 4...) │
│ - 市场资金池状态机(Trading -> Graduated / Finalised / Refunded)│
└──────────────┬──────────────────────────────┬───────────────┘
│ │
(查询联动曲线边际价与成本) (查询市场元数据、档位与治理配置)
▼ ▼
┌─────────────────────────────┐┌──────────────────────────────┐
│ PowerLDACurveV2.sol ││ WTFControllerV2.sol │
│ - 幂律 LDA 联合曲线计算库 ││ (Upgradeable Proxy + Facade)│
│ - calMarginalPrice / Seed ││ - MarketFactory (建盘分发) │
│ - 多结果自平衡与时间衰减 ││ - Governance (分档位与参数) │
│ ││ - Registry (命题确权与争议期) │
└─────────────────────────────┘└──────────────────────────────┘
核心合约模块职责
WTFControllerV2.sol(中枢控制器):- 作为协议的主入口与可升级代理实现(Proxy Pattern);
MarketFactory:负责根据创作者配置部署专属WTFMarketV2实例,并完成初始流动性(Seed)注入;Governance:管理创作者手续费分成、中心化收益钱包(Central Wallet)、全局默认毕业阈值与 分档位(Tiers)/ 单市场覆盖(Overrides);Registry:负责链上命题元数据确权(questionId)、选项绑定与裁决争议期管理。
WTFMarketV2.sol(预测市场交易实例):- 采用 ERC-6909 多资产标准,每个预测选项对应一个独立的
tokenId(如Yes = 1,No = 2); - 独立托管抵押品(WUSD / USDC),执行交易者的买入(
mintCollateralToExactOt)与卖出(redeemExactOtToCollateral); - 实现市场毕业(
graduate)、全员返还(refund)以及最终兑付(claim)。
- 采用 ERC-6909 多资产标准,每个预测选项对应一个独立的
PowerLDACurveV2.sol(联合曲线引擎):- 基于幂律连续拍卖(Linear Discrete Auction / Power Curve)算法;
- 实现任意数量选项(2 ~ 255 个)的联动价格发现;
- 保证资金池抵押品与代币铸造的严格守恒与无摩擦做市。
2. 经济模型与核心数学机制
2.1 创作者 Seed 机制(冷启动注入)
创作者建盘时需注入一定量的底仓(Seed OT),例如每个选项 1 ~ 10 OT:
- 零额外费用:初始 Seed 调用
curve.calSeedCost,不收取创作者手续费; - 博弈论本质:Seed 锁在池子中作为底仓,创作者持有全套结果代币。即使盘子无人交易,创作者可通过
refund()或到期claim()100% 取回大部分本金。
2.2 交易手续费流向 (Fee Split)
每一笔买入/卖出交易扣除的 feeRate(创作者建盘时在 0.1% ~ 3.0% 之间自主选择并冻结):
- 50% 创作者激励:直接沉淀为创作者待提取收入;
- 50% 平台中心化钱包:流入超级管理员配置的
centralWallet。
2.3 毕业(Graduation)机制
当买方狂热将资金池推升至阈值时触发毕业:
- 触发条件:
totalMarketCap >= thresholdMcap或maxSupplySingle >= thresholdMaxSupply; - 毕业效果:
- 联合曲线立即永久冻结,停止 Curve 买卖;
- 按照各选项最终边际价格归一化计算概率分布,锁定
redeemValue; - 资金池流动性与代币可平滑迁移至外部 CLOB 订单簿或 AMM 现货池。
3. 分档位治理体系与单市场覆盖
系统彻底废弃全局一刀切设计,建立了三级优先级的治理读取模型:
ext{生效参数} = \mathbf{单市场独立覆盖 (Override)} \succ \mathbf{所属市场档位 (Tier)} \succ \mathbf{全局兜底配置 (Global Default)}
3.1 预设标准档位参数 (Robinhood / Production Grade)
| 档位 | 命名 | 定位与场景 | 毕业 mcap | 单结果供给 | 争议窗口期 |
|---|---|---|---|---|---|
| Tier 1 | PvP 极速盘 | 链上热点、KOL 互撕、数小时结算 | $3,000 WUSD | 50,000 OT | 10 分钟 (600s) |
| Tier 2 | 社区主流盘 | 赛事决赛、周度行情、经济指标 | $25,000 WUSD | 300,000 OT | 2 小时 (7200s) |
| Tier 3 | 旗舰宏观盘 | 总统大选、宏观政策、机构大盘 | $100,000 WUSD | 1,000,000 OT | 24 小时 (86400s) |
| Tier 0 | 全局默认 | 兜底未分档市场 | $10,000 WUSD | 100,000 OT | 1 小时 (3600s) |
3.2 治理接口说明
setMarketTier(tierId, mcap, maxSupply, disputeWindow):管理员配置指定档位的标准参数;setMarketTierBinding(market, tierId):为特定市场切换绑定的档位;setMarketConfigOverride(market, mcap, maxSupply, disputeWindow, isCustom):为某个重要盘子定制独一无二的阈值(isCustom=true立即生效覆盖,isCustom=false撤销并回退到档位)。
4. 完整生命周期与业务流程
[创作者建盘] ──> [联合曲线交易阶段] ──> [触发毕业] (自动/Keeper冻结曲线)
│
▼ (事件截止)
[创作者裁决] (resolveOutcome -> finaliseOutcome)
│
▼
[争议窗口期内] (10分钟 ~ 24小时)
├── 超级管理员改判 (overrideFinalise)
└── 创作者/管理员全员返还 (refund)
│
▼ (争议期结束)
[赢家兑付] (claim 销毁获胜 OT 领取抵押品)
5. 目录结构与代码组织
wtf-contract/ 目录下包含了完整的合约体系与依赖:
wtf-contract/
├── main/ # 核心主合约体系
│ ├── src/
│ │ ├── controllerv2/ # 控制器、工厂、存储与治理逻辑
│ │ │ ├── ControllerStorage.sol # 统一存储槽与数据结构定义
│ │ │ ├── Governance.sol # 治理分档位与费率逻辑
│ │ │ ├── MarketFactory.sol # 市场部署与 Seed 注入
│ │ │ ├── Registry.sol # 命题注册与裁决逻辑
│ │ │ └── WTFControllerV2.sol # 主入口与代理合约
│ │ ├── interfaces/ # 外部与内部接口
│ │ │ ├── IRegistry.sol
│ │ │ ├── IWTFControllerV2.sol
│ │ │ ├── IWTFCurve.sol
│ │ │ └── IWTFMarketV2.sol
│ │ ├── libraries/ # 核心算法、事件与自定义错误
│ │ │ ├── Errors.sol # 统一 EVM Custom Errors
│ │ │ ├── Event.sol # 链上日志定义
│ │ │ ├── QuestionV2.sol # 命题状态与哈希算法
│ │ │ └── WTFMath.sol # 高精度定点数数学库
│ │ ├── WTFERC6909.sol # 极简高效 ERC-6909 多代币实现
│ │ └── WTFMarketV2.sol # 预测市场交易与资金池状态机
│ └── lib/ # OpenZeppelin & Solady 标准依赖库
│
├── curve/ # 联合曲线与高阶数学计算库
│ └── src/
│ └── curves/
│ ├── math/ # 幂律与 LDA 边际价求解器
│ │ ├── PowerLDAMath.sol
│ │ ├── PowerMath.sol
│ │ └── LDAMath.sol
│ └── PowerLDACurveV2.sol # 联合曲线合约
│
└── mock/ # 测试辅助合约
├── MockERC20.sol # 支持无限 Mint 领水的 WUSD 抵押品
└── TestProxy.sol # 极简 Delegatecall 可升级代理
6. 编译、部署与测试指南
6.1 本地与 Robinhood Chain 测试网环境要求
- Node.js:
>= 18.0.0 - Solidity 编译器:
0.8.29 - EVM Target:
cancun(或paris/shanghai,若目标链不支持 Cancun EIP-1153,可在MarketV2中使用标准 ReentrancyGuard)
6.2 部署到 Robinhood Chain Testnet 快速配置
在 Hardhat 配置文件中添加测试网网络:
module.exports = {
solidity: {
version: "0.8.29",
settings: {
evmVersion: "cancun",
optimizer: { enabled: true, runs: 200 }
}
},
networks: {
robinhoodTestnet: {
url: "https://rpc.testnet.chain.robinhood.com",
chainId: 46630,
accounts: [process.env.PRIVATE_KEY] // 部署者私钥
}
}
};
6.3 部署核心步骤
- 部署抵押品 (WUSD):部署
MockERC20("WTF USD", "WUSD", 18); - 部署联合曲线:部署
PowerLDACurveV2; - 部署控制器代理:
- 部署
Registry库并链接部署WTFControllerV2实现; - 部署
TestProxy指向实现合约; - 调用
controller.initialize(admin, treasury, defaultFeeRate, delay);
- 部署
- 初始化参数与档位:
- 授权抵押品与曲线进入白名单;
- 调用
setMarketTier初始化 Tier 1 ($3k)、Tier 2 ($25k)、Tier 3 ($100k)。
7. 关键接口速查与开发示例
1) 创建预测市场 (deployMarket)
QuestionParams memory qParams = QuestionParams({
timestampEnd: block.timestamp + 7 days,
title: "WTFX?Robinhood Chain 主网本季度会上线吗?",
ancillaryData: "0x",
imageUri: "https://...",
outcomeNames: ["会", "不会"],
outcomeImageUris: ["", ""]
});
MarketParams memory mParams = MarketParams({
parentTokenId: 0,
collateral: wusdAddress,
curve: curveAddress,
timestampStart: block.timestamp,
feeRate: 6000000000000000, // 0.6%
tierId: 1 // Tier 1: PvP 盘
});
// otSeed = 1e18 (每选项 1 个 OT)
(bytes32 questionId, address market) = controller.deployMarket(
qParams,
mParams,
oracleAddress,
1 ether
);
2) 买入指定结果代币 (mintCollateralToExactOt)
// 在 market 合约中买入 10 个 Yes (tokenId = 1)
uint256 tokenId = 1; // 2^0
uint256 otAmount = 10 ether;
// 先 approve 给 market 合约抵押品
wusd.approve(market, type(uint256).max);
// 执行买入
market.mintCollateralToExactOt(
msg.sender,
tokenId,
otAmount,
""
);
3) 创作者裁决与结算 (resolveOutcome & finaliseOutcome)
uint256 winningAnswer = 1; // 2^0 表示 Yes 赢
// 1. 提交裁决
controller.resolveOutcome(questionId, winningAnswer);
// 2. 定案并开启争议期
controller.finaliseOutcome(questionId, winningAnswer);
4) 争议期后领取获胜收益 (claim)
uint256[] memory tokenIds = new uint256[](1);
tokenIds[0] = 1;
uint256[] memory amounts = new uint256[](1);
amounts[0] = 10 ether; // 销毁 10 个 Yes
// 自动根据资金池总金额结算抵押品返回至接收者
market.claim(msg.sender, tokenIds, amounts);
Languages
Solidity
100%