[Bug-Candidate]: Ternary operation not handled bytes
Describe the issue:
Similar to #1198 and #1153, but seems those are for string and None respectively, whereas here the issue is bytes so figured I'd open a separate issue. Full stack trace below. Unfortunately repo is private so still tracking down exactly where this happens / trying to find a workaround
Code example to reproduce the issue:
TBD
Version:
0.8.3
Relevant log output:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/slither/__main__.py", line 744, in main_impl
) = process_all(filename, args, detector_classes, printer_classes)
File "/usr/local/lib/python3.9/site-packages/slither/__main__.py", line 87, in process_all
) = process_single(compilation, args, detector_classes, printer_classes)
File "/usr/local/lib/python3.9/site-packages/slither/__main__.py", line 70, in process_single
slither = Slither(target, ast_format=ast, **vars(args))
File "/usr/local/lib/python3.9/site-packages/slither/slither.py", line 118, in __init__
parser.parse_contracts()
File "/usr/local/lib/python3.9/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 489, in parse_contracts
self._analyze_third_part(contracts_to_be_analyzed, libraries)
File "/usr/local/lib/python3.9/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 596, in _analyze_third_part
self._analyze_variables_modifiers_functions(contract)
File "/usr/local/lib/python3.9/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 669, in _analyze_variables_modifiers_functions
contract.analyze_content_functions()
File "/usr/local/lib/python3.9/site-packages/slither/solc_parsing/declarations/contract.py", line 404, in analyze_content_functions
function_parser.analyze_content()
File "/usr/local/lib/python3.9/site-packages/slither/solc_parsing/declarations/function.py", line 310, in analyze_content
self._filter_ternary()
File "/usr/local/lib/python3.9/site-packages/slither/solc_parsing/declarations/function.py", line 1346, in _filter_ternary
st = SplitTernaryExpression(node.expression)
File "/usr/local/lib/python3.9/site-packages/slither/utils/expression_manipulations.py", line 53, in __init__
self.copy_expression(expression, self.true_expression, self.false_expression)
File "/usr/local/lib/python3.9/site-packages/slither/utils/expression_manipulations.py", line 113, in copy_expression
self.copy_expression(
File "/usr/local/lib/python3.9/site-packages/slither/utils/expression_manipulations.py", line 125, in copy_expression
self.copy_expression(next_expr, true_expression.called, false_expression.called)
File "/usr/local/lib/python3.9/site-packages/slither/utils/expression_manipulations.py", line 96, in copy_expression
self.copy_expression(
File "/usr/local/lib/python3.9/site-packages/slither/utils/expression_manipulations.py", line 149, in copy_expression
raise SlitherException(
slither.exceptions.SlitherException: Ternary operation not handled bytes(<class 'slither.core.expressions.elementary_type_name_expression.ElementaryTypeNameExpression'>)
Error:
Ternary operation not handled bytes(<class 'slither.core.expressions.elementary_type_name_expression.ElementaryTypeNameExpression'>)
Ah ok, turns out it was a bytes20 not a bytes. The expression format is below, where all params within the bytes20() cast are of type address
bytes20(x == y ? z : x)
Refactoring to a standard if/else block works as a workaround for now.
After fixing that I hit another ternary issue. The problematic expression was:
return myContract.myMethod{value: address1 == address2 ? myUint : 0}(/* irrelevant params */);
Pulling the ternary out of the braces and assigning to an intermediate uint resolved that one. Stack trace is below:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/slither/__main__.py", line 744, in main_impl
) = process_all(filename, args, detector_classes, printer_classes)
File "/usr/local/lib/python3.9/site-packages/slither/__main__.py", line 87, in process_all
) = process_single(compilation, args, detector_classes, printer_classes)
File "/usr/local/lib/python3.9/site-packages/slither/__main__.py", line 70, in process_single
slither = Slither(target, ast_format=ast, **vars(args))
File "/usr/local/lib/python3.9/site-packages/slither/slither.py", line 123, in __init__
parser.analyze_contracts()
File "/usr/local/lib/python3.9/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 496, in analyze_contracts
self._convert_to_slithir()
File "/usr/local/lib/python3.9/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 684, in _convert_to_slithir
func.generate_slithir_and_analyze()
File "/usr/local/lib/python3.9/site-packages/slither/core/declarations/function.py", line 1706, in generate_slithir_and_analyze
node.slithir_generation()
File "/usr/local/lib/python3.9/site-packages/slither/core/cfg/node.py", line 720, in slithir_generation
self._irs = convert_expression(expression, self)
File "/usr/local/lib/python3.9/site-packages/slither/slithir/convert.py", line 115, in convert_expression
visitor = ExpressionToSlithIR(expression, node)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/slithir/expression_to_slithir.py", line 140, in __init__
self._visit_expression(self.expression)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/expression/expression.py", line 51, in _visit_expression
self._visit_call_expression(expression)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/expression/expression.py", line 113, in _visit_call_expression
self._visit_expression(expression.call_value)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/expression/expression.py", line 95, in _visit_expression
self._post_visit(expression)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/expression/expression.py", line 274, in _post_visit
self._post_conditional_expression(expression)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/slithir/expression_to_slithir.py", line 353, in _post_conditional_expression
raise Exception(f"Ternary operator are not convertible to SlithIR {expression}")
Exception: Ternary operator are not convertible to SlithIR if _tokenIn == eth then _amount else 0
None
Error in .
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/slither/__main__.py", line 744, in main_impl
) = process_all(filename, args, detector_classes, printer_classes)
File "/usr/local/lib/python3.9/site-packages/slither/__main__.py", line 87, in process_all
) = process_single(compilation, args, detector_classes, printer_classes)
File "/usr/local/lib/python3.9/site-packages/slither/__main__.py", line 70, in process_single
slither = Slither(target, ast_format=ast, **vars(args))
File "/usr/local/lib/python3.9/site-packages/slither/slither.py", line 123, in __init__
parser.analyze_contracts()
File "/usr/local/lib/python3.9/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 496, in analyze_contracts
self._convert_to_slithir()
File "/usr/local/lib/python3.9/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 684, in _convert_to_slithir
func.generate_slithir_and_analyze()
File "/usr/local/lib/python3.9/site-packages/slither/core/declarations/function.py", line 1706, in generate_slithir_and_analyze
node.slithir_generation()
File "/usr/local/lib/python3.9/site-packages/slither/core/cfg/node.py", line 720, in slithir_generation
self._irs = convert_expression(expression, self)
File "/usr/local/lib/python3.9/site-packages/slither/slithir/convert.py", line 115, in convert_expression
visitor = ExpressionToSlithIR(expression, node)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/slithir/expression_to_slithir.py", line 140, in __init__
self._visit_expression(self.expression)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/expression/expression.py", line 51, in _visit_expression
self._visit_call_expression(expression)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/expression/expression.py", line 113, in _visit_call_expression
self._visit_expression(expression.call_value)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/expression/expression.py", line 95, in _visit_expression
self._post_visit(expression)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/expression/expression.py", line 274, in _post_visit
self._post_conditional_expression(expression)
File "/usr/local/lib/python3.9/site-packages/slither/visitors/slithir/expression_to_slithir.py", line 353, in _post_conditional_expression
raise Exception(f"Ternary operator are not convertible to SlithIR {expression}")
Exception: Ternary operator are not convertible to SlithIR if _tokenIn == eth then _amount else 0
I wasn't able to replicate an error on bytes20(x == y ? z : x). Do you have a full snippet I can use? (The call value ternary is not working for sure).
The repo is now public, so can link to the full codebase: here is the specific line.
That repo has changed a bit since I originally tried running slither against it in september, but slither . out of the box didn't work and led me to open a few issues here, so might be a good test case