Skip to content

[Bug-Candidate]: Slither analysis fails on structs containing a balance field #2793

@0xPhantom2

Description

@0xPhantom2

Describe the issue:

When running Slither on the project, the analysis fails if a struct contains a field named balance and this field is used.

Code example to reproduce the issue:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

struct Account {
   address owner;
    uint256 balance;
}

using AccountLib for Account global;

library AccountLib {

    function pay(Account storage self, uint256 amount) internal {
        if (amount == 0) return;
        self.balance += amount;
    }
}

Version:

0.11.3

Relevant log output:

ERROR:SlitherSolcParsing:
Failed to generate IR for AccountLib.pay. Please open an issue https://github.com/crytic/slither/issues.
AccountLib.pay (src/Counter.sol#13-16):
        amount == 0
        self.balance += amount
Traceback (most recent call last):
  File "/opt/homebrew/bin/slither", line 8, in <module>
    sys.exit(main())
             ~~~~^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/__main__.py", line 776, in main
    main_impl(all_detector_classes=detectors, all_printer_classes=printers)
    ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/__main__.py", line 882, in main_impl
    ) = process_all(filename, args, detector_classes, printer_classes)
        ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/__main__.py", line 107, in process_all
    ) = process_single(compilation, args, detector_classes, printer_classes)
        ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/__main__.py", line 80, in process_single
    slither = Slither(target, ast_format=ast, **vars(args))
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/slither.py", line 202, in __init__
    self._init_parsing_and_analyses(kwargs.get("skip_analyze", False))
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/slither.py", line 221, in _init_parsing_and_analyses
    raise e
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/slither.py", line 217, in _init_parsing_and_analyses
    parser.analyze_contracts()
    ~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 593, in analyze_contracts
    self._convert_to_slithir()
    ~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 828, in _convert_to_slithir
    raise e
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/solc_parsing/slither_compilation_unit_solc.py", line 813, in _convert_to_slithir
    func.generate_slithir_and_analyze()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/core/declarations/function.py", line 1878, in generate_slithir_and_analyze
    node.slithir_generation()
    ~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/core/cfg/node.py", line 706, in slithir_generation
    self._irs = convert_expression(expression, self)  # type:ignore
                ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/slithir/convert.py", line 114, in convert_expression
    visitor = ExpressionToSlithIR(expression, node)
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/visitors/slithir/expression_to_slithir.py", line 174, in __init__
    self._visit_expression(self.expression)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/visitors/expression/expression.py", line 78, in _visit_expression
    self._post_visit(expression)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/visitors/expression/expression.py", line 252, in _post_visit
    self._post_assignement_operation(expression)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/visitors/slithir/expression_to_slithir.py", line 275, in _post_assignement_operation
    operation = convert_assignment(
        left, right, expression.type, expression.expression_return_type
    )
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/visitors/slithir/expression_to_slithir.py", line 152, in convert_assignment
    return Binary(left, left, right, BinaryType.ADDITION)
  File "/opt/homebrew/Cellar/slither-analyzer/0.11.3_3/libexec/lib/python3.13/site-packages/slither/slithir/operations/binary.py", line 113, in __init__
    assert is_valid_lvalue(result)
           ~~~~~~~~~~~~~~~^^^^^^^^
AssertionError

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug-candidateBugs reports that are not yet confirmed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions