Import Resolution
Troubleshoot and configure import path resolution. Import resolution is the most common source of scan failures. This guide helps you ensure BlockSecOps can...
Import Resolution
Troubleshoot and configure import path resolution.
Overview
Import resolution is the most common source of scan failures. This guide helps you ensure BlockSecOps can find all your dependencies.
How Import Resolution Works
When BlockSecOps encounters an import:
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
It looks for the file in this order:
- Remappings (Foundry) - Check
remappings.txtorfoundry.toml - Node modules (Hardhat) - Check
node_modules/ - Lib directory (Foundry) - Check
lib/ - Relative path - Check relative to current file
Common Import Patterns
OpenZeppelin
// Hardhat (npm)
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// Foundry (git submodule)
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// Requires remapping: @openzeppelin/=lib/openzeppelin-contracts/
Chainlink
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
Uniswap
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
Relative Imports
// Same directory
import "./IToken.sol";
// Parent directory
import "../libraries/Math.sol";
// Deeper nesting
import "../../interfaces/IVault.sol";
Foundry Resolution
Remappings
Create remappings.txt in project root:
@openzeppelin/=lib/openzeppelin-contracts/
forge-std/=lib/forge-std/src/
@chainlink/=lib/chainlink/contracts/
solmate/=lib/solmate/src/
Or in foundry.toml:
[profile.default]
remappings = [
"@openzeppelin/=lib/openzeppelin-contracts/",
"forge-std/=lib/forge-std/src/",
"@chainlink/=lib/chainlink/contracts/"
]
Generate Remappings
# Auto-generate from installed libraries
forge remappings > remappings.txt
Verify Remappings
# Check current remappings
forge remappings
# Test compilation
forge build
Hardhat Resolution
node_modules Structure
node_modules/
├── @openzeppelin/
│ └── contracts/
│ └── token/
│ └── ERC20/
│ └── ERC20.sol
└── @chainlink/
└── contracts/
└── src/
└── v0.8/
Package.json Dependencies
{
"dependencies": {
"@openzeppelin/contracts": "^4.9.0",
"@chainlink/contracts": "^0.6.0"
}
}
Include in Upload
You must include node_modules in your upload:
zip -r project.zip \
contracts/ \
node_modules/ \
hardhat.config.js
Or specific packages only:
zip -r project.zip \
contracts/ \
node_modules/@openzeppelin/ \
node_modules/@chainlink/ \
hardhat.config.js
Troubleshooting
"File not found" Error
Error: Source "@openzeppelin/contracts/token/ERC20/ERC20.sol" not found
Solutions:
Check the package is installed:
# Foundry ls lib/openzeppelin-contracts/contracts/token/ERC20/ # Hardhat ls node_modules/@openzeppelin/contracts/token/ERC20/Verify remapping exists (Foundry):
grep "@openzeppelin" remappings.txtInclude in upload:
# Make sure lib/ or node_modules/ is in the zip unzip -l project.zip | grep openzeppelin
"Multiple remappings" Error
Error: Multiple remappings match for "@openzeppelin"
Solution: Check for duplicate or conflicting remappings:
# Look for duplicates
cat remappings.txt | sort | uniq -d
Import Path Mismatch
Import doesn't match directory structure:
// Your import
import "@openzeppelin/contracts/ERC20.sol";
// Actual location
// node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol
Solution: Use correct path:
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
Common Package Paths
OpenZeppelin Contracts
// Token contracts
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
// Access control
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
// Security
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
// Utilities
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
Chainlink
// Price feeds
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
// VRF
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
// Automation
import "@chainlink/contracts/src/v0.8/automation/AutomationCompatible.sol";
Uniswap
// V3 Core
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol";
// V3 Periphery
import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";
Complex Remapping Scenarios
Versioned Dependencies
Multiple versions of same library:
lib/
├── openzeppelin-contracts-v4/
└── openzeppelin-contracts-v5/
Remappings:
@openzeppelin-v4/=lib/openzeppelin-contracts-v4/
@openzeppelin-v5/=lib/openzeppelin-contracts-v5/
Nested Dependencies
When a dependency has its own dependencies:
lib/
├── my-library/
│ └── lib/
│ └── openzeppelin-contracts/
Add nested remapping:
my-library/=lib/my-library/src/
@openzeppelin/=lib/my-library/lib/openzeppelin-contracts/
Overriding Package Location
Custom location for a package:
vendor/
└── custom-openzeppelin/
Remapping:
@openzeppelin/=vendor/custom-openzeppelin/
Diagnostic Commands
Foundry
# List all remappings
forge remappings
# Verify build works
forge build --force
# Show import tree
forge tree
Hardhat
# Compile to verify imports
npx hardhat compile
# List installed packages
npm ls
# Check specific package
npm ls @openzeppelin/contracts
Best Practices
1. Always Test Compilation First
# Foundry
forge build
# Hardhat
npx hardhat compile
If local compilation fails, the scan will also fail.
2. Include All Dependencies
Don't exclude needed dependencies:
# Good: Include all libs
zip -r project.zip src/ lib/ foundry.toml
# Bad: Missing dependencies
zip -r project.zip src/ foundry.toml
3. Use Consistent Import Style
Pick one style per project:
// Consistent: Always use @ prefix
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol";
// Avoid mixing styles
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "lib/chainlink/contracts/src/v0.8/VRFConsumerBase.sol"; // Inconsistent
4. Generate Remappings Automatically
# Foundry: Let forge detect remappings
forge remappings > remappings.txt
Next Steps
- Foundry Guide - Foundry-specific setup
- Hardhat Guide - Hardhat-specific setup
- Troubleshooting - Upload problems