generated from PaulRBerg/foundry-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8730fbf
Showing
27 changed files
with
992 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
name: "CI" | ||
|
||
env: | ||
API_KEY_ALCHEMY: ${{ secrets.API_KEY_ALCHEMY }} | ||
FOUNDRY_PROFILE: "ci" | ||
|
||
on: | ||
workflow_dispatch: | ||
pull_request: | ||
push: | ||
branches: | ||
- "main" | ||
|
||
jobs: | ||
lint: | ||
runs-on: "ubuntu-latest" | ||
steps: | ||
- name: "Check out the repo" | ||
uses: "actions/checkout@v4" | ||
|
||
- name: "Install Foundry" | ||
uses: "foundry-rs/foundry-toolchain@v1" | ||
|
||
- name: "Install Bun" | ||
uses: "oven-sh/setup-bun@v1" | ||
|
||
- name: "Install the Node.js dependencies" | ||
run: "bun install" | ||
|
||
- name: "Lint the code" | ||
run: "bun run 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@v4" | ||
|
||
- name: "Install Foundry" | ||
uses: "foundry-rs/foundry-toolchain@v1" | ||
|
||
- name: "Install Bun" | ||
uses: "oven-sh/setup-bun@v1" | ||
|
||
- name: "Install the Node.js dependencies" | ||
run: "bun install" | ||
|
||
- 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@v4" | ||
|
||
- name: "Install Foundry" | ||
uses: "foundry-rs/foundry-toolchain@v1" | ||
|
||
- name: "Install Bun" | ||
uses: "oven-sh/setup-bun@v1" | ||
|
||
- name: "Install the Node.js dependencies" | ||
run: "bun install" | ||
|
||
- 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# directories | ||
cache | ||
coverage | ||
node_modules | ||
out | ||
|
||
# files | ||
*.env | ||
*.log | ||
.DS_Store | ||
.pnp.* | ||
lcov.info | ||
package-lock.json | ||
pnpm-lock.yaml | ||
yarn.lock | ||
|
||
# broadcasts | ||
!broadcast | ||
broadcast/* | ||
broadcast/*/31337/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[submodule "lib/solady"] | ||
path = lib/solady | ||
url = https://github.com/Vectorized/solady | ||
[submodule "lib/openzeppelin-contracts"] | ||
path = lib/openzeppelin-contracts | ||
url = https://github.com/OpenZeppelin/openzeppelin-contracts | ||
[submodule "lib/forge-std"] | ||
path = lib/forge-std | ||
url = https://github.com/foundry-rs/forge-std |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
image: "gitpod/workspace-bun" | ||
|
||
tasks: | ||
- name: "Install dependencies" | ||
before: | | ||
curl -L https://foundry.paradigm.xyz | bash | ||
source ~/.bashrc | ||
foundryup | ||
init: "bun install" | ||
|
||
vscode: | ||
extensions: | ||
- "esbenp.prettier-vscode" | ||
- "NomicFoundation.hardhat-solidity" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# directories | ||
broadcast | ||
cache | ||
coverage | ||
node_modules | ||
out | ||
|
||
# files | ||
*.env | ||
*.log | ||
.DS_Store | ||
.pnp.* | ||
bun.lockb | ||
lcov.info | ||
package-lock.json | ||
pnpm-lock.yaml | ||
yarn.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
bracketSpacing: true | ||
printWidth: 120 | ||
proseWrap: "always" | ||
singleQuote: false | ||
tabWidth: 2 | ||
trailingComma: "all" | ||
useTabs: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"extends": "solhint:recommended", | ||
"rules": { | ||
"code-complexity": ["error", 8], | ||
"compiler-version": ["error", ">=0.8.23"], | ||
"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", | ||
"one-contract-per-file": "off" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"[solidity]": { | ||
"editor.defaultFormatter": "NomicFoundation.hardhat-solidity" | ||
}, | ||
"[toml]": { | ||
"editor.defaultFormatter": "tamasfe.even-better-toml" | ||
}, | ||
"solidity.formatter": "forge" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Single Keccak Create3 | ||
|
||
This is a different implementation of `CREATE3` that only requires a single keccak256 hash to calculate deployed address. | ||
|
||
## How it works | ||
|
||
To achieve this, before deploying a proxy, we `SSTORE2.write` the final deployed bytecode from the deployer and store a pointer to the storage contract in the deployer. The proxies deployed from the deployer will do a `SSTORE2.read` on `CALLER.pointer` to get the final deployed bytecode and return that in its constructor. | ||
|
||
We use a different SSTORE2 implementation here, using CREATE2 instead of CREATE under the hood. This bumps up costs slightly for the first deployment, but on the 2nd+ deployment of the same contract we get significant savings. | ||
|
||
Because of how this works, contract constructors are never run. It's highly recommended for constructor logic to be in an `initializer` function instead. See the section on safety below. | ||
|
||
## Gas | ||
|
||
Gas estimates with Solady's CREATE3 are in [GasComparison.t.sol](./test/GasComparison.t.sol). Disclaimer: Gas values are measured using foundry and will be inaccurate so this should only be used as a ballpark estimate. | ||
|
||
Cost of deploying an ERC20: | ||
Single Keccak Create3, cached contract + no storage: 636k | ||
Solady CREATE3: 732k | ||
Single Keccak Create3, cached contract + storage: 810k | ||
Single Keccak Create3, new contract + no storage: 1.26m | ||
Single Keccak Create3, new contract + storage: 1.44m | ||
|
||
## Safety | ||
|
||
Deployments using this proxy bypass all constructor logic and is significantly less safe than regular deployments. The danger here can largely be mitigated via adding tests to foundry deploy scripts - see example in [SafeDeployPatternDemo](./script/SafeDeployPatternDemo.s.sol). | ||
|
||
## Acknowledgements + Future Extensions | ||
|
||
A significant amount of assembly logic was lifted from [Solady](https://github.com/Vectorized/solady). | ||
|
||
1. Utilizing SSTORE or TSTORE instead of another SSTORE2 for `storageArgs` | ||
2. We currently cache deployed bytecode, this means deploying a second contract a different immutable variable wouldn't count as 2nd+ deployment. Can consider doing it like how solidity constructors set up immutable vars and have the proxy take in arrays of memory arguments and memory locations of immutable args |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Full reference https://github.com/foundry-rs/foundry/tree/master/crates/config | ||
|
||
[profile.default] | ||
auto_detect_solc = false | ||
block_timestamp = 1_680_220_800 # March 31, 2023 at 00:00 GMT | ||
bytecode_hash = "none" | ||
evm_version = "paris" # See https://www.evmdiff.com/features?name=PUSH0&kind=opcode | ||
fuzz = { runs = 1_000 } | ||
gas_reports = ["*"] | ||
optimizer = true | ||
optimizer_runs = 10_000 | ||
out = "out" | ||
script = "script" | ||
solc = "0.8.23" | ||
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}" |
Submodule openzeppelin-contracts
added at
01ef44
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"name": "@howydev/skc3", | ||
"description": "", | ||
"version": "1.0.0", | ||
"author": { | ||
"name": "howydev", | ||
"url": "https://github.com/howydev" | ||
}, | ||
"dependencies": { | ||
"@openzeppelin/contracts": "^5.0.1" | ||
}, | ||
"devDependencies": { | ||
"@prb/test": "^0.6.4", | ||
"forge-std": "github:foundry-rs/forge-std#v1.7.5", | ||
"prettier": "^3.0.0", | ||
"solhint": "^3.6.2" | ||
}, | ||
"keywords": [ | ||
"blockchain", | ||
"ethereum", | ||
"forge", | ||
"foundry", | ||
"smart-contracts", | ||
"solidity", | ||
"template" | ||
], | ||
"private": true, | ||
"scripts": { | ||
"clean": "rm -rf cache out", | ||
"build": "forge build", | ||
"lint": "bun run lint:sol && bun run prettier:check", | ||
"lint:sol": "forge fmt --check && bun solhint {script,src,test}/**/*.sol", | ||
"prettier:check": "prettier --check **/*.{json,md,yml} --ignore-path=.prettierignore", | ||
"prettier:write": "prettier --write **/*.{json,md,yml} --ignore-path=.prettierignore", | ||
"test": "forge test", | ||
"test:coverage": "forge coverage", | ||
"test:coverage:report": "forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir coverage" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
@solady/=lib/solady/ | ||
@openzeppelin-contracts/=lib/openzeppelin-contracts/ | ||
@forge-std/=lib/forge-std/src |
Oops, something went wrong.