• Stars
    star
    202
  • Rank 193,635 (Top 4 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 2 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

πŸ› οΈ Easily track & compare gas costs estimated by Foundry on each of your Pull Requests!

image

πŸ”₯πŸ› οΈ Foundry Gas Diff Reporter

  • Easily compare gas reports generated by Foundry automatically on each of your Pull Requests!
  • Check out the Live example to see how it looks!

Getting started

Automatically generate a gas report diff on every PR

Add a workflow (.github/workflows/foundry-gas-diff.yml):

name: Report gas diff

on:
  push:
    branches:
      - main
  pull_request:
    # Optionally configure to run only for changes in specific files. For example:
    # paths:
    # - src/**
    # - test/**
    # - foundry.toml
    # - remappings.txt
    # - .github/workflows/foundry-gas-diff.yml

jobs:
  compare_gas_reports:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive

      - name: Install Foundry
        uses: onbjerg/foundry-toolchain@v1
        with:
          version: nightly

      # Add any step generating a gas report to a temporary file named gasreport.ansi. For example:
      - name: Run tests
        run: forge test --gas-report > gasreport.ansi # <- this file name should be unique in your repository!
        env:
          # make fuzzing semi-deterministic to avoid noisy gas cost estimation
          # due to non-deterministic fuzzing (but still use pseudo-random fuzzing seeds)
          FOUNDRY_FUZZ_SEED: 0x${{ github.event.pull_request.base.sha || github.sha }}

      - name: Compare gas reports
        uses: Rubilmax/[email protected]
        with:
          summaryQuantile: 0.9 # only display the 10% most significant gas diffs in the summary (defaults to 20%)
          sortCriteria: avg,max # sort diff rows by criteria
          sortOrders: desc,asc # and directions
          ignore: test-foundry/**/* # filter out gas reports from specific paths (test/ is included by default)
        id: gas_diff

      - name: Add gas diff to sticky comment
        if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target'
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          # delete the comment in case changes no longer impact gas costs
          delete: ${{ !steps.gas_diff.outputs.markdown }}
          message: ${{ steps.gas_diff.outputs.markdown }}

ℹ️ An error will appear at first run!
πŸ”΄ Error: No workflow run found with an artifact named "main.gasreport.ansi"
As the action is expecting a comparative file stored on the base branch and cannot find it (because the action never ran on the target branch and thus has never uploaded any gas report)

⚠️ v3.9+ is no longer working with the latest release of Foundry. Please use v3.10+ if a message displays "Is this a Foundry gas report?"


How it works

Everytime somebody opens a Pull Request, the action expects Foundry forge to run a test suite, generating a gas report to a temporary file (named gasreport.ansi by default).

Once generated, the action will fetch the comparative gas report stored as an artifact from previous runs; parse & compare them, storing the results in the action's outputs as shell and as markdown.

You can then do whatever you want with the results!

Our recommandation: Automatically submit a sticky comment displaying the gas diff!


Options

report {string}

This should correspond to the path of a file where the output of forge's gas report has been logged. Only necessary when generating multiple gas reports on the same repository.

⚠️ Make sure this file uniquely identifies a gas report, to avoid messing up with a gas report of another workflow on the same repository!

Defaults to: gasreport.ansi

base {string}

The gas diff reference branch name, used to fetch the previous gas report to compare the freshly generated gas report to.

Defaults to: ${{ github.base_ref || github.ref_name }}

head {string}

The gas diff target branch name, used to upload the freshly generated gas report.

Defaults to: ${{ github.head_ref || github.ref_name }}

token {string}

The github token allowing the action to upload and download gas reports generated by foundry. You should not need to customize this, as the action already has access to the default Github Action token.

Defaults to: ${{ github.token }}

header {string}

The top section displayed in the markdown output. Can be used to identify multiple gas diffs in the same PR or add metadata/information to the markdown output.

Defaults to:

# Changes to gas cost

summaryQuantile {number}

The quantile threshold to filter avg gas cost diffs to display in the summary top section.

Defaults to: 0.8

sortCriteria {string[]}

A list of criteria to sort diff rows by in the report table (can be name | min | avg | median | max | calls), separated by a comma. Must have the same length as sortOrders.

Defaults to: name

sortOrders {string[]}

A list of directions to sort diff rows by in the report table (can be asc | desc), for each sort criterion, separated by a comma. Must have the same length as sortCriteria.

Defaults to: asc

ignore {string[]}

The list of contract paths from which to ignore gas reports, separated by a comma. This allows to clean out gas diffs from dependency contracts impacted by a change (e.g. Proxies, ERC20, ...).

No default assigned: optional opt-in (Please note that node dependencies are always discarded from gas reports)

match {string[]}

The list of contract paths of which only to keep gas reports, separated by a comma. This allows to only display gas diff of specific contracts.

No default assigned: optional opt-in

⚠️ Known limitations

Library gas reports
Forge does not generate library gas reports. You need to wrap their usage in a contract calling the library to be able to compare gas costs of calling the library.

Average gas cost estimation
Average & median gas costs for each function is estimated based on the test suite, which means they are easily impacted by small changes in the tests. We recommend using a separate, specific test suite, rarily updated, designed to perform accurate gas estimations.

Fuzzing impacts gas costs
Fuzzing can lead differences in gas costs estimated each time a test suite is ran. We thus recommend setting a deterministic fuzzing seed via the --fuzz-seed argument.

This repository is maintained independently from Foundry and may not work as expected with all versions of forge.

More Repositories

1

foundry-storage-check

πŸ” Protect your Smart Contract Proxy from storage collisions upon upgrading, by running this action in a CI on each of your Pull Requests!
TypeScript
92
star
2

executooor

πŸ›£οΈ The safest & most versatile multi-purpose execution contract (highway to MEV!)
TypeScript
60
star
3

ethers-multicall-provider

βš‘πŸ•°οΈ Call any set of functions from any set of smart contracts in a single RPC query, seamlessly using ethers' providers API!
TypeScript
58
star
4

peerjs-multichat

Serverless, secure & persistent multichat proof of concept
HTML
18
star
5

etherscan-abi

⏬ Fetch the most up-to-date ABI of verified Smart Contracts (including proxy implementations) from Etherscan in seconds!
TypeScript
12
star
6

evm-maths

βž— Useful bigint math libraries to ease the journey through off-chain fixed-point arithmetics
TypeScript
11
star
7

hardhat-deal

🎩πŸͺ„ Easily deal any amount of any ERC20 tokens to any account on the hardhat network
TypeScript
11
star
8

ethers-types

πŸ›Ÿ Making web3 more predictable & safer, 1 type at a time!
TypeScript
6
star
9

viem-deal

🎩πŸͺ„ Easily deal any amount of any ERC20 tokens to any account on any `setStorageAt`-compatible network, using viem!
TypeScript
6
star
10

Rubilmax

2
star
11

peerpy

P2P connections over TCP made dead simple!
Python
2
star
12

react-generator

Template minimal setup for React, with generators
Handlebars
1
star
13

solidity-interfacer

πŸš€πŸ–¨οΈ Automatically generates your Solidity contracts' interfaces!
JavaScript
1
star
14

FreeFlowGame

School Java Project
Java
1
star
15

locketh

Solidity
1
star
16

etherscan-src

β¬πŸš€ Fetch the most up-to-date sources of verified Smart Contracts (including proxy implementations) from Etherscan in seconds!
TypeScript
1
star