Buidler plugin for eth-gas-reporter, a mocha reporter for Ethereum test suites


Keywords
ethereum, smart-contracts, buidler, buidler-plugin, gas, hardhat-plugin, solidity, unit-tests
License
MIT
Install
npm install buidler-gas-reporter@0.1.4

Documentation

npm version Build Status buidler

hardhat-gas-reporter

Gas Usage Analytics for Hardhat

  • Get gas metrics for method calls and deployments on L1 and L2 by running your test suite.
  • Get national currency costs of deploying and using your contract system.
  • Output data in multiple formats including text, markdown, reStructuredText and JSON.

Example report

Screen Shot 2024-04-02 at 6 04 53 PM

Installation

npm install --save-dev hardhat-gas-reporter

Add the following to your hardhat.config.ts:

import "hardhat-gas-reporter"

Configuration

Configuration is optional.

// Example
const config: HardhatUserConfig = {
  gasReporter: {
    currency: 'EUR',
    L1: "polygon",
    coinmarketcap: "abc123...",
  }
}

Usage

This plugin overrides the built-in test task. Gas reports are generated by default with:

npx hardhat test

💡 Turning the plugin on/off

The enabled option lets you toggle gas reporting on and off using shell environment variables. Tests run faster when the gas reporter is off because fewer calls are made to the client to read data.

const config: HardhatUserConfig = {
  gasReporter: {
    enabled: (process.env.REPORT_GAS) ? true : false
  }
}

🔍 Caveats about Accuracy:

  • Gas readings for pure and view methods are only a lower bound of their real world cost. Actual gas usage will depend on the way the methods are called and the storage/memory state of the EVM at the moment of invocation. For more information on this see the excellent summary at wolfio/evm/gas
  • L1 gas readings for Arbitrum & OPStack chains are approximations - some variance is expected.
    • Optimism estimates should be within 1% of observed usage on optimistic-etherscan.
    • Arbitrum estimates should be within 10% of observed usage on arbiscan
  • The Hardhat client implements the Ethereum Foundation EVM. To get accurate measurements for other EVM-based chains you may need to run your tests against development clients developed specifically for those networks.

Options

Options Type Default Description
currency string USD National currency to represent gas costs in. Exchange rates are loaded at runtime from the coinmarketcap api. Available currency codes can be found here
coinmarketcap string - API key to use when fetching live token price data
enabled bool true Produce gas reports with hardhat test
excludeAutoGeneratedGetters bool false Exclude solc generated public state vars when reporting gas for pure and view methods. (Incurs a performance penalty on test startup when true) ⚠️ SLOW ⚠️
excludeContracts string[] [] Names of contracts to exclude from report. Ex: ["MyContract"]
includeIntrinsicGas bool true Include standard 21_000 + calldata bytes overhead in method gas usage data. (Setting to false can be useful for modelling contract infra that will never be called by an EOA)
L1 string ethereum Auto-configure reporter to emulate an L1 network. (See supported networks)
L2 string - Auto-configure reporter to emulate an L2 network (See supported networks)
L1Etherscan string - API key to use when fetching live gasPrice, baseFee, and blobBaseFee data from an L1 network. (Optional, see Supported Networks)
L2Etherscan string - API key to use when fetching live gasPrice data from an L2 network (Optional, see Supported Networks)
offline bool false Turn off remote calls to fetch data
optimismHardfork string ecotone Optimism hardfork to emulate L1 & L2 gas costs for.
proxyResolver Class - User-defined class which helps reporter identify contract targets of proxied calls. (See Advanced Usage)
remoteContracts Array - List of forked-network deployed contracts to track execution costs for.(See Advanced Usage)
reportPureAndViewMethods bool false Track gas usage for methods invoked via eth_call. (Incurs a performance penalty that can be significant for large test suites)
🔆 DISPLAY
currencyDisplayPrecision number 2 Decimal precision to show nation state currency costs in
darkMode bool false Use colors better for dark backgrounds when printing to stdout
forceTerminalOutput bool false Write to terminal even when saving output to file
forceTerminalOutputFormat string - Table format to output forced terminal output in ("legacy" / "terminal" / "markdown")
noColors bool false Omit terminal color in output
reportFormat string terminal Report formats ("legacy" / "terminal" / "markdown")
showMethodSig bool false Display the complete function signature of methods. (Useful if you have overloaded methods)
showUncalledMethods bool false List all methods and deployments, even if no transactions were recorded for them
suppressTerminalOutput bool false Skip writing the table to stdout. (Useful if you only want to write JSON to file)
💾 OUTPUT
includeBytecodeInJSON bool false Include bytecode and deployedBytecode blobs in JSON output
outputFile string - Relative path to a file to output text table to (instead of stdout)
outputJSONFile string - Relative path to a file to output gas data in JSON format to. (See Advanced Usage)
outputJSON bool false Write options, methods, deployment data in JSON format to file. (See Advanced Usage)
rst bool false Output with a reStructured text code-block directive. (Useful if you want to include report in ReadTheDocs or Sphinx docs)
rstTitle string - Title for reStructured text header
🔍 LOW-LEVEL CONFIG
gasPrice number - Gwei price per gas unit (Ex: 25). By default, this is fetched from live network when coinmarketcap option is defined
baseFee number - Gwei base fee per gas unit used to calculate L1 calldata costs for L2 transactions (Ex: 25). By default, this is fetched from live network when L2 & coinmarketcap options are defined
baseFeePerByte number - Gwei fee per byte used to calculate L1 calldata costs for Arbitrum transactions (Ex: 25). See arbitrum gas estimation docs for details. By default, this is fetched from live network when L2 is set to 'arbitrum' & coinmarketcap options are defined
blobBaseFee number - Gwei blob base fee per gas unit used to calculate post-EIP-7516 L1 calldata costs for L2 transactions (Ex: 25). By default, this is fetched from live network when L2 & coinmarketcap options are defined
blobBaseFeeApi string - URL to fetch live execution network blob base fee from. (By default, this is auto-configured based on the L1 or L2 setting)
gasPriceApi string - URL to fetch live execution network gas price from. (By default, this is auto-configured based on the L1 or L2 setting)
getBlockApi string - URL to fetch L1 block header from when simulating L2. (By default, this is auto-configured based on the L2 setting)
opStackBaseFeeScalar number - Scalar applied to L1 base fee when calculating L1 data cost (see Advanced Usage)
opStackBlobBaseFeeScalar number - Scalar applied to L1 blob base fee when calculating L1 data cost (see Advanced Usage)
token string - Network token gas fees are denominated in (ex:"ETH"). (By default, this is auto-configured based on the L1 or L2 setting)
tokenPrice string - Network token price per nation state currency unit. (To denominate costs in network token set this to "1")

Utility Tasks

The plugin also provides additional utility commands for managing gas reporter output

hhgas:merge

Merges several JSON formatted gas reports into a single object. This is useful if you're post-processing the data and running your tests in a parallelized CI environment.

Usage

npx hardhat hhgas:merge "gasReporterOutput-*.json"

Supported Networks

API keys for the networks this plugin auto-configures via the L1 and L2 options are available from the links below. In many cases these aren't equired - you'll only need to set them if you start seeing rate-limit warnings.

L2

  • arbitrum (live baseFeePerByte prices require an API key)
  • base (live blobBaseFee prices require an API key)
  • optimism (live blobBaseFee prices require an API key)

L1

Funding

You can support hardhat-gas-reporter via DRIPS, a public goods protocol that helps you direct funding to packages in your dependency tree.