feat: initial commit
This commit is contained in:
commit
284cc38916
|
@ -0,0 +1,19 @@
|
||||||
|
# EditorConfig http://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# All files
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.sol]
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.tree]
|
||||||
|
indent_size = 1
|
|
@ -0,0 +1,11 @@
|
||||||
|
export API_KEY_ALCHEMY="YOUR_API_KEY_ALCHEMY"
|
||||||
|
export API_KEY_ARBISCAN="YOUR_API_KEY_ARBISCAN"
|
||||||
|
export API_KEY_BSCSCAN="YOUR_API_KEY_BSCSCAN"
|
||||||
|
export API_KEY_ETHERSCAN="YOUR_API_KEY_ETHERSCAN"
|
||||||
|
export API_KEY_GNOSISSCAN="YOUR_API_KEY_GNOSISSCAN"
|
||||||
|
export API_KEY_INFURA="YOUR_API_KEY_INFURA"
|
||||||
|
export API_KEY_OPTIMISTIC_ETHERSCAN="YOUR_API_KEY_OPTIMISTIC_ETHERSCAN"
|
||||||
|
export API_KEY_POLYGONSCAN="YOUR_API_KEY_POLYGONSCAN"
|
||||||
|
export API_KEY_SNOWTRACE="YOUR_API_KEY_SNOWTRACE"
|
||||||
|
export MNEMONIC="YOUR_MNEMONIC"
|
||||||
|
export FOUNDRY_PROFILE="default"
|
|
@ -0,0 +1,18 @@
|
||||||
|
| script/Deploy.s.sol:Deploy contract | | | | | |
|
||||||
|
|-------------------------------------|-----------------|--------|--------|--------|---------|
|
||||||
|
| Deployment Cost | Deployment Size | | | | |
|
||||||
|
| 320782 | 2729 | | | | |
|
||||||
|
| Function Name | min | avg | median | max | # calls |
|
||||||
|
| run | 221942 | 221942 | 221942 | 221942 | 1 |
|
||||||
|
|
||||||
|
|
||||||
|
| src/Foo.sol:Foo contract | | | | | |
|
||||||
|
|--------------------------|-----------------|-----|--------|-----|---------|
|
||||||
|
| Deployment Cost | Deployment Size | | | | |
|
||||||
|
| 20275 | 131 | | | | |
|
||||||
|
| Function Name | min | avg | median | max | # calls |
|
||||||
|
| id | 235 | 235 | 235 | 235 | 1 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
FooTest:test_Example() (gas: 8662)
|
|
@ -0,0 +1,3 @@
|
||||||
|
lib/** linguist-vendored
|
||||||
|
|
||||||
|
* text=auto eol=lf
|
|
@ -0,0 +1,11 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Describe the changes made in your pull request here.
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
Ensure you completed **all of the steps** below before submitting your pull request:
|
||||||
|
|
||||||
|
- [ ] Added natspec comments?
|
||||||
|
- [ ] Ran `pnpm adorno`?
|
||||||
|
- [ ] Ran `pnpm verify`?
|
|
@ -0,0 +1,18 @@
|
||||||
|
name: Add issue to task board
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
add-to-project:
|
||||||
|
name: Add to task board
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/add-to-project@v0.5.0
|
||||||
|
with:
|
||||||
|
# You can target a project in a different organization
|
||||||
|
# to the issue
|
||||||
|
project-url: https://github.com/orgs/vacp2p/projects/10
|
||||||
|
github-token: ${{ secrets.ADD_TO_VAC_BOARD_PAT }}
|
|
@ -0,0 +1,18 @@
|
||||||
|
name: Add PR task board
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
add-to-project:
|
||||||
|
name: Add to task board
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/add-to-project@v0.5.0
|
||||||
|
with:
|
||||||
|
# You can target a project in a different organization
|
||||||
|
# to the issue
|
||||||
|
project-url: https://github.com/orgs/vacp2p/projects/10
|
||||||
|
github-token: ${{ secrets.ADD_TO_VAC_BOARD_PAT }}
|
|
@ -0,0 +1,171 @@
|
||||||
|
name: "CI"
|
||||||
|
|
||||||
|
env:
|
||||||
|
API_KEY_ALCHEMY: ${{ secrets.API_KEY_ALCHEMY }}
|
||||||
|
FOUNDRY_PROFILE: "ci"
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "main"
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
cancel-in-progress: true
|
||||||
|
group: ${{github.workflow}}-${{github.ref}}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
steps:
|
||||||
|
- name: "Check out the repo"
|
||||||
|
uses: "actions/checkout@v3"
|
||||||
|
with:
|
||||||
|
submodules: "recursive"
|
||||||
|
|
||||||
|
- name: "Install Foundry"
|
||||||
|
uses: "foundry-rs/foundry-toolchain@v1"
|
||||||
|
|
||||||
|
- name: "Install Pnpm"
|
||||||
|
uses: "pnpm/action-setup@v2"
|
||||||
|
with:
|
||||||
|
version: "8"
|
||||||
|
|
||||||
|
- name: "Install Node.js"
|
||||||
|
uses: "actions/setup-node@v3"
|
||||||
|
with:
|
||||||
|
cache: "pnpm"
|
||||||
|
node-version: "lts/*"
|
||||||
|
|
||||||
|
- name: "Install the Node.js dependencies"
|
||||||
|
run: "pnpm install"
|
||||||
|
|
||||||
|
- name: "Lint the contracts"
|
||||||
|
run: "pnpm lint"
|
||||||
|
|
||||||
|
- name: "Add lint summary"
|
||||||
|
run: |
|
||||||
|
echo "## Lint result" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
steps:
|
||||||
|
- name: "Check out the repo"
|
||||||
|
uses: "actions/checkout@v3"
|
||||||
|
with:
|
||||||
|
submodules: "recursive"
|
||||||
|
|
||||||
|
- name: "Install Foundry"
|
||||||
|
uses: "foundry-rs/foundry-toolchain@v1"
|
||||||
|
|
||||||
|
- name: "Build the contracts and print their size"
|
||||||
|
run: "forge build --sizes"
|
||||||
|
|
||||||
|
- name: "Add build summary"
|
||||||
|
run: |
|
||||||
|
echo "## Build result" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
test:
|
||||||
|
needs: ["lint", "build"]
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
steps:
|
||||||
|
- name: "Check out the repo"
|
||||||
|
uses: "actions/checkout@v3"
|
||||||
|
with:
|
||||||
|
submodules: "recursive"
|
||||||
|
|
||||||
|
- name: "Install Foundry"
|
||||||
|
uses: "foundry-rs/foundry-toolchain@v1"
|
||||||
|
|
||||||
|
- name: "Show the Foundry config"
|
||||||
|
run: "forge config"
|
||||||
|
|
||||||
|
- name: "Generate a fuzz seed that changes weekly to avoid burning through RPC allowance"
|
||||||
|
run: >
|
||||||
|
echo "FOUNDRY_FUZZ_SEED=$(
|
||||||
|
echo $(($EPOCHSECONDS - $EPOCHSECONDS % 604800))
|
||||||
|
)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: "Run the tests"
|
||||||
|
run: "forge test"
|
||||||
|
|
||||||
|
- name: "Add test summary"
|
||||||
|
run: |
|
||||||
|
echo "## Tests result" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
needs: ["lint", "build"]
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
steps:
|
||||||
|
- name: "Check out the repo"
|
||||||
|
uses: "actions/checkout@v3"
|
||||||
|
with:
|
||||||
|
submodules: "recursive"
|
||||||
|
|
||||||
|
- name: "Install Foundry"
|
||||||
|
uses: "foundry-rs/foundry-toolchain@v1"
|
||||||
|
|
||||||
|
- name: "Generate the coverage report using the unit and the integration tests"
|
||||||
|
run: 'forge coverage --match-path "test/**/*.sol" --report lcov'
|
||||||
|
|
||||||
|
- name: "Upload coverage report to Codecov"
|
||||||
|
uses: "codecov/codecov-action@v3"
|
||||||
|
with:
|
||||||
|
files: "./lcov.info"
|
||||||
|
|
||||||
|
- name: "Add coverage summary"
|
||||||
|
run: |
|
||||||
|
echo "## Coverage result" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "✅ Uploaded to Codecov" >> $GITHUB_STEP_SUMMARY
|
||||||
|
verify:
|
||||||
|
needs: ["lint", "build"]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Install Python
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with: { python-version: 3.9 }
|
||||||
|
|
||||||
|
- name: Install Java
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with: { java-version: "11", java-package: jre }
|
||||||
|
|
||||||
|
- name: Install Certora CLI
|
||||||
|
run: pip3 install certora-cli==5.0.5
|
||||||
|
|
||||||
|
- name: Install Solidity
|
||||||
|
run: |
|
||||||
|
wget https://github.com/ethereum/solidity/releases/download/v0.8.19/solc-static-linux
|
||||||
|
chmod +x solc-static-linux
|
||||||
|
sudo mv solc-static-linux /usr/local/bin/solc
|
||||||
|
|
||||||
|
- name: "Install Pnpm"
|
||||||
|
uses: "pnpm/action-setup@v2"
|
||||||
|
with:
|
||||||
|
version: "8"
|
||||||
|
|
||||||
|
- name: "Install Node.js"
|
||||||
|
uses: "actions/setup-node@v3"
|
||||||
|
with:
|
||||||
|
cache: "pnpm"
|
||||||
|
node-version: "lts/*"
|
||||||
|
|
||||||
|
- name: "Install the Node.js dependencies"
|
||||||
|
run: "pnpm install"
|
||||||
|
|
||||||
|
- name: Verify rules
|
||||||
|
run: "pnpm verify"
|
||||||
|
env:
|
||||||
|
CERTORAKEY: ${{ secrets.CERTORAKEY }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
max-parallel: 16
|
|
@ -0,0 +1,19 @@
|
||||||
|
# directories
|
||||||
|
cache
|
||||||
|
node_modules
|
||||||
|
out
|
||||||
|
|
||||||
|
# files
|
||||||
|
*.env
|
||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
.pnp.*
|
||||||
|
lcov.info
|
||||||
|
yarn.lock
|
||||||
|
|
||||||
|
# broadcasts
|
||||||
|
!broadcast
|
||||||
|
broadcast/*
|
||||||
|
broadcast/*/31337/
|
||||||
|
|
||||||
|
.certora_internal
|
|
@ -0,0 +1,4 @@
|
||||||
|
[submodule "lib/forge-std"]
|
||||||
|
branch = "v1"
|
||||||
|
path = lib/forge-std
|
||||||
|
url = https://github.com/foundry-rs/forge-std
|
|
@ -0,0 +1,18 @@
|
||||||
|
# directories
|
||||||
|
broadcast
|
||||||
|
cache
|
||||||
|
lib
|
||||||
|
node_modules
|
||||||
|
out
|
||||||
|
|
||||||
|
# files
|
||||||
|
*.env
|
||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
.pnp.*
|
||||||
|
lcov.info
|
||||||
|
package-lock.json
|
||||||
|
pnpm-lock.yaml
|
||||||
|
yarn.lock
|
||||||
|
|
||||||
|
slither.config.json
|
|
@ -0,0 +1,7 @@
|
||||||
|
bracketSpacing: true
|
||||||
|
printWidth: 120
|
||||||
|
proseWrap: "always"
|
||||||
|
singleQuote: false
|
||||||
|
tabWidth: 2
|
||||||
|
trailingComma: "all"
|
||||||
|
useTabs: false
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"extends": "solhint:recommended",
|
||||||
|
"rules": {
|
||||||
|
"code-complexity": ["error", 8],
|
||||||
|
"compiler-version": ["error", ">=0.8.19"],
|
||||||
|
"func-name-mixedcase": "off",
|
||||||
|
"func-visibility": ["error", { "ignoreConstructors": true }],
|
||||||
|
"max-line-length": ["error", 120],
|
||||||
|
"named-parameters-mapping": "warn",
|
||||||
|
"no-console": "off",
|
||||||
|
"not-rely-on-time": "off"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"[solidity]": {
|
||||||
|
"editor.defaultFormatter": "NomicFoundation.hardhat-solidity"
|
||||||
|
},
|
||||||
|
"[toml]": {
|
||||||
|
"editor.defaultFormatter": "tamasfe.even-better-toml"
|
||||||
|
},
|
||||||
|
"npm.exclude": "**/lib/**",
|
||||||
|
"solidity.formatter": "forge"
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 Paul Razvan Berg
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||||
|
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
||||||
|
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||||
|
persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||||
|
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,15 @@
|
||||||
|
## Protocol properties and invariants
|
||||||
|
|
||||||
|
Below is a list of all documented properties and invariants of this project that must hold true.
|
||||||
|
|
||||||
|
- **Property** - Describes the property of the project / protocol that should ultimately be tested and formaly verified.
|
||||||
|
- **Type** - Properties are split into 5 main types: **Valid State**, **State Transition**, **Variable Transition**,
|
||||||
|
**High-Level Property**, **Unit Test**
|
||||||
|
- **Risk** - One of **High**, **Medium** and **Low**, depending on the property's risk factor
|
||||||
|
- **Tested** - Whether this property has been (fuzz) tested
|
||||||
|
|
||||||
|
| **Property** | **Type** | **Risk** | **Tested** |
|
||||||
|
| ------------ | -------- | -------- | ---------- |
|
||||||
|
| | | | |
|
||||||
|
| | | | |
|
||||||
|
| | | | |
|
|
@ -0,0 +1,201 @@
|
||||||
|
# Foundry Template [![Github Actions][gha-badge]][gha] [![Foundry][foundry-badge]][foundry] [![License: MIT][license-badge]][license]
|
||||||
|
|
||||||
|
[gha]: https://github.com/waku-org/waku-rlnv2-contract/actions
|
||||||
|
[gha-badge]: https://github.com/waku-org/waku-rlnv2-contract/actions/workflows/ci.yml/badge.svg
|
||||||
|
[foundry]: https://getfoundry.sh/
|
||||||
|
[foundry-badge]: https://img.shields.io/badge/Built%20with-Foundry-FFDB1C.svg
|
||||||
|
[license]: https://opensource.org/licenses/MIT
|
||||||
|
[license-badge]: https://img.shields.io/badge/License-MIT-blue.svg
|
||||||
|
|
||||||
|
A Foundry-based template for developing Solidity smart contracts, with sensible defaults.
|
||||||
|
|
||||||
|
This is a fork of [PaulRBerg's template](https://github.com/PaulRBerg/foundry-template) and adjusted to Vac's smart
|
||||||
|
contracts unit's needs. See [Upstream differences](#upstream-differences) to learn more about how this template differs
|
||||||
|
from Paul's.
|
||||||
|
|
||||||
|
## What's Inside
|
||||||
|
|
||||||
|
- [Forge](https://github.com/foundry-rs/foundry/blob/master/forge): compile, test, fuzz, format, and deploy smart
|
||||||
|
contracts
|
||||||
|
- [Forge Std](https://github.com/foundry-rs/forge-std): collection of helpful contracts and cheatcodes for testing
|
||||||
|
- [Solhint Community](https://github.com/solhint-community/solhint-community): linter for Solidity code
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
Click the [`Use this template`](https://github.com/vacp2p/foundry-template/generate) 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:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ mkdir my-project
|
||||||
|
$ cd my-project
|
||||||
|
$ forge init --template vacp2p/foundry-template
|
||||||
|
$ pnpm install # install Solhint, Prettier, and other Node.js deps
|
||||||
|
```
|
||||||
|
|
||||||
|
If this is your first time with Foundry, check out the
|
||||||
|
[installation](https://github.com/foundry-rs/foundry#installation) instructions.
|
||||||
|
|
||||||
|
## 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](https://book.getfoundry.sh/). In particular, you may be interested in reading the
|
||||||
|
[Writing Tests](https://book.getfoundry.sh/forge/writing-tests.html) tutorial.
|
||||||
|
|
||||||
|
### Upstream differences
|
||||||
|
|
||||||
|
As mentioned above, this template is a fork with adjustments specific to the needs of Vac's smart contract service unit.
|
||||||
|
These differences are:
|
||||||
|
|
||||||
|
- **Removal of [PRBTest](https://github.com/PaulRBerg/prb-test)** - In an attempt to keep dependence on third-party code
|
||||||
|
low, we've decided to remove this library as a standard dependency of every project within Vac. If we do see a need
|
||||||
|
for it, we might bring it back in the future.
|
||||||
|
- **PROPERTIES.md** - For invariant testing and formal verification, we've introduced a `PROPERTIES.md` to document all
|
||||||
|
protocol properties that must hold true.
|
||||||
|
|
||||||
|
### 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:
|
||||||
|
|
||||||
|
```text
|
||||||
|
├── .editorconfig
|
||||||
|
├── .gitignore
|
||||||
|
├── .prettierignore
|
||||||
|
├── .prettierrc.yml
|
||||||
|
├── .solhint.json
|
||||||
|
├── foundry.toml
|
||||||
|
├── remappings.txt
|
||||||
|
└── slither.config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### VSCode Integration
|
||||||
|
|
||||||
|
This template is IDE agnostic, but for the best user experience, you may want to use it in VSCode alongside Nomic
|
||||||
|
Foundation's [Solidity extension](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity).
|
||||||
|
|
||||||
|
For guidance on how to integrate a Foundry project in VSCode, please refer to this
|
||||||
|
[guide](https://book.getfoundry.sh/config/vscode).
|
||||||
|
|
||||||
|
### GitHub Actions
|
||||||
|
|
||||||
|
This template comes with GitHub Actions pre-configured. Your contracts will be linted and tested on every push and pull
|
||||||
|
request made to the `main` branch.
|
||||||
|
|
||||||
|
You can edit the CI script in [.github/workflows/ci.yml](./.github/workflows/ci.yml).
|
||||||
|
|
||||||
|
## Writing Tests
|
||||||
|
|
||||||
|
If you would like to view the logs in the terminal output you can add the `-vvv` flag and use
|
||||||
|
[console.log](https://book.getfoundry.sh/faq?highlight=console.log#how-do-i-use-consolelog).
|
||||||
|
|
||||||
|
This template comes with an example test contract [Foo.t.sol](./test/Foo.t.sol)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
This is a list of the most frequently needed commands.
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
Build the contracts:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ forge build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Clean
|
||||||
|
|
||||||
|
Delete the build artifacts and cache directories:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ forge clean
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compile
|
||||||
|
|
||||||
|
Compile the contracts:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ forge build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Coverage
|
||||||
|
|
||||||
|
Get a test coverage report:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ forge coverage
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deploy
|
||||||
|
|
||||||
|
Deploy to Anvil:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ 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](https://iancoleman.io/bip39/).
|
||||||
|
|
||||||
|
For instructions on how to deploy to a testnet or mainnet, check out the
|
||||||
|
[Solidity Scripting](https://book.getfoundry.sh/tutorials/solidity-scripting.html) tutorial.
|
||||||
|
|
||||||
|
### Format
|
||||||
|
|
||||||
|
Format the contracts:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ forge fmt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gas Usage
|
||||||
|
|
||||||
|
Get a gas report:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ forge test --gas-report
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lint
|
||||||
|
|
||||||
|
Lint the contracts:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ pnpm lint
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Fixing linting issues
|
||||||
|
|
||||||
|
For any errors in solidity files, run `forge fmt`. For errors in any other file type, run `pnpm prettier:write`.
|
||||||
|
|
||||||
|
### Test
|
||||||
|
|
||||||
|
Run the tests:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ forge test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
1. Foundry uses [git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to manage dependencies. For
|
||||||
|
detailed instructions on working with dependencies, please refer to the
|
||||||
|
[guide](https://book.getfoundry.sh/projects/dependencies.html) in the book
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
## Related Efforts
|
||||||
|
|
||||||
|
- [abigger87/femplate](https://github.com/abigger87/femplate)
|
||||||
|
- [cleanunicorn/ethereum-smartcontract-template](https://github.com/cleanunicorn/ethereum-smartcontract-template)
|
||||||
|
- [foundry-rs/forge-template](https://github.com/foundry-rs/forge-template)
|
||||||
|
- [FrankieIsLost/forge-template](https://github.com/FrankieIsLost/forge-template)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under MIT.
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"files": ["src/Foo.sol"],
|
||||||
|
"msg": "Verifying Foo.sol",
|
||||||
|
"rule_sanity": "basic",
|
||||||
|
"verify": "Foo:certora/specs/Foo.spec",
|
||||||
|
"wait_for_results": "all",
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
methods {
|
||||||
|
function id(uint256) external returns (uint256) envfree;
|
||||||
|
}
|
||||||
|
|
||||||
|
rule checkIdOutputIsAlwaysEqualToInput {
|
||||||
|
uint256 input;
|
||||||
|
|
||||||
|
assert id(input) == input;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
codecov:
|
||||||
|
require_ci_to_pass: false
|
||||||
|
comment: false
|
||||||
|
ignore:
|
||||||
|
- "script"
|
||||||
|
- "test"
|
||||||
|
coverage:
|
||||||
|
status:
|
||||||
|
project:
|
||||||
|
default:
|
||||||
|
# advanced settings
|
||||||
|
|
||||||
|
# Prevents PR from being blocked with a reduction in coverage.
|
||||||
|
# Note, if we want to re-enable this, a `threshold` value can be used
|
||||||
|
# allow coverage to drop by x% while still posting a success status.
|
||||||
|
# `informational`: https://docs.codecov.com/docs/commit-status#informational
|
||||||
|
# `threshold`: https://docs.codecov.com/docs/commit-status#threshold
|
||||||
|
informational: true
|
||||||
|
patch:
|
||||||
|
default:
|
||||||
|
# advanced settings
|
||||||
|
|
||||||
|
# Prevents PR from being blocked with a reduction in coverage.
|
||||||
|
# Note, if we want to re-enable this, a `threshold` value can be used
|
||||||
|
# allow coverage to drop by x% while still posting a success status.
|
||||||
|
# `informational`: https://docs.codecov.com/docs/commit-status#informational
|
||||||
|
# `threshold`: https://docs.codecov.com/docs/commit-status#threshold
|
||||||
|
informational: true
|
|
@ -0,0 +1,55 @@
|
||||||
|
# Full reference https://github.com/foundry-rs/foundry/tree/master/config
|
||||||
|
|
||||||
|
[profile.default]
|
||||||
|
auto_detect_solc = false
|
||||||
|
block_timestamp = 1_680_220_800 # March 31, 2023 at 00:00 GMT
|
||||||
|
bytecode_hash = "none"
|
||||||
|
cbor_metadata = false
|
||||||
|
evm_version = "paris"
|
||||||
|
fuzz = { runs = 1_000 }
|
||||||
|
gas_reports = ["*"]
|
||||||
|
libs = ["lib"]
|
||||||
|
optimizer = true
|
||||||
|
optimizer_runs = 10_000
|
||||||
|
out = "out"
|
||||||
|
script = "script"
|
||||||
|
solc = "0.8.19"
|
||||||
|
src = "src"
|
||||||
|
test = "test"
|
||||||
|
|
||||||
|
[profile.ci]
|
||||||
|
fuzz = { runs = 10_000 }
|
||||||
|
verbosity = 4
|
||||||
|
|
||||||
|
[etherscan]
|
||||||
|
arbitrum = { key = "${API_KEY_ARBISCAN}" }
|
||||||
|
avalanche = { key = "${API_KEY_SNOWTRACE}" }
|
||||||
|
bnb_smart_chain = { key = "${API_KEY_BSCSCAN}" }
|
||||||
|
gnosis_chain = { key = "${API_KEY_GNOSISSCAN}" }
|
||||||
|
goerli = { key = "${API_KEY_ETHERSCAN}" }
|
||||||
|
mainnet = { key = "${API_KEY_ETHERSCAN}" }
|
||||||
|
optimism = { key = "${API_KEY_OPTIMISTIC_ETHERSCAN}" }
|
||||||
|
polygon = { key = "${API_KEY_POLYGONSCAN}" }
|
||||||
|
sepolia = { key = "${API_KEY_ETHERSCAN}" }
|
||||||
|
|
||||||
|
[fmt]
|
||||||
|
bracket_spacing = true
|
||||||
|
int_types = "long"
|
||||||
|
line_length = 120
|
||||||
|
multiline_func_header = "all"
|
||||||
|
number_underscore = "thousands"
|
||||||
|
quote_style = "double"
|
||||||
|
tab_width = 4
|
||||||
|
wrap_comments = true
|
||||||
|
|
||||||
|
[rpc_endpoints]
|
||||||
|
arbitrum = "https://arbitrum-mainnet.infura.io/v3/${API_KEY_INFURA}"
|
||||||
|
avalanche = "https://avalanche-mainnet.infura.io/v3/${API_KEY_INFURA}"
|
||||||
|
bnb_smart_chain = "https://bsc-dataseed.binance.org"
|
||||||
|
gnosis_chain = "https://rpc.gnosischain.com"
|
||||||
|
goerli = "https://goerli.infura.io/v3/${API_KEY_INFURA}"
|
||||||
|
localhost = "http://localhost:8545"
|
||||||
|
mainnet = "https://eth-mainnet.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
|
||||||
|
optimism = "https://optimism-mainnet.infura.io/v3/${API_KEY_INFURA}"
|
||||||
|
polygon = "https://polygon-mainnet.infura.io/v3/${API_KEY_INFURA}"
|
||||||
|
sepolia = "https://sepolia.infura.io/v3/${API_KEY_INFURA}"
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 74cfb77e308dd188d2f58864aaf44963ae6b88b1
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"name": "@waku-org/waku-rlnv2-contract",
|
||||||
|
"description": "rln-v2 Contracts for Waku",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"author": {
|
||||||
|
"name": "waku-org",
|
||||||
|
"url": "https://github.com/waku-org"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"prettier": "^3.0.0",
|
||||||
|
"solhint-community": "^3.6.0",
|
||||||
|
"commit-and-tag-version": "^12.2.0"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"blockchain",
|
||||||
|
"ethereum",
|
||||||
|
"forge",
|
||||||
|
"foundry",
|
||||||
|
"smart-contracts",
|
||||||
|
"solidity",
|
||||||
|
"template"
|
||||||
|
],
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"clean": "rm -rf cache out",
|
||||||
|
"lint": "pnpm lint:sol && pnpm prettier:check",
|
||||||
|
"verify": "certoraRun certora/certora.conf",
|
||||||
|
"lint:sol": "forge fmt --check && pnpm solhint {script,src,test,certora}/**/*.sol",
|
||||||
|
"prettier:check": "prettier --check **/*.{json,md,yml} --ignore-path=.prettierignore",
|
||||||
|
"prettier:write": "prettier --write **/*.{json,md,yml} --ignore-path=.prettierignore",
|
||||||
|
"gas-report": "forge test --gas-report 2>&1 | (tee /dev/tty | awk '/Test result:/ {found=1; buffer=\"\"; next} found && !/Ran/ {buffer=buffer $0 ORS} /Ran/ {found=0} END {printf \"%s\", buffer}' > .gas-report)",
|
||||||
|
"release": "commit-and-tag-version",
|
||||||
|
"adorno": "pnpm prettier:write && forge fmt && forge snapshot && pnpm gas-report"
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
||||||
|
forge-std/=lib/forge-std/src/
|
|
@ -0,0 +1,41 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity >=0.8.19 <=0.9.0;
|
||||||
|
|
||||||
|
import { Script } from "forge-std/Script.sol";
|
||||||
|
|
||||||
|
abstract contract BaseScript is Script {
|
||||||
|
/// @dev Included to enable compilation of the script without a $MNEMONIC environment variable.
|
||||||
|
string internal constant TEST_MNEMONIC = "test test test test test test test test test test test junk";
|
||||||
|
|
||||||
|
/// @dev Needed for the deterministic deployments.
|
||||||
|
bytes32 internal constant ZERO_SALT = bytes32(0);
|
||||||
|
|
||||||
|
/// @dev The address of the transaction broadcaster.
|
||||||
|
address internal broadcaster;
|
||||||
|
|
||||||
|
/// @dev Used to derive the broadcaster's address if $ETH_FROM is not defined.
|
||||||
|
string internal mnemonic;
|
||||||
|
|
||||||
|
/// @dev Initializes the transaction broadcaster like this:
|
||||||
|
///
|
||||||
|
/// - If $ETH_FROM is defined, use it.
|
||||||
|
/// - Otherwise, derive the broadcaster address from $MNEMONIC.
|
||||||
|
/// - If $MNEMONIC is not defined, default to a test mnemonic.
|
||||||
|
///
|
||||||
|
/// The use case for $ETH_FROM is to specify the broadcaster key and its address via the command line.
|
||||||
|
constructor() {
|
||||||
|
address from = vm.envOr({ name: "ETH_FROM", defaultValue: address(0) });
|
||||||
|
if (from != address(0)) {
|
||||||
|
broadcaster = from;
|
||||||
|
} else {
|
||||||
|
mnemonic = vm.envOr({ name: "MNEMONIC", defaultValue: TEST_MNEMONIC });
|
||||||
|
(broadcaster,) = deriveRememberKey({ mnemonic: mnemonic, index: 0 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier broadcast() {
|
||||||
|
vm.startBroadcast(broadcaster);
|
||||||
|
_;
|
||||||
|
vm.stopBroadcast();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
|
pragma solidity >=0.8.19 <=0.9.0;
|
||||||
|
|
||||||
|
import { Foo } from "../src/Foo.sol";
|
||||||
|
import { BaseScript } from "./Base.s.sol";
|
||||||
|
import { DeploymentConfig } from "./DeploymentConfig.s.sol";
|
||||||
|
|
||||||
|
contract Deploy is BaseScript {
|
||||||
|
function run() public returns (Foo foo, DeploymentConfig deploymentConfig) {
|
||||||
|
deploymentConfig = new DeploymentConfig(broadcaster);
|
||||||
|
foo = new Foo();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
//// SPDX-License-Identifier: UNLICENSED
|
||||||
|
|
||||||
|
pragma solidity >=0.8.19 <=0.9.0;
|
||||||
|
|
||||||
|
import { Script } from "forge-std/Script.sol";
|
||||||
|
|
||||||
|
contract DeploymentConfig is Script {
|
||||||
|
error DeploymentConfig_InvalidDeployerAddress();
|
||||||
|
error DeploymentConfig_NoConfigForChain(uint256);
|
||||||
|
|
||||||
|
struct NetworkConfig {
|
||||||
|
address deployer;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkConfig public activeNetworkConfig;
|
||||||
|
|
||||||
|
address private deployer;
|
||||||
|
|
||||||
|
constructor(address _broadcaster) {
|
||||||
|
if (_broadcaster == address(0)) revert DeploymentConfig_InvalidDeployerAddress();
|
||||||
|
deployer = _broadcaster;
|
||||||
|
if (block.chainid == 31_337) {
|
||||||
|
activeNetworkConfig = getOrCreateAnvilEthConfig();
|
||||||
|
} else {
|
||||||
|
revert DeploymentConfig_NoConfigForChain(block.chainid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOrCreateAnvilEthConfig() public view returns (NetworkConfig memory) {
|
||||||
|
return NetworkConfig({ deployer: deployer });
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is a hack to have it excluded by `forge coverage` until
|
||||||
|
// https://github.com/foundry-rs/foundry/issues/2988 is fixed.
|
||||||
|
// See: https://github.com/foundry-rs/foundry/issues/2988#issuecomment-1437784542
|
||||||
|
// for more info.
|
||||||
|
// solhint-disable-next-line
|
||||||
|
function test() public { }
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"detectors_to_exclude": "naming-convention,reentrancy-events,solc-version,timestamp",
|
||||||
|
"filter_paths": "(lib|test)",
|
||||||
|
"solc_remaps": [
|
||||||
|
"@openzeppelin/contracts=lib/openzeppelin-contracts/contracts/",
|
||||||
|
"forge-std/=lib/forge-std/src/"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
|
pragma solidity >=0.8.19;
|
||||||
|
|
||||||
|
contract Foo {
|
||||||
|
function id(uint256 value) external pure returns (uint256) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
|
pragma solidity >=0.8.19 <0.9.0;
|
||||||
|
|
||||||
|
import { Test, console } from "forge-std/Test.sol";
|
||||||
|
|
||||||
|
import { Deploy } from "../script/Deploy.s.sol";
|
||||||
|
import { DeploymentConfig } from "../script/DeploymentConfig.s.sol";
|
||||||
|
import { Foo } from "../src/Foo.sol";
|
||||||
|
|
||||||
|
contract FooTest is Test {
|
||||||
|
Foo internal foo;
|
||||||
|
DeploymentConfig internal deploymentConfig;
|
||||||
|
|
||||||
|
address internal deployer;
|
||||||
|
|
||||||
|
function setUp() public virtual {
|
||||||
|
Deploy deployment = new Deploy();
|
||||||
|
(foo, deploymentConfig) = deployment.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_Example() external {
|
||||||
|
console.log("Hello World");
|
||||||
|
uint256 x = 42;
|
||||||
|
assertEq(foo.id(x), x, "value mismatch");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue