crytic / crytic-compile

Abstraction layer for smart contract build systems
GNU Affero General Public License v3.0
145 stars 83 forks source link

Support for multiple different solc compiler versions (--solc-solcs-select/--solc-solcs-bin usage) #374

Open taiyangc opened 1 year ago

taiyangc commented 1 year ago

Describe the desired feature

Hello, I am trying to run slither against multiple contracts with different required solc versions, however I am seeing this error:

$ slither ./ --checklist
Compilation warnings/errors on ./Arithmetic1.sol:
Error: Source file requires different compiler version (current compiler is 0.8.17+commit.8df45f5f.Darwin.appleclang) - note that nightly builds are considered to be strictly less than the released version
 --> Arithmetic1.sol:2:1:
  |
2 | pragma solidity ^0.7.0;
  | ^^^^^^^^^^^^^^^^^^^^^^^

Note that I have both 0.8.17 and 0.7.6 installed through solc-select:

$ solc-select versions
0.8.17 (current, set by /Users/eric/.solc-select/global-version)
0.7.6

Based on the docs for --solc-solcs-select/--solc-solcs-bin:

  --solc-solcs-select SOLC_SOLCS_SELECT
                        Specify different solc version to try (env config). Depends on solc-select
  --solc-solcs-bin SOLC_SOLCS_BIN
                        Specify different solc version to try (path config). Example: --solc-solcs-bin
                        solc-0.4.24,solc-0.5.3

I would assume this means that I should be able to specify multiple versions or bins of solc, and slither would pick one that works for a particular contract. But this is not the case:

$ slither ./ --solc-solcs-select 0.8.17,0.7.6 --checklist
Compilation warnings/errors on ./Arithmetic1.sol:
Error: Source file requires different compiler version (current compiler is 0.8.17+commit.8df45f5f.Darwin.appleclang) - note that nightly builds are considered to be strictly less than the released version
 --> Arithmetic1.sol:2:1:
  |
2 | pragma solidity ^0.7.0;
  | ^^^^^^^^^^^^^^^^^^^^^^^

Trying again with bin paths directly:

$ slither ./ --solc-solcs-bin ~/.solc-select/artifacts/solc-0.8.17/solc-0.8.17,~/.solc-select/artifacts/solc-0.7.6/solc-0.7.6 --checklist
Compilation warnings/errors on ./Arithmetic1.sol:
Error: Source file requires different compiler version (current compiler is 0.8.17+commit.8df45f5f.Darwin.appleclang) - note that nightly builds are considered to be strictly less than the released version
 --> Arithmetic1.sol:2:1:
  |
2 | pragma solidity ^0.7.0;
  | ^^^^^^^^^^^^^^^^^^^^^^^

If I reverse the ordering of 0.8.17 and 0.7.6 on the command line, then the contract with ^0.7.0 succeeds but the ones with ^0.8.0 fail instead. I am confused as to why the doc allows multiple bins, but in reality only the first bin will be used to compile all contracts, instead of being selective.

Assuming this is not a bug (intended to support only one solc version at a time), would it be useful to request (maybe yet another option) to allow exhausting all available solc versions for each individual contract, instead of a blanket compile using just one solc version?

0xalpharush commented 1 year ago

We would need to create a new compilation unit every time a file compiles with a given version. Also, we could consider just parsing the pragma and switching the solc version with solc-select if it's installed. @taiyangc I would think a compilation framework that supports multiple compiler versions such as hardhat or foundry would fit your needs. Is there something about your current use case that prohibits this?

taiyangc commented 1 year ago

In my use case the contracts being tested against may not come from one single project (it would take significant effort to combine them), hence if detection can be done at pragma level and use solc-select to switch that would be great.