30分钟入门Foundry框架速成

背景

Hardhat的debug实在太不方便了。对于大型的协议开发在fork网络调试的时候,用console.log不仅慢,而且调试太不方便了。而Foundry的优点有:

  1. 工具包小巧,安装十分方便
  2. 直接使用solidity来编写测试代码
  3. 自带fuzz测试,符号执行工具(开发中)
  4. Cheat code 功能
  5. 运行速度飞快,"开发-测试-调试" 流程十分顺畅
  6. 可以兼容hardhat 工程结构

其中,在我现在要做的聚合dex上。如果calldata这种数据要进行解析,非常需要用到cast这个小工具。所以,利用五一恶补Fountry框架。

安装

curl -L https://foundry.paradigm.xyz | bash
foundryup

安装成功之后就可以使用 forge, cast 这两个命令行工具了,后期升级直接运行 foundryup 即可。

forge init foundry-demo

采用forge init来初始化工程。项目工程主要包括:src,lib和test目录。

  • lib 目录 项目使用的第三方库,如 ds-test, openzeppelin,solmate

  • src 目录 项目的主要业务代码。

  • test目录

    项目的主要的测试逻辑。

编译

forge build

部署

部署的话,Foundry原生的方法有点难用。这边建议还是用hardhat来进行deploy。

单元测试

 forge test -m "testDouble()" -vvvv

模糊测试

模糊测试是对单元测试的补充,模糊测试可能会发现一些我们单元测试无法覆盖的一些边界条件。

forge test -m "testFuzzDouble()" -vvvv

Fork 主网测试

Fork mainnet 测试可以直接使用主网上面已经部署好的合约,并结合cheat code 完成一些在本地环境很难完成的测试。一个简单的演示例子: 在使用ETH主网的WETH进行存款。


interface IWETH {
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
    function balanceOf(address) external returns(uint256);
}

contract ContractTest is DSTest {
    Vm vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
    // weth 主网地址
    IWETH weth = IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);

    function setUp() public {
        vm.label(address(weth), "weth");
    }

    function testWethDeposit() public {
        address myAddress = vm.addr(1337);
        vm.deal(myAddress, 10 ether);
        vm.prank(myAddress);
        weth.deposit{value: 1 ether}();
        assertEq(weth.balanceOf(myAddress), 1 ether);
    }
}  

交互式测试

forge run ./src/test/Contract.t.sol -t FooTest --sig "testDouble()" --debu

【核武器】Cheat Codes EVM环境开洞测试

Cheat code 是对EVM执行环境的开洞,可以在运行时改变EVM的状态,比如说当前区块时间,当前区块号,改变任意账号余额,代码等功能。这些功能在我们写测试代码的时候会非常方便。例如:defi 项目中根据区块号或者区块时间计算奖励的测试。

详情:

Subscribe to shaneson.eth
Receive the latest updates directly to your inbox.
Verification
This entry has been permanently stored onchain and signed by its creator.