Skip to content

Instantly share code, notes, and snippets.

@pcaversaccio
Last active March 20, 2023 19:44
Show Gist options
  • Save pcaversaccio/cc58ccd6a84826d2d80eb08a9f7fae2b to your computer and use it in GitHub Desktop.
Save pcaversaccio/cc58ccd6a84826d2d80eb08a9f7fae2b to your computer and use it in GitHub Desktop.
A Solidity contract to estimate the used gas via the `gasleft()` syntax for dedicated function calls.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
contract GasTesting {
function testInlined(uint256 length) external view returns (uint256 gasUsed) {
uint256 total;
uint256 startGas = gasleft();
for (uint256 i; i < length; i = _uncheckedInc(i)) {
total += i;
}
gasUsed = startGas - gasleft();
}
function _uncheckedInc(uint256 i) private pure returns (uint256) {
unchecked {
return i + 1;
}
}
function testPure(uint256 length) external view returns (uint256 gasUsed) {
uint256 total;
uint256 startGas = gasleft();
for (uint256 i; i < length; ) {
total += i;
unchecked {
++i;
}
}
gasUsed = startGas - gasleft();
}
function greater(uint256 a) external view returns (uint256 gasUsed) {
uint256 startGas = gasleft();
require(a > 0, "!a > 0");
gasUsed = startGas - gasleft();
}
function unequal(uint256 a) external view returns (uint256 gasUsed) {
uint256 startGas = gasleft();
require(a != 0, "!a > 0");
gasUsed = startGas - gasleft();
}
function oldWay() external view returns (string memory, uint256 gasUsed) {
string memory hiMom = "Hi Mom, ";
string memory missYou = "miss you.";
uint256 startGas = gasleft();
string memory concat = string(abi.encodePacked(hiMom, missYou));
gasUsed = startGas - gasleft();
return (concat, gasUsed);
}
function newWay() external view returns(string memory, uint256 gasUsed) {
string memory hiMom = "Hi Mom, ";
string memory missYou = "miss you.";
uint256 startGas = gasleft();
string memory concat = string.concat(hiMom, missYou);
gasUsed = startGas - gasleft();
return (concat, gasUsed);
}
}
@pcaversaccio
Copy link
Author

pcaversaccio commented Mar 12, 2022

In order to use the hevm debug tooling you can do the following:

Copy the above contract into a file:

vi GasTesting.sol

Generate the Solidity compiler artifacts:

solc --bin-runtime GasTesting.sol -o . --overwrite
solc --combined-json=srcmap,srcmap-runtime,bin,bin-runtime,ast,metadata,storage-layout,abi --pretty-json GasTesting.sol > combined.json

Debug using hevm:

  • Function greater(uint256):
hevm symbolic --code $(<GasTesting.bin-runtime) --sig "greater(uint256)" --arg 0x64 --json-file combined.json --solver cvc4 --debug
  • Function unequal(uint256):
hevm symbolic --code $(<GasTesting.bin-runtime) --sig "unequal(uint256)" --arg 0x64 --json-file combined.json --solver cvc4 --debug

You can also get the optimised artifacts, but the step-by-step debugger visualisation would fail in this case:

solc --optimize --optimize-runs 200 --bin-runtime GasTesting.sol -o . --overwrite

If you use Foundry, you can run everything in one line, e.g.:

forge debug --optimize --optimizer-runs 200 --use 0.8.17 --via-ir GasTesting.sol --target-contract GasTesting --sig "greater(uint256)" 0x64 --debug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment