├── .cargo └── config.toml ├── .config └── nextest.toml ├── .dockerignore ├── .git-blame-ignore-revs ├── .gitattributes ├── .github ├── CODEOWNERS ├── INTEGRATION_FAILURE.md ├── ISSUE_TEMPLATE │ ├── BUG-FORM.yml │ ├── FEATURE-FORM.yml │ └── config.yml ├── PULL_REQUEST_TEMPLATE.md ├── RELEASE_FAILURE_ISSUE_TEMPLATE.md ├── changelog.json ├── compilation-benchmark.png ├── demo.gif ├── logo.png ├── scripts │ ├── create-tag.js │ ├── matrices.py │ ├── move-tag.js │ └── prune-prereleases.js └── workflows │ ├── deny.yml │ ├── dependencies.yml │ ├── docker-publish.yml │ ├── project.yml │ ├── release.yml │ └── test.yml ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── Dockerfile ├── FUNDING.json ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── clippy.toml ├── crates ├── anvil │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── core │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── eth │ │ │ ├── block.rs │ │ │ ├── mod.rs │ │ │ ├── proof.rs │ │ │ ├── serde_helpers.rs │ │ │ ├── subscription.rs │ │ │ ├── transaction │ │ │ │ ├── mod.rs │ │ │ │ └── optimism.rs │ │ │ ├── trie.rs │ │ │ └── utils.rs │ │ │ ├── lib.rs │ │ │ └── types.rs │ ├── rpc │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── error.rs │ │ │ ├── lib.rs │ │ │ ├── request.rs │ │ │ └── response.rs │ ├── server │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── config.rs │ │ │ ├── error.rs │ │ │ ├── handler.rs │ │ │ ├── ipc.rs │ │ │ ├── lib.rs │ │ │ ├── pubsub.rs │ │ │ └── ws.rs │ ├── src │ │ ├── anvil.rs │ │ ├── cmd.rs │ │ ├── config.rs │ │ ├── eth │ │ │ ├── api.rs │ │ │ ├── backend │ │ │ │ ├── cheats.rs │ │ │ │ ├── db.rs │ │ │ │ ├── executor.rs │ │ │ │ ├── fork.rs │ │ │ │ ├── genesis.rs │ │ │ │ ├── info.rs │ │ │ │ ├── mem │ │ │ │ │ ├── cache.rs │ │ │ │ │ ├── fork_db.rs │ │ │ │ │ ├── in_memory_db.rs │ │ │ │ │ ├── inspector.rs │ │ │ │ │ ├── mod.rs │ │ │ │ │ ├── state.rs │ │ │ │ │ └── storage.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── notifications.rs │ │ │ │ ├── time.rs │ │ │ │ └── validate.rs │ │ │ ├── error.rs │ │ │ ├── fees.rs │ │ │ ├── macros.rs │ │ │ ├── miner.rs │ │ │ ├── mod.rs │ │ │ ├── otterscan │ │ │ │ ├── api.rs │ │ │ │ ├── mod.rs │ │ │ │ └── types.rs │ │ │ ├── pool │ │ │ │ ├── mod.rs │ │ │ │ └── transactions.rs │ │ │ ├── sign.rs │ │ │ └── util.rs │ │ ├── filter.rs │ │ ├── hardfork.rs │ │ ├── lib.rs │ │ ├── logging.rs │ │ ├── pubsub.rs │ │ ├── server │ │ │ ├── error.rs │ │ │ ├── handler.rs │ │ │ └── mod.rs │ │ ├── service.rs │ │ ├── shutdown.rs │ │ └── tasks │ │ │ ├── block_listener.rs │ │ │ └── mod.rs │ ├── test-data │ │ ├── SimpleStorage.json │ │ ├── SimpleStorage.sol │ │ ├── emit_logs.json │ │ ├── emit_logs.sol │ │ ├── greeter.json │ │ ├── multicall.json │ │ └── multicall.sol │ └── tests │ │ └── it │ │ ├── abi.rs │ │ ├── anvil.rs │ │ ├── anvil_api.rs │ │ ├── api.rs │ │ ├── fork.rs │ │ ├── ganache.rs │ │ ├── gas.rs │ │ ├── genesis.rs │ │ ├── geth.rs │ │ ├── ipc.rs │ │ ├── logs.rs │ │ ├── main.rs │ │ ├── optimism.rs │ │ ├── otterscan.rs │ │ ├── proof │ │ ├── eip1186.rs │ │ └── mod.rs │ │ ├── pubsub.rs │ │ ├── revert.rs │ │ ├── sign.rs │ │ ├── state.rs │ │ ├── traces.rs │ │ ├── transaction.rs │ │ ├── txpool.rs │ │ ├── utils.rs │ │ └── wsapi.rs ├── cast │ ├── Cargo.toml │ ├── README.md │ ├── benches │ │ └── vanity.rs │ ├── bin │ │ ├── cmd │ │ │ ├── access_list.rs │ │ │ ├── bind.rs │ │ │ ├── call.rs │ │ │ ├── create2.rs │ │ │ ├── estimate.rs │ │ │ ├── find_block.rs │ │ │ ├── interface.rs │ │ │ ├── logs.rs │ │ │ ├── mod.rs │ │ │ ├── rpc.rs │ │ │ ├── run.rs │ │ │ ├── send.rs │ │ │ ├── storage.rs │ │ │ └── wallet │ │ │ │ ├── mod.rs │ │ │ │ └── vanity.rs │ │ ├── main.rs │ │ └── opts.rs │ ├── build.rs │ ├── src │ │ ├── base.rs │ │ ├── errors.rs │ │ ├── lib.rs │ │ ├── rlp_converter.rs │ │ └── tx.rs │ └── tests │ │ ├── cli │ │ └── main.rs │ │ └── fixtures │ │ ├── ERC20Artifact.json │ │ ├── cast_logs.stdout │ │ ├── keystore │ │ ├── UTC--2022-10-30T06-51-20.130356000Z--560d246fcddc9ea98a8b032c9a2f474efb493c28 │ │ ├── UTC--2022-12-20T10-30-43.591916000Z--ec554aeafe75601aaab43bd4621a22284db566c2 │ │ ├── password │ │ └── password-ec554 │ │ └── sign_typed_data.json ├── cheatcodes │ ├── Cargo.toml │ ├── README.md │ ├── assets │ │ ├── cheatcodes.json │ │ └── cheatcodes.schema.json │ ├── spec │ │ ├── Cargo.toml │ │ ├── README.md │ │ └── src │ │ │ ├── cheatcode.rs │ │ │ ├── function.rs │ │ │ ├── items.rs │ │ │ ├── lib.rs │ │ │ └── vm.rs │ └── src │ │ ├── base64.rs │ │ ├── config.rs │ │ ├── env.rs │ │ ├── error.rs │ │ ├── evm.rs │ │ ├── evm │ │ ├── fork.rs │ │ ├── mapping.rs │ │ ├── mock.rs │ │ └── prank.rs │ │ ├── fs.rs │ │ ├── inspector.rs │ │ ├── json.rs │ │ ├── lib.rs │ │ ├── script.rs │ │ ├── string.rs │ │ ├── test.rs │ │ ├── test │ │ ├── assert.rs │ │ └── expect.rs │ │ └── utils.rs ├── chisel │ ├── Cargo.toml │ ├── README.md │ ├── assets │ │ ├── preview.gif │ │ └── preview.tape │ ├── benches │ │ └── session_source.rs │ ├── bin │ │ └── main.rs │ ├── build.rs │ ├── src │ │ ├── cmd.rs │ │ ├── dispatcher.rs │ │ ├── executor.rs │ │ ├── history.rs │ │ ├── lib.rs │ │ ├── runner.rs │ │ ├── session.rs │ │ ├── session_source.rs │ │ └── solidity_helper.rs │ └── tests │ │ └── cache.rs ├── cli │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── handler.rs │ │ ├── lib.rs │ │ ├── opts │ │ ├── build │ │ │ ├── core.rs │ │ │ ├── mod.rs │ │ │ └── paths.rs │ │ ├── chain.rs │ │ ├── dependency.rs │ │ ├── ethereum.rs │ │ ├── mod.rs │ │ ├── transaction.rs │ │ └── wallet │ │ │ ├── error.rs │ │ │ ├── mod.rs │ │ │ └── multi_wallet.rs │ │ ├── stdin.rs │ │ └── utils │ │ ├── cmd.rs │ │ ├── mod.rs │ │ └── suggestions.rs ├── common │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── abi.rs │ │ ├── calc.rs │ │ ├── compile.rs │ │ ├── constants.rs │ │ ├── contracts.rs │ │ ├── errors │ │ ├── artifacts.rs │ │ ├── fs.rs │ │ └── mod.rs │ │ ├── evm.rs │ │ ├── fmt │ │ ├── console.rs │ │ ├── dynamic.rs │ │ ├── mod.rs │ │ └── ui.rs │ │ ├── fs.rs │ │ ├── glob.rs │ │ ├── lib.rs │ │ ├── provider │ │ ├── alloy.rs │ │ ├── ethers.rs │ │ ├── mod.rs │ │ ├── retry.rs │ │ ├── runtime_transport.rs │ │ └── tower.rs │ │ ├── retry.rs │ │ ├── rpc.rs │ │ ├── runtime_client.rs │ │ ├── selectors.rs │ │ ├── serde_helpers.rs │ │ ├── shell.rs │ │ ├── term.rs │ │ ├── traits.rs │ │ ├── transactions.rs │ │ ├── types.rs │ │ └── units.rs ├── config │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── cache.rs │ │ ├── doc.rs │ │ ├── endpoints.rs │ │ ├── error.rs │ │ ├── etherscan.rs │ │ ├── fix.rs │ │ ├── fmt.rs │ │ ├── fs_permissions.rs │ │ ├── fuzz.rs │ │ ├── inline │ │ ├── conf_parser.rs │ │ ├── error.rs │ │ ├── mod.rs │ │ └── natspec.rs │ │ ├── invariant.rs │ │ ├── lib.rs │ │ ├── macros.rs │ │ ├── providers │ │ ├── mod.rs │ │ └── remappings.rs │ │ ├── resolve.rs │ │ ├── utils.rs │ │ └── warning.rs ├── debugger │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── op.rs │ │ └── tui │ │ ├── builder.rs │ │ ├── context.rs │ │ ├── draw.rs │ │ └── mod.rs ├── doc │ ├── Cargo.toml │ ├── README.md │ ├── src │ │ ├── builder.rs │ │ ├── document.rs │ │ ├── helpers.rs │ │ ├── lib.rs │ │ ├── parser │ │ │ ├── comment.rs │ │ │ ├── error.rs │ │ │ ├── item.rs │ │ │ └── mod.rs │ │ ├── preprocessor │ │ │ ├── contract_inheritance.rs │ │ │ ├── deployments.rs │ │ │ ├── git_source.rs │ │ │ ├── infer_hyperlinks.rs │ │ │ ├── inheritdoc.rs │ │ │ └── mod.rs │ │ └── writer │ │ │ ├── as_doc.rs │ │ │ ├── buf_writer.rs │ │ │ ├── markdown.rs │ │ │ ├── mod.rs │ │ │ └── traits.rs │ └── static │ │ ├── book.css │ │ ├── book.toml │ │ └── solidity.min.js ├── evm │ ├── core │ │ ├── Cargo.toml │ │ ├── src │ │ │ ├── abi │ │ │ │ ├── HardhatConsole.json │ │ │ │ ├── console.rs │ │ │ │ ├── hardhat_console.rs │ │ │ │ └── mod.rs │ │ │ ├── backend │ │ │ │ ├── diagnostic.rs │ │ │ │ ├── error.rs │ │ │ │ ├── fuzz.rs │ │ │ │ ├── in_memory_db.rs │ │ │ │ ├── mod.rs │ │ │ │ └── snapshot.rs │ │ │ ├── constants.rs │ │ │ ├── debug.rs │ │ │ ├── decode.rs │ │ │ ├── fork │ │ │ │ ├── backend.rs │ │ │ │ ├── cache.rs │ │ │ │ ├── database.rs │ │ │ │ ├── init.rs │ │ │ │ ├── mod.rs │ │ │ │ └── multi.rs │ │ │ ├── ic.rs │ │ │ ├── lib.rs │ │ │ ├── opts.rs │ │ │ ├── snapshot.rs │ │ │ └── utils.rs │ │ └── test-data │ │ │ └── storage.json │ ├── coverage │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── analysis.rs │ │ │ ├── anchors.rs │ │ │ ├── inspector.rs │ │ │ └── lib.rs │ ├── evm │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── executors │ │ │ ├── builder.rs │ │ │ ├── fuzz │ │ │ │ ├── mod.rs │ │ │ │ └── types.rs │ │ │ ├── invariant │ │ │ │ ├── error.rs │ │ │ │ ├── funcs.rs │ │ │ │ └── mod.rs │ │ │ ├── mod.rs │ │ │ └── tracing.rs │ │ │ ├── inspectors │ │ │ ├── access_list.rs │ │ │ ├── chisel_state.rs │ │ │ ├── debugger.rs │ │ │ ├── logs.rs │ │ │ ├── mod.rs │ │ │ ├── printer.rs │ │ │ └── stack.rs │ │ │ └── lib.rs │ ├── fuzz │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── error.rs │ │ │ ├── inspector.rs │ │ │ ├── invariant │ │ │ ├── call_override.rs │ │ │ ├── filters.rs │ │ │ └── mod.rs │ │ │ ├── lib.rs │ │ │ └── strategies │ │ │ ├── calldata.rs │ │ │ ├── int.rs │ │ │ ├── invariants.rs │ │ │ ├── mod.rs │ │ │ ├── param.rs │ │ │ ├── state.rs │ │ │ └── uint.rs │ ├── test-data │ │ └── solc-obj.json │ └── traces │ │ ├── Cargo.toml │ │ └── src │ │ ├── decoder │ │ ├── mod.rs │ │ └── precompiles.rs │ │ ├── identifier │ │ ├── etherscan.rs │ │ ├── local.rs │ │ ├── mod.rs │ │ └── signatures.rs │ │ └── lib.rs ├── fmt │ ├── Cargo.toml │ ├── README.md │ ├── src │ │ ├── buffer.rs │ │ ├── chunk.rs │ │ ├── comments.rs │ │ ├── formatter.rs │ │ ├── helpers.rs │ │ ├── inline_config.rs │ │ ├── lib.rs │ │ ├── macros.rs │ │ ├── solang_ext │ │ │ ├── ast_eq.rs │ │ │ ├── loc.rs │ │ │ ├── mod.rs │ │ │ └── safe_unwrap.rs │ │ ├── string.rs │ │ └── visit.rs │ ├── testdata │ │ ├── Annotation │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ArrayExpressions │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── BlockComments │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── BlockCommentsFunction │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ConditionalOperatorExpression │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ConstructorDefinition │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ConstructorModifierStyle │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ContractDefinition │ │ │ ├── bracket-spacing.fmt.sol │ │ │ ├── contract-new-lines.fmt.sol │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── DoWhileStatement │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── DocComments │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ └── wrap-comments.fmt.sol │ │ ├── EmitStatement │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── EnumDefinition │ │ │ ├── bracket-spacing.fmt.sol │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── EnumVariants │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ErrorDefinition │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── EventDefinition │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ForStatement │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── FunctionCall │ │ │ ├── bracket-spacing.fmt.sol │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── FunctionCallArgsStatement │ │ │ ├── bracket-spacing.fmt.sol │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── FunctionDefinition │ │ │ ├── all.fmt.sol │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ ├── override-spacing.fmt.sol │ │ │ └── params-first.fmt.sol │ │ ├── FunctionDefinitionWithFunctionReturns │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── FunctionType │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── HexUnderscore │ │ │ ├── bytes.fmt.sol │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ ├── preserve.fmt.sol │ │ │ └── remove.fmt.sol │ │ ├── IfStatement │ │ │ ├── block-multi.fmt.sol │ │ │ ├── block-single.fmt.sol │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── IfStatement2 │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ImportDirective │ │ │ ├── bracket-spacing.fmt.sol │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ ├── preserve-quote.fmt.sol │ │ │ └── single-quote.fmt.sol │ │ ├── InlineDisable │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── IntTypes │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ ├── preserve.fmt.sol │ │ │ └── short.fmt.sol │ │ ├── LiteralExpression │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ ├── preserve-quote.fmt.sol │ │ │ └── single-quote.fmt.sol │ │ ├── MappingType │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ModifierDefinition │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ └── override-spacing.fmt.sol │ │ ├── NamedFunctionCallExpression │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── NumberLiteralUnderscore │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ ├── preserve.fmt.sol │ │ │ ├── remove.fmt.sol │ │ │ └── thousands.fmt.sol │ │ ├── OperatorExpressions │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── PragmaDirective │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── Repros │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ReturnStatement │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── RevertNamedArgsStatement │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── RevertStatement │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── SimpleComments │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ └── wrap-comments.fmt.sol │ │ ├── SortedImports │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── StatementBlock │ │ │ ├── bracket-spacing.fmt.sol │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── StructDefinition │ │ │ ├── bracket-spacing.fmt.sol │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── ThisExpression │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── TrailingComma │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── TryStatement │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── TypeDefinition │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── UnitExpression │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── UsingDirective │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── VariableAssignment │ │ │ ├── bracket-spacing.fmt.sol │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── VariableDefinition │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ └── override-spacing.fmt.sol │ │ ├── WhileStatement │ │ │ ├── block-multi.fmt.sol │ │ │ ├── block-single.fmt.sol │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ ├── Yul │ │ │ ├── fmt.sol │ │ │ └── original.sol │ │ └── YulStrings │ │ │ ├── fmt.sol │ │ │ ├── original.sol │ │ │ ├── preserve-quote.fmt.sol │ │ │ └── single-quote.fmt.sol │ └── tests │ │ └── formatter.rs ├── forge │ ├── Cargo.toml │ ├── README.md │ ├── assets │ │ ├── .gitignoreTemplate │ │ ├── CounterTemplate.s.sol │ │ ├── CounterTemplate.sol │ │ ├── CounterTemplate.t.sol │ │ ├── README.md │ │ ├── generated │ │ │ └── TestTemplate.t.sol │ │ └── workflowTemplate.yml │ ├── benches │ │ └── test.rs │ ├── bin │ │ ├── cmd │ │ │ ├── bind.rs │ │ │ ├── build.rs │ │ │ ├── cache.rs │ │ │ ├── config.rs │ │ │ ├── coverage.rs │ │ │ ├── create.rs │ │ │ ├── debug.rs │ │ │ ├── doc │ │ │ │ ├── mod.rs │ │ │ │ └── server.rs │ │ │ ├── flatten.rs │ │ │ ├── fmt.rs │ │ │ ├── geiger │ │ │ │ ├── error.rs │ │ │ │ ├── find.rs │ │ │ │ ├── mod.rs │ │ │ │ └── visitor.rs │ │ │ ├── generate │ │ │ │ └── mod.rs │ │ │ ├── init.rs │ │ │ ├── inspect.rs │ │ │ ├── install.rs │ │ │ ├── mod.rs │ │ │ ├── remappings.rs │ │ │ ├── remove.rs │ │ │ ├── retry.rs │ │ │ ├── script │ │ │ │ ├── artifacts.rs │ │ │ │ ├── broadcast.rs │ │ │ │ ├── build.rs │ │ │ │ ├── cmd.rs │ │ │ │ ├── executor.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── multi.rs │ │ │ │ ├── providers.rs │ │ │ │ ├── receipts.rs │ │ │ │ ├── runner.rs │ │ │ │ ├── sequence.rs │ │ │ │ ├── transaction.rs │ │ │ │ └── verify.rs │ │ │ ├── selectors.rs │ │ │ ├── snapshot.rs │ │ │ ├── test │ │ │ │ ├── filter.rs │ │ │ │ ├── mod.rs │ │ │ │ └── summary.rs │ │ │ ├── tree.rs │ │ │ ├── update.rs │ │ │ ├── verify │ │ │ │ ├── etherscan │ │ │ │ │ ├── flatten.rs │ │ │ │ │ ├── mod.rs │ │ │ │ │ └── standard_json.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── provider.rs │ │ │ │ └── sourcify.rs │ │ │ └── watch.rs │ │ ├── main.rs │ │ └── opts.rs │ ├── build.rs │ ├── src │ │ ├── coverage.rs │ │ ├── gas_report.rs │ │ ├── lib.rs │ │ ├── link.rs │ │ ├── multi_runner.rs │ │ ├── result.rs │ │ └── runner.rs │ └── tests │ │ ├── cli │ │ ├── build.rs │ │ ├── cache.rs │ │ ├── cmd.rs │ │ ├── config.rs │ │ ├── constants.rs │ │ ├── coverage.rs │ │ ├── create.rs │ │ ├── debug.rs │ │ ├── doc.rs │ │ ├── ext_integration.rs │ │ ├── main.rs │ │ ├── multi_script.rs │ │ ├── script.rs │ │ ├── svm.rs │ │ ├── test_cmd.rs │ │ ├── utils.rs │ │ └── verify.rs │ │ ├── fixtures │ │ ├── ScriptVerify.sol │ │ ├── can_build_skip_contracts.stdout │ │ ├── can_build_skip_glob.stdout │ │ ├── can_check_snapshot.stdout │ │ ├── can_create_template_contract-2nd.stdout │ │ ├── can_create_template_contract.stdout │ │ ├── can_create_using_unlocked-2nd.stdout │ │ ├── can_create_using_unlocked.stdout │ │ ├── can_create_with_constructor_args.stdout │ │ ├── can_create_with_tuple_constructor_args.stdout │ │ ├── can_detect_dirty_git_status_on_init.stderr │ │ ├── can_execute_script_and_skip_contracts.stdout │ │ ├── can_execute_script_command.stdout │ │ ├── can_execute_script_command_fqn.stdout │ │ ├── can_execute_script_command_with_args.stdout │ │ ├── can_execute_script_command_with_returned.stdout │ │ ├── can_execute_script_command_with_sig.stdout │ │ ├── can_run_test_in_custom_test_folder.stdout │ │ ├── can_set_yul_optimizer.stderr │ │ ├── can_test_repeatedly.stdout │ │ ├── can_use_libs_in_multi_fork.stdout │ │ ├── compile_json.stdout │ │ ├── include_custom_types_in_traces.stdout │ │ ├── repro_6531.stdout │ │ ├── runs_tests_exactly_once_with_changed_versions.1.stdout │ │ ├── runs_tests_exactly_once_with_changed_versions.2.stdout │ │ ├── suggest_when_no_tests_match.stdout │ │ ├── warn_no_tests.stdout │ │ └── warn_no_tests_match.stdout │ │ ├── it │ │ ├── cheats.rs │ │ ├── config.rs │ │ ├── core.rs │ │ ├── fork.rs │ │ ├── fs.rs │ │ ├── fuzz.rs │ │ ├── inline.rs │ │ ├── invariant.rs │ │ ├── main.rs │ │ ├── repros.rs │ │ ├── spec.rs │ │ └── test_helpers.rs │ │ └── rpc-cache-keyfile ├── macros │ ├── Cargo.toml │ └── src │ │ ├── cheatcodes.rs │ │ ├── console_fmt.rs │ │ └── lib.rs └── test-utils │ ├── Cargo.toml │ └── src │ ├── fd_lock.rs │ ├── filter.rs │ ├── lib.rs │ ├── macros.rs │ ├── script.rs │ └── util.rs ├── deny.toml ├── docs └── dev │ ├── README.md │ ├── architecture.md │ ├── cheatcodes.md │ ├── debugging.md │ └── scripting.md ├── flake.lock ├── flake.nix ├── foundryup ├── README.md ├── foundryup └── install ├── rustfmt.toml └── testdata ├── .gitignore ├── README.md ├── cheats ├── Addr.t.sol ├── Assert.t.sol ├── Assume.t.sol ├── Bank.t.sol ├── Base64.t.sol ├── Broadcast.t.sol ├── ChainId.t.sol ├── Cool.t.sol ├── Deal.t.sol ├── Derive.t.sol ├── Env.t.sol ├── Etch.t.sol ├── ExpectCall.t.sol ├── ExpectEmit.t.sol ├── ExpectRevert.t.sol ├── Fee.t.sol ├── Ffi.t.sol ├── Fork.t.sol ├── Fork2.t.sol ├── Fs.t.sol ├── GasMetering.t.sol ├── GetBlockTimestamp.t.sol ├── GetCode.t.sol ├── GetDeployedCode.t.sol ├── GetLabel.t.sol ├── GetNonce.t.sol ├── Json.t.sol ├── Label.t.sol ├── Load.t.sol ├── Mapping.t.sol ├── MemSafety.t.sol ├── MockCall.t.sol ├── Parse.t.sol ├── Prank.t.sol ├── Prevrandao.t.sol ├── ProjectRoot.t.sol ├── ReadCallers.t.sol ├── Record.t.sol ├── RecordAccountAccesses.t.sol ├── RecordLogs.t.sol ├── Remember.t.sol ├── ResetNonce.t.sol ├── Roll.t.sol ├── RpcUrls.t.sol ├── SetNonce.t.sol ├── SetNonceUnsafe.t.sol ├── Setup.t.sol ├── Sign.t.sol ├── SignP256.t.sol ├── Skip.t.sol ├── Sleep.t.sol ├── Snapshots.t.sol ├── Store.t.sol ├── StringUtils.t.sol ├── ToString.t.sol ├── Travel.t.sol ├── TryFfi.sol ├── UnixTime.t.sol ├── Vm.sol ├── Wallet.t.sol ├── Warp.t.sol ├── dumpState.t.sol ├── getBlockNumber.t.sol └── loadAllocs.t.sol ├── core ├── Abstract.t.sol ├── ContractEnvironment.t.sol ├── DSStyle.t.sol ├── FailingSetup.t.sol ├── FailingTestAfterFailedSetup.t.sol ├── MultipleSetup.t.sol ├── PaymentFailure.t.sol ├── Reverting.t.sol └── SetupConsistency.t.sol ├── fixtures ├── Derive │ ├── mnemonic_chinese_simplified.txt │ ├── mnemonic_chinese_traditional.txt │ ├── mnemonic_czech.txt │ ├── mnemonic_english.txt │ ├── mnemonic_french.txt │ ├── mnemonic_italian.txt │ ├── mnemonic_japanese.txt │ ├── mnemonic_korean.txt │ ├── mnemonic_portuguese.txt │ └── mnemonic_spanish.txt ├── Dir │ ├── depth1 │ └── nested │ │ ├── depth2 │ │ └── nested2 │ │ └── depth3 ├── File │ ├── read.txt │ └── symlink ├── GetCode │ ├── HardhatWorkingContract.json │ ├── HuffWorkingContract.json │ ├── Override.json │ ├── Override.sol │ ├── UnlinkedContract.sol │ ├── WorkingContract.json │ └── WorkingContract.sol ├── Json │ ├── Issue4630.json │ ├── test.json │ ├── test_allocs.json │ ├── wholeJson.json │ ├── write_complex_test.json │ └── write_test.json ├── Rpc │ ├── README.md │ ├── balance_params.json │ └── eth_getLogs.json ├── SolidityGeneration │ ├── Fastlane.json │ ├── GaugeController.json │ ├── GeneratedFastLane.sol │ ├── GeneratedGaugeController.sol │ ├── GeneratedLiquidityGaugeV4.sol │ ├── GeneratedNamedInterface.sol │ ├── GeneratedUnnamedInterface.sol │ ├── InterfaceABI.json │ ├── LiquidityGaugeV4.json │ ├── WithStructs.json │ └── WithStructs.sol ├── broadcast.log.json └── broadcast.sensitive.log.json ├── fork ├── DssExecLib.sol ├── ForkSame_1.t.sol ├── ForkSame_2.t.sol ├── LaunchFork.t.sol └── Transact.t.sol ├── foundry.toml ├── fs ├── Default.t.sol └── Disabled.t.sol ├── fuzz ├── Fuzz.t.sol ├── FuzzCollection.t.sol ├── FuzzInt.t.sol ├── FuzzUint.t.sol └── invariant │ ├── common │ ├── InvariantHandlerFailure.t.sol │ ├── InvariantInnerContract.t.sol │ ├── InvariantReentrancy.t.sol │ └── InvariantTest1.t.sol │ ├── storage │ └── InvariantStorageTest.t.sol │ ├── target │ ├── ExcludeContracts.t.sol │ ├── ExcludeSenders.t.sol │ ├── TargetContracts.t.sol │ ├── TargetInterfaces.t.sol │ ├── TargetSelectors.t.sol │ └── TargetSenders.t.sol │ └── targetAbi │ ├── ExcludeArtifacts.t.sol │ ├── TargetArtifactSelectors.t.sol │ ├── TargetArtifactSelectors2.t.sol │ └── TargetArtifacts.t.sol ├── inline ├── FuzzInlineConf.t.sol └── InvariantInlineConf.t.sol ├── lib └── ds-test │ └── src │ └── test.sol ├── linking ├── duplicate │ └── Duplicate.t.sol ├── nested │ └── Nested.t.sol └── simple │ └── Simple.t.sol ├── logs ├── DebugLogs.t.sol ├── HardhatLogs.t.sol └── console.sol ├── repros ├── Issue2623.t.sol ├── Issue2629.t.sol ├── Issue2723.t.sol ├── Issue2898.t.sol ├── Issue2956.t.sol ├── Issue2984.t.sol ├── Issue3055.t.sol ├── Issue3077.t.sol ├── Issue3110.t.sol ├── Issue3119.t.sol ├── Issue3189.t.sol ├── Issue3190.t.sol ├── Issue3192.t.sol ├── Issue3220.t.sol ├── Issue3221.t.sol ├── Issue3223.t.sol ├── Issue3347.t.sol ├── Issue3437.t.sol ├── Issue3596.t.sol ├── Issue3653.t.sol ├── Issue3661.t.sol ├── Issue3674.t.sol ├── Issue3685.t.sol ├── Issue3703.t.sol ├── Issue3708.t.sol ├── Issue3723.t.sol ├── Issue3753.t.sol ├── Issue3792.t.sol ├── Issue4586.t.sol ├── Issue4630.t.sol ├── Issue4640.t.sol ├── Issue4832.t.sol ├── Issue5038.t.sol ├── Issue5808.t.sol ├── Issue5929.t.sol ├── Issue5935.t.sol ├── Issue5948.t.sol ├── Issue6006.t.sol ├── Issue6032.t.sol ├── Issue6070.t.sol ├── Issue6115.t.sol ├── Issue6170.t.sol ├── Issue6180.t.sol ├── Issue6293.t.sol ├── Issue6355.t.sol ├── Issue6437.t.sol ├── Issue6501.t.sol ├── Issue6538.t.sol ├── Issue6554.t.sol ├── Issue6759.t.sol └── Issue6966.t.sol ├── script ├── broadcast │ └── deploy.sol │ │ └── 31337 │ │ └── run-latest.json └── deploy.sol ├── spec └── ShanghaiCompat.t.sol └── trace ├── ConflictingSignatures.t.sol └── Trace.t.sol /.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 | 5 | # Increase the stack size to 10MB for Windows targets, which is in line with Linux 6 | # (whereas default for Windows is 1MB). 7 | [target.x86_64-pc-windows-msvc] 8 | rustflags = ["-Clink-arg=/STACK:10000000"] 9 | 10 | [target.i686-pc-windows-msvc] 11 | rustflags = ["-Clink-arg=/STACK:10000000"] 12 | -------------------------------------------------------------------------------- /.config/nextest.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | retries = { backoff = "exponential", count = 2, delay = "2s", jitter = true } 3 | slow-timeout = { period = "1m", terminate-after = 3 } 4 | 5 | [[profile.default.overrides]] 6 | filter = "test(/ext_integration|can_test_forge_std/)" 7 | slow-timeout = { period = "5m", terminate-after = 4 } 8 | 9 | [[profile.default.overrides]] 10 | filter = "package(foundry-cheatcodes-spec)" 11 | retries = 0 12 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | target 2 | .github 3 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | crates/cheatcodes/assets/*.json linguist-generated 2 | testdata/cheats/Vm.sol linguist-generated 3 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @danipopes @evalir @mattsse 2 | 3 | crates/anvil/ @evalir @mattsse 4 | crates/evm/coverage/ @evalir @onbjerg 5 | crates/fmt/ @rkrasiuk 6 | crates/macros/impls/ @danipopes 7 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | ## Motivation 9 | 10 | 15 | 16 | ## Solution 17 | 18 | 22 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.github/changelog.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": [ 3 | { 4 | "title": "## Features", 5 | "labels": ["T-feature"] 6 | }, 7 | { 8 | "title": "## Fixes", 9 | "labels": ["T-bug", "T-fix"] 10 | } 11 | ], 12 | "ignore_labels": ["L-ignore"], 13 | "template": "${{CHANGELOG}}\n## Other\n\n${{UNCATEGORIZED}}", 14 | "pr_template": "- ${{TITLE}} (#${{NUMBER}})", 15 | "empty_template": "- No changes" 16 | } 17 | -------------------------------------------------------------------------------- /.github/compilation-benchmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/base/foundry/5ef0d6f22305b78ed240a7371be57108941f12cc/.github/compilation-benchmark.png -------------------------------------------------------------------------------- /.github/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/base/foundry/5ef0d6f22305b78ed240a7371be57108941f12cc/.github/demo.gif -------------------------------------------------------------------------------- /.github/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/base/foundry/5ef0d6f22305b78ed240a7371be57108941f12cc/.github/logo.png -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.github/workflows/deny.yml: -------------------------------------------------------------------------------- 1 | name: deny 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: [Cargo.lock, deny.toml] 7 | pull_request: 8 | branches: [master] 9 | paths: [Cargo.lock, deny.toml] 10 | 11 | env: 12 | CARGO_TERM_COLOR: always 13 | 14 | jobs: 15 | cargo-deny: 16 | name: cargo deny check 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 30 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: EmbarkStudios/cargo-deny-action@v1 22 | with: 23 | command: check all 24 | # Clear out arguments to not pass `--all-features` to `cargo deny`. 25 | # many crates have an `openssl` feature which enables banned dependencies 26 | arguments: "" 27 | -------------------------------------------------------------------------------- /.github/workflows/project.yml: -------------------------------------------------------------------------------- 1 | name: project 2 | 3 | on: 4 | issues: 5 | types: [opened, transferred] 6 | 7 | jobs: 8 | add-to-project: 9 | name: add issue 10 | runs-on: ubuntu-latest 11 | timeout-minutes: 30 12 | steps: 13 | - uses: actions/add-to-project@main 14 | with: 15 | project-url: https://github.com/orgs/foundry-rs/projects/2 16 | github-token: ${{ secrets.GH_PROJECTS_TOKEN }} 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_STORE 2 | /target 3 | out/ 4 | out.json 5 | .idea 6 | .vscode 7 | -------------------------------------------------------------------------------- /FUNDING.json: -------------------------------------------------------------------------------- 1 | { 2 | "drips": { 3 | "ethereum": { 4 | "ownedBy": "0x86308c59a6005d012C51Eef104bBc21786aC5D2E" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | msrv = "1.74" 2 | -------------------------------------------------------------------------------- /crates/anvil/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | vergen::EmitBuilder::builder().build_timestamp().git_sha(true).emit().unwrap(); 3 | } 4 | -------------------------------------------------------------------------------- /crates/anvil/core/src/eth/proof.rs: -------------------------------------------------------------------------------- 1 | //! Return types for `eth_getProof` 2 | 3 | use crate::eth::trie::KECCAK_NULL_RLP; 4 | use alloy_primitives::{B256, U256}; 5 | use revm::primitives::KECCAK_EMPTY; 6 | 7 | #[derive(Clone, Debug, PartialEq, Eq, alloy_rlp::RlpEncodable, alloy_rlp::RlpDecodable)] 8 | pub struct BasicAccount { 9 | pub nonce: U256, 10 | pub balance: U256, 11 | pub storage_root: B256, 12 | pub code_hash: B256, 13 | } 14 | 15 | impl Default for BasicAccount { 16 | fn default() -> Self { 17 | BasicAccount { 18 | balance: U256::ZERO, 19 | nonce: U256::ZERO, 20 | code_hash: KECCAK_EMPTY, 21 | storage_root: KECCAK_NULL_RLP, 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /crates/anvil/core/src/lib.rs: -------------------------------------------------------------------------------- 1 | /// Various Ethereum types 2 | pub mod eth; 3 | 4 | /// Additional useful types 5 | pub mod types; 6 | -------------------------------------------------------------------------------- /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 | [dependencies] 13 | serde.workspace = true 14 | serde_json.workspace = true 15 | 16 | [dev-dependencies] 17 | rand = "0.8" 18 | -------------------------------------------------------------------------------- /crates/anvil/rpc/src/lib.rs: -------------------------------------------------------------------------------- 1 | /// JSON-RPC request bindings 2 | pub mod request; 3 | 4 | /// JSON-RPC response bindings 5 | pub mod response; 6 | 7 | /// JSON-RPC error bindings 8 | pub mod error; 9 | -------------------------------------------------------------------------------- /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/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 executor; 12 | pub mod fork; 13 | pub mod genesis; 14 | pub mod info; 15 | pub mod notifications; 16 | pub mod validate; 17 | -------------------------------------------------------------------------------- /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/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/anvil/src/eth/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod api; 2 | pub mod otterscan; 3 | pub mod sign; 4 | pub use api::EthApi; 5 | 6 | pub mod backend; 7 | 8 | pub mod error; 9 | 10 | pub mod fees; 11 | pub(crate) mod macros; 12 | pub mod miner; 13 | pub mod pool; 14 | pub mod util; 15 | -------------------------------------------------------------------------------- /crates/anvil/src/eth/otterscan/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod api; 2 | pub mod types; 3 | -------------------------------------------------------------------------------- /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/anvil/test-data/SimpleStorage.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.24; 2 | 3 | contract SimpleStorage { 4 | 5 | event ValueChanged(address indexed author, address indexed oldAuthor, string oldValue, string newValue); 6 | 7 | address public lastSender; 8 | string _value; 9 | string _otherValue; 10 | 11 | constructor(string memory value) public { 12 | emit ValueChanged(msg.sender, address(0), _value, value); 13 | _value = value; 14 | } 15 | 16 | function getValue() view public returns (string memory) { 17 | return _value; 18 | } 19 | 20 | function setValue(string memory value) public { 21 | emit ValueChanged(msg.sender, lastSender, _value, value); 22 | _value = value; 23 | lastSender = msg.sender; 24 | } 25 | 26 | function setValues(string memory value, string memory value2) public { 27 | _value = value; 28 | _otherValue = value2; 29 | lastSender = msg.sender; 30 | } 31 | 32 | function _hashPuzzle() public view returns (uint256) { 33 | return 100; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /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/anvil/tests/it/main.rs: -------------------------------------------------------------------------------- 1 | mod abi; 2 | mod anvil; 3 | mod anvil_api; 4 | mod api; 5 | mod fork; 6 | mod ganache; 7 | mod gas; 8 | mod genesis; 9 | mod geth; 10 | mod ipc; 11 | mod logs; 12 | mod optimism; 13 | mod proof; 14 | mod pubsub; 15 | // mod revert; // TODO uncomment 16 | mod otterscan; 17 | 18 | mod sign; 19 | mod state; 20 | mod traces; 21 | mod transaction; 22 | mod txpool; 23 | pub mod utils; 24 | mod wsapi; 25 | 26 | #[allow(unused)] 27 | pub(crate) fn init_tracing() { 28 | let _ = tracing_subscriber::FmtSubscriber::builder() 29 | .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) 30 | .try_init(); 31 | } 32 | 33 | fn main() {} 34 | -------------------------------------------------------------------------------- /crates/anvil/tests/it/state.rs: -------------------------------------------------------------------------------- 1 | //! general eth api tests 2 | 3 | use anvil::{spawn, NodeConfig}; 4 | 5 | #[tokio::test(flavor = "multi_thread")] 6 | async fn can_load_state() { 7 | let tmp = tempfile::tempdir().unwrap(); 8 | let state_file = tmp.path().join("state.json"); 9 | 10 | let (api, _handle) = spawn(NodeConfig::test()).await; 11 | 12 | api.mine_one().await; 13 | 14 | let num = api.block_number().unwrap(); 15 | 16 | let state = api.serialized_state().await.unwrap(); 17 | foundry_common::fs::write_json_file(&state_file, &state).unwrap(); 18 | 19 | let (api, _handle) = spawn(NodeConfig::test().with_init_state_path(state_file)).await; 20 | 21 | let num2 = api.block_number().unwrap(); 22 | assert_eq!(num, num2); 23 | } 24 | -------------------------------------------------------------------------------- /crates/anvil/tests/it/wsapi.rs: -------------------------------------------------------------------------------- 1 | //! general eth api tests with websocket provider 2 | 3 | use alloy_providers::provider::TempProvider; 4 | use anvil::{spawn, NodeConfig}; 5 | use ethers::types::U256; 6 | use foundry_common::types::ToAlloy; 7 | 8 | #[tokio::test(flavor = "multi_thread")] 9 | async fn can_get_block_number_ws() { 10 | let (api, handle) = spawn(NodeConfig::test()).await; 11 | let block_num = api.block_number().unwrap(); 12 | assert_eq!(block_num, U256::zero().to_alloy()); 13 | 14 | let provider = handle.ws_provider(); 15 | 16 | let num = provider.get_block_number().await.unwrap(); 17 | assert_eq!(num, block_num.to::()); 18 | } 19 | 20 | #[tokio::test(flavor = "multi_thread")] 21 | async fn can_dev_get_balance_ws() { 22 | let (_api, handle) = spawn(NodeConfig::test()).await; 23 | let provider = handle.ws_provider(); 24 | 25 | let genesis_balance = handle.genesis_balance(); 26 | for acc in handle.genesis_accounts() { 27 | let balance = provider.get_balance(acc, None).await.unwrap(); 28 | assert_eq!(balance, genesis_balance); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /crates/cast/README.md: -------------------------------------------------------------------------------- 1 | # `cast` 2 | 3 | Cast is a command-line tool for performing Ethereum RPC calls. You can make smart contract calls, send transactions, or retrieve any type of chain data - all from your command-line! 4 | 5 | For more information, see the [📖 Foundry Book (Cast Guide)](https://book.getfoundry.sh/cast/index.html). 6 | -------------------------------------------------------------------------------- /crates/cast/bin/cmd/mod.rs: -------------------------------------------------------------------------------- 1 | //! Subcommands for cast 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 bind; 10 | pub mod call; 11 | pub mod create2; 12 | pub mod estimate; 13 | pub mod find_block; 14 | pub mod interface; 15 | pub mod logs; 16 | pub mod rpc; 17 | pub mod run; 18 | pub mod send; 19 | pub mod storage; 20 | pub mod wallet; 21 | -------------------------------------------------------------------------------- /crates/cast/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | vergen::EmitBuilder::builder().build_timestamp().git_sha(true).emit().unwrap(); 3 | } 4 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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} -------------------------------------------------------------------------------- /crates/cast/tests/fixtures/keystore/password: -------------------------------------------------------------------------------- 1 | this is keystore password 2 | -------------------------------------------------------------------------------- /crates/cast/tests/fixtures/keystore/password-ec554: -------------------------------------------------------------------------------- 1 | keystorepassword -------------------------------------------------------------------------------- /crates/cast/tests/fixtures/sign_typed_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "types": { 3 | "EIP712Domain": [ 4 | { 5 | "name": "name", 6 | "type": "string" 7 | }, 8 | { 9 | "name": "version", 10 | "type": "string" 11 | }, 12 | { 13 | "name": "chainId", 14 | "type": "uint256" 15 | }, 16 | { 17 | "name": "verifyingContract", 18 | "type": "address" 19 | } 20 | ], 21 | "Message": [ 22 | { 23 | "name": "data", 24 | "type": "string" 25 | } 26 | ] 27 | }, 28 | "primaryType": "Message", 29 | "domain": { 30 | "name": "example.metamask.io", 31 | "version": "1", 32 | "chainId": "1", 33 | "verifyingContract": "0x0000000000000000000000000000000000000000" 34 | }, 35 | "message": { 36 | "data": "Hello!" 37 | } 38 | } -------------------------------------------------------------------------------- /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 | [dependencies] 15 | foundry-macros.workspace = true 16 | alloy-sol-types = { workspace = true, features = ["json"] } 17 | serde.workspace = true 18 | 19 | # schema 20 | schemars = { version = "0.8.15", optional = true } 21 | 22 | [dev-dependencies] 23 | serde_json.workspace = true 24 | 25 | [features] 26 | schema = ["dep:schemars"] 27 | -------------------------------------------------------------------------------- /crates/cheatcodes/spec/README.md: -------------------------------------------------------------------------------- 1 | # foundry-cheatcodes-spec 2 | 3 | Minimal crate to provide a cheatcodes specification. 4 | -------------------------------------------------------------------------------- /crates/cheatcodes/src/base64.rs: -------------------------------------------------------------------------------- 1 | use crate::{Cheatcode, Cheatcodes, Result, Vm::*}; 2 | use alloy_sol_types::SolValue; 3 | use base64::prelude::*; 4 | 5 | impl Cheatcode for toBase64_0Call { 6 | fn apply(&self, _state: &mut Cheatcodes) -> Result { 7 | let Self { data } = self; 8 | Ok(BASE64_STANDARD.encode(data).abi_encode()) 9 | } 10 | } 11 | 12 | impl Cheatcode for toBase64_1Call { 13 | fn apply(&self, _state: &mut Cheatcodes) -> Result { 14 | let Self { data } = self; 15 | Ok(BASE64_STANDARD.encode(data).abi_encode()) 16 | } 17 | } 18 | 19 | impl Cheatcode for toBase64URL_0Call { 20 | fn apply(&self, _state: &mut Cheatcodes) -> Result { 21 | let Self { data } = self; 22 | Ok(BASE64_URL_SAFE.encode(data).abi_encode()) 23 | } 24 | } 25 | 26 | impl Cheatcode for toBase64URL_1Call { 27 | fn apply(&self, _state: &mut Cheatcodes) -> Result { 28 | let Self { data } = self; 29 | Ok(BASE64_URL_SAFE.encode(data).abi_encode()) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /crates/chisel/assets/preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/base/foundry/5ef0d6f22305b78ed240a7371be57108941f12cc/crates/chisel/assets/preview.gif -------------------------------------------------------------------------------- /crates/chisel/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | vergen::EmitBuilder::builder().build_timestamp().git_sha(true).emit().unwrap(); 3 | } 4 | -------------------------------------------------------------------------------- /crates/chisel/src/history.rs: -------------------------------------------------------------------------------- 1 | //! chisel history file 2 | 3 | use std::path::PathBuf; 4 | 5 | /// The name of the chisel history file 6 | pub const CHISEL_HISTORY_FILE_NAME: &str = ".chisel_history"; 7 | 8 | /// Returns the path to foundry's global toml file that's stored at `~/.foundry/.chisel_history` 9 | pub fn chisel_history_file() -> Option { 10 | foundry_config::Config::foundry_dir().map(|p| p.join(CHISEL_HISTORY_FILE_NAME)) 11 | } 12 | -------------------------------------------------------------------------------- /crates/chisel/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | #![warn(missing_docs)] 3 | #![warn(unused_extern_crates)] 4 | #![forbid(unsafe_code)] 5 | #![forbid(where_clauses_object_safety)] 6 | 7 | /// REPL input dispatcher module 8 | pub mod dispatcher; 9 | 10 | /// Builtin Chisel commands 11 | pub mod cmd; 12 | 13 | pub mod history; 14 | 15 | /// Chisel Environment Module 16 | pub mod session; 17 | 18 | /// Chisel Session Source wrapper 19 | pub mod session_source; 20 | 21 | /// REPL contract runner 22 | pub mod runner; 23 | 24 | /// REPL contract executor 25 | pub mod executor; 26 | 27 | /// A Solidity Helper module for rustyline 28 | pub mod solidity_helper; 29 | 30 | /// Prelude of all chisel modules 31 | pub mod prelude { 32 | pub use crate::{ 33 | cmd::*, dispatcher::*, runner::*, session::*, session_source::*, solidity_helper::*, 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /crates/cli/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![warn(unused_crate_dependencies)] 2 | 3 | #[macro_use] 4 | extern crate tracing; 5 | 6 | pub mod handler; 7 | pub mod opts; 8 | pub mod stdin; 9 | pub mod utils; 10 | -------------------------------------------------------------------------------- /crates/cli/src/opts/mod.rs: -------------------------------------------------------------------------------- 1 | mod build; 2 | mod chain; 3 | mod dependency; 4 | mod ethereum; 5 | mod transaction; 6 | mod wallet; 7 | 8 | pub use build::*; 9 | pub use chain::*; 10 | pub use dependency::*; 11 | pub use ethereum::*; 12 | pub use transaction::*; 13 | pub use wallet::*; 14 | -------------------------------------------------------------------------------- /crates/cli/src/opts/wallet/error.rs: -------------------------------------------------------------------------------- 1 | //! Errors when working with wallets 2 | 3 | use hex::FromHexError; 4 | 5 | #[derive(Debug, thiserror::Error)] 6 | pub enum PrivateKeyError { 7 | #[error("Failed to create wallet from private key. Private key is invalid hex: {0}")] 8 | InvalidHex(#[from] FromHexError), 9 | #[error("Failed to create wallet from private key. Invalid private key. But env var {0} exists. Is the `$` anchor missing?")] 10 | ExistsAsEnvVar(String), 11 | } 12 | -------------------------------------------------------------------------------- /crates/common/README.md: -------------------------------------------------------------------------------- 1 | Common utilities for building and using foundry's tools. 2 | -------------------------------------------------------------------------------- /crates/common/src/errors/artifacts.rs: -------------------------------------------------------------------------------- 1 | //! Errors that can occur when working with `solc` artifacts 2 | 3 | /// Error when encountering unlinked code 4 | #[derive(Clone, Debug, thiserror::Error)] 5 | pub enum UnlinkedByteCode { 6 | /// `bytecode` is unlinked 7 | #[error("Contract `{0}` has unlinked bytecode. Please check all libraries settings.")] 8 | Bytecode(String), 9 | /// `deployedBytecode` is unlinked 10 | #[error("Contract `{0}` has unlinked deployed Bytecode. Please check all libraries settings.")] 11 | DeployedBytecode(String), 12 | } 13 | -------------------------------------------------------------------------------- /crates/common/src/errors/mod.rs: -------------------------------------------------------------------------------- 1 | //! Commonly used errors 2 | 3 | mod fs; 4 | pub use fs::FsPathError; 5 | 6 | mod artifacts; 7 | pub use artifacts::*; 8 | -------------------------------------------------------------------------------- /crates/common/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Common utilities for building and using foundry's tools. 2 | 3 | #![warn(missing_docs, unused_crate_dependencies)] 4 | 5 | extern crate self as foundry_common; 6 | 7 | #[macro_use] 8 | extern crate tracing; 9 | 10 | pub mod abi; 11 | pub mod calc; 12 | pub mod compile; 13 | pub mod constants; 14 | pub mod contracts; 15 | pub mod errors; 16 | pub mod evm; 17 | pub mod fmt; 18 | pub mod fs; 19 | pub mod glob; 20 | pub mod provider; 21 | pub mod retry; 22 | pub mod rpc; 23 | pub mod runtime_client; 24 | pub mod selectors; 25 | pub mod serde_helpers; 26 | pub mod shell; 27 | pub mod term; 28 | pub mod traits; 29 | pub mod transactions; 30 | pub mod types; 31 | 32 | pub use constants::*; 33 | pub use contracts::*; 34 | pub use traits::*; 35 | pub use transactions::*; 36 | -------------------------------------------------------------------------------- /crates/common/src/provider/mod.rs: -------------------------------------------------------------------------------- 1 | //! Provider-related instantiation and usage utilities. 2 | 3 | pub mod alloy; 4 | pub mod ethers; 5 | pub mod retry; 6 | pub mod runtime_transport; 7 | pub mod tower; 8 | -------------------------------------------------------------------------------- /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 | [dependencies] 13 | foundry-common.workspace = true 14 | foundry-compilers.workspace = true 15 | foundry-evm-core.workspace = true 16 | foundry-evm-traces.workspace = true 17 | revm-inspectors.workspace = true 18 | 19 | alloy-primitives.workspace = true 20 | 21 | crossterm = "0.27" 22 | eyre.workspace = true 23 | ratatui = { version = "0.24.0", default-features = false, features = ["crossterm"] } 24 | revm.workspace = true 25 | tracing.workspace = true 26 | -------------------------------------------------------------------------------- /crates/debugger/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # foundry-debugger 2 | //! 3 | //! Interactive Solidity TUI debugger. 4 | 5 | #![warn(unused_crate_dependencies, unreachable_pub)] 6 | 7 | #[macro_use] 8 | extern crate tracing; 9 | 10 | mod op; 11 | 12 | mod tui; 13 | pub use tui::{Debugger, DebuggerBuilder, ExitReason}; 14 | -------------------------------------------------------------------------------- /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 | [dependencies] 14 | forge-fmt.workspace = true 15 | foundry-common.workspace = true 16 | foundry-compilers.workspace = true 17 | foundry-config.workspace = true 18 | 19 | alloy-primitives.workspace = true 20 | 21 | auto_impl = "1" 22 | derive_more = "0.99" 23 | eyre.workspace = true 24 | itertools.workspace = true 25 | mdbook = { version = "0.4", default-features = false, features = ["search"] } 26 | once_cell = "1" 27 | rayon = "1" 28 | serde_json.workspace = true 29 | serde.workspace = true 30 | solang-parser.workspace = true 31 | thiserror = "1" 32 | toml.workspace = true 33 | tracing.workspace = true 34 | regex = "1.10.2" 35 | -------------------------------------------------------------------------------- /crates/doc/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! The module for generating Solidity documentation. 2 | //! 3 | //! See [DocBuilder] 4 | 5 | #![warn(missing_debug_implementations, missing_docs, unreachable_pub, unused_crate_dependencies)] 6 | #![deny(unused_must_use, rust_2018_idioms)] 7 | #![doc(test( 8 | no_crate_inject, 9 | attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) 10 | ))] 11 | 12 | #[macro_use] 13 | extern crate tracing; 14 | 15 | mod builder; 16 | pub use builder::DocBuilder; 17 | 18 | mod document; 19 | pub use document::Document; 20 | 21 | mod helpers; 22 | 23 | mod parser; 24 | pub use parser::{ 25 | error, Comment, CommentTag, Comments, CommentsRef, ParseItem, ParseSource, Parser, 26 | }; 27 | 28 | mod preprocessor; 29 | pub use preprocessor::*; 30 | 31 | mod writer; 32 | pub use writer::{AsDoc, AsDocResult, BufWriter, Markdown}; 33 | 34 | pub use mdbook; 35 | -------------------------------------------------------------------------------- /crates/doc/src/parser/error.rs: -------------------------------------------------------------------------------- 1 | use forge_fmt::FormatterError; 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(#[from] FormatterError), 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 | -------------------------------------------------------------------------------- /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/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/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 | 10 | [output.html.fold] 11 | enable = true 12 | -------------------------------------------------------------------------------- /crates/evm/core/src/abi/mod.rs: -------------------------------------------------------------------------------- 1 | //! Several ABI-related utilities for executors. 2 | 3 | pub use foundry_cheatcodes_spec::Vm; 4 | 5 | mod console; 6 | pub use console::{format_units_int, format_units_uint, Console}; 7 | 8 | mod hardhat_console; 9 | pub use hardhat_console::{ 10 | hh_console_selector, patch_hh_console_selector, HardhatConsole, 11 | HARDHAT_CONSOLE_SELECTOR_PATCHES, 12 | }; 13 | -------------------------------------------------------------------------------- /crates/evm/core/src/fork/mod.rs: -------------------------------------------------------------------------------- 1 | use super::opts::EvmOpts; 2 | use revm::primitives::Env; 3 | 4 | mod backend; 5 | pub use backend::{BackendHandler, SharedBackend}; 6 | 7 | mod init; 8 | pub use init::environment; 9 | 10 | mod cache; 11 | pub use cache::{BlockchainDb, BlockchainDbMeta, JsonBlockCacheDB, MemDb}; 12 | 13 | pub mod database; 14 | 15 | mod multi; 16 | pub use multi::{ForkId, MultiFork, MultiForkHandler}; 17 | 18 | /// Represents a _fork_ of a remote chain whose data is available only via the `url` endpoint. 19 | #[derive(Clone, Debug)] 20 | pub struct CreateFork { 21 | /// Whether to enable rpc storage caching for this fork 22 | pub enable_caching: bool, 23 | /// The URL to a node for fetching remote state 24 | pub url: String, 25 | /// The env to create this fork, main purpose is to provide some metadata for the fork 26 | pub env: Env, 27 | /// All env settings as configured by the user 28 | pub evm_opts: EvmOpts, 29 | } 30 | -------------------------------------------------------------------------------- /crates/evm/core/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # foundry-evm-core 2 | //! 3 | //! Core EVM abstractions. 4 | 5 | #![warn(unused_crate_dependencies)] 6 | 7 | #[macro_use] 8 | extern crate tracing; 9 | 10 | mod ic; 11 | 12 | pub mod abi; 13 | pub mod backend; 14 | pub mod constants; 15 | pub mod debug; 16 | pub mod decode; 17 | pub mod fork; 18 | pub mod opts; 19 | pub mod snapshot; 20 | pub mod utils; 21 | -------------------------------------------------------------------------------- /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/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 | [dependencies] 14 | foundry-common.workspace = true 15 | foundry-compilers.workspace = true 16 | foundry-evm-core.workspace = true 17 | 18 | alloy-primitives.workspace = true 19 | eyre = "0.6" 20 | revm.workspace = true 21 | semver = "1" 22 | tracing = "0.1" 23 | -------------------------------------------------------------------------------- /crates/evm/coverage/src/inspector.rs: -------------------------------------------------------------------------------- 1 | use crate::{HitMap, HitMaps}; 2 | use alloy_primitives::Bytes; 3 | use revm::{interpreter::Interpreter, Database, EVMData, Inspector}; 4 | 5 | #[derive(Clone, Debug, Default)] 6 | pub struct CoverageCollector { 7 | /// Maps that track instruction hit data. 8 | pub maps: HitMaps, 9 | } 10 | 11 | impl Inspector for CoverageCollector { 12 | #[inline] 13 | fn initialize_interp(&mut self, interpreter: &mut Interpreter<'_>, _: &mut EVMData<'_, DB>) { 14 | let hash = interpreter.contract.hash; 15 | self.maps.entry(hash).or_insert_with(|| { 16 | HitMap::new(Bytes::copy_from_slice( 17 | interpreter.contract.bytecode.original_bytecode_slice(), 18 | )) 19 | }); 20 | } 21 | 22 | #[inline] 23 | fn step(&mut self, interpreter: &mut Interpreter<'_>, _: &mut EVMData<'_, DB>) { 24 | let hash = interpreter.contract.hash; 25 | self.maps.entry(hash).and_modify(|map| map.hit(interpreter.program_counter())); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /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::CoverageCollector; 5 | pub use foundry_evm_fuzz::Fuzzer; 6 | pub use foundry_evm_traces::{StackSnapshotType, TracingInspector, TracingInspectorConfig}; 7 | 8 | mod access_list; 9 | pub use access_list::AccessListTracer; 10 | 11 | mod chisel_state; 12 | pub use chisel_state::ChiselState; 13 | 14 | mod debugger; 15 | pub use debugger::Debugger; 16 | 17 | mod logs; 18 | pub use logs::LogCollector; 19 | 20 | mod printer; 21 | pub use printer::TracePrinter; 22 | 23 | mod stack; 24 | pub use stack::{InspectorData, InspectorStack, InspectorStackBuilder}; 25 | -------------------------------------------------------------------------------- /crates/evm/evm/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # foundry-evm 2 | //! 3 | //! Main Foundry EVM backend abstractions. 4 | 5 | #![warn(unreachable_pub, unused_crate_dependencies, rust_2018_idioms)] 6 | 7 | #[macro_use] 8 | extern crate tracing; 9 | 10 | pub mod executors; 11 | pub mod inspectors; 12 | 13 | pub use foundry_evm_core::{backend, constants, debug, decode, fork, opts, utils}; 14 | pub use foundry_evm_coverage as coverage; 15 | pub use foundry_evm_fuzz as fuzz; 16 | pub use foundry_evm_traces as traces; 17 | 18 | // TODO: We should probably remove these, but it's a pretty big breaking change. 19 | #[doc(hidden)] 20 | pub use {hashbrown, revm}; 21 | -------------------------------------------------------------------------------- /crates/evm/fuzz/src/error.rs: -------------------------------------------------------------------------------- 1 | //! errors related to fuzz tests 2 | use proptest::test_runner::Reason; 3 | 4 | /// Possible errors when running fuzz tests 5 | #[derive(Debug, thiserror::Error)] 6 | pub enum FuzzError { 7 | #[error("Couldn't call unknown contract")] 8 | UnknownContract, 9 | #[error("Failed contract call")] 10 | FailedContractCall, 11 | #[error("Empty state changeset")] 12 | EmptyChangeset, 13 | #[error("`vm.assume` reject")] 14 | AssumeReject, 15 | #[error("The `vm.assume` cheatcode rejected too many inputs ({0} allowed)")] 16 | TooManyRejects(u32), 17 | } 18 | 19 | impl From for Reason { 20 | fn from(error: FuzzError) -> Self { 21 | error.to_string().into() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /crates/evm/fuzz/src/invariant/mod.rs: -------------------------------------------------------------------------------- 1 | use alloy_json_abi::{Function, JsonAbi}; 2 | use alloy_primitives::{Address, Bytes}; 3 | use parking_lot::Mutex; 4 | use std::{collections::BTreeMap, sync::Arc}; 5 | 6 | mod call_override; 7 | pub use call_override::RandomCallGenerator; 8 | 9 | mod filters; 10 | pub use filters::{ArtifactFilters, SenderFilters}; 11 | 12 | pub type TargetedContracts = BTreeMap)>; 13 | pub type FuzzRunIdentifiedContracts = Arc>; 14 | 15 | /// (Sender, (TargetContract, Calldata)) 16 | pub type BasicTxDetails = (Address, (Address, Bytes)); 17 | 18 | /// Test contract which is testing its invariants. 19 | #[derive(Clone, Debug)] 20 | pub struct InvariantContract<'a> { 21 | /// Address of the test contract. 22 | pub address: Address, 23 | /// Invariant function present in the test contract. 24 | pub invariant_function: &'a Function, 25 | /// ABI of the test contract. 26 | pub abi: &'a JsonAbi, 27 | } 28 | -------------------------------------------------------------------------------- /crates/evm/fuzz/src/strategies/calldata.rs: -------------------------------------------------------------------------------- 1 | use super::fuzz_param; 2 | use alloy_dyn_abi::JsonAbiExt; 3 | use alloy_json_abi::Function; 4 | use alloy_primitives::Bytes; 5 | use proptest::prelude::{BoxedStrategy, Strategy}; 6 | 7 | /// Given a function, it returns a strategy which generates valid calldata 8 | /// for that function's input types. 9 | pub fn fuzz_calldata(func: Function) -> BoxedStrategy { 10 | // We need to compose all the strategies generated for each parameter in all 11 | // possible combinations 12 | let strats = func 13 | .inputs 14 | .iter() 15 | .map(|input| fuzz_param(&input.selector_type().parse().unwrap())) 16 | .collect::>(); 17 | 18 | strats 19 | .prop_map(move |tokens| { 20 | trace!(input=?tokens); 21 | func.abi_encode_input(&tokens).unwrap().into() 22 | }) 23 | .boxed() 24 | } 25 | -------------------------------------------------------------------------------- /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}; 9 | 10 | mod calldata; 11 | pub use calldata::fuzz_calldata; 12 | 13 | mod state; 14 | pub use state::{ 15 | build_initial_state, collect_created_contracts, collect_state_from_call, 16 | fuzz_calldata_from_state, EvmFuzzState, 17 | }; 18 | 19 | mod invariants; 20 | pub use invariants::{fuzz_contract_with_calldata, invariant_strat, override_call_strat}; 21 | -------------------------------------------------------------------------------- /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 | [dependencies] 13 | foundry-config.workspace = true 14 | 15 | alloy-primitives.workspace = true 16 | 17 | ariadne = "0.3" 18 | itertools.workspace = true 19 | solang-parser.workspace = true 20 | thiserror = "1" 21 | tracing.workspace = true 22 | 23 | [dev-dependencies] 24 | itertools.workspace = true 25 | pretty_assertions.workspace = true 26 | toml.workspace = true 27 | tracing-subscriber = { workspace = true, features = ["env-filter"] } 28 | -------------------------------------------------------------------------------- /crates/fmt/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 3 | 4 | #[macro_use] 5 | extern crate tracing; 6 | 7 | mod buffer; 8 | pub mod chunk; 9 | mod comments; 10 | mod formatter; 11 | mod helpers; 12 | pub mod inline_config; 13 | mod macros; 14 | pub mod solang_ext; 15 | mod string; 16 | pub mod visit; 17 | 18 | pub use foundry_config::fmt::*; 19 | 20 | pub use comments::Comments; 21 | pub use formatter::{Formatter, FormatterError}; 22 | pub use helpers::{ 23 | format, format_to, offset_to_line_column, parse, print_diagnostics_report, Parsed, 24 | }; 25 | pub use inline_config::InlineConfig; 26 | pub use visit::{Visitable, Visitor}; 27 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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/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) Ownable() ERC1155() {} 13 | } 14 | -------------------------------------------------------------------------------- /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) Ownable() ERC1155() {} 13 | } 14 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ContractDefinition/original.sol: -------------------------------------------------------------------------------- 1 | contract ContractDefinition is Contract1, Contract2, Contract3, Contract4, Contract5 { 2 | } 3 | 4 | // comment 7 5 | contract SampleContract { 6 | 7 | // spaced comment 1 8 | 9 | // spaced comment 2 10 | // that spans multiple lines 11 | 12 | // comment 8 13 | constructor() { /* comment 9 */ } // comment 10 14 | 15 | // comment 11 16 | function max(/* comment 13 */ uint256 arg1, uint256 /* comment 14 */ arg2, uint256 /* comment 15 */) 17 | // comment 16 18 | external /* comment 17 */ 19 | pure 20 | returns(uint256) 21 | // comment 18 22 | { // comment 19 23 | return arg1 > arg2 ? arg1 : arg2; 24 | } 25 | } 26 | 27 | // comment 20 28 | contract /* comment 21 */ ExampleContract /* comment 22 */ is SampleContract {} 29 | 30 | contract ERC20DecimalsMock is ERC20 { 31 | uint8 private immutable _decimals; 32 | 33 | constructor( 34 | string memory name_, 35 | string memory symbol_, 36 | uint8 decimals_ 37 | ) ERC20(name_, symbol_) { 38 | _decimals = decimals_; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /crates/fmt/testdata/EmitStatement/fmt.sol: -------------------------------------------------------------------------------- 1 | // config: line_length = 80 2 | event NewEvent( 3 | address beneficiary, uint256 index, uint64 timestamp, uint64 endTimestamp 4 | ); 5 | 6 | function emitEvent() { 7 | emit NewEvent( 8 | beneficiary, 9 | _vestingBeneficiaries.length - 1, 10 | uint64(block.timestamp), 11 | endTimestamp 12 | ); 13 | 14 | emit NewEvent( 15 | /* beneficiary */ 16 | beneficiary, 17 | /* index */ 18 | _vestingBeneficiaries.length - 1, 19 | /* timestamp */ 20 | uint64(block.timestamp), 21 | /* end timestamp */ 22 | endTimestamp 23 | ); 24 | 25 | emit NewEvent( 26 | beneficiary, // beneficiary 27 | _vestingBeneficiaries.length - 1, // index 28 | uint64(block.timestamp), // timestamp 29 | endTimestamp // end timestamp 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /crates/fmt/testdata/EmitStatement/original.sol: -------------------------------------------------------------------------------- 1 | event NewEvent(address beneficiary, uint256 index, uint64 timestamp, uint64 endTimestamp); 2 | 3 | function emitEvent() { 4 | emit NewEvent( 5 | beneficiary, 6 | _vestingBeneficiaries.length - 1, 7 | uint64(block.timestamp), 8 | endTimestamp 9 | ); 10 | 11 | emit 12 | NewEvent( 13 | /* beneficiary */ beneficiary, 14 | /* index */ _vestingBeneficiaries.length - 1, 15 | /* timestamp */ uint64(block.timestamp), 16 | /* end timestamp */ endTimestamp); 17 | 18 | emit NewEvent( 19 | beneficiary, // beneficiary 20 | _vestingBeneficiaries.length - 1, // index 21 | uint64(block.timestamp), // timestamp 22 | endTimestamp // end timestamp 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /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/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/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/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, 14 | /// No caller modification is currently active2. 15 | Some 16 | } 17 | 18 | function bar() public {} 19 | } 20 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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/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 | } -------------------------------------------------------------------------------- /crates/fmt/testdata/ForStatement/fmt.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.8; 2 | 3 | contract ForStatement { 4 | function test() external { 5 | for (uint256 i1; i1 < 10; i1++) { 6 | i1++; 7 | } 8 | 9 | uint256 i2; 10 | for (++i2; i2 < 10; i2++) {} 11 | 12 | uint256 veryLongVariableName = 1000; 13 | for ( 14 | uint256 i3; 15 | i3 < 10 && veryLongVariableName > 999 && veryLongVariableName < 1001; 16 | i3++ 17 | ) { 18 | i3++; 19 | } 20 | 21 | for (type(uint256).min;;) {} 22 | 23 | for (;;) { 24 | "test"; 25 | } 26 | 27 | for (uint256 i4; i4 < 10; i4++) { 28 | i4++; 29 | } 30 | 31 | for (uint256 i5;;) { 32 | for (uint256 i6 = 10; i6 > i5; i6--) { 33 | i5++; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /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 (type(uint256).min;;) {} 24 | 25 | for (;;) { "test" ; } 26 | 27 | for (uint256 i4; i4< 10; i4++) i4++; 28 | 29 | for (uint256 i5; ;) 30 | for (uint256 i6 = 10; i6 > i5; i6--) 31 | i5++; 32 | } 33 | } -------------------------------------------------------------------------------- /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 ( 9 | function() 10 | internal pure returns (uint256) 11 | ) 12 | {} 13 | } 14 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /crates/fmt/testdata/FunctionType/fmt.sol: -------------------------------------------------------------------------------- 1 | // config: line_length = 90 2 | library ArrayUtils { 3 | function map(uint256[] memory self, function (uint) pure returns (uint) f) 4 | internal 5 | pure 6 | returns (uint256[] memory r) 7 | { 8 | r = new uint256[](self.length); 9 | for (uint256 i = 0; i < self.length; i++) { 10 | r[i] = f(self[i]); 11 | } 12 | } 13 | 14 | function reduce(uint256[] memory self, function (uint, uint) pure returns (uint) f) 15 | internal 16 | pure 17 | returns (uint256 r) 18 | { 19 | r = self[0]; 20 | for (uint256 i = 1; i < self.length; i++) { 21 | r = f(r, self[i]); 22 | } 23 | } 24 | 25 | function range(uint256 length) internal pure returns (uint256[] memory r) { 26 | r = new uint256[](length); 27 | for (uint256 i = 0; i < r.length; i++) { 28 | r[i] = i; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /crates/fmt/testdata/FunctionType/original.sol: -------------------------------------------------------------------------------- 1 | library ArrayUtils { 2 | function map(uint[] memory self, function (uint) pure returns (uint) f) 3 | internal 4 | pure 5 | returns ( 6 | uint[] memory r 7 | ) 8 | { 9 | r = new uint[]( self.length); 10 | for (uint i = 0; i < self.length; i++) { 11 | r[i] = f(self[i]); 12 | } 13 | } 14 | 15 | function reduce( 16 | uint[] memory self, 17 | function (uint, uint) pure returns (uint) f 18 | ) internal pure returns (uint256 r) { 19 | r = self[0]; 20 | for (uint i = 1; i < self.length; i++) { 21 | r = f(r, self[i]); 22 | } 23 | } 24 | 25 | function range(uint256 length) internal pure returns (uint[] memory r) { 26 | r = new uint256[](length ); 27 | for (uint i = 0; i < r.length; i++) { 28 | r[i] = i; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/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/IfStatement2/fmt.sol: -------------------------------------------------------------------------------- 1 | contract IfStatement { 2 | function test() external { 3 | bool anotherLongCondition; 4 | 5 | if (condition && ((condition || anotherLongCondition))) execute(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /crates/fmt/testdata/IfStatement2/original.sol: -------------------------------------------------------------------------------- 1 | contract IfStatement { 2 | 3 | function test() external { 4 | bool anotherLongCondition; 5 | 6 | if (condition && ((condition || anotherLongCondition) 7 | ) 8 | ) execute(); 9 | } 10 | } -------------------------------------------------------------------------------- /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 alias, symbol2 } from "File.sol"; 9 | import { symbol1 as alias, 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 | -------------------------------------------------------------------------------- /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 alias, symbol2} from "File.sol"; 8 | import {symbol1 as alias, 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 | -------------------------------------------------------------------------------- /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 alias, symbol2} from "File.sol"; 8 | import {symbol1 as alias, 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 | -------------------------------------------------------------------------------- /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 alias, symbol2} from "File.sol"; 9 | import {symbol1 as alias, 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 | -------------------------------------------------------------------------------- /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 alias, symbol2} from 'File.sol'; 9 | import {symbol1 as alias, 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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /crates/fmt/testdata/MappingType/fmt.sol: -------------------------------------------------------------------------------- 1 | // config: line_length = 40 2 | contract X { 3 | type Y is bytes32; 4 | } 5 | 6 | type SomeVeryLongTypeName is uint256; 7 | 8 | contract Mapping { 9 | mapping(uint256 => X.Y) mapping1; 10 | mapping( 11 | uint256 key => uint256 value 12 | ) mapping2; 13 | mapping( 14 | uint256 veryLongKeyName 15 | => uint256 veryLongValueName 16 | ) mapping3; 17 | mapping( 18 | string anotherVeryLongKeyName 19 | => uint256 anotherVeryLongValueName 20 | ) mapping4; 21 | mapping( 22 | SomeVeryLongTypeName anotherVeryLongKeyName 23 | => uint256 anotherVeryLongValueName 24 | ) mapping5; 25 | 26 | mapping( 27 | // comment1 28 | uint256 key => uint256 value 29 | // comment2 30 | ) mapping6; 31 | mapping( /* comment3 */ 32 | uint256 /* comment4 */ key /* comment5 */ 33 | => /* comment6 */ uint256 /* comment7 */ value /* comment8 */ /* comment9 */ 34 | ) /* comment10 */ mapping7; 35 | } 36 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /crates/fmt/testdata/NumberLiteralUnderscore/fmt.sol: -------------------------------------------------------------------------------- 1 | contract NumberLiteral { 2 | function test() external { 3 | 1; 4 | 123_000; 5 | 1_2e345_678; 6 | -1; 7 | 2e-10; 8 | 0.1; 9 | 1.3; 10 | 2.5e1; 11 | 1.23454; 12 | 1.2e34_5_678; 13 | 134411.2e34_5_678; 14 | 13431.134112e34_135_678; 15 | 13431.0134112; 16 | 13431.134112e-139_3141340; 17 | 134411.2e34_5_6780; 18 | 13431.134112e34_135_6780; 19 | 0.134112; 20 | 1.0; 21 | 13431.134112e-139_3141340; 22 | 123e456; 23 | 1_000; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /crates/fmt/testdata/NumberLiteralUnderscore/original.sol: -------------------------------------------------------------------------------- 1 | contract NumberLiteral { 2 | function test() external { 3 | 1; 4 | 123_000; 5 | 1_2e345_678; 6 | -1; 7 | 2e-10; 8 | .1; 9 | 1.3; 10 | 2.5e1; 11 | 1.23454e0; 12 | 1.2e34_5_678; 13 | 134411.2e34_5_678; 14 | 13431.134112e34_135_678; 15 | 13431.0134112; 16 | 13431.134112e-139_3141340; 17 | 00134411.200e0034_5_6780; 18 | 013431.13411200e34_135_6780; 19 | 00.1341120000; 20 | 1.0000; 21 | 0013431.13411200e-00139_3141340; 22 | 123E456; 23 | 1_000; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /crates/fmt/testdata/NumberLiteralUnderscore/preserve.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: number_underscore = "preserve" 2 | contract NumberLiteral { 3 | function test() external { 4 | 1; 5 | 123_000; 6 | 1_2e345_678; 7 | -1; 8 | 2e-10; 9 | 0.1; 10 | 1.3; 11 | 2.5e1; 12 | 1.23454; 13 | 1.2e34_5_678; 14 | 134411.2e34_5_678; 15 | 13431.134112e34_135_678; 16 | 13431.0134112; 17 | 13431.134112e-139_3141340; 18 | 134411.2e34_5_6780; 19 | 13431.134112e34_135_6780; 20 | 0.134112; 21 | 1.0; 22 | 13431.134112e-139_3141340; 23 | 123e456; 24 | 1_000; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /crates/fmt/testdata/NumberLiteralUnderscore/remove.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: number_underscore = "remove" 2 | contract NumberLiteral { 3 | function test() external { 4 | 1; 5 | 123000; 6 | 12e345678; 7 | -1; 8 | 2e-10; 9 | 0.1; 10 | 1.3; 11 | 2.5e1; 12 | 1.23454; 13 | 1.2e345678; 14 | 134411.2e345678; 15 | 13431.134112e34135678; 16 | 13431.0134112; 17 | 13431.134112e-1393141340; 18 | 134411.2e3456780; 19 | 13431.134112e341356780; 20 | 0.134112; 21 | 1.0; 22 | 13431.134112e-1393141340; 23 | 123e456; 24 | 1000; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /crates/fmt/testdata/NumberLiteralUnderscore/thousands.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: number_underscore = "thousands" 2 | contract NumberLiteral { 3 | function test() external { 4 | 1; 5 | 123_000; 6 | 12e345_678; 7 | -1; 8 | 2e-10; 9 | 0.1; 10 | 1.3; 11 | 2.5e1; 12 | 1.23454; 13 | 1.2e345_678; 14 | 134_411.2e345_678; 15 | 13_431.134112e34_135_678; 16 | 13_431.0134112; 17 | 13_431.134112e-1_393_141_340; 18 | 134_411.2e3_456_780; 19 | 13_431.134112e341_356_780; 20 | 0.134112; 21 | 1.0; 22 | 13_431.134112e-1_393_141_340; 23 | 123e456; 24 | 1000; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /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/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; -------------------------------------------------------------------------------- /crates/fmt/testdata/Repros/fmt.sol: -------------------------------------------------------------------------------- 1 | // Repros of fmt issues 2 | 3 | // https://github.com/foundry-rs/foundry/issues/4403 4 | function errorIdentifier() { 5 | bytes memory error = bytes(""); 6 | if (error.length > 0) {} 7 | } 8 | -------------------------------------------------------------------------------- /crates/fmt/testdata/Repros/original.sol: -------------------------------------------------------------------------------- 1 | // Repros of fmt issues 2 | 3 | // https://github.com/foundry-rs/foundry/issues/4403 4 | function errorIdentifier() { 5 | bytes memory error = bytes(""); 6 | if (error.length > 0) {} 7 | } 8 | -------------------------------------------------------------------------------- /crates/fmt/testdata/SortedImports/fmt.sol: -------------------------------------------------------------------------------- 1 | // config: sort_imports = true 2 | import "SomeFile0.sol" as SomeOtherFile; 3 | import "SomeFile1.sol" as SomeOtherFile; 4 | import "SomeFile2.sol"; 5 | import "SomeFile3.sol"; 6 | 7 | import "AnotherFile1.sol" as SomeSymbol; 8 | import "AnotherFile2.sol" as SomeSymbol; 9 | 10 | import { 11 | symbol1 as alias3, 12 | symbol2 as alias2, 13 | symbol3 as alias1, 14 | symbol4 15 | } from "File0.sol"; 16 | import {symbol1 as alias, symbol2} from "File2.sol"; 17 | import {symbol1 as alias, symbol2} from "File3.sol"; 18 | import { 19 | symbol1 as alias1, 20 | symbol2 as alias2, 21 | symbol3 as alias3, 22 | symbol4 23 | } from "File6.sol"; 24 | 25 | uint256 constant someConstant = 10; 26 | 27 | import {Something2, Something3} from "someFile.sol"; 28 | 29 | // This is a comment 30 | import {Something2, Something3} from "someFile.sol"; 31 | 32 | import {symbol1 as alias, symbol2} from "File3.sol"; 33 | // comment inside group is treated as a separator for now 34 | import {symbol1 as alias, symbol2} from "File2.sol"; 35 | -------------------------------------------------------------------------------- /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 alias} from "File3.sol"; 10 | import {symbol2, symbol1 as alias} 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 alias} from "File3.sol"; 22 | // comment inside group is treated as a separator for now 23 | import {symbol2, symbol1 as alias} from "File2.sol"; -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/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/fmt/testdata/StructDefinition/original.sol: -------------------------------------------------------------------------------- 1 | struct Foo { 2 | } struct Bar { uint foo ;string bar ; } 3 | 4 | struct MyStruct { 5 | // first 1 6 | // first 2 7 | uint256 field1; 8 | // second 9 | uint256 field2; 10 | } 11 | -------------------------------------------------------------------------------- /crates/fmt/testdata/ThisExpression/fmt.sol: -------------------------------------------------------------------------------- 1 | contract ThisExpression { 2 | function someFunc() public {} 3 | function someVeryVeryVeryLongVariableNameThatWillBeAccessedByThisKeyword() 4 | public 5 | {} 6 | 7 | function test() external { 8 | this.someFunc(); 9 | this.someVeryVeryVeryLongVariableNameThatWillBeAccessedByThisKeyword(); 10 | this // comment1 11 | .someVeryVeryVeryLongVariableNameThatWillBeAccessedByThisKeyword(); 12 | address(this).balance; 13 | 14 | address thisAddress = address( 15 | // comment2 16 | /* comment3 */ 17 | this // comment 4 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /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/TrailingComma/fmt.sol: -------------------------------------------------------------------------------- 1 | contract C is Contract { 2 | modifier m(uint256) {} 3 | // invalid solidity code, but valid pt 4 | modifier m2(uint256) returns (uint256) {} 5 | 6 | function f(uint256 a) external {} 7 | function f2(uint256 a, bytes32 b) external returns (uint256) {} 8 | 9 | function f3() external { 10 | try some.invoke() returns (uint256, uint256) {} catch {} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /crates/fmt/testdata/TrailingComma/original.sol: -------------------------------------------------------------------------------- 1 | contract C is Contract { 2 | modifier m(uint256, ,,, ) {} 3 | // invalid solidity code, but valid pt 4 | modifier m2(uint256) returns (uint256,,,) {} 5 | 6 | function f(uint256 a, ) external {} 7 | function f2(uint256 a, , , ,bytes32 b) external returns (uint256,,,,) {} 8 | 9 | function f3() external { 10 | try some.invoke() returns (uint256,,,uint256) {} catch {} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 /* comment1 */ ether; // comment2 19 | 20 | value = 1 // comment3 21 | // comment4 22 | ether; // comment5 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /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 /* comment1 */ ether; // comment2 18 | 19 | value = 1 // comment3 20 | // comment4 21 | ether; // comment5 22 | } 23 | } -------------------------------------------------------------------------------- /crates/fmt/testdata/UsingDirective/fmt.sol: -------------------------------------------------------------------------------- 1 | contract UsingExampleContract { 2 | using UsingExampleLibrary for *; 3 | using UsingExampleLibrary for uint256; 4 | using Example.UsingExampleLibrary for uint256; 5 | using {M.g, M.f} for uint256; 6 | using UsingExampleLibrary for uint256 global; 7 | using { 8 | These, 9 | Are, 10 | MultipleLibraries, 11 | ThatNeedToBePut, 12 | OnSeparateLines 13 | } for uint256; 14 | using { 15 | This 16 | .isareally 17 | .longmember 18 | .access 19 | .expression 20 | .that 21 | .needs 22 | .to 23 | .besplit 24 | .into 25 | .lines 26 | } for uint256; 27 | using {and as &, or as |, xor as ^, cpl as ~} for Bitmap global; 28 | using { 29 | eq as ==, 30 | ne as !=, 31 | lt as <, 32 | lte as <=, 33 | gt as >, 34 | gte as >= 35 | } for Bitmap global; 36 | } 37 | -------------------------------------------------------------------------------- /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/fmt/testdata/VariableAssignment/bracket-spacing.fmt.sol: -------------------------------------------------------------------------------- 1 | // config: bracket_spacing = true 2 | contract TestContract { 3 | function aLongerTestFunctionName(uint256 input) 4 | public 5 | view 6 | returns (uint256 num) 7 | { 8 | (, uint256 second) = (1, 2); 9 | (uint256 listItem001) = 1; 10 | (uint256 listItem002, uint256 listItem003) = (10, 20); 11 | (uint256 listItem004, uint256 listItem005, uint256 listItem006) = 12 | (10, 20, 30); 13 | ( 14 | uint256 listItem007, 15 | uint256 listItem008, 16 | uint256 listItem009, 17 | uint256 listItem010 18 | ) = (10, 20, 30, 40); 19 | return 1; 20 | } 21 | 22 | function test() external { 23 | uint256 value = map[key]; 24 | uint256 allowed = allowance[from][msg.sender]; 25 | allowance[from][msg.sender] = allowed; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /crates/fmt/testdata/VariableAssignment/fmt.sol: -------------------------------------------------------------------------------- 1 | contract TestContract { 2 | function aLongerTestFunctionName(uint256 input) 3 | public 4 | view 5 | returns (uint256 num) 6 | { 7 | (, uint256 second) = (1, 2); 8 | (uint256 listItem001) = 1; 9 | (uint256 listItem002, uint256 listItem003) = (10, 20); 10 | (uint256 listItem004, uint256 listItem005, uint256 listItem006) = 11 | (10, 20, 30); 12 | ( 13 | uint256 listItem007, 14 | uint256 listItem008, 15 | uint256 listItem009, 16 | uint256 listItem010 17 | ) = (10, 20, 30, 40); 18 | return 1; 19 | } 20 | 21 | function test() external { 22 | uint256 value = map[key]; 23 | uint256 allowed = allowance[from][msg.sender]; 24 | allowance[from][msg.sender] = allowed; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /crates/fmt/testdata/VariableAssignment/original.sol: -------------------------------------------------------------------------------- 1 | contract TestContract { 2 | function aLongerTestFunctionName(uint256 input) 3 | public 4 | view 5 | returns (uint256 num) 6 | { 7 | (, uint256 second) = (1, 2); 8 | (uint256 listItem001) = 1; 9 | (uint256 listItem002, uint256 listItem003) = (10, 20); 10 | (uint256 listItem004, uint256 listItem005, uint256 listItem006) = 11 | (10, 20, 30); 12 | ( 13 | uint256 listItem007, 14 | uint256 listItem008, 15 | uint256 listItem009, 16 | uint256 listItem010 17 | ) = (10, 20, 30, 40); 18 | return 1; 19 | } 20 | 21 | function test() external { 22 | uint256 value = map[key]; 23 | uint256 allowed = allowance[from][msg.sender]; 24 | allowance[from][msg.sender] = allowed; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /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 := "abc":u32 7 | let d := "abc":u32 8 | let e := hex"deadbeef" 9 | let f := hex"deadbeef" 10 | let g := hex"deadbeef":u32 11 | let h := hex"deadbeef":u32 12 | datacopy(0, dataoffset("runtime"), datasize("runtime")) 13 | return(0, datasize("runtime")) 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /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 := "abc":u32 7 | let d := 'abc':u32 8 | let e := hex"deadbeef" 9 | let f := hex'deadbeef' 10 | let g := hex"deadbeef":u32 11 | let h := hex'deadbeef':u32 12 | datacopy(0, dataoffset('runtime'), datasize("runtime")) 13 | return(0, datasize("runtime")) 14 | } 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 := "abc":u32 8 | let d := 'abc':u32 9 | let e := hex"deadbeef" 10 | let f := hex'deadbeef' 11 | let g := hex"deadbeef":u32 12 | let h := hex'deadbeef':u32 13 | datacopy(0, dataoffset('runtime'), datasize("runtime")) 14 | return(0, datasize("runtime")) 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /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 := 'abc':u32 8 | let d := 'abc':u32 9 | let e := hex'deadbeef' 10 | let f := hex'deadbeef' 11 | let g := hex'deadbeef':u32 12 | let h := hex'deadbeef':u32 13 | datacopy(0, dataoffset('runtime'), datasize('runtime')) 14 | return(0, datasize('runtime')) 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /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/CounterTemplate.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import {Script, console} from "forge-std/Script.sol"; 5 | 6 | contract CounterScript is Script { 7 | function setUp() public {} 8 | 9 | function run() public { 10 | vm.broadcast(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /crates/forge/assets/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/forge/assets/CounterTemplate.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 {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 | -------------------------------------------------------------------------------- /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/assets/workflowTemplate.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: workflow_dispatch 4 | 5 | env: 6 | FOUNDRY_PROFILE: ci 7 | 8 | jobs: 9 | check: 10 | strategy: 11 | fail-fast: true 12 | 13 | name: Foundry project 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | with: 18 | submodules: recursive 19 | 20 | - name: Install Foundry 21 | uses: foundry-rs/foundry-toolchain@v1 22 | with: 23 | version: nightly 24 | 25 | - name: Run Forge build 26 | run: | 27 | forge --version 28 | forge build --sizes 29 | id: build 30 | 31 | - name: Run Forge tests 32 | run: | 33 | forge test -vvv 34 | id: test 35 | -------------------------------------------------------------------------------- /crates/forge/benches/test.rs: -------------------------------------------------------------------------------- 1 | use criterion::{criterion_group, criterion_main, Criterion}; 2 | use foundry_test_utils::{util::setup_forge_remote, TestCommand, TestProject}; 3 | 4 | /// Returns a cloned and `forge built` `solmate` project 5 | fn built_solmate() -> (TestProject, TestCommand) { 6 | setup_forge_remote("transmissions11/solmate") 7 | } 8 | 9 | fn forge_test_benchmark(c: &mut Criterion) { 10 | let (prj, _) = built_solmate(); 11 | 12 | let mut group = c.benchmark_group("forge test"); 13 | group.sample_size(10); 14 | group.bench_function("solmate", |b| { 15 | let mut cmd = prj.forge_command(); 16 | cmd.arg("test"); 17 | b.iter(|| { 18 | cmd.ensure_execute_success().unwrap(); 19 | }); 20 | }); 21 | } 22 | 23 | criterion_group!(benches, forge_test_benchmark); 24 | criterion_main!(benches); 25 | -------------------------------------------------------------------------------- /crates/forge/bin/cmd/geiger/error.rs: -------------------------------------------------------------------------------- 1 | use foundry_common::errors::FsPathError; 2 | use solang_parser::diagnostics::Diagnostic; 3 | use std::path::PathBuf; 4 | 5 | /// Possible errors when scanning a solidity file 6 | #[derive(Debug, thiserror::Error)] 7 | pub enum ScanFileError { 8 | #[error(transparent)] 9 | Io(#[from] FsPathError), 10 | #[error("Failed to parse {1:?}: {0:?}")] 11 | ParseSol(Vec, PathBuf), 12 | } 13 | -------------------------------------------------------------------------------- /crates/forge/bin/cmd/script/artifacts.rs: -------------------------------------------------------------------------------- 1 | use alloy_json_abi::JsonAbi; 2 | 3 | /// Bundles info of an artifact 4 | pub struct ArtifactInfo<'a> { 5 | pub contract_name: String, 6 | pub contract_id: String, 7 | pub abi: &'a JsonAbi, 8 | pub code: &'a Vec, 9 | } 10 | -------------------------------------------------------------------------------- /crates/forge/bin/cmd/tree.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | use eyre::Result; 3 | use foundry_cli::{opts::ProjectPathsArgs, utils::LoadConfig}; 4 | use foundry_compilers::{ 5 | resolver::{Charset, TreeOptions}, 6 | Graph, 7 | }; 8 | 9 | /// CLI arguments for `forge tree`. 10 | #[derive(Clone, Debug, Parser)] 11 | pub struct TreeArgs { 12 | /// Do not de-duplicate (repeats all shared dependencies) 13 | #[clap(long)] 14 | no_dedupe: bool, 15 | 16 | /// Character set to use in output. 17 | /// 18 | /// [possible values: utf8, ascii] 19 | #[clap(long, default_value = "utf8")] 20 | charset: Charset, 21 | 22 | #[clap(flatten)] 23 | opts: ProjectPathsArgs, 24 | } 25 | 26 | foundry_config::impl_figment_convert!(TreeArgs, opts); 27 | 28 | impl TreeArgs { 29 | pub fn run(self) -> Result<()> { 30 | let config = self.try_load_config_emit_warnings()?; 31 | let graph = Graph::resolve(&config.project_paths())?; 32 | let opts = TreeOptions { charset: self.charset, no_dedupe: self.no_dedupe }; 33 | graph.print_with_options(opts); 34 | 35 | Ok(()) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /crates/forge/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | vergen::EmitBuilder::builder().build_timestamp().git_sha(true).emit().unwrap(); 3 | } 4 | -------------------------------------------------------------------------------- /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.clear_cache(); 20 | 21 | cmd.args(["test", "--no-cache"]).assert_success(); 22 | assert!(!prj.cache().exists(), "cache file should not exist"); 23 | 24 | cmd.forge_fuse().arg("test").assert_success(); 25 | assert!(prj.cache().exists(), "cache file should exist"); 26 | }); 27 | -------------------------------------------------------------------------------- /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/tests/cli/doc.rs: -------------------------------------------------------------------------------- 1 | use foundry_test_utils::util::{setup_forge_remote, RemoteProject}; 2 | 3 | #[test] 4 | fn can_generate_solmate_docs() { 5 | let (prj, _) = 6 | setup_forge_remote(RemoteProject::new("transmissions11/solmate").set_build(false)); 7 | prj.forge_command().args(["doc", "--build"]).assert_success(); 8 | } 9 | -------------------------------------------------------------------------------- /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 build; 8 | mod cache; 9 | mod cmd; 10 | mod config; 11 | mod coverage; 12 | mod create; 13 | mod debug; 14 | mod doc; 15 | mod multi_script; 16 | mod script; 17 | mod svm; 18 | mod test_cmd; 19 | mod verify; 20 | 21 | mod ext_integration; 22 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_build_skip_contracts.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 finished in 34.45ms 3 | Compiler run successful! 4 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_build_skip_glob.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 finished in 33.25ms 3 | Compiler run successful! 4 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_check_snapshot.stdout: -------------------------------------------------------------------------------- 1 | Compiling 2 files with 0.8.23 2 | Solc 0.8.23 finished in 424.55ms 3 | Compiler run successful! 4 | 5 | Running 1 test for src/ATest.t.sol:ATest 6 | [PASS] testExample() (gas: 168) 7 | Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.42ms 8 | 9 | Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests) 10 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_create_template_contract-2nd.stdout: -------------------------------------------------------------------------------- 1 | No files changed, compilation skipped 2 | Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 3 | Deployed to: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 4 | Transaction hash: 0x3d78b08c411f05d5e79adc92a4c814e0f818d1a09c111b0ab688270f35a07ae7 5 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_create_template_contract.stdout: -------------------------------------------------------------------------------- 1 | Compiling 24 files with 0.8.23 2 | Solc 0.8.23 finished in 2.27s 3 | Compiler run successful! 4 | Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 5 | Deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 6 | Transaction hash: 0x4c3d9f7c4cc26876b43a11ba7ff218374471786a8ae8bf5574deb1d97fc1e851 7 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_create_using_unlocked-2nd.stdout: -------------------------------------------------------------------------------- 1 | No files changed, compilation skipped 2 | Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 3 | Deployed to: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 4 | Transaction hash: 0x3d78b08c411f05d5e79adc92a4c814e0f818d1a09c111b0ab688270f35a07ae7 5 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_create_using_unlocked.stdout: -------------------------------------------------------------------------------- 1 | Compiling 24 files with 0.8.23 2 | Solc 0.8.23 finished in 1.95s 3 | Compiler run successful! 4 | Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 5 | Deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 6 | Transaction hash: 0x4c3d9f7c4cc26876b43a11ba7ff218374471786a8ae8bf5574deb1d97fc1e851 7 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_create_with_constructor_args.stdout: -------------------------------------------------------------------------------- 1 | Compiling 25 files with 0.8.23 2 | Solc 0.8.23 finished in 2.82s 3 | Compiler run successful! 4 | Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 5 | Deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 6 | Transaction hash: 0x294df85109c991ec2760cd51e5ddc869bf5dc3b249b296305ffcd1a0563b2eea 7 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_create_with_tuple_constructor_args.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 finished in 26.44ms 3 | Compiler run successful! 4 | Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 5 | Deployed to: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 6 | Transaction hash: 0x69625b76d83634603a9dbc5b836ef89bafdd9fc7c180fc6d636c5088353cf501 7 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_detect_dirty_git_status_on_init.stderr: -------------------------------------------------------------------------------- 1 | Error: 2 | The target directory is a part of or on its own an already initialized git repository, 3 | and it requires clean working and staging areas, including no untracked files. 4 | 5 | Check the current git repository's status with `git status`. 6 | Then, you can track files with `git add ...` and then commit them with `git commit`, 7 | ignore them in the `.gitignore` file, or run this command again with the `--no-commit` flag. 8 | 9 | If none of the previous steps worked, please open an issue at: 10 | https://github.com/foundry-rs/foundry/issues/new/choose 11 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_execute_script_and_skip_contracts.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 3 | Compiler run successful! 4 | Script ran successfully. 5 | Gas used: 22900 6 | 7 | == Return == 8 | result: uint256 255 9 | 1: uint8 3 10 | 11 | == Logs == 12 | script ran 13 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_execute_script_command.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 finished in 23.34ms 3 | Compiler run successful! 4 | Script ran successfully. 5 | Gas used: 22815 6 | 7 | == Logs == 8 | script ran 9 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_execute_script_command_fqn.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 finished in 23.70ms 3 | Compiler run successful! 4 | Script ran successfully. 5 | Gas used: 22815 6 | 7 | == Logs == 8 | script ran 9 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_execute_script_command_with_args.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 finished in 35.28ms 3 | Compiler run successful! 4 | Script ran successfully. 5 | Gas used: 25301 6 | 7 | == Logs == 8 | script ran 9 | 1 10 | 2 11 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_execute_script_command_with_returned.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 finished in 1.27s 3 | Compiler run successful! 4 | Script ran successfully. 5 | Gas used: 22900 6 | 7 | == Return == 8 | result: uint256 255 9 | 1: uint8 3 10 | 11 | == Logs == 12 | script ran 13 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_execute_script_command_with_sig.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 finished in 24.49ms 3 | Compiler run successful! 4 | Script ran successfully. 5 | Gas used: 22815 6 | 7 | == Logs == 8 | script ran 9 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_run_test_in_custom_test_folder.stdout: -------------------------------------------------------------------------------- 1 | Compiling 2 files with 0.8.23 2 | Solc 0.8.23 finished in 185.25ms 3 | Compiler run successful! 4 | 5 | Running 1 test for src/nested/forge-tests/MyTest.t.sol:MyTest 6 | [PASS] testTrue() (gas: 168) 7 | Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.93ms 8 | 9 | Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests) 10 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_set_yul_optimizer.stderr: -------------------------------------------------------------------------------- 1 | Error: 2 | Compiler run failed: 3 | Error (6553): SyntaxError: The msize instruction cannot be used when the Yul optimizer is activated because it can change its semantics. Either disable the Yul optimizer or do not use the instruction. 4 | --> src/Foo.sol:6:8: 5 | | 6 | 6 | assembly { 7 | | ^ (Relevant source part starts here and spans across multiple lines). 8 | 9 | 10 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_test_repeatedly.stdout: -------------------------------------------------------------------------------- 1 | No files changed, compilation skipped 2 | 3 | Running 2 tests for test/Counter.t.sol:CounterTest 4 | [PASS] testFuzz_SetNumber(uint256) (runs: 256, μ: 26521, ~: 28387) 5 | [PASS] test_Increment() (gas: 28379) 6 | Test result: ok. 2 passed; 0 failed; 0 skipped; finished in 9.42ms 7 | 8 | Ran 1 test suites: 2 tests passed, 0 failed, 0 skipped (2 total tests) 9 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/can_use_libs_in_multi_fork.stdout: -------------------------------------------------------------------------------- 1 | Compiling 2 files with 0.8.23 2 | Solc 0.8.23 finished in 1.95s 3 | Compiler run successful! 4 | 5 | Running 1 test for test/Contract.t.sol:ContractTest 6 | [PASS] test() (gas: 70360) 7 | Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.21s 8 | 9 | Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests) 10 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/compile_json.stdout: -------------------------------------------------------------------------------- 1 | { 2 | "errors": [ 3 | { 4 | "sourceLocation": { 5 | "file": "src/jsonError.sol", 6 | "start": 184, 7 | "end": 193 8 | }, 9 | "type": "DeclarationError", 10 | "component": "general", 11 | "severity": "error", 12 | "errorCode": "7576", 13 | "message": "Undeclared identifier. Did you mean \"newNumber\"?", 14 | "formattedMessage": "DeclarationError: Undeclared identifier. Did you mean \"newNumber\"?\n --> src/dummy.sol:7:18:\n |\n7 | number = newnumber; // error here\n | ^^^^^^^^^\n\n" 15 | } 16 | ], 17 | "sources": {}, 18 | "contracts": {}, 19 | "build_infos": {} 20 | } 21 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/include_custom_types_in_traces.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 finished in 798.51ms 3 | Compiler run successful! 4 | 5 | Running 2 tests for test/Contract.t.sol:CustomTypesTest 6 | [FAIL. Reason: PoolNotInitialized()] testErr() (gas: 231) 7 | Traces: 8 | [231] CustomTypesTest::testErr() 9 | └─ ← PoolNotInitialized() 10 | 11 | [PASS] testEvent() (gas: 1312) 12 | Traces: 13 | [1312] CustomTypesTest::testEvent() 14 | ├─ emit MyEvent(a: 100) 15 | └─ ← () 16 | 17 | Test result: FAILED. 1 passed; 1 failed; 0 skipped; finished in 3.88ms 18 | 19 | Ran 1 test suites: 1 tests passed, 1 failed, 0 skipped (2 total tests) 20 | 21 | Failing tests: 22 | Encountered 1 failing test in test/Contract.t.sol:CustomTypesTest 23 | [FAIL. Reason: PoolNotInitialized()] testErr() (gas: 231) 24 | 25 | Encountered a total of 1 failing tests, 1 tests succeeded 26 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/repro_6531.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | 3 | Compiler run successful! 4 | 5 | Running 1 test for test/Contract.t.sol:USDCCallingTest 6 | [PASS] test() (gas: 16799) 7 | Traces: 8 | [16799] USDCCallingTest::test() 9 | ├─ [0] VM::createSelectFork("") 10 | │ └─ ← 0 11 | ├─ [10350] 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48::name() [staticcall] 12 | │ ├─ [3061] 0x43506849D7C04F9138D1A2050bbF3A0c054402dd::name() [delegatecall] 13 | │ │ └─ ← "USD Coin" 14 | │ └─ ← "USD Coin" 15 | └─ ← () 16 | 17 | Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.43s 18 | 19 | Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests) 20 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/runs_tests_exactly_once_with_changed_versions.1.stdout: -------------------------------------------------------------------------------- 1 | Compiling 2 files with 0.8.23 2 | Solc 0.8.23 finished in 185.25ms 3 | Compiler run successful! 4 | 5 | Running 1 test for src/Contract.t.sol:ContractTest 6 | [PASS] testExample() (gas: 190) 7 | Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.89ms 8 | 9 | Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests) 10 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/runs_tests_exactly_once_with_changed_versions.2.stdout: -------------------------------------------------------------------------------- 1 | Compiling 2 files with 0.8.22 2 | Solc 0.8.22 finished in 185.25ms 3 | Compiler run successful! 4 | 5 | Running 1 test for src/Contract.t.sol:ContractTest 6 | [PASS] testExample() (gas: 190) 7 | Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.89ms 8 | 9 | Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests) 10 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/suggest_when_no_tests_match.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 finished in 185.25ms 3 | Compiler run successful! 4 | 5 | No tests match the provided pattern: 6 | match-test: `testA.*` 7 | no-match-test: `testB.*` 8 | match-contract: `TestC.*` 9 | no-match-contract: `TestD.*` 10 | match-path: `*TestE*` 11 | no-match-path: `*TestF*` 12 | 13 | Did you mean `test1`? 14 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/warn_no_tests.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 3 | Compiler run successful! 4 | 5 | No tests found in project! Forge looks for functions that starts with `test`. 6 | -------------------------------------------------------------------------------- /crates/forge/tests/fixtures/warn_no_tests_match.stdout: -------------------------------------------------------------------------------- 1 | Compiling 1 files with 0.8.23 2 | Solc 0.8.23 3 | Compiler run successful! 4 | 5 | No tests match the provided pattern: 6 | match-test: `testA.*` 7 | no-match-test: `testB.*` 8 | match-contract: `TestC.*` 9 | no-match-contract: `TestD.*` 10 | match-path: `*TestE*` 11 | no-match-path: `*TestF*` 12 | -------------------------------------------------------------------------------- /crates/forge/tests/it/cheats.rs: -------------------------------------------------------------------------------- 1 | //! Forge tests for cheatcodes. 2 | 3 | use crate::{ 4 | config::*, 5 | test_helpers::{PROJECT, RE_PATH_SEPARATOR}, 6 | }; 7 | use foundry_config::{fs_permissions::PathPermission, Config, FsPermissions}; 8 | use foundry_test_utils::Filter; 9 | 10 | /// Executes all cheat code tests but not fork cheat codes 11 | #[tokio::test(flavor = "multi_thread")] 12 | async fn test_cheats_local() { 13 | let mut config = Config::with_root(PROJECT.root()); 14 | config.fs_permissions = FsPermissions::new(vec![PathPermission::read_write("./")]); 15 | let runner = runner_with_config(config); 16 | let filter = 17 | Filter::new(".*", ".*", &format!(".*cheats{RE_PATH_SEPARATOR}*")).exclude_paths("Fork"); 18 | 19 | // on windows exclude ffi tests since no echo and file test that expect a certain file path 20 | #[cfg(windows)] 21 | let filter = filter.exclude_tests("(Ffi|File|Line|Root)"); 22 | 23 | TestConfig::with_filter(runner.await, filter).run().await; 24 | } 25 | -------------------------------------------------------------------------------- /crates/forge/tests/it/fs.rs: -------------------------------------------------------------------------------- 1 | //! Filesystem tests. 2 | 3 | use crate::{config::*, test_helpers::PROJECT}; 4 | use foundry_config::{fs_permissions::PathPermission, Config, FsPermissions}; 5 | use foundry_test_utils::Filter; 6 | 7 | #[tokio::test(flavor = "multi_thread")] 8 | async fn test_fs_disabled() { 9 | let mut config = Config::with_root(PROJECT.root()); 10 | config.fs_permissions = FsPermissions::new(vec![PathPermission::none("./")]); 11 | let runner = runner_with_config(config).await; 12 | let filter = Filter::new(".*", ".*", ".*fs/Disabled"); 13 | TestConfig::with_filter(runner, filter).run().await; 14 | } 15 | 16 | #[tokio::test(flavor = "multi_thread")] 17 | async fn test_fs_default() { 18 | let mut config = Config::with_root(PROJECT.root()); 19 | config.fs_permissions = FsPermissions::new(vec![PathPermission::read("./fixtures")]); 20 | let runner = runner_with_config(config); 21 | let filter = Filter::new(".*", ".*", ".*fs/Default"); 22 | TestConfig::with_filter(runner.await, filter).run().await; 23 | } 24 | -------------------------------------------------------------------------------- /crates/forge/tests/it/main.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod test_helpers; 3 | 4 | mod cheats; 5 | mod core; 6 | mod fork; 7 | mod fs; 8 | mod fuzz; 9 | mod inline; 10 | mod invariant; 11 | mod repros; 12 | mod spec; 13 | -------------------------------------------------------------------------------- /crates/forge/tests/it/spec.rs: -------------------------------------------------------------------------------- 1 | //! Integration tests for EVM specifications. 2 | 3 | use crate::config::*; 4 | use foundry_evm::revm::primitives::SpecId; 5 | use foundry_test_utils::Filter; 6 | 7 | #[tokio::test(flavor = "multi_thread")] 8 | async fn test_shanghai_compat() { 9 | let filter = Filter::new("", "ShanghaiCompat", ".*spec"); 10 | TestConfig::filter(filter).await.evm_spec(SpecId::SHANGHAI).run().await; 11 | } 12 | -------------------------------------------------------------------------------- /crates/forge/tests/rpc-cache-keyfile: -------------------------------------------------------------------------------- 1 | This file serves as the key for the github actions/cache 2 | 3 | Any change in this file will invalidate the cache in CI that stores RPC data. 4 | 5 | Last updated: 05-26-2022 -------------------------------------------------------------------------------- /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 | [lib] 13 | proc-macro = true 14 | # proc-macro tests aren't fully supported by cargo-nextest archives 15 | test = false 16 | doc = false 17 | 18 | [dependencies] 19 | proc-macro2 = "1.0" 20 | quote = "1.0" 21 | syn = "2.0" 22 | proc-macro-error = "1" 23 | -------------------------------------------------------------------------------- /crates/macros/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![warn(unused_crate_dependencies)] 2 | 3 | #[macro_use] 4 | extern crate proc_macro_error; 5 | 6 | use proc_macro::TokenStream; 7 | use proc_macro_error::proc_macro_error; 8 | use syn::{parse_macro_input, DeriveInput, Error}; 9 | 10 | mod cheatcodes; 11 | mod console_fmt; 12 | 13 | #[proc_macro_derive(ConsoleFmt)] 14 | pub fn console_fmt(input: TokenStream) -> TokenStream { 15 | let input = parse_macro_input!(input as DeriveInput); 16 | console_fmt::console_fmt(&input).into() 17 | } 18 | 19 | #[proc_macro_derive(Cheatcode, attributes(cheatcode))] 20 | #[proc_macro_error] 21 | pub fn cheatcode(input: TokenStream) -> TokenStream { 22 | let input = parse_macro_input!(input as DeriveInput); 23 | cheatcodes::derive_cheatcode(&input).unwrap_or_else(Error::into_compile_error).into() 24 | } 25 | -------------------------------------------------------------------------------- /crates/test-utils/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foundry-test-utils" 3 | description = "Foundry testing utilities" 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 | [dependencies] 15 | foundry-common.workspace = true 16 | foundry-compilers = { workspace = true, features = ["project-util"] } 17 | foundry-config.workspace = true 18 | 19 | alloy-primitives.workspace = true 20 | 21 | ethers-core.workspace = true 22 | ethers-providers.workspace = true 23 | 24 | eyre.workspace = true 25 | fd-lock = "4.0.0" 26 | once_cell = "1" 27 | parking_lot = "0.12" 28 | pretty_assertions.workspace = true 29 | regex = "1" 30 | serde_json.workspace = true 31 | tracing = "0.1" 32 | tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] } 33 | walkdir = "2" 34 | 35 | [features] 36 | # feature for integration tests that test external projects 37 | external-integration-tests = [] 38 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /crates/test-utils/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![warn(unused_crate_dependencies, unreachable_pub)] 2 | 3 | #[macro_use] 4 | extern crate tracing; 5 | 6 | // Macros useful for testing. 7 | mod macros; 8 | 9 | pub mod fd_lock; 10 | 11 | mod filter; 12 | pub use filter::Filter; 13 | 14 | // Utilities for making it easier to handle tests. 15 | pub mod util; 16 | pub use util::{TestCommand, TestProject}; 17 | 18 | mod script; 19 | pub use script::{ScriptOutcome, ScriptTester}; 20 | 21 | // re-exports for convenience 22 | pub use foundry_compilers; 23 | 24 | /// Initializes tracing for tests. 25 | pub fn init_tracing() { 26 | let _ = tracing_subscriber::FmtSubscriber::builder() 27 | .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) 28 | .try_init(); 29 | } 30 | -------------------------------------------------------------------------------- /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 | - [cheatcodes](./cheatcodes.md) a set of solidity calls dedicated to testing which can manipulate the environment in which the execution is run 10 | 11 | ### `config/` 12 | 13 | Includes all of Foundry's settings and how to get them 14 | 15 | ### `cli/` 16 | 17 | The core `forge` and `cast` cli implementation. Includes all subcommands. 18 | -------------------------------------------------------------------------------- /docs/dev/debugging.md: -------------------------------------------------------------------------------- 1 | ## Debugging Foundry tools 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 of the `cli` crate, same for 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 [`env_logger` crate docs](https://docs.rs/env_logger). 20 | 21 | ### Compiler input and output 22 | 23 | You can get the compiler input JSON and output JSON from `ethers-solc` by passing the `--build-info` flag. This will create two files: one for the input and one for the output. 24 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | reorder_imports = true 2 | imports_granularity = "Crate" 3 | use_small_heuristics = "Max" 4 | comment_width = 100 5 | wrap_comments = true 6 | binop_separator = "Back" 7 | trailing_comma = "Vertical" 8 | trailing_semicolon = false 9 | use_field_init_shorthand = true 10 | format_code_in_doc_comments = true 11 | doc_comment_code_block_width = 100 12 | -------------------------------------------------------------------------------- /testdata/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | .lock 5 | -------------------------------------------------------------------------------- /testdata/README.md: -------------------------------------------------------------------------------- 1 | ## Foundry Tests 2 | 3 | A test suite that tests different aspects of Foundry. 4 | 5 | ### Structure 6 | 7 | - [`core`](core): Tests for fundamental aspects of Foundry 8 | - [`logs`](logs): Tests for Foundry logging capabilities 9 | - [`cheats`](cheats): Tests for Foundry cheatcodes 10 | - [`fuzz`](fuzz): Tests for the Foundry fuzzer 11 | - [`trace`](trace): Tests for the Foundry tracer 12 | - [`fork`](fork): Tests for Foundry forking capabilities 13 | -------------------------------------------------------------------------------- /testdata/cheats/Addr.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract AddrTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testFailPrivKeyZero() public { 11 | vm.addr(0); 12 | } 13 | 14 | function testAddr() public { 15 | uint256 pk = 77814517325470205911140941194401928579557062014761831930645393041380819009408; 16 | address expected = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266; 17 | 18 | assertEq(vm.addr(pk), expected, "expected address did not match"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /testdata/cheats/Assume.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract AssumeTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testAssume(uint8 x) public { 11 | vm.assume(x < 2 ** 7); 12 | assertTrue(x < 2 ** 7, "did not discard inputs"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /testdata/cheats/Bank.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract CoinbaseTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testCoinbase() public { 11 | vm.coinbase(0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8); 12 | assertEq(block.coinbase, 0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8, "coinbase failed"); 13 | } 14 | 15 | function testCoinbaseFuzzed(address who) public { 16 | vm.coinbase(who); 17 | assertEq(block.coinbase, who, "coinbase failed"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/cheats/Base64.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | import "../logs/console.sol"; 7 | 8 | contract Base64Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function test_toBase64() public { 12 | bytes memory input = hex"00112233445566778899aabbccddeeff"; 13 | string memory expected = "ABEiM0RVZneImaq7zN3u/w=="; 14 | string memory actual = vm.toBase64(input); 15 | assertEq(actual, expected); 16 | } 17 | 18 | function test_toBase64URL() public { 19 | bytes memory input = hex"00112233445566778899aabbccddeeff"; 20 | string memory expected = "ABEiM0RVZneImaq7zN3u_w=="; 21 | string memory actual = vm.toBase64URL(input); 22 | assertEq(actual, expected); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /testdata/cheats/ChainId.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract DealTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testChainId() public { 11 | uint256 newChainId = 99; 12 | vm.chainId(newChainId); 13 | assertEq(newChainId, block.chainid); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /testdata/cheats/Deal.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract DealTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testDeal(uint256 amount) public { 11 | address target = address(10); 12 | assertEq(target.balance, 0, "initial balance incorrect"); 13 | 14 | // Give half the amount 15 | vm.deal(target, amount / 2); 16 | assertEq(target.balance, amount / 2, "half balance is incorrect"); 17 | 18 | // Give the entire amount to check that deal is not additive 19 | vm.deal(target, amount); 20 | assertEq(target.balance, amount, "deal did not overwrite balance"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /testdata/cheats/Derive.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract DeriveTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testDerive() public { 11 | string memory mnemonic = "test test test test test test test test test test test junk"; 12 | 13 | uint256 privateKey = vm.deriveKey(mnemonic, 0); 14 | assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); 15 | 16 | uint256 privateKeyDerivationPathChanged = vm.deriveKey(mnemonic, "m/44'/60'/0'/1/", 0); 17 | assertEq(privateKeyDerivationPathChanged, 0x6abb89895f93b02c1b9470db0fa675297f6cca832a5fc66d5dfd7661a42b37be); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/cheats/Etch.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract EtchTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testEtch() public { 11 | address target = address(10); 12 | bytes memory code = hex"1010"; 13 | vm.etch(target, code); 14 | assertEq(string(code), string(target.code)); 15 | } 16 | 17 | function testEtchNotAvailableOnPrecompiles() public { 18 | address target = address(1); 19 | bytes memory code = hex"1010"; 20 | vm._expectCheatcodeRevert(bytes("cannot call `etch` on precompile 0x0000000000000000000000000000000000000001")); 21 | vm.etch(target, code); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testdata/cheats/Fee.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract FeeTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testFee() public { 11 | vm.fee(10); 12 | assertEq(block.basefee, 10, "fee failed"); 13 | } 14 | 15 | function testFeeFuzzed(uint256 fee) public { 16 | vm.fee(fee); 17 | assertEq(block.basefee, fee, "fee failed"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/cheats/Ffi.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract FfiTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testFfi() public { 11 | string[] memory inputs = new string[](3); 12 | inputs[0] = "bash"; 13 | inputs[1] = "-c"; 14 | inputs[2] = 15 | "echo -n 0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000966666920776f726b730000000000000000000000000000000000000000000000"; 16 | 17 | bytes memory res = vm.ffi(inputs); 18 | (string memory output) = abi.decode(res, (string)); 19 | assertEq(output, "ffi works", "ffi failed"); 20 | } 21 | 22 | function testFfiString() public { 23 | string[] memory inputs = new string[](3); 24 | inputs[0] = "echo"; 25 | inputs[1] = "-n"; 26 | inputs[2] = "gm"; 27 | 28 | bytes memory res = vm.ffi(inputs); 29 | assertEq(string(res), "gm"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /testdata/cheats/GetBlockTimestamp.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract GetBlockTimestampTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testGetTimestamp() public { 11 | uint256 timestamp = vm.getBlockTimestamp(); 12 | assertEq(timestamp, 1, "timestamp should be 1"); 13 | } 14 | 15 | function testGetTimestampWithWarp() public { 16 | assertEq(vm.getBlockTimestamp(), 1, "timestamp should be 1"); 17 | vm.warp(10); 18 | assertEq(vm.getBlockTimestamp(), 10, "warp failed"); 19 | } 20 | 21 | function testGetTimestampWithWarpFuzzed(uint128 jump) public { 22 | uint256 pre = vm.getBlockTimestamp(); 23 | vm.warp(pre + jump); 24 | assertEq(vm.getBlockTimestamp(), pre + jump, "warp failed"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /testdata/cheats/GetLabel.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity >=0.8.0; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract GetLabelTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testGetLabel() public { 11 | // Label an address. 12 | vm.label(address(1), "Sir Address the 1st"); 13 | 14 | // Retrieve the label and check it. 15 | string memory label = vm.getLabel(address(1)); 16 | assertEq(label, "Sir Address the 1st"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /testdata/cheats/GetNonce.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract Foo {} 8 | 9 | contract GetNonceTest is DSTest { 10 | Vm constant vm = Vm(HEVM_ADDRESS); 11 | 12 | function testGetNonce() public { 13 | uint64 nonce1 = vm.getNonce(address(this)); 14 | new Foo(); 15 | new Foo(); 16 | uint64 nonce2 = vm.getNonce(address(this)); 17 | assertEq(nonce1 + 2, nonce2); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/cheats/Label.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract LabelTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testLabel() public { 11 | vm.label(address(1), "Sir Address the 1st"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /testdata/cheats/ProjectRoot.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract ProjectRootTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | bytes public manifestDirBytes; 10 | 11 | function testProjectRoot() public { 12 | manifestDirBytes = bytes(vm.envString("CARGO_MANIFEST_DIR")); 13 | for (uint256 i = 0; i < 7; i++) { 14 | manifestDirBytes.pop(); 15 | } 16 | // replace "forge" suffix with "testdata" suffix to get expected project root from manifest dir 17 | bytes memory expectedRootSuffix = bytes("testd"); 18 | for (uint256 i = 1; i < 6; i++) { 19 | manifestDirBytes[manifestDirBytes.length - i] = expectedRootSuffix[expectedRootSuffix.length - i]; 20 | } 21 | bytes memory expectedRootDir = abi.encodePacked(manifestDirBytes, "ata"); 22 | 23 | assertEq(vm.projectRoot(), string(expectedRootDir)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /testdata/cheats/Remember.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract RememberTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testRememberKey() public { 11 | string memory mnemonic = "test test test test test test test test test test test junk"; 12 | 13 | uint256 privateKey = vm.deriveKey(mnemonic, 0); 14 | assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); 15 | 16 | address thisAddress = vm.rememberKey(privateKey); 17 | assertEq(thisAddress, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/cheats/Roll.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract RollTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testRoll() public { 11 | vm.roll(10); 12 | assertEq(block.number, 10, "roll failed"); 13 | } 14 | 15 | function testRollFuzzed(uint128 jump) public { 16 | uint256 pre = block.number; 17 | vm.roll(block.number + jump); 18 | assertEq(block.number, pre + jump, "roll failed"); 19 | } 20 | 21 | function testRollHash() public { 22 | assertEq(blockhash(block.number), 0x0, "initial block hash is incorrect"); 23 | 24 | vm.roll(5); 25 | bytes32 hash = blockhash(5); 26 | assertTrue(blockhash(4) != 0x0, "new block hash is incorrect"); 27 | 28 | vm.roll(10); 29 | assertTrue(blockhash(5) != blockhash(10), "block hash collision"); 30 | 31 | vm.roll(5); 32 | assertEq(blockhash(5), hash, "block 5 changed hash"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /testdata/cheats/SetNonce.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract Foo { 8 | function f() external view returns (uint256) { 9 | return 1; 10 | } 11 | } 12 | 13 | contract SetNonceTest is DSTest { 14 | Vm constant vm = Vm(HEVM_ADDRESS); 15 | Foo public foo; 16 | 17 | function setUp() public { 18 | foo = new Foo(); 19 | } 20 | 21 | function testSetNonce() public { 22 | vm.setNonce(address(foo), 10); 23 | // makes sure working correctly after mutating nonce. 24 | foo.f(); 25 | assertEq(vm.getNonce(address(foo)), 10); 26 | foo.f(); 27 | } 28 | 29 | function testFailInvalidNonce() public { 30 | vm.setNonce(address(foo), 10); 31 | // set lower nonce should fail 32 | vm.setNonce(address(foo), 5); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /testdata/cheats/SetNonceUnsafe.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract Foo { 8 | function f() external view returns (uint256) { 9 | return 1; 10 | } 11 | } 12 | 13 | contract SetNonceTest is DSTest { 14 | Vm constant vm = Vm(HEVM_ADDRESS); 15 | Foo public foo; 16 | 17 | function setUp() public { 18 | foo = new Foo(); 19 | } 20 | 21 | function testSetNonceUnsafe() public { 22 | vm.setNonceUnsafe(address(foo), 10); 23 | // makes sure working correctly after mutating nonce. 24 | foo.f(); 25 | assertEq(vm.getNonce(address(foo)), 10); 26 | foo.f(); 27 | } 28 | 29 | function testDoesNotFailDecreasingNonce() public { 30 | vm.setNonce(address(foo), 10); 31 | vm.setNonceUnsafe(address(foo), 5); 32 | assertEq(vm.getNonce(address(foo)), 5); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /testdata/cheats/Sign.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract SignTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testSignDigest(uint248 pk, bytes32 digest) public { 11 | vm.assume(pk != 0); 12 | 13 | (uint8 v, bytes32 r, bytes32 s) = vm.sign(pk, digest); 14 | address expected = vm.addr(pk); 15 | address actual = ecrecover(digest, v, r, s); 16 | 17 | assertEq(actual, expected, "digest signer did not match"); 18 | } 19 | 20 | function testSignMessage(uint248 pk, bytes memory message) public { 21 | testSignDigest(pk, keccak256(message)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testdata/cheats/SignP256.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract SignTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testSignP256() public { 11 | bytes32 pk = hex"A8568B74282DCC66FF70F10B4CE5CC7B391282F5381BBB4F4D8DD96974B16E6B"; 12 | bytes32 digest = hex"54705ba3baafdbdfba8c5f9a70f7a89bee98d906b53e31074da7baecdc0da9ad"; 13 | 14 | (bytes32 r, bytes32 s) = vm.signP256(uint256(pk), digest); 15 | assertEq(r, hex"7C11C3641B19E7822DB644CBF76ED0420A013928C2FD3E36D8EF983B103BDFE1"); 16 | assertEq(s, hex"317D89879868D484810D4E508A96109F8C87617B7BE9337411348D7B786F945F"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /testdata/cheats/Skip.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract SkipTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testSkip() public { 11 | vm.skip(true); 12 | revert("Should not reach this revert"); 13 | } 14 | 15 | function testFailNotSkip() public { 16 | vm.skip(false); 17 | revert("This test should fail"); 18 | } 19 | 20 | function testFuzzSkip(uint256 x) public { 21 | vm.skip(true); 22 | revert("Should not reach revert"); 23 | } 24 | 25 | function testFailFuzzSkip(uint256 x) public { 26 | vm.skip(false); 27 | revert("This test should fail"); 28 | } 29 | 30 | function statefulFuzzSkip() public { 31 | vm.skip(true); 32 | require(true == false, "Test should not reach invariant"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /testdata/cheats/Travel.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract ChainIdTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testChainId() public { 11 | vm.chainId(10); 12 | assertEq(block.chainid, 10, "chainId switch failed"); 13 | } 14 | 15 | function testChainIdFuzzed(uint64 chainId) public { 16 | vm.chainId(chainId); 17 | assertEq(block.chainid, chainId, "chainId switch failed"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/cheats/Warp.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract WarpTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testWarp() public { 11 | vm.warp(10); 12 | assertEq(block.timestamp, 10, "warp failed"); 13 | } 14 | 15 | function testWarpFuzzed(uint128 jump) public { 16 | uint256 pre = block.timestamp; 17 | vm.warp(block.timestamp + jump); 18 | assertEq(block.timestamp, pre + jump, "warp failed"); 19 | } 20 | 21 | function testWarp2() public { 22 | assertEq(block.timestamp, 1); 23 | vm.warp(100); 24 | assertEq(block.timestamp, 100); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /testdata/cheats/getBlockNumber.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "./Vm.sol"; 6 | 7 | contract GetBlockNumberTest is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testGetBlockNumber() public { 11 | uint256 height = vm.getBlockNumber(); 12 | assertEq(height, uint256(block.number), "height should be equal to block.number"); 13 | } 14 | 15 | function testGetBlockNumberWithRoll() public { 16 | vm.roll(10); 17 | assertEq(vm.getBlockNumber(), 10, "could not get correct block height after roll"); 18 | } 19 | 20 | function testGetBlockNumberWithRollFuzzed(uint128 jump) public { 21 | uint256 pre = vm.getBlockNumber(); 22 | vm.roll(pre + jump); 23 | assertEq(vm.getBlockNumber(), pre + jump, "could not get correct block height after roll"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /testdata/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/core/DSStyle.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract DSStyleTest is DSTest { 7 | function testFailingAssertions() public { 8 | emit log_string("assertionOne"); 9 | assertEq(uint256(1), uint256(2)); 10 | emit log_string("assertionTwo"); 11 | assertEq(uint256(3), uint256(4)); 12 | emit log_string("done"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /testdata/core/FailingSetup.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract FailingSetupTest is DSTest { 7 | event Test(uint256 n); 8 | 9 | function setUp() public { 10 | emit Test(42); 11 | require(false, "setup failed predictably"); 12 | } 13 | 14 | function testFailShouldBeMarkedAsFailedBecauseOfSetup() public { 15 | emit log("setup did not fail"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /testdata/core/FailingTestAfterFailedSetup.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract FailingTestAfterFailedSetupTest is DSTest { 7 | function setUp() public { 8 | assertTrue(false); 9 | } 10 | 11 | function testAssertSuccess() public { 12 | assertTrue(true); 13 | } 14 | 15 | function testAssertFailure() public { 16 | assertTrue(false); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /testdata/core/MultipleSetup.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract MultipleSetup is DSTest { 7 | function setUp() public {} 8 | 9 | function setup() public {} 10 | 11 | function testFailShouldBeMarkedAsFailedBecauseOfSetup() public { 12 | assert(true); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /testdata/core/PaymentFailure.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | contract Payable { 8 | function pay() public payable {} 9 | } 10 | 11 | contract PaymentFailureTest is DSTest { 12 | Vm constant vm = Vm(HEVM_ADDRESS); 13 | 14 | function testCantPay() public { 15 | Payable target = new Payable(); 16 | vm.prank(address(1)); 17 | target.pay{value: 1}(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/core/Reverting.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | contract RevertingTest { 5 | function testFailRevert() public pure { 6 | require(false, "should revert here"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /testdata/core/SetupConsistency.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract SetupConsistencyCheck is DSTest { 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/fixtures/Derive/mnemonic_chinese_simplified.txt: -------------------------------------------------------------------------------- 1 | 谐 谐 谐 谐 谐 谐 谐 谐 谐 谐 谐 宗 -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_chinese_traditional.txt: -------------------------------------------------------------------------------- 1 | 諧 諧 諧 諧 諧 諧 諧 諧 諧 諧 諧 宗 -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_czech.txt: -------------------------------------------------------------------------------- 1 | uzenina uzenina uzenina uzenina uzenina uzenina uzenina uzenina uzenina uzenina uzenina nevina -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_english.txt: -------------------------------------------------------------------------------- 1 | test test test test test test test test test test test junk -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_french.txt: -------------------------------------------------------------------------------- 1 | sonde sonde sonde sonde sonde sonde sonde sonde sonde sonde sonde hématome -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_italian.txt: -------------------------------------------------------------------------------- 1 | surgelato surgelato surgelato surgelato surgelato surgelato surgelato surgelato surgelato surgelato surgelato mansarda -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_japanese.txt: -------------------------------------------------------------------------------- 1 | ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ほんけ ぜんご -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_korean.txt: -------------------------------------------------------------------------------- 1 | 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 큰어머니 시스템 -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_portuguese.txt: -------------------------------------------------------------------------------- 1 | sobra sobra sobra sobra sobra sobra sobra sobra sobra sobra sobra guarani -------------------------------------------------------------------------------- /testdata/fixtures/Derive/mnemonic_spanish.txt: -------------------------------------------------------------------------------- 1 | tacto tacto tacto tacto tacto tacto tacto tacto tacto tacto tacto lacra -------------------------------------------------------------------------------- /testdata/fixtures/Dir/depth1: -------------------------------------------------------------------------------- 1 | Wow! 😀 -------------------------------------------------------------------------------- /testdata/fixtures/Dir/nested/depth2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/base/foundry/5ef0d6f22305b78ed240a7371be57108941f12cc/testdata/fixtures/Dir/nested/depth2 -------------------------------------------------------------------------------- /testdata/fixtures/Dir/nested/nested2/depth3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/base/foundry/5ef0d6f22305b78ed240a7371be57108941f12cc/testdata/fixtures/Dir/nested/nested2/depth3 -------------------------------------------------------------------------------- /testdata/fixtures/File/read.txt: -------------------------------------------------------------------------------- 1 | hello readable world 2 | this is the second line! -------------------------------------------------------------------------------- /testdata/fixtures/File/symlink: -------------------------------------------------------------------------------- 1 | read.txt -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/fixtures/Json/Issue4630.json: -------------------------------------------------------------------------------- 1 | { 2 | "local": { 3 | "prop1": 10 4 | }, 5 | "localempty": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /testdata/fixtures/Json/wholeJson.json: -------------------------------------------------------------------------------- 1 | { 2 | "str": "hai", 3 | "uintArray": [42, 43], 4 | "strArray": ["hai", "there"] 5 | } 6 | -------------------------------------------------------------------------------- /testdata/fixtures/Json/write_complex_test.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": 123, 3 | "b": "test", 4 | "c": { 5 | "a": 123, 6 | "b": "test" 7 | } 8 | } -------------------------------------------------------------------------------- /testdata/fixtures/Json/write_test.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": 123, 3 | "b": "0x000000000000000000000000000000000000bEEF" 4 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /testdata/fixtures/Rpc/balance_params.json: -------------------------------------------------------------------------------- 1 | ["0x8D97689C9818892B700e27F316cc3E41e17fBeb9", "0x117BC09"] -------------------------------------------------------------------------------- /testdata/fixtures/SolidityGeneration/GeneratedNamedInterface.sol: -------------------------------------------------------------------------------- 1 | interface test { 2 | event Bar(address indexed x); 3 | event Foo(address x); 4 | 5 | function guess(uint8 n, address x) external payable; 6 | function isComplete() external view returns (bool example, string memory); 7 | } 8 | -------------------------------------------------------------------------------- /testdata/fixtures/SolidityGeneration/GeneratedUnnamedInterface.sol: -------------------------------------------------------------------------------- 1 | interface Interface { 2 | event Bar(address indexed x); 3 | event Foo(address x); 4 | 5 | function guess(uint8 n, address x) external payable; 6 | function isComplete() external view returns (bool example, string memory); 7 | } 8 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /testdata/fork/ForkSame_1.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | contract ForkTest is DSTest { 8 | address constant WETH_TOKEN_ADDR = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | uint256 forkA; 11 | 12 | // this will create two _different_ forks during setup 13 | function setUp() public { 14 | forkA = vm.createFork("https://eth-mainnet.alchemyapi.io/v2/Lc7oIGYeL_QvInzI0Wiu_pOZZDEKBrdf", 15_977_624); 15 | } 16 | 17 | function testDummy() public { 18 | uint256 balance = WETH_TOKEN_ADDR.balance; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /testdata/fork/ForkSame_2.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | contract ForkTest is DSTest { 8 | address constant WETH_TOKEN_ADDR = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | uint256 forkA; 11 | 12 | // this will create two _different_ forks during setup 13 | function setUp() public { 14 | forkA = vm.createFork("https://eth-mainnet.alchemyapi.io/v2/Lc7oIGYeL_QvInzI0Wiu_pOZZDEKBrdf", 15_977_624); 15 | } 16 | 17 | function testDummy() public { 18 | uint256 balance = WETH_TOKEN_ADDR.balance; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /testdata/fuzz/Fuzz.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | interface Vm { 7 | function toString(bytes32) external returns (string memory); 8 | } 9 | 10 | contract FuzzTest is DSTest { 11 | constructor() { 12 | emit log("constructor"); 13 | } 14 | 15 | function setUp() public { 16 | emit log("setUp"); 17 | } 18 | 19 | function testFailFuzz(uint8 x) public { 20 | emit log("testFailFuzz"); 21 | require(x > 128, "should revert"); 22 | } 23 | 24 | function testSuccessfulFuzz(uint128 a, uint128 b) public { 25 | emit log("testSuccessfulFuzz"); 26 | assertEq(uint256(a) + uint256(b), uint256(a) + uint256(b)); 27 | } 28 | 29 | function testToStringFuzz(bytes32 data) public { 30 | Vm vm = Vm(HEVM_ADDRESS); 31 | vm.toString(data); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /testdata/fuzz/invariant/common/InvariantHandlerFailure.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity ^0.8.0; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | struct FuzzSelector { 7 | address addr; 8 | bytes4[] selectors; 9 | } 10 | 11 | contract Handler is DSTest { 12 | function doSomething() public { 13 | require(false, "failed on revert"); 14 | } 15 | } 16 | 17 | contract InvariantHandlerFailure is DSTest { 18 | bytes4[] internal selectors; 19 | 20 | Handler handler; 21 | 22 | function targetSelectors() public returns (FuzzSelector[] memory) { 23 | FuzzSelector[] memory targets = new FuzzSelector[](1); 24 | bytes4[] memory selectors = new bytes4[](1); 25 | selectors[0] = handler.doSomething.selector; 26 | targets[0] = FuzzSelector(address(handler), selectors); 27 | return targets; 28 | } 29 | 30 | function setUp() public { 31 | handler = new Handler(); 32 | } 33 | 34 | function statefulFuzz_BrokenInvariant() public {} 35 | } 36 | -------------------------------------------------------------------------------- /testdata/fuzz/invariant/common/InvariantTest1.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract InvariantBreaker { 7 | bool public flag0 = true; 8 | bool public flag1 = true; 9 | 10 | function set0(int256 val) public returns (bool) { 11 | if (val % 100 == 0) { 12 | flag0 = false; 13 | } 14 | return flag0; 15 | } 16 | 17 | function set1(int256 val) public returns (bool) { 18 | if (val % 10 == 0 && !flag0) { 19 | flag1 = false; 20 | } 21 | return flag1; 22 | } 23 | } 24 | 25 | contract InvariantTest is DSTest { 26 | InvariantBreaker inv; 27 | 28 | function setUp() public { 29 | inv = new InvariantBreaker(); 30 | } 31 | 32 | function invariant_neverFalse() public { 33 | require(inv.flag1(), "false"); 34 | } 35 | 36 | function statefulFuzz_neverFalseWithInvariantAlias() public { 37 | require(inv.flag1(), "false"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /testdata/fuzz/invariant/target/ExcludeContracts.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract Hello { 7 | bool public world = true; 8 | 9 | function change() public { 10 | world = false; 11 | } 12 | } 13 | 14 | contract ExcludeContracts is DSTest { 15 | Hello hello; 16 | 17 | function setUp() public { 18 | hello = new Hello(); 19 | new Hello(); 20 | } 21 | 22 | function excludeContracts() public returns (address[] memory) { 23 | address[] memory addrs = new address[](1); 24 | addrs[0] = address(hello); 25 | return addrs; 26 | } 27 | 28 | function invariantTrueWorld() public { 29 | require(hello.world() == true, "false world"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /testdata/fuzz/invariant/target/TargetContracts.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract Hello { 7 | bool public world = true; 8 | 9 | function change() public { 10 | world = false; 11 | } 12 | } 13 | 14 | contract TargetContracts is DSTest { 15 | Hello hello1; 16 | Hello hello2; 17 | 18 | function setUp() public { 19 | hello1 = new Hello(); 20 | hello2 = new Hello(); 21 | } 22 | 23 | function targetContracts() public returns (address[] memory) { 24 | address[] memory addrs = new address[](1); 25 | addrs[0] = address(hello1); 26 | return addrs; 27 | } 28 | 29 | function invariantTrueWorld() public { 30 | require(hello2.world() == true, "false world"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /testdata/fuzz/invariant/target/TargetSelectors.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | struct FuzzSelector { 7 | address addr; 8 | bytes4[] selectors; 9 | } 10 | 11 | contract Hello { 12 | bool public world = true; 13 | 14 | function change() public { 15 | world = true; 16 | } 17 | 18 | function real_change() public { 19 | world = false; 20 | } 21 | } 22 | 23 | contract TargetSelectors is DSTest { 24 | Hello hello; 25 | 26 | function setUp() public { 27 | hello = new Hello(); 28 | } 29 | 30 | function targetSelectors() public returns (FuzzSelector[] memory) { 31 | FuzzSelector[] memory targets = new FuzzSelector[](1); 32 | bytes4[] memory selectors = new bytes4[](1); 33 | selectors[0] = Hello.change.selector; 34 | targets[0] = FuzzSelector(address(hello), selectors); 35 | return targets; 36 | } 37 | 38 | function invariantTrueWorld() public { 39 | require(hello.world() == true, "false world"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /testdata/fuzz/invariant/target/TargetSenders.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract Hello { 7 | bool public world = true; 8 | 9 | function change() public { 10 | require(msg.sender == address(0xdeadbeef)); 11 | world = false; 12 | } 13 | } 14 | 15 | contract TargetSenders is DSTest { 16 | Hello hello; 17 | 18 | function setUp() public { 19 | hello = new Hello(); 20 | } 21 | 22 | function targetSenders() public returns (address[] memory) { 23 | address[] memory addrs = new address[](1); 24 | addrs[0] = address(0xdeadbeef); 25 | return addrs; 26 | } 27 | 28 | function invariantTrueWorld() public { 29 | require(hello.world() == true, "false world"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /testdata/inline/FuzzInlineConf.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity >=0.8.0; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract FuzzInlineConf is DSTest { 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 | -------------------------------------------------------------------------------- /testdata/linking/simple/Simple.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/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 DSTest { 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 | -------------------------------------------------------------------------------- /testdata/repros/Issue2623.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/2623 8 | contract Issue2623Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testRollFork() public { 12 | uint256 fork = vm.createFork("rpcAlias", 10); 13 | vm.selectFork(fork); 14 | 15 | assertEq(block.number, 10); 16 | assertEq(block.timestamp, 1438270128); 17 | 18 | vm.rollFork(11); 19 | 20 | assertEq(block.number, 11); 21 | assertEq(block.timestamp, 1438270136); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testdata/repros/Issue2629.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/2629 8 | contract Issue2629Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testSelectFork() public { 12 | address coinbase = 0x0193d941b50d91BE6567c7eE1C0Fe7AF498b4137; 13 | 14 | uint256 f1 = vm.createSelectFork("rpcAlias", 9); 15 | vm.selectFork(f1); 16 | 17 | assertEq(block.number, 9); 18 | assertEq(coinbase.balance, 11250000000000000000); 19 | 20 | uint256 f2 = vm.createFork("rpcAlias", 10); 21 | vm.selectFork(f2); 22 | 23 | assertEq(block.number, 10); 24 | assertEq(coinbase.balance, 16250000000000000000); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /testdata/repros/Issue2723.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/2723 8 | contract Issue2723Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testRollFork() public { 12 | address coinbase = 0x0193d941b50d91BE6567c7eE1C0Fe7AF498b4137; 13 | 14 | vm.createSelectFork("rpcAlias", 9); 15 | 16 | assertEq(block.number, 9); 17 | assertEq(coinbase.balance, 11250000000000000000); 18 | 19 | vm.rollFork(10); 20 | 21 | assertEq(block.number, 10); 22 | assertEq(coinbase.balance, 16250000000000000000); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /testdata/repros/Issue2898.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | import "../logs/console.sol"; 7 | 8 | // https://github.com/foundry-rs/foundry/issues/2898 9 | contract Issue2898Test is DSTest { 10 | address private constant BRIDGE = address(10); 11 | address private constant BENEFICIARY = address(11); 12 | Vm constant vm = Vm(HEVM_ADDRESS); 13 | 14 | function setUp() public { 15 | vm.deal(BRIDGE, 100); 16 | vm.deal(BENEFICIARY, 99); 17 | 18 | vm.setNonce(BRIDGE, 10); 19 | } 20 | 21 | function testDealBalance() public { 22 | assertEq(BRIDGE.balance, 100); 23 | assertEq(BENEFICIARY.balance, 99); 24 | } 25 | 26 | function testSetNonce() public { 27 | assertEq(vm.getNonce(BRIDGE), 10); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /testdata/repros/Issue2984.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/2984 8 | contract Issue2984Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | uint256 fork; 11 | uint256 snapshot; 12 | 13 | function setUp() public { 14 | fork = vm.createSelectFork("https://api.avax-test.network/ext/bc/C/rpc", 12880747); 15 | snapshot = vm.snapshot(); 16 | } 17 | 18 | function testForkRevertSnapshot() public { 19 | vm.revertTo(snapshot); 20 | } 21 | 22 | function testForkSelectSnapshot() public { 23 | uint256 fork2 = vm.createSelectFork("https://api.avax-test.network/ext/bc/C/rpc", 12880749); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /testdata/repros/Issue3119.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/3119 8 | contract Issue3119Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | address public owner = vm.addr(1); 12 | address public alice = vm.addr(2); 13 | 14 | function testRollFork() public { 15 | uint256 fork = vm.createFork("rpcAlias"); 16 | vm.selectFork(fork); 17 | 18 | FortressSwap fortressSwap = new FortressSwap(address(owner)); 19 | vm.prank(owner); 20 | fortressSwap.updateOwner(alice); 21 | } 22 | } 23 | 24 | contract FortressSwap { 25 | address owner; 26 | 27 | constructor(address _owner) { 28 | owner = _owner; 29 | } 30 | 31 | function updateOwner(address new_owner) public { 32 | require(msg.sender == owner, "must be owner"); 33 | owner = new_owner; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /testdata/repros/Issue3189.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/3189 8 | contract MyContract { 9 | function foo(uint256 arg) public returns (uint256) { 10 | return arg + 2; 11 | } 12 | } 13 | 14 | contract MyContractUser is DSTest { 15 | MyContract immutable myContract; 16 | 17 | constructor() { 18 | myContract = new MyContract(); 19 | } 20 | 21 | function foo(uint256 arg) public returns (uint256 ret) { 22 | ret = myContract.foo(arg); 23 | assertEq(ret, arg + 1, "Invariant failed"); 24 | } 25 | } 26 | 27 | contract Issue3189Test is DSTest { 28 | function testFoo() public { 29 | MyContractUser user = new MyContractUser(); 30 | uint256 fooRet = user.foo(123); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /testdata/repros/Issue3190.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | import "../logs/console.sol"; 7 | 8 | // https://github.com/foundry-rs/foundry/issues/3190 9 | contract Issue3190Test is DSTest { 10 | Vm constant vm = Vm(HEVM_ADDRESS); 11 | 12 | function setUp() public { 13 | vm.chainId(99); 14 | assertEq(99, block.chainid); 15 | } 16 | 17 | function testChainId() public { 18 | assertEq(99, block.chainid); 19 | vm.chainId(100); 20 | assertEq(100, block.chainid); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /testdata/repros/Issue3192.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/3192 8 | contract Issue3192Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | uint256 fork1; 11 | uint256 fork2; 12 | 13 | function setUp() public { 14 | fork1 = vm.createFork("rpcAlias", 7475589); 15 | fork2 = vm.createFork("rpcAlias", 12880747); 16 | vm.selectFork(fork1); 17 | } 18 | 19 | function testForkSwapSelect() public { 20 | assertEq(fork1, vm.activeFork()); 21 | vm.selectFork(fork2); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testdata/repros/Issue3223.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/3223 8 | contract Issue3223Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | uint256 fork1; 11 | uint256 fork2; 12 | 13 | function setUp() public { 14 | fork1 = vm.createFork("https://goerli.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001", 7475589); 15 | fork2 = vm.createFork("https://api.avax-test.network/ext/bc/C/rpc", 12880747); 16 | } 17 | 18 | function testForkNonce() public { 19 | address user = address(0xF0959944122fb1ed4CfaBA645eA06EED30427BAA); 20 | assertEq(user, msg.sender); 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), 3); 29 | vm.prank(user); 30 | new Counter(); 31 | } 32 | } 33 | 34 | contract Counter {} 35 | -------------------------------------------------------------------------------- /testdata/repros/Issue3347.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/3347 8 | contract Issue3347Test is DSTest { 9 | event log2(uint256, uint256); 10 | 11 | function test() public { 12 | emit log2(1, 2); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /testdata/repros/Issue3437.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity >=0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/3437 8 | contract Issue3347Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function internalRevert() internal { 12 | revert(); 13 | } 14 | 15 | function testFailExample() public { 16 | vm.expectRevert(); 17 | internalRevert(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/repros/Issue3596.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/3596 8 | contract Issue3596Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testDealTransfer() public { 12 | address addr = vm.addr(1337); 13 | vm.startPrank(addr); 14 | vm.deal(addr, 20000001 ether); 15 | payable(address(this)).transfer(20000000 ether); 16 | 17 | Nested nested = new Nested(); 18 | nested.doStuff(); 19 | vm.stopPrank(); 20 | } 21 | } 22 | 23 | contract Nested { 24 | function doStuff() public { 25 | doRevert(); 26 | } 27 | 28 | function doRevert() public { 29 | revert("This fails"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /testdata/repros/Issue3653.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/3653 8 | contract Issue3653Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | uint256 fork; 11 | Token token; 12 | 13 | constructor() { 14 | fork = vm.createSelectFork("rpcAlias", 10); 15 | token = new Token(); 16 | vm.makePersistent(address(token)); 17 | } 18 | 19 | function testDummy() public { 20 | assertEq(block.number, 10); 21 | } 22 | } 23 | 24 | contract Token {} 25 | -------------------------------------------------------------------------------- /testdata/repros/Issue3661.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | // https://github.com/foundry-rs/foundry/issues/3661 7 | contract Issue3661Test is DSTest { 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 | -------------------------------------------------------------------------------- /testdata/repros/Issue3674.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/3674 8 | contract Issue3674Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testNonceCreateSelect() public { 12 | vm.createSelectFork("https://goerli.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001"); 13 | 14 | vm.createSelectFork("https://api.avax-test.network/ext/bc/C/rpc"); 15 | assert(vm.getNonce(msg.sender) > 0x17); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /testdata/repros/Issue3723.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity >=0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/3723 8 | contract Issue3723Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testFailExample() public { 12 | vm.expectRevert(); 13 | revert(); 14 | 15 | vm.expectRevert(); 16 | emit log_string("Do not revert"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /testdata/repros/Issue3753.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/3753 8 | contract Issue3753Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function test_repro() public { 12 | bool res; 13 | assembly { 14 | res := staticcall(gas(), 4, 0, 0, 0, 0) 15 | } 16 | vm.expectRevert("require"); 17 | this.revert_require(); 18 | } 19 | 20 | function revert_require() public { 21 | revert("require"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testdata/repros/Issue3792.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/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.snapshot(); 20 | 21 | vm.prank(test); 22 | 23 | vm.revertTo(snapshotId); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /testdata/repros/Issue4630.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/4630 8 | contract Issue4630Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testExistingValue() public { 12 | string memory path = "fixtures/Json/Issue4630.json"; 13 | string memory json = vm.readFile(path); 14 | uint256 val = vm.parseJsonUint(json, ".local.prop1"); 15 | assertEq(val, 10); 16 | } 17 | 18 | function testMissingValue() public { 19 | string memory path = "fixtures/Json/Issue4630.json"; 20 | string memory json = vm.readFile(path); 21 | vm._expectCheatcodeRevert(); 22 | vm.parseJsonUint(json, ".localempty.prop1"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /testdata/repros/Issue4640.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/4640 8 | contract Issue4640Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testArbitrumBlockNumber() public { 12 | // 13 | vm.createSelectFork("https://arb-mainnet.alchemyapi.io/v2/Lc7oIGYeL_QvInzI0Wiu_pOZZDEKBrdf", 75219831); 14 | // L1 block number 15 | assertEq(block.number, 16939475); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /testdata/repros/Issue4832.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity >=0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/4832 8 | contract Issue4832Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testFailExample() public { 12 | assertEq(uint256(1), 2); 13 | 14 | vm.expectRevert(); 15 | revert(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /testdata/repros/Issue5808.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/5808 8 | contract Issue5808Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testReadInt() public { 12 | string memory str1 = '["ffffffff","00000010"]'; 13 | vm._expectCheatcodeRevert(); 14 | int256[] memory ints1 = vm.parseJsonIntArray(str1, ""); 15 | 16 | string memory str2 = '["0xffffffff","0x00000010"]'; 17 | int256[] memory ints2 = vm.parseJsonIntArray(str2, ""); 18 | assertEq(ints2[0], 0xffffffff); 19 | assertEq(ints2[1], 16); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /testdata/repros/Issue5929.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/5929 8 | contract Issue5929Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function test_transact_not_working() public { 12 | vm.createSelectFork("rpcAlias", 15625301); 13 | // https://etherscan.io/tx/0x96a129768ec66fd7d65114bf182f4e173bf0b73a44219adaf71f01381a3d0143 14 | vm.transact(hex"96a129768ec66fd7d65114bf182f4e173bf0b73a44219adaf71f01381a3d0143"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /testdata/repros/Issue5948.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/5948 8 | contract Issue5948Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | /// forge-config: default.fuzz.runs = 2 12 | function testSleepFuzzed(uint256 _milliseconds) public { 13 | // Limit sleep time to 2 seconds to decrease test time 14 | uint256 milliseconds = _milliseconds % 2000; 15 | 16 | string[] memory inputs = new string[](2); 17 | inputs[0] = "date"; 18 | // OS X does not support precision more than 1 second 19 | inputs[1] = "+%s000"; 20 | 21 | bytes memory res = vm.ffi(inputs); 22 | uint256 start = vm.parseUint(string(res)); 23 | 24 | vm.sleep(milliseconds); 25 | 26 | res = vm.ffi(inputs); 27 | uint256 end = vm.parseUint(string(res)); 28 | 29 | // Limit precision to 1000 ms 30 | assertGe(end - start, milliseconds / 1000 * 1000, "sleep failed"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /testdata/repros/Issue6070.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/6070 8 | contract Issue6066Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testNonPrefixed() public { 12 | vm.setEnv("__FOUNDRY_ISSUE_6066", "abcd"); 13 | vm._expectCheatcodeRevert( 14 | "failed parsing $__FOUNDRY_ISSUE_6066 as type `uint256`: missing hex prefix (\"0x\") for hex string" 15 | ); 16 | uint256 x = vm.envUint("__FOUNDRY_ISSUE_6066"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /testdata/repros/Issue6170.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | contract Emitter { 8 | event Values(uint256 indexed a, uint256 indexed b); 9 | 10 | function plsEmit(uint256 a, uint256 b) external { 11 | emit Values(a, b); 12 | } 13 | } 14 | 15 | // https://github.com/foundry-rs/foundry/issues/6170 16 | contract Issue6170Test is DSTest { 17 | Vm constant vm = Vm(HEVM_ADDRESS); 18 | 19 | event Values(uint256 indexed a, uint256 b); 20 | 21 | Emitter e = new Emitter(); 22 | 23 | function test() public { 24 | vm.expectEmit(true, true, false, true); 25 | emit Values(69, 420); 26 | e.plsEmit(69, 420); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /testdata/repros/Issue6180.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/6180 8 | contract Issue6180Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function test_timebug() external { 12 | uint256 start = block.timestamp; 13 | uint256 count = 4; 14 | uint256 duration = 15; 15 | for (uint256 i; i < count; i++) { 16 | vm.warp(block.timestamp + duration); 17 | } 18 | 19 | uint256 end = block.timestamp; 20 | assertEq(end, start + count * duration); 21 | assertEq(end - start, count * duration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testdata/repros/Issue6293.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Unlicense 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/6293 8 | contract Issue6293Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | constructor() { 12 | require(address(this).balance > 0); 13 | payable(address(1)).call{value: 1}(""); 14 | } 15 | 16 | function test() public { 17 | assertGt(address(this).balance, 0); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/repros/Issue6355.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/6355 8 | contract Issue6355Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | uint256 snapshot; 11 | Target targ; 12 | 13 | function setUp() public { 14 | snapshot = vm.snapshot(); 15 | targ = new Target(); 16 | } 17 | 18 | // this non-deterministically fails sometimes and passes sometimes 19 | function test_shouldPass() public { 20 | assertEq(2, targ.num()); 21 | } 22 | 23 | // always fails 24 | function test_shouldFailWithRevertTo() public { 25 | assertEq(3, targ.num()); 26 | vm.revertTo(snapshot); 27 | } 28 | 29 | // always fails 30 | function test_shouldFail() public { 31 | assertEq(3, targ.num()); 32 | } 33 | } 34 | 35 | contract Target { 36 | function num() public pure returns (uint256) { 37 | return 2; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /testdata/repros/Issue6501.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../logs/console.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/6501 8 | contract Issue6501Test is DSTest { 9 | function test_hhLogs() public { 10 | console.log("a"); 11 | console.log(uint256(1)); 12 | console.log("b", uint256(2)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /testdata/repros/Issue6538.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/6538 8 | contract Issue6538Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function test_transact() public { 12 | bytes32 lastHash = 0xdbdce1d5c14a6ca17f0e527ab762589d6a73f68697606ae0bb90df7ac9ec5087; 13 | vm.createSelectFork("rpcAlias", lastHash); 14 | bytes32 txhash = 0xadbe5cf9269a001d50990d0c29075b402bcc3a0b0f3258821881621b787b35c6; 15 | vm.transact(txhash); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /testdata/repros/Issue6554.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/6554 8 | contract Issue6554Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testPermissions() public { 12 | vm.writeFile("./out/Issue6554.t.sol/cachedFile.txt", "cached data"); 13 | string memory content = vm.readFile("./out/Issue6554.t.sol/cachedFile.txt"); 14 | assertEq(content, "cached data"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /testdata/repros/Issue6759.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | // https://github.com/foundry-rs/foundry/issues/6759 8 | contract Issue6759Test is DSTest { 9 | Vm constant vm = Vm(HEVM_ADDRESS); 10 | 11 | function testCreateMulti() public { 12 | uint256 fork1 = vm.createFork("rpcAlias", 10); 13 | uint256 fork2 = vm.createFork("rpcAlias", 10); 14 | uint256 fork3 = vm.createFork("rpcAlias", 10); 15 | assert(fork1 != fork2); 16 | assert(fork1 != fork3); 17 | assert(fork2 != fork3); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testdata/repros/Issue6966.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import "ds-test/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 DSTest { 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 | -------------------------------------------------------------------------------- /testdata/script/deploy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.18; 3 | 4 | import {DSTest} from "../lib/ds-test/src/test.sol"; 5 | import {Vm} from "../cheats/Vm.sol"; 6 | 7 | contract Greeter { 8 | string name; 9 | uint256 age; 10 | 11 | event Greet(string greet); 12 | 13 | function greeting(string memory _name) public returns (string memory) { 14 | name = _name; 15 | string memory greet = string(abi.encodePacked("Hello ", _name)); 16 | emit Greet(greet); 17 | return greet; 18 | } 19 | 20 | function setAge(uint256 _age) external { 21 | age = _age; 22 | } 23 | } 24 | 25 | contract Deploy is DSTest { 26 | Vm constant vm = Vm(HEVM_ADDRESS); 27 | 28 | Greeter greeter; 29 | string greeting; 30 | 31 | function run() external { 32 | vm.startBroadcast(); 33 | greeter = new Greeter(); 34 | greeting = greeter.greeting("john"); 35 | greeter.setAge(123); 36 | vm.stopBroadcast(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /testdata/spec/ShanghaiCompat.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | pragma solidity 0.8.20; 3 | 4 | import "ds-test/test.sol"; 5 | import "../cheats/Vm.sol"; 6 | 7 | contract ShanghaiCompat is DSTest { 8 | Vm constant vm = Vm(HEVM_ADDRESS); 9 | 10 | function testPush0() public { 11 | address target = address(uint160(uint256(0xc4f3))); 12 | 13 | bytes memory bytecode = hex"365f5f37365ff3"; 14 | // 36 CALLDATASIZE 15 | // 5F PUSH0 16 | // 5F PUSH0 17 | // 37 CALLDATACOPY -> copies calldata at mem[0..calldatasize] 18 | 19 | // 36 CALLDATASIZE 20 | // 5F PUSH0 21 | // F3 RETURN -> returns mem[0..calldatasize] 22 | 23 | vm.etch(target, bytecode); 24 | 25 | (bool success, bytes memory result) = target.call(bytes("hello PUSH0")); 26 | assertTrue(success); 27 | assertEq(string(result), "hello PUSH0"); 28 | } 29 | } 30 | --------------------------------------------------------------------------------