预测市场安全不变量、测试矩阵与主网上线¶
要点卡¶
30 秒回答
我不会从“列出重入和签名重放”开始,而是先写资金与状态不变量:抵押物和 outcome position 守恒,订单不超量、价格不劣化、费用不越界,取消/成交单调,resolution 只能按 冻结规则通过授权 oracle 最终一次写入,重组不能留下孤块资金事实。然后按合约、CLOB、 signer/operator、数据源/oracle、indexer、升级和运营后台建立威胁模型,用 unit、fuzz、 invariant、差分模型、fork/localnet 故障注入、升级兼容、压测和安全演练逐层取证。审计是 上线门禁之一,不是安全证明;主网还要限额灰度、独立密钥、监控、暂停/退出和事故预案。
3 分钟展开
- 不变量优先:资产守恒、order authorization、fill/cancel 单调、唯一 resolution、 canonical settlement 和账本对账。
- 攻击面分层:恶意 token/hook、ECDSA/ERC-1271、operator 越权、oracle 早报/错报、 admin/upgrade、RPC/indexer reorg、CI/供应链和后台账号。
- 测试分层:单测规则向量;fuzz 输入;stateful invariant;参考模型差分;fork/localnet 重组、宕机、升级;外审和修复复验;演练 pause/rotate/recover。
- 渐进上线:冻结机制与权限矩阵,小 TVL/少市场 canary,指标和 kill criteria 达标后 扩容;任何硬编码时间/限额都由风险评审得出,不背行业“标准值”。
| 记忆槽 | 内容 |
|---|---|
| 三个不变量 | 资金守恒;签名授权不能被扩大;orphan/争议状态不能成为最终余额 |
| 手画图 | rules/order/data → CLOB/operator → contracts/oracle → indexer/ledger,每个边界标攻击者和恢复动作 |
| 项目落点 | 用 Launchpad 类 DEX 的合约审计、索引重组、对账和发布治理举例;明确预测市场部分是迁移设计而非既有生产履历 |
| 一个取舍 | 精细 market/user pause 缩小事故面但状态更复杂;global pause 简单却可能阻断撤单和用户退出 |
错误表达
- ❌ “通过两家审计且合约不可升级就安全了;链上结算不会出现重复或回滚。”
- ✅ “审计覆盖特定 commit 和范围;不可升级也会固化缺陷,链上仍有重组、治理、预言机和外围系统风险。”
自测追问:如果攻击者拿不到私钥和管理员权限,仍能通过哪些路径造成错误结算或资金损失?
10 分钟版(威胁模型 + 上线门禁)¶
先定义系统与攻击者¶
flowchart LR
User["user / market maker"] --> API["API + CLOB"]
API --> Operator["operator / settler"]
Operator --> Exchange["exchange contracts"]
Exchange --> Asset["collateral + outcome token"]
Feed["event providers"] --> Oracle["oracle + dispute"]
Oracle --> Resolve["resolution adapter"]
Resolve --> Asset
Exchange --> Indexer["canonical indexer"]
Resolve --> Indexer
Indexer --> Ledger["ledger / market state"]
Admin["admin / upgrade / pause"] --> Exchange
Admin --> Resolve
CI["source / dependency / CI"] --> Deploy["artifact + deployment"]
Deploy --> Exchange
至少考虑:
- 普通用户、做市商、恶意 order signer、恶意 ERC-1271 wallet;
- 被入侵或作恶的 operator、oracle proposer/challenger、数据供应商;
- 被盗后台账号、admin/safe signer、CI/deployer;
- 不一致 RPC、重组链、审查/拥堵、恶意 collateral/ERC-1155 receiver;
- 内部误操作、版本漂移和事故中“带着旧状态重试”的自动化。
威胁模型要绑定代码 commit、部署拓扑、合约地址、oracle/adapter 和权限版本;架构变化后旧审计 不能自动覆盖新系统。
核心安全不变量¶
| 域 | 可测试不变量 |
|---|---|
| Collateral/CTF | split/merge/redeem 后总 claim 不超过有效抵押物;完整 set 守恒 |
| Order authorization | digest 唯一绑定 domain 与全部经济字段;执行 signer 当前有效 |
| Fill | 0 ≤ filled ≤ signed amount;部分成交累计不 overfill |
| Price | 用户实际支出/获得不劣于签名 limit;不用浮点 |
| Fee | fee 非负且不超过签名/协议允许上限;取整方向显式 |
| Cancel/status | cancel、filled、resolved 等终态单调;重启/重放不能复活订单 |
| Resolution | 只接受绑定 rules/condition 的授权结果;payout vector 合法且只能最终写入一次 |
| Settlement | tentative match 不记最终资产;finalized projection 可由 canonical block lineage 证明 |
| Ledger | 每资产双分录守恒;reorg 用 reversal/compensation,不静默 UPDATE 历史 |
| Availability | pause 后禁止风险扩大,同时保留产品承诺的撤单、查询、redeem/退出路径 |
不变量应落成测试和监控。只写“防重入、做鉴权”无法判断一个修复是否真正守住资金边界。
主要攻击路径与控制¶
1. 签名与订单¶
- domain/字段遗漏导致跨链、跨合约或“批 A 签 B”;
- salt/timestamp/nonce 唯一但 order status 未记录,仍可重复 fill;
- EOA malleability、错误
ecrecover;ERC-1271 验证结果随合约状态变化; - amount/side/tokenId 编码或 SDK 与合约 type hash 不一致;
- partial fill、rounding、fee 和 batch 累加产生 overfill/价值泄漏。
控制:官方/审计密码库、golden vectors、链上 fill status、signed economic bounds、全组合 fuzz/invariant、SDK/合约跨语言差分测试。
2. 资产与外部调用¶
- 恶意/非标准 ERC-20、转账税、回调、返回值异常;
- ERC-1155 receiver hook 或 adapter 外部调用引入重入和状态交错;
- approval 过大、adapter/collateral 地址替换、余额前后差异常;
- mint/merge 路径选错 condition/token,资产仍“守恒”但给错市场。
控制:checks-effects-interactions、最小允许资产集合、余额差验证、明确 callback/reentrancy
假设、condition-token registry/derivation 验证和 malicious-token harness。onlyOperator
减少入口但不能自动证明所有外部调用无重入风险。
3. Operator、CLOB 与交易公平¶
- sequencer 双主、WAL/数据库恢复水位不一致,重复 match;
- operator 越过 price/fee/fill 限制,审查撤单,选择性延迟或抢跑;
- settlement key 被盗,批量提交合法格式的恶意计划;
- market data gap 使做市商在错误盘口交易。
控制:单写者/fencing、确定性 WAL 回放、链上经济约束、细粒度限额、独立 signer policy、 可审计 sequence、用户可取消/暂停/退出和市场数据 gap recovery。
4. Oracle 与事件数据¶
- too-early/wrong proposal 无人 challenge;
- proposer 和 watcher 共享同一 provider/故障域;
- 题面/规则可变、source ID 映射错、赛事 correction 未处理;
- oracle callback 重放、错误 condition 或 adapter 升级错配。
控制:rules hash、独立 watcher、bond/liveness 风险参数、callback caller/assertion/condition 校验、一次性 resolution 和争议演练。
5. Admin、升级与供应链¶
- proxy 未初始化/重复初始化、storage layout 冲突、升级后 domain/订单兼容错误;
- pause/upgrader/operator 权限过大或由同一密钥控制;
- 前端/SDK、合约 artifact、deployer 参数或依赖被投毒;
- 外审后的 commit 与实际上线 bytecode 不一致。
控制:初始化锁、storage layout/upgrade tests、timelock/multisig/职责分离、artifact digest 和 provenance、verified source/bytecode、部署参数复核、fork rehearsal 和旧订单迁移计划。
测试矩阵¶
| 层 | 覆盖内容 | 关键证据 |
|---|---|---|
| Unit / rule vector | hash、price、fee、fill、CTF、状态机、权限 | 明确输入输出和 revert reason |
| Fuzz | 任意 amount、partition、签名、batch、rounding | 不 panic/revert 泄漏 + 业务 invariant |
| Stateful invariant | 随机 split/match/cancel/resolve/redeem 序列 | 资产、fill、终态长期成立 |
| Differential model | Solidity 对照简化参考模型/Go matcher | 同一命令序列结果一致 |
| Fork/localnet | 真实依赖、恶意 token、reorg、RPC failover | canonical 恢复和 tx unknown outcome |
| Upgrade compatibility | storage、domain、旧订单、旧 position/adapter | 升级前后资产与订单迁移矩阵 |
| Load/soak | 热市场、批量 settlement、oracle 高峰、背压 | P99/P999、队列、gas、失败恢复 |
| Security exercise | key compromise、错误 proposal、pause、rollback | runbook 时间线与证据完整性 |
| External audit | 指定 commit/范围的独立审查和修复复验 | 报告、issue disposition、最终 commit |
覆盖率百分比不能替代状态空间。预测市场尤其要生成:
- 同一 order 多次部分成交、取消与结算并发;
- complementary/mint/merge 混合 batch;
- 极小金额、最大金额、边界 fee 与多次向下取整;
- resolution 前后 split/merge/redeem 的合法/非法调用;
- callback、恶意 token、pause、upgrade 与 reorg 交错序列。
主网上线门禁¶
flowchart LR
RFC["mechanism + rules RFC"] --> Threat["threat model + invariants"]
Threat --> Proto["prototype / testnet"]
Proto --> Test["fuzz + invariant + fault injection"]
Test --> Audit["external audit + fix verification"]
Audit --> Rehearse["key ceremony + upgrade/pause/recovery drill"]
Rehearse --> Canary["limited markets / TVL / users"]
Canary --> Expand["progressive expansion"]
Canary -->|"kill criteria"| Pause["pause / rollback / resolve safely"]
上线前清单:
- 机制冻结:market types、CTF/neg-risk、order/fee/cancel、resolution 和 invalid policy。
- 信任矩阵:operator、oracle、admin、upgrader、pauser、signer、data provider 的能力和退出路径。
- 资产范围:允许 collateral、decimals、adapter、approval 和最大 exposure。
- 代码证据:测试、静态分析、fuzz/invariant、外审修复复验、deployed bytecode 对应 commit。
- 密钥与发布:独立环境、multisig/timelock、key ceremony、artifact digest、参数双人复核。
- 运行手册:provider stale、错误 proposal、operator key compromise、链拥堵/reorg、 indexer lag、合约 pause、升级失败和用户沟通。
- Canary:少量市场/抵押物/用户和明确限额;先验证完整 create→trade→resolve→redeem 闭环。
- 退出与恢复:暂停后用户还能做什么、未结算订单如何处理、争议如何继续、资产如何赎回。
指标与 kill criteria¶
不要等“已经损失”才暂停。可定义:
- order reject/signature failure/settlement revert 突增;
- fill ledger 与链上
OrderStatus/资产余额不一致; - collateral coverage 或 position supply invariant 破坏;
- indexer finality lag、RPC disagreement、reorg 深度超出运行假设;
- event source stale/conflict、oracle challenge deadline 无 watcher;
- admin/operator/signer 异常调用、配置或 bytecode digest 漂移;
- P99 settlement、queue age、gas 或失败重试超过容量预算。
阈值由 TVL、链特性、流动性和恢复时间目标确定;正文不提供虚假的通用“安全数字”。
新链生态依赖不完善怎么办¶
建立 capability matrix:finality/reorg、RPC 方法、event/log、fee、nonce、simulation、 contract verification、multisig/timelock、indexer、fork/localnet 和 explorer。对缺口:
- pin SDK/node/compiler 版本和 checksums,保存签名/交易/事件 golden vectors;
- adapter conformance test 验证 chain ID、地址、decimal、receipt/finality 和错误分类;
- vendoring/fork 必须记录 upstream commit、patch、许可证和升级策略;
- 主网升级前在 fork/localnet 重放历史订单、结算和 resolution;
- 能力不满足安全不变量时缩小功能或不上线,不能用人工值守代替永久控制。
事故响应¶
优先停止风险扩大、保留证据和用户退出能力:
detect → scope → precise pause → protect keys/funds
→ preserve chain/order/oracle evidence
→ reconcile canonical state
→ fix + independent review
→ controlled resume + postmortem
暂停粒度可包括 user、market、operator、oracle adapter、global trading;但每种 pause 对 撤单、在途 settlement、resolve 和 redeem 的影响必须预先测试。事故中不要升级未知代码、 删除原始账本或反复重发 unknown transaction。
架构取舍¶
不可升级减少治理攻击面,却可能无法修复已部署缺陷;可升级提高恢复能力,但引入 admin、 storage 和订单兼容风险。合理答案不是绝对选择,而是结合合约职责、TVL、退出能力、timelock、 审计和迁移路径说明残余风险。operator-only 也不是“安全结论”,只是一个必须公开的信任模型。
深挖问答¶
- 安全审计通过是否可主网? → 还需修复复验、部署一致性、密钥/权限、运行监控、灰度和事故演练。
- 最重要的预测市场不变量是什么? → 资金/position 守恒、订单授权不扩大、唯一合法 resolution、canonical 结算与账本一致。
- 如何测试签名重放? → 跨 chain/domain/contract/version、重复 order hash、部分成交、取消、epoch 和 ERC-1271 状态变化组合。
- 暂停是否越快越好? → 要快且精确;错误 global pause 可能阻断撤单/兑付,所有路径需预演。
- 不可升级更安全吗? → 减少 admin 面但固化缺陷;要结合资产退出和迁移能力评估。
- 如何证明实际上线的是审计版本? → source commit、构建环境、artifact digest、部署参数、bytecode 验证和治理交易形成证据链。
反模式与事故¶
- 只做 happy-path 单测和覆盖率统计,没有 stateful invariant。
- 把
onlyOperator当成验签、价格、fee、重入和资产检查的替代品。 - 外审后继续改合约/编译器/依赖,却沿用旧报告宣传。
- 只暂停 API,旧签名和 operator 仍可链上执行。
- 升级改变 EIP-712 domain/order struct,却没有旧订单失效与迁移计划。
- indexer 把 orphan settlement 写成最终账本,之后靠人工 UPDATE 抹平。
- 数据源、oracle proposer 和 watcher 同故障域,错误结果无人挑战。