Description
Slither fails with an AssertionError when analyzing Solidity code that imports files using import aliasing (specifically the Chainlink KeeperCompatibleInterface.sol pattern).
Environment
- Slither version: 0.11.5
- Python version: 3.11
- Operating system: macOS (Darwin 22.3.0)
- Solidity compiler: 0.8.34
- Framework: Foundry
Steps to Reproduce
- Create a Foundry project with the following structure:
foundry.toml:
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
remappings.txt:
@chainlink/=lib/chainlink-evm/
src/KeepersCounter.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@chainlink/contracts/src/v0.8/automation/interfaces/KeeperCompatibleInterface.sol";
contract KeepersCounter is KeeperCompatibleInterface {
uint256 public counter;
uint256 public immutable interval;
uint256 public lastTimeStamp;
constructor(uint256 updateInterval) {
interval = updateInterval;
lastTimeStamp = block.timestamp;
counter = 0;
}
function checkUpkeep(bytes calldata) external view override returns (bool upkeepNeeded, bytes memory) {
upkeepNeeded = (block.timestamp - lastTimeStamp) > interval;
}
function performUpkeep(bytes calldata) external override {
if ((block.timestamp - lastTimeStamp) > interval) {
lastTimeStamp = block.timestamp;
counter = counter + 1;
}
}
}
lib/chainlink-evm/contracts/src/v0.8/automation/interfaces/KeeperCompatibleInterface.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {AutomationCompatibleInterface as KeeperCompatibleInterface} from "./AutomationCompatibleInterface.sol";
lib/chainlink-evm/contracts/src/v0.8/automation/interfaces/AutomationCompatibleInterface.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface AutomationCompatibleInterface {
function checkUpkeep(bytes calldata checkData) external returns (bool upkeepNeeded, bytes memory performData);
function performUpkeep(bytes calldata performData) external;
}
- Run: forge build (this succeeds)
- Run: slither .
Expected Behavior
Slither should successfully analyze the contract.
Actual Behavior
Slither fails with:
Traceback (most recent call last):
File "/opt/homebrew/bin/slither", line 8, in
sys.exit(main())
^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/slither/main.py", line 760, in main
main_impl(all_detector_classes=detectors, all_printer_classes=printers)
File "/opt/homebrew/lib/python3.11/site-packages/slither/main.py", line 865, in main_impl
) = process_all(filename, args, detector_classes, printer_classes)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/slither/main.py", line 106, in process_all
) = process_single(compilation, args, detector_classes, printer_classes)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/slither/main.py", line 79, in process_single
slither = Slither(target, ast_format=ast, **vars(args))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/slither/slither.py", line 197, in init
self._init_parsing_and_analyses(kwargs.get("skip_analyze", False))
File "/opt/homebrew/lib/python3.11/site-packages/slither/slither.py", line 206, in _init_parsing_and_analyses
raise e
File "/opt/homebrew/lib/python3.11/site-packages/slither/slither.py", line 202, in _init_parsing_and_analyses
parser.parse_contracts()
File "/opt/homebrew/lib/python3.11/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 502, in parse_contracts
target = resolve_remapping_and_renaming(contract_parser, i)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 488, in resolve_remapping_and_renaming
assert target, f"Contract {contract_name} not found"
AssertionError: Contract KeeperCompatibleInterface not found
Trying slither with --ignore-compile and running forge build --ast before hand throws these errors:
File "/opt/homebrew/lib/python3.11/site-packages/crytic_compile/crytic_compile.py", line 211, in __init__
self._compile(**kwargs)
File "/opt/homebrew/lib/python3.11/site-packages/crytic_compile/crytic_compile.py", line 633, in _compile
self._platform.compile(self, **kwargs)
File "/opt/homebrew/lib/python3.11/site-packages/crytic_compile/platform/foundry.py", line 102, in compile
hardhat_like_parsing(
File "/opt/homebrew/lib/python3.11/site-packages/crytic_compile/platform/hardhat.py", line 72, in hardhat_like_parsing
targets_json = loaded_json["output"]
~~~~~~~~~~~^^^^^^^^^^
KeyError: 'output'
Root Cause
The issue occurs in slither_compilation_unit_solc.py:488 in the resolve_remapping_and_renaming function. The file KeeperCompatibleInterface.sol uses the pattern:
import {AutomationCompatibleInterface as KeeperCompatibleInterface} from "./AutomationCompatibleInterface.sol";
This creates an alias/re-export where KeeperCompatibleInterface is not actually defined as a contract in the file, but is aliased from AutomationCompatibleInterface. Slither's contract resolver cannot find
KeeperCompatibleInterface as an actual contract definition and fails.
Additional Context
Description
Slither fails with an
AssertionErrorwhen analyzing Solidity code that imports files using import aliasing (specifically the ChainlinkKeeperCompatibleInterface.solpattern).Environment
Steps to Reproduce
foundry.toml:
remappings.txt:
src/KeepersCounter.sol:
lib/chainlink-evm/contracts/src/v0.8/automation/interfaces/KeeperCompatibleInterface.sol:
Expected Behavior
Slither should successfully analyze the contract.
Actual Behavior
Slither fails with:
Traceback (most recent call last):
File "/opt/homebrew/bin/slither", line 8, in
sys.exit(main())
^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/slither/main.py", line 760, in main
main_impl(all_detector_classes=detectors, all_printer_classes=printers)
File "/opt/homebrew/lib/python3.11/site-packages/slither/main.py", line 865, in main_impl
) = process_all(filename, args, detector_classes, printer_classes)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/slither/main.py", line 106, in process_all
) = process_single(compilation, args, detector_classes, printer_classes)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/slither/main.py", line 79, in process_single
slither = Slither(target, ast_format=ast, **vars(args))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/slither/slither.py", line 197, in init
self._init_parsing_and_analyses(kwargs.get("skip_analyze", False))
File "/opt/homebrew/lib/python3.11/site-packages/slither/slither.py", line 206, in _init_parsing_and_analyses
raise e
File "/opt/homebrew/lib/python3.11/site-packages/slither/slither.py", line 202, in _init_parsing_and_analyses
parser.parse_contracts()
File "/opt/homebrew/lib/python3.11/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 502, in parse_contracts
target = resolve_remapping_and_renaming(contract_parser, i)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 488, in resolve_remapping_and_renaming
assert target, f"Contract {contract_name} not found"
AssertionError: Contract KeeperCompatibleInterface not found
Trying slither with
--ignore-compileand runningforge build --astbefore hand throws these errors:Root Cause
The issue occurs in slither_compilation_unit_solc.py:488 in the resolve_remapping_and_renaming function. The file KeeperCompatibleInterface.sol uses the pattern:
import {AutomationCompatibleInterface as KeeperCompatibleInterface} from "./AutomationCompatibleInterface.sol";
This creates an alias/re-export where KeeperCompatibleInterface is not actually defined as a contract in the file, but is aliased from AutomationCompatibleInterface. Slither's contract resolver cannot find
KeeperCompatibleInterface as an actual contract definition and fails.
Additional Context