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
@sakulstra
Copy link

@0xrusowsky What happened to this pr? Would love to see this move forward.
Again facing quite big issues with the current inability to do proper multichain scripts.

@zerosnacks
Copy link
Member

Shifting priorities unfortunately, this is still something we want to do but just haven't been able to get around to it.

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

4 participants