Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Forge Standard Library is a collection of helpful contracts for use with forge and foundry. It leverages forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes. For more in-depth usage examples checkout the tests.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
NotificationsYou must be signed in to change notification settings

foundry-rs/forge-std

Repository files navigation

Forge Standard Library is a collection of helpful contracts and libraries for use withForge and Foundry. It leverages Forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes.

Learn how to use Forge-Std with the📖 Foundry Book (Forge-Std Guide).

Install

forge install foundry-rs/forge-std

Contracts

stdError

This is a helper contract for errors and reverts. In Forge, this contract is particularly helpful for theexpectRevert cheatcode, as it provides all compiler built-in errors.

See the contract itself for all error codes.

Example usage

import"forge-std/Test.sol";contractTestContractisTest {    ErrorsTest test;function setUp()public {        test=newErrorsTest();    }function testExpectArithmetic()public {        vm.expectRevert(stdError.arithmeticError);        test.arithmeticError(10);    }}contractErrorsTest {function arithmeticError(uint256a)public {        a= a-100;    }}

stdStorage

This is a rather large contract due to all of the overloading to make the UX decent. Primarily, it is a wrapper around therecord andaccesses cheatcodes. It canalways find and write the storage slot(s) associated with a particular variable without knowing the storage layout. The onemajor caveat to this is while a slot can be found for packed storage variables, we can't write to that variable safely. If a user tries to write to a packed slot, the execution throws an error, unless it is uninitialized (bytes32(0)).

This works by recording allSLOADs andSSTOREs during a function call. If there is a single slot read or written to, it immediately returns the slot. Otherwise, behind the scenes, we iterate through and check each one (assuming the user passed in adepth parameter). If the variable is a struct, you can pass in adepth parameter which is basically the field depth.

I.e.:

struct T {// depth 0uint256 a;// depth 1uint256 b;}

Example usage

import"forge-std/Test.sol";contractTestContractisTest {using stdStoragefor StdStorage;    Storage test;function setUp()public {        test=newStorage();    }function testFindExists()public {// Lets say we want to find the slot for the public// variable `exists`. We just pass in the function selector// to the `find` commanduint256 slot= stdstore.target(address(test)).sig("exists()").find();assertEq(slot,0);    }function testWriteExists()public {// Lets say we want to write to the slot for the public// variable `exists`. We just pass in the function selector// to the `checked_write` command        stdstore.target(address(test)).sig("exists()").checked_write(100);assertEq(test.exists(),100);    }// It supports arbitrary storage layouts, like assembly based storage locationsfunction testFindHidden()public {// `hidden` is a random hash of a bytes, iteration through slots would// not find it. Our mechanism does// Also, you can use the selector instead of a stringuint256 slot= stdstore.target(address(test)).sig(test.hidden.selector).find();assertEq(slot,uint256(keccak256("my.random.var")));    }// If targeting a mapping, you have to pass in the keys necessary to perform the find// i.e.:function testFindMapping()public {uint256 slot= stdstore            .target(address(test))            .sig(test.map_addr.selector)            .with_key(address(this))            .find();// in the `Storage` constructor, we wrote that this address' value was 1 in the map// so when we load the slot, we expect it to be 1assertEq(uint(vm.load(address(test),bytes32(slot))),1);    }// If the target is a struct, you can specify the field depth:function testFindStruct()public {// NOTE: see the depth parameter - 0 means 0th field, 1 means 1st field, etc.uint256 slot_for_a_field= stdstore            .target(address(test))            .sig(test.basicStruct.selector)            .depth(0)            .find();uint256 slot_for_b_field= stdstore            .target(address(test))            .sig(test.basicStruct.selector)            .depth(1)            .find();assertEq(uint(vm.load(address(test),bytes32(slot_for_a_field))),1);assertEq(uint(vm.load(address(test),bytes32(slot_for_b_field))),2);    }}// A complex storage contractcontractStorage {struct UnpackedStruct {uint256 a;uint256 b;    }constructor() {        map_addr[msg.sender]=1;    }uint256publicexists=1;mapping(address=>uint256)public map_addr;// mapping(address => Packed) public map_packed;mapping(address=> UnpackedStruct)public map_struct;mapping(address=>mapping(address=>uint256))public deep_map;mapping(address=>mapping(address=> UnpackedStruct))public deep_map_struct;    UnpackedStructpublic basicStruct=UnpackedStruct({        a:1,        b:2    });function hidden()publicviewreturns (bytes32t) {// an extremely hidden storage slotbytes32 slot=keccak256("my.random.var");assembly {            t:=sload(slot)        }    }}

stdCheats

This is a wrapper over miscellaneous cheatcodes that need wrappers to be more dev friendly. Currently there are only functions related toprank. In general, users may expect ETH to be put into an address onprank, but this is not the case for safety reasons. Explicitly thishoax function should only be used for addresses that have expected balances as it will get overwritten. If an address already has ETH, you should just useprank. If you want to change that balance explicitly, just usedeal. If you want to do both,hoax is also right for you.

Example usage:

// SPDX-License-Identifier: MITpragma solidity^0.8.0;import"forge-std/Test.sol";// Inherit the stdCheatscontractStdCheatsTestisTest {    Bar test;function setUp()public {        test=newBar();    }function testHoax()public {// we call `hoax`, which gives the target address// eth and then calls `prank`hoax(address(1337));        test.bar{value:100}(address(1337));// overloaded to allow you to specify how much eth to// initialize the address withhoax(address(1337),1);        test.bar{value:1}(address(1337));    }function testStartHoax()public {// we call `startHoax`, which gives the target address// eth and then calls `startPrank`//// it is also overloaded so that you can specify an eth amountstartHoax(address(1337));        test.bar{value:100}(address(1337));        test.bar{value:100}(address(1337));        vm.stopPrank();        test.bar(address(this));    }}contractBar {function bar(addressexpectedSender)publicpayable {require(msg.sender== expectedSender,"!prank");    }}

Std Assertions

Contains various assertions.

console.log

Usage follows the same format asHardhat.It's recommended to useconsole2.sol as shown below, as this will show the decoded logs in Forge traces.

// import it indirectly via Test.solimport"forge-std/Test.sol";// or directly import itimport"forge-std/console2.sol";...console2.log(someValue);

If you need compatibility with Hardhat, you must use the standardconsole.sol instead.Due to a bug inconsole.sol, logs that useuint256 orint256 types will not be properly decoded in Forge traces.

// import it indirectly via Test.solimport"forge-std/Test.sol";// or directly import itimport"forge-std/console.sol";...console.log(someValue);

Contributing

See ourcontributing guidelines.

Getting Help

First, see if the answer to your question can be found inbook.

If the answer is not there:

If you want to contribute, or follow along with contributor discussion, you can use ourmain telegram to chat with us about the development of Foundry!

License

Forge Standard Library is offered under eitherMIT orApache 2.0 license.

About

Forge Standard Library is a collection of helpful contracts for use with forge and foundry. It leverages forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes. For more in-depth usage examples checkout the tests.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp