Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: gas benchmark setup #176

Merged
merged 2 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .forge-snapshots/LightAccount_Runtime_AccountCreation.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
143836
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
174143
25 changes: 25 additions & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Format

on: [pull_request, workflow_dispatch]

concurrency:
group: ${{github.workflow}}-${{github.ref}}
cancel-in-progress: true

# Runs linter, tests, and inspection checker in parallel
jobs:
lint:
name: Check Format and Run Linters
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- uses: ./.github/workflows/setup-ci

- name: "Check formatting"
run: pnpm fmt:check

- name: "Lint the contracts"
run: "pnpm lint"
22 changes: 22 additions & 0 deletions .github/workflows/gas.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Gas

on: [pull_request, workflow_dispatch]

concurrency:
group: ${{github.workflow}}-${{github.ref}}
cancel-in-progress: true

# Runs linter, tests, and inspection checker in parallel
jobs:
lint:
name: Check gas snapshot values
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- uses: ./.github/workflows/setup-ci

- name: "Check gas snapshot"
run: pnpm gas:check
16 changes: 0 additions & 16 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,6 @@ concurrency:

# Runs linter, tests, and inspection checker in parallel
jobs:
lint:
name: Run Linters
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- uses: ./.github/workflows/setup-ci

- name: "Check formatting"
run: forge fmt --check

- name: "Lint the contracts"
run: "pnpm lint"

