可升级智能合约
虽然存在其他可升级设计方案,但目前最常见的USC模式是基于delegatecall的代理模式。在该模式中,代理合约存储实现合约地址,合约所有者可更改该地址。关键特性是在代理的fallback函数中使用delegatecall操作码,它会从目标合约获取函数代码但在代理上下文中执行,因此所有业务逻辑都使用代理的存储空间。
差分模糊测试
模糊测试是通过随机生成输入来检测软件异常的安全分析技术。差分模糊测试是其中一种变体,它向两个相似实现提供相同输入,寻找执行差异。针对智能合约的专用模糊测试工具Echidna会监测不变量违反情况,而差分模糊测试通过外部测试函数比较两个实现的调用结果。
Diffusc实现架构
Diffusc是结合Slither静态分析与Echidna差分测试的工具链:
- 使用Slither扩展组件对比USC版本差异,通过污点分析识别受变更影响的代码区域
- 自动生成两种测试封装合约(标准模式与分叉模式)
- 用户需手动审查生成的封装逻辑,补充必要的前置条件
- 最终通过Echidna执行差分模糊测试
基于Slither的升级对比分析
核心分析流程包含:
- 函数变更检测:通过SlithIR中间表示对比控制流图,识别语义级修改(忽略注释/格式变更)
- 污点传播分析:
- 标记直接读写新/修改函数涉及的存储变量的所有函数
- 对包含外部调用的函数执行跨合约污点分析
- 在Compound案例中,分析将待测函数从69个减少到38个(减少45%)
|
|
测试合约生成技术
工具自动生成包含以下要素的测试合约:
- 标准模式:本地部署所有合约,通过HEVM存储槽模拟升级
|
|
- 分叉模式:利用HEVM实验性功能创建链状态分叉
|
|
- 差分测试封装:对每个目标函数生成包含断言逻辑的包装器
|
|
Compound漏洞复现案例
通过Diffusc成功复现了导致4000万美元损失的COMP代币分配漏洞,关键步骤包括:
- 自定义升级函数触发Comptroller的_become逻辑
|
|
- 构造测试序列:先调用mint()→执行升级→调用claimComp()
- 标准模式下1小时内即可检测到余额不变量违反
使用建议
- 需人工审查自动生成的测试逻辑,特别是:
- 合约初始化流程
- 升级函数的具体实现
- 特殊业务不变量
- 标准模式适合简单合约,分叉模式适合复杂协议交互场景
- 建议结合其他审计工具在升级前进行全面验证