Foundry's configuration system allows you to configure it's tools the way you want while also providing with a sensible set of defaults.
Configurations can be arbitrarily namespaced by profiles. Foundry's default config is also named default
, but can
arbitrarily name and configure profiles as you like and set the FOUNDRY_PROFILE
environment variable to the selected
profile's name. This results in foundry's tools (forge) preferring the values in the profile with the named that's set
in FOUNDRY_PROFILE
. But all custom profiles inherit from the default
profile.
Foundry's tools search for a foundry.toml
or the filename in a FOUNDRY_CONFIG
environment variable starting at the
current working directory. If it is not found, the parent directory, its parent directory, and so on are searched until
the file is found or the root is reached. But the typical location for the global foundry.toml
would
be ~/.foundry/foundry.toml
, which is also checked. If the path set in FOUNDRY_CONFIG
is absolute, no such search
takes place and the absolute path is used directly.
In foundry.toml
you can define multiple profiles, therefore the file is assumed to be nested, so each top-level key
declares a profile and its values configure the profile.
The following is an example of what such a file might look like. This can also be obtained with forge config
```toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.10" # to use a specific local solc install set the path as solc = "<path to solc>/solc"
eth-rpc-url = "https://mainnet.infura.io"
hardhat
profile is selected[profile.hardhat] src = "contracts" out = "artifacts" libs = ["node_modules"]
spells
profile is selected[profile.spells]
```
When determining the profile to use, Config
considers the following sources in ascending priority order to read from
and merge, at the per-key level:
Config::default()
], which provides default values for all parameters.foundry.toml
or TOML file path in FOUNDRY_CONFIG
environment variable.FOUNDRY_
or DAPP_
prefixed environment variables.The selected profile is the value of the FOUNDRY_PROFILE
environment variable, or if it is not set, "default".
The following is a foundry.toml file with all configuration options set. See also /config/src/lib.rs and /cli/tests/it/config.rs.
```toml
[profile.default] src = 'src' test = 'test' script = 'script' out = 'out' libs = ['lib'] autodetectremappings = true # recursive auto-detection of remappings remappings = []
<path to lib>:<lib name>:<address>
: "src/MyLib.sol:MyLib:0x8De6DDbCd5053d32292AAA0D2105A32d108484a6"
libraries = [] cache = true cache_path = 'cache' broadcast = 'broadcast'
allow_paths = []
includepaths = [] force = false evmversion = 'shanghai' gasreports = ['*'] gasreports_ignore = []
auto_detect_solc
valueautodetectsolc = true offline = false optimizer = true optimizerruns = 200 modelchecker = { contracts = { 'a.sol' = [ 'A1', 'A2', ], 'b.sol' = [ 'B1', 'B2', ] }, engine = 'chc', targets = [ 'assert', 'outOfBounds', ], timeout = 10000 } verbosity = 0 ethrpcurl = "https://example.com/"
etherscanapikey = "YOURETHERSCANAPIKEY"
ignorederrorcodes = ["license", "code-size"] denywarnings = false matchtest = "Foo" nomatchtest = "Bar" matchcontract = "Foo" nomatchcontract = "Bar" matchpath = "/Foo" nomatchpath = "/Bar" ffi = false
address(uint160(uint256(keccak256("foundry default caller"))))
sender = '0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38' txorigin = '0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38' initialbalance = '0xffffffffffffffffffffffff' blocknumber = 0 forkblocknumber = 0 chainid = 1
i64::MAX
(9223372036854775807)gas_limit = "Max"
is equivalent to gas_limit = "18446744073709551615"
gaslimit = 9223372036854775807 gasprice = 0 blockbasefeepergas = 0 blockcoinbase = '0x0000000000000000000000000000000000000000' blocktimestamp = 0 blockdifficulty = 0 blockprevrandao = '0x0000000000000000000000000000000000000000' blockgaslimit = 30000000 memorylimit = 33554432 extraoutput = ["metadata"] extraoutputfiles = [] names = false sizes = false via_ir = false
chains = ["optimism", "mainnet"]
no_storage_caching = true
rpcstoragecaching = { chains = "all", endpoints = "all" }
rpc_storage_caching
entirelynostoragecaching = false
useliteralcontent = false
bytecode_hash = "ipfs"
cbor_metadata = true
revert_strings = "default"
forge test
a bit but is considered experimental at this point.sparsemode = false buildinfo = true buildinfopath = "build-info" root = "root"
vm.writeFile
access
restricts how the path
can be accessed via cheatcodesread-write
| true
=> read
+ write
access allowed (vm.readFile
+ vm.writeFile
)none
| false
=> no accessread
=> only read access (vm.readFile
)write
=> only write access (vm.writeFile
)allowed_paths
further lists the paths that are considered, e.g. ./
represents the project root directoryfs_permissions = [{ access = "read-write", path = "./"}]
fspermissions = [{ access = "read", path = "./out"}] [fuzz] runs = 256 maxtestrejects = 65536 seed = '0x3e8' dictionaryweight = 40 includestorage = true includepush_bytes = true
[invariant] runs = 256 depth = 15 failonrevert = false calloverride = false dictionaryweight = 80 includestorage = true includepushbytes = true shrinksequence = true
[fmt] linelength = 100 tabwidth = 2 bracket_spacing = true ```
Optimizer components can be tweaked with the OptimizerDetails
object:
See Compiler Input Description settings.optimizer.details
The optimizer_details
(optimizerDetails
also works) settings must be prefixed with the profile they correspond
to: [profile.default.optimizer_details]
belongs to the [profile.default]
profile
```toml [profile.default.optimizer_details] constantOptimizer = true yul = true
yulDetails
of the optimizer_details
for the default
profile[profile.default.optimizer_details.yulDetails] stackAllocation = true optimizerSteps = 'dhfoDgvulfnTUtnIf' ```
The rpc_endpoints
value accepts a list of alias = "<url|env var>"
pairs.
The following example declares two pairs:
The alias optimism
references the endpoint URL directly.
The alias mainnet
references the environment variable RPC_MAINNET
which holds the entire URL.
The alias goerli
references an endpoint that will be interpolated with the value the GOERLI_API_KEY
holds.
Environment variables need to be wrapped in ${}
toml
[rpc_endpoints]
optimism = "https://optimism.alchemyapi.io/v2/1234567"
mainnet = "${RPC_MAINNET}"
goerli = "https://eth-goerli.alchemyapi.io/v2/${GOERLI_API_KEY}"
The etherscan
value accepts a list of alias = "{key = "", url? ="", chain?= """""}"
items.
the key
attribute is always required and should contain the actual API key for that chain or an env var that holds the key in the form ${ENV_VAR}
The chain
attribute is optional if the alias
is the already the chain
name, such as in mainnet = { key = "${ETHERSCAN_MAINNET_KEY}"}
The optional url
attribute can be used to explicitly set the Etherscan API url, this is the recommended setting for chains not natively supported by name.
toml
[etherscan]
mainnet = { key = "${ETHERSCAN_MAINNET_KEY}" }
mainnet2 = { key = "ABCDEFG", chain = "mainnet" }
optimism = { key = "1234576" }
unknownchain = { key = "ABCDEFG", url = "https://<etherscan-api-url-for-that-chain>" }
Solidity's built-in model checker
is an opt-in module that can be enabled via the ModelChecker
object.
See Compiler Input Description settings.modelChecker
and the model checker's options.
The module is available in solc
release binaries for OSX and Linux.
The latter requires the z3 library version [4.8.8, 4.8.14] to be installed
in the system (SO version 4.8).
Similarly to the optimizer settings above, the model_checker
settings must be
prefixed with the profile they correspond to: [profile.default.model_checker]
belongs
to the [profile.default]
profile.
toml
[profile.default.model_checker]
contracts = { 'src/Contract.sol' = [ 'Contract' ] }
engine = 'chc'
timeout = 10000
targets = [ 'assert' ]
The fields above are recommended when using the model checker.
Setting which contract should be verified is extremely important, otherwise all
available contracts will be verified which can consume a lot of time.
The recommended engine is chc
, but bmc
and all
(runs both) are also
accepted.
It is also important to set a proper timeout (given in milliseconds), since the
default time given to the underlying solvers may not be enough.
If no verification targets are given, only assertions will be checked.
The model checker will run when forge build
is invoked, and will show
findings as warnings if any.
Foundry's tools read all environment variable names prefixed with FOUNDRY_
using the string after the _
as the name
of a configuration value as the value of the parameter as the value itself. But the
corresponding dapptools config vars are also
supported, this means that FOUNDRY_SRC
and DAPP_SRC
are equivalent.
Some exceptions to the above are explicitly ignored due to security concerns.
Environment variables take precedence over values in foundry.toml
. Values are parsed as loose form of TOML syntax.
Consider the following examples: