L1 Oracle Reader — 设计

日期: 2026-03-03 状态: 已批准 前置: Phase 2(Oracle 系统合约 0x8016)、Phase 3(FastWithdrawalPoolV2 + IMailbox)

目标

在 L1 上实现 Oracle 价格查询能力,配置 TestnetVerifier 和 ValidatorTimelock,为 BabyDriver testnet 部署做准备。

架构决策

决策 1: L1 Oracle — 独立合约(Sidecar 模式)

选择方案 B,与 Phase 3 的 FastWithdrawalPoolV2 一致:

方案
描述
选择

A: Diamond Facet

修改 ZKChainStorage,深度集成

❌ 存储布局风险

B: 独立合约

L1OracleReader + Mailbox 证明

选定

C: Facet + 委托

Diamond 薄代理 + 外部合约

❌ 过度工程

理由: 零 era-contracts 修改,保持 fork 干净,MVP 最务实。

决策 2: Oracle L1 查询机制 — L2→L1 消息证明

通过 IMailbox.proveL2MessageInclusion() 验证 L2 OracleHub 发出的价格消息。 无信任模式:任何人都可以提交有效证明来更新 L1 价格。

决策 3: TestnetVerifier + ValidatorTimelock — 配置任务

两个组件已存在于 era-contracts,不需要写新合约:

  • TestnetVerifier: 部署时选用,空 proof 跳过验证

  • ValidatorTimelock: 配置角色和延迟参数

L1OracleReader 合约设计

数据流

接口

核心合约

关键设计点

  • 无信任: 任何人可提交证明(与 FastWithdrawalPoolV2 settler 模式一致)

  • 防重放: _processedMessages[keccak256(batchNumber, messageIndex)]

  • 时间戳递增: 只接受更新的价格(newTimestamp > existing.timestamp

  • sender 验证: L2Message.sender 必须等于 L2_ORACLE_HUB

  • 复用 IMailbox: 与 FastWithdrawalPoolV2 共享接口和 MockMailbox

TestnetVerifier 配置

ValidatorTimelock 配置

文件清单

文件
操作
说明

contracts/src/interfaces/IL1OracleReader.sol

新建

Oracle 读取器接口

contracts/src/oracle/L1OracleReader.sol

新建

核心合约

contracts/test/L1OracleReader.t.sol

新建

完整测试套件

contracts/test/mocks/MockMailbox.sol

复用

Phase 3 已创建

contracts/src/interfaces/IMailbox.sol

复用

Phase 3 已创建

测试计划(~15 个测试)

核心功能:

  • 有效证明更新价格

  • 无效证明拒绝

  • 错误 sender 拒绝(非 OracleHub)

  • 重放保护

  • 旧时间戳不覆盖新价格

  • 多交易对独立更新

  • 未初始化返回零值

边界情况:

  • 零价格拒绝

  • 构造函数参数校验

  • view 函数正确性

集成:

  • 多人可提交证明

  • 连续多次更新同一交易对

Last updated