foundry
foundry copied to clipboard
`vm.resumeGasMetering` can cause tests with expected reverts to fail with an `OutOfGas` error
Component
Forge
Have you ensured that all of these are up to date?
- [X] Foundry
- [X] Foundryup
What version of Foundry are you on?
forge 0.2.0 (6672134 2023-08-08T00:21:59.824374000Z)
What command(s) is the bug in?
forge test
Operating System
macOS (Apple Silicon)
Describe the bug
After calling vm.pauseGasMetering
, calling vm.resumeGasMetering
within a reverting external call causes tests to fail with an OutOfGas
error.
There seem to broadly be inconsistencies and unexpected behavior with the GasMetering
functions; see #5491 as possibly related.
A reproduction, which eliminates self-external-calls as the issue.
import {Test, Vm} from "forge-std/Test.sol";
contract RevertingExternalContract {
error MyError();
Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
function externalReverts() external {
vm.resumeGasMetering();
revert MyError();
}
}
contract MeteringTest is Test {
error MyError();
RevertingExternalContract externalContract;
function setUp() public {
externalContract = new RevertingExternalContract();
}
function testSelfNormalRevert() public {
vm.expectRevert(MeteringTest.MyError.selector);
this.selfReverts();
}
function testSelfMeteringRevert() public {
vm.pauseGasMetering();
vm.expectRevert(MeteringTest.MyError.selector);
this.selfReverts();
}
function testExternalNormalRevert() public {
vm.expectRevert(RevertingExternalContract.MyError.selector);
externalContract.externalReverts();
}
function testExternalMeteringRevert() public {
vm.pauseGasMetering();
vm.expectRevert(RevertingExternalContract.MyError.selector);
externalContract.externalReverts();
}
function testExternalMeteringManualCheck() public {
vm.pauseGasMetering();
(bool success,) = address(this).call(abi.encodeWithSelector(this.selfReverts.selector));
assertEq(success, false);
}
function selfReverts() external {
vm.resumeGasMetering();
revert MyError();
}
}
Output of running these tests:
[PASS] testSelfNormalRevert() (gas: 3953)
Test result: FAILED. 2 passed; 3 failed; 0 skipped; finished in 402.42µs
Ran 1 test suites: 2 tests passed, 3 failed, 0 skipped (5 total tests)
Failing tests:
Encountered 3 failing tests in test/Metering.t.sol:MeteringTest
[FAIL. Reason: EvmError: OutOfGas] testExternalMeteringManualCheck() (gas: 9223372036854754743)
[FAIL. Reason: EvmError: OutOfGas] testExternalMeteringRevert() (gas: 9223372036854754743)
[FAIL. Reason: EvmError: OutOfGas] testSelfMeteringRevert() (gas: 9223372036854754743)