区块浏览器显示“Contract Source Code Verified”,不代表合约逻辑永远不会变化。很多 DeFi、稳定币和智能账户采用代理模式:用户一直与代理地址交互,资产和状态也留在代理里,但实际执行的代码来自另一个实现合约。真正需要核验的是代理当前指向谁、谁能改变这个指向,以及升级是否有多签、延迟和治理约束。
三个地址分别做什么
代理地址是用户调用和资产记录的入口。实现地址保存业务代码,代理通过 delegatecall 在代理自己的状态上下文中执行它。管理员或升级授权地址负责把实现切换到新版本。
这意味着项目可以修复漏洞和增加功能,也意味着控制升级权限的一方可能改变关键逻辑。准备授权前,可先结合 连接智能合约前要检查什么 核对域名、网络和入口地址,再继续追踪代理结构。
ERC-1967 提供哪些可核验线索
ERC-1967 为实现地址、Beacon 地址和管理员地址规定了标准存储槽,并建议变更时发出 Upgraded、BeaconUpgraded 或 AdminChanged 事件。支持该标准的区块浏览器通常会展示“Read as Proxy”或当前 implementation,但仍应核对事件历史与管理员控制。
| 核验对象 | 回答的问题 | 主要风险 |
|---|---|---|
| Proxy | 你实际交互的是哪个入口 | 仿冒入口或错误网络 |
| Implementation | 当前执行哪份代码 | 未验证代码或突然变更 |
| Admin / Upgrader | 谁能升级 | 单签、密钥泄露、治理集中 |
| Upgrade events | 何时发生变更 | 未披露升级或频繁修改 |
Transparent、UUPS 与 Beacon 不一样
透明代理常由 ProxyAdmin 管理升级;管理员地址调用代理时走管理接口,普通用户调用才委托给实现。UUPS 的升级逻辑位于实现合约,关键是升级函数的授权条件。Beacon 代理则由 Beacon 统一提供实现地址,升级一个 Beacon 可能同时影响多个代理。
因此只查某个公开的 admin() 函数并不可靠。自定义代理、Diamond 等架构还会使用不同机制。本文提供的是核验框架,不是识别所有代理的自动脚本。
区块浏览器核验顺序
- 从项目官方文档取得代理地址,核对链和完整地址。
- 查看浏览器是否识别 Proxy,记录当前实现与 Beacon。
- 打开实现合约,检查源码验证、编译设置和部署时间。
- 查询 ERC-1967 相关槽位或升级事件,整理版本时间线。
- 找到 ProxyAdmin、owner、角色或升级授权函数,继续追踪其控制者。
- 判断控制者是单一 EOA、多签、Timelock 还是治理合约,并核对阈值与延迟。
若管理员是多签,还要继续核对签名人独立性和阈值,不能看到“multisig”就停止。智能账户权限的其他层次可阅读 智能账户授权检查。
升级后需要重新检查什么
实现合约变化后,旧审计并不会自动覆盖新代码。应重新核对初始化调用、存储布局、关键角色、暂停与资产转移能力,以及前端是否披露版本变化。OpenZeppelin 提醒升级必须保持存储布局兼容,否则已有状态可能被破坏。
如果升级同时要求你重新授权代币,需确认 spender 是否变化、额度是否合理,并用 代币花费额度复核清单 检查旧授权是否仍存在。
四个高风险信号
- 升级管理员是单一新地址,且没有公开说明。
- 实现代码未验证,或升级事件与公告时间不一致。
- Timelock 很短、可以绕过,或紧急角色权限没有边界。
- 项目只展示审计报告,却不说明报告对应哪个实现版本。
本文只做防御性安全教育,不构成投资建议,也不判断任何具体协议安全。代理架构复杂且可自定义,涉及资产操作前请以官方文档、链上存储、事件和当前实现代码交叉核验。不要把私钥、助记词或管理员凭证输入任何检查网站。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。