跳到正文

如何监控代理合约升级

监控可升级代理的实现、信标与控制权变更,并在执行后核验代码、存储兼容性、初始化、权限和关键行为。

更新于

仅供教育参考,不构成投资建议;投资可能产生损失。

直接答案

监控可升级系统时,既要看代理地址,也要看它的控制路径。告警应指出谁能授权和执行升级、是否有强制延迟、旧实现与新实现是什么,以及初始化调用数据。执行后还要独立读取链上配置并测试关键行为。

代理地址及其余额可以保持不变,而委托执行的代码却能改变权限、费用、记账、暂停机制或提款逻辑。过去的审计不会自动覆盖新实现及其初始化过程。

工作原理

首先识别代理模式。ERC-1967 为 eip1967.proxy.implementationeip1967.proxy.beacon 和可选的 eip1967.proxy.admin 分别定义了存储槽。直接更换实现时应发出 Upgraded,更换信标地址时应发出 BeaconUpgraded,管理员槽变更时应发出 AdminChanged。对于信标代理,还要调用信标的 implementation(),因为信标可在代理的信标槽不变时更换实现。

不要根据管理员槽推断完整的权限模型。Transparent 代理可能通过 ProxyAdmin 控制,而 UUPS 的升级授权由当前逻辑合约中的 _authorizeUpgrade 实现。需要追踪所有者、角色、多签阈值、时间锁、治理合约、紧急路径,以及修改这些控制措施的能力。

同时使用事件订阅和定期状态读取。ERC-1967 建议发出相应事件,但并不强制每个实现都发出。通过独立 RPC 节点记录链、区块、交易、代理、实现或信标、运行时代码哈希、执行者及相关控制状态。对已排期、已取消和已执行的操作分别告警,并按该链选定的确认或最终性策略等待后,再将状态视为稳定。

示例

某借贷代理由 3-of-5 多签通过 24-hour 时间锁控制。升级排期后,监控器记录提案标识符、目标、调用数据、最早执行时间、当前实现、拟议实现及源码验证状态。审查者比较代码和存储布局,检查初始化调用,并核对角色、外部调用、费用、暂停规则和提款路径的变化。

执行后,监控器再次读取相关 ERC-1967 槽,核验部署的运行时代码,并检查实现版本、管理员或角色持有人、暂停状态、资产记账和只读提款预览等预期后置条件。如果观察到的地址或代码哈希与已审提案不符,或定期轮询发现事件未报告的变更,则触发第二次告警。

风险

  • 控制权风险: 名义上的多签可能被其他所有者、角色、模块、治理合约、紧急密钥或可变时间锁绕过。应沿每条路径追踪到最终签名者和延迟。
  • 代码与存储风险: 未验证代码、不兼容的存储布局、不安全的初始化或依赖项变化,可能破坏状态或授予非预期权限。应验证实际部署的构件,而不是只看仓库分支或审计名称。
  • 监控风险: 单一 RPC、只看事件的索引器、前端或区块浏览器都可能延迟或出错。应跨独立数据源核对事件、存储、字节码、交易回执和协议状态。
  • 响应风险: 没有负责人和已演练流程的告警可能来得太迟。应明确延迟期内由谁审查、暂停集成、沟通或退出,同时认识到仓促批准和非官方恢复链接会带来额外风险。

最低运行手册:

  1. 盘点每条链上的所有代理、信标、实现、管理员、角色和升级入口。
  2. 保存存储槽、代码哈希、控制状态及关键只读结果的已知良好基线。
  3. 在治理或时间锁允许时于执行前告警,并在执行或取消时再次告警。
  4. 将实际执行的目标、调用数据、实现、字节码、存储布局和升级后状态与已审提案比较。
  5. 对意外变更、后置条件失败、源码未验证或延迟被缩短或绕过进行升级处置;不要把代理地址不变当作安全证明。

常见误区

  • 误区 1:“只监控 Upgraded 就够了。” 信标实现变更和非标准代理可能需要监控另一个合约或轮询状态;事件必须与直接读取结果核对。
  • 误区 2:“管理员槽能显示每次升级由谁控制。” 该槽是可选的,Transparent、UUPS、信标、治理和自定义设计把权限放在不同合约与函数中。
  • 误区 3:“源码已验证或过去有审计就证明升级安全。” 应针对准确版本验证已部署字节码、编译器与构造假设、存储兼容性、初始化、配置和行为。

相关主题

来源

导航

搜索知识库...