crytic / crytic/slither

AssertionError in resolve_remapping_and_renaming when analyzing contract with import aliasing

Open
#3,019 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
6.4k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

## 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

1. 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;
}
```

2. Run: forge build (this succeeds)
3. 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

- The same code compiles successfully with forge build
- This is a legitimate Solidity pattern used in production (Chainlink contracts)
- Flags tried without success: --foundry-compile-all, --foundry-ignore-compile, --foundry-out-directory
- Related to issue #1452 about import aliasing support

Contributor guide

Open the contributing guide

Research direction

Start in slither_compilation_unit_solc.py at resolve_remapping_and_renaming around line 488, using the provided Foundry project and `slither .` reproduction. Trace the import-alias case and verify that analysis completes successfully for KeeperCompatibleInterface without the assertion; check related issue #1452 for context.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, solidity
Domain
compilers, devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.