Skip to content
This repository was archived by the owner on Apr 20, 2026. It is now read-only.

Invalid contract flattening with matching interface names #34

@SidestreamColdMelon

Description

@SidestreamColdMelon

This issue is the successor of gakonst/ethers-rs#2588, created after the deprecation announcement of ethers-rs.
Other issues relevant to flattening are collected here: foundry-rs/foundry#6022.

Problem

As previously described in foundry-rs/foundry#4034, the latest version of forge (that now depends on compilers instead of ethers-rs) still doesn't properly handle situations when multiple files contain interfaces with the same name.

Example

Given two files FileA.sol and FileB.sol

// FileA.sol
pragma solidity ^0.8.10;
import "./FileB.sol";

interface FooBar {
    function foo() external;
}
contract A {
    function execute() external {
        FooBar(address(0)).foo();
    }
}
// FileB.sol
pragma solidity ^0.8.10;

interface FooBar {
    function bar() external;
}
contract B {
    function execute() external {
        FooBar(address(0)).bar();
    }
}

Flattening will currently produce:

pragma solidity ^0.8.10;

interface FooBar {
    function bar() external;
}
contract B {
    function execute() external {
        FooBar(address(0)).bar();
    }
}

interface FooBar { // here is the conflict with the interface declared above
    function foo() external;
}
contract A {
    function execute() external {
        FooBar(address(0)).foo();
    }
}

Instead, the desired outcome is:

pragma solidity ^0.8.10;

interface FooBar_2 {
    function bar() external;
}
contract B {
    function execute() external {
        FooBar_2(address(0)).bar();
    }
}

interface FooBar_1 { // conflict avoided since the interface above was renamed before flattening
    function foo() external;
}
contract A {
    function execute() external {
        FooBar_1(address(0)).foo();
    }
}

Notes

  • Although it's obviously discussable, we specifically propose to use incremental _N suffix for all interfaces in order to keep flattening backward compatible with hevm flatten command output. It is also more readable and independent from the project structure compared to the potential path-based prefix

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions