crytic / slither

Static Analyzer for Solidity and Vyper
https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/
GNU Affero General Public License v3.0
5.33k stars 968 forks source link

[Bug-Candidate]: Slither seems not being able to find contracts in subfolder #1509

Closed theedisonlamp closed 1 year ago

theedisonlamp commented 1 year ago

Describe the issue:

When working with non standard folder structure in Foundry, Slither command is not finding any source from subfolder solidity in the this repo.

Then running the command yarn slither the following is the resulting log:

yarn run v1.22.19
$ slither . --filter-paths "lib|test" --exclude naming-convention
'forge build --extra-output abi --extra-output userdoc --extra-output devdoc --extra-output evm.methodIdentifiers --force' running
Compiling 16 files with 0.8.16
Solc 0.8.16 finished in 2.34s
Compiler run successful

No contract were found in None, check the correct compilation
No contract was analyzed
. analyzed (0 contracts with 80 detectors), 0 result(s) found
Done in 3.68s.

Code example to reproduce the issue:

git clone https://github.com/theedisonlamp/crytic-issue
yarn
yarn slither

Version:

0.9.1

Relevant log output:

yarn run v1.22.19
$ slither . --filter-paths "lib|test" --exclude naming-convention
'forge build --extra-output abi --extra-output userdoc --extra-output devdoc --extra-output evm.methodIdentifiers --force' running
Compiling 16 files with 0.8.16
Solc 0.8.16 finished in 2.34s
Compiler run successful

No contract were found in None, check the correct compilation
No contract was analyzed
. analyzed (0 contracts with 80 detectors), 0 result(s) found
Done in 3.68s.
elopez commented 1 year ago

Hi @theedisonlamp! crytic-compile has an option to support non-standard "out" directories in foundry projects, can you try adding --foundry-out-directory solidity/out to your slither command and report back if that helps?

theedisonlamp commented 1 year ago

Hi @theedisonlamp! crytic-compile has an option to support non-standard "out" directories in foundry projects, can you try adding --foundry-out-directory solidity/out to your slither command and report back if that helps?

Hi @elopez. Running the command slither . --filter-paths "lib|test" --exclude naming-convention --foundry-out-directory solidity/out results in the error unrecognized arguments: --foundry-out-directory solidity/out:

usage: slither target [flag]

target can be:
        - file.sol // a Solidity file
        - project_directory // a project directory. See https://github.com/crytic/crytic-compile/#crytic-compile for the supported platforms
        - 0x.. // a contract on mainnet
        - NETWORK:0x.. // a contract on a different network. Supported networks: mainet,optim,ropsten,kovan,rinkeby,goerli,tobalaba,bsc,testnet.bsc,arbi,testnet.arbi,poly,mumbai,avax,testnet.avax,ftm
slither: error: unrecognized arguments: --foundry-out-directory solidity/out
elopez commented 1 year ago

Oh, it looks like there's a missing piece in crytic-compile to actually expose the options in the CLI 😅 I opened a pull request to fix it: https://github.com/crytic/crytic-compile/pull/323

In the meantime you should be able to specify the foundry_out_directory option in a slither config file (slither.config.json)

{
"foundry_out_directory": "solidity/out"
}
theedisonlamp commented 1 year ago

Oh, it looks like there's a missing piece in crytic-compile to actually expose the options in the CLI 😅 I opened a pull request to fix it: crytic/crytic-compile#323

In the meantime you should be able to specify the foundry_out_directory option in a slither config file (slither.config.json)

{
"foundry_out_directory": "solidity/out"
}

After implementing this workaround, running Slither results in:

yarn run v1.22.19
$ slither . --filter-paths "lib|test" --exclude naming-convention
Traceback (most recent call last):
  File "/home/tel/crytic-issue/.venv/bin/slither", line 10, in <module>
    sys.exit(main())
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/slither/__main__.py", line 711, in main
    main_impl(all_detector_classes=detectors, all_printer_classes=printers)
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/slither/__main__.py", line 725, in main_impl
    args = parse_args(all_detector_classes, all_printer_classes)
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/slither/__main__.py", line 610, in parse_args
    read_config_file(args)
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/slither/utils/command_line.py", line 81, in read_config_file
    if getattr(args, key) == defaults_flag_in_config[key]:
AttributeError: 'Namespace' object has no attribute 'foundry_out_directory'
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
elopez commented 1 year ago

Looks like my guess about it working anyway via the config file was off 😞 Can you try installing the fixed version of crytic-compile and running it again? The following should do the trick to upgrade

pip3 install -U https://github.com/crytic/crytic-compile/archive/refs/heads/dev-fix-foundry-options.zip

theedisonlamp commented 1 year ago

Looks like my guess about it working anyway via the config file was off 😞 Can you try installing the fixed version of crytic-compile and running it again? The following should do the trick to upgrade

pip3 install -U https://github.com/crytic/crytic-compile/archive/refs/heads/dev-fix-foundry-options.zip

After installing within the virtualenv, the problem still persists...

