Skip to main content

Foundry

Fast build and testing of Solidity Smart Contracts in Rust.

Github Full Course

Env Variables

NEVER use a .env file

tip

Don't use VS Code but direct in terminal

cast wallet import defaultKey --interactive

Remove all history with any keys.

history -c
rm .bash_history

Resources

Testing

https://github.com/foundry-rs/forge-std
note

Tests are deployed to 0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84. If you deploy a contract within your test, then 0xb4c...7e84 will be its deployer. If the contract deployed within a test gives special permissions to its deployer, such as Ownable.sol's onlyOwner modifier, then the test contract 0xb4c...7e84 will have those permissions.

tip

Use the getCode cheatcode to deploy contracts with incompatible Solidity versions.

Cheatcodes - IMPORTANT

Most of the time, simply testing your smart contracts outputs isn't enough. To manipulate the state of the blockchain, as well as test for specific reverts and events, Foundry is shipped with a set of cheatcodes.

Cheatcodes allow you to change the block number, your identity, and more. They are invoked by calling specific functions on a specially designated address: 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.

You can access cheatcodes easily via the vm instance available in Forge Standard Library's Test contract. Forge Standard Library is explained in greater detail in the following section.

Forge Standard Library

Forge Standard Library (Forge Std for short) is a collection of helpful contracts that make writing tests easier, faster, and more user-friendly.

Using Forge Std is the preferred way of writing tests with Foundry.

It provides all the essential functionality you need to get started writing tests:

Vm.sol: Up-to-date cheatcodes interface console.sol and console2.sol: Hardhat-style logging functionality Test.sol: A superset of DSTest containing standard libraries, a cheatcodes instance (vm), and Hardhat console Simply import Test.sol and inherit from Test in your test contract:

Forking mode

Forking is especially useful when you need to interact with existing contracts, and you may choose to do integration testing this way, as if you were on an actual network.

Advanced Testing

One the main attractions of using Foundry.

Fuzz Testing - IMPORTANT

Provides Property-based testing which enables testing general behaviors as opposed to isolated scenarios.

Can automatically run many variants.

note

Fuzz tests are summarized differently to unit tests

  • runs refers to the amount of scenarios the fuzzer tested. By default, the fuzzer will generate 256 scenarios, however, this can be configured using the FOUNDRY_FUZZ_RUNS environment variable.
  • μ (Greek letter mu) is the mean gas used across all fuzz runs
  • ~ (tilde) is the median gas used across all fuzz runs

Differential Testing

Real life uses of uses of this type of testing include:

  • Differential Testing Merkle Tree Implementations
  • Comparing upgraded implementations to their predecessors
  • Testing code against known reference implementations
  • Confirming compatibility with third party tools and dependencies

Deploying

Forge can deploy smart contracts to a given network with the forge create command.

task

Establish best way to save contract into NX lib

Verifying is not Terrifying

Verify a contract on Etherscan with the forge verify-contract command.

You must provide:

  • compiler version used for build, with 8 hex digits from the commit version prefix (the commit will usually not be a nightly build)
  • the contract address
  • the path to the contract path:contractname
  • your Etherscan API key (env: ETHERSCAN_API_KEY).

Moreover, you may need to provide:

the constructor arguments in the ABI-encoded format, if there are any the number of optimizations, if the Solidity optimizer was activated the chain ID, if the contract is not on Ethereum Mainnet

Debugger - Handy

The debugger is accessible on forge run and on forge test.

Cast - Handy

Cast is Foundry's 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!

Cast Command Reference

VS Code

Recommended settings

tip

To make the extension play nice with Foundry, you will need to place your remappings in remappings.txt

Integrate Hardhat

Hardhat has more features / better DX.

For automatic Hardhat support you can also pass the --hh flag, which sets the following flags: --lib-paths node_modules --contracts contracts

tip

passing the --hh flag, sets: --lib-paths node_modules --contracts contracts

Tutorials

Solmate NFT

https://github.com/FredCoen/nft-tutorial

export RPC_URL=<Your RPC endpoint>
export PRIVATE_KEY=<Your wallets private key>
forge create NFT --rpc-url=$RPC_URL --private-key=$PRIVATE_KEY --constructor-args <name> <symbol>