Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug(compiler): solc compiler input contains same file multiple times, making build artifacts unusable #246

Open
2 tasks done
0xalpharush opened this issue Apr 7, 2024 · 3 comments
Milestone

Comments

@0xalpharush
Copy link

0xalpharush commented Apr 7, 2024

Component

Forge

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (0c961f7 2024-04-07T00:19:04.896666000Z)

What command(s) is the bug in?

forge build

Operating System

macOS (Apple Silicon)

Describe the bug

Foundry's artifacts contain multiple AST's for the same source file and this causes issues in tools like slither which maintain a mapping of source file -> AST. It makes it such that there are multiple reference ID's for what is an "identical" declaration presumably because the solc import resolution fails and adds the entry itself. I believe this is similar to but distinct from gakonst/ethers-rs#2609

Steps to reproduce:

git clone https://github.com/code-423n4/2023-01-timeswap
yarn
cd v2-token
forge build --build-info --skip '*/test/** */script/**' --force
ls out/build-info 
cat $(find out/build-info/*.json)  | jq '.output.sources | keys' |  grep 'node_modules/@openzeppelin/contracts/token/ERC1155/IERC1155.sol'

The output:

  "../../node_modules/@openzeppelin/contracts/token/ERC1155/IERC1155.sol",
  "/Users/alpharush/2023-01-timeswap/node_modules/@openzeppelin/contracts/token/ERC1155/IERC1155.sol",

I expect there only to be one AST for each source unit (file) in each compilation unit (all sources compiled together) as this is should be unique and be an absolute path on disk. This will also causes issue for LSP-like functionality as there would appear to be twice as many declarations in the same file since multiple ASTs are produced with different reference ID's.

As explained in this comment, this happens when the import lookup fails.

I checked the solc compilerinput which looks ok, there's something weird with the output however because it contains duplicate entries for Divider.sol: src/Divider.sol and /src/Divider.sol, this is usually a sign that solc fails to look up an import of a file in the json compilerinput (which works like a virtual file system) and instead tries to find it on disk and also adds this to the compileroutput.

The repo's commit I ran this against:

$ git log
ef4c84fb8535aad8abd6b67cc45d994337ec4514
@klkvr
Copy link
Member

klkvr commented Apr 8, 2024

This seems to be the case only for projects using libs outside of root. In the case above we get two different paths for the same file while resolving imports:

  1. import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol" at "src/interfaces/IERC1155Enumerable.sol" is resolved as "$ROOT/../../node_modules/@openzeppelin/contracts/token/ERC1155/IERC1155.sol"
  2. import "./IERC1155.sol" at "$ROOT/../../node_modules/@openzeppelin/contracts/token/ERC1155/ERC1155.sol" is getting normalized (because it is relative) and resolved as "/Users/alpharush/2023-01-timeswap/node_modules/@openzeppelin/contracts/token/ERC1155/IERC1155.sol",

cc @mattsse we can probably address this by ensuring that we never strip project root while normalizing them, or just replace some parts of global path prefixes with $ROOT/../../../.. before passing to solc

not sure if we support that kind of layout at all, this might probably be not the only issue

@0xalpharush
Copy link
Author

Another user is reporting issues relating to this crytic/slither#2483

@zerosnacks
Copy link
Member

From: foundry-rs/foundry#8797

Running forge build --build-info --skip test/** script/** --force generates multiple keys for the same file:

❯ cat $(find out/build-info/*.json) | jq '.output.sources | keys' | grep 'ITransferValidator.sol' "contracts/interfaces/callbacks/ITransferValidator.sol", "lib/core-v1/contracts/interfaces/callbacks/ITransferValidator.sol",

ITransferValidator.sol is a file in the submodule of the repo, and the correct path is lib/core-v1/contracts/interfaces/callbacks/ITransferValidator.sol. However, there is an additional key in the sources with this path: contracts/interfaces/callbacks/ITransferValidator.sol, which is the path in the repo that it belongs to.

This is causing issues for when I run slither . --ignore-compile --config-file=slither.config.json --fail-low, which is yielding this error: crytic_compile.platform.exceptions.InvalidCompilation: Unknown file: contracts/interfaces/callbacks/ITransferValidator.sol.

I would expect forge build to only generate one key in the output.sources, could use some insight to pinpoint the issue and what is causing the key generate with the incorrect path. Thank you!

Ref ticket in crytic-compile: crytic/crytic-compile#572

@zerosnacks zerosnacks changed the title solc compiler input contains same file multiple times, making build artifacts unusable bug(compiler): solc compiler input contains same file multiple times, making build artifacts unusable Sep 5, 2024
@zerosnacks zerosnacks transferred this issue from foundry-rs/foundry Feb 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants