As outlined in the Execution Overview, due to the nature of how transactions are executed in zkEVM, cheatcode support is limited to the root level of an executing test. That is, all cheatcode access must happen outside of any CREATE
or CALL
that is dispatched to the zkEVM.
Therefore, the following are valid cheatcode accesses:
contract MyContract {
function getNumber() public returns (uint256) {
return 42;
}
}
contract FooTest is Test {
function testFoo_1() public {
vm.roll(10); // valid
vm.assertEq(10, block.number);
}
function testFoo_2() public {
vm.roll(10); // valid
new MyContract();
}
function testFoo_3() public {
vm.roll(10); // valid
MyContract testContract = new MyContract();
testContract.getNumber();
}
}
And consequently, since libraries do not lead to a CREATE
or a CALL
, they can be used with cheatcodes:
library MyLibrary {
function setBlockNumber(value uint256) public {
vm.roll(value); // valid
}
}
contract FooTest is Test {
function testFoo_1() public {
vm.roll(10); // valid
vm.assertEq(10, block.number);
MyLibrary.setBlockNumber(20);
vm.assertEq(10, block.number);
}
}
However, the following situations will lead to undefined behavior (or not work at all), as the cheatcodes are not supported within the zkEVM:
contract MyContract {
constructor() {
vm.roll(20); // invalid
}
function getNumber() public returns (uint256) {
vm.roll(20); // invalid
return 42;
}
}
contract FooTest is Test {
function testFoo_1() public {
vm.roll(10); // valid
MyContract testContract = new MyContract();
testContract.getNumber();
}
}