Summary
When using crytic-compile with Foundry projects that have subdirectories with their own foundry.toml using relative paths, the sourceList in exported combined_solc.json becomes misaligned with the source IDs in bytecode source maps. This causes Echidna coverage reports and Slither analysis to attribute results to incorrect source files.
Minimal Reproduction
https://github.com/Mike4751/crytic-compile-sourcelist-bug
git clone https://github.com/Mike4751/crytic-compile-sourcelist-bug
cd crytic-compile-sourcelist-bug/test/fuzzing
forge build --build-info
crytic-compile . --export-format solc --export-dir crytic-export --foundry-ignore-compile
python3 ../../scripts/verify_sourcelist.py
Result with unpatched crytic-compile:
sourceList[0]: expected 'Main.sol' but got 'Base.sol' - MISMATCH!
sourceList[1]: expected 'Base.sol' but got 'IPrice.sol' - MISMATCH!
...
BUG DETECTED: 8 mismatches out of 8 sources
Environment
- crytic-compile: 0.3.11
- Foundry/Forge: 0.3.0
- Python: 3.14
- OS: macOS
When It Occurs
The bug manifests when:
- A subdirectory has its own
foundry.toml with relative paths (e.g., libs = ["../../lib", "../../node_modules"])
- The same files are referenced with different path representations (absolute vs relative)
- JSON key order in build-info differs from source ID order
Root Cause
In crytic_compile/platform/hardhat.py, the hardhat_like_parsing() function iterates over targets_json["sources"] in JSON key order rather than sorted by the id field:
# Current code
for path, info in targets_json["sources"].items(): # Not sorted by ID!
source_unit = compilation_unit.create_source_unit(path)
When JSON key order differs from ID order, the resulting sourceList indices don't match source IDs.
Backwards Compatibility
The fix has been tested on both complex and simple project structures:
| Environment |
Structure |
Unpatched |
Patched |
| Simple (A→B→C) |
Standard |
0 mismatches |
0 mismatches ✓ |
| Relative paths |
Complex |
8 mismatches |
0 mismatches ✓ |
| Large project (~470 files) |
Complex |
470 mismatches |
0 mismatches ✓ |
The fix resolves the bug without breaking existing projects.
Proposed Fix
I have a working fix ready: https://github.com/Mike4751/crytic-compile/tree/fix-foundry-sourcelist-order
Will submit PR shortly.
Summary
When using crytic-compile with Foundry projects that have subdirectories with their own
foundry.tomlusing relative paths, thesourceListin exportedcombined_solc.jsonbecomes misaligned with the source IDs in bytecode source maps. This causes Echidna coverage reports and Slither analysis to attribute results to incorrect source files.Minimal Reproduction
https://github.com/Mike4751/crytic-compile-sourcelist-bug
Result with unpatched crytic-compile:
Environment
When It Occurs
The bug manifests when:
foundry.tomlwith relative paths (e.g.,libs = ["../../lib", "../../node_modules"])Root Cause
In
crytic_compile/platform/hardhat.py, thehardhat_like_parsing()function iterates overtargets_json["sources"]in JSON key order rather than sorted by theidfield:When JSON key order differs from ID order, the resulting
sourceListindices don't match source IDs.Backwards Compatibility
The fix has been tested on both complex and simple project structures:
The fix resolves the bug without breaking existing projects.
Proposed Fix
I have a working fix ready: https://github.com/Mike4751/crytic-compile/tree/fix-foundry-sourcelist-order
Will submit PR shortly.