Open palinatolmach opened 1 year ago
When we run forge test --fork-url <some_fork_url>
, only the necessary storage will be fetched from the forked node.
For example, the following two tests can be found in this fork-testing
branch of ercx-kontrol
repo: https://github.com/runtimeverification/ercx-kontrol/tree/fork-testing.
function test_vault_totalSupply() public view {
// to be fetched from https://etherscan.io/token/0x4c406C068106375724275Cbff028770C544a1333#readContract
uint256 currentTotalSupply = 403372338086380169872;
assertEq(cut4626.totalSupply(), currentTotalSupply);
}
function test_balanceOf_highest_holder() public view {
// to be fetched from https://etherscan.io/token/0x4c406C068106375724275Cbff028770C544a1333#balances
address highestHolder = 0x096697720056886b905D0DEB0f06AfFB8e4665E5;
uint256 amount = 184197797095128198548;
assertEq(cut4626.balanceOf(highestHolder), amount);
}
And only the following storage values are retrieved which are found in the file ~/.foundry/cache/rpc/<chain name>/<block number>
(see https://book.getfoundry.sh/forge/fork-testing?highlight=fork-url%20cache#forking-mode):
...
"storage": {
"0x7109709ecfa91a80626ff3989d68f67f5b1dd12d": {
"0x6661696c65640000000000000000000000000000000000000000000000000000": "0x0"
},
"0x4c406c068106375724275cbff028770c544a1333": {
"0xf2d41a00f724aafd5389bd9279e365cac950b52aeee06556f9fae36cbce2f7e9": "0x9fc42088948986d94",
"0x2": "0x15ddea6c54d175ea90"
}
},
...
where 0x4c406c068106375724275cbff028770c544a1333 is the address of cut4626, 0xf2d41a00f724aafd5389bd9279e365cac950b52aeee06556f9fae36cbce2f7e9
represents the storage slot of cut4626.balanceOf(highestHolder)
and 0x2
represents the storage slot of totalSupply()
.
If we want kontrol
to support --fork-url
, it can only be done if:
the test suite is runnable with forge test --fork-url
so that we can retrieve the corresponding cache file, or
there exists some other command/s that allow us to fetch the necessary storage values without running forge build/test
so that we will not encounter any compilation error in the event that the test suite contains kontrol
cheatcodes that are only parsable by kontrol
but not forge
. For example, error such as "unknown cheatcode with selector 0x25449d64; you may have a mismatch between the Vm
interface (likely in forge-std
) and the forge
version" will occur when you run forge test
with kontrol
-only cheatcodes.
dumpState
Rust implementation: https://github.com/foundry-rs/foundry/blob/9faa0578981538aa0bcd70811f654bb5938347fc/crates/cheatcodes/src/evm.rs#L112vm.ignoreCheatCode
to ignore third party cheatcodes.
Related: https://github.com/runtimeverification/evm-semantics/issues/1401
We should consider supporting Foundry fork tests, which would make it easier to reproduce exploits, perform meaningful inter-contract analysis, and simplify the application of FV to the existing test suits that contain fork tests. We can also re-verify the property tests against the updated mainnet state against potentially changing mainnet state (e.g., if other contracts change through a proxy).
The existing workaround is to set the contracts' bytecode using the
etch
cheatcode (as discussed in https://github.com/runtimeverification/evm-semantics/issues/1401), but that would still require careful reconstruction of the state such as setting storage variables according to their values in a certain block, etc.Perhaps we might look into re-using the information fetched by Foundry when its run in the fork-test mode: