This commit is contained in:
Ricardo Guilherme Schmidt 2024-05-27 02:04:24 -03:00
parent 46c94c40c5
commit eb130a4d77
33 changed files with 2586 additions and 125 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)

4
.gitattributes vendored
View File

@ -1 +1,3 @@
*.sol linguist-language=Solidity
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`?

36
.github/scripts/rename.sh vendored Executable file
View File

@ -0,0 +1,36 @@
#!/usr/bin/env bash
# https://gist.github.com/vncsna/64825d5609c146e80de8b1fd623011ca
set -euo pipefail
# Define the input vars
GITHUB_REPOSITORY=${1?Error: Please pass username/repo, e.g. prb/foundry-template}
GITHUB_REPOSITORY_OWNER=${2?Error: Please pass username, e.g. prb}
GITHUB_REPOSITORY_DESCRIPTION=${3:-""} # If null then replace with empty string
echo "GITHUB_REPOSITORY: $GITHUB_REPOSITORY"
echo "GITHUB_REPOSITORY_OWNER: $GITHUB_REPOSITORY_OWNER"
echo "GITHUB_REPOSITORY_DESCRIPTION: $GITHUB_REPOSITORY_DESCRIPTION"
# jq is like sed for JSON data
JQ_OUTPUT=`jq \
--arg NAME "@$GITHUB_REPOSITORY" \
--arg AUTHOR_NAME "$GITHUB_REPOSITORY_OWNER" \
--arg URL "https://github.com/$GITHUB_REPOSITORY_OWNER" \
--arg DESCRIPTION "$GITHUB_REPOSITORY_DESCRIPTION" \
'.name = $NAME | .description = $DESCRIPTION | .author |= ( .name = $AUTHOR_NAME | .url = $URL )' \
package.json
`
# Overwrite package.json
echo "$JQ_OUTPUT" > package.json
# Make sed command compatible in both Mac and Linux environments
# Reference: https://stackoverflow.com/a/38595160/8696958
sedi () {
sed --version >/dev/null 2>&1 && sed -i -- "$@" || sed -i "" "$@"
}
# Rename instances of "vacp2p/foundry-template" to the new repo name in README.md for badges only
sedi "/gha/ s|vacp2p/foundry-template|"${GITHUB_REPOSITORY}"|;" "README.md"
sedi "/gha-badge/ s|vacp2p/foundry-template|"${GITHUB_REPOSITORY}"|;" "README.md"

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

52
.github/workflows/create.yml vendored Normal file
View File

@ -0,0 +1,52 @@
name: "Create"
# The workflow will run only when the "Use this template" button is used
on:
create:
jobs:
create:
# We only run this action when the repository isn't the template repository. References:
# - https://docs.github.com/en/actions/learn-github-actions/contexts
# - https://docs.github.com/en/actions/learn-github-actions/expressions
if: ${{ !github.event.repository.is_template }}
permissions: "write-all"
runs-on: "ubuntu-latest"
steps:
- name: "Check out the repo"
uses: "actions/checkout@v3"
- name: "Update package.json"
env:
GITHUB_REPOSITORY_DESCRIPTION: ${{ github.event.repository.description }}
run:
./.github/scripts/rename.sh "$GITHUB_REPOSITORY" "$GITHUB_REPOSITORY_OWNER" "$GITHUB_REPOSITORY_DESCRIPTION"
- name: "Add rename summary"
run: |
echo "## Commit result" >> $GITHUB_STEP_SUMMARY
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
- name: "Remove files not needed in the user's copy of the template"
run: |
rm -f "./.github/FUNDING.yml"
rm -f "./.github/scripts/rename.sh"
rm -f "./.github/workflows/create.yml"
- name: "Add remove summary"
run: |
echo "## Remove result" >> $GITHUB_STEP_SUMMARY
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
- name: "Update commit"
uses: "stefanzweifel/git-auto-commit-action@v4"
with:
commit_message: "feat: initial commit"
commit_options: "--amend"
push_options: "--force"
skip_fetch: true
- name: "Add commit summary"
run: |
echo "## Commit result" >> $GITHUB_STEP_SUMMARY
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY

59
.gitignore vendored
View File

@ -1,46 +1,19 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# directories
cache
node_modules
out
# embark
.embark/
chains.json
config/production/password
config/livenet/password
embarkArtifacts/
embark_demo/
# files
*.env
*.log
.DS_Store
.pnp.*
lcov.info
yarn.lock
# egg-related
viper.egg-info/
build/
dist/
.eggs/
# broadcasts
!broadcast
broadcast/*
broadcast/*/31337/
# pyenv
.python-version
# dotenv
.env
# virtualenv
.venv/
venv/
ENV/
# Coverage tests
.coverage
.cache/
coverage/
coverageEnv/
coverage.json
# node
node_modules/
npm-debug.log
# other
.vs/
bin/
.idea/
*.iml
.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** |
| ------------ | -------- | -------- | ---------- |
| | | | |
| | | | |
| | | | |

View File

@ -7,9 +7,9 @@ DApp to register usernames for Status Network, using ENS subnodes as usernames a
- Funds are deposited for 1 year. Your SNT will be locked, but not spent.
- After 1 year, the user can release the name for being registered again, and receive their deposit back.
- Usernames are created as a subdomain of `stateofus.eth` [ENS domain](https://ens.domains/).
- Usernames not allowed are less then 4 characters, or contained in this list (link to list), or starts with `0x` and more then 12 characters.
- Usernames not allowed are less then 4 characters, or contained in this list (link to list), or starts with `0x` and more then 12 characters.
- Revealing a registered not allowed username will result in loss of deposit and removal of username.
- Users are free to own the subdomains, but they are property of Status Network, and might be subject of new terms.
- Users are free to own the subdomains, but they are property of Status Network, and might be subject of new terms.
- If terms of the contract change—e.g. Status Network makes contract upgrades—the user has the right to get their deposit back and release the username, or do nothing and keep using username as long new contract allows it.
- User's handle (name) is always secret to network until user reveals it to someone.
- User's address(es) when associated with a username will be publicly visible.
@ -17,7 +17,7 @@ DApp to register usernames for Status Network, using ENS subnodes as usernames a
Usernames eliminates the need to copy/scan - and worse, type - long hexadecimal addresses / public keys, by providing an ENS subdomain registry and recognition of ENS names in Status for interacting with other people in Status.
Requires https://github.com/creationix/nvm
Usage:
Usage:
```
nvm install v8.9.4
nvm use v8.9.4

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

