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-Candidate]: slither.core.solidity_types.elementary_type.NonElementaryType #1834

Closed
wisehalvdan opened this issue Apr 8, 2023 · 3 comments
Labels
bug-candidate Bugs reports that are not yet confirmed

Comments

@wisehalvdan
Copy link

wisehalvdan commented Apr 8, 2023

Describe the issue:

Even thought the compiler works just fine :

'npx hardhat clean' running (wd: /Users/developer/solidity/project)
'npx hardhat clean --global' running (wd: /Users/developer/solidity/project)
'npx hardhat compile --force' running
Downloading compiler 0.8.18
Compiled 87 Solidity files successfully

Slither crashes while trying to analyze it :

ERROR:root:Error in .
ERROR:root:Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.9/site-packages/slither/__main__.py", line 837, in main_impl
    ) = process_all(filename, args, detector_classes, printer_classes)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/__main__.py", line 101, in process_all
    ) = process_single(compilation, args, detector_classes, printer_classes)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/__main__.py", line 79, in process_single
    slither = Slither(target, ast_format=ast, **vars(args))
  File "/opt/homebrew/lib/python3.9/site-packages/slither/slither.py", line 135, in __init__
    self._init_parsing_and_analyses(kwargs.get("skip_analyze", False))
  File "/opt/homebrew/lib/python3.9/site-packages/slither/slither.py", line 155, in _init_parsing_and_analyses
    raise e
  File "/opt/homebrew/lib/python3.9/site-packages/slither/slither.py", line 151, in _init_parsing_and_analyses
    parser.analyze_contracts()
  File "/opt/homebrew/lib/python3.9/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 528, in analyze_contracts
    self._convert_to_slithir()
  File "/opt/homebrew/lib/python3.9/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 739, in _convert_to_slithir
    func.generate_slithir_and_analyze()
  File "/opt/homebrew/lib/python3.9/site-packages/slither/core/declarations/function.py", line 1761, in generate_slithir_and_analyze
    node.slithir_generation()
  File "/opt/homebrew/lib/python3.9/site-packages/slither/core/cfg/node.py", line 679, in slithir_generation
    self._irs = convert_expression(expression, self)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/slithir/convert.py", line 140, in convert_expression
    result = apply_ir_heuristics(result, node)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/slithir/convert.py", line 1926, in apply_ir_heuristics
    irs = propagate_type_and_convert_call(irs, node)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/slithir/convert.py", line 463, in propagate_type_and_convert_call
    new_ins = propagate_types(ins, node)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/slithir/convert.py", line 750, in propagate_types
    t = ir.variable_left.type
  File "/opt/homebrew/lib/python3.9/site-packages/slither/core/declarations/solidity_variables.py", line 123, in type
    return ElementaryType(SOLIDITY_VARIABLES[self.name])
  File "/opt/homebrew/lib/python3.9/site-packages/slither/core/solidity_types/elementary_type.py", line 156, in __init__
    raise NonElementaryType
slither.core.solidity_types.elementary_type.NonElementaryType

Using hardhat doesn't even provide with message to where to look. But If we try the same project with truffle, it at least points us to some file.

*[master][~/solidity/project]$ slither .
'npx truffle compile --all' running (use --truffle-version [email protected] to use specific version)

Compiling your contracts...
===========================
<CONTRACTS_LIST>
> Artifacts written to /Users/developer/solidity/project/build/contracts
> Compiled successfully using:
   - solc: 0.8.18+commit.87f61d96.Emscripten.clang

