feat: initial commit

This commit is contained in:
rymnc 2024-05-21 06:16:07 +05:30 committed by github-actions[bot]
commit 284cc38916
33 changed files with 2739 additions and 0 deletions

19
.editorconfig Normal file
View File

@ -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

11
.env.example Normal file
View File

@ -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"

18
.gas-report Normal file
View File

@ -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 |

1
.gas-snapshot Normal file
View File

@ -0,0 +1 @@
FooTest:test_Example() (gas: 8662)

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
lib/** linguist-vendored
* text=auto eol=lf

11
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -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`?

View File

@ -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 }}

View File

@ -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 }}

171
.github/workflows/ci.yml vendored Normal file
View File

@ -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

19
.gitignore vendored Normal file
View File

@ -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

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "lib/forge-std"]
branch = "v1"
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std

18
.prettierignore Normal file
View File

@ -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

7
.prettierrc.yml Normal file
View File

@ -0,0 +1,7 @@
bracketSpacing: true
printWidth: 120
proseWrap: "always"
singleQuote: false
tabWidth: 2
trailingComma: "all"
useTabs: false

13
.solhint.json Normal file
View File

@ -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"
}
}

10
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,10 @@
{
"[solidity]": {
"editor.defaultFormatter": "NomicFoundation.hardhat-solidity"
},
"[toml]": {
"editor.defaultFormatter": "tamasfe.even-better-toml"
},
"npm.exclude": "**/lib/**",
"solidity.formatter": "forge"
}

0
CHANGELOG.md Normal file
View File

16
LICENSE.md Normal file
View File

@ -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.

15
PROPERTIES.md Normal file
View File

@ -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** |
| ------------ | -------- | -------- | ---------- |
| | | | |
| | | | |
| | | | |

201
README.md Normal file
View File

@ -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.

8
certora/certora.conf Normal file
View File

@ -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",
}

9
certora/specs/Foo.spec Normal file
View File

@ -0,0 +1,9 @@
methods {
function id(uint256) external returns (uint256) envfree;
}
rule checkIdOutputIsAlwaysEqualToInput {
uint256 input;
assert id(input) == input;
}

28
codecov.yml Normal file
View File

@ -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

55
foundry.toml Normal file
View File

@ -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}"

1
lib/forge-std vendored Submodule

@ -0,0 +1 @@
Subproject commit 74cfb77e308dd188d2f58864aaf44963ae6b88b1

35
package.json Normal file
View File

@ -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"
}
}

1894
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

1
remappings.txt Normal file
View File

@ -0,0 +1 @@
forge-std/=lib/forge-std/src/

41
script/Base.s.sol Normal file
View File

@ -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();
}
}

13
script/Deploy.s.sol Normal file
View File

@ -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();
}
}

View File

@ -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 { }
}

8
slither.config.json Normal file
View File

@ -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/"
]
}

8
src/Foo.sol Normal file
View File

@ -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;
}
}

26
test/Foo.t.sol Normal file
View File

@ -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");
}
}