可升级智能合约
基于委托调用(delegatecall)的代理模式是目前最常见的可升级智能合约(USC)实现方式。该模式中,代理合约存储实现合约地址,合约所有者可通过修改该地址升级逻辑。关键特性是在代理合约的fallback函数中使用delegatecall操作码,这使得所有未在代理中定义的函数调用都会被捕获。
与普通call操作码不同,delegatecall从目标合约获取函数代码但在代理合约上下文中执行,因此所有业务逻辑都使用代理的存储状态。这使得无需迁移状态即可更换实现合约。
差异模糊测试
模糊测试是一种通过随机生成输入来检测软件异常的安全分析技术。差异模糊测试是其变种,通过向两个相似实现提供相同输入,检测执行过程中的差异。
Echidna是最成熟的智能合约模糊测试工具,通常用于检测不变量违规。差异模糊测试采用外部测试方式,测试函数接收随机输入并调用两个实现的相同函数,然后断言结果应相同。
Diffusc实现
Diffusc是结合静态分析与差异模糊测试的工具链:
- 使用Slither静态分析识别升级影响的所有函数
- 生成用于部署和交互的包装合约(标准模式/分叉模式)
- 用户审查包装合约并补充必要信息
- 使用Echidna执行差异模糊测试
使用Slither进行版本差异分析
Diffusc的Slither扩展主要完成:
- 比较两个USC实现生成差异,通过污点分析识别受影响的未修改代码
- 识别代理合约存储实现地址的插槽
分析过程包括:
- 通过函数签名和变量列表比较识别新增/修改内容
- 使用SlithIR中间表示和控制流图对比检测语义变更
- 执行污点分析标记读取/写入相同存储变量的函数
- 跨合约污点分析处理外部调用情况
以Compound升级事件为例,分析显示21个状态变量和26个函数被污染,包括关键的compSupplyState映射。
为Echidna生成差异测试
Diffusc自动为每个目标函数生成包装方法,例如:
|
|
支持两种测试模式:
- 标准模式:本地测试网部署所有合约
- 分叉模式:从链上地址获取合约,使用两个分叉
实战案例:Compound漏洞复现
2021年9月,Compound升级引入的Comptroller合约漏洞导致约4000万美元COMP代币错误分配。Diffusc通过以下步骤复现:
- 在测试合约中包含升级函数
- 用户需自定义升级逻辑(调用_become函数)
- 标准模式下部署cToken合约并初始化市场
- 交易序列:mint() → upgradeV2() → claimComp()
分叉模式需额外设置测试合约为Comptroller管理员。两种模式均能在1小时内发现代币分配异常。
将Diffusc加入安全工具箱
Diffusc自动生成差异模糊测试合约,帮助开发者在升级前检测行为差异。虽然需要部分人工干预(如初始化逻辑和特殊前提条件),但作为安全工具链的重要补充,应在每次升级前使用。
特别感谢HEVM团队为分叉模式提供的支持,以及Slither静态分析工具的基础能力。