Skip to content

Conversation

@0xrusowsky
Copy link
Contributor

@0xrusowsky 0xrusowsky commented Oct 23, 2025

Motivation

closes foundry-rs/foundry#9840

requires foundry-rs/foundry#12150, which introduces introduced getProfile() cheatcodes that provide profile metadata (artifacts path and EVM version) to enable multi-chain deployments with different EVM versions in a single script.

this PR completes the multi-EVM support story by refactoring the Config abstract to leverage these new cheatcodes, providing users with an ergonomic and safe multi-chain scripting experience.

Solution

refactor the Config abstract to support multi-EVM, multi-chain scripts with profile-aware artifact loading:

  • each unique evm version gets its own StdConfig instance deployed from the corresponding profile's artifact directory. Multiple chains sharing the same EVM version reuse the same instance.
  • selectFork() handles both fork selection and EVM version switching in one call.
  • the deployCode() methods automatically locate and deploy contracts from the correct profile artifacts based on the active evm version of the active chain.
  • the new ConfigView struct (via configOf(chainId)) provides a clea API for reading/writing config vars without repeating the chain id.

Safety Guards

this impl includes several safety mechanisms to prevent common multi-chain deployment errors:

  • profile artifacts are validated before deployment to catch missing or misconfigured profiles early
    error ProfileArtifactsNotFound(string profileName, string expectedPath);
  • loadConfig() reverts if multiple chains are detected, forcing explicit use of loadConfigAndForks() for multi-chain setups
    error MultiChainConfig(uint256 numChains);
  • fork validation:
    • isCached modifier ensures chain IDs are loaded before use, preventing operations on uninitialized forks
    • isActive modifier on deployCode() ensures deployments only occur on the active fork, preventing wrong-chain deployments
    error ForkNotLoaded(uint256 chainId);
    error ForkNotActive(uint256 chainId);

API and example usage

// Load configuration for a single chain (replaces _loadConfig)
function loadConfig(string memory filePath, bool writeToFile) internal;

// Load configuration and create forks for multiple chains with different EVM versions
function loadConfigAndForks(string memory filePath, bool writeToFile) internal;

// Select fork and set the corresponding EVM version
function selectFork(uint256 chainId) internal;

// Deploy contracts from profile-specific artifacts
function deployCode(uint256 chainId, string memory contractFile, string memory contractName)
    internal returns (address);
// ... (multiple overloads supporting constructorArgs, value, salt, CREATE2, etc.)

// Ergonomic config access
function configOf(uint256 chainId) internal view returns (ConfigView memory);
// instead of: config.get(chainId, "my_key").toUint256()
// use: configOf(chainId).get("my_key").toUint256()

uint256 value = configOf(1).get("my_key").toUint256();
configOf(1).set("my_key", 42);
contract MultiChainScript is Script, Config {
    function run() public {
        // Load config and create forks for all chains
        loadConfigAndForks("config.toml", false);

        // Deploy to Mainnet
        selectFork(1);
        address counter = deployCode(1, "Counter.sol", "Counter");

        // Deploy to Optimism
        selectFork(10);
        address counterOP = deployCode(56, "Counter.sol", "Counter");

        // Each deployment uses the correct bytecode for its EVM version
    }
}
# foundry.toml
[profile.default]
evm_version = "cancun"
out = "out"

[profile.shanghai]
evm_version = "shanghai"
out = "out-shanghai"
# config.toml
[1]
rpc_url = "..."
profile = "default"  # Uses cancun

[10]
rpc_url = "..."
profile = "shanghai"  # Uses shanghai

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

@0xrusowsky 0xrusowsky force-pushed the rusowsky/multi-evm-support branch from edfcde7 to adefbf8 Compare October 27, 2025 08:20
@0xrusowsky 0xrusowsky self-assigned this Oct 27, 2025
@0xrusowsky 0xrusowsky moved this to Ready For Review in Foundry Oct 27, 2025
@0xrusowsky 0xrusowsky marked this pull request as ready for review October 27, 2025 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready For Review

Development

Successfully merging this pull request may close these issues.

feat(config): add chain dependent solc config and support in multichain scripts

2 participants