We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[False Negative]: divide-before-multiply not found when in modifier
### What bug did Slither miss and which detector did you anticipate would catch it?

If a divide-before-multiply statement is added inside a modifier, the detector `divide-before-multiply` does not seem to be triggered.

### Frequency

Very Frequently

### Code example to reproduce the issue:

```
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.18;

contract Test {
    uint256 constant A_NUMBER = 10000;

    modifier checkDivideAndMultiply(uint256 a, uint256 b) {
        require((A_NUMBER / a) * b > 0, "fail");

        _;
    }

    function divideAndMultiplyMod(
        uint256 a,
        uint256 b
    ) public checkDivideAndMultiply(a, b) {}

    function divideAndMultiply(uint256 a, uint256 b) public returns (uint256) {
        return (A_NUMBER / a) * b;
    }
}
```

### Version:

0.10.0

### Relevant log output:

```shell
INFO:Detectors:
Test.divideAndMultiply(uint256,uint256) (contracts/Storage.sol#19-21) performs a multiplication on the result of a division:
        - (A_NUMBER / a) * b (contracts/Storage.sol#20)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply
INFO:Slither:. analyzed (1 contracts with 93 detectors), 1 result(s) found
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `slither/detectors/statements/divide_before_multiply.py`
Content:
```
1 """
2 Module detecting possible loss of precision due to divide before multiple
3 """
4 from collections import defaultdict
5 from typing import DefaultDict, List, Tuple
6 
7 from slither.core.cfg.node import Node
8 from slither.core.declarations.contract import Contract
9 from slither.core.declarations.function_contract import FunctionContract
10 from slither.detectors.abstract_detector import (
11     AbstractDetector,
12     DetectorClassification,
13     DETECTOR_INFO,
14 )
15 from slither.slithir.operations import Binary, Assignment, BinaryType, LibraryCall, Operation
16 from slither.slithir.utils.utils import LVALUE
17 from slither.slithir.variables import Constant
18 from slither.utils.output import Output
19 
20 
21 def is_division(ir: Operation) -> bool:
22     if isinstance(ir, Binary):
23         if ir.type == BinaryType.DIVISION:
24             return True
25 
26     if isinstance(ir, LibraryCall):
27         if ir.function.name and ir.function.name.lower() in [
28             "div",
29             "safediv",
30         ]:
31             if len(ir.arguments) == 2:
32                 if ir.lvalue:
33                     return True
34     return False
35 
36 
37 def is_multiplication(ir: Operation) -> bool:
38     if isinstance(ir, Binary):
39         if ir.type == BinaryType.MULTIPLICATION:
40             return True
41 
42     if isinstance(ir, LibraryCall):
43         if ir.function.name and ir.function.name.lower() in [
44             "mul",
45             "safemul",
46         ]:
47             if len(ir.arguments) == 2:
48                 if ir.lvalue:
49                     return True
50     return False
51 
52 
53 def is_assert(node: Node) -> bool:
54     if node.contains_require_or_assert():
55         return True
56     # Old Solidity code where using an internal 'assert(bool)' function
57     # While we dont check that this function is correct, we assume it is
58     # To avoid too many FP
59     if "assert(bool)" in [c.full_name for c in node.internal_calls]:
60         return True
61     return False
62 
63 
64 # pylint: disable=too-many-branches
65 def _explore(
66     to_explore: List[Node], f_results: List[List[Node]], divisions: DefaultDict[LVALUE, List[Node]]
67 ) -> None:
68     explored = set()
69     while to_explore:  # pylint: disable=too-many-nested-blocks
70         node = to_explore.pop()
71 
72         if node in explored:
73             continue
74         explored.add(node)
75 
76         equality_found = False
77         # List of nodes related to one bug instance
78         node_results: List[Node] = []
79 
80         for ir in node.irs:
81             if isinstance(ir, Assignment):
82                 if ir.rvalue in divisions:
83                     # Avoid dupplicate. We dont use set so we keep the order of the nodes
84                     if node not in divisions[ir.rvalue]:  # type: ignore
85                         divisions[ir.lvalue] = divisions[ir.rvalue] + [node]  # type: ignore
86                     else:
87                         divisions[ir.lvalue] = divisions[ir.rvalue]  # type: ignore
88 
89             if is_division(ir):
90                 divisions[ir.lvalue] = [node]  # type: ignore
91 
92             if is_multiplication(ir):
93                 mul_arguments = ir.read if isinstance(ir, Binary) else ir.arguments  # type: ignore
94                 nodes = []
95                 for r in mul_arguments:
96                     if not isinstance(r, Constant) and (r in divisions):
97                         # Dont add node already present to avoid dupplicate
98                         # We dont use set to keep the order of the nodes
99                         if node in divisions[r]:
100                             nodes += [n for n in divisions[r] if n not in nodes]
101                         else:
102                             nodes += [n for n in divisions[r] + [node] if n not in nodes]
103                 if nodes:
104                     node_results = nodes
105 
106             if isinstance(ir, Binary) and ir.type == BinaryType.EQUAL:
107                 equality_found = True
108 
109         if node_results:
110             # We do not track the case where the multiplication is done in a require() or assert()
111             # Which also contains a ==, to prevent FP due to the form
112             # assert(a == b * c + a % b)
113             if not (is_assert(node) and equality_found):
114                 f_results.append(node_results)
115 
116         for son in node.sons:
117             to_explore.append(son)
118 
119 
120 def detect_divide_before_multiply(
121     contract: Contract,
122 ) -> List[Tuple[FunctionContract, List[Node]]]:
123     """
124     Detects and returns all nodes with multiplications of division results.
125     :param contract: Contract to detect assignment within.
126     :return: A list of nodes with multiplications of divisions.
127     """
128 
129     # Create our result set.
130     # List of tuple (function -> list(list(nodes)))
131     # Each list(nodes) of the list is one bug instances
132     # Each node in the list(nodes) is involved in the bug
133     results: List[Tuple[FunctionContract, List[Node]]] = []
134 
135     # Loop for each function and modifier.
136     for function in contract.functions_declared:
137         if not function.entry_point:
138             continue
139 
140         # List of list(nodes)
141         # Each list(nodes) is one bug instances
142         f_results: List[List[Node]] = []
143 
144         # lvalue -> node
145         # track all the division results (and the assignment of the division results)
146         divisions: DefaultDict[LVALUE, List[Node]] = defaultdict(list)
147 
148         _explore([function.entry_point], f_results, divisions)
149 
150         for f_result in f_results:
151             results.append((function, f_result))
152 
153     # Return the resulting set of nodes with divisions before multiplications
154     return results
155 
156 
157 class DivideBeforeMultiply(AbstractDetector):
158     """
159     Divide before multiply
160     """
161 
162     ARGUMENT = "divide-before-multiply"
163     HELP = "Imprecise arithmetic operations order"
164     IMPACT = DetectorClassification.MEDIUM
165     CONFIDENCE = DetectorClassification.MEDIUM
166 
167     WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply"
168 
169     WIKI_TITLE = "Divide before multiply"
170     WIKI_DESCRIPTION = """Solidity's integer division truncates. Thus, performing division before multiplication can lead to precision loss."""
171 
172     # region wiki_exploit_scenario
173     WIKI_EXPLOIT_SCENARIO = """
174 ```solidity
175 contract A {
176 	function f(uint n) public {
177         coins = (oldSupply / n) * interest;
178     }
179 }
180 ```
181 If `n` is greater than `oldSupply`, `coins` will be zero. For example, with `oldSupply = 5; n = 10, interest = 2`, coins will be zero.  
182 If `(oldSupply * interest / n)` was used, `coins` would have been `1`.   
183 In general, it's usually a good idea to re-arrange arithmetic to perform multiplication before division, unless the limit of a smaller type makes this dangerous."""
184     # endregion wiki_exploit_scenario
185 
186     WIKI_RECOMMENDATION = """Consider ordering multiplication before division."""
187 
188     def _detect(self) -> List[Output]:
189         """
190         Detect divisions before multiplications
191         """
192         results = []
193         for contract in self.contracts:
194             divisions_before_multiplications = detect_divide_before_multiply(contract)
195             if divisions_before_multiplications:
196                 for (func, nodes) in divisions_before_multiplications:
197 
198                     info: DETECTOR_INFO = [
199                         func,
200                         " performs a multiplication on the result of a division:\n",
201                     ]
202 
203                     # sort the nodes to get deterministic results
204                     nodes.sort(key=lambda x: x.node_id)
205 
206                     for node in nodes:
207                         info += ["\t- ", node, "\n"]
208 
209                     res = self.generate_result(info)
210                     results.append(res)
211 
212         return results
213
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/slither/detectors/statements/divide_before_multiply.py b/slither/detectors/statements/divide_before_multiply.py
--- a/slither/detectors/statements/divide_before_multiply.py
+++ b/slither/detectors/statements/divide_before_multiply.py
@@ -133,7 +133,7 @@
     results: List[Tuple[FunctionContract, List[Node]]] = []
 
     # Loop for each function and modifier.
