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

Last updated: January 14, 2026

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:

  1. Remappings (Foundry) - Check remappings.txt or foundry.toml
  2. Node modules (Hardhat) - Check node_modules/
  3. Lib directory (Foundry) - Check lib/
  4. 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:

  1. Check the package is installed:

    # Foundry
    ls lib/openzeppelin-contracts/contracts/token/ERC20/
    
    # Hardhat
    ls node_modules/@openzeppelin/contracts/token/ERC20/
    
  2. Verify remapping exists (Foundry):

    grep "@openzeppelin" remappings.txt
    
  3. Include 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