仅供教育参考,不构成投资或安全建议。审计报告、工具结果、已解决的发现或匹配的源文件,都不是认证、保险、赔偿承诺,也不能证明线上部署是安全的。
直接答案
智能合约审计是在明确期间内,对指定需求、源代码、构建输入、部署逻辑和安全假设进行的有限审查。审计人员运用相互补充的方法识别缺陷、展示利用路径、评估影响并检查拟议修复。结论只适用于报告所述的审计快照和证据。
快照应锁定代码仓库与提交或目录树哈希、子模块与依赖锁、编译器及设置、生成代码、部署脚本、目标链和地址、代理、实现或信标、构造器或初始化器数据、库、管理员、时间锁,以及某一区块或时间点。明确排除项与纳入项同样重要:前端、keeper、预言机、跨链桥、治理流程或链下签名者即使不在审计范围内,也可能主导风险。
审计需要威胁模型和规范。应识别资产、参与者、特权角色、信任边界、攻击者能力、排序与重组假设、外部依赖、状态转换,以及精确的安全性和活性性质。缺少单位、前置条件、量词和例外的不变量,可能完美地证明或测试了错误行为。
应维护四本账:范围、构建与部署身份账;需求、威胁与不变量账;发现、证据与复测账;残余风险、接受与披露账。报告没有 critical 发现不等于安全认证,标为 resolved 的发现不一定已经部署,而证明也只覆盖其编码的性质、模型和假设。
运作机制
人工审查追踪架构、资金流、跨函数状态和经济意图。静态分析寻找模式与数据流,但可能产生假阳性和假阴性。单元、集成、分叉和差分测试比较具体行为。有状态模糊测试与不变量测试探索生成的调用序列,但结果取决于处理器、选择器、种子、语料库、运行次数、深度和建模环境。
符号执行与形式化验证可在受支持的语义和假设下确立特定断言。求解器返回 unknown、超时或遇到不支持的行为,都不构成证明。即使性质已获证明,也可能遗漏预言机经济机制、治理、部署配置、链上行为,或团队真正意图实现的需求。规范与解释仍由人工审查负责;AI 生成的观察并非独立的保证方法。
每项发现都应指出受影响的制品与部署、前提条件、最小证明、利用路径、可达性、所需权限、攻击者资本、可重复性、经济影响、严重度标准和修复建议。可利用性或发生可能性与影响是两个不同维度。理论最大值、漏洞名称或工具标签不能证明可执行损失。
open、acknowledged、risk accepted、partially fixed、resolved 和 retested 等状态并非通用标准。可信的结项应把原发现绑定到精确修复提交,记录已测试的变更路径与相邻路径,并说明由谁在何时复测了什么。已接受风险仍然是风险,有限复测不会把原审计范围扩展至所有新增代码。
可升级部署需要专项核对。应解析代理、实现或信标及管理员插槽;验证初始化器与再初始化器行为、实现合约锁定、存储兼容性、升级授权、时间锁或紧急绕过、迁移与回滚。从被审构建中复现创建字节码和运行时字节码,再在每条链上比较链接库、参数、角色和已初始化状态。
最终报告应说明修订版、审计人员和日期、精确范围、方法与配置、限制、发现、证据、修复状态、未解决或已接受风险和披露条款。发布后应监控实现哈希、角色、参数、依赖与事件。任何重大变更都会产生需要复审的新差异;附在旧报告上的徽章不会自动跟随未来代码。
请按以下流程执行:
- 冻结审计清单:代码仓库、提交、依赖、编译器与设置、生成和部署代码、链、地址、代理栈、参数、区块、报告修订版、纳入项与排除项。
- 定义资产、参与者、特权角色、信任边界、攻击者能力、生命周期、排序与活性假设、外部依赖和可度量不变量。
- 复现构建并梳理架构、存储、数据、资金和控制流;核对源码、制品、库、创建与运行时字节码、初始化器、角色和线上部署。
- 组合开展人工、静态、单元、集成、分叉、差分、模糊、不变量、符号或形式化方法,并记录工具版本、配置、种子、语料库、覆盖率、超时和未知结果。
- 记录每项问题的受影响制品、前提、证明、可利用性、影响、严重度方法、部署暴露、建议及保密证据,不把工具标签当作判断。
- 冻结修复提交并复测问题、相邻路径和不变量;验证代理存储、初始化、迁移、回滚、可复现构建和部署收据,再赋予有证据支持的状态。
- 发布范围、方法、限制和残余风险;将被审制品同每条线上链核对,并随系统变化持续更新监控、披露、事件响应和漏洞赏金控制。
示例
- 金库通胀路径需要完整账本。 攻击者通过首存分支存入
1 asset并获得1 share,随后捐赠1,000,000 assets;总量变为1,000,001 assets和1 share。受害者存入500,000 assets,不安全的向下取整计算得到floor(500,000 * 1 / 1,000,001) = 0 shares。若系统接受零份额存款,金库将持有1,500,001 assets;攻击者赎回全部资产并获利500,000 assets,其投入为1,000,001-asset。若实现会在零份额时回退交易,则这条具体损失路径不会执行。 - 文件覆盖率不等于部署覆盖率。 清单包含
24 source units、4 deployment scripts和3 keeper services,合计31 items。审计纳入20 source units与2 scripts,所以按数量计算的覆盖率为22 / 31 = 70.96774194%;其余9 items被排除。如果线上代理指向由排除单元构建的实现,则该线上实现的覆盖率是0%,即使标题数字是70.96774194%。 - 模糊测试观察不构成不存在性证明。 一次有状态测试执行
2,000 sequences * 64 calls = 128,000 calls;不变量在3 sequences中失败,占生成序列的观察比例3 / 2,000 = 0.15%。修复后,10,000 sequences * 64 calls = 640,000 calls未出现失败。这表示该语料库中为零,而非证明;在独立且生成器稳定的教学假设下,三倍法则给出的近似95%上限是每个生成序列3 / 10,000 = 0.03%。 - 发现结项与部署身份彼此独立。 报告有
12 findings:2 critical、3 high、4 medium和3 low。复测关闭2 + 2 + 3 + 2 = 9项,按数量计算的结项率为9 / 12 = 75%;仍有一项高、一项中和一项低未关闭。被审运行时哈希为H1,但线上实现是H2,因此无论结项率如何,部署验证都失败。换成精确的H1并匹配代理插槽、初始化器和角色,只能证明所检查区块时点的身份一致。
风险
- 代码仓库、提交、子模块或生成源码陈旧或含糊。
- 编译器版本、优化器设置、库或依赖没有锁定。
- 部署脚本、构造器数据、初始化器或 CREATE2 salt 被排除。
- 审查了错误的链、地址、代理、信标或实现。
- 源码、制品、创建字节码和运行时字节码无法相互核对。
- 威胁模型遗漏参与者、权限、资产或信任边界。
- 规范或不变量使用错误的单位、前置条件或例外。
- 管理员、守护者、时间锁、暂停、升级或迁移路径被遗漏。
- 预言机、代币、跨链桥、keeper、治理或链上假设失效。
- 静态分析产生未经分流核验的假阳性。
- 人工审查、测试或模糊测试遗漏未生成的路径。
- 模糊测试工具、选择器、种子、语料库、深度或状态模型有偏。
- 求解器超时、不支持的语义或
unknown被误认为证明。 - 正确的证明形式化了错误需求或不完整系统。
- 严重度依据漏洞名称,而非可利用性和影响。
- 理论风险价值被误认为可达损失或攻击者利润。
- 修复引入相邻回归或破坏经济不变量。
- 代理存储、初始化器、升级或迁移破坏线上状态。
- 已接受、未关闭或仅部分修复的问题被“通过审计”徽章掩盖。
- 报告被视为保险、认证、赔偿承诺或永久覆盖。
常见误区
- “没有严重发现就说明合约安全。” 这只描述有限范围、时间与方法下报告的发现,并非所有可能缺陷。
- “测试覆盖率高或模糊测试零失败,就证明没有漏洞。” 这些只是对选定代码和生成路径的度量,不是不存在性证明。
- “形式化验证证明整个协议安全。” 它只证明模型在假设下编码的性质;规范和周边系统仍可能有误。
- “已解决意味着所有线上部署都已修复。” 结项需要独立复测,并逐一核对每个部署的构建、字节码、代理、参数与角色。
- “知名审计机构会保证赔偿或未来升级。” 责任取决于审计合同,用户未必是受益人,后续代码或配置不在旧快照范围内。
相关主题
来源
- OWASP Smart Contract Security Verification Standard (SCSVS) - OWASP (查阅日期: 2026-08-13)
- Security Considerations - Solidity (查阅日期: 2026-08-13)
- Slither, the smart contract static analyzer - Crytic (查阅日期: 2026-08-13)
- Invariant Testing - Foundry (查阅日期: 2026-08-13)
- Certora User’s Guide - Certora (查阅日期: 2026-08-13)
- ERC-1967: Proxy Storage Slots - Ethereum Improvement Proposals (查阅日期: 2026-08-13)
- Writing Upgradeable Contracts - OpenZeppelin (查阅日期: 2026-08-13)
- Contract Metadata - Solidity (查阅日期: 2026-08-13)