elopez commented 1 year ago

can you confirm that the installation was successful and crytic-compile --help shows the foundry options?

...

Foundry options:
  --foundry-ignore-compile
                        Do not run foundry compile
  --foundry-out-directory FOUNDRY_OUT_DIRECTORY
theedisonlamp commented 1 year ago

can you confirm that the installation was successful and crytic-compile --help shows the foundry options?

...

Foundry options:
  --foundry-ignore-compile
                        Do not run foundry compile
  --foundry-out-directory FOUNDRY_OUT_DIRECTORY

crytic-compile --help shows:

usage: crytic-compile contract.sol [flag]

crytic-compile. For usage information, see https://github.com/crytic/crytic-compile/wiki/Usage

positional arguments:
  target                contract.sol

optional arguments:
  -h, --help            show this help message and exit
  --config-file CONFIG_FILE
                        Provide a config file (default: crytic_compile.config.json)
  --export-format EXPORT_FORMAT
                        Export json with non crytic-compile format (default None. Accepted: standard, solc, truffle)
  --export-formats EXPORT_FORMATS
                        Comma-separated list of export format, defaults to None
  --export-dir EXPORT_DIR
                        Export directory (default: crytic-export)
  --export-zip EXPORT_TO_ZIP
                        Export all the projects to a zip file
  --export-zip-type EXPORT_TO_ZIP_TYPE
                        Zip compression type. One of lzma,stored,deflated,bzip2. Default lzma
  --print-filenames     Print all the filenames
  --version             displays the current version
  --supported-platforms
                        Shows the platforms supported

Compile options:
  --compile-force-framework COMPILE_FORCE_FRAMEWORK
                        Force the compile to a given framework
                        (solc,truffle,embark,dapp,etherlime,etherscan,vyper,waffle,brownie,solc-
                        json,buidler,hardhat,foundry,standard,archive)
  --compile-remove-metadata
                        Remove the metadata from the bytecodes
  --compile-custom-build COMPILE_CUSTOM_BUILD
                        Replace platform specific build command
  --ignore-compile      Do not run compile of any platform

Solc options:
  --solc SOLC           solc path
  --solc-remaps SOLC_REMAPS
                        Add remapping
  --solc-args SOLC_ARGS
                        Add custom solc arguments. Example: --solc-args "--allow-path /tmp --evm-version byzantium".
  --solc-disable-warnings
                        Disable solc warnings
  --solc-working-dir SOLC_WORKING_DIR
                        Change the default working directory
  --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
  --solc-standard-json  Compile all specified targets in a single compilation using solc standard json
  --solc-force-legacy-json
                        Force the solc compiler to use the legacy json ast format over the compact json ast format

Truffle options:
  --truffle-ignore-compile
                        Do not run truffle compile
  --truffle-build-directory TRUFFLE_BUILD_DIRECTORY
                        Use an alternative truffle build directory
  --truffle-version TRUFFLE_VERSION
                        Use a local Truffle version (with npx)
  --truffle-overwrite-config
                        Use a simplified version of truffle-config.js for compilation
  --truffle-overwrite-version TRUFFLE_OVERWRITE_VERSION
                        Overwrite solc version in truffle-config.js (only if --truffle-overwrite-config)

Embark options:
  --embark-ignore-compile
                        Do not run embark build
  --embark-overwrite-config
                        Install @trailofbits/embark-contract-export and add it to embark.json

Dapp options:
  --dapp-ignore-compile
                        Do not run dapp build

Etherlime options:
  --etherlime-ignore-compile
                        Do not run etherlime compile
  --etherlime-compile-arguments
                        Add arbitrary arguments to etherlime compile (note: [dir] is the the directory provided to
                        crytic-compile)

Etherscan options:
  --etherscan-only-source-code
                        Only compile if the source code is available.
  --etherscan-only-bytecode
                        Only looks for bytecode.
  --etherscan-apikey ETHERSCAN_API_KEY
                        Etherscan API key.
  --arbiscan-apikey ARBISCAN_API_KEY
                        Etherscan API key.
  --polygonscan-apikey POLYGONSCAN_API_KEY
                        Etherscan API key.
  --test-polygonscan-apikey TEST_POLYGONSCAN_API_KEY
                        Etherscan API key.
  --avax-apikey AVAX_API_KEY
                        Etherscan API key.
  --ftmscan-apikey FTMSCAN_API_KEY
                        Etherscan API key.
  --bscan-apikey BSCAN_API_KEY
                        Etherscan API key.
  --optim-apikey OPTIM_API_KEY
                        Optimistic API key.
  --etherscan-export-directory ETHERSCAN_EXPORT_DIR
                        Directory in which to save the analyzed contracts.

Waffle options:
  --waffle-ignore-compile
                        Do not run waffle compile
  --waffle-config-file WAFFLE_CONFIG_FILE
                        Provide a waffle config file

NPX options:
  --npx-disable         Do not use npx

