Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.githooks/* text eol=lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/sh
#
# Custom pre-commit hook to run Solhint on staged Solidity files

old_stash=$(git rev-parse -q --verify refs/stash)
git stash push -q --keep-index
new_stash=$(git rev-parse -q --verify refs/stash)

# If there were no changes (e.g., `--amend` or `--allow-empty`)
# then nothing was stashed, and we should skip everything.
if [ "$old_stash" = "$new_stash" ]; then
exit 0
fi

# Run Solhint on all staged .sol files
SOL_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep ".sol$")
status=0
if [ -n "$SOL_FILES" ]; then
npx solhint $SOL_FILES
status=$?
fi

# Restore changes
git reset --hard -q && git stash apply --index -q && git stash drop -q

# Exit with status from test-run: nonzero prevents commit
if [ $status -ne 0 ]; then
echo "Solhint failed. Please fix errors and try again."
fi
exit $status
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: test

on: workflow_dispatch

env:
FOUNDRY_PROFILE: ci

jobs:
check:
strategy:
fail-fast: true

name: Foundry project
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

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

- name: Run Forge build
run: |
forge --version
forge build --sizes
id: build

- name: Run Forge tests
run: |
forge test -vvv
id: test
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "solhint:recommended",
"rules": {
"compiler-version": ["error", "^0.8.18"],
"func-visibility": ["error", { "ignoreConstructors": true }],
"reason-string": ["warn", { "maxLength": 96 }],
"no-console": "off"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# ERC-2470 Libs

This repository contains helpers for interacting with the [ERC-2470 Singleton Deployer](https://eips.ethereum.org/EIPS/eip-2470) in [forge scripts](https://book.getfoundry.sh/reference/forge/forge-script).

## Usage

Install this package via forge install:

```bash
forge install ScreamingHawk/erc2470-libs
```

Base your scripts on the `SingletonDeployer` script contract:

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.18;

import {SingletonDeployer, console} from "erc2470-libs/script/SingletonDeployer.s.sol";
import {MyContract} from "../src/MyContract.sol";

contract Deploy is SingletonDeployer {
function run() external {
uint256 pk = vm.envUint("PRIVATE_KEY");

bytes32 salt = bytes32(0);
address exampleConstructorArg = address(0);

bytes memory initCode = abi.encodePacked(type(MyContract).creationCode, abi.encode(exampleConstructorArg));

address expectedAddr = _singletonAddressOf(initCode, salt);
address actualAddr = _deployIfNotAlready("MyContract", initCode, salt, pk);
}
}
```

This script will deploy your contract using the `SingletonDeployer` and output the address of the deployed contract.
If your contract has already been deployed, the address will be returned without deploying again.
If the `SingletonDeployer` has not yet been deployed on chain, that will be done first.

> [!NOTE]
> The `SingletonDeployer` has a fixed gas cost which may not be compatible with all networks. If deployment fails, check the gas settings of the network.
> A network base fee exceeding 100 gwei will cause the deployment to fail.
> Networks requiring additional gas costs (L2, etc) will require additional funds for the factory deployer.

Ensure you have your private key set in your `.env` file:

```txt
PRIVATE_KEY=0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
```

Then run your script using [forge script](https://book.getfoundry.sh/reference/forge/forge-script):

```bash
forge script script/Deploy.s.sol
```

> [!WARNING]
> Forge is unable to automatically verify deployments created via the `SingletonDeployer`. You will need to manually verify the contract using the `forge verify` command.

### Git Hooks

To install git hooks run the following:

```bash
chmod +x .githooks/pre-commit
git config core.hooksPath .githooks
```

### Testing

Test by running the `MockERC20Deployer` script against a local anvil instance (or the network of your choice):

```bash
anvil
```

```bash
forge script script/MockERC20Deployer.s.sol --rpc-url http://localhost:8545
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[profile.default]
src = "src"
out = "out"
libs = ["lib"]

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/Vm.sol linguist-generated
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: CI

on:
workflow_dispatch:
pull_request:
push:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

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

- name: Print forge version
run: forge --version

# Backwards compatibility checks:
# - the oldest and newest version of each supported minor version
# - versions with specific issues
- name: Check compatibility with latest
if: always()
run: |
output=$(forge build --skip test)
if echo "$output" | grep -q "Warning"; then
echo "$output"
exit 1
fi

- name: Check compatibility with 0.8.0
if: always()
run: |
output=$(forge build --skip test --use solc:0.8.0)
if echo "$output" | grep -q "Warning"; then
echo "$output"
exit 1
fi

- name: Check compatibility with 0.7.6
if: always()
run: |
output=$(forge build --skip test --use solc:0.7.6)
if echo "$output" | grep -q "Warning"; then
echo "$output"
exit 1
fi

- name: Check compatibility with 0.7.0
if: always()
run: |
output=$(forge build --skip test --use solc:0.7.0)
if echo "$output" | grep -q "Warning"; then
echo "$output"
exit 1
fi

- name: Check compatibility with 0.6.12
if: always()
run: |
output=$(forge build --skip test --use solc:0.6.12)
if echo "$output" | grep -q "Warning"; then
echo "$output"
exit 1
fi

- name: Check compatibility with 0.6.2
if: always()
run: |
output=$(forge build --skip test --use solc:0.6.2)
if echo "$output" | grep -q "Warning"; then
echo "$output"
exit 1
fi

# via-ir compilation time checks.
- name: Measure compilation time of Test with 0.8.17 --via-ir
if: always()
run: forge build --skip test --contracts test/compilation/CompilationTest.sol --use solc:0.8.17 --via-ir

- name: Measure compilation time of TestBase with 0.8.17 --via-ir
if: always()
run: forge build --skip test --contracts test/compilation/CompilationTestBase.sol --use solc:0.8.17 --via-ir

- name: Measure compilation time of Script with 0.8.17 --via-ir
if: always()
run: forge build --skip test --contracts test/compilation/CompilationScript.sol --use solc:0.8.17 --via-ir

- name: Measure compilation time of ScriptBase with 0.8.17 --via-ir
if: always()
run: forge build --skip test --contracts test/compilation/CompilationScriptBase.sol --use solc:0.8.17 --via-ir

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

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

- name: Print forge version
run: forge --version

- name: Run tests
run: forge test -vvv

fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

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

- name: Print forge version
run: forge --version

- name: Check formatting
run: forge fmt --check
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Sync Release Branch

on:
release:
types:
- created

jobs:
sync-release-branch:
runs-on: ubuntu-latest
if: startsWith(github.event.release.tag_name, 'v1')
steps:
- name: Check out the repo
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: v1

# The email is derived from the bots user id,
# found here: https://api.github.com/users/github-actions%5Bbot%5D
- name: Configure Git
run: |
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com

- name: Sync Release Branch
run: |
git fetch --tags
git checkout v1
git reset --hard ${GITHUB_REF}
git push --force
Loading