feat: `noPrecompiles` modifier or function
Ref https://github.com/foundry-rs/foundry/issues/1228
The fuzzer will pass precompile addresses to tests. These are valid inputs so we don't want to strip them from the fuzzer, but in some tests they can cause problems. The scope of this issue is to add a modifier OR a function (I'm not yet sure which we should prefer, open to discussion here, as well a name other than noPrecompiles) that does something like this:
// --- forge-std ---
// Use this version to infer the chain ID from the test environment.
function noPrecompiles(address who) internal {
noPrecompiles(who, block.chainid);
}
// Use this version to specify which chain's precompiles to use.
function noPrecompiles(address who, uint256 chainId) internal {
if (chainid == 1 || chainid == 31337) {
// Mainnet precompiles: https://www.evm.codes/precompiled
vm.assume(who > address(9));
} else if (chainid == 10 || chainid == 69 || chainid == 420) {
// Optimism precompiles: https://github.com/ethereum-optimism/optimism/blob/master/packages/contracts/contracts/libraries/constants/Lib_PredeployAddresses.sol
vm.assume(who < 0x4200000000000000000000000000000000000000 && who > 0x4200000000000000000000000000000000000013);
}
// etc. for other chains
}
// --- myTest.t.sol ---
function testSomeAddress(address a, address b) public {
noPrecomples(a); // Precompiles for `b` are allowed.
}
I think including mainnet, optimism, and arbitrum precompiles is a good start for this PR
Additional modifiers to exclude foundry addresses (such as Vm and the test contract), as well as an array of user provided addresses, would also be useful. See https://twitter.com/0xArbiter/status/1571927649353711618
Per @mds1 request on https://github.com/foundry-rs/foundry/issues/1078 here are some additional precompiles for Avalanche evm-based subnets. A list of such subnets is maintained here.
One thing to note is that Optimism doesn't have extra precompiles, they are technically predeploys so they are evm bytecode placed at specific addresses. I do think that it makes sense to avoid those addresses while fuzzing, it makes sense to include them in assumeNoPrecompiles. The address space for predeploys is 0x4200..00 to 0x4200..0800` in bedrock, the first 2048 addresses in that range
Closed by https://github.com/foundry-rs/forge-std/pull/184