- 默认禁用 Solc 优化器
- 内部调用默认禁用期望回滚测试辅助代码
- 移除对 testFail 测试的支持
- 移除对旧版 console.sol 签名的支持
- 忽略冲突的重映射
- Forge 覆盖率报告不持久化产物文件
- 其他变更
Foundry v1.0 版本引入了多项破坏性变更,使用旧版本的项目可能需要相应调整。本指南记录了从旧版本迁移时的最佳实践建议。
主要变更清单:
- 默认禁用 Solc 优化器
- 内部调用默认禁用期望回滚测试辅助代码(expect revert cheatcode)
- 移除对 testFail 测试的支持
- 移除对旧版 console.sol 签名的支持
- 忽略冲突的重映射
- Forge 覆盖率报告不持久化产物文件
- 其他变更
默认禁用 Solc 优化器
默认启用优化器可能为表面正确的代码引入潜在缺陷(若优化器本身存在漏洞,参见 #2486)。Foundry v1.0 的默认设置可能对现有项目产生以下影响:导致合约体积增大和/或项目构建失败。建议在 foundry.toml
配置文件中显式启用优化器并指定运行参数:
optimizer = true
optimizer_runs = 200
详见:优化配置
内部调用默认禁用期望回滚测试辅助代码
当在相同调用层级使用 vm.expectRevert
测试辅助代码测试内部函数时,仅首个 vm.expectRevert
会生效(详见 #3437)。Foundry v1.0 默认禁用了该行为,可能导致现有项目出现测试失败,报错信息为 [FAIL: 调用未在比测试辅助代码调用层级更浅的位置触发回滚]。建议检查这些失败的测试用例,选择启用内部调用回滚功能或重构测试代码以避免此类问题。
例如,类似以下测试案例:
contract ContractTest is Test {
error CustomError();
function revertWithCustomError() internal {
revert CustomError();
}
function testExample() public {
vm.expectRevert();
revertWithCustomError();
}
}
可以通过修改为使用一个模拟的 CustomContract 并公开公共函数来实现:
contract CustomContract {
error CustomError();
function revertWithCustomError() external {
revert CustomError();
}
}
contract ContractTest is Test {
CustomContract internal c;
function setUp() public {
c = new CustomContract();
}
function testExample() public {
vm.expectRevert();
c.revertWithCustomError();
}
}
或通过配置允许预期回滚检测:
/// forge-config: default.allow_internal_expect_revert = true
function testExample() public {
vm.expectRevert();
revertWithCustomError();
}
移除对 testFail 测试的支持
Foundry v1.0 移除了 testFail
测试前缀支持以避免混淆 - 详见 #4437。这可能导致现有项目在非预期位置报告测试失败。迁移现有 testFail
测试至 v1.0 可通过以下方式实现:使用 vm.expectRevert()
作弊码,或者使用 try/catch
方法并断言失败。
例如,原测试代码:
function testFail_IncrementAsNotOwner() public {
vm.prank(address(0));
upOnly.increment();
}
可重写为:
function test_RevertWhen_CallerIsNotOwner() public {
vm.expectRevert(Unauthorized.selector);
vm.prank(address(0));
upOnly.increment();
}
移除对旧版 console.sol 签名的支持
Foundry v1.0 移除了对使用错误 ABI 编码的 console.sol
选择器的支持 - 详见 #8910。这可能导致现有项目出现测试构建失败,因此需要相应更新。例如:
console.log("testMisc", 42);
console.log(0);
应重写为:
console.log("testMisc", uint256(42));
console.log(uint256(0));
忽略冲突的重映射
在 Foundry v1.0 之前,forge
会通过子项目的重映射推断全局重映射。当存在冲突时,最长/最具体的路径会优先。此行为存在安全隐患,因为添加子项目可能完全改变实际执行的代码逻辑(即使根项目重映射未修改)- 详见 #8910。v1.0 版本中,若相同重映射定义同时存在于根项目和依赖项中,构建将失败。例如:
@openzeppelin/=lib/openzeppelin-contracts/contracts/
修复方法:在根项目的 remappings.txt
中为冲突的重映射添加 src
上下文限定:
src:@openzeppelin/=lib/openzeppelin-contracts/contracts/
这会将重映射范围限制在项目的 src
目录内,避免与依赖项中的同名重映射冲突。
Forge 覆盖率报告不持久化产物文件
在旧版本中,运行 forge coverage
会修改构建产物(这些产物未经过优化,用于提供准确的源码命中映射)且无任何警告。这容易引发混淆,并导致如 #8840 讨论中的意外情况。Foundry v1.0 在运行覆盖率测试时不再生成构建产物,因此项目需注意此项变更。
其他变更
重要变更说明
FORGE_SNAPSHOT_CHECK
需指定布尔值:现在必须明确设置FORGE_SNAPSHOT_CHECK=true
或FORGE_SNAPSHOT_CHECK=false
,不再支持隐式值。forge inspect --pretty
参数已移除:直接使用forge inspect
查看表格视图,无需--pretty
参数。forge bind --ethers
已弃用:默认绑定器切换为alloy
,直接运行forge bind
即可。forge debug
子命令移除:调试功能迁移至:- 测试场景:使用
forge test --debug
- 脚本场景:使用
forge script --debug
- 测试场景:使用
cast etherscan-source
更名为cast source
:新命令explorer_url
和explorer_api_url
支持自定义区块浏览器。foundryup
默认安装稳定版:- 稳定版:
foundryup
(默认) - 测试版:
foundryup -i nightly
- 稳定版:

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
腾讯云开发者社区:孟斯特
—