Smart Contract Audits: What Auditors Check—and What an Audit Does Not Guarantee
智能合约审计是在明确范围内对代码和架构进行的独立审查,旨在识别漏洞、实现错误以及预期行为与实际行为之间的不一致。
审计可以降低不确定性,但不能使合约完全没有风险。Ethereum 官方安全指南将审计视为额外审查,而不是能够发现所有漏洞的万能方案。
本文仅供教育用途。审计不保证安全、资金追回或回报。
首先确认审查范围
有用的报告会明确指出审查了哪些内容:
- 代码仓库和提交哈希;
- 文件和合约;
- 编译器版本和构建设置;
- 依赖项;
- 架构和特权角色;
- 分支或发布版本;
- 排除项、限制和假设;
- 审查日期。
这一点很重要,因为真实的审计可能只涵盖旧版本、不同部署或更大系统中的一部分。
审计人员通常检查什么
1. 预期行为与不变量
审计人员会将代码与其规范进行比较:
- 谁可以调用各个函数;
- 金额和费用的计算方式;
- 状态何时发生变化;
- 哪些属性必须始终保持成立;
- 边界情况和故障的处理方式。
如果规范遗漏重要要求,即使代码在技术上正确,也可能实现不安全或不符合预期的设计。
2. 访问控制
审查人员会检查 owner、admin、operator 和其他特权角色,包括以下权限:
- 授予或撤销权限;
- 暂停系统;
- 更改费用和限制;
- 铸造代币;
- 提取资产;
- 升级实现合约。
还需考虑一把密钥能否执行关键变更,以及设计中是否包含多重签名或时间锁等控制措施。
3. 外部调用与重入
合约在执行过程中可能把控制权交给另一个合约,从而产生重入风险:外部合约可能在原始状态转换完成前回调。Solidity 官方指南建议在适用情况下谨慎安排检查、状态变更和外部交互的顺序。
4. 计算与单位
审计人员会查找:
- 舍入和精度损失;
- 代币小数位不匹配;
- 错误的操作顺序;
- 边界值;
- 除以零;
- unsafe
uncheckedarithmetic; - 内部单位与显示单位之间的差异。
5. 拒绝服务与 Gas
无限循环、不断增长的数组、失败的外部调用或高成本操作可能使函数难以实际执行。审查人员会测试数据增长或输入异常时设计是否仍可用。
6. 代理合约与升级
对于可升级系统,审查应涵盖:
- 代理合约和实现合约;
- 升级者或管理员权限;
- 初始化;
- 存储布局兼容性;
- 未经授权的升级路径;
- 审计后更改逻辑所产生的影响。
代理合约可以在面向用户的地址保持不变的同时,将执行委托给新逻辑。因此,任何“合约无法更改”的说法都必须结合实际架构核查。
7. 集成
合约可能依赖代币、价格预言机、跨链桥、DEX、签名或其他合约。审计人员会检查有关这些依赖项的假设、过时数据、异常代币行为和外部故障模式。
8. 事件与监控
审查人员可能会检查事件是否准确公开角色变更、升级、暂停和转账等重要操作。事件有助于监控,但不能替代状态检查。
审计采用的方法
核查通常结合:
- 人工代码和架构分析;
- 单元测试和集成测试;
- 静态和动态分析;
- 使用生成输入进行模糊测试;
- 基于属性的测试;
- 检查已知漏洞类型;
- 构建和部署审查;
- 有时还会对选定属性进行形式化验证。
没有任何单一方法能够涵盖一切。形式化验证可以证明代码符合形式规范,但无法证明规范本身未表达的属性。
用户应如何阅读审计报告
1. 匹配已审核版本
查找 commit hash 并确认:
- 当前实现合约是否由该代码构建;
- 报告日期之后是否发生过升级;
- 链和部署地址是否一致;
- 关键依赖项是否在审查范围内。
如果无法确认这一点,该报告对线上部署所提供的证据就十分有限。
2. 阅读审计发现,而不只看摘要
对于每项发现,请审查:
- 严重程度和场景;
- 受影响的代码;
- 建议;
- 开发者回复;
- 当前状态;
- 审计机构是否重新测试了修复内容。
已修复 或 已解决 is meaningful only when tied to a specific corrected version.
3. 阅读限制说明
报告可能不涵盖:
- 前端和后端系统;
- 密钥管理;
- 经济机制设计;
- 第三方合约;
- 部署基础设施;
- 生产环境配置;
- 法律和运营问题。
用户与整个系统交互,而不只是其 Solidity 文件。
4. 审查管理权限风险
请确认:
- 谁控制升级;
- 操作是否可以暂停;
- 费用或关联地址是否可以更改;
- 是否设有时间锁;
- 是否使用多重签名;
- 用户如何获知变更。
即使代码中没有发现漏洞,这些仍属于治理和信任问题。
5. 审计后继续关注安全变化
实用的持续衡量指标包括:
- 测试每个发布版本;
- 审查重大升级;
- 漏洞赏金计划;
- 监控角色和实现合约;
- 事件响应流程;
- 限制风险敞口中的资产数量。
审计不能保证什么
审计不能保证:
- 不存在任何漏洞;
- 审查后被更改代码的安全性;
- 网站、钱包、DNS 或服务器的安全性;
- 特权密钥的安全性;
- 外部代币、预言机和跨链桥的正确性;
- 抵御所有经济攻击的能力;
- 团队的诚信;
- 法律合规;
- 代币流动性;
- 资金返还;
- 固定或任何其他形式的回报。
谨慎用户应提出的问题
Is an auditor’s logo enough?
No. Find the report from the auditor’s own source and check its scope, commit, date, and findings.
If every finding was fixed, is the contract safe?
It means the listed findings were addressed in a stated version. Unknown issues and out-of-scope risks remain.
Are several audits automatically better?
The count alone says little. Coverage, quality, independence, recency, and version matching matter more.
Does an audit still apply after a proxy upgrade?
Only if the new implementation and configuration are covered by the reviewed version.
报告检查清单
- 可从审计机构获得该报告。
- 已注明代码仓库和 commit hash。
- 关键合约和依赖项已纳入审查范围。
- 已审查版本与线上部署相匹配。
- 审查范围涵盖代理合约、实现合约和 admin。
- 已记录状态查找和重新测试过程。
- 已阅读假设条件和排除项。
- 已单独评估代码之外的风险。