Open
Description
Component
Forge
Have you ensured that all of these are up to date?
- Foundry
- Foundryup
What version of Foundry are you on?
forge 0.2.0 (dffdfde 2023-08-14T00:22:15.788827000Z)
What command(s) is the bug in?
forge test
Operating System
macOS (Apple Silicon)
Describe the bug
It seems that gasleft()
is returning an extremely high gas usage amount within a function callback. I ran into this issue when trying to measure gas usage in a UniswapV3Pool callback.
Heres an example that you can test with forge test:
contract Callback {
function execute(uint256 startGas) external returns (uint256, uint256) {
uint256 g1 = GasTester(msg.sender).callbackResponse(startGas); // inaccurate value
uint256 g2 = startGas - gasleft(); // inaccurate value
return (g1, g2);
}
}
contract GasTester {
Callback callback;
constructor() {
callback = new Callback();
}
function run() public returns (uint256, uint256, uint256, uint256, uint256) {
uint256 startGas = gasleft(); // accurate value
// use some gas
require(msg.sender == msg.sender && msg.sender != address(0));
uint256 g0 = startGas - gasleft(); // accurate value
(uint256 g1, uint256 g2) = callback.execute(startGas); // inaccurate values
uint256 g3 = startGas - gasleft(); // accurate value
return (startGas, g0, g1, g2, g3);
}
function callbackResponse(uint256 startGas) external returns (uint256) {
return startGas - gasleft(); // inaccurate value
}
}
the test case:
function test_gas() public {
GasTester gasTester = new GasTester();
(uint256 startGas, uint256 g0, uint256 g1, uint256 g2, uint256 g3) = gasTester.run();
console2.log("startGas", startGas);
console2.log("g0", g0);
console2.log("g1", g1);
console2.log("g2", g2);
console2.log("g3", g3);
}
and finally the log output:
[PASS] test_gas() (gas: 291458)
Logs:
startGas 9079256848778620484
g0 26
g1 281510161082736559
g2 141863388262167292
g3 1732
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.64ms
Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests)
It seems that any gas usage calculated using gasleft()
is accurate but if execution context changes gasleft()
becomes extremely large. g0
ad g3
are accurate while g1
and g2
which are calculated in a callback or a separate contract are inaccurate.
I also ran into this previously closed issue which may be related (not 100% sure):
#3863
Metadata
Metadata
Assignees
Type
Projects
Status
Todo