预测市场 + SDK — 设计
日期:2026-03-10 状态:已批准 作者:BabyDriver Team
1. 背景与决策
1.1 目标
构建 Polymarket 风格的预测市场系统,集成 BabyDriver 原生 OracleHub 实现价格类市场自动结算,并提供 isomorphic TypeScript SDK 供 DApp 和 Bot 开发者使用。
1.2 关键决策
条件代币标准
ERC-1155 Conditional Tokens(Gnosis CTF)
行业标准,Polymarket 使用,生态兼容
交易模式
链上 CLOB 订单簿
L2 gas 低,资金效率高于 AMM
结算模式
混合:OracleHub 自动 + admin 手动
价格类自动化,事件类灵活
SDK 风格
isomorphic(browser + Node.js)
一个包覆盖前端 + Bot
SDK 底层库
viem
轻量、tree-shakeable、类型安全
架构
Polymarket 克隆(方案 A)
refs/ 有完整参考,行业验证
2. 合约架构
2.1 目录结构
2.2 合约职责
ConditionalTokens
ERC-1155 position tokens,split/merge/redeem
refs/conditional-tokens-contracts
CTFExchange
限价单撮合,EIP-712 签名验证,maker/taker 费率
refs/ctf-exchange
OracleResolver
混合结算 + 市场创建工厂
refs/uma-ctf-adapter 简化版
2.3 数据流
Collateral 默认 WETH(BabyDriver L2 上的 wrapped ETH)。
3. ConditionalTokens 合约
简化版 Gnosis CTF,去掉嵌套条件(parentCollectionId),只支持单层市场。
3.1 核心数据
3.2 核心函数
prepareCondition(oracle, questionId, outcomeSlotCount)
注册条件(由 OracleResolver 调用)
reportPayouts(questionId, payouts[])
Oracle 报告结果(仅 oracle 地址可调用)
splitPosition(collateral, conditionId, partition[], amount)
锁定 collateral,铸造 outcome position tokens
mergePositions(collateral, conditionId, partition[], amount)
销毁 position tokens,解锁 collateral
redeemPositions(collateral, conditionId, indexSets[])
结算后按 payout 比例赎回 collateral
getOutcomeSlotCount(conditionId)
查询 outcome 数量
3.3 简化点(vs Gnosis 原版)
去掉
parentCollectionId(不支持嵌套条件)去掉 P-256 椭圆曲线计算(collectionId 改为简单 keccak256)
positionId = uint(keccak256(collateral, conditionId, indexSet))直接计算
4. CTFExchange 订单簿
链上 CLOB,EIP-712 签名订单,任何人可以提交匹配。
4.1 Order 结构
4.2 核心函数
fillOrder(order, fillAmount, signature)
填充单个订单
matchOrders(takerOrder, makerOrders[], fillAmounts[], sigs)
批量撮合
cancelOrder(order)
maker 取消订单
incrementNonce()
批量取消(nonce 以下全部失效)
4.3 交易模式
COMPLEMENTARY
BUY YES vs BUY NO,互为对手方
最常见
MINT
两个 BUY 订单 → split collateral 铸造
新建流动性
MERGE
两个 SELL 订单 → merge positions 回 collateral
回收流动性
4.4 费率
默认 maker 0 bps, taker 2 bps (0.02%)
admin 可调
费用从交易 proceeds 中扣除
4.5 简化点(vs Polymarket 原版)
去掉 POLY_PROXY / POLY_GNOSIS_SAFE 签名类型,只支持 EOA + EIP-1271
去掉 taker 字段的定向订单(所有订单公开可填充)
去掉 operator 代理模式
5. OracleResolver 混合结算器
5.1 结算模式
5.2 核心函数
createPriceMarket(question, symbol, threshold, time, collateral, outcomeCount)
创建价格类市场
createManualMarket(question, resolver, collateral, outcomeCount)
创建事件类市场
resolvePrice(marketId)
任何人调用,自动读 OracleHub 结算
resolveManual(marketId, payouts[])
仅 resolver 可调用
getMarket(marketId)
查询市场信息
5.3 OracleHub 集成
构造函数接收
oracleHub地址(0x8016)和conditionalTokens地址resolvePrice内部调用OracleHub.getLatestPrice(symbol)获取价格价格有效性检查:staleness < 1h,否则 revert
价格类自动结算:
price > threshold ? payouts=[1,0] : payouts=[0,1]
6. TypeScript SDK
6.1 包结构
6.2 核心 API
6.3 技术栈
viem — 轻量、tree-shakeable、isomorphic
TypeScript strict mode
vitest 测试
tsup 打包(ESM + CJS 双输出)
6.4 不做
React hooks(用户自己封装)
GraphQL 索引(后续加)
WebSocket 实时订单推送(后续加)
7. 测试策略
7.1 Solidity 合约测试
ConditionalTokens
ConditionalTokens.t.sol
~20(prepare, split, merge, redeem, payout)
CTFExchange
CTFExchange.t.sol
~25(fill, match, cancel, nonce, fees, EIP-712)
OracleResolver
OracleResolver.t.sol
~15(create, resolvePrice, resolveManual, OracleHub mock)
E2E
PredictionMarketE2E.t.sol
~5(完整生命周期)
7.2 SDK 测试
helpers
helpers.test.ts
~10(ID 计算、签名)
contracts
contracts.test.ts
~15(合约交互 mock)
client
client.test.ts
~5(初始化、provider)
8. 实现范围
做
ConditionalTokens
简化版 Gnosis CTF ERC-1155
~400
CTFExchange
链上 CLOB + EIP-712
~500
OracleResolver
混合结算 + 市场工厂
~300
接口
3 个 interface 文件
~150
Foundry 测试
4 个测试文件
~800
SDK 核心
client + contracts + market + did
~600
SDK 测试
vitest
~200
不做
AMM / FPMM
选择了 CLOB,AMM 留后续
嵌套条件市场
复杂度高,MVP 不需要
链下 orderbook server
MVP 阶段链上 CLOB 够用
React hooks
SDK 只提供底层,用户自己封装 UI
GraphQL indexer
后续加
多 collateral
MVP 仅 WETH
Operator 代理模式
简化,直接 EOA 交易
9. 与现有系统的关系
OracleHub (0x8016)
OracleResolver 读取价格做自动结算
DIDRegistry (0x8017)
SDK 封装 DID 操作
CredentialRegistry (0x8018)
SDK 封装凭证操作
IdentityVerifier (0x8019)
可选:限制只有 KYC 用户可交易
FastWithdrawalPoolV2
独立,不直接集成
Last updated