Foundry Template
A Foundry-based template for developing Solidity smart contracts, with sensible defaults. Based on @PaulRBerg template.
What's Inside
- Forge: compile, test, fuzz, format, and deploy smart contracts
- Forge Std: collection of helpful contracts and cheatcodes for testing
- PRBTest: modern collection of testing assertions and logging utilities
- Prettier: code formatter for non-Solidity files
- Solhint Community: linter for Solidity code
- Make: build automation tool that allows developers to automate repetitive tasks
- Lefthook: Fast and powerful Git hooks manager for any type of projects
Getting Started
Prerequisites
This repository uses make
to automate repetitive tasks.
make
is a build automation tool that employs a file known as a makefile to automate the construction of executable
programs and libraries. The makefile details the process of deriving the target program from the source files and other
dependencies. This allows developers to automate repetitive tasks and manage complex build processes efficiently. make
is our primary tool in a multi-environment repository. It enables us to centralize all commands into a single file
(the makefile), eliminating the need to deal with npm
scripts defined in a package.json or remembering
the various commands provided by the foundry
cli. If you're unfamiliar with make
, you can read more about it
here.
đĄ Running make at the root of the project will display a list of all the available commands. This can be useful to know what you can do with the project.
Make of Linux
make
is automatically included in all modern Linux distributions. If you're using Linux, you should be able to use
make
without any additional steps. If not, you can likely find it in the package tool you usually use.
Make on MacOS
MacOS users can install make
using Homebrew with the following command:
brew install make
Installation
Click the Use this template
button at the top of the page to
create a new repository with this repo as the initial state.
Or, if you prefer to install the template manually:
forge init my-project --template https://github.com/qd-qd/template-foundry
cd my-project
make install # install the forge dependencies and the npm dependencies
If this is your first time with Foundry, check out the installation instructions.
âšī¸ As part of the initialization process, a one-time script, which can be found here, is utilized to tailor the template to your specific project. This script will automatically update the package.json file with details like your project's name, the author's name, the homepage, the repository URL, etc. Additionally, it will remove unnecessary files, such as the FUNDING.yml file and the initialization script itself.
Git hooks
This project uses Lefthook
to manage Git hooks, which are scripts that run automatically when certain Git events
occur, such as committing code or pushing changes to a remote repository. Lefthook
simplifies the management and
execution of these scripts.
After installing the dependencies, you can configure the Git hooks by running the following command in the project directory:
make hooks-i
This command installs a Git hook that runs Lefthook before pushing code to a remote repository. If Lefthook fails, the push is aborted.
If you wish to run Lefthook manually, you can use the following command:
make hooks
Executing this will activate all the Git hooks specified in the lefthook file, including commands for linting, formatting, testing, and compiling.
Skipping git hooks
If you need to intentionally skip Lefthook, you can pass the --no-verify
flag to the git push command. For example to
bypass Lefthook when pushing code, use the following command:
git push origin --no-verify
Features
This template builds upon the frameworks and libraries mentioned above, so for details about their specific features, please consult their respective documentation.
For example, if you're interested in exploring Foundry in more detail, you should look at the Foundry Book. In particular, you may be interested in reading the Writing Tests tutorial.
Sensible Defaults
This template comes with a set of sensible default configurations for you to use. These defaults can be found in the following files:
âââ .gitignore
âââ .prettierignore
âââ .prettierrc.yml
âââ .solhint.json
âââ .nvmrc
âââ lefthook.yml
âââ makefile
âââ slither.config.json
âââ foundry.toml
GitHub Actions
This template comes with GitHub Actions pre-configured.
- quality-checks.yml: runs the compilation command, the linter and the
formatter on every push and pull request made to the
main
branch. The size of the contracts is printed in the logs. - static-analysis.yml: runs the static analysis tool on every push and pull
request made to the
main
branch. This action uses slither and is only triggered when specific files are modified. - tests.yml: runs the tests onsevery push and pull request made to the
main
branch. This action also compare the gas cost between themain
branch and the pull request branch and post the difference as a comment on the pull request. - release-package.yml: creates a new release every time you push a new tag to
the repository. This action is only triggered on tags starting with
v
. Once the release is created, the action is also in charge of deploying the documentation to thegh-pages
branch. THIS ACTION NEEDS AN ACTION FROM YOUR SIDE TO WORK
You can edit the CI scripts in the workflows directory.
Configure the release action
The release action is in charge of deploying the documentation to the gh-pages
branch. To do so, it needs to have a
personal access token with the right permissions. To create this token, go to the
settings of your Github account. Make sure to select the permissions
listed below. Once create, copy the token, go to the Github repository of this project and create a secret named
RELEASE_TOKEN
with the value of the token you just created. Here are the repositories permissions required by the
token:
- Actions: Read and write
- Contents: Read and write
- Commit statuses: Read-only
- Metadata: Read-only
- Pull requests: Read-only
Writing Tests
To write a new test contract, you start by importing PRBTest and inherit from
it in your test contract. PRBTest comes with a pre-instantiated cheatcodes
environment accessible via the vm
property. If you would like to view the logs in the terminal output you can run the
dedicated verbose command and use
console.log.
This template comes with an example test contract Foo.t.sol
Usage
You can access a list of all available commands by running make
in the project's root directory.
make
These commands are outlined in the makefile.
Scripts
Deploy
This script is located in the script directory. It deploys the contract to a network. For example, to deploy to Anvil, you can run the following command:
forge script script/Deploy.s.sol --broadcast --fork-url http://localhost:8545
For this script to work, you need to have a MNEMONIC
environment variable set to a valid
BIP39 mnemonic.
For instructions on how to deploy to a testnet or mainnet, check out the Solidity Scripting tutorial.
Notes
- Foundry uses git submodules to manage dependencies. For detailed instructions on working with dependencies, please refer to the guide in the book
- You don't have to create a
.env
file, but filling in the environment variables may be useful when debugging and testing against a fork. - This template uses npm to manage JavaScript dependencies.
- This template only uses slither in the CI pipeline. If you want to run it locally, you need to install it for yourself by following the instructions in the documentation.
- This template includes a opiniated contributing guide you free to update.
- Remappings are configured in the foundry.toml file file in order to centralize the configuration. Feel free to update them.
Related Efforts
- abigger87/femplate
- cleanunicorn/ethereum-smartcontract-template
- foundry-rs/forge-template
- FrankieIsLost/forge-template
- PaulRBerg/foundry-template
License
This project is licensed under MIT.
Acknowledgements
This template has been boostrapped using @PaulRBerg
template. This version is a bit more opinionated (make
...) and comes
with a few more features. Thanks to him for his valuable contributions to the community.