View File

@ -1,84 +1,35 @@
{
"name": "status-contracts",
"name": "status-im/ens-usernames",
"version": "0.0.1",
"description": "",
"scripts": {
"solidity-coverage": "./node_modules/.bin/solidity-coverage",
"test": "embark test",
"lint": "eslint"
},
"repository": {
"type": "git",
"url": "git+https://github.com/status-im/contracts.git"
},
"author": "Status Research & Development GMBH",
"license": "ISC",
"bugs": {
"url": "https://github.com/status-im/contracts/issues"
},
"homepage": "https://github.com/status-im/contracts#readme",
"dependencies": {
"@material-ui/core": "^1.2.1",
"@material-ui/icons": "^1.1.0",
"bignumber.js": "^5.0.0",
"classnames": "^2.2.6",
"elliptic": "^6.4.1",
"eth-ens-namehash": "^2.0.8",
"formik": "^0.11.11",
"i18n-js": "^3.1.0",
"idna-normalize": "^1.0.0",
"install": "^0.11.0",
"npm": "^6.1.0",
"prop-types": "^15.6.1",
"react": "^16.4.2",
"react-blockies": "^1.3.0",
"react-bootstrap": "^0.32.1",
"react-copy-to-clipboard": "^5.0.1",
"react-dom": "^16.4.2",
"react-redux": "^5.0.7",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"react-toggle": "^4.0.2",
"redux": "^4.0.0",
"redux-action-creator": "^2.3.0",
"redux-thunk": "^2.3.0",
"reselect": "^3.0.1",
"styled-components": "^3.3.2",
"typeface-roboto": "0.0.54",
"web3-utils": "^1.0.0-beta.34"
"author": {
"name": "Status Research & Development GMBH",
"url": "https://github.com/status-im/ens-usernames"
},
"devDependencies": {
"embark": "^6.0.0",
"embark-basic-pipeline": "^6.0.0",
"embark-geth": "^6.0.0",
"embark-graph": "^6.0.0",
"embark-ipfs": "^6.0.0",
"embark-parity": "^6.0.0",
"embark-profiler": "^6.0.0",
"embark-swarm": "^6.0.0",
"embark-whisper-geth": "^6.0.0",
"embarkjs": "^6.0.0",
"embarkjs-ens": "^6.0.0",
"embarkjs-ipfs": "^6.0.0",
"embarkjs-swarm": "^6.0.0",
"embarkjs-web3": "^6.0.0",
"embarkjs-whisper": "^6.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.0.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"eslint": "^4.19.1",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-import": "^2.12.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.8.2",
"ethereumjs-util": "^5.2.0"
}
"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"
],
"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"
},
"license": "ISC"
}

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