Skip to content

feat(forge): specify compilation profile in vm.getCode#13191

Merged
grandizzy merged 20 commits into
masterfrom
feat/getcode-profile-support
Jun 10, 2026
Merged

feat(forge): specify compilation profile in vm.getCode#13191
grandizzy merged 20 commits into
masterfrom
feat/getcode-profile-support

Conversation

@gakonst

@gakonst gakonst commented Jan 23, 2026

Copy link
Copy Markdown
Member

Summary

Add support for specifying a compilation profile in artifact path parsing for vm.getCode, vm.getDeployedCode, and vm.deployCode cheatcodes.

Motivation

This allows users with multiple compilation profiles in foundry.toml to select specific artifact versions. For example, if you have:

[profile.v1]
optimizer = false

[profile.v2]
optimizer = true
optimizer_runs = 1000

You can now use:

  • vm.getCode("Contract.sol:v1")
  • vm.getCode("Contract.sol:v2")
  • vm.getCode("Contract.sol:ContractName:optimized")

Implementation

The feature distinguishes between semver versions (like 0.8.23) and profile names (like v1, optimized) by:

  1. First checking if the suffix contains a dot (0.8.23)
  2. Then attempting to parse as a semver version
  3. If neither, treating it as a profile name

The profile filter is applied during artifact lookup to select the correct compiled artifact.

Supported Formats

  • path/to/contract.sol:ContractName:profile
  • path/to/contract.sol:profile
  • ContractName:profile

Closes #12821

Add support for specifying a compilation profile in artifact path parsing for
vm.getCode, vm.getDeployedCode, and vm.deployCode cheatcodes.

This allows users with multiple compilation profiles in foundry.toml to select
specific artifact versions. For example:
- `vm.getCode("Contract.sol:v1")`
- `vm.getCode("Contract.sol:ContractName:optimized")`

The feature distinguishes between semver versions (like 0.8.23) and profile
names (like v1, optimized) by attempting to parse the suffix as a version
first.

Closes #12821
gakonst and others added 12 commits January 23, 2026 08:51
- Combine duplicate if branches for version detection
- Remove needless ref borrow in profile comparison
- Refactor parsing logic into reusable parse_artifact_path function
- Add 11 unit tests covering all artifact path formats:
  - file only, file+contract, file+contract+version, file+contract+profile
  - file+version, contract only, contract+version, contract+profile
  - Various profile name patterns (v1, v2, paris, optimized, etc.)
- Add Solidity integration test for profile-based getCode
…file

Add comprehensive tests showing that vm.getCode correctly retrieves
different bytecode for different compilation profiles:

- Create testdata/multi-profile/ with Counter contract compiled using
  'default', 'optimized' (10000 runs), and 'unoptimized' (no optimizer) profiles
- Add tests verifying:
  - Different profiles produce different bytecode
  - vm.getCode('Contract:profile') works correctly
  - vm.getCode('path/to/Contract.sol:Contract:profile') works correctly
  - vm.deployCode with profile works
  - vm.getDeployedCode with profile works
  - Non-existent profiles fail appropriately
- Remove invalid 'profiles' field from compilation_restrictions
- Use assertTrue instead of assertNotEq (not available in DSTest)
- Simplify tests to verify profile parsing works with default profile
- Test that non-existent profiles fail appropriately
The multi-version tests use a contract named Counter, causing conflicts
when my multi-profile tests also used Counter.
The additional_compiler_profiles cause all contracts to be compiled with
multiple profiles, which breaks the existing multi-version tests that
rely on version-based disambiguation.

The unit tests for artifact path parsing adequately test the profile
feature at the parsing level. End-to-end testing of profile-based
selection requires a more complex test setup.
Add test demonstrating vm.getCode with profile selection using the existing
paris compilation profile. Tests:
- vm.getCode("path:Contract:paris") format
- vm.getCode("Contract:paris") format
- vm.getDeployedCode and vm.deployCode with profile
- Error when using non-existent profile
- Error when requesting wrong profile for a contract

This test uses the existing paris profile which is already scoped to
paris/** files, avoiding conflicts with other multi-version tests.

Amp-Thread-ID: https://ampcode.com/threads/T-019bea01-185e-7079-990e-f33585663be2
Co-authored-by: Amp <amp@ampcode.com>
Fix the artifact disambiguation logic to not filter by running_artifact's
version/profile when user has explicitly specified those criteria. This
allows adding global additional_compiler_profiles without breaking
existing tests.

Changes:
- Fix disambiguation: only use running_artifact's version for filtering
  when user did NOT specify a version in the artifact path
- Same fix for profile filtering
- Add 'optimized' and 'unoptimized' profiles to testdata/foundry.toml
- Add GetCodeMultiProfile.t.sol demonstrating that different profiles
  produce different bytecode and can be selected via vm.getCode

The test verifies:
- vm.getCode("Contract:optimized") returns different bytecode than
  vm.getCode("Contract:unoptimized")
- vm.deployCode and vm.getDeployedCode work with profile selection
- Non-existent profiles fail appropriately

Amp-Thread-ID: https://ampcode.com/threads/T-019bea01-185e-7079-990e-f33585663be2
Co-authored-by: Amp <amp@ampcode.com>
assertNotEq doesn't have an overload for bytes32, use require with != instead
@zerosnacks zerosnacks closed this Jan 23, 2026
@github-project-automation github-project-automation Bot moved this to Done in Foundry Jan 23, 2026
@zerosnacks zerosnacks reopened this Jan 23, 2026
gakonst and others added 2 commits January 23, 2026 11:34
Changes:
- Remove GetCodeMultiProfile.t.sol test that expected artifacts compiled
  with 'optimized' and 'unoptimized' profiles without corresponding
  compilation_restrictions
- Remove unused 'optimized' and 'unoptimized' profiles from foundry.toml
  (the paris profile remains as it has proper restrictions)
- Update multi-version tests to use full paths (multi-version/Counter.sol)
  to avoid ambiguity with other Counter contracts in testdata that would
  cause 'multiple matching artifacts found' error

Amp-Thread-ID: https://ampcode.com/threads/T-019bea8a-abde-7172-9b50-efb0569a8222
Co-authored-by: Amp <amp@ampcode.com>
@zerosnacks zerosnacks marked this pull request as ready for review January 23, 2026 12:29
@decofe decofe requested a review from mablr as a code owner June 10, 2026 12:27
Comment thread crates/cheatcodes/src/fs.rs
@grandizzy grandizzy requested a review from mablr June 10, 2026 14:44
@mablr mablr force-pushed the feat/getcode-profile-support branch from 6bd1467 to b06d8a7 Compare June 10, 2026 15:17
@grandizzy grandizzy enabled auto-merge (squash) June 10, 2026 17:06
@grandizzy grandizzy merged commit c419100 into master Jun 10, 2026
19 checks passed
@grandizzy grandizzy deleted the feat/getcode-profile-support branch June 10, 2026 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

feat(forge): specify compilation profile in vm.getCode

5 participants