Description
Aderyn 0.6.8 panics with content not found at aderyn_driver/src/compile.rs:78 when analyzing projects that use parent-relative remappings (e.g., ../dependencies/...) and the remapped library contains internal relative imports (e.g., ./IERC20.sol, ../../utils/Context.sol).
This is a common pattern in Foundry monorepos managed by Soldeer, where dependencies are installed at the workspace root and subprojects reference them via ../dependencies/.
Root Cause
At compile.rs:78:
let content = sources.get(&source_path).expect("content not found");
The sources map (solc input) and sources_ast map (solc output) use different path representations when ../ is involved. When solc resolves a remapping like @openzeppelin/contracts/=../dependencies/@openzeppelin-contracts-5.5.0/ and then follows an internal relative import (e.g., import {Context} from "../../utils/Context.sol"), the resulting canonical path in sources_ast doesn't match the key registered in sources.
Reproduction
I verified the following 4 test cases to isolate the exact trigger:
| # |
Remapping path |
Library internal imports |
Result |
| 1 |
../dependencies/ (parent) |
Yes (OpenZeppelin) |
CRASH |
| 2 |
../dependencies/ (parent) |
No (Solady CREATE3) |
OK |
| 3 |
dependencies/ (local) |
Yes (OpenZeppelin) |
OK |
| 4 |
../dependencies/ (parent) |
Yes (Solady OwnableRoles) |
CRASH |
The crash requires BOTH conditions: parent-relative path (../) in remapping AND internal relative imports within the library. Either condition alone works fine.
Minimal reproduction (Test case #1 — CRASH)
repro/
├── dependencies/
│ └── @openzeppelin-contracts-5.5.0/ # OpenZeppelin v5.5.0+
└── subproject/
├── foundry.toml
└── src/
└── Token.sol
subproject/src/Token.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.34;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Token is ERC20 {
constructor() ERC20("Test", "TST") {
_mint(msg.sender, 1_000_000e18);
}
}
subproject/foundry.toml:
[profile.default]
src = "src"
libs = ["lib", "../dependencies"]
auto_detect_remappings = false
solc_version = "0.8.34"
evm_version = "osaka"
remappings = [
"@openzeppelin/contracts/=../dependencies/@openzeppelin-contracts-5.5.0/",
"forge-std/=../dependencies/forge-std-1.14.0/src/",
]
cd subproject
forge build # succeeds
aderyn . # CRASH: compile.rs:78 "content not found"
Control case #2 — OK (no internal imports)
Same ../dependencies/ remapping but with Solady's CREATE3.sol which has zero imports:
import {CREATE3} from "solady/utils/CREATE3.sol";
remappings = ["solady/=../dependencies/solady-0.1.19/src/"]
→ Works fine — no internal imports means solc doesn't resolve any additional relative paths.
Control case #3 — OK (local path)
Same OpenZeppelin import but with dependencies/ in the same directory (no ../):
remappings = ["@openzeppelin/contracts/=dependencies/@openzeppelin-contracts-5.5.0/"]
→ Works fine — without ../, solc's path resolution stays within the project root.
Control case #4 — CRASH (Solady with internal imports)
Solady's OwnableRoles.sol (which imports ./Ownable.sol) with ../dependencies/:
import {OwnableRoles} from "solady/auth/OwnableRoles.sol";
remappings = ["solady/=../dependencies/solady-0.1.19/src/"]
→ CRASH — confirms this is NOT OpenZeppelin-specific. Any library with internal imports triggers it.
Output
Ingesting 1 compiled files [solc : v0.8.34]
error: Fatal compiler bug!
Panic: aderyn_driver/src/compile.rs:78
content not found
Aderyn version: 0.6.8
Note: forge build succeeds for all 4 cases. The issue is only with aderyn's source path resolution.
Environment
- Aderyn version: 0.6.8 (latest as of 2025-04-03, installed via Homebrew)
- Forge version: 1.3.5-stable
- Solc version: 0.8.34
- OS: macOS 26.2 (Apple Silicon, arm64)
- EVM version: osaka (also reproducible with cancun)
Impact
This affects all Foundry monorepos using Soldeer where subprojects reference shared dependencies via ../dependencies/. In our case, 10 out of 11 subprojects failed (all except one that only used self-contained libraries with no internal imports).
Workaround
forge flatten: Inline all dependencies into a single file before running aderyn. This works but loses file-level granularity and introduces false positives from library code.
- Copy dependencies locally: Move
dependencies/ into each subproject so remappings don't need ../.
Suggested Fix
In compile.rs, canonicalize paths before the sources.get(&source_path) lookup — e.g., resolve .. segments via std::fs::canonicalize() or manual path normalization on both the sources HashMap keys and the source_path from sources_ast. This would ensure that subproject/../dependencies/lib/foo.sol and dependencies/lib/foo.sol match as the same key.
Description
Aderyn 0.6.8 panics with
content not foundataderyn_driver/src/compile.rs:78when analyzing projects that use parent-relative remappings (e.g.,../dependencies/...) and the remapped library contains internal relative imports (e.g.,./IERC20.sol,../../utils/Context.sol).This is a common pattern in Foundry monorepos managed by Soldeer, where dependencies are installed at the workspace root and subprojects reference them via
../dependencies/.Root Cause
At
compile.rs:78:The
sourcesmap (solc input) andsources_astmap (solc output) use different path representations when../is involved. When solc resolves a remapping like@openzeppelin/contracts/=../dependencies/@openzeppelin-contracts-5.5.0/and then follows an internal relative import (e.g.,import {Context} from "../../utils/Context.sol"), the resulting canonical path insources_astdoesn't match the key registered insources.Reproduction
I verified the following 4 test cases to isolate the exact trigger:
../dependencies/(parent)../dependencies/(parent)dependencies/(local)../dependencies/(parent)The crash requires BOTH conditions: parent-relative path (
../) in remapping AND internal relative imports within the library. Either condition alone works fine.Minimal reproduction (Test case #1 — CRASH)
subproject/src/Token.sol:subproject/foundry.toml:Control case #2 — OK (no internal imports)
Same
../dependencies/remapping but with Solady'sCREATE3.solwhich has zero imports:→ Works fine — no internal imports means solc doesn't resolve any additional relative paths.
Control case #3 — OK (local path)
Same OpenZeppelin import but with
dependencies/in the same directory (no../):→ Works fine — without
../, solc's path resolution stays within the project root.Control case #4 — CRASH (Solady with internal imports)
Solady's
OwnableRoles.sol(which imports./Ownable.sol) with../dependencies/:→ CRASH — confirms this is NOT OpenZeppelin-specific. Any library with internal imports triggers it.
Output
Note:
forge buildsucceeds for all 4 cases. The issue is only with aderyn's source path resolution.Environment
Impact
This affects all Foundry monorepos using Soldeer where subprojects reference shared dependencies via
../dependencies/. In our case, 10 out of 11 subprojects failed (all except one that only used self-contained libraries with no internal imports).Workaround
forge flatten: Inline all dependencies into a single file before running aderyn. This works but loses file-level granularity and introduces false positives from library code.dependencies/into each subproject so remappings don't need../.Suggested Fix
In
compile.rs, canonicalize paths before thesources.get(&source_path)lookup — e.g., resolve..segments viastd::fs::canonicalize()or manual path normalization on both thesourcesHashMap keys and thesource_pathfromsources_ast. This would ensure thatsubproject/../dependencies/lib/foo.solanddependencies/lib/foo.solmatch as the same key.