├── .dockerignore ├── testdata ├── fixtures │ ├── Dir │ │ ├── depth1 │ │ └── nested │ │ │ ├── depth2 │ │ │ └── nested2 │ │ │ └── depth3 │ ├── File │ │ ├── symlink │ │ ├── ignored │ │ │ └── .gitignore │ │ └── read.txt │ ├── Derive │ │ ├── mnemonic_chinese_simplified.txt │ │ ├── mnemonic_chinese_traditional.txt │ │ ├── mnemonic_japanese.txt │ │ ├── mnemonic_english.txt │ │ ├── mnemonic_spanish.txt │ │ ├── mnemonic_french.txt │ │ ├── mnemonic_portuguese.txt │ │ ├── mnemonic_czech.txt │ │ ├── mnemonic_italian.txt │ │ └── mnemonic_korean.txt │ ├── Rpc │ │ ├── balance_params.json │ │ └── README.md │ ├── Toml │ │ ├── write_test.toml │ │ ├── Issue4402.toml │ │ ├── whole_toml.toml │ │ ├── write_complex_test.toml │ │ └── nested_toml_struct.toml │ ├── Json │ │ ├── write_test.json │ │ ├── Issue4402.json │ │ ├── Issue4630.json │ │ ├── whole_json.json │ │ ├── write_complex_test.json │ │ └── test_allocs.json │ ├── GetCode │ │ ├── WorkingContract.sol │ │ ├── Override.sol │ │ ├── UnlinkedContract.sol │ │ └── HuffWorkingContract.json │ └── broadcast.sensitive.log.json ├── forge-std-rev ├── .gitignore ├── src │ ├── ICounter.vyi │ └── Counter.vy ├── etherscan │ ├── 0x044b75f554b886A065b9567891e45c79542d7357 │ │ └── creation_data.json │ ├── 0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193 │ │ └── creation_data.json │ ├── 0x3a23F943181408EAC424116Af7b7790c94Cb97a5 │ │ └── creation_data.json │ ├── 0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05 │ │ └── creation_data.json │ ├── 0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545 │ │ └── creation_data.json │ ├── 0x9AB6b21cDF116f611110b048987E58894786C244 │ │ └── creation_data.json │ ├── 0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec │ │ └── creation_data.json │ └── 0x9d27527Ada2CF29fBDAB2973cfa243845a08Bd3F │ │ └── creation_data.json ├── default │ ├── cheats │ │ ├── RandomAddress.t.sol │ │ ├── Label.t.sol │ │ ├── BlobBaseFee.t.sol │ │ ├── Assume.t.sol │ │ ├── ChainId.t.sol │ │ ├── Fee.t.sol │ │ ├── GetNonce.t.sol │ │ ├── GetLabel.t.sol │ │ ├── RandomBytes.t.sol │ │ ├── SetBlockhash.t.sol │ │ ├── Travel.t.sol │ │ ├── GetRawBlockHeader.t.sol │ │ ├── Bank.t.sol │ │ ├── EnsNamehash.t.sol │ │ ├── Sort.t.sol │ │ ├── Remember.t.sol │ │ ├── SignP256.t.sol │ │ ├── Addr.t.sol │ │ ├── Deal.t.sol │ │ ├── Derive.t.sol │ │ ├── Etch.t.sol │ │ ├── Blobhashes.t.sol │ │ ├── Warp.t.sol │ │ ├── Base64.t.sol │ │ ├── Nonce.t.sol │ │ ├── RandomUint.t.sol │ │ ├── GetBlockTimestamp.t.sol │ │ ├── getBlockNumber.t.sol │ │ ├── SetNonceUnsafe.t.sol │ │ └── GetArtifactPath.t.sol │ ├── core │ │ ├── BadSigAfterInvariant.t.sol │ │ ├── Reverting.t.sol │ │ ├── Abstract.t.sol │ │ └── SetupConsistency.t.sol │ ├── linking │ │ ├── cycle │ │ │ └── Cycle.t.sol │ │ ├── samefile_union │ │ │ ├── Libs.sol │ │ │ └── SameFileUnion.t.sol │ │ └── simple │ │ │ └── Simple.t.sol │ ├── repros │ │ ├── Issue3661.t.sol │ │ ├── Issue4640.t.sol │ │ ├── Issue6554.t.sol │ │ ├── Issue3190.t.sol │ │ ├── Issue6293.t.sol │ │ ├── Issue3674.t.sol │ │ ├── Issue5929.t.sol │ │ ├── Issue6070.t.sol │ │ ├── Issue3753.t.sol │ │ ├── Issue6538.t.sol │ │ ├── Issue6759.t.sol │ │ ├── Issue3653.t.sol │ │ ├── Issue2623.t.sol │ │ ├── Issue3192.t.sol │ │ ├── Issue11616.t.sol │ │ ├── Issue5808.t.sol │ │ ├── Issue2723.t.sol │ │ ├── Issue6180.t.sol │ │ ├── Issue8566.t.sol │ │ ├── Issue2984.t.sol │ │ ├── Issue6616.t.sol │ │ ├── Issue6966.t.sol │ │ ├── Issue2629.t.sol │ │ ├── Issue2898.t.sol │ │ ├── Issue4630.t.sol │ │ ├── Issue3792.t.sol │ │ ├── Issue2851.t.sol │ │ ├── Issue5935.t.sol │ │ ├── Issue10527.t.sol │ │ ├── Issue8277.t.sol │ │ ├── Issue3119.t.sol │ │ ├── Issue3223.t.sol │ │ ├── Issue3221.t.sol │ │ ├── Issue12075.t.sol │ │ └── Issue2956.t.sol │ ├── vyper │ │ └── CounterTest.vy │ ├── fork │ │ ├── ForkSame_1.t.sol │ │ └── ForkSame_2.t.sol │ ├── inline │ │ └── FuzzInlineConf.t.sol │ └── spec │ │ └── ShanghaiCompat.t.sol ├── multi-version │ ├── Importer.sol │ ├── Counter.sol │ └── cheats │ │ └── GetCode.t.sol ├── utils │ └── Test.sol ├── README.md └── paris │ └── spec │ └── ShanghaiCompat.t.sol ├── crates ├── lint │ ├── testdata │ │ ├── .gitignore │ │ ├── auxiliary │ │ │ ├── ImportsAnotherFile.sol │ │ │ ├── ImportsAnotherFile2.sol │ │ │ ├── ImportsSomeFile2.sol │ │ │ ├── ImportsConstants.sol │ │ │ ├── ImportsTypes.sol │ │ │ ├── ImportsSomeFile.sol │ │ │ ├── ImportsUtils.sol │ │ │ └── ImportsUtils2.sol │ │ ├── NamedStructFields.stderr │ │ ├── NamedStructFields.sol │ │ └── StructPascalCase.sol │ ├── src │ │ ├── sol │ │ │ ├── gas │ │ │ │ └── mod.rs │ │ │ ├── codesize │ │ │ │ └── mod.rs │ │ │ ├── med │ │ │ │ └── mod.rs │ │ │ └── high │ │ │ │ └── mod.rs │ │ └── lib.rs │ └── Cargo.toml ├── anvil │ ├── src │ │ ├── eth │ │ │ ├── otterscan │ │ │ │ └── mod.rs │ │ │ ├── mod.rs │ │ │ ├── macros.rs │ │ │ ├── backend │ │ │ │ ├── mod.rs │ │ │ │ └── notifications.rs │ │ │ ├── util.rs │ │ │ └── beacon │ │ │ │ ├── mod.rs │ │ │ │ └── data.rs │ │ ├── server │ │ │ └── error.rs │ │ └── opts.rs │ ├── core │ │ └── src │ │ │ ├── lib.rs │ │ │ └── types.rs │ ├── rpc │ │ ├── src │ │ │ └── lib.rs │ │ └── Cargo.toml │ ├── bin │ │ └── main.rs │ ├── tests │ │ └── it │ │ │ └── main.rs │ ├── server │ │ └── src │ │ │ └── error.rs │ └── test-data │ │ └── emit_logs.sol ├── evm │ ├── networks │ │ ├── src │ │ │ └── celo │ │ │ │ └── mod.rs │ │ └── Cargo.toml │ ├── abi │ │ ├── src │ │ │ ├── lib.rs │ │ │ └── console │ │ │ │ ├── hh.rs │ │ │ │ └── mod.rs │ │ └── Cargo.toml │ ├── fuzz │ │ └── src │ │ │ ├── error.rs │ │ │ └── strategies │ │ │ └── mod.rs │ ├── coverage │ │ └── Cargo.toml │ ├── evm │ │ └── src │ │ │ ├── lib.rs │ │ │ └── inspectors │ │ │ └── mod.rs │ └── core │ │ ├── src │ │ └── fork │ │ │ └── mod.rs │ │ └── test-data │ │ └── storage.json ├── chisel │ ├── tests │ │ └── it │ │ │ └── main.rs │ ├── assets │ │ └── preview.gif │ ├── bin │ │ └── main.rs │ └── src │ │ └── lib.rs ├── cast │ ├── tests │ │ └── fixtures │ │ │ ├── keystore │ │ │ ├── password-ec554 │ │ │ ├── password │ │ │ ├── UTC--2022-10-30T06-51-20.130356000Z--560d246fcddc9ea98a8b032c9a2f474efb493c28 │ │ │ └── UTC--2022-12-20T10-30-43.591916000Z--ec554aeafe75601aaab43bd4621a22284db566c2 │ │ │ ├── sign_typed_data.json │ │ │ └── cast_logs.stdout │ ├── bin │ │ └── main.rs │ └── src │ │ └── cmd │ │ └── mod.rs ├── common │ ├── README.md │ ├── src │ │ ├── io │ │ │ ├── style.rs │ │ │ └── mod.rs │ │ └── iter.rs │ └── fmt │ │ ├── src │ │ └── lib.rs │ │ └── Cargo.toml ├── wallets │ └── src │ │ ├── wallet_browser │ │ ├── app │ │ │ ├── assets │ │ │ │ ├── logo.png │ │ │ │ ├── banner.png │ │ │ │ └── index.html │ │ │ └── mod.rs │ │ └── error.rs │ │ └── lib.rs ├── config │ └── src │ │ ├── providers │ │ └── mod.rs │ │ ├── vyper.rs │ │ └── bind_json.rs ├── fmt │ ├── testdata │ │ ├── PragmaDirective │ │ │ ├── original.sol │ │ │ └── fmt.sol │ │ ├── HexUnderscore │ │ │ ├── original.sol │ │ │ ├── fmt.sol │ │ │ ├── remove.fmt.sol │ │ │ ├── bytes.fmt.sol │ │ │ └── preserve.fmt.sol │ │ ├── StructDefinition │ │ │ ├── original.sol │ │ │ ├── fmt.sol │ │ │ └── bracket-spacing.fmt.sol │ │ ├── EnumDefinition │ │ │ ├── original.sol │ │ │ ├── fmt.sol │ │ │ └── bracket-spacing.fmt.sol │ │ ├── TrailingComma │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── StatementBlock │ │ │ ├── original.sol │ │ │ ├── fmt.sol │ │ │ └── bracket-spacing.fmt.sol │ │ ├── TypeDefinition │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── Annotation │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ReprosFunctionDefs │ │ │ ├── original.sol │ │ │ └── all.120.fmt.sol │ │ ├── ModifierDefinition │ │ │ ├── original.sol │ │ │ ├── fmt.sol │ │ │ └── override-spacing.fmt.sol │ │ ├── YulStrings │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ ├── single-quote.fmt.sol │ │ │ └── preserve-quote.fmt.sol │ │ ├── ErrorDefinition │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── FunctionDefinitionWithFunctionReturns │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ConstructorModifierStyle │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── EnumVariants │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── DoWhileStatement │ │ │ ├── original.sol │ │ │ └── fmt.sol │ │ ├── ConstructorDefinition │ │ │ ├── original.sol │ │ │ └── fmt.sol │ │ ├── ThisExpression │ │ │ ├── original.sol │ │ │ └── fmt.sol │ │ ├── UsingDirective │ │ │ └── original.sol │ │ ├── BlockComments │ │ │ ├── tab.fmt.sol │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── IntTypes │ │ │ ├── original.sol │ │ │ ├── fmt.sol │ │ │ ├── short.fmt.sol │ │ │ └── preserve.fmt.sol │ │ ├── BlockCommentsFunction │ │ │ ├── tab.fmt.sol │ │ │ ├── original.sol │ │ │ └── fmt.sol │ │ ├── ImportDirective │ │ │ ├── original.sol │ │ │ ├── fmt.sol │ │ │ ├── single_line_import.fmt.sol │ │ │ ├── preserve-quote.fmt.sol │ │ │ ├── single-quote.fmt.sol │ │ │ └── bracket-spacing.fmt.sol │ │ ├── UnitExpression │ │ │ ├── original.sol │ │ │ └── fmt.sol │ │ ├── MappingType │ │ │ └── original.sol │ │ ├── NonKeywords │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── SortedImports │ │ │ └── original.sol │ │ └── ForStatement │ │ │ └── original.sol │ └── Cargo.toml ├── doc │ ├── static │ │ ├── book.css │ │ └── book.toml │ ├── src │ │ ├── writer │ │ │ └── mod.rs │ │ ├── parser │ │ │ └── error.rs │ │ └── lib.rs │ └── Cargo.toml ├── sol-macro-gen │ ├── src │ │ └── lib.rs │ └── Cargo.toml ├── forge │ ├── assets │ │ ├── .gitignoreTemplate │ │ ├── vyper │ │ │ ├── CounterTemplate.vy │ │ │ ├── ICounterTemplate.sol │ │ │ ├── CounterTemplate.s.sol │ │ │ └── CounterTemplate.t.sol │ │ ├── solidity │ │ │ ├── CounterTemplate.sol │ │ │ ├── CounterTemplate.s.sol │ │ │ ├── CounterTemplate.t.sol │ │ │ └── workflowTemplate.yml │ │ └── generated │ │ │ └── TestTemplate.t.sol │ ├── tests │ │ ├── cli │ │ │ ├── constants.rs │ │ │ ├── version.rs │ │ │ ├── main.rs │ │ │ ├── bind.rs │ │ │ └── cache.rs │ │ ├── ui.rs │ │ └── fixtures │ │ │ ├── SimpleContractTestNonVerbose.json │ │ │ └── backtraces │ │ │ ├── SimpleRevert.sol │ │ │ └── NestedCalls.sol │ ├── bin │ │ └── main.rs │ └── src │ │ ├── cmd │ │ └── mod.rs │ │ └── lib.rs ├── cli │ ├── src │ │ ├── utils │ │ │ └── default_directives.txt │ │ ├── opts │ │ │ └── mod.rs │ │ └── lib.rs │ └── README.md ├── script-sequence │ ├── src │ │ └── lib.rs │ └── Cargo.toml ├── debugger │ ├── src │ │ └── lib.rs │ └── Cargo.toml ├── linking │ └── Cargo.toml ├── macros │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── verify │ └── src │ │ └── lib.rs ├── cheatcodes │ └── spec │ │ └── Cargo.toml └── test-utils │ └── src │ └── fd_lock.rs ├── .github ├── assets │ ├── demo.gif │ ├── banner.png │ ├── build_benchmark_solady_dark.png │ ├── build_benchmark_solady_light.png │ ├── build_benchmark_openzeppelin_dark.png │ └── build_benchmark_openzeppelin_light.png ├── CODEOWNERS ├── compilation-benchmark.png ├── dependabot.yml ├── ISSUE_TEMPLATE │ └── config.yml ├── scripts │ ├── format.sh │ ├── create-tag.js │ └── move-tag.js ├── RELEASE_FAILURE_ISSUE_TEMPLATE.md ├── INTEGRATION_FAILURE.md └── workflows │ ├── test-isolate.yml │ └── dependencies.yml ├── SECURITY.md ├── npm ├── bunfig.toml ├── .env.example ├── package.json └── .gitignore ├── FUNDING.json ├── .gitignore ├── rustfmt.toml ├── docs └── dev │ ├── networks.md │ ├── architecture.md │ └── debugging.md ├── typos.toml ├── .gitattributes ├── .config └── nextest.toml ├── .cargo └── config.toml ├── .git-blame-ignore-revs ├── clippy.toml └── benches └── Cargo.toml /.dockerignore: -------------------------------------------------------------------------------- 1 | target 2 | .github 3 | -------------------------------------------------------------------------------- /testdata/fixtures/Dir/depth1: -------------------------------------------------------------------------------- 1 | Wow! 😀 -------------------------------------------------------------------------------- /testdata/fixtures/Dir/nested/depth2: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testdata/fixtures/File/symlink: -------------------------------------------------------------------------------- 1 | read.txt -------------------------------------------------------------------------------- /testdata/fixtures/Dir/nested/nested2/depth3: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testdata/fixtures/File/ignored/.gitignore: -------------------------------------------------------------------------------- 1 | . 2 | -------------------------------------------------------------------------------- /crates/lint/testdata/.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | out/ 3 | -------------------------------------------------------------------------------- /crates/anvil/src/eth/otterscan/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod api; 2 | -------------------------------------------------------------------------------- /crates/evm/networks/src/celo/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod transfer; 2 | -------------------------------------------------------------------------------- /crates/chisel/tests/it/main.rs: -------------------------------------------------------------------------------- 1 | #[cfg(unix)] 2 | mod repl; 3 | -------------------------------------------------------------------------------- /testdata/forge-std-rev: -------------------------------------------------------------------------------- 1 | 8e40513d678f392f398620b3ef2b418648b33e89 -------------------------------------------------------------------------------- /crates/cast/tests/fixtures/keystore/password-ec554: -------------------------------------------------------------------------------- 1 | keystorepassword -------------------------------------------------------------------------------- /testdata/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | .lock 5 | -------------------------------------------------------------------------------- /crates/cast/tests/fixtures/keystore/password: -------------------------------------------------------------------------------- 1 | this is keystore password 2 | -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_chinese_simplified.txt: -------------------------------------------------------------------------------- 1 | 谐 谐 谐 谐 谐 谐 谐 谐 谐 谐 谐 宗 -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_chinese_traditional.txt: -------------------------------------------------------------------------------- 1 | 諧 諧 諧 諧 諧 諧 諧 諧 諧 諧 諧 宗 -------------------------------------------------------------------------------- /testdata/fixtures/File/read.txt: -------------------------------------------------------------------------------- 1 | hello readable world 2 | this is the second line! -------------------------------------------------------------------------------- /crates/common/README.md: -------------------------------------------------------------------------------- 1 | Common utilities for building and using foundry's tools. 2 | -------------------------------------------------------------------------------- /.github/assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stalim17/foundry/HEAD/.github/assets/demo.gif -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_japanese.txt: -------------------------------------------------------------------------------- 1 | ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ぜんご -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @danipopes @mattsse @grandizzy @yash-atreya @zerosnacks @onbjerg @0xrusowsky 2 | -------------------------------------------------------------------------------- /.github/assets/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stalim17/foundry/HEAD/.github/assets/banner.png -------------------------------------------------------------------------------- /testdata/fixtures/Rpc/balance_params.json: -------------------------------------------------------------------------------- 1 | ["0x8D97689C9818892B700e27F316cc3E41e17fBeb9", "0x117BC09"] -------------------------------------------------------------------------------- /testdata/fixtures/Toml/write_test.toml: -------------------------------------------------------------------------------- 1 | a = 123 2 | b = "0x000000000000000000000000000000000000bEEF" 3 | -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_english.txt: -------------------------------------------------------------------------------- 1 | test test test test test test test test test test test junk -------------------------------------------------------------------------------- /testdata/fixtures/Toml/Issue4402.toml: -------------------------------------------------------------------------------- 1 | tokens = ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"] 2 | empty = [] 3 | -------------------------------------------------------------------------------- /testdata/fixtures/Toml/whole_toml.toml: -------------------------------------------------------------------------------- 1 | str = "hai" 2 | uintArray = [42, 43] 3 | strArray = ["hai", "there"] 4 | -------------------------------------------------------------------------------- /testdata/fixtures/Toml/write_complex_test.toml: -------------------------------------------------------------------------------- 1 | a = 123 2 | b = "test" 3 | 4 | [c] 5 | a = 123 6 | b = "test" 7 | -------------------------------------------------------------------------------- /.github/compilation-benchmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stalim17/foundry/HEAD/.github/compilation-benchmark.png -------------------------------------------------------------------------------- /crates/chisel/assets/preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stalim17/foundry/HEAD/crates/chisel/assets/preview.gif -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_spanish.txt: -------------------------------------------------------------------------------- 1 | tacto tacto tacto tacto tacto tacto tacto tacto tacto tacto tacto lacra -------------------------------------------------------------------------------- /testdata/fixtures/Json/write_test.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": 123, 3 | "b": "0x000000000000000000000000000000000000bEEF" 4 | } -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_french.txt: -------------------------------------------------------------------------------- 1 | sonde sonde sonde sonde sonde sonde sonde sonde sonde sonde sonde hématome -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_portuguese.txt: -------------------------------------------------------------------------------- 1 | sobra sobra sobra sobra sobra sobra sobra sobra sobra sobra sobra guarani -------------------------------------------------------------------------------- /testdata/fixtures/Json/Issue4402.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"], 3 | "empty": [] 4 | } -------------------------------------------------------------------------------- /testdata/fixtures/Json/Issue4630.json: -------------------------------------------------------------------------------- 1 | { 2 | "local": { 3 | "prop1": 10 4 | }, 5 | "localempty": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_czech.txt: -------------------------------------------------------------------------------- 1 | uzenina uzenina uzenina uzenina uzenina uzenina uzenina uzenina uzenina uzenina uzenina nevina -------------------------------------------------------------------------------- /testdata/fixtures/Json/whole_json.json: -------------------------------------------------------------------------------- 1 | { 2 | "str": "hai", 3 | "uintArray": [42, 43], 4 | "strArray": ["hai", "there"] 5 | } 6 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | Contact [security@ithaca.xyz](mailto:security@ithaca.xyz). 6 | -------------------------------------------------------------------------------- /.github/assets/build_benchmark_solady_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stalim17/foundry/HEAD/.github/assets/build_benchmark_solady_dark.png -------------------------------------------------------------------------------- /.github/assets/build_benchmark_solady_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stalim17/foundry/HEAD/.github/assets/build_benchmark_solady_light.png -------------------------------------------------------------------------------- /testdata/fixtures/Json/write_complex_test.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": 123, 3 | "b": "test", 4 | "c": { 5 | "a": 123, 6 | "b": "test" 7 | } 8 | } -------------------------------------------------------------------------------- /.github/assets/build_benchmark_openzeppelin_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stalim17/foundry/HEAD/.github/assets/build_benchmark_openzeppelin_dark.png -------------------------------------------------------------------------------- /.github/assets/build_benchmark_openzeppelin_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stalim17/foundry/HEAD/.github/assets/build_benchmark_openzeppelin_light.png -------------------------------------------------------------------------------- /crates/wallets/src/wallet_browser/app/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stalim17/foundry/HEAD/crates/wallets/src/wallet_browser/app/assets/logo.png -------------------------------------------------------------------------------- /crates/wallets/src/wallet_browser/app/assets/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stalim17/foundry/HEAD/crates/wallets/src/wallet_browser/app/assets/banner.png -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_italian.txt: -------------------------------------------------------------------------------- 1 | surgelato surgelato surgelato surgelato surgelato surgelato surgelato surgelato surgelato surgelato surgelato mansarda -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_korean.txt: -------------------------------------------------------------------------------- 1 | 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 시스템 -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /crates/lint/testdata/auxiliary/ImportsAnotherFile.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | contract AnotherFile { 5 | // This contract is not used 6 | } 7 | -------------------------------------------------------------------------------- /crates/lint/testdata/auxiliary/ImportsAnotherFile2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | contract AnotherDummy { 5 | // This file is not used 6 | } 7 | -------------------------------------------------------------------------------- /crates/lint/testdata/auxiliary/ImportsSomeFile2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | struct Baz { 5 | address sender; 6 | uint256 value; 7 | } 8 | -------------------------------------------------------------------------------- /crates/lint/testdata/auxiliary/ImportsConstants.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | uint256 constant CONSTANT_0 = 42; 5 | uint256 constant CONSTANT_1 = 99; 6 | -------------------------------------------------------------------------------- /crates/lint/src/sol/gas/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::sol::{EarlyLintPass, LateLintPass, SolLint}; 2 | 3 | mod keccak; 4 | use keccak::ASM_KECCAK256; 5 | 6 | register_lints!((AsmKeccak256, late, (ASM_KECCAK256)),); 7 | -------------------------------------------------------------------------------- /crates/config/src/providers/mod.rs: -------------------------------------------------------------------------------- 1 | //! Config providers. 2 | 3 | mod ext; 4 | pub use ext::*; 5 | 6 | mod remappings; 7 | pub use remappings::*; 8 | 9 | mod warnings; 10 | pub use warnings::*; 11 | -------------------------------------------------------------------------------- /crates/lint/testdata/auxiliary/ImportsTypes.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | type MyType is uint256; 5 | type MyOtherType is uint256; 6 | type YetAnotherType is bool; 7 | -------------------------------------------------------------------------------- /testdata/fixtures/GetCode/WorkingContract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | contract WorkingContract { 5 | uint256 public constant secret = 42; 6 | } 7 | -------------------------------------------------------------------------------- /testdata/src/ICounter.vyi: -------------------------------------------------------------------------------- 1 | @view 2 | @external 3 | def number() -> uint256: 4 | ... 5 | 6 | @external 7 | def set_number(new_number: uint256): 8 | ... 9 | 10 | @external 11 | def increment(): 12 | ... -------------------------------------------------------------------------------- /crates/fmt/testdata/PragmaDirective/original.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.8.17; 2 | pragma experimental ABIEncoderV2; 3 | 4 | contract Contract {} 5 | 6 | // preserves lines 7 | pragma solidity 0.8.17; 8 | 9 | pragma experimental ABIEncoderV2; -------------------------------------------------------------------------------- /npm/bunfig.toml: -------------------------------------------------------------------------------- 1 | telemetry = false 2 | 3 | run.bun = true 4 | 5 | [install] 6 | auto = "auto" 7 | 8 | [install.scopes] 9 | "@foundry-rs" = { url = "$NPM_REGISTRY_URL", username = "$NPM_USERNAME" } 10 | 11 | logLevel = "debug" 12 | -------------------------------------------------------------------------------- /crates/common/src/io/style.rs: -------------------------------------------------------------------------------- 1 | #![allow(missing_docs)] 2 | use anstyle::*; 3 | 4 | pub const ERROR: Style = AnsiColor::Red.on_default().effects(Effects::BOLD); 5 | pub const WARN: Style = AnsiColor::Yellow.on_default().effects(Effects::BOLD); 6 | -------------------------------------------------------------------------------- /crates/evm/abi/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Solidity ABI-related utilities and [`sol!`](alloy_sol_types::sol) definitions. 2 | 3 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 4 | #![cfg_attr(docsrs, feature(doc_cfg))] 5 | 6 | pub mod console; 7 | -------------------------------------------------------------------------------- /crates/fmt/testdata/HexUnderscore/original.sol: -------------------------------------------------------------------------------- 1 | contract HexLiteral { 2 | function test() external { 3 | hex"0123_0000"; 4 | hex"01230000"; 5 | hex"0123_00_00"; 6 | hex""; 7 | hex"6001_6002_53"; 8 | } 9 | } -------------------------------------------------------------------------------- /crates/fmt/testdata/PragmaDirective/fmt.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.8.17; 2 | pragma experimental ABIEncoderV2; 3 | 4 | contract Contract {} 5 | 6 | // preserves lines 7 | pragma solidity 0.8.17; 8 | 9 | pragma experimental ABIEncoderV2; 10 | -------------------------------------------------------------------------------- /crates/lint/testdata/auxiliary/ImportsSomeFile.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | library SomeFile { 5 | struct Baz { 6 | uint256 amount; 7 | address owner; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /crates/doc/static/book.css: -------------------------------------------------------------------------------- 1 | table { 2 | margin: 0 auto; 3 | border-collapse: collapse; 4 | width: 100%; 5 | } 6 | 7 | table td:first-child { 8 | width: 15%; 9 | } 10 | 11 | table td:nth-child(2) { 12 | width: 25%; 13 | } -------------------------------------------------------------------------------- /crates/lint/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 3 | #![cfg_attr(docsrs, feature(doc_cfg))] 4 | #![allow(elided_lifetimes_in_paths)] 5 | 6 | pub mod linter; 7 | pub mod sol; 8 | -------------------------------------------------------------------------------- /crates/sol-macro-gen/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate contains the logic for Rust bindings generating from Solidity contracts 2 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 3 | 4 | pub mod sol_macro_gen; 5 | 6 | pub use sol_macro_gen::*; 7 | -------------------------------------------------------------------------------- /crates/fmt/testdata/HexUnderscore/fmt.sol: -------------------------------------------------------------------------------- 1 | contract HexLiteral { 2 | function test() external { 3 | hex"01230000"; 4 | hex"01230000"; 5 | hex"01230000"; 6 | hex""; 7 | hex"6001600253"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Support 4 | url: https://t.me/foundry_support 5 | about: This issue tracker is only for bugs and feature requests. Support is available on Telegram! 6 | -------------------------------------------------------------------------------- /crates/common/src/io/mod.rs: -------------------------------------------------------------------------------- 1 | //! Utilities for working with standard input, output, and error. 2 | 3 | #[macro_use] 4 | mod macros; 5 | 6 | pub mod shell; 7 | pub mod stdin; 8 | pub mod style; 9 | 10 | #[doc(no_inline)] 11 | pub use shell::Shell; 12 | -------------------------------------------------------------------------------- /crates/forge/assets/.gitignoreTemplate: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | 5 | # Ignores development broadcast logs 6 | !/broadcast 7 | /broadcast/*/31337/ 8 | /broadcast/**/dry-run/ 9 | 10 | # Docs 11 | docs/ 12 | 13 | # Dotenv file 14 | .env 15 | -------------------------------------------------------------------------------- /crates/forge/assets/vyper/CounterTemplate.vy: -------------------------------------------------------------------------------- 1 | # pragma version ~=0.4.3 2 | 3 | number: public(uint256) 4 | 5 | @external 6 | def setNumber(newNumber: uint256): 7 | self.number = newNumber 8 | 9 | @external 10 | def increment(): 11 | self.number += 1 -------------------------------------------------------------------------------- /crates/cli/src/utils/default_directives.txt: -------------------------------------------------------------------------------- 1 | [ 2 | // Low level networking 3 | "hyper=off", 4 | "hyper_util=off", 5 | "h2=off", 6 | "rustls=off", 7 | // Tokio 8 | "mio=off", 9 | // Too verbose 10 | "jsonpath_lib=off", 11 | ] 12 | -------------------------------------------------------------------------------- /crates/fmt/testdata/StructDefinition/original.sol: -------------------------------------------------------------------------------- 1 | struct Foo { 2 | 3 | } struct Bar { uint foo ;string bar ; } 4 | 5 | struct MyStruct { 6 | // first 1 7 | // first 2 8 | uint256 field1; 9 | // second 10 | uint256 field2; 11 | } 12 | -------------------------------------------------------------------------------- /FUNDING.json: -------------------------------------------------------------------------------- 1 | { 2 | "drips": { 3 | "ethereum": { 4 | "ownedBy": "0x86308c59a6005d012C51Eef104bBc21786aC5D2E" 5 | } 6 | }, 7 | "opRetro": { 8 | "projectId": "0x4562c0630907577f433cad78c7e2cc03349d918b6c14ef982f11a2678f5999ad" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /crates/fmt/testdata/EnumDefinition/original.sol: -------------------------------------------------------------------------------- 1 | contract EnumDefinitions { 2 | enum Empty { 3 | 4 | } 5 | enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } 6 | enum States { State1, State2, State3, State4, State5, State6, State7, State8, State9 } 7 | } -------------------------------------------------------------------------------- /crates/fmt/testdata/StructDefinition/fmt.sol: -------------------------------------------------------------------------------- 1 | struct Foo {} 2 | 3 | struct Bar { 4 | uint256 foo; 5 | string bar; 6 | } 7 | 8 | struct MyStruct { 9 | // first 1 10 | // first 2 11 | uint256 field1; 12 | // second 13 | uint256 field2; 14 | } 15 | -------------------------------------------------------------------------------- /crates/lint/src/sol/codesize/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::sol::{EarlyLintPass, LateLintPass, SolLint}; 2 | 3 | mod unwrapped_modifier_logic; 4 | use unwrapped_modifier_logic::UNWRAPPED_MODIFIER_LOGIC; 5 | 6 | register_lints!((UnwrappedModifierLogic, late, (UNWRAPPED_MODIFIER_LOGIC))); 7 | -------------------------------------------------------------------------------- /testdata/src/Counter.vy: -------------------------------------------------------------------------------- 1 | from . import ICounter 2 | implements: ICounter 3 | 4 | number: public(uint256) 5 | 6 | @external 7 | def set_number(new_number: uint256): 8 | self.number = new_number 9 | 10 | @external 11 | def increment(): 12 | self.number += 1 13 | -------------------------------------------------------------------------------- /testdata/etherscan/0x044b75f554b886A065b9567891e45c79542d7357/creation_data.json: -------------------------------------------------------------------------------- 1 | {"contractAddress":"0x044b75f554b886a065b9567891e45c79542d7357","contractCreator":"0xf87bc5535602077d340806d71f805ea9907a843d","txHash":"0x9a89d2f5528bf07661e92f3f78a3311396f11f15da19e3ec4d880be1ad1a4bec"} -------------------------------------------------------------------------------- /testdata/etherscan/0x35Fb958109b70799a8f9Bc2a8b1Ee4cC62034193/creation_data.json: -------------------------------------------------------------------------------- 1 | {"contractAddress":"0x35fb958109b70799a8f9bc2a8b1ee4cc62034193","contractCreator":"0x3e32324277e96b69750bc6f7c4ba27e122413e07","txHash":"0x41e3517f8262b55e1eb1707ba0760b603a70e89ea4a86eff56072fcc80c3d0a1"} -------------------------------------------------------------------------------- /testdata/etherscan/0x3a23F943181408EAC424116Af7b7790c94Cb97a5/creation_data.json: -------------------------------------------------------------------------------- 1 | {"contractAddress":"0x3a23f943181408eac424116af7b7790c94cb97a5","contractCreator":"0xe8dd38e673a93ccfc2e3d7053efccb5c93f49365","txHash":"0x29328ac0edf7b080320bc8ed998fcd3e866f7eec3775b0d91a86f5d02ab83c28"} -------------------------------------------------------------------------------- /testdata/etherscan/0x71356E37e0368Bd10bFDbF41dC052fE5FA24cD05/creation_data.json: -------------------------------------------------------------------------------- 1 | {"contractAddress":"0x71356e37e0368bd10bfdbf41dc052fe5fa24cd05","contractCreator":"0xaa1d342354d755ec515f40e7d5e83cb4184bb9ee","txHash":"0x1c800c2c2d5230823602cae6896a8db1ab7d1341ca697c6c64d9f0edf11dabe2"} -------------------------------------------------------------------------------- /testdata/etherscan/0x8B3D32cf2bb4d0D16656f4c0b04Fa546274f1545/creation_data.json: -------------------------------------------------------------------------------- 1 | {"contractAddress":"0x8b3d32cf2bb4d0d16656f4c0b04fa546274f1545","contractCreator":"0x958892b4a0512b28aaac890fc938868bbd42f064","txHash":"0x79820495643caf5a1e7e96578361c9ddba0e0735cd684ada7450254f6fd58f51"} -------------------------------------------------------------------------------- /testdata/etherscan/0x9AB6b21cDF116f611110b048987E58894786C244/creation_data.json: -------------------------------------------------------------------------------- 1 | {"contractAddress":"0x9ab6b21cdf116f611110b048987e58894786c244","contractCreator":"0x603d50bad151da8becf405e51a8c4abc8ba1c95e","txHash":"0x72be611ae1ade09242d9fc9c950a73d076f6c23514564a7b9ac730400dbaf2c0"} -------------------------------------------------------------------------------- /testdata/etherscan/0xDb53f47aC61FE54F456A4eb3E09832D08Dd7BEec/creation_data.json: -------------------------------------------------------------------------------- 1 | {"contractAddress":"0xdb53f47ac61fe54f456a4eb3e09832d08dd7beec","contractCreator":"0xc7f8d87734ab2cbf70030ac8aa82abfe3e8126cb","txHash":"0x196898c69f6b1944f1011120b15c0903329d46259c8cdc0fbcad71da1fe58245"} -------------------------------------------------------------------------------- /crates/anvil/src/eth/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod api; 2 | pub mod beacon; 3 | pub mod otterscan; 4 | pub mod sign; 5 | pub use api::EthApi; 6 | 7 | pub mod backend; 8 | 9 | pub mod error; 10 | 11 | pub mod fees; 12 | pub(crate) mod macros; 13 | pub mod miner; 14 | pub mod pool; 15 | pub mod util; 16 | -------------------------------------------------------------------------------- /npm/.env.example: -------------------------------------------------------------------------------- 1 | NODE_ENV="development" 2 | 3 | NPM_TOKEN="" 4 | 5 | PLATFORM_NAME="" 6 | ARCH="" 7 | 8 | # for testing purposes 9 | NPM_EMAIL="" 10 | NPM_PASSWORD="" 11 | NPM_REGISTRY_URL="" 12 | NPM_USER="foundry-rs" 13 | ALLOW_NO_INTEGRITY=false 14 | ALLOW_INSECURE_REGISTRY=false 15 | -------------------------------------------------------------------------------- /testdata/default/cheats/RandomAddress.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract RandomAddress is Test { 7 | function testRandomAddress() public { 8 | vm.randomAddress(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /crates/doc/src/writer/mod.rs: -------------------------------------------------------------------------------- 1 | //! The module for writing and formatting various parse tree items. 2 | 3 | mod as_doc; 4 | mod buf_writer; 5 | mod markdown; 6 | 7 | pub use as_doc::{AsDoc, AsDocResult}; 8 | pub use buf_writer::BufWriter; 9 | pub use markdown::Markdown; 10 | 11 | mod traits; 12 | -------------------------------------------------------------------------------- /crates/fmt/testdata/HexUnderscore/remove.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: hex_underscore = "remove" 2 | contract HexLiteral { 3 | function test() external { 4 | hex"01230000"; 5 | hex"01230000"; 6 | hex"01230000"; 7 | hex""; 8 | hex"6001600253"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /crates/fmt/testdata/TrailingComma/fmt.sol: -------------------------------------------------------------------------------- 1 | contract C is Contract { 2 | function f(uint256 a) external {} 3 | function f2(uint256 a, bytes32 b) external returns (uint256) {} 4 | 5 | function f3() external { 6 | try some.invoke() returns (uint256, uint256) {} catch {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /crates/forge/assets/vyper/ICounterTemplate.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | interface ICounter { 5 | function number() external view returns (uint256); 6 | function setNumber(uint256 newNumber) external; 7 | function increment() external; 8 | } 9 | -------------------------------------------------------------------------------- /testdata/default/cheats/Label.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract LabelTest is Test { 7 | function testLabel() public { 8 | vm.label(address(1), "Sir Address the 1st"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /testdata/multi-version/Importer.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.8.17; 2 | 3 | import "./Counter.sol"; 4 | 5 | // Please do not remove or change version pragma for this file. 6 | // If you need to ensure that some of the files are compiled with 7 | // solc 0.8.17, you should add imports of them to this file. 8 | -------------------------------------------------------------------------------- /crates/anvil/src/eth/macros.rs: -------------------------------------------------------------------------------- 1 | /// A `info!` helper macro that emits to the target, the node logger listens for 2 | macro_rules! node_info { 3 | ($($arg:tt)*) => { 4 | tracing::info!(target: $crate::logging::NODE_USER_LOG_TARGET, $($arg)*); 5 | }; 6 | } 7 | 8 | pub(crate) use node_info; 9 | -------------------------------------------------------------------------------- /crates/fmt/testdata/HexUnderscore/bytes.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: hex_underscore = "bytes" 2 | contract HexLiteral { 3 | function test() external { 4 | hex"01_23_00_00"; 5 | hex"01_23_00_00"; 6 | hex"01_23_00_00"; 7 | hex""; 8 | hex"60_01_60_02_53"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /crates/fmt/testdata/HexUnderscore/preserve.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: hex_underscore = "preserve" 2 | contract HexLiteral { 3 | function test() external { 4 | hex"0123_0000"; 5 | hex"01230000"; 6 | hex"0123_00_00"; 7 | hex""; 8 | hex"6001_6002_53"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /crates/fmt/testdata/TrailingComma/original.sol: -------------------------------------------------------------------------------- 1 | contract C is Contract { 2 | function f(uint256 a, ) external {} 3 | function f2(uint256 a, bytes32 b,) external returns (uint256,) {} 4 | 5 | function f3() external { 6 | try some.invoke() returns (uint256,uint256,) {} catch {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /testdata/etherscan/0x9d27527Ada2CF29fBDAB2973cfa243845a08Bd3F/creation_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "contractAddress": "0x9d27527ada2cf29fbdab2973cfa243845a08bd3f", 3 | "contractCreator": "0x7773ae67403d2e30102a84c48cc939919c4c881c", 4 | "txHash": "0xc757719b7ae11ea651b1b23249978a3e8fca94d358610f5809a5dc19fbf850ce" 5 | } -------------------------------------------------------------------------------- /testdata/multi-version/Counter.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.4; 2 | 3 | contract Counter { 4 | uint256 public number; 5 | 6 | function setNumber(uint256 newNumber) public { 7 | number = newNumber; 8 | } 9 | 10 | function increment() public { 11 | number++; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /crates/cli/src/opts/mod.rs: -------------------------------------------------------------------------------- 1 | mod build; 2 | mod chain; 3 | mod dependency; 4 | mod evm; 5 | mod global; 6 | mod rpc; 7 | mod transaction; 8 | 9 | pub use build::*; 10 | pub use chain::*; 11 | pub use dependency::*; 12 | pub use evm::*; 13 | pub use global::*; 14 | pub use rpc::*; 15 | pub use transaction::*; 16 | -------------------------------------------------------------------------------- /crates/fmt/testdata/StatementBlock/original.sol: -------------------------------------------------------------------------------- 1 | contract Contract { 2 | function test() { unchecked { a += 1; } 3 | 4 | unchecked { 5 | a += 1; 6 | } 7 | 2 + 2; 8 | 9 | unchecked { a += 1; 10 | } 11 | unchecked {} 12 | 13 | 1 + 1; 14 | 15 | 16 | } 17 | } -------------------------------------------------------------------------------- /crates/lint/testdata/auxiliary/ImportsUtils.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | function process(bool flag) pure returns (uint256) { 5 | return flag ? 1 : 0; 6 | } 7 | 8 | function calculate(uint256 a, uint256 b) pure returns (uint256) { 9 | return a + b; 10 | } 11 | -------------------------------------------------------------------------------- /crates/anvil/core/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # anvil-core 2 | //! 3 | //! Core Ethereum types for Anvil. 4 | 5 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 6 | #![cfg_attr(docsrs, feature(doc_cfg))] 7 | 8 | /// Various Ethereum types 9 | pub mod eth; 10 | 11 | /// Additional useful types 12 | pub mod types; 13 | -------------------------------------------------------------------------------- /crates/lint/testdata/auxiliary/ImportsUtils2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | function process(bool flag) pure returns (uint256) { 5 | return flag ? 1 : 0; 6 | } 7 | 8 | function calculate(uint256 a, uint256 b) pure returns (uint256) { 9 | return a + b; 10 | } 11 | -------------------------------------------------------------------------------- /testdata/utils/Test.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity >=0.6.2 <0.9.0; 3 | pragma experimental ABIEncoderV2; 4 | 5 | import "./DSTest.sol"; 6 | import "./Vm.sol"; 7 | import "./console.sol"; 8 | 9 | contract Test is DSTest { 10 | Vm public constant vm = Vm(HEVM_ADDRESS); 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_STORE 2 | /target* 3 | /*.sol 4 | CLAUDE.md 5 | 6 | # Foundry artifacts 7 | out/ 8 | snapshots/ 9 | 10 | # IDEs and extensions 11 | .idea 12 | .vscode 13 | .claude 14 | .zed 15 | 16 | # NPM 17 | .env 18 | node_modules 19 | dist 20 | bin 21 | _ 22 | *.tgz 23 | .vercel 24 | .vite 25 | .wrangler 26 | *.zip 27 | -------------------------------------------------------------------------------- /crates/evm/abi/src/console/hh.rs: -------------------------------------------------------------------------------- 1 | //! Hardhat `console.sol` interface. 2 | 3 | use alloy_sol_types::sol; 4 | use foundry_common_fmt::*; 5 | use foundry_macros::ConsoleFmt; 6 | 7 | sol!( 8 | #[sol(abi)] 9 | #[derive(ConsoleFmt)] 10 | Console, 11 | "src/Console.json" 12 | ); 13 | 14 | pub use Console::*; 15 | -------------------------------------------------------------------------------- /crates/fmt/testdata/StructDefinition/bracket-spacing.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: bracket_spacing = true 2 | struct Foo {} 3 | 4 | struct Bar { 5 | uint256 foo; 6 | string bar; 7 | } 8 | 9 | struct MyStruct { 10 | // first 1 11 | // first 2 12 | uint256 field1; 13 | // second 14 | uint256 field2; 15 | } 16 | -------------------------------------------------------------------------------- /crates/fmt/testdata/TypeDefinition/fmt.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.8; 2 | 3 | type Hello is uint256; 4 | 5 | contract TypeDefinition { 6 | event Moon(Hello world); 7 | 8 | function demo(Hello world) public { 9 | world = Hello.wrap(Hello.unwrap(world) + 1337); 10 | emit Moon(world); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /crates/fmt/testdata/TypeDefinition/original.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.8; 2 | 3 | type Hello is uint; 4 | 5 | contract TypeDefinition { 6 | event Moon(Hello world); 7 | 8 | function demo(Hello world) public { 9 | world = Hello.wrap(Hello.unwrap(world) + 1337); 10 | emit Moon(world); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | reorder_imports = true 2 | use_field_init_shorthand = true 3 | use_small_heuristics = "Max" 4 | 5 | # Nightly 6 | max_width = 100 7 | comment_width = 100 8 | imports_granularity = "Crate" 9 | wrap_comments = true 10 | format_code_in_doc_comments = true 11 | doc_comment_code_block_width = 100 12 | format_macro_matchers = true 13 | -------------------------------------------------------------------------------- /testdata/default/cheats/BlobBaseFee.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.25; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract BlobBaseFeeTest is Test { 7 | function test_blob_base_fee() public { 8 | vm.blobBaseFee(6969); 9 | assertEq(vm.getBlobBaseFee(), 6969); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.github/scripts/format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail 3 | 4 | # We have to ignore at shell level because testdata/ is not a valid Foundry project, 5 | # so running `forge fmt` with `--root testdata` won't actually check anything 6 | cargo run --bin forge -- fmt "$@" \ 7 | $(find testdata -name '*.sol' ! -name Vm.sol ! -name console.sol) 8 | -------------------------------------------------------------------------------- /crates/script-sequence/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Script Sequence and related types. 2 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 3 | 4 | #[macro_use] 5 | extern crate foundry_common; 6 | 7 | pub mod reader; 8 | pub mod sequence; 9 | pub mod transaction; 10 | 11 | pub use reader::*; 12 | pub use sequence::*; 13 | pub use transaction::*; 14 | -------------------------------------------------------------------------------- /testdata/default/cheats/Assume.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract AssumeTest is Test { 7 | function testAssume(uint8 x) public { 8 | vm.assume(x < 2 ** 7); 9 | assertTrue(x < 2 ** 7, "did not discard inputs"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /crates/doc/static/book.toml: -------------------------------------------------------------------------------- 1 | # For more configuration see https://rust-lang.github.io/mdBook/format/configuration/index.html 2 | [book] 3 | src = "src" 4 | 5 | [output.html] 6 | no-section-label = true 7 | additional-js = ["solidity.min.js"] 8 | additional-css = ["book.css"] 9 | mathjax-support = true 10 | 11 | [output.html.fold] 12 | enable = true 13 | -------------------------------------------------------------------------------- /testdata/default/core/BadSigAfterInvariant.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract BadSigAfterInvariant is Test { 7 | function afterinvariant() public {} 8 | 9 | function testShouldPassWithWarning() public { 10 | assert(true); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /testdata/default/linking/cycle/Cycle.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | library Foo { 5 | function foo() external { 6 | Bar.bar(); 7 | } 8 | 9 | function flum() external {} 10 | } 11 | 12 | library Bar { 13 | function bar() external { 14 | Foo.flum(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /crates/forge/assets/solidity/CounterTemplate.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | contract Counter { 5 | uint256 public number; 6 | 7 | function setNumber(uint256 newNumber) public { 8 | number = newNumber; 9 | } 10 | 11 | function increment() public { 12 | number++; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /crates/anvil/rpc/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # anvil-rpc 2 | //! 3 | //! JSON-RPC types. 4 | 5 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 6 | #![cfg_attr(docsrs, feature(doc_cfg))] 7 | 8 | /// JSON-RPC request bindings 9 | pub mod request; 10 | 11 | /// JSON-RPC response bindings 12 | pub mod response; 13 | 14 | /// JSON-RPC error bindings 15 | pub mod error; 16 | -------------------------------------------------------------------------------- /testdata/default/cheats/ChainId.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract ChainIdTest is Test { 7 | function testChainId() public { 8 | uint256 newChainId = 99; 9 | vm.chainId(newChainId); 10 | assertEq(newChainId, block.chainid); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /crates/anvil/src/eth/backend/mod.rs: -------------------------------------------------------------------------------- 1 | //! blockchain Backend 2 | 3 | /// [revm](foundry_evm::revm) related types 4 | pub mod db; 5 | /// In-memory Backend 6 | pub mod mem; 7 | 8 | pub mod cheats; 9 | pub mod time; 10 | 11 | pub mod env; 12 | pub mod executor; 13 | pub mod fork; 14 | pub mod genesis; 15 | pub mod info; 16 | pub mod notifications; 17 | pub mod validate; 18 | -------------------------------------------------------------------------------- /crates/anvil/src/server/error.rs: -------------------------------------------------------------------------------- 1 | /// Result alias 2 | pub type NodeResult = Result; 3 | 4 | /// An error that can occur when launching a anvil instance 5 | #[derive(Debug, thiserror::Error)] 6 | pub enum NodeError { 7 | #[error(transparent)] 8 | Hyper(#[from] hyper::Error), 9 | #[error(transparent)] 10 | Io(#[from] std::io::Error), 11 | } 12 | -------------------------------------------------------------------------------- /crates/fmt/testdata/Annotation/fmt.sol: -------------------------------------------------------------------------------- 1 | // Support for Solana/Substrate annotations 2 | contract A { 3 | @selector([1, 2, 3, 4]) 4 | function foo() public {} 5 | 6 | @selector("another one") 7 | function bar() public {} 8 | 9 | @first("") 10 | @second("") 11 | function foobar() public {} 12 | } 13 | 14 | @topselector(2) 15 | contract B {} 16 | -------------------------------------------------------------------------------- /crates/lint/src/sol/med/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::sol::{EarlyLintPass, LateLintPass, SolLint}; 2 | 3 | mod div_mul; 4 | use div_mul::DIVIDE_BEFORE_MULTIPLY; 5 | 6 | mod unsafe_typecast; 7 | use unsafe_typecast::UNSAFE_TYPECAST; 8 | 9 | register_lints!( 10 | (DivideBeforeMultiply, early, (DIVIDE_BEFORE_MULTIPLY)), 11 | (UnsafeTypecast, late, (UNSAFE_TYPECAST)) 12 | ); 13 | -------------------------------------------------------------------------------- /crates/fmt/testdata/Annotation/original.sol: -------------------------------------------------------------------------------- 1 | // Support for Solana/Substrate annotations 2 | contract A { 3 | @selector([1,2,3,4]) 4 | function foo() public {} 5 | 6 | @selector("another one") 7 | function bar() public {} 8 | 9 | @first("") 10 | @second("") 11 | function foobar() public {} 12 | } 13 | 14 | @topselector(2) 15 | contract B {} 16 | -------------------------------------------------------------------------------- /crates/fmt/testdata/StatementBlock/fmt.sol: -------------------------------------------------------------------------------- 1 | contract Contract { 2 | function test() { 3 | unchecked { 4 | a += 1; 5 | } 6 | 7 | unchecked { 8 | a += 1; 9 | } 10 | 2 + 2; 11 | 12 | unchecked { 13 | a += 1; 14 | } 15 | unchecked {} 16 | 17 | 1 + 1; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/default/linking/samefile_union/Libs.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.18; 3 | 4 | library LInit { 5 | function f() external view returns (uint256) { 6 | return block.number; 7 | } 8 | } 9 | 10 | library LRun { 11 | function g() external view returns (uint256) { 12 | return block.timestamp; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.github/RELEASE_FAILURE_ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "bug: release workflow failed" 3 | labels: P-high, T-bug 4 | --- 5 | 6 | The release workflow has failed. Some or all binaries might have not been published correctly. 7 | 8 | Check the [release workflow page]({{ env.WORKFLOW_URL }}) for details. 9 | 10 | This issue was raised by the workflow at `.github/workflows/release.yml`. 11 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ReprosFunctionDefs/original.sol: -------------------------------------------------------------------------------- 1 | contract Repros { 2 | // https://github.com/foundry-rs/foundry/issues/12109 3 | function createDefaultStream(UD21x18 ratePerSecond, uint40 startTime, IERC20 token_) internal returns (uint256); 4 | function calculateStreamedPercentage(uint128 streamedAmount, uint128 depositedAmount) internal pure returns (uint256) { a = 1; } 5 | } 6 | -------------------------------------------------------------------------------- /docs/dev/networks.md: -------------------------------------------------------------------------------- 1 | # Custom Network Features 2 | 3 | Foundry's `anvil`, `forge` and `cast` tools can be customized with specific network features (currently with custom 4 | precompiles, with planned support for custom transaction types). 5 | 6 | For supporting custom features of a network, please check out documentation and examples within [`evm-networks`](../../crates/evm/networks) crate. 7 | -------------------------------------------------------------------------------- /crates/anvil/src/eth/util.rs: -------------------------------------------------------------------------------- 1 | use alloy_primitives::hex; 2 | use itertools::Itertools; 3 | 4 | /// Formats values as hex strings, separated by commas. 5 | pub fn hex_fmt_many(i: I) -> String 6 | where 7 | I: IntoIterator, 8 | T: AsRef<[u8]>, 9 | { 10 | let items = i.into_iter().map(|item| hex::encode(item.as_ref())).format(", "); 11 | format!("{items}") 12 | } 13 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ModifierDefinition/original.sol: -------------------------------------------------------------------------------- 1 | contract ModifierDefinitions { 2 | modifier noParams() {} 3 | modifier oneParam(uint a) {} 4 | modifier twoParams(uint a,uint b) {} 5 | modifier threeParams(uint a,uint b ,uint c) {} 6 | modifier fourParams(uint a,uint b ,uint c, uint d) {} 7 | modifier overridden ( 8 | ) override ( Base1 , Base2) {} 9 | } 10 | -------------------------------------------------------------------------------- /crates/anvil/rpc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "anvil-rpc" 3 | 4 | version.workspace = true 5 | edition.workspace = true 6 | rust-version.workspace = true 7 | authors.workspace = true 8 | license.workspace = true 9 | homepage.workspace = true 10 | repository.workspace = true 11 | 12 | [lints] 13 | workspace = true 14 | 15 | [dependencies] 16 | serde.workspace = true 17 | serde_json.workspace = true 18 | -------------------------------------------------------------------------------- /crates/chisel/bin/main.rs: -------------------------------------------------------------------------------- 1 | //! The `chisel` CLI: a fast, utilitarian, and verbose Solidity REPL. 2 | 3 | use chisel::args::run; 4 | 5 | #[global_allocator] 6 | static ALLOC: foundry_cli::utils::Allocator = foundry_cli::utils::new_allocator(); 7 | 8 | fn main() { 9 | if let Err(err) = run() { 10 | let _ = foundry_common::sh_err!("{err:?}"); 11 | std::process::exit(1); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.github/INTEGRATION_FAILURE.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "bug: long-running integration tests failed" 3 | labels: P-high, T-bug 4 | --- 5 | 6 | The heavy (long-running) integration tests have failed. This indicates a regression in Foundry. 7 | 8 | Check the [heavy integration tests workflow page]({{ env.WORKFLOW_URL }}) for details. 9 | 10 | This issue was raised by the workflow at `.github/workflows/heavy-integration.yml`. 11 | -------------------------------------------------------------------------------- /testdata/default/core/Reverting.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract RevertingTest is Test { 7 | /// forge-config: default.allow_internal_expect_revert = true 8 | function testRevert() public { 9 | vm.expectRevert("should revert here"); 10 | require(false, "should revert here"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /testdata/fixtures/GetCode/Override.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.13; 3 | 4 | contract Override { 5 | event Payload(address sender, address target, bytes data); 6 | 7 | function emitPayload(address target, bytes calldata message) external payable returns (uint256) { 8 | emit Payload(msg.sender, target, message); 9 | return 0; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /crates/wallets/src/wallet_browser/app/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod contents { 2 | pub const INDEX_HTML: &str = include_str!("assets/index.html"); 3 | pub const STYLES_CSS: &str = include_str!("assets/styles.css"); 4 | pub const MAIN_JS: &str = include_str!("assets/main.js"); 5 | pub const BANNER_PNG: &[u8] = include_bytes!("assets/banner.png"); 6 | pub const LOGO_PNG: &[u8] = include_bytes!("assets/logo.png"); 7 | } 8 | -------------------------------------------------------------------------------- /crates/anvil/bin/main.rs: -------------------------------------------------------------------------------- 1 | //! The `anvil` CLI: a fast local Ethereum development node, akin to Hardhat Network, Tenderly. 2 | 3 | use anvil::args::run; 4 | 5 | #[global_allocator] 6 | static ALLOC: foundry_cli::utils::Allocator = foundry_cli::utils::new_allocator(); 7 | 8 | fn main() { 9 | if let Err(err) = run() { 10 | let _ = foundry_common::sh_err!("{err:?}"); 11 | std::process::exit(1); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /crates/fmt/testdata/StatementBlock/bracket-spacing.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: bracket_spacing = true 2 | contract Contract { 3 | function test() { 4 | unchecked { 5 | a += 1; 6 | } 7 | 8 | unchecked { 9 | a += 1; 10 | } 11 | 2 + 2; 12 | 13 | unchecked { 14 | a += 1; 15 | } 16 | unchecked { } 17 | 18 | 1 + 1; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /crates/cast/tests/fixtures/sign_typed_data.json: -------------------------------------------------------------------------------- 1 | {"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Message":[{"name":"data","type":"string"}]},"primaryType":"Message","domain":{"name":"example.metamask.io","version":"1","chainId":"1","verifyingContract":"0x0000000000000000000000000000000000000000"},"message":{"data":"Hello!"}} -------------------------------------------------------------------------------- /crates/fmt/testdata/EnumDefinition/fmt.sol: -------------------------------------------------------------------------------- 1 | contract EnumDefinitions { 2 | enum Empty {} 3 | enum ActionChoices { 4 | GoLeft, 5 | GoRight, 6 | GoStraight, 7 | SitStill 8 | } 9 | enum States { 10 | State1, 11 | State2, 12 | State3, 13 | State4, 14 | State5, 15 | State6, 16 | State7, 17 | State8, 18 | State9 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /crates/anvil/src/eth/beacon/mod.rs: -------------------------------------------------------------------------------- 1 | //! Beacon API types and utilities for Anvil 2 | //! 3 | //! This module provides types and utilities for implementing Beacon API endpoints 4 | //! in Anvil, allowing testing of blob-based transactions with standard beacon chain APIs. 5 | 6 | pub mod data; 7 | pub mod error; 8 | pub mod response; 9 | 10 | pub use data::GenesisDetails; 11 | pub use error::BeaconError; 12 | pub use response::BeaconResponse; 13 | -------------------------------------------------------------------------------- /crates/forge/assets/generated/TestTemplate.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import {Test, console} from "forge-std/Test.sol"; 5 | import {{contract_name}} from "../src/{contract_name}.sol"; 6 | 7 | contract {contract_name}Test is Test { 8 | {contract_name} public {instance_name}; 9 | 10 | function setUp() public { 11 | {instance_name} = new {contract_name}(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /crates/forge/tests/cli/constants.rs: -------------------------------------------------------------------------------- 1 | //! various constants 2 | 3 | pub const TEMPLATE_CONTRACT: &str = "Counter"; 4 | 5 | pub const TEMPLATE_TEST_CONTRACT: &str = "CounterTest"; 6 | 7 | pub const TEMPLATE_CONTRACT_ARTIFACT_BASE: &str = "Counter.sol/Counter"; 8 | 9 | pub const TEMPLATE_CONTRACT_ARTIFACT_JSON: &str = "Counter.sol/Counter.json"; 10 | 11 | pub const TEMPLATE_TEST_CONTRACT_ARTIFACT_JSON: &str = "Counter.t.sol/CounterTest.json"; 12 | -------------------------------------------------------------------------------- /crates/forge/bin/main.rs: -------------------------------------------------------------------------------- 1 | //! The `forge` CLI: build, test, fuzz, debug and deploy Solidity contracts, like Hardhat, Brownie, 2 | //! Ape. 3 | 4 | use forge::args::run; 5 | 6 | #[global_allocator] 7 | static ALLOC: foundry_cli::utils::Allocator = foundry_cli::utils::new_allocator(); 8 | 9 | fn main() { 10 | if let Err(err) = run() { 11 | let _ = foundry_common::sh_err!("{err:?}"); 12 | std::process::exit(1); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /crates/lint/src/sol/high/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::sol::{EarlyLintPass, LateLintPass, SolLint}; 2 | 3 | mod incorrect_shift; 4 | mod unchecked_calls; 5 | 6 | use incorrect_shift::INCORRECT_SHIFT; 7 | use unchecked_calls::{ERC20_UNCHECKED_TRANSFER, UNCHECKED_CALL}; 8 | 9 | register_lints!( 10 | (IncorrectShift, early, (INCORRECT_SHIFT)), 11 | (UncheckedCall, early, (UNCHECKED_CALL)), 12 | (UncheckedTransferERC20, late, (ERC20_UNCHECKED_TRANSFER)) 13 | ); 14 | -------------------------------------------------------------------------------- /testdata/default/cheats/Fee.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract FeeTest is Test { 7 | function testFee() public { 8 | vm.fee(10); 9 | assertEq(block.basefee, 10, "fee failed"); 10 | } 11 | 12 | function testFeeFuzzed(uint64 fee) public { 13 | vm.fee(fee); 14 | assertEq(block.basefee, fee, "fee failed"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /typos.toml: -------------------------------------------------------------------------------- 1 | [files] 2 | extend-exclude = [ 3 | ".git", 4 | "target", 5 | "testdata", 6 | "Cargo.toml", 7 | "Cargo.lock", 8 | "*.json", 9 | "*.js", 10 | "*.css", 11 | "*.html", 12 | "**/tests/**", 13 | "**/test/**", 14 | "**/*_test.*", 15 | "**/*_tests.*", 16 | ] 17 | 18 | [default.extend-words] 19 | ser = "ser" 20 | ratatui = "ratatui" 21 | Caf = "Caf" 22 | froms = "froms" 23 | strat = "strat" 24 | ba = "ba" 25 | -------------------------------------------------------------------------------- /.github/workflows/test-isolate.yml: -------------------------------------------------------------------------------- 1 | # Daily CI job to run tests with isolation mode enabled by default 2 | 3 | name: test-isolate 4 | 5 | permissions: {} 6 | 7 | on: 8 | schedule: 9 | - cron: "0 0 * * *" # Run daily at midnight UTC 10 | workflow_dispatch: # Needed so we can run it manually 11 | 12 | jobs: 13 | nextest: 14 | uses: ./.github/workflows/test.yml 15 | permissions: 16 | contents: read 17 | with: 18 | profile: isolate 19 | -------------------------------------------------------------------------------- /crates/cli/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # foundry-cli 2 | //! 3 | //! Common CLI utilities. 4 | 5 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 6 | #![cfg_attr(docsrs, feature(doc_cfg))] 7 | 8 | #[macro_use] 9 | extern crate foundry_common; 10 | 11 | #[macro_use] 12 | extern crate tracing; 13 | 14 | pub mod clap; 15 | pub mod handler; 16 | pub mod opts; 17 | pub mod utils; 18 | 19 | #[cfg(feature = "tracy")] 20 | tracing_tracy::client::register_demangler!(); 21 | -------------------------------------------------------------------------------- /npm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "imports": { 5 | "#*": "./src/*", 6 | "#scripts/*": "./scripts/*", 7 | "#package.json": "./package.json" 8 | }, 9 | "dependencies": { 10 | "@types/bun": "^1.3.1", 11 | "@types/node": "^24.9.1", 12 | "bun": "^1.3.1", 13 | "typescript": "^5.9.3" 14 | }, 15 | "license": "MIT OR Apache-2.0", 16 | "$schema": "https://json.schemastore.org/package.json" 17 | } 18 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue3661.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/3661 7 | contract Issue3661Test is Test { 8 | address sender; 9 | 10 | function setUp() public { 11 | sender = msg.sender; 12 | } 13 | 14 | function testSameSender() public { 15 | assert(sender == msg.sender); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /crates/cast/bin/main.rs: -------------------------------------------------------------------------------- 1 | //! The `cast` CLI: a Swiss Army knife for interacting with EVM smart contracts, sending 2 | //! transactions and getting chain data. 3 | 4 | use cast::args::run; 5 | 6 | #[global_allocator] 7 | static ALLOC: foundry_cli::utils::Allocator = foundry_cli::utils::new_allocator(); 8 | 9 | fn main() { 10 | if let Err(err) = run() { 11 | let _ = foundry_common::sh_err!("{err:?}"); 12 | std::process::exit(1); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /crates/fmt/testdata/YulStrings/fmt.sol: -------------------------------------------------------------------------------- 1 | contract Yul { 2 | function test() external { 3 | assembly { 4 | let a := "abc" 5 | let b := "abc" 6 | let c := hex"deadbeef" 7 | let d := hex"deadbeef" 8 | let e := 0xffffffffffffffffffffffffffffffffffffffff 9 | datacopy(0, dataoffset("runtime"), datasize("runtime")) 10 | return(0, datasize("runtime")) 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /testdata/fixtures/broadcast.sensitive.log.json: -------------------------------------------------------------------------------- 1 | { 2 | "transactions": [ 3 | { 4 | "rpc": "http://127.0.0.1:57544" 5 | }, 6 | { 7 | "rpc": "http://127.0.0.1:57544" 8 | }, 9 | { 10 | "rpc": "http://127.0.0.1:57544" 11 | }, 12 | { 13 | "rpc": "http://127.0.0.1:57544" 14 | }, 15 | { 16 | "rpc": "http://127.0.0.1:57544" 17 | }, 18 | { 19 | "rpc": "http://127.0.0.1:57544" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /crates/anvil/tests/it/main.rs: -------------------------------------------------------------------------------- 1 | mod abi; 2 | mod anvil; 3 | mod anvil_api; 4 | mod api; 5 | mod eip4844; 6 | mod eip7702; 7 | mod fork; 8 | mod gas; 9 | mod genesis; 10 | mod ipc; 11 | mod logs; 12 | mod optimism; 13 | mod otterscan; 14 | mod proof; 15 | mod pubsub; 16 | mod revert; 17 | mod sign; 18 | mod simulate; 19 | mod state; 20 | mod traces; 21 | mod transaction; 22 | mod txpool; 23 | pub mod utils; 24 | mod wsapi; 25 | 26 | pub use foundry_test_utils::init_tracing; 27 | -------------------------------------------------------------------------------- /crates/fmt/testdata/YulStrings/original.sol: -------------------------------------------------------------------------------- 1 | contract Yul { 2 | function test() external { 3 | assembly { 4 | let a := "abc" 5 | let b := 'abc' 6 | let c := hex"deadbeef" 7 | let d := hex'deadbeef' 8 | let e := 0xffffffffffffffffffffffffffffffffffffffff 9 | datacopy(0, dataoffset('runtime'), datasize("runtime")) 10 | return(0, datasize("runtime")) 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /testdata/default/cheats/GetNonce.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract Foo {} 7 | 8 | contract GetNonceTest is Test { 9 | function testGetNonce() public { 10 | uint64 nonce1 = vm.getNonce(address(this)); 11 | new Foo(); 12 | new Foo(); 13 | uint64 nonce2 = vm.getNonce(address(this)); 14 | assertEq(nonce1 + 2, nonce2); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /testdata/default/linking/samefile_union/SameFileUnion.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.18; 3 | 4 | import "./Libs.sol"; 5 | 6 | contract UsesBoth { 7 | uint256 public x; 8 | 9 | constructor() { 10 | // used only in creation bytecode 11 | x = LInit.f(); 12 | } 13 | 14 | function y() external view returns (uint256) { 15 | // used only in deployed bytecode 16 | return LRun.g(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /testdata/fixtures/GetCode/UnlinkedContract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | library SmolLibrary { 5 | function add(uint256 a, uint256 b) public pure returns (uint256 c) { 6 | c = a + b; 7 | } 8 | } 9 | 10 | contract UnlinkedContract { 11 | function complicated(uint256 a, uint256 b, uint256 c) public pure returns (uint256 d) { 12 | d = SmolLibrary.add(SmolLibrary.add(a, b), c); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /crates/forge/tests/cli/version.rs: -------------------------------------------------------------------------------- 1 | use foundry_test_utils::{forgetest, str}; 2 | 3 | forgetest!(print_short_version, |_prj, cmd| { 4 | cmd.arg("-V").assert_success().stdout_eq(str![[r#" 5 | forge [..]-[..] ([..] [..]) 6 | 7 | "#]]); 8 | }); 9 | 10 | forgetest!(print_long_version, |_prj, cmd| { 11 | cmd.arg("--version").assert_success().stdout_eq(str![[r#" 12 | forge Version: [..] 13 | Commit SHA: [..] 14 | Build Timestamp: [..] 15 | Build Profile: [..] 16 | 17 | "#]]); 18 | }); 19 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | crates/cheatcodes/assets/*.json linguist-generated 2 | testdata/cheats/Vm.sol linguist-generated 3 | bun.lock linguist-generated 4 | 5 | # See 6 | *.rs diff=rust 7 | crates/lint/testdata/* text eol=lf 8 | testdata/fixtures/**/* eol=lf 9 | 10 | dprint.json linguist-language=JSON-with-Comments 11 | .devcontainer/devcontainer.json linguist-language=JSON-with-Comments 12 | 13 | .env.example linguist-language=Dotenv -------------------------------------------------------------------------------- /.github/scripts/create-tag.js: -------------------------------------------------------------------------------- 1 | module.exports = async ({ github, context }, tagName) => { 2 | try { 3 | await github.rest.git.createRef({ 4 | owner: context.repo.owner, 5 | repo: context.repo.repo, 6 | ref: `refs/tags/${tagName}`, 7 | sha: context.sha, 8 | force: true, 9 | }); 10 | } catch (err) { 11 | console.error(`Failed to create tag: ${tagName}`); 12 | console.error(err); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /crates/anvil/server/src/error.rs: -------------------------------------------------------------------------------- 1 | //! Error variants used to unify different connection streams 2 | 3 | /// An error that can occur when reading an incoming request 4 | #[derive(Debug, thiserror::Error)] 5 | pub enum RequestError { 6 | #[error(transparent)] 7 | Axum(#[from] axum::Error), 8 | #[error(transparent)] 9 | Serde(#[from] serde_json::Error), 10 | #[error(transparent)] 11 | Io(#[from] std::io::Error), 12 | #[error("Disconnect")] 13 | Disconnect, 14 | } 15 | -------------------------------------------------------------------------------- /crates/fmt/testdata/EnumDefinition/bracket-spacing.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: bracket_spacing = true 2 | contract EnumDefinitions { 3 | enum Empty {} 4 | enum ActionChoices { 5 | GoLeft, 6 | GoRight, 7 | GoStraight, 8 | SitStill 9 | } 10 | enum States { 11 | State1, 12 | State2, 13 | State3, 14 | State4, 15 | State5, 16 | State6, 17 | State7, 18 | State8, 19 | State9 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ErrorDefinition/fmt.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.4; 2 | 3 | error TopLevelCustomError(); 4 | error TopLevelCustomErrorWithArg(uint256 x); 5 | error TopLevelCustomErrorArgWithoutName(string); 6 | error Error1( 7 | uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256 8 | ); 9 | 10 | contract Errors { 11 | error ContractCustomError(); 12 | error ContractCustomErrorWithArg(uint256 x); 13 | error ContractCustomErrorArgWithoutName(string); 14 | } 15 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ModifierDefinition/fmt.sol: -------------------------------------------------------------------------------- 1 | // config: line_length = 60 2 | contract ModifierDefinitions { 3 | modifier noParams() {} 4 | modifier oneParam(uint256 a) {} 5 | modifier twoParams(uint256 a, uint256 b) {} 6 | modifier threeParams(uint256 a, uint256 b, uint256 c) {} 7 | modifier fourParams( 8 | uint256 a, 9 | uint256 b, 10 | uint256 c, 11 | uint256 d 12 | ) {} 13 | modifier overridden() override(Base1, Base2) {} 14 | } 15 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ErrorDefinition/original.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.4; 2 | 3 | error 4 | TopLevelCustomError(); 5 | error TopLevelCustomErrorWithArg(uint x) ; 6 | error TopLevelCustomErrorArgWithoutName (string); 7 | error Error1(uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256); 8 | 9 | contract Errors { 10 | error 11 | ContractCustomError(); 12 | error ContractCustomErrorWithArg(uint x) ; 13 | error ContractCustomErrorArgWithoutName (string); 14 | } -------------------------------------------------------------------------------- /.config/nextest.toml: -------------------------------------------------------------------------------- 1 | [test-groups] 2 | 3 | [profile.default] 4 | retries = { backoff = "exponential", count = 2, delay = "5s", jitter = true } 5 | slow-timeout = { period = "30s", terminate-after = 3 } 6 | 7 | [[profile.default.overrides]] 8 | filter = "test(/ext_integration/)" 9 | slow-timeout = { period = "5m", terminate-after = 4 } 10 | 11 | # Do not re-run so that `cargo cheats` is ran locally. 12 | [[profile.default.overrides]] 13 | filter = "package(foundry-cheatcodes-spec)" 14 | retries = 0 15 | -------------------------------------------------------------------------------- /crates/lint/testdata/NamedStructFields.stderr: -------------------------------------------------------------------------------- 1 | note[named-struct-fields]: prefer initializing structs with named fields 2 | --> ROOT/testdata/NamedStructFields.sol:LL:CC 3 | | 4 | LL | Person memory person = Person("Alice", 25, address(0)); 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using named fields: `Person({ name: "Alice", age: 25, wallet: address(0) })` 6 | | 7 | = help: https://book.getfoundry.sh/reference/forge/forge-lint#named-struct-fields 8 | 9 | -------------------------------------------------------------------------------- /testdata/default/cheats/GetLabel.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract GetLabelTest is Test { 7 | function testGetLabel() public { 8 | // Label an address. 9 | vm.label(address(1), "Sir Address the 1st"); 10 | 11 | // Retrieve the label and check it. 12 | string memory label = vm.getLabel(address(1)); 13 | assertEq(label, "Sir Address the 1st"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue4640.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/4640 7 | contract Issue4640Test is Test { 8 | function testArbitrumBlockNumber() public { 9 | // 10 | vm.createSelectFork("arbitrum", 394276729); 11 | // L1 block number 12 | assertEq(block.number, 23675778); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /crates/forge/assets/solidity/CounterTemplate.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import {Script} from "forge-std/Script.sol"; 5 | import {Counter} from "../src/Counter.sol"; 6 | 7 | contract CounterScript is Script { 8 | Counter public counter; 9 | 10 | function setUp() public {} 11 | 12 | function run() public { 13 | vm.startBroadcast(); 14 | 15 | counter = new Counter(); 16 | 17 | vm.stopBroadcast(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/default/cheats/RandomBytes.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract RandomBytes is Test { 7 | function testRandomBytes4() public { 8 | vm.randomBytes4(); 9 | } 10 | 11 | function testRandomBytes8() public { 12 | vm.randomBytes8(); 13 | } 14 | 15 | function testFillrandomBytes() public view { 16 | uint256 len = 16; 17 | vm.randomBytes(len); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/default/cheats/SetBlockhash.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract SetBlockhash is Test { 7 | function testSetBlockhash() public { 8 | bytes32 blockHash = 0x1234567890123456789012345678901234567890123456789012345678901234; 9 | vm.setBlockhash(block.number - 1, blockHash); 10 | bytes32 expected = blockhash(block.number - 1); 11 | assertEq(blockHash, expected); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /crates/fmt/testdata/YulStrings/single-quote.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: quote_style = "single" 2 | contract Yul { 3 | function test() external { 4 | assembly { 5 | let a := 'abc' 6 | let b := 'abc' 7 | let c := hex'deadbeef' 8 | let d := hex'deadbeef' 9 | let e := 0xffffffffffffffffffffffffffffffffffffffff 10 | datacopy(0, dataoffset('runtime'), datasize('runtime')) 11 | return(0, datasize('runtime')) 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /crates/forge/tests/ui.rs: -------------------------------------------------------------------------------- 1 | use foundry_test_utils::ui_runner; 2 | use std::{env, path::Path}; 3 | 4 | const FORGE_CMD: &str = env!("CARGO_BIN_EXE_forge"); 5 | const FORGE_DIR: &str = env!("CARGO_MANIFEST_DIR"); 6 | 7 | fn main() -> impl std::process::Termination { 8 | let forge_cmd = Path::new(FORGE_CMD); 9 | let forge_dir = Path::new(FORGE_DIR); 10 | let lint_testdata = forge_dir.parent().unwrap().join("lint").join("testdata"); 11 | 12 | ui_runner::run_tests("lint", forge_cmd, &lint_testdata) 13 | } 14 | -------------------------------------------------------------------------------- /testdata/default/cheats/Travel.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract ChainIdTest is Test { 7 | function testChainId() public { 8 | vm.chainId(10); 9 | assertEq(block.chainid, 10, "chainId switch failed"); 10 | } 11 | 12 | function testChainIdFuzzed(uint64 chainId) public { 13 | vm.chainId(chainId); 14 | assertEq(block.chainid, chainId, "chainId switch failed"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /crates/fmt/testdata/YulStrings/preserve-quote.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: quote_style = "preserve" 2 | contract Yul { 3 | function test() external { 4 | assembly { 5 | let a := "abc" 6 | let b := 'abc' 7 | let c := hex"deadbeef" 8 | let d := hex'deadbeef' 9 | let e := 0xffffffffffffffffffffffffffffffffffffffff 10 | datacopy(0, dataoffset('runtime'), datasize("runtime")) 11 | return(0, datasize("runtime")) 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue6554.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/6554 7 | contract Issue6554Test is Test { 8 | function testPermissions() public { 9 | vm.writeFile("./out/Issue6554.t.sol/cachedFile.txt", "cached data"); 10 | string memory content = vm.readFile("./out/Issue6554.t.sol/cachedFile.txt"); 11 | assertEq(content, "cached data"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /crates/wallets/src/wallet_browser/app/assets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Foundry 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /testdata/README.md: -------------------------------------------------------------------------------- 1 | ## Foundry Tests 2 | 3 | A test suite that tests different aspects of Foundry. 4 | 5 | ### Structure 6 | 7 | - [`core`](default/core): Tests for fundamental aspects of Foundry 8 | - [`logs`](default/logs): Tests for Foundry logging capabilities 9 | - [`cheats`](default/cheats): Tests for Foundry cheatcodes 10 | - [`fuzz`](default/fuzz): Tests for the Foundry fuzzer 11 | - [`trace`](default/trace): Tests for the Foundry tracer 12 | - [`fork`](default/fork): Tests for Foundry forking capabilities 13 | -------------------------------------------------------------------------------- /crates/evm/fuzz/src/error.rs: -------------------------------------------------------------------------------- 1 | //! Errors related to fuzz tests. 2 | 3 | use proptest::test_runner::Reason; 4 | 5 | /// Possible errors when running fuzz tests 6 | #[derive(Debug, thiserror::Error)] 7 | pub enum FuzzError { 8 | #[error("`vm.assume` reject")] 9 | AssumeReject, 10 | #[error("`vm.assume` rejected too many inputs ({0} allowed)")] 11 | TooManyRejects(u32), 12 | } 13 | 14 | impl From for Reason { 15 | fn from(error: FuzzError) -> Self { 16 | error.to_string().into() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /crates/forge/assets/vyper/CounterTemplate.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import {Script} from "forge-std/Script.sol"; 5 | import {ICounter} from "../src/ICounter.sol"; 6 | 7 | contract CounterScript is Script { 8 | ICounter public counter; 9 | 10 | function setUp() public {} 11 | 12 | function run() public { 13 | vm.startBroadcast(); 14 | 15 | counter = ICounter(deployCode("src/Counter.vy")); 16 | 17 | vm.stopBroadcast(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/default/vyper/CounterTest.vy: -------------------------------------------------------------------------------- 1 | from src import ICounter 2 | 3 | interface Vm: 4 | def deployCode(artifact_name: String[1024], args: Bytes[1024] = b"") -> address: nonpayable 5 | 6 | vm: constant(Vm) = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D) 7 | counter: ICounter 8 | 9 | @external 10 | def setUp(): 11 | self.counter = ICounter(extcall vm.deployCode("src/Counter.vy")) 12 | 13 | @external 14 | def test_increment(): 15 | extcall self.counter.increment() 16 | assert staticcall self.counter.number() == 1 17 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue3190.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/3190 7 | contract Issue3190Test is Test { 8 | function setUp() public { 9 | vm.chainId(99); 10 | assertEq(99, block.chainid); 11 | } 12 | 13 | function testChainId() public { 14 | assertEq(99, block.chainid); 15 | vm.chainId(100); 16 | assertEq(100, block.chainid); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /crates/doc/src/parser/error.rs: -------------------------------------------------------------------------------- 1 | use solar::interface::diagnostics::EmittedDiagnostics; 2 | use thiserror::Error; 3 | 4 | /// The parser error. 5 | #[derive(Debug, Error)] 6 | #[error(transparent)] 7 | pub enum ParserError { 8 | /// Formatter error. 9 | #[error(transparent)] 10 | Formatter(EmittedDiagnostics), 11 | /// Internal parser error. 12 | #[error(transparent)] 13 | Internal(#[from] eyre::Error), 14 | } 15 | 16 | /// The parser result. 17 | pub type ParserResult = std::result::Result; 18 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue6293.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/6293 7 | contract Issue6293Test is Test { 8 | constructor() { 9 | require(address(this).balance > 0); 10 | (bool success,) = payable(address(1)).call{value: 1}(""); 11 | require(success, "call failed"); 12 | } 13 | 14 | function test() public { 15 | assertGt(address(this).balance, 0); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/scripts/move-tag.js: -------------------------------------------------------------------------------- 1 | module.exports = async ({ github, context }, tagName) => { 2 | try { 3 | await github.rest.git.updateRef({ 4 | owner: context.repo.owner, 5 | repo: context.repo.repo, 6 | ref: `tags/${tagName}`, 7 | sha: context.sha, 8 | force: true, 9 | }); 10 | } catch (err) { 11 | console.error(`Failed to move nightly tag.`); 12 | console.error(`This should only happen the first time.`); 13 | console.error(err); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ModifierDefinition/override-spacing.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: line_length = 60 2 | // config: override_spacing = true 3 | contract ModifierDefinitions { 4 | modifier noParams() {} 5 | modifier oneParam(uint256 a) {} 6 | modifier twoParams(uint256 a, uint256 b) {} 7 | modifier threeParams(uint256 a, uint256 b, uint256 c) {} 8 | modifier fourParams( 9 | uint256 a, 10 | uint256 b, 11 | uint256 c, 12 | uint256 d 13 | ) {} 14 | modifier overridden() override (Base1, Base2) {} 15 | } 16 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue3674.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/3674 7 | /// forge-config: default.sender = "0xF0959944122fb1ed4CfaBA645eA06EED30427BAA" 8 | contract Issue3674Test is Test { 9 | function testNonceCreateSelect() public { 10 | vm.createSelectFork("sepolia"); 11 | 12 | vm.createSelectFork("avaxTestnet"); 13 | assertTrue(vm.getNonce(msg.sender) > 0x17); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [alias] 2 | cheats = "test -p foundry-cheatcodes-spec --features schema tests::" 3 | test-debugger = "test -p forge --test cli manual_debug_setup -- --include-ignored --nocapture" 4 | bless-lints = "test -p forge --test ui -- --bless" 5 | 6 | # Increase the stack size to 10MB for Windows targets, which is in line with Linux 7 | # (whereas default for Windows is 1MB). 8 | [target.x86_64-pc-windows-msvc] 9 | rustflags = ["-Clink-arg=/STACK:10000000"] 10 | 11 | [target.i686-pc-windows-msvc] 12 | rustflags = ["-Clink-arg=/STACK:10000000"] 13 | -------------------------------------------------------------------------------- /crates/fmt/testdata/FunctionDefinitionWithFunctionReturns/fmt.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | contract ReturnFnFormat { 5 | function returnsFunction() 6 | internal 7 | pure 8 | returns (function() internal pure returns (uint256)) 9 | {} 10 | } 11 | 12 | // https://github.com/foundry-rs/foundry/issues/7920 13 | contract ReturnFnDisableFormat { 14 | // forgefmt: disable-next-line 15 | function disableFnFormat() external returns (uint256) { 16 | return 0; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/dependencies.yml: -------------------------------------------------------------------------------- 1 | # Runs `cargo update` periodically. 2 | 3 | name: dependencies 4 | 5 | permissions: {} 6 | 7 | on: 8 | schedule: 9 | - cron: "0 0 * * SUN" # Run weekly on Sundays at midnight UTC 10 | workflow_dispatch: # Needed so we can run it manually 11 | 12 | jobs: 13 | update: 14 | uses: ithacaxyz/ci/.github/workflows/cargo-update-pr.yml@9c8d0dc20e7ad02455d3fdab2378a05f29907630 # main 15 | permissions: 16 | contents: write 17 | pull-requests: write 18 | secrets: 19 | token: ${{ secrets.GITHUB_TOKEN }} 20 | -------------------------------------------------------------------------------- /testdata/default/cheats/GetRawBlockHeader.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract GetRawBlockHeaderTest is Test { 7 | function testGetRawBlockHeaderWithFork() public { 8 | vm.createSelectFork("mainnet"); 9 | assertEq( 10 | keccak256(vm.getRawBlockHeader(22985278)), 11 | // `cast keccak256 $(cast block 22985278 --raw)` 12 | 0x492419d85d2817f50577807a287742fbdcaae00ce89f2ea885e419ee4493b00f 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue5929.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/5929 7 | contract Issue5929Test is Test { 8 | function test_transact_not_working() public { 9 | vm.createSelectFork("mainnet", 21134547); 10 | // https://etherscan.io/tx/0x96a129768ec66fd7d65114bf182f4e173bf0b73a44219adaf71f01381a3d0143 11 | vm.transact(hex"7dcff74771babf9c23363c4228e55a27f50224d4596b1ba6608b0b45712f94ba"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /testdata/default/cheats/Bank.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract CoinbaseTest is Test { 7 | function testCoinbase() public { 8 | vm.coinbase(0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8); 9 | assertEq(block.coinbase, 0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8, "coinbase failed"); 10 | } 11 | 12 | function testCoinbaseFuzzed(address who) public { 13 | vm.coinbase(who); 14 | assertEq(block.coinbase, who, "coinbase failed"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /crates/fmt/testdata/FunctionDefinitionWithFunctionReturns/original.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | contract ReturnFnFormat { 5 | function returnsFunction() 6 | internal 7 | pure 8 | returns ( 9 | function() 10 | internal pure returns (uint256) 11 | ) 12 | {} 13 | } 14 | 15 | // https://github.com/foundry-rs/foundry/issues/7920 16 | contract ReturnFnDisableFormat { 17 | // forgefmt: disable-next-line 18 | function disableFnFormat() external returns (uint256) { 19 | return 0; 20 | } 21 | } -------------------------------------------------------------------------------- /crates/fmt/testdata/ReprosFunctionDefs/all.120.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: line_length = 120 2 | // config: multiline_func_header = "all" 3 | contract Repros { 4 | // https://github.com/foundry-rs/foundry/issues/12109 5 | function createDefaultStream(UD21x18 ratePerSecond, uint40 startTime, IERC20 token_) internal returns (uint256); 6 | 7 | function calculateStreamedPercentage( 8 | uint128 streamedAmount, 9 | uint128 depositedAmount 10 | ) 11 | internal 12 | pure 13 | returns (uint256) 14 | { 15 | a = 1; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /testdata/default/core/Abstract.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | contract TestFixture { 5 | function something() public pure returns (string memory) { 6 | return "something"; 7 | } 8 | } 9 | 10 | abstract contract AbstractTestBase { 11 | TestFixture fixture; 12 | 13 | function testSomething() public { 14 | fixture.something(); 15 | } 16 | } 17 | 18 | contract AbstractTest is AbstractTestBase { 19 | function setUp() public { 20 | fixture = new TestFixture(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /testdata/default/fork/ForkSame_1.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract ForkTest is Test { 7 | address constant WETH_TOKEN_ADDR = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; 8 | uint256 forkA; 9 | 10 | // this will create two _different_ forks during setup 11 | function setUp() public { 12 | forkA = vm.createFork("mainnet", 15_977_624); 13 | } 14 | 15 | function testDummy() public { 16 | uint256 balance = WETH_TOKEN_ADDR.balance; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /testdata/default/fork/ForkSame_2.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract ForkTest is Test { 7 | address constant WETH_TOKEN_ADDR = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; 8 | uint256 forkA; 9 | 10 | // this will create two _different_ forks during setup 11 | function setUp() public { 12 | forkA = vm.createFork("mainnet", 15_977_624); 13 | } 14 | 15 | function testDummy() public { 16 | uint256 balance = WETH_TOKEN_ADDR.balance; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue6070.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/6070 7 | contract Issue6066Test is Test { 8 | function testNonPrefixed() public { 9 | vm.setEnv("__FOUNDRY_ISSUE_6066", "abcd"); 10 | vm._expectCheatcodeRevert( 11 | "failed parsing $__FOUNDRY_ISSUE_6066 as type `uint256`: missing hex prefix (\"0x\") for hex string" 12 | ); 13 | uint256 x = vm.envUint("__FOUNDRY_ISSUE_6066"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /crates/anvil/test-data/emit_logs.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.24; 2 | 3 | contract SimpleStorage { 4 | 5 | event ValueChanged(address indexed author, string oldValue, string newValue); 6 | 7 | string _value; 8 | 9 | constructor(string memory value) public { 10 | _value = value; 11 | } 12 | 13 | function getValue() view public returns (string memory) { 14 | return _value; 15 | } 16 | 17 | function setValue(string memory value) public { 18 | emit ValueChanged(msg.sender, _value, value); 19 | _value = value; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /crates/cast/tests/fixtures/keystore/UTC--2022-10-30T06-51-20.130356000Z--560d246fcddc9ea98a8b032c9a2f474efb493c28: -------------------------------------------------------------------------------- 1 | {"address":"560d246fcddc9ea98a8b032c9a2f474efb493c28","crypto":{"cipher":"aes-128-ctr","ciphertext":"0b0012edfc7a1b22c7c616a78562807c363482490359ae23858c49d6a369b2ff","cipherparams":{"iv":"9d72960fe04dd987300e91c101c890b8"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"f7d24eae5e746700a1fdc0e0886801b0e7aff7e298f9409f74355a5387827181"},"mac":"981cae42a43ce975b9ff13d19a99ae755ad3f6125c94a4da517c50067ca87f07"},"id":"852dbcfc-726a-416e-9321-29f9b5d7e2de","version":3} -------------------------------------------------------------------------------- /crates/cast/tests/fixtures/keystore/UTC--2022-12-20T10-30-43.591916000Z--ec554aeafe75601aaab43bd4621a22284db566c2: -------------------------------------------------------------------------------- 1 | {"address":"ec554aeafe75601aaab43bd4621a22284db566c2","crypto":{"cipher":"aes-128-ctr","ciphertext":"f4e11a2667d97f42ad820f2aa735cd557ff608f47e2738d763a834b889611e18","cipherparams":{"iv":"99c3e2f1c98ccac50cb19f0a148e02ee"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"81f3033ffcc9fec9939eaec246a4037d9bc0c47cfb33247c98132b7d477b7e64"},"mac":"13bb4eac9a8d8f72905bca0c6f947c440d990baa649b0697b2083f3ab57d2cc5"},"id":"279ce8c3-dd94-43a8-aa46-15c3a45adbd1","version":3} -------------------------------------------------------------------------------- /testdata/default/repros/Issue3753.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/3753 7 | contract Issue3753Test is Test { 8 | function test_repro() public { 9 | bool res; 10 | assembly { 11 | res := staticcall(gas(), 4, 0, 0, 0, 0) 12 | } 13 | vm.expectRevert("require"); 14 | this.revert_require(); 15 | } 16 | 17 | function revert_require() public { 18 | revert("require"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue6538.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/6538 7 | contract Issue6538Test is Test { 8 | function test_transact() public { 9 | bytes32 lastHash = 0x4b70ca8c5a0990b43df3064372d424d46efa41dfaab961754b86c5afb2df4f61; 10 | vm.createSelectFork("mainnet", lastHash); 11 | bytes32 txhash = 0x7dcff74771babf9c23363c4228e55a27f50224d4596b1ba6608b0b45712f94ba; 12 | vm.transact(txhash); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /testdata/default/cheats/EnsNamehash.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract EnsNamehashTest is Test { 7 | function testEnsNamehash() public { 8 | assertEq(vm.ensNamehash(""), 0x0000000000000000000000000000000000000000000000000000000000000000); 9 | assertEq(vm.ensNamehash("eth"), 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae); 10 | assertEq(vm.ensNamehash("foo.eth"), 0xde9b09fd7c5f901e23a3f19fecc54828e9c848539801e86591bd9801b019f84f); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /testdata/default/cheats/Sort.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract SortTest is Test { 7 | function testSortCheatcode() public { 8 | uint256[] memory numbers = new uint256[](3); 9 | numbers[0] = 3; 10 | numbers[1] = 1; 11 | numbers[2] = 2; 12 | 13 | uint256[] memory sortedNumbers = vm.sort(numbers); 14 | 15 | assertEq(sortedNumbers[0], 1); 16 | assertEq(sortedNumbers[1], 2); 17 | assertEq(sortedNumbers[2], 3); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue6759.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/6759 7 | contract Issue6759Test is Test { 8 | function testCreateMulti() public { 9 | uint256 fork1 = vm.createFork("mainnet", 10); 10 | uint256 fork2 = vm.createFork("mainnet", 10); 11 | uint256 fork3 = vm.createFork("mainnet", 10); 12 | assert(fork1 != fork2); 13 | assert(fork1 != fork3); 14 | assert(fork2 != fork3); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /crates/evm/abi/src/console/mod.rs: -------------------------------------------------------------------------------- 1 | use alloy_primitives::{I256, U256}; 2 | 3 | pub mod ds; 4 | pub mod hh; 5 | 6 | pub fn format_units_int(x: &I256, decimals: &U256) -> String { 7 | let (sign, x) = x.into_sign_and_abs(); 8 | format!("{sign}{}", format_units_uint(&x, decimals)) 9 | } 10 | 11 | pub fn format_units_uint(x: &U256, decimals: &U256) -> String { 12 | match alloy_primitives::utils::Unit::new(decimals.saturating_to::()) { 13 | Some(units) => alloy_primitives::utils::ParseUnits::U256(*x).format_units(units), 14 | None => x.to_string(), 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /crates/debugger/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # foundry-debugger 2 | //! 3 | //! Interactive Solidity TUI debugger and debugger data file dumper 4 | 5 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 6 | #![cfg_attr(docsrs, feature(doc_cfg))] 7 | 8 | #[macro_use] 9 | extern crate foundry_common; 10 | 11 | #[macro_use] 12 | extern crate tracing; 13 | 14 | mod op; 15 | 16 | mod builder; 17 | mod debugger; 18 | mod dump; 19 | mod tui; 20 | 21 | mod node; 22 | 23 | pub use node::DebugNode; 24 | 25 | pub use builder::DebuggerBuilder; 26 | pub use debugger::Debugger; 27 | pub use tui::{ExitReason, TUI}; 28 | -------------------------------------------------------------------------------- /crates/linking/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foundry-linking" 3 | description = "Smart contract linking tools" 4 | 5 | version.workspace = true 6 | edition.workspace = true 7 | rust-version.workspace = true 8 | authors.workspace = true 9 | license.workspace = true 10 | homepage.workspace = true 11 | repository.workspace = true 12 | 13 | [lints] 14 | workspace = true 15 | 16 | [dependencies] 17 | foundry-compilers.workspace = true 18 | 19 | alloy-primitives = { workspace = true, features = ["rlp"] } 20 | 21 | rayon.workspace = true 22 | semver.workspace = true 23 | thiserror.workspace = true 24 | -------------------------------------------------------------------------------- /crates/macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foundry-macros" 3 | 4 | version.workspace = true 5 | edition.workspace = true 6 | rust-version.workspace = true 7 | authors.workspace = true 8 | license.workspace = true 9 | homepage.workspace = true 10 | repository.workspace = true 11 | 12 | [lints] 13 | workspace = true 14 | 15 | [lib] 16 | proc-macro = true 17 | # proc-macro tests aren't fully supported by cargo-nextest archives 18 | test = false 19 | doc = false 20 | 21 | [dependencies] 22 | proc-macro2.workspace = true 23 | quote.workspace = true 24 | syn.workspace = true 25 | proc-macro-error2 = "2" 26 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue3653.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/3653 7 | contract Issue3653Test is Test { 8 | uint256 fork; 9 | Token token; 10 | 11 | constructor() { 12 | fork = vm.createSelectFork("mainnet", 1000000); 13 | token = new Token(); 14 | vm.makePersistent(address(token)); 15 | } 16 | 17 | function testDummy() public { 18 | assertEq(block.number, 1000000); 19 | } 20 | } 21 | 22 | contract Token {} 23 | -------------------------------------------------------------------------------- /crates/common/fmt/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Helpers for formatting Ethereum types. 2 | 3 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 4 | 5 | mod console; 6 | pub use console::{ConsoleFmt, FormatSpec, console_format}; 7 | 8 | mod dynamic; 9 | pub use dynamic::{ 10 | StructDefinitions, TypeDefMap, format_token, format_token_raw, format_tokens, 11 | format_tokens_raw, parse_tokens, serialize_value_as_json, 12 | }; 13 | 14 | mod exp; 15 | pub use exp::{format_int_exp, format_uint_exp, to_exp_notation}; 16 | 17 | mod ui; 18 | pub use ui::{EthValue, UIfmt, get_pretty_block_attr, get_pretty_tx_attr}; 19 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ConstructorModifierStyle/fmt.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.5.2; 4 | 5 | import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; 6 | import {ERC1155} from "solmate/tokens/ERC1155.sol"; 7 | 8 | import {IAchievements} from "./interfaces/IAchievements.sol"; 9 | import {SoulBound1155} from "./abstracts/SoulBound1155.sol"; 10 | 11 | contract Achievements is IAchievements, SoulBound1155, Ownable { 12 | constructor(address owner) my_modifier Ownable() ERC1155() {} 13 | 14 | function f() my_modifier MyModifier my_modifier MyModifier {} 15 | } 16 | -------------------------------------------------------------------------------- /crates/verify/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Smart contract verification. 2 | 3 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 4 | #![cfg_attr(docsrs, feature(doc_cfg))] 5 | 6 | #[macro_use] 7 | extern crate foundry_common; 8 | 9 | #[macro_use] 10 | extern crate tracing; 11 | 12 | mod etherscan; 13 | 14 | pub mod provider; 15 | 16 | pub mod bytecode; 17 | pub use bytecode::VerifyBytecodeArgs; 18 | 19 | pub mod retry; 20 | pub use retry::RetryArgs; 21 | 22 | mod sourcify; 23 | 24 | pub mod verify; 25 | pub use verify::{VerifierArgs, VerifyArgs, VerifyCheckArgs}; 26 | 27 | mod types; 28 | 29 | mod utils; 30 | -------------------------------------------------------------------------------- /crates/lint/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "forge-lint" 3 | 4 | version.workspace = true 5 | edition.workspace = true 6 | rust-version.workspace = true 7 | authors.workspace = true 8 | license.workspace = true 9 | homepage.workspace = true 10 | repository.workspace = true 11 | 12 | [lints] 13 | workspace = true 14 | 15 | [dependencies] 16 | # lib 17 | foundry-common.workspace = true 18 | foundry-compilers.workspace = true 19 | foundry-config.workspace = true 20 | 21 | solar.workspace = true 22 | 23 | eyre.workspace = true 24 | heck.workspace = true 25 | rayon.workspace = true 26 | thiserror.workspace = true 27 | -------------------------------------------------------------------------------- /docs/dev/architecture.md: -------------------------------------------------------------------------------- 1 | # Architecture 2 | 3 | This document describes the high-level architecture of Foundry. 4 | 5 | ### `evm/` 6 | 7 | Foundry's EVM tooling. This is built around [`revm`](https://github.com/bluealloy/revm) and has additional 8 | implementation of: 9 | 10 | - [cheatcodes](./cheatcodes.md) a set of solidity calls dedicated to testing which can manipulate the environment in which the execution is run 11 | 12 | ### `config/` 13 | 14 | Includes all of Foundry's settings and how to get them 15 | 16 | ### `cli/` 17 | 18 | The core `forge` and `cast` cli implementation. Includes all subcommands. 19 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ConstructorModifierStyle/original.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.5.2; 4 | 5 | import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; 6 | import {ERC1155} from "solmate/tokens/ERC1155.sol"; 7 | 8 | import {IAchievements} from "./interfaces/IAchievements.sol"; 9 | import {SoulBound1155} from "./abstracts/SoulBound1155.sol"; 10 | 11 | contract Achievements is IAchievements, SoulBound1155, Ownable { 12 | constructor(address owner) my_modifier Ownable() ERC1155() {} 13 | 14 | function f() my_modifier MyModifier() my_modifier() MyModifier {} 15 | } 16 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue2623.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/2623 7 | contract Issue2623Test is Test { 8 | function testRollFork() public { 9 | uint256 fork = vm.createFork("mainnet", 10); 10 | vm.selectFork(fork); 11 | 12 | assertEq(block.number, 10); 13 | assertEq(block.timestamp, 1438270128); 14 | 15 | vm.rollFork(11); 16 | 17 | assertEq(block.number, 11); 18 | assertEq(block.timestamp, 1438270136); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Since version 2.23 (released in August 2019), git-blame has a feature 2 | # to ignore or bypass certain commits. 3 | # 4 | # This file contains a list of commits that are not likely what you 5 | # are looking for in a blame, such as mass reformatting or renaming. 6 | # You can set this file as a default ignore file for blame by running 7 | # the following command. 8 | # 9 | # $ git config blame.ignoreRevsFile .git-blame-ignore-revs 10 | 11 | # fmt: all (#3398) 12 | 860d083183b51a6f8d865408ef1a44aa694d6862 13 | 14 | # chore: bump to rust edition 2024 (#10802) 15 | 710a1584aae8e0f8ca8d5ba552632dc72381091e 16 | -------------------------------------------------------------------------------- /testdata/fixtures/Json/test_allocs.json: -------------------------------------------------------------------------------- 1 | { 2 | "0x0000000000000000000000000000000000000420": { 3 | "balance": "0xabcd", 4 | "code": "0x604260005260206000F3", 5 | "storage": { 6 | "0x1000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000000000000000000000000000000000000000beef" 7 | } 8 | }, 9 | "0x0000000000000000000000000000000000000421": { 10 | "balance": "0x0", 11 | "storage": { 12 | "0x1000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000000000000000000000000000000000000000beef" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /crates/fmt/testdata/EnumVariants/fmt.sol: -------------------------------------------------------------------------------- 1 | interface I { 2 | enum Empty {} 3 | 4 | /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`. 5 | enum CallerMode { 6 | /// No caller modification is currently active. 7 | None 8 | } 9 | 10 | /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`. 11 | enum CallerMode2 { 12 | /// No caller modification is currently active. 13 | None, /// No caller modification is currently active2. 14 | 15 | Some 16 | } 17 | 18 | function bar() public {} 19 | } 20 | -------------------------------------------------------------------------------- /crates/fmt/testdata/DoWhileStatement/original.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.8; 2 | 3 | contract DoWhileStatement { 4 | function test() external { 5 | uint256 i; 6 | do { "test"; } while (i != 0); 7 | 8 | do 9 | {} 10 | while 11 | ( 12 | i != 0); 13 | 14 | bool someVeryVeryLongCondition; 15 | do { "test"; } while( 16 | someVeryVeryLongCondition && !someVeryVeryLongCondition && 17 | !someVeryVeryLongCondition && 18 | someVeryVeryLongCondition); 19 | 20 | do i++; while(i < 10); 21 | 22 | do do i++; while (i < 30); while(i < 20); 23 | } 24 | } -------------------------------------------------------------------------------- /testdata/default/repros/Issue3192.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/3192 7 | contract Issue3192Test is Test { 8 | uint256 fork1; 9 | uint256 fork2; 10 | 11 | function setUp() public { 12 | fork1 = vm.createFork("mainnet", 7475589); 13 | fork2 = vm.createFork("mainnet", 12880747); 14 | vm.selectFork(fork1); 15 | } 16 | 17 | function testForkSwapSelect() public { 18 | assertEq(fork1, vm.activeFork()); 19 | vm.selectFork(fork2); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | # `bytes::Bytes` is included by default and `alloy_primitives::Bytes` is a wrapper around it, 2 | # so it is safe to ignore it as well. 3 | ignore-interior-mutability = ["bytes::Bytes", "alloy_primitives::Bytes"] 4 | 5 | disallowed-macros = [ 6 | # See `foundry_common::shell`. 7 | { path = "std::print", reason = "use `sh_print` or similar macros instead" }, 8 | { path = "std::eprint", reason = "use `sh_eprint` or similar macros instead" }, 9 | { path = "std::println", reason = "use `sh_println` or similar macros instead" }, 10 | { path = "std::eprintln", reason = "use `sh_eprintln` or similar macros instead" }, 11 | ] 12 | -------------------------------------------------------------------------------- /crates/lint/testdata/NamedStructFields.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | contract NamedStructFields { 5 | struct Person { 6 | string name; 7 | uint256 age; 8 | address wallet; 9 | } 10 | 11 | function namedArgs() public { 12 | Person memory person = Person({ 13 | name: "Alice", 14 | age: 25, 15 | wallet: address(0) 16 | }); 17 | } 18 | 19 | function positionalArgs() public { 20 | Person memory person = Person("Alice", 25, address(0)); //~NOTE: prefer initializing structs with named fields 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /crates/anvil/src/eth/backend/notifications.rs: -------------------------------------------------------------------------------- 1 | //! Notifications emitted from the backed 2 | 3 | use alloy_consensus::Header; 4 | use alloy_primitives::B256; 5 | use futures::channel::mpsc::UnboundedReceiver; 6 | use std::sync::Arc; 7 | 8 | /// A notification that's emitted when a new block was imported 9 | #[derive(Clone, Debug)] 10 | pub struct NewBlockNotification { 11 | /// Hash of the imported block 12 | pub hash: B256, 13 | /// block header 14 | pub header: Arc
, 15 | } 16 | 17 | /// Type alias for a receiver that receives [NewBlockNotification] 18 | pub type NewBlockNotifications = UnboundedReceiver; 19 | -------------------------------------------------------------------------------- /crates/evm/fuzz/src/strategies/mod.rs: -------------------------------------------------------------------------------- 1 | mod int; 2 | pub use int::IntStrategy; 3 | 4 | mod uint; 5 | pub use uint::UintStrategy; 6 | 7 | mod param; 8 | pub use param::{fuzz_param, fuzz_param_from_state, fuzz_param_with_fixtures, mutate_param_value}; 9 | 10 | mod calldata; 11 | pub use calldata::{fuzz_calldata, fuzz_calldata_from_state}; 12 | 13 | mod state; 14 | pub use state::EvmFuzzState; 15 | 16 | mod invariants; 17 | pub use invariants::{fuzz_contract_with_calldata, invariant_strat, override_call_strat}; 18 | 19 | mod mutators; 20 | pub use mutators::BoundMutator; 21 | 22 | mod literals; 23 | pub use literals::{LiteralMaps, LiteralsCollector}; 24 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ConstructorDefinition/original.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.5.2; 4 | 5 | // comment block starts here 6 | // comment block continues 7 | // 8 | 9 | // comment block 2 starts here 10 | // comment block 2 continues 11 | 12 | contract Constructors is Ownable, Changeable { 13 | function Constructors(variable1) public Changeable(variable1) Ownable() onlyOwner { 14 | } 15 | 16 | constructor(variable1, variable2, variable3, variable4, variable5, variable6, variable7) public Changeable(variable1, variable2, variable3, variable4, variable5, variable6, variable7) Ownable() onlyOwner {} 17 | } 18 | -------------------------------------------------------------------------------- /crates/fmt/testdata/EnumVariants/original.sol: -------------------------------------------------------------------------------- 1 | interface I { 2 | enum Empty { 3 | 4 | } 5 | 6 | /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`. 7 | enum CallerMode 8 | {/// No caller modification is currently active. 9 | None 10 | } 11 | 12 | /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`. 13 | enum CallerMode2 14 | {/// No caller modification is currently active. 15 | None,/// No caller modification is currently active2. 16 | 17 | Some 18 | } 19 | 20 | function bar() public { 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /testdata/default/repros/Issue11616.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.24; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract Emit { 7 | event A(); 8 | event B(); 9 | 10 | function emitB() public { 11 | emit B(); 12 | } 13 | } 14 | 15 | contract Issue11616Test is Test { 16 | Emit public e; 17 | 18 | function setUp() public { 19 | e = new Emit(); 20 | } 21 | 22 | function test_emitNotOk() public { 23 | vm.expectEmit({count: 0}); 24 | emit Emit.A(); 25 | vm.expectEmit(); 26 | emit Emit.B(); 27 | e.emitB(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /testdata/default/cheats/Remember.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract RememberTest is Test { 7 | function testRememberKey() public { 8 | string memory mnemonic = "test test test test test test test test test test test junk"; 9 | 10 | uint256 privateKey = vm.deriveKey(mnemonic, 0); 11 | assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); 12 | 13 | address thisAddress = vm.rememberKey(privateKey); 14 | assertEq(thisAddress, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /testdata/fixtures/Toml/nested_toml_struct.toml: -------------------------------------------------------------------------------- 1 | name = "test" 2 | 3 | [[members]] 4 | a = 100 5 | arr = [ 6 | [1, -2, -5], 7 | [1000, 2000, 0] 8 | ] 9 | str = "some string" 10 | b = "0x" 11 | addr = "0x0000000000000000000000000000000000000000" 12 | fixedBytes = "0x8ae3fc6bd1b150a73ec4afe3ef136fa2f88e9c96131c883c5e4a4714811c1598" 13 | 14 | [[members]] 15 | a = 200 16 | arr = [] 17 | str = "some other string" 18 | b = "0x0000000000000000000000000000000000000000" 19 | addr = "0x167D91deaEEE3021161502873d3bcc6291081648" 20 | fixedBytes = "0xed1c7beb1f00feaaaec5636950d6edb25a8d4fedc8deb2711287b64c4d27719d" 21 | 22 | [inner] 23 | fixedBytes = "0x12345678" 24 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ThisExpression/original.sol: -------------------------------------------------------------------------------- 1 | contract ThisExpression { 2 | function someFunc() public {} 3 | function someVeryVeryVeryLongVariableNameThatWillBeAccessedByThisKeyword() public {} 4 | 5 | function test() external { 6 | this.someFunc(); 7 | this.someVeryVeryVeryLongVariableNameThatWillBeAccessedByThisKeyword(); 8 | this // comment1 9 | .someVeryVeryVeryLongVariableNameThatWillBeAccessedByThisKeyword(); 10 | address(this).balance; 11 | 12 | address thisAddress = address( 13 | // comment2 14 | /* comment3 */ this // comment 4 15 | ); 16 | } 17 | } -------------------------------------------------------------------------------- /crates/fmt/testdata/UsingDirective/original.sol: -------------------------------------------------------------------------------- 1 | contract UsingExampleContract { 2 | using UsingExampleLibrary for * ; 3 | using UsingExampleLibrary for uint; 4 | using Example.UsingExampleLibrary for uint; 5 | using { M.g, M.f} for uint; 6 | using UsingExampleLibrary for uint global; 7 | using { These, Are, MultipleLibraries, ThatNeedToBePut, OnSeparateLines } for uint; 8 | using { This.isareally.longmember.access.expression.that.needs.to.besplit.into.lines } for uint; 9 | using {and as &, or as |, xor as ^, cpl as ~} for Bitmap global; 10 | using {eq as ==, ne as !=, lt as <, lte as <=, gt as >, gte as >=} for Bitmap global; 11 | } 12 | -------------------------------------------------------------------------------- /crates/evm/abi/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foundry-evm-abi" 3 | description = "Solidity ABI-related utilities and `sol!` definitions" 4 | 5 | version.workspace = true 6 | edition.workspace = true 7 | rust-version.workspace = true 8 | authors.workspace = true 9 | license.workspace = true 10 | homepage.workspace = true 11 | repository.workspace = true 12 | 13 | [lints] 14 | workspace = true 15 | 16 | [dependencies] 17 | foundry-common-fmt.workspace = true 18 | foundry-macros.workspace = true 19 | 20 | alloy-primitives.workspace = true 21 | alloy-sol-types = { workspace = true, features = ["json"] } 22 | 23 | derive_more.workspace = true 24 | itertools.workspace = true -------------------------------------------------------------------------------- /crates/fmt/testdata/ThisExpression/fmt.sol: -------------------------------------------------------------------------------- 1 | contract ThisExpression { 2 | function someFunc() public {} 3 | function someVeryVeryVeryLongVariableNameThatWillBeAccessedByThisKeyword() 4 | public {} 5 | 6 | function test() external { 7 | this.someFunc(); 8 | this.someVeryVeryVeryLongVariableNameThatWillBeAccessedByThisKeyword(); 9 | this // comment1 10 | .someVeryVeryVeryLongVariableNameThatWillBeAccessedByThisKeyword(); 11 | address(this).balance; 12 | 13 | address thisAddress = address( 14 | // comment2 15 | /* comment3 */ this // comment 4 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /crates/anvil/core/src/types.rs: -------------------------------------------------------------------------------- 1 | use alloy_primitives::Bytes; 2 | use alloy_rpc_types::TransactionRequest; 3 | use serde::Deserialize; 4 | 5 | /// Represents the options used in `anvil_reorg` 6 | #[derive(Debug, Clone, Deserialize)] 7 | pub struct ReorgOptions { 8 | // The depth of the reorg 9 | pub depth: u64, 10 | // List of transaction requests and blocks pairs to be mined into the new chain 11 | pub tx_block_pairs: Vec<(TransactionData, u64)>, 12 | } 13 | 14 | #[derive(Debug, Clone, Deserialize)] 15 | #[serde(untagged)] 16 | #[expect(clippy::large_enum_variant)] 17 | pub enum TransactionData { 18 | JSON(TransactionRequest), 19 | Raw(Bytes), 20 | } 21 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/SimpleContractTestNonVerbose.json: -------------------------------------------------------------------------------- 1 | { 2 | "src/Simple.t.sol:SimpleContractTest": { 3 | "duration": "{...}", 4 | "test_results": { 5 | "test()": { 6 | "status": "Success", 7 | "reason": null, 8 | "counterexample": null, 9 | "logs": [], 10 | "decoded_logs": [], 11 | "kind": { 12 | "Unit": { 13 | "gas": "{...}" 14 | } 15 | }, 16 | "traces": [], 17 | "labeled_addresses": {}, 18 | "duration": "{...}", 19 | "breakpoints": {}, 20 | "gas_snapshots": {} 21 | } 22 | }, 23 | "warnings": [] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue5808.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/5808 7 | contract Issue5808Test is Test { 8 | function testReadInt() public { 9 | string memory str1 = '["ffffffff","00000010"]'; 10 | vm._expectCheatcodeRevert(); 11 | int256[] memory ints1 = vm.parseJsonIntArray(str1, ""); 12 | 13 | string memory str2 = '["0xffffffff","0x00000010"]'; 14 | int256[] memory ints2 = vm.parseJsonIntArray(str2, ""); 15 | assertEq(ints2[0], 0xffffffff); 16 | assertEq(ints2[1], 16); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /npm/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies (bun install) 2 | node_modules 3 | 4 | # output 5 | out 6 | dist 7 | *.tgz 8 | 9 | # code coverage 10 | coverage 11 | *.lcov 12 | 13 | # logs 14 | logs 15 | _.log 16 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 17 | 18 | # dotenv environment variable files 19 | .env 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | .env.local 24 | 25 | # caches 26 | .eslintcache 27 | .cache 28 | *.tsbuildinfo 29 | 30 | # IntelliJ based IDEs 31 | .idea 32 | 33 | # Finder (MacOS) folder config 34 | .DS_Store 35 | 36 | forge/*/bin/forge 37 | anvil/*/bin/anvil 38 | cast/*/bin/cast 39 | chisel/*/bin/chisel 40 | @foundry-rs/*/bin/ 41 | _ 42 | -------------------------------------------------------------------------------- /crates/cast/tests/fixtures/cast_logs.stdout: -------------------------------------------------------------------------------- 1 | - address: 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE 2 | blockHash: 0x439b61565dacbc09a6d54378dff60d9b0400496d7a5a060cfdfdd899262f466c 3 | blockNumber: 12421182 4 | data: 0x000000000000000000000000000000000000027fd7b375dda5ef932dac18d302 5 | logIndex: 15 6 | removed: false 7 | topics: [ 8 | 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef 9 | 0x000000000000000000000000ab5801a7d398351b8be11c439e05c5b3259aec9b 10 | 0x00000000000000000000000068a99f89e475a078645f4bac491360afe255dff1 11 | ] 12 | transactionHash: 0xb65bcbb85c1633b0ab4e4886c3cd8eeaeb63edbb39cacdb9223fdcf4454fd2c7 13 | transactionIndex: 8 14 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue2723.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/2723 7 | contract Issue2723Test is Test { 8 | function testRollFork() public { 9 | address coinbase = 0x0193d941b50d91BE6567c7eE1C0Fe7AF498b4137; 10 | 11 | vm.createSelectFork("mainnet", 9); 12 | 13 | assertEq(block.number, 9); 14 | assertEq(coinbase.balance, 11250000000000000000); 15 | 16 | vm.rollFork(10); 17 | 18 | assertEq(block.number, 10); 19 | assertEq(coinbase.balance, 16250000000000000000); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue6180.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/6180 7 | contract Issue6180Test is Test { 8 | function test_timebug() external { 9 | uint256 start = block.timestamp; 10 | uint256 count = 4; 11 | uint256 duration = 15; 12 | for (uint256 i; i < count; i++) { 13 | vm.warp(block.timestamp + duration); 14 | } 15 | 16 | uint256 end = block.timestamp; 17 | assertEq(end, start + count * duration); 18 | assertEq(end - start, count * duration); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue8566.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/8566 7 | contract Issue8566Test is Test { 8 | function testParseJsonUint() public { 9 | string memory json = 10 | "{ \"1284\": { \"addRewardInfo\": { \"amount\": 74258.225772486694040708e18, \"rewardPerSec\": 0.03069536448928848133e20 } } }"; 11 | 12 | assertEq(74258225772486694040708, vm.parseJsonUint(json, ".1284.addRewardInfo.amount")); 13 | assertEq(3069536448928848133, vm.parseJsonUint(json, ".1284.addRewardInfo.rewardPerSec")); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /crates/fmt/testdata/BlockComments/tab.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: style = "tab" 2 | contract CounterTest is Test { 3 | /** 4 | * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. 5 | */ 6 | constructor(string memory name_, string memory symbol_) { 7 | _name = name_; 8 | _symbol = symbol_; 9 | } 10 | 11 | /** 12 | * @dev See {IERC721-balanceOf}. 13 | */ 14 | function test_Increment() public { 15 | counter.increment(); 16 | assertEq(counter.number(), 1); 17 | } 18 | 19 | /** 20 | * @dev See {IERC165-supportsInterface}. 21 | */ 22 | function test_Increment() public { 23 | counter.increment(); 24 | assertEq(counter.number(), 1); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /crates/forge/assets/solidity/CounterTemplate.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import {Test} from "forge-std/Test.sol"; 5 | import {Counter} from "../src/Counter.sol"; 6 | 7 | contract CounterTest is Test { 8 | Counter public counter; 9 | 10 | function setUp() public { 11 | counter = new Counter(); 12 | counter.setNumber(0); 13 | } 14 | 15 | function test_Increment() public { 16 | counter.increment(); 17 | assertEq(counter.number(), 1); 18 | } 19 | 20 | function testFuzz_SetNumber(uint256 x) public { 21 | counter.setNumber(x); 22 | assertEq(counter.number(), x); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /testdata/default/cheats/SignP256.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract SignTest is Test { 7 | function testSignP256() public { 8 | bytes32 pk = hex"A8568B74282DCC66FF70F10B4CE5CC7B391282F5381BBB4F4D8DD96974B16E6B"; 9 | bytes32 digest = hex"54705ba3baafdbdfba8c5f9a70f7a89bee98d906b53e31074da7baecdc0da9ad"; 10 | 11 | (bytes32 r, bytes32 s) = vm.signP256(uint256(pk), digest); 12 | assertEq(r, hex"7C11C3641B19E7822DB644CBF76ED0420A013928C2FD3E36D8EF983B103BDFE1"); 13 | assertEq(s, hex"317D89879868D484810D4E508A96109F8C87617B7BE9337411348D7B786F945F"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /crates/fmt/testdata/IntTypes/original.sol: -------------------------------------------------------------------------------- 1 | contract Contract { 2 | uint constant UINT256_IMPL = 0; 3 | uint8 constant UINT8 = 1; 4 | uint128 constant UINT128 = 2; 5 | uint256 constant UINT256_EXPL = 3; 6 | 7 | int constant INT256_IMPL = 4; 8 | int8 constant INT8 = 5; 9 | int128 constant INT128 = 6; 10 | int256 constant INT256_EXPL = 7; 11 | 12 | function test( 13 | uint uint256_impl, 14 | uint8 uint8_var, 15 | uint128 uint128_var, 16 | uint256 uint256_expl, 17 | int int256_impl, 18 | int8 int8_var, 19 | int128 int128_var, 20 | int256 int256_expl 21 | ) public { 22 | // do something 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /testdata/default/core/SetupConsistency.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract SetupConsistencyCheck is Test { 7 | uint256 two; 8 | uint256 four; 9 | uint256 result; 10 | 11 | function setUp() public { 12 | two = 2; 13 | four = 4; 14 | result = 0; 15 | } 16 | 17 | function testAdd() public { 18 | assertEq(result, 0); 19 | result = two + four; 20 | assertEq(result, 6); 21 | } 22 | 23 | function testMultiply() public { 24 | assertEq(result, 0); 25 | result = two * four; 26 | assertEq(result, 8); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue2984.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/2984 7 | contract Issue2984Test is Test { 8 | uint256 fork; 9 | uint256 snapshot; 10 | 11 | function setUp() public { 12 | fork = vm.createSelectFork("avaxTestnet", 12880747); 13 | snapshot = vm.snapshotState(); 14 | } 15 | 16 | function testForkRevertSnapshot() public { 17 | vm.revertToState(snapshot); 18 | } 19 | 20 | function testForkSelectSnapshot() public { 21 | uint256 fork2 = vm.createSelectFork("avaxTestnet", 12880749); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/backtraces/SimpleRevert.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | /// @title SimpleRevert - Basic revert testing contract 5 | contract SimpleRevert { 6 | function doRevert(string memory reason) public pure { 7 | revert(reason); 8 | } 9 | 10 | function doRequire(uint256 value) public pure { 11 | require(value > 0, "Value must be greater than zero"); 12 | } 13 | 14 | function doAssert() public pure { 15 | assert(false); 16 | } 17 | 18 | error CustomError(uint256 code, address sender); 19 | 20 | function doCustomError() public view { 21 | revert CustomError(42, msg.sender); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /crates/chisel/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Chisel is a fast, utilitarian, and verbose Solidity REPL. 2 | 3 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 4 | #![cfg_attr(docsrs, feature(doc_cfg))] 5 | 6 | #[macro_use] 7 | extern crate foundry_common; 8 | #[macro_use] 9 | extern crate tracing; 10 | 11 | pub mod args; 12 | 13 | pub mod cmd; 14 | 15 | pub mod dispatcher; 16 | 17 | pub mod executor; 18 | 19 | pub mod opts; 20 | 21 | pub mod runner; 22 | 23 | pub mod session; 24 | 25 | pub mod source; 26 | 27 | mod solidity_helper; 28 | pub use solidity_helper::SolidityHelper; 29 | 30 | pub mod prelude { 31 | pub use crate::{cmd::*, dispatcher::*, runner::*, session::*, solidity_helper::*, source::*}; 32 | } 33 | -------------------------------------------------------------------------------- /crates/fmt/testdata/IntTypes/fmt.sol: -------------------------------------------------------------------------------- 1 | contract Contract { 2 | uint256 constant UINT256_IMPL = 0; 3 | uint8 constant UINT8 = 1; 4 | uint128 constant UINT128 = 2; 5 | uint256 constant UINT256_EXPL = 3; 6 | 7 | int256 constant INT256_IMPL = 4; 8 | int8 constant INT8 = 5; 9 | int128 constant INT128 = 6; 10 | int256 constant INT256_EXPL = 7; 11 | 12 | function test( 13 | uint256 uint256_impl, 14 | uint8 uint8_var, 15 | uint128 uint128_var, 16 | uint256 uint256_expl, 17 | int256 int256_impl, 18 | int8 int8_var, 19 | int128 int128_var, 20 | int256 int256_expl 21 | ) public { 22 | // do something 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /crates/wallets/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # foundry-wallets 2 | //! 3 | //! Utilities for working with multiple signers. 4 | 5 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 6 | #![cfg_attr(docsrs, feature(doc_cfg))] 7 | 8 | #[macro_use] 9 | extern crate foundry_common; 10 | 11 | #[macro_use] 12 | extern crate tracing; 13 | 14 | pub mod error; 15 | pub mod opts; 16 | pub mod signer; 17 | pub mod utils; 18 | pub mod wallet_browser; 19 | pub mod wallet_multi; 20 | pub mod wallet_raw; 21 | 22 | pub use opts::WalletOpts; 23 | pub use signer::{PendingSigner, WalletSigner}; 24 | pub use wallet_multi::MultiWalletOpts; 25 | pub use wallet_raw::RawWalletOpts; 26 | 27 | #[cfg(feature = "aws-kms")] 28 | use aws_config as _; 29 | -------------------------------------------------------------------------------- /testdata/default/cheats/Addr.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract AddrTest is Test { 7 | /// forge-config: default.allow_internal_expect_revert = true 8 | function testRevertIfPkZero() public { 9 | vm.expectRevert("vm.addr: private key cannot be 0"); 10 | vm.addr(0); 11 | } 12 | 13 | function testAddr() public { 14 | uint256 pk = 77814517325470205911140941194401928579557062014761831930645393041380819009408; 15 | address expected = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266; 16 | 17 | assertEq(vm.addr(pk), expected, "expected address did not match"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/default/cheats/Deal.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract DealTest is Test { 7 | function testDeal(uint256 amount) public { 8 | address target = address(10); 9 | assertEq(target.balance, 0, "initial balance incorrect"); 10 | 11 | // Give half the amount 12 | vm.deal(target, amount / 2); 13 | assertEq(target.balance, amount / 2, "half balance is incorrect"); 14 | 15 | // Give the entire amount to check that deal is not additive 16 | vm.deal(target, amount); 17 | assertEq(target.balance, amount, "deal did not overwrite balance"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /crates/anvil/src/eth/beacon/data.rs: -------------------------------------------------------------------------------- 1 | //! Beacon data structures for the Beacon API responses 2 | 3 | use alloy_primitives::{B256, aliases::B32}; 4 | use serde::{Deserialize, Serialize}; 5 | use serde_with::{DisplayFromStr, serde_as}; 6 | 7 | /// Ethereum Beacon chain genesis details 8 | #[serde_as] 9 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] 10 | pub struct GenesisDetails { 11 | /// The genesis_time configured for the beacon chain 12 | #[serde_as(as = "DisplayFromStr")] 13 | pub genesis_time: u64, 14 | /// The genesis validators root 15 | pub genesis_validators_root: B256, 16 | /// The genesis fork version, as used in the beacon chain 17 | pub genesis_fork_version: B32, 18 | } 19 | -------------------------------------------------------------------------------- /crates/forge/assets/vyper/CounterTemplate.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import {Test} from "forge-std/Test.sol"; 5 | import {ICounter} from "../src/ICounter.sol"; 6 | 7 | contract CounterTest is Test { 8 | ICounter public counter; 9 | 10 | function setUp() public { 11 | counter = ICounter(deployCode("src/Counter.vy")); 12 | counter.setNumber(0); 13 | } 14 | 15 | function test_Increment() public { 16 | counter.increment(); 17 | assertEq(counter.number(), 1); 18 | } 19 | 20 | function testFuzz_SetNumber(uint256 x) public { 21 | counter.setNumber(x); 22 | assertEq(counter.number(), x); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /crates/forge/tests/cli/main.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate foundry_test_utils; 3 | 4 | pub mod constants; 5 | pub mod utils; 6 | 7 | mod backtrace; 8 | mod bind; 9 | mod bind_json; 10 | mod build; 11 | mod cache; 12 | mod cmd; 13 | mod compiler; 14 | mod config; 15 | mod context; 16 | mod coverage; 17 | mod create; 18 | mod debug; 19 | mod doc; 20 | mod eip712; 21 | mod failure_assertions; 22 | mod inline_config; 23 | mod install; 24 | mod json; 25 | mod lint; 26 | mod multi_script; 27 | mod precompiles; 28 | mod script; 29 | mod soldeer; 30 | mod svm; 31 | mod test_cmd; 32 | mod verify; 33 | mod verify_bytecode; 34 | mod version; 35 | 36 | mod ext_integration; 37 | mod fmt; 38 | mod fmt_integration; 39 | mod test_optimizer; 40 | -------------------------------------------------------------------------------- /crates/evm/coverage/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foundry-evm-coverage" 3 | description = "EVM bytecode coverage analysis" 4 | 5 | version.workspace = true 6 | edition.workspace = true 7 | rust-version.workspace = true 8 | authors.workspace = true 9 | license.workspace = true 10 | homepage.workspace = true 11 | repository.workspace = true 12 | 13 | [lints] 14 | workspace = true 15 | 16 | [dependencies] 17 | foundry-common.workspace = true 18 | foundry-compilers.workspace = true 19 | foundry-evm-core.workspace = true 20 | 21 | alloy-primitives.workspace = true 22 | eyre.workspace = true 23 | revm.workspace = true 24 | semver.workspace = true 25 | tracing.workspace = true 26 | rayon.workspace = true 27 | solar.workspace = true 28 | -------------------------------------------------------------------------------- /crates/fmt/testdata/BlockCommentsFunction/tab.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: style = "tab" 2 | contract A { 3 | Counter public counter; 4 | /** 5 | * TODO: this fuzz use too much time to execute 6 | * function testGetFuzz(bytes[2][] memory kvs) public { 7 | * for (uint256 i = 0; i < kvs.length; i++) { 8 | * bytes32 root = trie.update(kvs[i][0], kvs[i][1]); 9 | * console.logBytes32(root); 10 | * } 11 | * 12 | * for (uint256 i = 0; i < kvs.length; i++) { 13 | * (bool exist, bytes memory value) = trie.get(kvs[i][0]); 14 | * console.logBool(exist); 15 | * console.logBytes(value); 16 | * require(exist); 17 | * require(BytesSlice.equal(value, trie.getRaw(kvs[i][0]))); 18 | * } 19 | * } 20 | */ 21 | } 22 | -------------------------------------------------------------------------------- /crates/fmt/testdata/IntTypes/short.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: int_types = "short" 2 | contract Contract { 3 | uint constant UINT256_IMPL = 0; 4 | uint8 constant UINT8 = 1; 5 | uint128 constant UINT128 = 2; 6 | uint constant UINT256_EXPL = 3; 7 | 8 | int constant INT256_IMPL = 4; 9 | int8 constant INT8 = 5; 10 | int128 constant INT128 = 6; 11 | int constant INT256_EXPL = 7; 12 | 13 | function test( 14 | uint uint256_impl, 15 | uint8 uint8_var, 16 | uint128 uint128_var, 17 | uint uint256_expl, 18 | int int256_impl, 19 | int8 int8_var, 20 | int128 int128_var, 21 | int int256_expl 22 | ) public { 23 | // do something 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /testdata/default/cheats/Derive.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract DeriveTest is Test { 7 | function testDerive() public { 8 | string memory mnemonic = "test test test test test test test test test test test junk"; 9 | 10 | uint256 privateKey = vm.deriveKey(mnemonic, 0); 11 | assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); 12 | 13 | uint256 privateKeyDerivationPathChanged = vm.deriveKey(mnemonic, "m/44'/60'/0'/1/", 0); 14 | assertEq(privateKeyDerivationPathChanged, 0x6abb89895f93b02c1b9470db0fa675297f6cca832a5fc66d5dfd7661a42b37be); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /testdata/default/cheats/Etch.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract EtchTest is Test { 7 | function testEtch() public { 8 | address target = address(7070707); 9 | bytes memory code = hex"1010"; 10 | vm.etch(target, code); 11 | assertEq(string(code), string(target.code)); 12 | } 13 | 14 | function testEtchNotAvailableOnPrecompiles() public { 15 | address target = address(1); 16 | bytes memory code = hex"1010"; 17 | vm._expectCheatcodeRevert("cannot use precompile 0x0000000000000000000000000000000000000001 as an argument"); 18 | vm.etch(target, code); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /crates/evm/evm/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # foundry-evm 2 | //! 3 | //! Main Foundry EVM backend abstractions. 4 | 5 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 6 | #![cfg_attr(docsrs, feature(doc_cfg))] 7 | 8 | #[macro_use] 9 | extern crate tracing; 10 | 11 | pub mod executors; 12 | pub mod inspectors; 13 | 14 | pub use foundry_evm_core as core; 15 | pub use foundry_evm_core::{ 16 | Env, EnvMut, EvmEnv, InspectorExt, backend, constants, decode, fork, opts, utils, 17 | }; 18 | pub use foundry_evm_coverage as coverage; 19 | pub use foundry_evm_fuzz as fuzz; 20 | pub use foundry_evm_traces as traces; 21 | 22 | // TODO: We should probably remove these, but it's a pretty big breaking change. 23 | #[doc(hidden)] 24 | pub use revm; 25 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue6616.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/6616 7 | contract Issue6616Test is Test { 8 | function testCreateForkRollLatestBlock() public { 9 | vm.createSelectFork("mainnet"); 10 | uint256 startBlock = block.number; 11 | // this will create new forks and exit once a new latest block is found 12 | for (uint256 i; i < 10; i++) { 13 | vm.sleep(5000); 14 | vm.createSelectFork("mainnet"); 15 | if (block.number > startBlock) break; 16 | } 17 | assertGt(block.number, startBlock); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /crates/fmt/testdata/BlockComments/fmt.sol: -------------------------------------------------------------------------------- 1 | contract CounterTest is Test { 2 | /** 3 | * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. 4 | */ 5 | constructor(string memory name_, string memory symbol_) { 6 | _name = name_; 7 | _symbol = symbol_; 8 | } 9 | 10 | /** 11 | * @dev See {IERC721-balanceOf}. 12 | */ 13 | function test_Increment() public { 14 | counter.increment(); 15 | assertEq(counter.number(), 1); 16 | } 17 | 18 | /** 19 | * @dev See {IERC165-supportsInterface}. 20 | */ 21 | function test_Increment() public { 22 | counter.increment(); 23 | assertEq(counter.number(), 1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /testdata/default/cheats/Blobhashes.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.25; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract BlobhashesTest is Test { 7 | function testSetAndGetBlobhashes() public { 8 | bytes32[] memory blobhashes = new bytes32[](2); 9 | blobhashes[0] = bytes32(0x0000000000000000000000000000000000000000000000000000000000000001); 10 | blobhashes[1] = bytes32(0x0000000000000000000000000000000000000000000000000000000000000002); 11 | vm.blobhashes(blobhashes); 12 | 13 | bytes32[] memory gotBlobhashes = vm.getBlobhashes(); 14 | assertEq(gotBlobhashes[0], blobhashes[0]); 15 | assertEq(gotBlobhashes[1], blobhashes[1]); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /crates/fmt/testdata/BlockComments/original.sol: -------------------------------------------------------------------------------- 1 | contract CounterTest is Test { 2 | /** 3 | * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. 4 | */ 5 | 6 | constructor(string memory name_, string memory symbol_) { 7 | _name = name_; 8 | _symbol = symbol_; 9 | } 10 | 11 | /** 12 | * @dev See {IERC721-balanceOf}. 13 | */ 14 | function test_Increment() public { 15 | counter.increment(); 16 | assertEq(counter.number(), 1); 17 | } 18 | 19 | /** 20 | * @dev See {IERC165-supportsInterface}. 21 | */ function test_Increment() public { 22 | counter.increment(); 23 | assertEq(counter.number(), 1); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /crates/fmt/testdata/IntTypes/preserve.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: int_types = "preserve" 2 | contract Contract { 3 | uint constant UINT256_IMPL = 0; 4 | uint8 constant UINT8 = 1; 5 | uint128 constant UINT128 = 2; 6 | uint256 constant UINT256_EXPL = 3; 7 | 8 | int constant INT256_IMPL = 4; 9 | int8 constant INT8 = 5; 10 | int128 constant INT128 = 6; 11 | int256 constant INT256_EXPL = 7; 12 | 13 | function test( 14 | uint uint256_impl, 15 | uint8 uint8_var, 16 | uint128 uint128_var, 17 | uint256 uint256_expl, 18 | int int256_impl, 19 | int8 int8_var, 20 | int128 int128_var, 21 | int256 int256_expl 22 | ) public { 23 | // do something 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /testdata/default/cheats/Warp.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract WarpTest is Test { 7 | function testWarp() public { 8 | vm.warp(10); 9 | assertEq(vm.getBlockTimestamp(), 10, "warp failed"); 10 | } 11 | 12 | function testWarpFuzzed(uint32 jump) public { 13 | uint256 pre = vm.getBlockTimestamp(); 14 | vm.warp(vm.getBlockTimestamp() + jump); 15 | assertEq(vm.getBlockTimestamp(), pre + jump, "warp failed"); 16 | } 17 | 18 | function testWarp2() public { 19 | assertEq(vm.getBlockTimestamp(), 1); 20 | vm.warp(100); 21 | assertEq(vm.getBlockTimestamp(), 100); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /crates/cheatcodes/spec/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foundry-cheatcodes-spec" 3 | description = "Foundry cheatcodes specification" 4 | 5 | version.workspace = true 6 | edition.workspace = true 7 | rust-version.workspace = true 8 | authors.workspace = true 9 | license.workspace = true 10 | homepage.workspace = true 11 | repository.workspace = true 12 | exclude.workspace = true 13 | 14 | [lints] 15 | workspace = true 16 | 17 | [dependencies] 18 | foundry-macros.workspace = true 19 | alloy-sol-types = { workspace = true, features = ["json"] } 20 | serde.workspace = true 21 | 22 | # schema 23 | schemars = { version = "1.0", optional = true } 24 | 25 | [dev-dependencies] 26 | serde_json.workspace = true 27 | 28 | [features] 29 | schema = ["dep:schemars"] 30 | -------------------------------------------------------------------------------- /crates/script-sequence/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "forge-script-sequence" 3 | description = "Script sequence types" 4 | 5 | version.workspace = true 6 | edition.workspace = true 7 | rust-version.workspace = true 8 | authors.workspace = true 9 | license.workspace = true 10 | homepage.workspace = true 11 | repository.workspace = true 12 | 13 | [lints] 14 | workspace = true 15 | 16 | [dependencies] 17 | foundry-config.workspace = true 18 | foundry-common.workspace = true 19 | foundry-compilers.workspace = true 20 | 21 | serde.workspace = true 22 | eyre.workspace = true 23 | serde_json.workspace = true 24 | walkdir.workspace = true 25 | 26 | revm-inspectors.workspace = true 27 | 28 | alloy-primitives.workspace = true 29 | alloy-network.workspace = true 30 | -------------------------------------------------------------------------------- /crates/fmt/testdata/BlockCommentsFunction/original.sol: -------------------------------------------------------------------------------- 1 | contract A { 2 | Counter public counter; 3 | /** 4 | * TODO: this fuzz use too much time to execute 5 | function testGetFuzz(bytes[2][] memory kvs) public { 6 | for (uint256 i = 0; i < kvs.length; i++) { 7 | bytes32 root = trie.update(kvs[i][0], kvs[i][1]); 8 | console.logBytes32(root); 9 | } 10 | 11 | for (uint256 i = 0; i < kvs.length; i++) { 12 | (bool exist, bytes memory value) = trie.get(kvs[i][0]); 13 | console.logBool(exist); 14 | console.logBytes(value); 15 | require(exist); 16 | require(BytesSlice.equal(value, trie.getRaw(kvs[i][0]))); 17 | } 18 | } 19 | */ 20 | } -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/backtraces/NestedCalls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | /// @title NestedCalls - Testing nested call stack traces 5 | contract NestedCalls { 6 | uint256 public depth; 7 | 8 | function nestedCall(uint256 maxDepth) public { 9 | depth++; 10 | if (depth >= maxDepth) { 11 | revert("Maximum depth reached"); 12 | } 13 | this.nestedCall(maxDepth); 14 | } 15 | 16 | function callChain1() public pure { 17 | callChain2(); 18 | } 19 | 20 | function callChain2() internal pure { 21 | callChain3(); 22 | } 23 | 24 | function callChain3() internal pure { 25 | revert("Failed at chain level 3"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /crates/cli/README.md: -------------------------------------------------------------------------------- 1 | # Foundry CLIs 2 | 3 | The CLIs are written using [clap's](https://docs.rs/clap) [derive feature](https://docs.rs/clap/latest/clap/_derive). 4 | 5 | ## Installation 6 | 7 | See [Installation](../../README.md#Installation). 8 | 9 | ## Usage 10 | 11 | Read the [📖 Foundry Book][foundry-book] 12 | 13 | ## Debugging 14 | 15 | Debug logs are printed with 16 | [`tracing`](https://docs.rs/tracing/latest/tracing/). You can configure the 17 | verbosity level via the 18 | [`RUST_LOG`](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/index.html#filtering-events-with-environment-variables) 19 | environment variable, on a per package level, 20 | e.g.:`RUST_LOG=forge,foundry_evm forge test` 21 | 22 | [foundry-book]: https://book.getfoundry.sh 23 | -------------------------------------------------------------------------------- /testdata/default/cheats/Base64.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract Base64Test is Test { 7 | function test_toBase64() public { 8 | bytes memory input = hex"00112233445566778899aabbccddeeff"; 9 | string memory expected = "ABEiM0RVZneImaq7zN3u/w=="; 10 | string memory actual = vm.toBase64(input); 11 | assertEq(actual, expected); 12 | } 13 | 14 | function test_toBase64URL() public { 15 | bytes memory input = hex"00112233445566778899aabbccddeeff"; 16 | string memory expected = "ABEiM0RVZneImaq7zN3u_w=="; 17 | string memory actual = vm.toBase64URL(input); 18 | assertEq(actual, expected); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ImportDirective/original.sol: -------------------------------------------------------------------------------- 1 | import "SomeFile.sol"; 2 | import 'SomeFile.sol'; 3 | import "SomeFile.sol" as SomeOtherFile; 4 | import 'SomeFile.sol' as SomeOtherFile; 5 | import * as SomeSymbol from "AnotherFile.sol"; 6 | import * as SomeSymbol from 'AnotherFile.sol'; 7 | import {symbol1 as alias0, symbol2} from "File.sol"; 8 | import {symbol1 as alias0, symbol2} from 'File.sol'; 9 | import {symbol1 as alias1, symbol2 as alias2, symbol3 as alias3, symbol4} from "File2.sol"; 10 | import {symbol1 as alias1, symbol2 as alias2, symbol3 as alias3, symbol4} from 'File2.sol'; 11 | 12 | // Single import that exceeds line length (121 chars) 13 | import { ITransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; 14 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue6966.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/6966 7 | // See also https://github.com/RustCrypto/elliptic-curves/issues/988#issuecomment-1817681013 8 | contract Issue6966Test is Test { 9 | function testEcrecover() public { 10 | bytes32 h = 0x0000000000000000000000000000000000000000000000000000000000000000; 11 | uint8 v = 27; 12 | bytes32 r = bytes32(0xf87fff3202dfeae34ce9cb8151ce2e176bee02a937baac6de85c4ea03d6a6618); 13 | bytes32 s = bytes32(0xedf9ab5c7d3ec1df1c2b48600ab0a35f586e069e9a69c6cdeebc99920128d1a5); 14 | assert(ecrecover(h, v, r, s) != address(0)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /crates/fmt/testdata/DoWhileStatement/fmt.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.8; 2 | 3 | contract DoWhileStatement { 4 | function test() external { 5 | uint256 i; 6 | do { 7 | "test"; 8 | } while (i != 0); 9 | 10 | do {} while (i != 0); 11 | 12 | bool someVeryVeryLongCondition; 13 | do { 14 | "test"; 15 | } while ( 16 | someVeryVeryLongCondition && !someVeryVeryLongCondition 17 | && !someVeryVeryLongCondition && someVeryVeryLongCondition 18 | ); 19 | 20 | do { 21 | i++; 22 | } while (i < 10); 23 | 24 | do { 25 | do { 26 | i++; 27 | } while (i < 30); 28 | } while (i < 20); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue2629.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/2629 7 | contract Issue2629Test is Test { 8 | function testSelectFork() public { 9 | address coinbase = 0x0193d941b50d91BE6567c7eE1C0Fe7AF498b4137; 10 | 11 | uint256 f1 = vm.createSelectFork("mainnet", 9); 12 | vm.selectFork(f1); 13 | 14 | assertEq(block.number, 9); 15 | assertEq(coinbase.balance, 11250000000000000000); 16 | 17 | uint256 f2 = vm.createFork("mainnet", 10); 18 | vm.selectFork(f2); 19 | 20 | assertEq(block.number, 10); 21 | assertEq(coinbase.balance, 16250000000000000000); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue2898.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/2898 7 | contract Issue2898Test is Test { 8 | address private constant BRIDGE = address(10); 9 | address private constant BENEFICIARY = address(11); 10 | 11 | function setUp() public { 12 | vm.deal(BRIDGE, 100); 13 | vm.deal(BENEFICIARY, 99); 14 | 15 | vm.setNonce(BRIDGE, 10); 16 | } 17 | 18 | function testDealBalance() public { 19 | assertEq(BRIDGE.balance, 100); 20 | assertEq(BENEFICIARY.balance, 99); 21 | } 22 | 23 | function testSetNonce() public { 24 | assertEq(vm.getNonce(BRIDGE), 10); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /testdata/fixtures/Rpc/README.md: -------------------------------------------------------------------------------- 1 | # Fixture Generation Instructions 2 | 3 | ### `eth_getLogs.json` 4 | 5 | To generate this fixture, send a POST request to a Eth Mainnet (chainId = 1) RPC 6 | 7 | ``` 8 | { 9 | "jsonrpc": "2.0", 10 | "method": "eth_getLogs", 11 | "id": "1", 12 | "params": [ 13 | { 14 | "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", 15 | "fromBlock": "0x10CEB1B", 16 | "toBlock": "0x10CEB1B", 17 | "topics": [ 18 | "0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65" 19 | ] 20 | } 21 | ] 22 | } 23 | ``` 24 | 25 | Then you must change the `address` key to `emitter` because in Solidity, a struct's name cannot be `address` as that is a keyword. 26 | -------------------------------------------------------------------------------- /crates/evm/core/src/fork/mod.rs: -------------------------------------------------------------------------------- 1 | use super::opts::EvmOpts; 2 | use crate::Env; 3 | 4 | mod init; 5 | pub use init::{configure_env, environment}; 6 | 7 | pub mod database; 8 | 9 | mod multi; 10 | pub use multi::{ForkId, MultiFork, MultiForkHandler}; 11 | 12 | /// Represents a _fork_ of a remote chain whose data is available only via the `url` endpoint. 13 | #[derive(Clone, Debug)] 14 | pub struct CreateFork { 15 | /// Whether to enable rpc storage caching for this fork 16 | pub enable_caching: bool, 17 | /// The URL to a node for fetching remote state 18 | pub url: String, 19 | /// The env to create this fork, main purpose is to provide some metadata for the fork 20 | pub env: Env, 21 | /// All env settings as configured by the user 22 | pub evm_opts: EvmOpts, 23 | } 24 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue4630.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/4630 7 | contract Issue4630Test is Test { 8 | function testExistingValue() public { 9 | string memory path = "fixtures/Json/Issue4630.json"; 10 | string memory json = vm.readFile(path); 11 | uint256 val = vm.parseJsonUint(json, ".local.prop1"); 12 | assertEq(val, 10); 13 | } 14 | 15 | function testMissingValue() public { 16 | string memory path = "fixtures/Json/Issue4630.json"; 17 | string memory json = vm.readFile(path); 18 | vm._expectCheatcodeRevert(); 19 | vm.parseJsonUint(json, ".localempty.prop1"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /crates/fmt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "forge-fmt" 3 | 4 | version.workspace = true 5 | edition.workspace = true 6 | rust-version.workspace = true 7 | authors.workspace = true 8 | license.workspace = true 9 | homepage.workspace = true 10 | repository.workspace = true 11 | 12 | [lints] 13 | workspace = true 14 | 15 | [dependencies] 16 | foundry-config.workspace = true 17 | foundry-common.workspace = true 18 | 19 | solar.workspace = true 20 | 21 | itertools.workspace = true 22 | similar = { version = "2", features = ["inline"] } 23 | 24 | [dev-dependencies] 25 | foundry-test-utils.workspace = true 26 | 27 | itertools.workspace = true 28 | similar-asserts.workspace = true 29 | toml.workspace = true 30 | tracing-subscriber = { workspace = true, features = ["env-filter"] } 31 | snapbox.workspace = true 32 | -------------------------------------------------------------------------------- /crates/fmt/testdata/BlockCommentsFunction/fmt.sol: -------------------------------------------------------------------------------- 1 | contract A { 2 | Counter public counter; 3 | /** 4 | * TODO: this fuzz use too much time to execute 5 | * function testGetFuzz(bytes[2][] memory kvs) public { 6 | * for (uint256 i = 0; i < kvs.length; i++) { 7 | * bytes32 root = trie.update(kvs[i][0], kvs[i][1]); 8 | * console.logBytes32(root); 9 | * } 10 | * 11 | * for (uint256 i = 0; i < kvs.length; i++) { 12 | * (bool exist, bytes memory value) = trie.get(kvs[i][0]); 13 | * console.logBool(exist); 14 | * console.logBytes(value); 15 | * require(exist); 16 | * require(BytesSlice.equal(value, trie.getRaw(kvs[i][0]))); 17 | * } 18 | * } 19 | */ 20 | } 21 | -------------------------------------------------------------------------------- /crates/sol-macro-gen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "forge-sol-macro-gen" 3 | description = "Contains types and methods for generating rust bindings using sol!" 4 | publish = false 5 | 6 | version.workspace = true 7 | edition.workspace = true 8 | rust-version.workspace = true 9 | authors.workspace = true 10 | license.workspace = true 11 | homepage.workspace = true 12 | repository.workspace = true 13 | 14 | [lints] 15 | workspace = true 16 | 17 | [dependencies] 18 | alloy-sol-macro-input.workspace = true 19 | alloy-sol-macro-expander = { workspace = true, features = ["json"] } 20 | foundry-common.workspace = true 21 | 22 | proc-macro2.workspace = true 23 | quote.workspace = true 24 | syn.workspace = true 25 | prettyplease.workspace = true 26 | 27 | eyre.workspace = true 28 | 29 | heck.workspace = true 30 | -------------------------------------------------------------------------------- /testdata/default/linking/simple/Simple.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // Linking scenario: contract with one library 7 | 8 | library Lib { 9 | function plus100(uint256 a) public pure returns (uint256) { 10 | return a + 100; 11 | } 12 | } 13 | 14 | contract LibraryConsumer { 15 | function consume(uint256 a) public pure returns (uint256) { 16 | return Lib.plus100(a); 17 | } 18 | } 19 | 20 | contract SimpleLibraryLinkingTest is Test { 21 | LibraryConsumer consumer; 22 | 23 | function setUp() public { 24 | consumer = new LibraryConsumer(); 25 | } 26 | 27 | function testCall() public { 28 | assertEq(consumer.consume(1), 101, "library call failed"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /crates/debugger/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foundry-debugger" 3 | 4 | version.workspace = true 5 | edition.workspace = true 6 | rust-version.workspace = true 7 | authors.workspace = true 8 | license.workspace = true 9 | homepage.workspace = true 10 | repository.workspace = true 11 | 12 | [lints] 13 | workspace = true 14 | 15 | [dependencies] 16 | foundry-common.workspace = true 17 | foundry-compilers.workspace = true 18 | foundry-evm-traces.workspace = true 19 | foundry-evm-core.workspace = true 20 | revm-inspectors.workspace = true 21 | 22 | alloy-primitives.workspace = true 23 | 24 | crossterm = "0.29" 25 | eyre.workspace = true 26 | ratatui = { version = "0.29", default-features = false, features = [ 27 | "crossterm", 28 | ] } 29 | revm.workspace = true 30 | tracing.workspace = true 31 | serde.workspace = true 32 | -------------------------------------------------------------------------------- /testdata/default/cheats/Nonce.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract Counter { 7 | uint256 public count; 8 | 9 | function increment() public { 10 | count += 1; 11 | } 12 | } 13 | 14 | /// forge-config: default.isolate = true 15 | contract NonceIsolatedTest is Test { 16 | function testIncrementNonce() public { 17 | address bob = address(14); 18 | vm.startPrank(bob); 19 | Counter counter = new Counter(); 20 | assertEq(vm.getNonce(bob), 1); 21 | counter.increment(); 22 | assertEq(vm.getNonce(bob), 2); 23 | new Counter(); 24 | assertEq(vm.getNonce(bob), 3); 25 | counter.increment(); 26 | assertEq(vm.getNonce(bob), 4); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue3792.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/DSTest.sol"; 5 | import "utils/Vm.sol"; 6 | 7 | contract Config { 8 | address public test = 0xcBa28b38103307Ec8dA98377ffF9816C164f9AFa; 9 | } 10 | 11 | contract TestSetup is Config, DSTest { 12 | Vm constant vm = Vm(HEVM_ADDRESS); 13 | 14 | // More context: the inheritance order causes the _failed flag 15 | // that is usually checked on snapshots to be shifted. 16 | // We now check for keccak256("failed") on the hevm address. 17 | // This test should succeed. 18 | function testSnapshotStorageShift() public { 19 | uint256 snapshotId = vm.snapshotState(); 20 | 21 | vm.prank(test); 22 | 23 | vm.revertToState(snapshotId); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /crates/cast/src/cmd/mod.rs: -------------------------------------------------------------------------------- 1 | //! `cast` subcommands. 2 | //! 3 | //! All subcommands should respect the `foundry_config::Config`. 4 | //! If a subcommand accepts values that are supported by the `Config`, then the subcommand should 5 | //! implement `figment::Provider` which allows the subcommand to override the config's defaults, see 6 | //! [`foundry_config::Config`]. 7 | 8 | pub mod access_list; 9 | pub mod artifact; 10 | pub mod b2e_payload; 11 | pub mod bind; 12 | pub mod call; 13 | pub mod constructor_args; 14 | pub mod create2; 15 | pub mod creation_code; 16 | pub mod da_estimate; 17 | pub mod erc20; 18 | pub mod estimate; 19 | pub mod find_block; 20 | pub mod interface; 21 | pub mod logs; 22 | pub mod mktx; 23 | pub mod rpc; 24 | pub mod run; 25 | pub mod send; 26 | pub mod storage; 27 | pub mod txpool; 28 | pub mod wallet; 29 | -------------------------------------------------------------------------------- /crates/config/src/vyper.rs: -------------------------------------------------------------------------------- 1 | //! Vyper specific configuration types. 2 | 3 | use foundry_compilers::artifacts::vyper::VyperOptimizationMode; 4 | use serde::{Deserialize, Serialize}; 5 | use std::path::PathBuf; 6 | 7 | #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] 8 | pub struct VyperConfig { 9 | /// Vyper optimization mode. "gas", "none" or "codesize" 10 | #[serde(default, skip_serializing_if = "Option::is_none")] 11 | pub optimize: Option, 12 | /// The Vyper instance to use if any. 13 | #[serde(default, skip_serializing_if = "Option::is_none")] 14 | pub path: Option, 15 | /// Optionally enables experimental Venom pipeline 16 | #[serde(default, skip_serializing_if = "Option::is_none")] 17 | pub experimental_codegen: Option, 18 | } 19 | -------------------------------------------------------------------------------- /crates/doc/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! The module for generating Solidity documentation. 2 | //! 3 | //! See [`DocBuilder`]. 4 | 5 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 6 | #![cfg_attr(docsrs, feature(doc_cfg))] 7 | 8 | #[macro_use] 9 | extern crate foundry_common; 10 | 11 | #[macro_use] 12 | extern crate tracing; 13 | 14 | mod builder; 15 | pub use builder::DocBuilder; 16 | 17 | mod document; 18 | pub use document::Document; 19 | 20 | mod helpers; 21 | 22 | mod parser; 23 | pub use parser::{ 24 | Comment, CommentTag, Comments, CommentsRef, ParseItem, ParseSource, Parser, error, 25 | }; 26 | 27 | mod preprocessor; 28 | pub use preprocessor::*; 29 | 30 | mod writer; 31 | pub use writer::{AsDoc, AsDocResult, BufWriter, Markdown}; 32 | 33 | pub use mdbook; 34 | 35 | // old formatter dependencies 36 | pub mod solang_ext; 37 | -------------------------------------------------------------------------------- /crates/evm/evm/src/inspectors/mod.rs: -------------------------------------------------------------------------------- 1 | //! EVM inspectors. 2 | 3 | pub use foundry_cheatcodes::{self as cheatcodes, Cheatcodes, CheatsConfig}; 4 | pub use foundry_evm_coverage::LineCoverageCollector; 5 | pub use foundry_evm_fuzz::Fuzzer; 6 | pub use foundry_evm_traces::{StackSnapshotType, TracingInspector, TracingInspectorConfig}; 7 | 8 | pub use revm_inspectors::access_list::AccessListInspector; 9 | 10 | mod custom_printer; 11 | pub use custom_printer::CustomPrintTracer; 12 | 13 | mod chisel_state; 14 | pub use chisel_state::ChiselState; 15 | 16 | mod logs; 17 | pub use logs::LogCollector; 18 | 19 | mod script; 20 | pub use script::ScriptExecutionInspector; 21 | 22 | mod stack; 23 | pub use stack::{InspectorData, InspectorStack, InspectorStackBuilder}; 24 | 25 | mod revert_diagnostic; 26 | pub use revert_diagnostic::RevertDiagnostic; 27 | -------------------------------------------------------------------------------- /crates/forge/tests/cli/bind.rs: -------------------------------------------------------------------------------- 1 | // 2 | forgetest!(bind_unlinked_bytecode, |prj, cmd| { 3 | prj.add_source( 4 | "SomeLibContract.sol", 5 | r#" 6 | library SomeLib { 7 | function add(uint256 a, uint256 b) external pure returns (uint256) { 8 | return a + b; 9 | } 10 | } 11 | 12 | contract SomeLibContract { 13 | function add(uint256 a, uint256 b) public pure returns (uint256) { 14 | return SomeLib.add(a, b); 15 | } 16 | } 17 | "#, 18 | ); 19 | cmd.args(["bind", "--select", "SomeLibContract"]).assert_success().stdout_eq(str![[r#" 20 | [COMPILING_FILES] with [SOLC_VERSION] 21 | [SOLC_VERSION] [ELAPSED] 22 | Compiler run successful! 23 | Generating bindings for 1 contracts 24 | Bindings have been generated to [..] 25 | "#]]); 26 | }); 27 | -------------------------------------------------------------------------------- /crates/fmt/testdata/UnitExpression/original.sol: -------------------------------------------------------------------------------- 1 | contract UnitExpression { 2 | function test() external { 3 | uint256 timestamp; 4 | timestamp = 1 seconds; 5 | timestamp = 1 minutes; 6 | timestamp = 1 hours; 7 | timestamp = 1 days; 8 | timestamp = 1 weeks; 9 | 10 | uint256 value; 11 | value = 1 wei; 12 | value = 1 gwei; 13 | value = 1 ether; 14 | 15 | uint256 someVeryVeryVeryLongVariableNameForTheMultiplierForEtherValue; 16 | 17 | value = someVeryVeryVeryLongVariableNameForTheMultiplierForEtherValue * 1 ether; 18 | value = someVeryVeryVeryLongVariableNameForTheMultiplierForEtherValue * 1 /* comment1 */ ether; // comment2 19 | 20 | value = 1 // comment3 21 | // comment4 22 | ether; // comment5 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /crates/test-utils/src/fd_lock.rs: -------------------------------------------------------------------------------- 1 | //! File locking utilities. 2 | 3 | use crate::util::pretty_err; 4 | use std::{ 5 | fs::{File, OpenOptions}, 6 | path::Path, 7 | }; 8 | 9 | pub use fd_lock::*; 10 | 11 | /// Creates a new lock file at the given path. 12 | pub fn new_lock(lock_path: impl AsRef) -> RwLock { 13 | fn new_lock(lock_path: &Path) -> RwLock { 14 | let lock_file = pretty_err( 15 | lock_path, 16 | OpenOptions::new().read(true).write(true).create(true).truncate(false).open(lock_path), 17 | ); 18 | RwLock::new(lock_file) 19 | } 20 | new_lock(lock_path.as_ref()) 21 | } 22 | 23 | pub(crate) const LOCK_TOKEN: &[u8] = b"1"; 24 | 25 | pub(crate) fn lock_exists(lock_path: &Path) -> bool { 26 | std::fs::read(lock_path).is_ok_and(|b| b == LOCK_TOKEN) 27 | } 28 | -------------------------------------------------------------------------------- /crates/wallets/src/wallet_browser/error.rs: -------------------------------------------------------------------------------- 1 | use alloy_signer::Error as SignerError; 2 | 3 | #[derive(Debug, thiserror::Error)] 4 | pub enum BrowserWalletError { 5 | #[error("{operation} request timed out")] 6 | Timeout { operation: &'static str }, 7 | 8 | #[error("{operation} rejected: {reason}")] 9 | Rejected { operation: &'static str, reason: String }, 10 | 11 | #[error("Wallet not connected")] 12 | NotConnected, 13 | 14 | #[error("Server error: {0}")] 15 | ServerError(String), 16 | } 17 | 18 | impl From for SignerError { 19 | fn from(err: BrowserWalletError) -> Self { 20 | Self::other(err) 21 | } 22 | } 23 | 24 | impl From for BrowserWalletError { 25 | fn from(err: SignerError) -> Self { 26 | Self::ServerError(err.to_string()) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /testdata/default/cheats/RandomUint.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract RandomUint is Test { 7 | function testRandomUint() public { 8 | vm.randomUint(); 9 | } 10 | 11 | function testRandomUintRangeOverflow() public { 12 | vm.randomUint(0, uint256(int256(-1))); 13 | } 14 | 15 | function testRandomUintSame(uint256 val) public { 16 | uint256 rand = vm.randomUint(val, val); 17 | assertTrue(rand == val); 18 | } 19 | 20 | function testRandomUintRange(uint256 min, uint256 max) public { 21 | vm.assume(max >= min); 22 | uint256 rand = vm.randomUint(min, max); 23 | assertTrue(rand >= min, "rand >= min"); 24 | assertTrue(rand <= max, "rand <= max"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ImportDirective/fmt.sol: -------------------------------------------------------------------------------- 1 | import "SomeFile.sol"; 2 | import "SomeFile.sol"; 3 | import "SomeFile.sol" as SomeOtherFile; 4 | import "SomeFile.sol" as SomeOtherFile; 5 | import "AnotherFile.sol" as SomeSymbol; 6 | import "AnotherFile.sol" as SomeSymbol; 7 | import {symbol1 as alias0, symbol2} from "File.sol"; 8 | import {symbol1 as alias0, symbol2} from "File.sol"; 9 | import { 10 | symbol1 as alias1, 11 | symbol2 as alias2, 12 | symbol3 as alias3, 13 | symbol4 14 | } from "File2.sol"; 15 | import { 16 | symbol1 as alias1, 17 | symbol2 as alias2, 18 | symbol3 as alias3, 19 | symbol4 20 | } from "File2.sol"; 21 | 22 | // Single import that exceeds line length (121 chars) 23 | import { 24 | ITransparentUpgradeableProxy 25 | } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; 26 | -------------------------------------------------------------------------------- /testdata/default/cheats/GetBlockTimestamp.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract GetBlockTimestampTest is Test { 7 | function testGetTimestamp() public { 8 | uint256 timestamp = vm.getBlockTimestamp(); 9 | assertEq(timestamp, 1, "timestamp should be 1"); 10 | } 11 | 12 | function testGetTimestampWithWarp() public { 13 | assertEq(vm.getBlockTimestamp(), 1, "timestamp should be 1"); 14 | vm.warp(10); 15 | assertEq(vm.getBlockTimestamp(), 10, "warp failed"); 16 | } 17 | 18 | function testGetTimestampWithWarpFuzzed(uint32 jump) public { 19 | uint256 pre = vm.getBlockTimestamp(); 20 | vm.warp(pre + jump); 21 | assertEq(vm.getBlockTimestamp(), pre + jump, "warp failed"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testdata/default/inline/FuzzInlineConf.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract FuzzInlineConf is Test { 7 | /** 8 | * forge-config: default.fuzz.runs = 1024 9 | * forge-config: default.fuzz.max-test-rejects = 500 10 | */ 11 | function testInlineConfFuzz(uint8 x) public { 12 | require(true, "this is not going to revert"); 13 | } 14 | } 15 | 16 | /// forge-config: default.fuzz.runs = 10 17 | contract FuzzInlineConf2 is Test { 18 | /// forge-config: default.fuzz.runs = 1 19 | function testInlineConfFuzz1(uint8 x) public { 20 | require(true, "this is not going to revert"); 21 | } 22 | 23 | function testInlineConfFuzz2(uint8 x) public { 24 | require(true, "this is not going to revert"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /testdata/paris/spec/ShanghaiCompat.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract ShanghaiCompat is Test { 7 | function testPush0() public { 8 | address target = address(uint160(uint256(0xc4f3))); 9 | 10 | bytes memory bytecode = hex"365f5f37365ff3"; 11 | // 36 CALLDATASIZE 12 | // 5F PUSH0 13 | // 5F PUSH0 14 | // 37 CALLDATACOPY -> copies calldata at mem[0..calldatasize] 15 | 16 | // 36 CALLDATASIZE 17 | // 5F PUSH0 18 | // F3 RETURN -> returns mem[0..calldatasize] 19 | 20 | vm.etch(target, bytecode); 21 | 22 | (bool success, bytes memory result) = target.call(bytes("hello PUSH0")); 23 | assertTrue(success); 24 | assertEq(string(result), "hello PUSH0"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /crates/evm/core/test-data/storage.json: -------------------------------------------------------------------------------- 1 | {"meta":{"cfg_env":{"chain_id":1,"spec_id":"LATEST","perf_all_precompiles_have_balance":false,"memory_limit":4294967295,"perf_analyse_created_bytecodes":"Analyse","limit_contract_code_size":24576,"disable_coinbase_tip":false},"block_env":{"number":"0xdc42b8","coinbase":"0x0000000000000000000000000000000000000000","timestamp":"0x1","difficulty":"0x0","basefee":"0x0","gas_limit":"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},"hosts":["mainnet.infura.io"]},"accounts":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"balance":"0x0","code_hash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","code":null,"nonce":0}},"storage":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"0x0":"0x0","0x1":"0x0","0x2":"0x0","0x3":"0x0","0x4":"0x0","0x5":"0x0","0x6":"0x0","0x7":"0x0","0x8":"0x0","0x9":"0x0"}},"block_hashes":{}} -------------------------------------------------------------------------------- /crates/fmt/testdata/UnitExpression/fmt.sol: -------------------------------------------------------------------------------- 1 | contract UnitExpression { 2 | function test() external { 3 | uint256 timestamp; 4 | timestamp = 1 seconds; 5 | timestamp = 1 minutes; 6 | timestamp = 1 hours; 7 | timestamp = 1 days; 8 | timestamp = 1 weeks; 9 | 10 | uint256 value; 11 | value = 1 wei; 12 | value = 1 gwei; 13 | value = 1 ether; 14 | 15 | uint256 someVeryVeryVeryLongVariableNameForTheMultiplierForEtherValue; 16 | 17 | value = someVeryVeryVeryLongVariableNameForTheMultiplierForEtherValue 18 | * 1 ether; 19 | value = someVeryVeryVeryLongVariableNameForTheMultiplierForEtherValue 20 | * 1 ether; /* comment1 */ // comment2 21 | 22 | value = 1 ether; // comment3 23 | // comment4 24 | // comment5 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /crates/forge/tests/cli/cache.rs: -------------------------------------------------------------------------------- 1 | //! Tests for various cache command. 2 | 3 | forgetest!(can_list_cache, |_prj, cmd| { 4 | cmd.args(["cache", "ls"]); 5 | cmd.assert_success(); 6 | }); 7 | 8 | forgetest!(can_list_cache_all, |_prj, cmd| { 9 | cmd.args(["cache", "ls", "all"]); 10 | cmd.assert_success(); 11 | }); 12 | 13 | forgetest!(can_list_specific_chain, |_prj, cmd| { 14 | cmd.args(["cache", "ls", "mainnet"]); 15 | cmd.assert_success(); 16 | }); 17 | 18 | forgetest_init!(can_test_no_cache, |prj, cmd| { 19 | prj.initialize_default_contracts(); 20 | prj.clear_cache(); 21 | 22 | cmd.args(["test", "--no-cache"]).assert_success(); 23 | assert!(!prj.cache().exists(), "cache file should not exist"); 24 | 25 | cmd.forge_fuse().arg("test").assert_success(); 26 | assert!(prj.cache().exists(), "cache file should exist"); 27 | }); 28 | -------------------------------------------------------------------------------- /testdata/default/cheats/getBlockNumber.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract GetBlockNumberTest is Test { 7 | function testGetBlockNumber() public { 8 | uint256 height = vm.getBlockNumber(); 9 | assertEq(height, uint256(block.number), "height should be equal to block.number"); 10 | } 11 | 12 | function testGetBlockNumberWithRoll() public { 13 | vm.roll(10); 14 | assertEq(vm.getBlockNumber(), 10, "could not get correct block height after roll"); 15 | } 16 | 17 | function testGetBlockNumberWithRollFuzzed(uint32 jump) public { 18 | uint256 pre = vm.getBlockNumber(); 19 | vm.roll(pre + jump); 20 | assertEq(vm.getBlockNumber(), pre + jump, "could not get correct block height after roll"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue2851.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.1; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract Backdoor { 7 | uint256 public number = 1; 8 | 9 | function backdoor(uint256 newNumber) public payable { 10 | uint256 x = newNumber - 1; 11 | if (x == 6912213124124531) { 12 | number = 0; 13 | } 14 | } 15 | } 16 | 17 | // https://github.com/foundry-rs/foundry/issues/2851 18 | contract Issue2851Test is Test { 19 | Backdoor back; 20 | 21 | function setUp() public { 22 | back = new Backdoor(); 23 | } 24 | 25 | /// forge-config: default.fuzz.dictionary.max_fuzz_dictionary_literals = 0 26 | /// forge-config: default.fuzz.seed = '111' 27 | function invariantNotZero() public { 28 | assertEq(back.number(), 1); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /testdata/default/spec/ShanghaiCompat.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract ShanghaiCompat is Test { 7 | function testPush0() public { 8 | address target = address(uint160(uint256(0xc4f3))); 9 | 10 | bytes memory bytecode = hex"365f5f37365ff3"; 11 | // 36 CALLDATASIZE 12 | // 5F PUSH0 13 | // 5F PUSH0 14 | // 37 CALLDATACOPY -> copies calldata at mem[0..calldatasize] 15 | 16 | // 36 CALLDATASIZE 17 | // 5F PUSH0 18 | // F3 RETURN -> returns mem[0..calldatasize] 19 | 20 | vm.etch(target, bytecode); 21 | 22 | (bool success, bytes memory result) = target.call(bytes("hello PUSH0")); 23 | assertTrue(success); 24 | assertEq(string(result), "hello PUSH0"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /crates/forge/assets/solidity/workflowTemplate.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | env: 11 | FOUNDRY_PROFILE: ci 12 | 13 | jobs: 14 | check: 15 | name: Foundry project 16 | runs-on: ubuntu-latest 17 | permissions: 18 | contents: read 19 | steps: 20 | - uses: actions/checkout@v5 21 | with: 22 | persist-credentials: false 23 | submodules: recursive 24 | 25 | - name: Install Foundry 26 | uses: foundry-rs/foundry-toolchain@v1 27 | 28 | - name: Show Forge version 29 | run: forge --version 30 | 31 | - name: Run Forge fmt 32 | run: forge fmt --check 33 | 34 | - name: Run Forge build 35 | run: forge build --sizes 36 | 37 | - name: Run Forge tests 38 | run: forge test -vvv 39 | -------------------------------------------------------------------------------- /crates/fmt/testdata/MappingType/original.sol: -------------------------------------------------------------------------------- 1 | contract X { 2 | type Y is bytes32; 3 | } 4 | 5 | type SomeVeryLongTypeName is uint256; 6 | 7 | contract Mapping { 8 | mapping(uint256 => X.Y) mapping1; 9 | mapping(uint256 key => uint256 value) mapping2; 10 | mapping(uint256 veryLongKeyName => uint256 veryLongValueName) mapping3; 11 | mapping(string anotherVeryLongKeyName => uint256 anotherVeryLongValueName) mapping4; 12 | mapping(SomeVeryLongTypeName anotherVeryLongKeyName => uint256 anotherVeryLongValueName) mapping5; 13 | 14 | mapping( 15 | 16 | // comment1 17 | uint256 key => uint256 value 18 | // comment2 19 | ) mapping6; 20 | mapping( /* comment3 */ 21 | uint256 /* comment4 */ key /* comment5 */ => /* comment6 */ uint256 /* comment7 */ value /* comment8 */ /* comment9 */ 22 | ) /* comment10 */ mapping7; 23 | } -------------------------------------------------------------------------------- /testdata/default/repros/Issue5935.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract SimpleStorage { 7 | uint256 public value; 8 | 9 | function set(uint256 _value) external { 10 | value = _value; 11 | } 12 | } 13 | 14 | contract Issue5935Test is Test { 15 | function testFork() public { 16 | uint256 forkId1 = vm.createFork("mainnet", 18234083); 17 | uint256 forkId2 = vm.createFork("mainnet", 18234083); 18 | vm.selectFork(forkId1); 19 | SimpleStorage myContract = new SimpleStorage(); 20 | myContract.set(42); 21 | vm.selectFork(forkId2); 22 | SimpleStorage myContract2 = new SimpleStorage(); 23 | assertEq(myContract2.value(), 0); 24 | 25 | vm.selectFork(forkId1); 26 | assertEq(myContract.value(), 42); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ImportDirective/single_line_import.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: single_line_imports = true 2 | import "SomeFile.sol"; 3 | import "SomeFile.sol"; 4 | import "SomeFile.sol" as SomeOtherFile; 5 | import "SomeFile.sol" as SomeOtherFile; 6 | import "AnotherFile.sol" as SomeSymbol; 7 | import "AnotherFile.sol" as SomeSymbol; 8 | import {symbol1 as alias0, symbol2} from "File.sol"; 9 | import {symbol1 as alias0, symbol2} from "File.sol"; 10 | import { 11 | symbol1 as alias1, 12 | symbol2 as alias2, 13 | symbol3 as alias3, 14 | symbol4 15 | } from "File2.sol"; 16 | import { 17 | symbol1 as alias1, 18 | symbol2 as alias2, 19 | symbol3 as alias3, 20 | symbol4 21 | } from "File2.sol"; 22 | 23 | // Single import that exceeds line length (121 chars) 24 | import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; 25 | -------------------------------------------------------------------------------- /crates/common/src/iter.rs: -------------------------------------------------------------------------------- 1 | use std::iter::Peekable; 2 | 3 | pub struct Delimited { 4 | is_first: bool, 5 | iter: Peekable, 6 | } 7 | 8 | pub trait IterDelimited: Iterator + Sized { 9 | fn delimited(self) -> Delimited { 10 | Delimited { is_first: true, iter: self.peekable() } 11 | } 12 | } 13 | 14 | impl IterDelimited for I {} 15 | 16 | pub struct IteratorPosition { 17 | pub is_first: bool, 18 | pub is_last: bool, 19 | } 20 | 21 | impl Iterator for Delimited { 22 | type Item = (IteratorPosition, I::Item); 23 | 24 | fn next(&mut self) -> Option { 25 | let item = self.iter.next()?; 26 | let position = 27 | IteratorPosition { is_first: self.is_first, is_last: self.iter.peek().is_none() }; 28 | self.is_first = false; 29 | Some((position, item)) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /crates/fmt/testdata/NonKeywords/fmt.sol: -------------------------------------------------------------------------------- 1 | struct S { 2 | uint256 error; 3 | uint256 layout; 4 | uint256 at; 5 | // uint256 transient; 6 | } 7 | 8 | function f() { 9 | uint256 error = 0; 10 | uint256 layout = 0; 11 | uint256 at = 0; 12 | // uint256 transient = 0; 13 | 14 | error = 0; 15 | // layout = 0; 16 | at = 0; 17 | // transient = 0; 18 | 19 | S memory x = S({ 20 | // format 21 | error: 0, 22 | layout: 0, 23 | at: 0 24 | // transient: 0 25 | }); 26 | 27 | x.error = 0; 28 | x.layout = 0; 29 | x.at = 0; 30 | // x.transient = 0; 31 | 32 | assembly { 33 | let error := 0 34 | let layout := 0 35 | let at := 0 36 | // let transient := 0 37 | 38 | error := 0 39 | layout := 0 40 | at := 0 41 | // transient := 0 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /docs/dev/debugging.md: -------------------------------------------------------------------------------- 1 | # Debugging 2 | 3 | This is a working document intended to outline some commands contributors can use to debug various parts of Foundry. 4 | 5 | ## Logs 6 | 7 | All crates use [tracing](https://docs.rs/tracing/latest/tracing/) for logging. A console formatter is installed in each binary (`cast`, `forge`, `anvil`). 8 | 9 | By setting `RUST_LOG=` you can get a lot more info out of Forge and Cast. For example, running Forge with `RUST_LOG=forge` will emit all logs from the `forge` package, same for Cast with `RUST_LOG=cast`. 10 | 11 | The most basic valid filter is a log level, of which these are valid: 12 | 13 | - `error` 14 | - `warn` 15 | - `info` 16 | - `debug` 17 | - `trace` 18 | 19 | Filters are explained in detail in the [`tracing-subscriber` crate docs](https://docs.rs/tracing-subscriber). 20 | 21 | You can also use the `dbg!` macro from Rust's standard library. 22 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue10527.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract A { 7 | event Event1(); 8 | event Event2(); 9 | 10 | function foo() public { 11 | emit Event1(); 12 | } 13 | 14 | function bar() public { 15 | emit Event2(); 16 | } 17 | } 18 | 19 | contract Issue10527Test is Test { 20 | event Event1(); 21 | event Event2(); 22 | 23 | A a; 24 | 25 | function setUp() public { 26 | a = new A(); 27 | } 28 | 29 | function test_foo_Event1() public { 30 | vm.expectEmit(address(a)); 31 | emit Event1(); 32 | 33 | a.foo(); 34 | } 35 | 36 | function test_foo_Event2() public { 37 | vm.expectEmit({emitter: address(a), count: 0}); 38 | emit Event2(); 39 | 40 | a.foo(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue8277.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/8277 7 | contract Issue8277Test is Test { 8 | struct MyJson { 9 | string s; 10 | } 11 | 12 | function test_hexprefixednonhexstring() public { 13 | { 14 | bytes memory b = vm.parseJson("{\"a\": \"0x834629f473876e5f0d3d9d269af3dabcb0d7d520-identifier-0\"}"); 15 | MyJson memory decoded = abi.decode(b, (MyJson)); 16 | assertEq(decoded.s, "0x834629f473876e5f0d3d9d269af3dabcb0d7d520-identifier-0"); 17 | } 18 | 19 | { 20 | bytes memory b = vm.parseJson("{\"b\": \"0xBTC\"}"); 21 | MyJson memory decoded = abi.decode(b, (MyJson)); 22 | assertEq(decoded.s, "0xBTC"); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ImportDirective/preserve-quote.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: quote_style = "preserve" 2 | import "SomeFile.sol"; 3 | import 'SomeFile.sol'; 4 | import "SomeFile.sol" as SomeOtherFile; 5 | import 'SomeFile.sol' as SomeOtherFile; 6 | import "AnotherFile.sol" as SomeSymbol; 7 | import 'AnotherFile.sol' as SomeSymbol; 8 | import {symbol1 as alias0, symbol2} from "File.sol"; 9 | import {symbol1 as alias0, symbol2} from 'File.sol'; 10 | import { 11 | symbol1 as alias1, 12 | symbol2 as alias2, 13 | symbol3 as alias3, 14 | symbol4 15 | } from "File2.sol"; 16 | import { 17 | symbol1 as alias1, 18 | symbol2 as alias2, 19 | symbol3 as alias3, 20 | symbol4 21 | } from 'File2.sol'; 22 | 23 | // Single import that exceeds line length (121 chars) 24 | import { 25 | ITransparentUpgradeableProxy 26 | } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; 27 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ImportDirective/single-quote.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: quote_style = "single" 2 | import 'SomeFile.sol'; 3 | import 'SomeFile.sol'; 4 | import 'SomeFile.sol' as SomeOtherFile; 5 | import 'SomeFile.sol' as SomeOtherFile; 6 | import 'AnotherFile.sol' as SomeSymbol; 7 | import 'AnotherFile.sol' as SomeSymbol; 8 | import {symbol1 as alias0, symbol2} from 'File.sol'; 9 | import {symbol1 as alias0, symbol2} from 'File.sol'; 10 | import { 11 | symbol1 as alias1, 12 | symbol2 as alias2, 13 | symbol3 as alias3, 14 | symbol4 15 | } from 'File2.sol'; 16 | import { 17 | symbol1 as alias1, 18 | symbol2 as alias2, 19 | symbol3 as alias3, 20 | symbol4 21 | } from 'File2.sol'; 22 | 23 | // Single import that exceeds line length (121 chars) 24 | import { 25 | ITransparentUpgradeableProxy 26 | } from '@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol'; 27 | -------------------------------------------------------------------------------- /crates/fmt/testdata/NonKeywords/original.sol: -------------------------------------------------------------------------------- 1 | struct S { 2 | uint256 error; 3 | uint256 layout; 4 | uint256 at; 5 | // uint256 transient; 6 | } 7 | 8 | function f() { 9 | uint256 error = 0; 10 | uint256 layout = 0; 11 | uint256 at = 0; 12 | // uint256 transient = 0; 13 | 14 | error = 0; 15 | // layout = 0; 16 | at = 0; 17 | // transient = 0; 18 | 19 | S memory x = S({ 20 | // format 21 | error: 0, 22 | layout: 0, 23 | at: 0 24 | // transient: 0 25 | }); 26 | 27 | x.error = 0; 28 | x.layout = 0; 29 | x.at = 0; 30 | // x.transient = 0; 31 | 32 | assembly { 33 | let error := 0 34 | let layout := 0 35 | let at := 0 36 | // let transient := 0 37 | 38 | error := 0 39 | layout := 0 40 | at := 0 41 | // transient := 0 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ImportDirective/bracket-spacing.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: bracket_spacing = true 2 | import "SomeFile.sol"; 3 | import "SomeFile.sol"; 4 | import "SomeFile.sol" as SomeOtherFile; 5 | import "SomeFile.sol" as SomeOtherFile; 6 | import "AnotherFile.sol" as SomeSymbol; 7 | import "AnotherFile.sol" as SomeSymbol; 8 | import { symbol1 as alias0, symbol2 } from "File.sol"; 9 | import { symbol1 as alias0, symbol2 } from "File.sol"; 10 | import { 11 | symbol1 as alias1, 12 | symbol2 as alias2, 13 | symbol3 as alias3, 14 | symbol4 15 | } from "File2.sol"; 16 | import { 17 | symbol1 as alias1, 18 | symbol2 as alias2, 19 | symbol3 as alias3, 20 | symbol4 21 | } from "File2.sol"; 22 | 23 | // Single import that exceeds line length (121 chars) 24 | import { 25 | ITransparentUpgradeableProxy 26 | } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; 27 | -------------------------------------------------------------------------------- /crates/anvil/src/opts.rs: -------------------------------------------------------------------------------- 1 | use crate::cmd::NodeArgs; 2 | use clap::{Parser, Subcommand}; 3 | use foundry_cli::opts::GlobalArgs; 4 | use foundry_common::version::{LONG_VERSION, SHORT_VERSION}; 5 | 6 | /// A fast local Ethereum development node. 7 | #[derive(Parser)] 8 | #[command(name = "anvil", version = SHORT_VERSION, long_version = LONG_VERSION, next_display_order = None)] 9 | pub struct Anvil { 10 | /// Include the global arguments. 11 | #[command(flatten)] 12 | pub global: GlobalArgs, 13 | 14 | #[command(flatten)] 15 | pub node: NodeArgs, 16 | 17 | #[command(subcommand)] 18 | pub cmd: Option, 19 | } 20 | 21 | #[derive(Subcommand)] 22 | pub enum AnvilSubcommand { 23 | /// Generate shell completions script. 24 | #[command(visible_alias = "com")] 25 | Completions { 26 | #[arg(value_enum)] 27 | shell: foundry_cli::clap::Shell, 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /crates/config/src/bind_json.rs: -------------------------------------------------------------------------------- 1 | use crate::filter::GlobMatcher; 2 | use serde::{Deserialize, Serialize}; 3 | use std::path::PathBuf; 4 | 5 | /// Contains the config for `forge bind-json` 6 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 7 | pub struct BindJsonConfig { 8 | /// Path for the generated bindings file. 9 | pub out: PathBuf, 10 | /// Globs to include. 11 | /// 12 | /// If provided, only the files matching the globs will be included. Otherwise, defaults to 13 | /// including all project files. 14 | pub include: Vec, 15 | /// Globs to ignore 16 | pub exclude: Vec, 17 | } 18 | 19 | impl Default for BindJsonConfig { 20 | fn default() -> Self { 21 | Self { 22 | out: PathBuf::from("utils/JsonBindings.sol"), 23 | exclude: Vec::new(), 24 | include: Vec::new(), 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /testdata/default/cheats/SetNonceUnsafe.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract Foo { 7 | function f() external view returns (uint256) { 8 | return 1; 9 | } 10 | } 11 | 12 | contract SetNonceTest is Test { 13 | Foo public foo; 14 | 15 | function setUp() public { 16 | foo = new Foo(); 17 | } 18 | 19 | function testSetNonceUnsafe() public { 20 | vm.setNonceUnsafe(address(foo), 10); 21 | // makes sure working correctly after mutating nonce. 22 | foo.f(); 23 | assertEq(vm.getNonce(address(foo)), 10); 24 | foo.f(); 25 | } 26 | 27 | function testDoesNotFailDecreasingNonce() public { 28 | vm.setNonce(address(foo), 10); 29 | vm.setNonceUnsafe(address(foo), 5); 30 | assertEq(vm.getNonce(address(foo)), 5); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /crates/lint/testdata/StructPascalCase.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.18; 3 | 4 | contract StructPascalCaseTest { 5 | struct PascalCase { 6 | uint256 a; 7 | } 8 | 9 | struct PascalCAse { 10 | uint256 a; 11 | } 12 | 13 | struct _PascalCase { //~NOTE: structs should use PascalCase 14 | uint256 a; 15 | } 16 | 17 | struct pascalCase { //~NOTE: structs should use PascalCase 18 | uint256 a; 19 | } 20 | 21 | struct pascalcase { //~NOTE: structs should use PascalCase 22 | uint256 a; 23 | } 24 | 25 | struct pascal_case { //~NOTE: structs should use PascalCase 26 | uint256 a; 27 | } 28 | 29 | struct PASCAL_CASE { //~NOTE: structs should use PascalCase 30 | uint256 a; 31 | } 32 | 33 | struct PASCALCASE { //~NOTE: structs should use PascalCase 34 | uint256 a; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /crates/macros/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # foundry-macros 2 | //! 3 | //! Internal Foundry proc-macros. 4 | 5 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 6 | #![cfg_attr(docsrs, feature(doc_cfg))] 7 | 8 | #[macro_use] 9 | extern crate proc_macro_error2; 10 | 11 | use proc_macro::TokenStream; 12 | use syn::{DeriveInput, Error, parse_macro_input}; 13 | 14 | mod cheatcodes; 15 | mod console_fmt; 16 | 17 | #[proc_macro_derive(ConsoleFmt)] 18 | pub fn console_fmt(input: TokenStream) -> TokenStream { 19 | let input = parse_macro_input!(input as DeriveInput); 20 | console_fmt::console_fmt(&input).into() 21 | } 22 | 23 | #[proc_macro_derive(Cheatcode, attributes(cheatcode))] 24 | #[proc_macro_error] 25 | pub fn cheatcode(input: TokenStream) -> TokenStream { 26 | let input = parse_macro_input!(input as DeriveInput); 27 | cheatcodes::derive_cheatcode(&input).unwrap_or_else(Error::into_compile_error).into() 28 | } 29 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue3119.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/3119 7 | contract Issue3119Test is Test { 8 | address public owner = vm.addr(1); 9 | address public alice = vm.addr(2); 10 | 11 | function testRollFork() public { 12 | uint256 fork = vm.createFork("mainnet"); 13 | vm.selectFork(fork); 14 | 15 | FortressSwap fortressSwap = new FortressSwap(address(owner)); 16 | vm.prank(owner); 17 | fortressSwap.updateOwner(alice); 18 | } 19 | } 20 | 21 | contract FortressSwap { 22 | address owner; 23 | 24 | constructor(address _owner) { 25 | owner = _owner; 26 | } 27 | 28 | function updateOwner(address new_owner) public { 29 | require(msg.sender == owner, "must be owner"); 30 | owner = new_owner; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /crates/forge/src/cmd/mod.rs: -------------------------------------------------------------------------------- 1 | //! `forge` subcommands. 2 | //! 3 | //! All subcommands should respect the `foundry_config::Config`. 4 | //! If a subcommand accepts values that are supported by the `Config`, then the subcommand should 5 | //! implement `figment::Provider` which allows the subcommand to override the config's defaults, see 6 | //! [`foundry_config::Config`]. 7 | 8 | pub mod bind; 9 | pub mod bind_json; 10 | pub mod build; 11 | pub mod cache; 12 | pub mod clone; 13 | pub mod compiler; 14 | pub mod config; 15 | pub mod coverage; 16 | pub mod create; 17 | pub mod doc; 18 | pub mod eip712; 19 | pub mod flatten; 20 | pub mod fmt; 21 | pub mod geiger; 22 | pub mod generate; 23 | pub mod init; 24 | pub mod inspect; 25 | pub mod install; 26 | pub mod lint; 27 | pub mod remappings; 28 | pub mod remove; 29 | pub mod selectors; 30 | pub mod snapshot; 31 | pub mod soldeer; 32 | pub mod test; 33 | pub mod tree; 34 | pub mod update; 35 | pub mod watch; 36 | -------------------------------------------------------------------------------- /crates/fmt/testdata/SortedImports/original.sol: -------------------------------------------------------------------------------- 1 | import "SomeFile3.sol"; 2 | import "SomeFile2.sol"; 3 | import "SomeFile1.sol" as SomeOtherFile; 4 | import "SomeFile0.sol" as SomeOtherFile; 5 | 6 | import "AnotherFile2.sol" as SomeSymbol; 7 | import "AnotherFile1.sol" as SomeSymbol; 8 | 9 | import {symbol2, symbol1 as alias0} from "File3.sol"; 10 | import {symbol2, symbol1 as alias0} from "File2.sol"; 11 | import {symbol2 as alias2, symbol1 as alias1, symbol3 as alias3, symbol4} from "File6.sol"; 12 | import {symbol3 as alias1, symbol2 as alias2, symbol1 as alias3, symbol4} from "File0.sol"; 13 | 14 | uint256 constant someConstant = 10; 15 | 16 | import {Something3, Something2} from "someFile.sol"; 17 | 18 | // This is a comment 19 | import {Something3, Something2} from "someFile.sol"; 20 | 21 | import {symbol2, symbol1 as alias0} from "File3.sol"; 22 | // comment inside group is treated as a separator for now 23 | import {symbol2, symbol1 as alias0} from "File2.sol"; -------------------------------------------------------------------------------- /crates/common/fmt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foundry-common-fmt" 3 | description = "Common formatting utilities for Foundry" 4 | 5 | version.workspace = true 6 | edition.workspace = true 7 | rust-version.workspace = true 8 | authors.workspace = true 9 | license.workspace = true 10 | homepage.workspace = true 11 | repository.workspace = true 12 | 13 | [lints] 14 | workspace = true 15 | 16 | [dependencies] 17 | alloy-primitives.workspace = true 18 | alloy-dyn-abi = { workspace = true, features = ["eip712"] } 19 | eyre.workspace = true 20 | 21 | # ui 22 | alloy-consensus.workspace = true 23 | alloy-network.workspace = true 24 | alloy-rpc-types = { workspace = true, features = ["eth"] } 25 | alloy-serde.workspace = true 26 | serde.workspace = true 27 | serde_json.workspace = true 28 | chrono.workspace = true 29 | revm.workspace = true 30 | yansi.workspace = true 31 | 32 | [dev-dependencies] 33 | foundry-macros.workspace = true 34 | similar-asserts.workspace = true 35 | -------------------------------------------------------------------------------- /testdata/multi-version/cheats/GetCode.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity =0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | import "../Counter.sol"; 6 | 7 | contract GetCodeTest is Test { 8 | function testGetCodeMultiVersion() public { 9 | assertEq(vm.getCode("Counter.sol"), type(Counter).creationCode); 10 | require( 11 | keccak256(vm.getCode("Counter.sol")) != keccak256(vm.getCode("Counter.sol:Counter:0.8.17")), 12 | "Invalid artifact" 13 | ); 14 | assertEq(vm.getCode("Counter.sol"), vm.getCode("Counter.sol:Counter:0.8.18")); 15 | } 16 | 17 | function testGetCodeByNameMultiVersion() public { 18 | assertEq(vm.getCode("Counter"), type(Counter).creationCode); 19 | require(keccak256(vm.getCode("Counter")) != keccak256(vm.getCode("Counter:0.8.17")), "Invalid artifact"); 20 | assertEq(vm.getCode("Counter"), vm.getCode("Counter:0.8.18")); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /benches/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foundry-bench" 3 | description = "Foundry benchmark runner" 4 | 5 | version.workspace = true 6 | edition.workspace = true 7 | rust-version.workspace = true 8 | authors.workspace = true 9 | license.workspace = true 10 | homepage.workspace = true 11 | repository.workspace = true 12 | 13 | [lints] 14 | workspace = true 15 | 16 | [[bin]] 17 | name = "foundry-bench" 18 | path = "src/main.rs" 19 | 20 | [dependencies] 21 | foundry-test-utils.workspace = true 22 | foundry-common.workspace = true 23 | foundry-compilers = { workspace = true, features = ["project-util"] } 24 | eyre.workspace = true 25 | color-eyre.workspace = true 26 | serde.workspace = true 27 | serde_json.workspace = true 28 | tempfile.workspace = true 29 | chrono = { version = "0.4", features = ["serde"] } 30 | rayon.workspace = true 31 | clap = { version = "4", features = ["derive"] } 32 | once_cell = "1.21" 33 | 34 | [dev-dependencies] 35 | foundry-test-utils.workspace = true 36 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue3223.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/3223 7 | /// forge-config: default.sender = "0xF0959944122fb1ed4CfaBA645eA06EED30427BAA" 8 | contract Issue3223Test is Test { 9 | uint256 fork1; 10 | uint256 fork2; 11 | 12 | function setUp() public { 13 | fork1 = vm.createFork("sepolia", 2362365); 14 | fork2 = vm.createFork("avaxTestnet", 12880747); 15 | } 16 | 17 | function testForkNonce() public { 18 | address user = address(0xF0959944122fb1ed4CfaBA645eA06EED30427BAA); 19 | assertEq(user, msg.sender); 20 | 21 | vm.selectFork(fork2); 22 | assertEq(vm.getNonce(user), 3); 23 | vm.prank(user); 24 | new Counter(); 25 | 26 | vm.selectFork(fork1); 27 | assertEq(vm.getNonce(user), 1); 28 | } 29 | } 30 | 31 | contract Counter {} 32 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ConstructorDefinition/fmt.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.5.2; 4 | 5 | // comment block starts here 6 | // comment block continues 7 | // 8 | 9 | // comment block 2 starts here 10 | // comment block 2 continues 11 | 12 | contract Constructors is Ownable, Changeable { 13 | function Constructors(variable1) 14 | public 15 | Changeable(variable1) 16 | Ownable() 17 | onlyOwner 18 | {} 19 | 20 | constructor( 21 | variable1, 22 | variable2, 23 | variable3, 24 | variable4, 25 | variable5, 26 | variable6, 27 | variable7 28 | ) 29 | public 30 | Changeable( 31 | variable1, 32 | variable2, 33 | variable3, 34 | variable4, 35 | variable5, 36 | variable6, 37 | variable7 38 | ) 39 | Ownable() 40 | onlyOwner 41 | {} 42 | } 43 | -------------------------------------------------------------------------------- /testdata/fixtures/GetCode/HuffWorkingContract.json: -------------------------------------------------------------------------------- 1 | { 2 | "file": { 3 | "path": "src/WorkingContract.huff" 4 | }, 5 | "bytecode": "602d8060093d393df33d3560e01c63d1efd30d14610012573d3dfd5b6f656d6f2e6574682077757a206865726560801b3d523d6020f3", 6 | "runtime": "3d3560e01c63d1efd30d14610012573d3dfd5b6f656d6f2e6574682077757a206865726560801b3d523d6020f3", 7 | "abi": { 8 | "constructor": null, 9 | "functions": { 10 | "secret": { 11 | "name": "secret", 12 | "inputs": [], 13 | "outputs": [ 14 | { 15 | "name": "", 16 | "kind": { 17 | "Uint": 256 18 | }, 19 | "internal_type": null 20 | } 21 | ], 22 | "constant": false, 23 | "state_mutability": "View" 24 | } 25 | }, 26 | "events": {}, 27 | "errors": {}, 28 | "receive": false, 29 | "fallback": false 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /testdata/default/cheats/GetArtifactPath.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity =0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | contract DummyForGetArtifactPath {} 7 | 8 | contract GetArtifactPathTest is Test { 9 | function testGetArtifactPathByCode() public { 10 | bytes memory dummyCreationCode = type(DummyForGetArtifactPath).creationCode; 11 | 12 | string memory path = vm.getArtifactPathByCode(dummyCreationCode); 13 | assertTrue(vm.contains(path, "/out/GetArtifactPath.t.sol/DummyForGetArtifactPath.json")); 14 | } 15 | 16 | function testGetArtifactPathByDeployedCode() public { 17 | DummyForGetArtifactPath dummy = new DummyForGetArtifactPath(); 18 | bytes memory dummyRuntimeCode = address(dummy).code; 19 | 20 | string memory path = vm.getArtifactPathByDeployedCode(dummyRuntimeCode); 21 | assertTrue(vm.contains(path, "/out/GetArtifactPath.t.sol/DummyForGetArtifactPath.json")); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ForStatement/original.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.8; 2 | 3 | contract ForStatement { 4 | function test() external { 5 | for 6 | (uint256 i1 7 | ; i1 < 10; i1++) 8 | { 9 | i1++; 10 | } 11 | 12 | uint256 i2; 13 | for(++i2;i2<10;i2++) 14 | 15 | {} 16 | 17 | uint256 veryLongVariableName = 1000; 18 | for ( uint256 i3; i3 < 10 19 | && veryLongVariableName>999 && veryLongVariableName< 1001 20 | ; i3++) 21 | { i3 ++ ; } 22 | 23 | for ( uint256 i3; i3 < 10 24 | && veryLongVariableName>900 && veryLongVariableName< 999 25 | ; i3++) 26 | { i3 ++ ; } 27 | 28 | 29 | for (type(uint256).min;;) {} 30 | 31 | for (;;) { "test" ; } 32 | 33 | for (uint256 i4; i4< 10; i4++) i4++; 34 | 35 | for (uint256 i5; ;) 36 | for (uint256 i6 = 10; i6 > i5; i6--) 37 | i5++; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue3221.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/3221 7 | contract Issue3221Test is Test { 8 | uint256 fork1; 9 | uint256 fork2; 10 | 11 | function setUp() public { 12 | fork1 = vm.createFork("sepolia", 5565573); 13 | fork2 = vm.createFork("avaxTestnet", 12880747); 14 | } 15 | 16 | function testForkNonce() public { 17 | address user = address(0xF0959944122fb1ed4CfaBA645eA06EED30427BAA); 18 | 19 | // Loads but doesn't touch 20 | assertEq(vm.getNonce(user), 0); 21 | 22 | vm.selectFork(fork2); 23 | assertEq(vm.getNonce(user), 3); 24 | vm.prank(user); 25 | new Counter(); 26 | 27 | vm.selectFork(fork1); 28 | assertEq(vm.getNonce(user), 1); 29 | vm.prank(user); 30 | new Counter(); 31 | } 32 | } 33 | 34 | contract Counter {} 35 | -------------------------------------------------------------------------------- /crates/forge/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Forge is a fast and flexible Ethereum testing framework. 2 | 3 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 4 | #![cfg_attr(docsrs, feature(doc_cfg))] 5 | 6 | #[macro_use] 7 | extern crate foundry_common; 8 | 9 | #[macro_use] 10 | extern crate tracing; 11 | 12 | // Required for optional features (aws-kms, gcp-kms, turnkey) 13 | #[cfg(any(feature = "aws-kms", feature = "gcp-kms", feature = "turnkey"))] 14 | use foundry_wallets as _; 15 | 16 | pub mod args; 17 | pub mod cmd; 18 | pub mod opts; 19 | 20 | pub mod coverage; 21 | 22 | pub mod gas_report; 23 | 24 | pub mod multi_runner; 25 | pub use multi_runner::{MultiContractRunner, MultiContractRunnerBuilder}; 26 | 27 | mod runner; 28 | pub use runner::ContractRunner; 29 | 30 | mod progress; 31 | pub mod result; 32 | 33 | // TODO: remove 34 | pub use foundry_common::traits::TestFilter; 35 | pub use foundry_evm::*; 36 | 37 | mod lockfile; 38 | pub use lockfile::{DepIdentifier, DepMap, FOUNDRY_LOCK, Lockfile}; 39 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue12075.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/12075 7 | contract Issue12075Test is Test { 8 | address payable internal ALICE = payable(address(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)); 9 | address payable internal BOB = payable(address(0x70997970C51812dc3A010C7d01b50e0d17dc79C8)); 10 | 11 | Target internal target; 12 | 13 | function setUp() public virtual { 14 | target = new Target(); 15 | 16 | vm.deal({account: ALICE, newBalance: 100 ether}); 17 | vm.startPrank(ALICE); 18 | } 19 | 20 | function test_NativeTransfer() public { 21 | BOB.transfer(1 ether); 22 | assertEq(BOB.balance, 1 ether); 23 | } 24 | 25 | function test_PayableFunction() public { 26 | target.hit{value: 1 wei}(); 27 | } 28 | } 29 | 30 | contract Target { 31 | function hit() public payable {} 32 | } 33 | -------------------------------------------------------------------------------- /crates/doc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "forge-doc" 3 | description = "Solidity documentation generator" 4 | 5 | version.workspace = true 6 | edition.workspace = true 7 | rust-version.workspace = true 8 | authors.workspace = true 9 | license.workspace = true 10 | homepage.workspace = true 11 | repository.workspace = true 12 | 13 | [lints] 14 | workspace = true 15 | 16 | [dependencies] 17 | forge-fmt.workspace = true 18 | foundry-common.workspace = true 19 | foundry-compilers.workspace = true 20 | foundry-config.workspace = true 21 | 22 | solar.workspace = true 23 | alloy-primitives.workspace = true 24 | 25 | derive_more.workspace = true 26 | eyre.workspace = true 27 | itertools.workspace = true 28 | mdbook = { version = "0.4", default-features = false, features = ["search"] } 29 | rayon.workspace = true 30 | serde_json.workspace = true 31 | serde.workspace = true 32 | solang-parser.workspace = true 33 | thiserror.workspace = true 34 | toml.workspace = true 35 | tracing.workspace = true 36 | regex.workspace = true 37 | -------------------------------------------------------------------------------- /testdata/default/repros/Issue2956.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.18; 3 | 4 | import "utils/Test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/2956 7 | contract Issue2956Test is Test { 8 | uint256 fork1; 9 | uint256 fork2; 10 | 11 | function setUp() public { 12 | fork1 = vm.createFork("sepolia", 5565573); 13 | fork2 = vm.createFork("avaxTestnet", 12880747); 14 | } 15 | 16 | function testForkNonce() public { 17 | address user = address(0xF0959944122fb1ed4CfaBA645eA06EED30427BAA); 18 | 19 | assertEq(vm.getNonce(user), 0); 20 | vm.prank(user); 21 | new Counter(); 22 | 23 | vm.selectFork(fork2); 24 | assertEq(vm.getNonce(user), 3); 25 | vm.prank(user); 26 | new Counter(); 27 | 28 | vm.selectFork(fork1); 29 | assertEq(vm.getNonce(user), 1); 30 | vm.prank(user); 31 | new Counter(); 32 | } 33 | } 34 | 35 | contract Counter {} 36 | -------------------------------------------------------------------------------- /crates/evm/networks/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foundry-evm-networks" 3 | description = "Custom network features, like precompiles and custom tx types" 4 | 5 | version.workspace = true 6 | edition.workspace = true 7 | rust-version.workspace = true 8 | authors.workspace = true 9 | license.workspace = true 10 | homepage.workspace = true 11 | repository.workspace = true 12 | 13 | [lints] 14 | workspace = true 15 | 16 | [dependencies] 17 | alloy-chains.workspace = true 18 | alloy-evm.workspace = true 19 | alloy-primitives = { workspace = true, features = [ 20 | "serde", 21 | "getrandom", 22 | "arbitrary", 23 | "rlp", 24 | ] } 25 | 26 | revm = { workspace = true, features = [ 27 | "std", 28 | "serde", 29 | "memory_limit", 30 | "optional_eip3607", 31 | "optional_block_gas_limit", 32 | "optional_no_base_fee", 33 | "arbitrary", 34 | "c-kzg", 35 | "blst", 36 | ] } 37 | 38 | clap = { version = "4", features = ["derive", "env", "unicode", "wrap_help"] } 39 | serde.workspace = true --------------------------------------------------------------------------------