test-optimized-test-deep:
name: Run Forge Tests (optimized-test-deep)
runs-on: ubuntu-latest
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/forge-gas-snapshot"]
path = lib/forge-gas-snapshot
url = https://github.com/marktoda/forge-gas-snapshot
File renamed without changes.
21 changes: 21 additions & 0 deletions config/solhint-gas.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"extends": "solhint:recommended",
"rules": {
"func-name-mixedcase": "off",
"immutable-vars-naming": ["error"],
"no-unused-import": ["error"],
"compiler-version": ["error", ">=0.8.20"],
"custom-errors": "off",
"func-visibility": ["error", { "ignoreConstructors": true }],
"max-line-length": "off",
"no-console": "off",
"max-states-count": ["warn", 30],
"modifier-name-mixedcase": ["error"],
"private-vars-leading-underscore": ["error"],
"no-inline-assembly": "off",
"avoid-low-level-calls": "off",
"one-contract-per-file": "off",
"no-empty-blocks": "off",
"reason-string": ["warn", { "maxLength": 64 }]
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
16 changes: 16 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ bytecode_hash = "none"
auto_detect_remappings = false
fs_permissions = [
{ access = "read", path = "./out-optimized" },
{ access = "read-write", path = "./.forge-snapshots" },
{ access = "read", path = "./test/bin" },
]
remappings = [
'forge-std/=lib/forge-std/src/'
]

[fuzz]
runs = 500
Expand Down Expand Up @@ -49,6 +53,18 @@ runs = 100000
runs = 5000
depth = 32

[profile.gas]
via_ir = true
test = 'gas'
optimizer_runs = 10000
out = 'out-optimized'
ffi = true
isolate = true
# forge-gas-snapshot uses a different remapping for forge-std, so we also need to do this within the gas profile.
remappings = [
'forge-std/=lib/forge-std/',
]

[fmt]
line_length = 115
wrap_comments = true
Expand Down
57 changes: 57 additions & 0 deletions gas/lightaccount-v2/ILightAccountFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// SPDX-License-Identifier: UNLICENSED
// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.8.0. SEE SOURCE BELOW. !!
pragma solidity ^0.8.20;

interface ILightAccountFactory {
error AddressEmptyCode(address target);
error AddressInsufficientBalance(address account);
error FailedInnerCall();
error InvalidAction();
error InvalidEntryPoint(address entryPoint);
error OwnableInvalidOwner(address owner);
error OwnableUnauthorizedAccount(address account);
error SafeERC20FailedOperation(address token);
error TransferFailed();
error ZeroAddressNotAllowed();

event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

function ACCOUNT_IMPLEMENTATION() external view returns (address);

function ENTRY_POINT() external view returns (address);

function acceptOwnership() external;

function addStake(uint32 unstakeDelay, uint256 amount) external payable;

function createAccount(address owner, uint256 salt) external returns (address account);

function getAddress(address owner, uint256 salt) external view returns (address);

function owner() external view returns (address);

function pendingOwner() external view returns (address);

function renounceOwnership() external view;

function transferOwnership(address newOwner) external;

function unlockStake() external;

function withdraw(address to, address token, uint256 amount) external;

function withdrawStake(address to) external;

receive() external payable;
}

// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON:
/*
[{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"contract
IEntryPoint","name":"entryPoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidAction","type":"error"},{"inputs":[{"internalType":"address","name":"entryPoint","type":"address"}],"name":"InvalidEntryPoint","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"ACCOUNT_IMPLEMENTATION","outputs":[{"internalType":"contract
LightAccount","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ENTRY_POINT","outputs":[{"internalType":"contract
IEntryPoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"unstakeDelay","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addStake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"createAccount","outputs":[{"internalType":"contract
LightAccount","name":"account","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address
payable","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address
payable","name":"to","type":"address"}],"name":"withdrawStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]*/
39 changes: 39 additions & 0 deletions gas/lightaccount-v2/LightAccount.gas.t.sol

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions gas/simpleaccount/ISimpleAccountFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: UNLICENSED
// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.8.0. SEE SOURCE BELOW. !!
pragma solidity ^0.8.20;

interface ISimpleAccountFactory {
function accountImplementation() external view returns (address);

function createAccount(address owner, uint256 salt) external returns (address ret);

function getAddress(address owner, uint256 salt) external view returns (address);
}

// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON:
/*
[{"inputs":[{"internalType":"contract
IEntryPoint","name":"_entryPoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"accountImplementation","outputs":[{"internalType":"contract
SimpleAccount","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"createAccount","outputs":[{"internalType":"contract
SimpleAccount","name":"ret","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]*/
39 changes: 39 additions & 0 deletions gas/simpleaccount/SimpleAccount.gas.t.sol

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lib/forge-gas-snapshot
Submodule forge-gas-snapshot added at 03b10b
13 changes: 9 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@
"solhint": "^3.6.2"
},
"scripts": {
"lint": "pnpm lint:src && pnpm lint:test && pnpm lint:script",
"lint:src": "solhint --max-warnings 0 -c .solhint-src.json './src/**/*.sol'",
"lint:test": "solhint --max-warnings 0 -c .solhint-test.json './test/**/*.sol'",
"lint:script": "solhint --max-warnings 0 -c .solhint-script.json './script/**/*.sol'"
"fmt": "forge fmt && FOUNDRY_PROFILE=gas forge fmt",
"fmt:check": "forge fmt --check && FOUNDRY_PROFILE=gas forge fmt --check",
"gas": "FOUNDRY_PROFILE=gas forge test -vv",
"gas:check": "FOUNDRY_PROFILE=gas FORGE_SNAPSHOT_CHECK=true forge test -vv",
"lint": "pnpm lint:src && pnpm lint:test && pnpm lint:gas && pnpm lint:script",
"lint:src": "solhint --max-warnings 0 -c ./config/solhint-src.json './src/**/*.sol'",
"lint:test": "solhint --max-warnings 0 -c ./config/solhint-test.json './test/**/*.sol'",
"lint:gas": "solhint --max-warnings 0 -c ./config/solhint-gas.json './gas/**/*.sol'",
"lint:script": "solhint --max-warnings 0 -c ./config/solhint-script.json './script/**/*.sol'"
}
}
4 changes: 2 additions & 2 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
ds-test/=lib/forge-std/lib/ds-test/src/
forge-std/=lib/forge-std/src/
modular-account-libs/=node_modules/modular-account-libs/src/
@eth-infinitism/account-abstraction/=node_modules/account-abstraction/contracts/
account-abstraction/=node_modules/account-abstraction/contracts/
@openzeppelin/=lib/openzeppelin-contracts/
@alchemy/light-account/=lib/light-account/
solady=node_modules/solady/src/
@erc-6900/reference-implementation/=node_modules/reference-implementation/src/
@erc-6900/reference-implementation/=node_modules/reference-implementation/src/
forge-gas-snapshot/=lib/forge-gas-snapshot/src/
Loading
Loading