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

Top level objects in files without contracts are not included in the compilation artifacts #1646

Closed
1 of 2 tasks
montyly opened this issue May 17, 2022 · 8 comments
Closed
1 of 2 tasks
Assignees
Labels
C-forge Command: forge Cmd-forge-build Command: forge build T-bug Type: bug

Comments

@montyly
Copy link

montyly commented May 17, 2022

Component

Forge

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

  • Foundry
  • Foundryup

What version of Foundry are you on?

No response

What command(s) is the bug in?

No response

Operating System

No response

Describe the bug

Hey,

If a foundry codebase has a file that contains only top-level objects without contract, foundry does not generate their compilation artifacts.

For example: (after foundry init):

$ cat src/top_level.sol 
function test() {

}
$ cat src/Contract.sol 
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.10;

import "./top_level.sol";

contract Contract {
    function a() public{
        test();
    }
}

Running forge build will not generate a json file in out/free.sol/.

However by adding an empty contract to top_level.sol:

function test() {

}
contract T{}

Running forge build will generate a json file in out/free.sol/T.json.

This prevent third-party tools (such as Slither) to work on such codebase.

Related: crytic/crytic-compile#271

@onbjerg
Copy link
Member

onbjerg commented May 19, 2022

I think this is expected behavior - if there is no library and no contract, then what do you want from the compilation artifacts? Free standing functions are not included in the ABI.

@onbjerg onbjerg added C-forge Command: forge Cmd-forge-build Command: forge build labels May 19, 2022
@onbjerg onbjerg moved this from Todo to May be solved in Foundry May 19, 2022
@mattsse
Copy link
Member

mattsse commented May 19, 2022

I think this is expected behavior - if there is no library and no contract.

exactly, solc only emits a SourceFile for files that don't contain any contracts/interfaces.

I've though about this after @mds1 brought it up, we could generate an empty artifact with only the AST set for files like this, but I'm not a fan of that tbh. it's potentially unsound because the general assumption is contract = artifact, however, we already handle these edge cases in ethers-solc and never check for outputs to be present (like bytecode), so generating an empty artifact for a file that does not contain any source units should generally just work.

I'm not sure why slither expects a file to begin with, judging from the logs, it parses the ast and maps that to a file structure: parse_top_level_from_loaded_json?

I will investigate this

@montyly
Copy link
Author

montyly commented May 20, 2022

The issue is that with forge's compilation artifacts structure the data associated with top-level objects are missing (unless the top level objects are in a file that has a contract).

In this example, when I run forge build --extra-output userdoc --extra-output devdoc, in cache/solidity-files-cache.json, I see:

    "/tmp/tests_foundry/src/top_level.sol": {
      "lastModificationDate": 1653035419629,
      "contentHash": "6e6c34f5c3278ef99f3777de8ddf2601",
      "sourceName": "src/top_level.sol",
      "solcConfig": {
        "settings": {
          "optimizer": {
            "enabled": true,
            "runs": 200
          },
          "metadata": {
            "bytecodeHash": "ipfs"
          },
          "outputSelection": {
            "*": {
              "": [
                "ast"
              ],
              "*": [
                "evm.bytecode",
                "evm.deployedBytecode",
                "devdoc",
                "userdoc"
              ]
            }
          },
          "evmVersion": "london"
        }
      },
      "imports": [],
      "versionRequirement": null,
      "artifacts": {}
    },

So I would expect to have access to the ast/devdoc/userdoc of the content in top_level.sol, but it's not available. It's the same with other top-level objects (i.e. if there is a top-level structure, I would expect to see its ast). The lack of AST for top-level objects will prevent Slither from working.

It's also unexpected imho that the top-level object artifacts are available if the objects are in a file with a contract, and are not available otherwise.

I think that anything that can generate Solidity artifacts (ast/doc/etc ..) should be available in some format in the compilation artifacts.

@montyly
Copy link
Author

montyly commented May 20, 2022

For info, the way hardhat handles it, is that it will create, per compilation unit, a artifacts/build-info/<random_id>.json with all the compilation artifacts (but there is probably a better way to structure this)

@mattsse
Copy link
Member

mattsse commented May 20, 2022

I get it now, thanks.

this should be an easy fix and I'm on it now.

@gakonst
Copy link
Member

gakonst commented May 23, 2022

@montyly can you check if this works now on latest foundryup -b master?

@pedrommaiaa
Copy link
Contributor

I'm not sure about @montyly but I was having a very similar problem that was caused when running slither and now its working @gakonst.

@mattsse
Copy link
Member

mattsse commented Jun 8, 2022

closing this as we emit artifacts for sol files without contract definitions now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-forge Command: forge Cmd-forge-build Command: forge build T-bug Type: bug
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

5 participants