Skip to content

address(console) internal library linking error #8404

Description

@kanej

When a Solidity test takes the address of forge-std's console library (i.e. address(console)), solc emits a deploy-time link reference to lib/forge-std/src/console.sol:console. Foundry resolves this by linking console to its console-log address. Hardhat's Solidity test runner instead aborts the entire test run with:

Running Solidity tests

HardhatError: HHE802: Unhandled EDR error while running Solidity tests: wasn't able to find artifact for library 'console' at 'project/lib/forge-std/src/console.sol' when linking 'ConsoleAddrTest' at 'project/test/ConsoleAddr.t.sol'
    at <anonymous> (/tmp/console-linking-minimal-reproduction/node_modules/.pnpm/hardhat@3.9.0/node_modules/hardhat/src/internal/builtin-plugins/solidity-test/runner.ts:104:9)

I believe this will happen whether the console in question is imported from Hardhat or forge-std.

This issue was found will testing a migration of 0x-settler.

Minimal reproduction

contracts/Noop.sol (any trivial contract is fine):

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
contract Noop {}

test/ConsoleAddr.t.sol:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import "forge-std/Test.sol"; // brings in `console`

contract ConsoleAddrTest is Test {
    function test_consoleAddress() public pure {
        // Taking the ADDRESS of the console library forces solc to emit a
        // link reference to lib/forge-std/src/console.sol:console.
        address a = address(console);
        assert(a != address(0));
    }
}

hardhat.config.ts (minimal):

import { defineConfig } from "hardhat/config";

export default defineConfig({
  solidity: { compilers: [{ version: "0.8.25", settings: { viaIR: true } }] },
  paths: { tests: { solidity: "./test" } },
});

remappings.txt:

forge-std/=lib/forge-std/src/

Setup the submodule and then run:

git submodule add https://github.com/foundry-rs/forge-std lib/forge-std
pnpm install
pnpm hardhat test solidity

Suggested fix direction

  1. Mirror Foundry's behaviour: when a link reference targets forge-std's
    console (or any library with empty/internal-only deployed bytecode),
    auto-link it to a stable address rather than requiring an
    on-disk artifact.
  2. More generally, internal-only libraries that produce no deployable bytecode
    should be linkable to a zero/placeholder address (their code is inlined; the
    address is only ever compared, never called).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Inbox
    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions