slither icon indicating copy to clipboard operation
slither copied to clipboard

[Bug]: convert_library_call is buggy and doesn't convert high level call/ set function properly

Open eccentricexit opened this issue 3 years ago • 1 comments

Describe the issue:

Slither with slither . --print echidna throws this error when the contract uses a library with fixed sized arrays.

Code example to reproduce the issue:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

library Setter {
    function set(
        uint256[1] storage self,
        uint256 key,
        uint256 value
    ) internal {
        self[key] = value;
    }
}

contract SetterTest {
    using Setter for uint256[1];

    uint256[1] public params;

    function f(uint256 key, uint256 value) external {
        params.set(key, value);
    }
}

Version:

$ slither --version
0.8.3

$ truffle version
Truffle v5.5.21 (core: 5.5.21)
Ganache v7.2.0
Solidity - 0.8.10 (solc-js)
Node v12.22.12
Web3.js v1.7.4

Relevant log output:

...
> Compiled successfully using:
   - solc: 0.8.10+commit.fc410830.Emscripten.clang

Traceback (most recent call last):
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/__main__.py", line 744, in main_impl
    ) = process_all(filename, args, detector_classes, printer_classes)
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/__main__.py", line 87, in process_all
    ) = process_single(compilation, args, detector_classes, printer_classes)
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/__main__.py", line 72, in process_single
    return _process(slither, detector_classes, printer_classes)
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/__main__.py", line 119, in _process
    printer_results = slither.run_printers()
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/slither.py", line 211, in run_printers
    return [p.output(self._crytic_compile.target).data for p in self._printers]
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/slither.py", line 211, in <listcomp>
    return [p.output(self._crytic_compile.target).data for p in self._printers]
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/printers/guidance/echidna.py", line 380, in output
    cst_functions = _extract_constant_functions(self.slither)
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/printers/guidance/echidna.py", line 118, in _extract_constant_functions
    cst_functions = [_get_name(f) for f in contract.functions_entry_points if _is_constant(f)]
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/printers/guidance/echidna.py", line 118, in <listcomp>
    cst_functions = [_get_name(f) for f in contract.functions_entry_points if _is_constant(f)]
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/printers/guidance/echidna.py", line 102, in _is_constant
    if isinstance(ir.function, Variable) or ir.function.view or ir.function.pure:
AttributeError: 'NoneType' object has no attribute 'view'
None
Error in .
Traceback (most recent call last):
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/__main__.py", line 744, in main_impl
    ) = process_all(filename, args, detector_classes, printer_classes)
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/__main__.py", line 87, in process_all
    ) = process_single(compilation, args, detector_classes, printer_classes)
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/__main__.py", line 72, in process_single
    return _process(slither, detector_classes, printer_classes)
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/__main__.py", line 119, in _process
    printer_results = slither.run_printers()
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/slither.py", line 211, in run_printers
    return [p.output(self._crytic_compile.target).data for p in self._printers]
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/slither.py", line 211, in <listcomp>
    return [p.output(self._crytic_compile.target).data for p in self._printers]
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/printers/guidance/echidna.py", line 380, in output
    cst_functions = _extract_constant_functions(self.slither)
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/printers/guidance/echidna.py", line 118, in _extract_constant_functions
    cst_functions = [_get_name(f) for f in contract.functions_entry_points if _is_constant(f)]
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/printers/guidance/echidna.py", line 118, in <listcomp>
    cst_functions = [_get_name(f) for f in contract.functions_entry_points if _is_constant(f)]
  File "/home/deadcode/.local/lib/python3.10/site-packages/slither/printers/guidance/echidna.py", line 102, in _is_constant
    if isinstance(ir.function, Variable) or ir.function.view or ir.function.pure:
AttributeError: 'NoneType' object has no attribute 'view'

eccentricexit avatar Jul 13 '22 18:07 eccentricexit

Here, using_for can have keys that are objects and not strings: https://github.com/crytic/slither/blob/ce9dbf650d7acfee51ddafd844929f4e8d345672/slither/slithir/convert.py#L529-L532 Thus, the high level call is not converted to a library call and the function attribute is not set, producing the following incorrect IR:

Contract Setter
        Function Setter.set(uint256[1],uint256,uint256) (*)
                Expression: self[key] = value
                IRs:
                        REF_0(uint256) -> self[key]
                        REF_0 (->self) := value(uint256)
Contract SetterTest
        Function SetterTest.f(uint256,uint256) (*)
                Expression: params.set(key,value)
                IRs:
                        TMP_0(None) = HIGH_LEVEL_CALL, dest:params(uint256[1]), function:set, arguments:['key', 'value']

EDIT: The __eq__ function for ArrayType compares equality of its length property (which in this case is a Literal). The Literal class does not implement __eq__

0xalpharush avatar Aug 04 '22 22:08 0xalpharush