Foundry

Installation

(For Linux and MacOS Users)

Install foundryup:

curl -L https://foundry.paradigm.xyz | bash

This will download foundryup. Then install Foundry by running:

foundryup

Basic Commands

To start a new project with Foundry:

forge init hello_foundry

Compile Solidity code:

forge build

Run Solidity tests:

forge test -vvvv 

Install Dependencies

forge install transmissions11/solmate
forge install openzeppelin/openzeppelin-contracts

Generate remappings for installed libraries

forge remappings > remappings.txt

Update Dependencies

forge update lib/<dependency-name>

Testing

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.16;

import "forge-std/Test.sol";
import "../src/SampleContract.sol";
import "forge-std/console.sol";

// vm deployer address: 0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84

abstract contract StateZero is Test {
    SampleContract internal sampleContract; 
    address alice;
    address bob;
    
    function setUp() public virtual {
        sampleContract = new SampleContract();
        alice = address(0x1);
        bob = address(0x2);

        vm.label(alice, "alice");
        vm.label(bob, "bob");
    }
} 

contract StateZeroTest is StateZero {
    function testChangeStateOne() public {} 
    
    function testChangStateOneReverts() public {
         vm.expectRevert(bytes("revert message"));
         // call function that is intended to revert here 
    }
    
    function testChangStateOneEmitsEvent() public {
         vm.expectEmit(true, true, true, true);
         // 1. emit the event with expected values 
         // 2. call function that is intended to emit the event  
    }
} 

abstract contract StateOne is StateZero {
    function setUp() public virtual override {
        // run initial set-up function from StateZero 
        super.setUp();
        
        // function that changes state from zero to one
        sampleContract.changeStateOne(); 
    }
}

contract StateOneTest is StateOne {
    function testChangeStateTwo() public {} 
    
} 

Deployment

Create .env file in root folder:

PRIVATE_KEY=
ETHERSCAN_KEY=
GOERLI_RPC_URL=

Update foundry.toml:

[rpc_endpoints]
goerli = "${GOERLI_RPC_URL}"

[etherscan]
goerli = { key = "${ETHERSCAN_KEY}" }

SampleContract.s.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.16;

import "../src/SampleContract.sol";
import "forge-std/Script.sol";

contract SampleContractScript is Script {
    function setUp() public {}

    function run() public {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        vm.startBroadcast(deployerPrivateKey);
        
        SampleContract contract = new SampleContract();        
        vm.stopBroadcast();
    }
}

To run the above script:

forge script script/SampleContract.s.sol

To deploy SampleContract to a live testnet, run the following in your terminal:

forge script script/SampleContract.s.sol:SampleContractScript --rpc-url $GOERLI_RPC_URL --broadcast \

Verification

To verify an existing contract:

forge verify-contract --chain-id 5 --num-of-optimizations 1000000 --watch \
--compiler-version v0.8.16+commit.fc410830 <the_contract_address> \
src/SampleContract.sol:SampleContract <your_etherscan_api_key>

Check verification status:

forge verify-check --chain-id 5 <GUID> <your_etherscan_api_key>

References:

https://book.getfoundry.sh/tutorials/solidity-scripting#deploying-our-contract

Last updated