安全
哪些东西有价值
- 池子里的 ETH 和代币,存放在任何人都无法撤出的仓位中。一个阵营的 ETH 只有在该阵营被卖入这个池子时才会离开它:由交易者卖出,或在一笔交易拉开三个价格之后由钩子的再平衡卖出。
- 奖池、创建者手续费和协议手续费,由钩子以 ETH 债权的形式保存在 Uniswap V4 的 PoolManager 中,每场对决分开记账。
什么在保护它们
- 锁定的流动性。 只有工厂合约能开设已注册池子并添加发射流动性;撤出与捐赠都会回滚。
- 受限的收款方。 奖池只回购其对决的胜者;创建者手续费只发给对决的创建者:发射它的钱包,或接受其角色转让的地址。协议手续费支付给当前金库。工厂所有者可以在 48 小时后更改该地址,也适用于已累计的协议手续费。
- 受限的工厂权限。 代币没有所有者或增发函数,钩子无法升级或暂停。所有者可以暂停新发射、为未来对决提出受限条款,或在延迟后更改金库。所有者还可以立即将所有对决兑换手续费中的协议份额降至零,或重新调高,但绝不超过对决的条款:协议未收取的部分进入奖池。所有者可以永久放弃这一角色(
renounceOwnership):此后条款、金库、协议收取比例和暂停状态都保持原样,只有已提出的变更仍可在延迟后由任何人应用。 - 先结算再兑换。 结束后的第一笔兑换会在交易前结算已结束的平均值。回购上限约为参考价之上 10%,参考价保留不足一个 tick 的精度:它是 ETH 池 tick 的 30 分钟指数平均值,并以当前 tick 为下限,因此会立即跟随价格下跌。
- 只用 ETH 的回合。 占比和平均值使用两个 ETH 池。不改变 ETH 价格的 A/B 切换不会改变信号,也不会激活原本没有活动的回合。
- 完整成交才收取预付手续费。 预先收取手续费的兑换若无法完成请求数量,就会回滚。网络 gas 费另计。
- 隔离的再平衡。 只保留盈利循环,并受买入代币所用 ETH 池的可用 ETH 限制。失败的尝试会回滚并跳过;因 gas 不足而失败时,兑换会以
ArbitrageStarved回滚,调用者无法靠少给 gas 跳过再平衡。这不保证价格一致,也不保证免受所有交易损失。 - 所有路径规则相同。 无论使用 Duel 路由器还是其他 V4 路由器,手续费、税和销毁均由钩子处理。
工厂部署时,发射即处于暂停状态。paused() 为 true 时,只有 owner() 可以发射对决;其他调用者会以 CreationPaused 回滚。所有者通过 setPaused(false) 开放发射。现有对决仍可交易。
网站显示的内容
- 图片只来自网站本身。 页面只从 Duel 自己的地址显示对决图片,而且只显示网站处理过的图片:先从文件头读取的 JPEG、PNG 或 WebP(最多 1536 × 1536 像素、5 MB),在 WebAssembly 中解码,缩放到 1024 像素以内,再去掉元数据重新编码为 WebP。页面的安全策略不允许从其他任何地方加载图片。
- 编解码器单独运行。 图片在一个独立的 Worker 中解码,只有网站能调用它,它不持有任何东西:没有密钥,也没有存储。编解码器即使存在漏洞,也只能触及它正在读取的那张图片。网站在保存之前会检查这个 Worker 返回的结果(预期尺寸的静态 WebP),用 C 编写的解码器对每张图片都重新初始化。
- 直接通过合约发射的对决。 它们的详情可以写任何地址。网站不显示 https 图片;对于 IPFS 图片,它只从公共网关获取一次(最多 5 MB、10 秒),像上传一样处理,然后显示自己的副本,否则显示阵营的首字母。
- 有上限的上传。 网站只接受来自自己页面的图片:同一地址每分钟最多十张,每天也有数量上限。没有任何对决使用的图片会在一天后删除。
如何验证
- 自动化测试覆盖合约行为、网页应用和提醒机器人。覆盖率是测试指标,不能证明所有可能行为都安全。
- 分叉测试检验与 Robinhood Chain 已部署 Uniswap V4 合约的集成,包括 Universal Router、Permit2 和 V4 Quoter。
- 回归测试保留内部审查发现的案例,包括手续费记账、发射边界情况、结算及耗尽资金的池子。
- 不变量测试在随机交易、结算和领取序列中检查记账:ETH 债权须与应付金额一致,钩子、工厂合约和路由器中不能遗留中间代币。通过配置的测试运行不代表所有可能序列都已证明安全。
内部审查发现并修复了:一条通过精确输出兑换绕过防狙击税的路径、占比无法跟随单独被买入的阵营、回购的参考价格误读已卖空的池子,以及对决元数据中的不安全链接。
报告漏洞
如果你认为发现了漏洞,感谢你花时间告诉我们。请通过 Telegram 私下联系 @chatwithdivine,说明你发现的问题,如果可以,请附上复现步骤;在公开任何信息之前,也请给我们一些时间调查。我们会尽快回复,并随时告知进展。
我们从不主动私信:请只信任 @chatwithdivine。