ERROR:root:Error in .
ERROR:root:Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.9/site-packages/slither/__main__.py", line 837, in main_impl
    ) = process_all(filename, args, detector_classes, printer_classes)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/__main__.py", line 101, in process_all
    ) = process_single(compilation, args, detector_classes, printer_classes)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/__main__.py", line 79, in process_single
    slither = Slither(target, ast_format=ast, **vars(args))
  File "/opt/homebrew/lib/python3.9/site-packages/slither/slither.py", line 114, in __init__
    parser.parse_top_level_from_loaded_json(ast, path)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 280, in parse_top_level_from_loaded_json
    get_imported_scope = self.compilation_unit.get_scope(import_directive.filename)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/core/compilation_unit.py", line 243, in get_scope
    filename = self._crytic_compile_compilation_unit.crytic_compile.filename_lookup(
  File "/opt/homebrew/lib/python3.9/site-packages/crytic_compile/crytic_compile.py", line 203, in filename_lookup
    raise ValueError(f"{filename} does not exist")
ValueError: project:/contracts/structs/Combatant.sol does not exist

Even if the errors is file does not exists, I believe this is the same underlying error somehow. What I suspect causing this issue is the following Struct :

struct ActiveSkill {
	bool exists;
	uint256 id;
	string name;
	uint8 vigorCost;
	uint16 requiredLevel;
	function (Combatant memory, uint8, uint8, Combatant[2][3] memory, Combatant memory) external view returns (Combatant[2][3] memory, Combatant memory) useSkill;
}

I've seen this struct breaking console on Truffle and web3.js while used on ABI. So my guess this also breaks Slither.
Solidity handles function pointers as bytes24 consists of 20 byte address + 4 byte function selector. On JS side of things manually changing the abi to reflect type bytes24 instead of function fixes this issue, but not sure what slither depends on the artifact, probably more than ABI so don't think it will fix the issue there.

Code example to reproduce the issue:

struct ActiveSkill {
	bool exists;
	uint256 id;
	string name;
	uint8 vigorCost;
	uint16 requiredLevel;
	function (Combatant memory, uint8, uint8, Combatant[2][3] memory, Combatant memory) external view returns (Combatant[2][3] memory, Combatant memory) useSkill;
}

Version:

0.9.3

Relevant log output:

No response

@wisehalvdan wisehalvdan added the bug-candidate Bugs reports that are not yet confirmed label Apr 8, 2023
@wisehalvdan
Copy link
Author

OK did some tests

Let's have following folder structure for Truffle:

.
├── contracts
│   ├── Ex1834.sol
│   └── structs
│       └── Struct1834.sol
└── truffle-config.js

Struct1834.sol Contents :

struct Struct1834 {
    function(uint256) external pure returns(uint256) Function;
}

Ex1834.sol Contents:

import "./structs/Struct1834.sol";

contract Ex1834 {
    Struct1834 test;

    constructor() {
        init();
    }

    function init() internal {
        test.Function = this.testFunction;
    }

    function testFunction(uint256 _value) external pure returns(uint256) {
        return _value;
    }
}

If we try to run slither on this example :

[~/solidity/slither]$ slither . 
> Compiled successfully using:
   - solc: 0.8.18+commit.87f61d96.Emscripten.clang

Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.9/site-packages/slither/__main__.py", line 837, in main_impl
    ) = process_all(filename, args, detector_classes, printer_classes)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/__main__.py", line 101, in process_all
    ) = process_single(compilation, args, detector_classes, printer_classes)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/__main__.py", line 79, in process_single
    slither = Slither(target, ast_format=ast, **vars(args))
  File "/opt/homebrew/lib/python3.9/site-packages/slither/slither.py", line 114, in __init__
    parser.parse_top_level_from_loaded_json(ast, path)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 280, in parse_top_level_from_loaded_json
    get_imported_scope = self.compilation_unit.get_scope(import_directive.filename)
  File "/opt/homebrew/lib/python3.9/site-packages/slither/core/compilation_unit.py", line 243, in get_scope
    filename = self._crytic_compile_compilation_unit.crytic_compile.filename_lookup(
  File "/opt/homebrew/lib/python3.9/site-packages/crytic_compile/crytic_compile.py", line 203, in filename_lookup
    raise ValueError(f"{filename} does not exist")
ValueError: project:/contracts/structs/Struct1834.sol does not exist

But If we change the Ex1834.Sol as follows :

struct Struct1834 {
    function(uint256) external pure returns(uint256) Function;
}
contract Ex1834 {
    Struct1834 test;

    constructor() {
        init();
    }

    function init() internal {
        test.Function = this.testFunction;
    }

    function testFunction(uint256 _value) external pure returns(uint256) {
        return _value;
    }
}

Slither works perfectly fine

[~/solidity/slither]$ slither .
> Compiled successfully using:
   - solc: 0.8.18+commit.87f61d96.Emscripten.clang

INFO:Detectors:
Parameter Ex1834.testFunction(uint256)._value (Ex1834.sol#18) is not in mixedCase
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions
INFO:Slither:. analyzed (1 contracts with 85 detectors), 1 result(s) found

Which still doesn't make me understand the problem but looks like both Truffle and Hardhat outputs are correct in a way.
But I hope it helps to someone with more broad understanding of codebase.

@0xalpharush
Copy link
Contributor

@wisehalvdan I believe this is a bug in truffle trufflesuite/truffle#3124 and is a current limitation of Slither's integration with it crytic/crytic-compile#267

@duckki
Copy link

duckki commented Aug 2, 2023

This happened to me today compiling https://github.com/RuneArtLtd/rune/blob/d1d8ba3b241dd84acf9cac439323c984daa37434/Rune.sol, using slither 0.9.3.
But, it does not happen with slither 0.9.6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug-candidate Bugs reports that are not yet confirmed
Projects
None yet
Development

No branches or pull requests

3 participants