Buidler options:
  --buidler-ignore-compile
                        Do not run buidler compile
  --buidler-cache-directory BUIDLER_CACHE_DIRECTORY
                        Use an alternative buidler cache directory (default ./cache)
  --buidler-skip-directory-name-fix
                        Disable directory name fix (see https://github.com/crytic/crytic-compile/issues/116)

hardhat options:
  --hardhat-ignore-compile
                        Do not run hardhat compile
  --hardhat-cache-directory HARDHAT_CACHE_DIRECTORY
                        Use an alternative hardhat cache directory (default ./cache)
  --hardhat-artifacts-directory HARDHAT_ARTIFACTS_DIRECTORY
                        Use an alternative hardhat artifacts directory (default ./artifacts)
theedisonlamp commented 1 year ago

And crytic-compile --version shows 0.2.4

elopez commented 1 year ago

You don't have the foundry options there, it looks like the upgrade didn't take place. Try uninstalling crytic-compile and re-installing the fixed version. Also make sure you don't have any other installation shadowing the one from your venv (running which crytic-compile can help you determine that)

theedisonlamp commented 1 year ago

You don't have the foundry options there, it looks like the upgrade didn't take place. Try uninstalling crytic-compile and re-installing the fixed version. Also make sure you don't have any other installation shadowing the one from your venv (running which crytic-compile can help you determine that)

Uninstalling and installing back again did the trick. It is now working as intended.

theedisonlamp commented 1 year ago

@elopez , so basically, the resulting preinstall script in package.json to make your strategy work was:

{
    "preinstall": "python -m venv .venv && . .venv/bin/activate && pip install slither-analyzer && yes | pip uninstall crytic-compile && pip install -U https://github.com/crytic/crytic-compile/archive/refs/heads/dev-fix-foundry-options.zip",
}
theedisonlamp commented 1 year ago

There is one problem though.

If I do not comment the following line: https://github.com/theedisonlamp/crytic-issue/blob/main/foundry.toml#L4, yarn slither command results in:

yarn run v1.22.19
$ slither . --filter-paths "lib|test" --exclude naming-convention
'forge build --extra-output abi --extra-output userdoc --extra-output devdoc --extra-output evm.methodIdentifiers --force' running
Compiling 16 files with 0.8.16
Solc 0.8.16 finished in 2.59s
Compiler run successful

Traceback (most recent call last):
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/slither/__main__.py", line 826, in main_impl
    ) = process_all(filename, args, detector_classes, printer_classes)
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/slither/__main__.py", line 86, in process_all
    compilations = compile_all(target, **vars(args))
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/crytic_compile/crytic_compile.py", line 637, in compile_all
    compilations.append(CryticCompile(target, **kwargs))
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/crytic_compile/crytic_compile.py", line 117, in __init__
    self._compile(**kwargs)
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/crytic_compile/crytic_compile.py", line 548, in _compile
    self._platform.compile(self, **kwargs)
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/crytic_compile/platform/foundry.py", line 154, in compile
    version, optimized, runs = _get_config_info(self._target)
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/crytic_compile/platform/foundry.py", line 216, in _get_config_info
    raise InvalidCompilation(
crytic_compile.platform.exceptions.InvalidCompilation: Could not find the cache/solidity-files-cache.json file.If you are using 'cache = true' in foundry's config file, please remove it. Otherwise please open an issue in https://github.com/crytic/crytic-compile
Error in .
Traceback (most recent call last):
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/slither/__main__.py", line 826, in main_impl
    ) = process_all(filename, args, detector_classes, printer_classes)
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/slither/__main__.py", line 86, in process_all
    compilations = compile_all(target, **vars(args))
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/crytic_compile/crytic_compile.py", line 637, in compile_all
    compilations.append(CryticCompile(target, **kwargs))
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/crytic_compile/crytic_compile.py", line 117, in __init__
    self._compile(**kwargs)
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/crytic_compile/crytic_compile.py", line 548, in _compile
    self._platform.compile(self, **kwargs)
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/crytic_compile/platform/foundry.py", line 154, in compile
    version, optimized, runs = _get_config_info(self._target)
  File "/home/tel/crytic-issue/.venv/lib/python3.9/site-packages/crytic_compile/platform/foundry.py", line 216, in _get_config_info
    raise InvalidCompilation(
crytic_compile.platform.exceptions.InvalidCompilation: Could not find the cache/solidity-files-cache.json file.If you are using 'cache = true' in foundry's config file, please remove it. Otherwise please open an issue in https://github.com/crytic/crytic-compile

error Command failed with exit code 255.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

And a cache folder is created as a sibling folder to solidity folder instead of inside solidity folder.

elopez commented 1 year ago

Unfortunately there is no way to adjust the cache path to a custom value in crytic-compile at this time, it is hardcoded to the default (cache)

https://github.com/crytic/crytic-compile/blob/master/crytic_compile/platform/foundry.py#L214

I opened a new issue (crytic/crytic-compile#326) to track that.

elopez commented 1 year ago

This should be working now that Slither 0.9.2 and crytic-compile 0.3.0 are released 🎉