-    for function in contract.functions_declared:
+    for function in contract.functions_declared + contract.modifiers_declared:
         if not function.entry_point:
             continue

{"golden_diff": "diff --git a/slither/detectors/statements/divide_before_multiply.py b/slither/detectors/statements/divide_before_multiply.py\n--- a/slither/detectors/statements/divide_before_multiply.py\n+++ b/slither/detectors/statements/divide_before_multiply.py\n@@ -133,7 +133,7 @@\n     results: List[Tuple[FunctionContract, List[Node]]] = []\n \n     # Loop for each function and modifier.\n-    for function in contract.functions_declared:\n+    for function in contract.functions_declared + contract.modifiers_declared:\n         if not function.entry_point:\n             continue\n", "issue": "[False Negative]: divide-before-multiply not found when in modifier\n### What bug did Slither miss and which detector did you anticipate would catch it?\n\nIf a divide-before-multiply statement is added inside a modifier, the detector `divide-before-multiply` does not seem to be triggered.\n\n### Frequency\n\nVery Frequently\n\n### Code example to reproduce the issue:\n\n```\r\n// SPDX-License-Identifier: GPL-3.0\r\n\r\npragma solidity 0.8.18;\r\n\r\ncontract Test {\r\n    uint256 constant A_NUMBER = 10000;\r\n\r\n    modifier checkDivideAndMultiply(uint256 a, uint256 b) {\r\n        require((A_NUMBER / a) * b > 0, \"fail\");\r\n\r\n        _;\r\n    }\r\n\r\n    function divideAndMultiplyMod(\r\n        uint256 a,\r\n        uint256 b\r\n    ) public checkDivideAndMultiply(a, b) {}\r\n\r\n    function divideAndMultiply(uint256 a, uint256 b) public returns (uint256) {\r\n        return (A_NUMBER / a) * b;\r\n    }\r\n}\r\n```\n\n### Version:\n\n0.10.0\n\n### Relevant log output:\n\n```shell\nINFO:Detectors:\r\nTest.divideAndMultiply(uint256,uint256) (contracts/Storage.sol#19-21) performs a multiplication on the result of a division:\r\n        - (A_NUMBER / a) * b (contracts/Storage.sol#20)\r\nReference: https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply\r\nINFO:Slither:. analyzed (1 contracts with 93 detectors), 1 result(s) found\n```\n\n", "before_files": [{"content": "\"\"\"\nModule detecting possible loss of precision due to divide before multiple\n\"\"\"\nfrom collections import defaultdict\nfrom typing import DefaultDict, List, Tuple\n\nfrom slither.core.cfg.node import Node\nfrom slither.core.declarations.contract import Contract\nfrom slither.core.declarations.function_contract import FunctionContract\nfrom slither.detectors.abstract_detector import (\n    AbstractDetector,\n    DetectorClassification,\n    DETECTOR_INFO,\n)\nfrom slither.slithir.operations import Binary, Assignment, BinaryType, LibraryCall, Operation\nfrom slither.slithir.utils.utils import LVALUE\nfrom slither.slithir.variables import Constant\nfrom slither.utils.output import Output\n\n\ndef is_division(ir: Operation) -> bool:\n    if isinstance(ir, Binary):\n        if ir.type == BinaryType.DIVISION:\n            return True\n\n    if isinstance(ir, LibraryCall):\n        if ir.function.name and ir.function.name.lower() in [\n            \"div\",\n            \"safediv\",\n        ]:\n            if len(ir.arguments) == 2:\n                if ir.lvalue:\n                    return True\n    return False\n\n\ndef is_multiplication(ir: Operation) -> bool:\n    if isinstance(ir, Binary):\n        if ir.type == BinaryType.MULTIPLICATION:\n            return True\n\n    if isinstance(ir, LibraryCall):\n        if ir.function.name and ir.function.name.lower() in [\n            \"mul\",\n            \"safemul\",\n        ]:\n            if len(ir.arguments) == 2:\n                if ir.lvalue:\n                    return True\n    return False\n\n\ndef is_assert(node: Node) -> bool:\n    if node.contains_require_or_assert():\n        return True\n    # Old Solidity code where using an internal 'assert(bool)' function\n    # While we dont check that this function is correct, we assume it is\n    # To avoid too many FP\n    if \"assert(bool)\" in [c.full_name for c in node.internal_calls]:\n        return True\n    return False\n\n\n# pylint: disable=too-many-branches\ndef _explore(\n    to_explore: List[Node], f_results: List[List[Node]], divisions: DefaultDict[LVALUE, List[Node]]\n) -> None:\n    explored = set()\n    while to_explore:  # pylint: disable=too-many-nested-blocks\n        node = to_explore.pop()\n\n        if node in explored:\n            continue\n        explored.add(node)\n\n        equality_found = False\n        # List of nodes related to one bug instance\n        node_results: List[Node] = []\n\n        for ir in node.irs:\n            if isinstance(ir, Assignment):\n                if ir.rvalue in divisions:\n                    # Avoid dupplicate. We dont use set so we keep the order of the nodes\n                    if node not in divisions[ir.rvalue]:  # type: ignore\n                        divisions[ir.lvalue] = divisions[ir.rvalue] + [node]  # type: ignore\n                    else:\n                        divisions[ir.lvalue] = divisions[ir.rvalue]  # type: ignore\n\n            if is_division(ir):\n                divisions[ir.lvalue] = [node]  # type: ignore\n\n            if is_multiplication(ir):\n                mul_arguments = ir.read if isinstance(ir, Binary) else ir.arguments  # type: ignore\n                nodes = []\n                for r in mul_arguments:\n                    if not isinstance(r, Constant) and (r in divisions):\n                        # Dont add node already present to avoid dupplicate\n                        # We dont use set to keep the order of the nodes\n                        if node in divisions[r]:\n                            nodes += [n for n in divisions[r] if n not in nodes]\n                        else:\n                            nodes += [n for n in divisions[r] + [node] if n not in nodes]\n                if nodes:\n                    node_results = nodes\n\n            if isinstance(ir, Binary) and ir.type == BinaryType.EQUAL:\n                equality_found = True\n\n        if node_results:\n            # We do not track the case where the multiplication is done in a require() or assert()\n            # Which also contains a ==, to prevent FP due to the form\n            # assert(a == b * c + a % b)\n            if not (is_assert(node) and equality_found):\n                f_results.append(node_results)\n\n        for son in node.sons:\n            to_explore.append(son)\n\n\ndef detect_divide_before_multiply(\n    contract: Contract,\n) -> List[Tuple[FunctionContract, List[Node]]]:\n    \"\"\"\n    Detects and returns all nodes with multiplications of division results.\n    :param contract: Contract to detect assignment within.\n    :return: A list of nodes with multiplications of divisions.\n    \"\"\"\n\n    # Create our result set.\n    # List of tuple (function -> list(list(nodes)))\n    # Each list(nodes) of the list is one bug instances\n    # Each node in the list(nodes) is involved in the bug\n    results: List[Tuple[FunctionContract, List[Node]]] = []\n\n    # Loop for each function and modifier.\n    for function in contract.functions_declared:\n        if not function.entry_point:\n            continue\n\n        # List of list(nodes)\n        # Each list(nodes) is one bug instances\n        f_results: List[List[Node]] = []\n\n        # lvalue -> node\n        # track all the division results (and the assignment of the division results)\n        divisions: DefaultDict[LVALUE, List[Node]] = defaultdict(list)\n\n        _explore([function.entry_point], f_results, divisions)\n\n        for f_result in f_results:\n            results.append((function, f_result))\n\n    # Return the resulting set of nodes with divisions before multiplications\n    return results\n\n\nclass DivideBeforeMultiply(AbstractDetector):\n    \"\"\"\n    Divide before multiply\n    \"\"\"\n\n    ARGUMENT = \"divide-before-multiply\"\n    HELP = \"Imprecise arithmetic operations order\"\n    IMPACT = DetectorClassification.MEDIUM\n    CONFIDENCE = DetectorClassification.MEDIUM\n\n    WIKI = \"https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply\"\n\n    WIKI_TITLE = \"Divide before multiply\"\n    WIKI_DESCRIPTION = \"\"\"Solidity's integer division truncates. Thus, performing division before multiplication can lead to precision loss.\"\"\"\n\n    # region wiki_exploit_scenario\n    WIKI_EXPLOIT_SCENARIO = \"\"\"\n```solidity\ncontract A {\n\tfunction f(uint n) public {\n        coins = (oldSupply / n) * interest;\n    }\n}\n```\nIf `n` is greater than `oldSupply`, `coins` will be zero. For example, with `oldSupply = 5; n = 10, interest = 2`, coins will be zero.  \nIf `(oldSupply * interest / n)` was used, `coins` would have been `1`.   \nIn general, it's usually a good idea to re-arrange arithmetic to perform multiplication before division, unless the limit of a smaller type makes this dangerous.\"\"\"\n    # endregion wiki_exploit_scenario\n\n    WIKI_RECOMMENDATION = \"\"\"Consider ordering multiplication before division.\"\"\"\n\n    def _detect(self) -> List[Output]:\n        \"\"\"\n        Detect divisions before multiplications\n        \"\"\"\n        results = []\n        for contract in self.contracts:\n            divisions_before_multiplications = detect_divide_before_multiply(contract)\n            if divisions_before_multiplications:\n                for (func, nodes) in divisions_before_multiplications:\n\n                    info: DETECTOR_INFO = [\n                        func,\n                        \" performs a multiplication on the result of a division:\\n\",\n                    ]\n\n                    # sort the nodes to get deterministic results\n                    nodes.sort(key=lambda x: x.node_id)\n\n                    for node in nodes:\n                        info += [\"\\t- \", node, \"\\n\"]\n\n                    res = self.generate_result(info)\n                    results.append(res)\n\n        return results\n", "path": "slither/detectors/statements/divide_before_multiply.py"}], "after_files": [{"content": "\"\"\"\nModule detecting possible loss of precision due to divide before multiple\n\"\"\"\nfrom collections import defaultdict\nfrom typing import DefaultDict, List, Tuple\n\nfrom slither.core.cfg.node import Node\nfrom slither.core.declarations.contract import Contract\nfrom slither.core.declarations.function_contract import FunctionContract\nfrom slither.detectors.abstract_detector import (\n    AbstractDetector,\n    DetectorClassification,\n    DETECTOR_INFO,\n)\nfrom slither.slithir.operations import Binary, Assignment, BinaryType, LibraryCall, Operation\nfrom slither.slithir.utils.utils import LVALUE\nfrom slither.slithir.variables import Constant\nfrom slither.utils.output import Output\n\n\ndef is_division(ir: Operation) -> bool:\n    if isinstance(ir, Binary):\n        if ir.type == BinaryType.DIVISION:\n            return True\n\n    if isinstance(ir, LibraryCall):\n        if ir.function.name and ir.function.name.lower() in [\n            \"div\",\n            \"safediv\",\n        ]:\n            if len(ir.arguments) == 2:\n                if ir.lvalue:\n                    return True\n    return False\n\n\ndef is_multiplication(ir: Operation) -> bool:\n    if isinstance(ir, Binary):\n        if ir.type == BinaryType.MULTIPLICATION:\n            return True\n\n    if isinstance(ir, LibraryCall):\n        if ir.function.name and ir.function.name.lower() in [\n            \"mul\",\n            \"safemul\",\n        ]:\n            if len(ir.arguments) == 2:\n                if ir.lvalue:\n                    return True\n    return False\n\n\ndef is_assert(node: Node) -> bool:\n    if node.contains_require_or_assert():\n        return True\n    # Old Solidity code where using an internal 'assert(bool)' function\n    # While we dont check that this function is correct, we assume it is\n    # To avoid too many FP\n    if \"assert(bool)\" in [c.full_name for c in node.internal_calls]:\n        return True\n    return False\n\n\n# pylint: disable=too-many-branches\ndef _explore(\n    to_explore: List[Node], f_results: List[List[Node]], divisions: DefaultDict[LVALUE, List[Node]]\n) -> None:\n    explored = set()\n    while to_explore:  # pylint: disable=too-many-nested-blocks\n        node = to_explore.pop()\n\n        if node in explored:\n            continue\n        explored.add(node)\n\n        equality_found = False\n        # List of nodes related to one bug instance\n        node_results: List[Node] = []\n\n        for ir in node.irs:\n            if isinstance(ir, Assignment):\n                if ir.rvalue in divisions:\n                    # Avoid dupplicate. We dont use set so we keep the order of the nodes\n                    if node not in divisions[ir.rvalue]:  # type: ignore\n                        divisions[ir.lvalue] = divisions[ir.rvalue] + [node]  # type: ignore\n                    else:\n                        divisions[ir.lvalue] = divisions[ir.rvalue]  # type: ignore\n\n            if is_division(ir):\n                divisions[ir.lvalue] = [node]  # type: ignore\n\n            if is_multiplication(ir):\n                mul_arguments = ir.read if isinstance(ir, Binary) else ir.arguments  # type: ignore\n                nodes = []\n                for r in mul_arguments:\n                    if not isinstance(r, Constant) and (r in divisions):\n                        # Dont add node already present to avoid dupplicate\n                        # We dont use set to keep the order of the nodes\n                        if node in divisions[r]:\n                            nodes += [n for n in divisions[r] if n not in nodes]\n                        else:\n                            nodes += [n for n in divisions[r] + [node] if n not in nodes]\n                if nodes:\n                    node_results = nodes\n\n            if isinstance(ir, Binary) and ir.type == BinaryType.EQUAL:\n                equality_found = True\n\n        if node_results:\n            # We do not track the case where the multiplication is done in a require() or assert()\n            # Which also contains a ==, to prevent FP due to the form\n            # assert(a == b * c + a % b)\n            if not (is_assert(node) and equality_found):\n                f_results.append(node_results)\n\n        for son in node.sons:\n            to_explore.append(son)\n\n\ndef detect_divide_before_multiply(\n    contract: Contract,\n) -> List[Tuple[FunctionContract, List[Node]]]:\n    \"\"\"\n    Detects and returns all nodes with multiplications of division results.\n    :param contract: Contract to detect assignment within.\n    :return: A list of nodes with multiplications of divisions.\n    \"\"\"\n\n    # Create our result set.\n    # List of tuple (function -> list(list(nodes)))\n    # Each list(nodes) of the list is one bug instances\n    # Each node in the list(nodes) is involved in the bug\n    results: List[Tuple[FunctionContract, List[Node]]] = []\n\n    # Loop for each function and modifier.\n    for function in contract.functions_declared + contract.modifiers_declared:\n        if not function.entry_point:\n            continue\n\n        # List of list(nodes)\n        # Each list(nodes) is one bug instances\n        f_results: List[List[Node]] = []\n\n        # lvalue -> node\n        # track all the division results (and the assignment of the division results)\n        divisions: DefaultDict[LVALUE, List[Node]] = defaultdict(list)\n\n        _explore([function.entry_point], f_results, divisions)\n\n        for f_result in f_results:\n            results.append((function, f_result))\n\n    # Return the resulting set of nodes with divisions before multiplications\n    return results\n\n\nclass DivideBeforeMultiply(AbstractDetector):\n    \"\"\"\n    Divide before multiply\n    \"\"\"\n\n    ARGUMENT = \"divide-before-multiply\"\n    HELP = \"Imprecise arithmetic operations order\"\n    IMPACT = DetectorClassification.MEDIUM\n    CONFIDENCE = DetectorClassification.MEDIUM\n\n    WIKI = \"https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply\"\n\n    WIKI_TITLE = \"Divide before multiply\"\n    WIKI_DESCRIPTION = \"\"\"Solidity's integer division truncates. Thus, performing division before multiplication can lead to precision loss.\"\"\"\n\n    # region wiki_exploit_scenario\n    WIKI_EXPLOIT_SCENARIO = \"\"\"\n```solidity\ncontract A {\n\tfunction f(uint n) public {\n        coins = (oldSupply / n) * interest;\n    }\n}\n```\nIf `n` is greater than `oldSupply`, `coins` will be zero. For example, with `oldSupply = 5; n = 10, interest = 2`, coins will be zero.  \nIf `(oldSupply * interest / n)` was used, `coins` would have been `1`.   \nIn general, it's usually a good idea to re-arrange arithmetic to perform multiplication before division, unless the limit of a smaller type makes this dangerous.\"\"\"\n    # endregion wiki_exploit_scenario\n\n    WIKI_RECOMMENDATION = \"\"\"Consider ordering multiplication before division.\"\"\"\n\n    def _detect(self) -> List[Output]:\n        \"\"\"\n        Detect divisions before multiplications\n        \"\"\"\n        results = []\n        for contract in self.contracts:\n            divisions_before_multiplications = detect_divide_before_multiply(contract)\n            if divisions_before_multiplications:\n                for (func, nodes) in divisions_before_multiplications:\n\n                    info: DETECTOR_INFO = [\n                        func,\n                        \" performs a multiplication on the result of a division:\\n\",\n                    ]\n\n                    # sort the nodes to get deterministic results\n                    nodes.sort(key=lambda x: x.node_id)\n\n                    for node in nodes:\n                        info += [\"\\t- \", node, \"\\n\"]\n\n                    res = self.generate_result(info)\n                    results.append(res)\n\n        return results\n", "path": "slither/detectors/statements/divide_before_multiply.py"}]}