How to see gas costs with foundry/forge

When working with contracts I sometimes want to optimize the gas spent to complete common transactions.

Forge has the capability to do this.

https://github.com/xliumin/payable-gas-optimization/tree/main/src

Here’s an example github repo. The concept behind this repo is that it demonstrates that functions marked as payable actually use less gas than functions that are not marked as payable. (Note that this doesn’t necessarily mean you should do this, it has security tradeoffs.)

You can run

forge test -vvv

You should see the following output:

[FAIL. Reason: Revert(Reverted)] testExample() (gas: 57835)
Traces:

  [98] ContractTest::setUp()
    └─ ← ()
  [57835] ContractTest::testExample()
    ├─ → new Contract@0xce71c246
    │   └─ ← 125 bytes of code
    ├─ [129] Contract::doSomething()
    │   └─ ← ()
    └─ ← ()

[FAIL. Reason: Revert(Reverted)] testExamplePayable() (gas: 57811)
Traces:

  [98] ContractTest::setUp()
    └─ ← ()
  [57811] ContractTest::testExamplePayable()
    ├─ → new Contract@0xce71c246
    │   └─ ← 125 bytes of code
    ├─ [83] Contract::doSomethingPayable()
    │   └─ ← ()
    └─ ← ()


Failed tests:
[FAIL. Reason: Revert(Reverted)] testExample() (gas: 57835)
[FAIL. Reason: Revert(Reverted)] testExamplePayable() (gas: 57811)

We can see each individual call’s gas usage, and see that the payable version uses less gas. Note that you have to have a failing test to see the gas output here. I am not aware of a way to see the gas output without having a failing test.