MetaOracle(偏差时间锁)

MetaOracleDeviationTimelock 是一个安全封装器,用于在主预言机和备份预言机之间进行选择。当价格在持续的挑战期内偏离超过阈值时,它会切换到备份;当价格在持续的恢复期内重新收敛时,它会切回主预言机。该合约实现了 Morpho 的 IOracle 接口,因此下游系统可以像对待其他任何预言机一样对待它。

部署

使用特定网络的工厂地址来部署新的 MetaOracleDeviationTimelock 实例。

浏览器链接反映当前的公共区块浏览器;如有需要可替换为首选的区块浏览器。

审计与源码

核心行为

  • 合约在初始化后以主预言机被选中开始运行。

  • price() 反映当前激活的预言机(主或备)。

  • 偏差按如下方式计算 abs(primary - backup) * 1e18 / average(primary, backup).

  • 偏差只有在经过有时限的挑战后才会触发切换;重新收敛只有在经过有时限的恢复后才会触发切换回主预言机。

流程图

主 → 备(挑战)

spinner

备 → 主(恢复)

spinner

参数

  • primaryOracle:在正常情况下使用的首选预言机。

  • backupOracle:在偏差期间使用的备用预言机。

  • deviationThreshold:允许的最大相对偏差,按 1e18 缩放(例如, 0.01e18 表示 1%)。

  • challengeTimelockDuration:偏差必须持续的秒数,超过后才会切换到备份。

  • healingTimelockDuration:价格必须保持重新收敛的秒数,超过后才会切回主预言机。

初始化会拒绝零地址、相同的预言机地址、非正阈值,以及任何初始偏差高于 deviationThreshold.

挑战流程(主 → 备)

  1. 任何人调用 challenge() 当主预言机处于激活且价格偏离时。

  2. 合约开始一个挑战时限(challengeExpiresAt).

  3. 如果在到期前价格重新收敛,任何人都可以调用 revokeChallenge().

  4. 到期后,任何人都可以在偏差仍然存在时调用 acceptChallenge() 以切换到备份。

恢复流程(备 → 主)

  1. 任何人调用 heal() 当备预言机处于激活且价格已重新收敛时。

  2. 合约开始一个恢复时限(healingExpiresAt).

  3. 如果在到期前价格再次偏离,任何人可以调用 revokeHealing().

  4. 到期后,任何人都可以在偏差仍然存在时调用 acceptHealing() 在价格仍然收敛的情况下以切换回主预言机。

示例:XAUT/USDT 市场

设置

  • 主预言机:XAUT 由 XAU(金)参考喂价定价,USDT 固定为 1.

  • 备预言机:XAUT/USDT 市场 TWAP(两端均来自市场定价)。

流程

  1. 只要金价参考与 XAUT 市场价格接近,MetaOracle 就使用主预言机。

  2. 如果 XAUT 的交易价格偏离金价参考(或 USDT 漂移),偏差超过阈值并且 challenge() 开始时限。

  3. 如果偏差在挑战时限期间持续, acceptChallenge() 将定价切换到市场 TWAP 备份。

  4. 一旦市场价格在恢复时限内与金价参考重新收敛, acceptHealing() 将切换回主预言机。

spinner

工厂

MetaOracleDeviationTimelock 实例由 MetaOracleDeviationTimelockFactory 使用 EIP-1167 克隆部署。每次部署都会触发 MetaOracleDeployed 事件,包含代理地址、实现合约、预言机对、阈值和时限持续时间。

最后更新于