Merge branch 'dev' into ssa-copy

pull/1488/head
alpharush 2 years ago
commit e77b36c8c8
  1. 5
      scripts/ci_test_dapp.sh
  2. 3
      setup.py
  3. 45
      slither/__main__.py
  4. 35
      slither/core/declarations/contract.py
  5. 48
      slither/core/declarations/function.py
  6. 66
      slither/core/slither_core.py
  7. 33
      slither/detectors/abstract_detector.py
  8. 1
      slither/detectors/all_detectors.py
  9. 10
      slither/detectors/attributes/const_functions_asm.py
  10. 10
      slither/detectors/attributes/const_functions_state.py
  11. 29
      slither/detectors/compiler_bugs/enum_conversion.py
  12. 16
      slither/detectors/compiler_bugs/public_mapping_nested.py
  13. 12
      slither/detectors/compiler_bugs/reused_base_constructor.py
  14. 44
      slither/detectors/compiler_bugs/storage_ABIEncoderV2_array.py
  15. 45
      slither/detectors/compiler_bugs/storage_signed_integer_array.py
  16. 45
      slither/detectors/compiler_bugs/uninitialized_function_ptr_in_constructor.py
  17. 2
      slither/detectors/erc/erc20/arbitrary_send_erc20_no_permit.py
  18. 2
      slither/detectors/erc/erc20/arbitrary_send_erc20_permit.py
  19. 136
      slither/detectors/functions/codex.py
  20. 21
      slither/detectors/functions/external_function.py
  21. 2
      slither/detectors/functions/protected_variable.py
  22. 61
      slither/detectors/reentrancy/reentrancy.py
  23. 31
      slither/detectors/reentrancy/reentrancy_eth.py
  24. 2
      slither/detectors/reentrancy/reentrancy_events.py
  25. 32
      slither/detectors/reentrancy/reentrancy_read_before_write.py
  26. 12
      slither/detectors/statements/array_length_assignment.py
  27. 2
      slither/detectors/statements/divide_before_multiply.py
  28. 2
      slither/printers/summary/function_ids.py
  29. 8
      slither/slither.py
  30. 53
      slither/utils/codex.py
  31. 6
      slither/utils/command_line.py
  32. 8
      slither/utils/function.py
  33. 19
      tests/detectors/protected-vars/0.8.2/comment.sol
  34. 183
      tests/detectors/protected-vars/0.8.2/comment.sol.0.8.2.ProtectedVariables.json
  35. 1782
      tests/detectors/reentrancy-eth/0.4.25/DAO.sol.0.4.25.ReentrancyEth.json
  36. 190
      tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol.0.4.25.ReentrancyEth.json
  37. 6
      tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol.0.4.25.ReentrancyEth.json
  38. 222
      tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol.0.5.16.ReentrancyEth.json
  39. 6
      tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol.0.5.16.ReentrancyEth.json
  40. 222
      tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol.0.6.11.ReentrancyEth.json
  41. 6
      tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol.0.6.11.ReentrancyEth.json
  42. 12
      tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol.0.7.6.ReentrancyEth.json
  43. 6
      tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol.0.7.6.ReentrancyEth.json
  44. 22
      tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol
  45. 231
      tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol.0.8.10.ReentrancyEth.json
  46. 151
      tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol
  47. 981
      tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol.0.8.10.ReentrancyEth.json
  48. 9454
      tests/detectors/reentrancy-no-eth/0.4.25/DAO.sol.0.4.25.ReentrancyReadBeforeWritten.json
  49. 354
      tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol.0.4.25.ReentrancyReadBeforeWritten.json
  50. 12
      tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol.0.5.16.ReentrancyReadBeforeWritten.json
  51. 12
      tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol.0.6.11.ReentrancyReadBeforeWritten.json
  52. 352
      tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol.0.7.6.ReentrancyReadBeforeWritten.json
  53. 505
      tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol.0.5.10.StorageSignedIntegerArray.json
  54. 4
      tests/test_detectors.py
  55. 17
      tests/test_function.py
  56. 36
      tests/test_function_reentrant.sol

@ -2,6 +2,11 @@
### Test Dapp integration
# work around having two python versions loading libraries from each other in CI
OLD_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
alias crytic-compile='LD_LIBRARY_PATH=$OLD_LD_LIBRARY_PATH crytic-compile'
unset LD_LIBRARY_PATH
mkdir test_dapp
cd test_dapp || exit 255
# The dapp init process makes a temporary local git repo and needs certain values to be set

@ -13,7 +13,7 @@ setup(
python_requires=">=3.8",
install_requires=[
"prettytable>=0.7.2",
"pysha3>=1.0.2",
"pycryptodome>=3.4.6",
"crytic-compile>=0.2.4",
# "crytic-compile@git+https://github.com/crytic/crytic-compile.git@master#egg=crytic-compile",
],
@ -26,6 +26,7 @@ setup(
"deepdiff",
"numpy",
"solc-select>=v1.0.0b1",
"openai",
]
},
license="AGPL-3.0",

@ -166,7 +166,6 @@ def process_from_asts(
def get_detectors_and_printers() -> Tuple[
List[Type[AbstractDetector]], List[Type[AbstractPrinter]]
]:
detectors_ = [getattr(all_detectors, name) for name in dir(all_detectors)]
detectors = [d for d in detectors_ if inspect.isclass(d) and issubclass(d, AbstractDetector)]
@ -286,7 +285,6 @@ def parse_filter_paths(args: argparse.Namespace) -> List[str]:
def parse_args(
detector_classes: List[Type[AbstractDetector]], printer_classes: List[Type[AbstractPrinter]]
) -> argparse.Namespace:
usage = "slither target [flag]\n"
usage += "\ntarget can be:\n"
usage += "\t- file.sol // a Solidity file\n"
@ -316,6 +314,7 @@ def parse_args(
"Checklist (consider using https://github.com/crytic/slither-action)"
)
group_misc = parser.add_argument_group("Additional options")
group_codex = parser.add_argument_group("Codex (https://beta.openai.com/docs/guides/code)")
group_detector.add_argument(
"--detect",
@ -556,6 +555,48 @@ def parse_args(
default=False,
)
group_codex.add_argument(
"--codex",
help="Enable codex (require an OpenAI API Key)",
action="store_true",
default=defaults_flag_in_config["codex"],
)
group_codex.add_argument(
"--codex-log",
help="Log codex queries (in crytic_export/codex/)",
action="store_true",
default=False,
)
group_codex.add_argument(
"--codex-contracts",
help="Comma separated list of contracts to submit to OpenAI Codex",
action="store",
default=defaults_flag_in_config["codex_contracts"],
)
group_codex.add_argument(
"--codex-model",
help="Name of the Codex model to use (affects pricing). Defaults to 'text-davinci-003'",
action="store",
default=defaults_flag_in_config["codex_model"],
)
group_codex.add_argument(
"--codex-temperature",
help="Temperature to use with Codex. Lower number indicates a more precise answer while higher numbers return more creative answers. Defaults to 0",
action="store",
default=defaults_flag_in_config["codex_temperature"],
)
group_codex.add_argument(
"--codex-max-tokens",
help="Maximum amount of tokens to use on the response. This number plus the size of the prompt can be no larger than the limit (4097 for text-davinci-003)",
action="store",
default=defaults_flag_in_config["codex_max_tokens"],
)
# debugger command
parser.add_argument("--debug", help=argparse.SUPPRESS, action="store_true", default=False)

@ -2,8 +2,9 @@
Contract module
"""
import logging
from collections import defaultdict
from pathlib import Path
from typing import Optional, List, Dict, Callable, Tuple, TYPE_CHECKING, Union
from typing import Optional, List, Dict, Callable, Tuple, TYPE_CHECKING, Union, Set
from crytic_compile.platform import Type as PlatformType
@ -100,6 +101,11 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
self.compilation_unit: "SlitherCompilationUnit" = compilation_unit
self.file_scope: "FileScope" = scope
# memoize
self._state_variables_used_in_reentrant_targets: Optional[
Dict["StateVariable", Set[Union["StateVariable", "Function"]]]
] = None
###################################################################################
###################################################################################
# region General's properties
@ -356,6 +362,33 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
slithir_variables = [item for sublist in slithir_variabless for item in sublist]
return list(set(slithir_variables))
@property
def state_variables_used_in_reentrant_targets(
self,
) -> Dict["StateVariable", Set[Union["StateVariable", "Function"]]]:
"""
Returns the state variables used in reentrant targets. Heuristics:
- Variable used (read/write) in entry points that are reentrant
- State variables that are public
"""
from slither.core.variables.state_variable import StateVariable
if self._state_variables_used_in_reentrant_targets is None:
reentrant_functions = [f for f in self.functions_entry_points if f.is_reentrant]
variables_used: Dict[
StateVariable, Set[Union[StateVariable, "Function"]]
] = defaultdict(set)
for function in reentrant_functions:
for ir in function.all_slithir_operations():
state_variables = [v for v in ir.used if isinstance(v, StateVariable)]
for state_variable in state_variables:
variables_used[state_variable].add(ir.node.function)
for variable in [v for v in self.state_variables if v.visibility == "public"]:
variables_used[variable].add(variable)
self._state_variables_used_in_reentrant_targets = variables_used
return self._state_variables_used_in_reentrant_targets
# endregion
###################################################################################
###################################################################################

@ -189,7 +189,8 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
# set(ReacheableNode)
self._reachable_from_nodes: Set[ReacheableNode] = set()
self._reachable_from_functions: Set[ReacheableNode] = set()
self._reachable_from_functions: Set[Function] = set()
self._all_reachable_from_functions: Optional[Set[Function]] = None
# Constructor, fallback, State variable constructor
self._function_type: Optional[FunctionType] = None
@ -214,7 +215,7 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
self.compilation_unit: "SlitherCompilationUnit" = compilation_unit
# Assume we are analyzing Solidty by default
# Assume we are analyzing Solidity by default
self.function_language: FunctionLanguage = FunctionLanguage.Solidity
self._id: Optional[str] = None
@ -1029,9 +1030,30 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
return self._reachable_from_nodes
@property
def reachable_from_functions(self) -> Set[ReacheableNode]:
def reachable_from_functions(self) -> Set["Function"]:
return self._reachable_from_functions
@property
def all_reachable_from_functions(self) -> Set["Function"]:
"""
Give the recursive version of reachable_from_functions (all the functions that lead to call self in the CFG)
"""
if self._all_reachable_from_functions is None:
functions: Set["Function"] = set()
new_functions = self.reachable_from_functions
# iterate until we have are finding new functions
while new_functions and not new_functions.issubset(functions):
functions = functions.union(new_functions)
# Use a temporary set, because we iterate over new_functions
new_functionss: Set["Function"] = set()
for f in new_functions:
new_functionss = new_functionss.union(f.reachable_from_functions)
new_functions = new_functionss - functions
self._all_reachable_from_functions = functions
return self._all_reachable_from_functions
def add_reachable_from_node(self, n: "Node", ir: "Operation"):
self._reachable_from_nodes.add(ReacheableNode(n, ir))
self._reachable_from_functions.add(n.function)
@ -1460,6 +1482,26 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
)
return self._is_protected
@property
def is_reentrant(self) -> bool:
"""
Determine if the function can be re-entered
"""
# TODO: compare with hash of known nonReentrant modifier instead of the name
if "nonReentrant" in [m.name for m in self.modifiers]:
return False
if self.visibility in ["public", "external"]:
return True
# If it's an internal function, check if all its entry points have the nonReentrant modifier
all_entry_points = [
f for f in self.all_reachable_from_functions if f.visibility in ["public", "external"]
]
if not all_entry_points:
return True
return not all(("nonReentrant" in [m.name for m in f.modifiers] for f in all_entry_points))
# endregion
###################################################################################
###################################################################################

@ -71,6 +71,12 @@ class SlitherCore(Context):
self._show_ignored_findings = False
# Maps from file to detector name to the start/end ranges for that detector.
# Infinity is used to signal a detector has no end range.
self._ignore_ranges: defaultdict[str, defaultdict[str, List[(int, int)]]] = defaultdict(
lambda: defaultdict(lambda: [])
)
self._compilation_units: List[SlitherCompilationUnit] = []
self._contracts: List[Contract] = []
@ -151,7 +157,7 @@ class SlitherCore(Context):
def filename(self, filename: str):
self._filename = filename
def add_source_code(self, path):
def add_source_code(self, path: str) -> None:
"""
:param path:
:return:
@ -162,6 +168,8 @@ class SlitherCore(Context):
with open(path, encoding="utf8", newline="") as f:
self.source_code[path] = f.read()
self.parse_ignore_comments(path)
@property
def markdown_root(self) -> str:
return self._markdown_root
@ -284,9 +292,52 @@ class SlitherCore(Context):
###################################################################################
###################################################################################
def parse_ignore_comments(self, file: str) -> None:
# The first time we check a file, find all start/end ignore comments and memoize them.
line_number = 1
while True:
line_text = self.crytic_compile.get_code_from_line(file, line_number)
if line_text is None:
break
start_regex = r"^\s*//\s*slither-disable-start\s*([a-zA-Z0-9_,-]*)"
end_regex = r"^\s*//\s*slither-disable-end\s*([a-zA-Z0-9_,-]*)"
start_match = re.findall(start_regex, line_text.decode("utf8"))
end_match = re.findall(end_regex, line_text.decode("utf8"))
if start_match:
ignored = start_match[0].split(",")
if ignored:
for check in ignored:
vals = self._ignore_ranges[file][check]
if len(vals) == 0 or vals[-1][1] != float("inf"):
# First item in the array, or the prior item is fully populated.
self._ignore_ranges[file][check].append((line_number, float("inf")))
else:
logger.error(
f"Consecutive slither-disable-starts without slither-disable-end in {file}#{line_number}"
)
return
if end_match:
ignored = end_match[0].split(",")
if ignored:
for check in ignored:
vals = self._ignore_ranges[file][check]
if len(vals) == 0 or vals[-1][1] != float("inf"):
logger.error(
f"slither-disable-end without slither-disable-start in {file}#{line_number}"
)
return
self._ignore_ranges[file][check][-1] = (vals[-1][0], line_number)
line_number += 1
def has_ignore_comment(self, r: Dict) -> bool:
"""
Check if the result has an ignore comment on the proceeding line, in which case, it is not valid
Check if the result has an ignore comment in the file or on the preceding line, in which
case, it is not valid
"""
if not self.crytic_compile:
return False
@ -303,6 +354,15 @@ class SlitherCore(Context):
)
for file, lines in mapping_elements_with_lines:
# Check if result is within an ignored range.
ignore_ranges = self._ignore_ranges[file][r["check"]] + self._ignore_ranges[file]["all"]
for start, end in ignore_ranges:
# The full check must be within the ignore range to be ignored.
if start < lines[0] and end > lines[-1]:
return True
# Check for next-line matchers.
ignore_line_index = min(lines) - 1
ignore_line_text = self.crytic_compile.get_code_from_line(file, ignore_line_index)
if ignore_line_text:
@ -324,7 +384,7 @@ class SlitherCore(Context):
- All its source paths belong to the source path filtered
- Or a similar result was reported and saved during a previous run
- The --exclude-dependencies flag is set and results are only related to dependencies
- There is an ignore comment on the preceding line
- There is an ignore comment on the preceding line or in the file
"""
# Remove duplicate due to the multiple compilation support

@ -46,6 +46,20 @@ classification_txt = {
}
def make_solc_versions(minor: int, patch_min: int, patch_max: int) -> List[str]:
"""
Create a list of solc version: [0.minor.patch_min .... 0.minor.patch_max]
"""
return [f"0.{minor}.{x}" for x in range(patch_min, patch_max + 1)]
ALL_SOLC_VERSIONS_04 = make_solc_versions(4, 0, 26)
ALL_SOLC_VERSIONS_05 = make_solc_versions(5, 0, 17)
ALL_SOLC_VERSIONS_06 = make_solc_versions(6, 0, 12)
ALL_SOLC_VERSIONS_07 = make_solc_versions(7, 0, 6)
# No VERSIONS_08 as it is still in dev
class AbstractDetector(metaclass=abc.ABCMeta):
ARGUMENT = "" # run the detector with slither.py --ARGUMENT
HELP = "" # help information
@ -61,6 +75,10 @@ class AbstractDetector(metaclass=abc.ABCMeta):
STANDARD_JSON = True
# list of vulnerable solc versions as strings (e.g. ["0.4.25", "0.5.0"])
# If the detector is meant to run on all versions, use None
VULNERABLE_SOLC_VERSIONS: Optional[List[str]] = None
def __init__(
self, compilation_unit: SlitherCompilationUnit, slither: "Slither", logger: Logger
):
@ -108,6 +126,11 @@ class AbstractDetector(metaclass=abc.ABCMeta):
f"WIKI_RECOMMENDATION is not initialized {self.__class__.__name__}"
)
if self.VULNERABLE_SOLC_VERSIONS is not None and not self.VULNERABLE_SOLC_VERSIONS:
raise IncorrectDetectorInitialization(
f"VULNERABLE_SOLC_VERSIONS should not be an empty list {self.__class__.__name__}"
)
if re.match("^[a-zA-Z0-9_-]*$", self.ARGUMENT) is None:
raise IncorrectDetectorInitialization(
f"ARGUMENT has illegal character {self.__class__.__name__}"
@ -139,6 +162,11 @@ class AbstractDetector(metaclass=abc.ABCMeta):
if self.logger:
self.logger.info(self.color(info))
def _uses_vulnerable_solc_version(self) -> bool:
if self.VULNERABLE_SOLC_VERSIONS:
return self.compilation_unit.solc_version in self.VULNERABLE_SOLC_VERSIONS
return True
@abc.abstractmethod
def _detect(self) -> List[Output]:
"""TODO Documentation"""
@ -147,6 +175,11 @@ class AbstractDetector(metaclass=abc.ABCMeta):
# pylint: disable=too-many-branches
def detect(self) -> List[Dict]:
results: List[Dict] = []
# check solc version
if not self._uses_vulnerable_solc_version():
return results
# only keep valid result, and remove duplicate
# Keep only dictionaries
for r in [output.data for output in self._detect()]:

@ -85,3 +85,4 @@ from .statements.msg_value_in_loop import MsgValueInLoop
from .statements.delegatecall_in_loop import DelegatecallInLoop
from .functions.protected_variable import ProtectedVariables
from .functions.permit_domain_signature_collision import DomainSeparatorCollision
from .functions.codex import Codex

@ -2,7 +2,11 @@
Module detecting constant functions
Recursively check the called functions
"""
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
ALL_SOLC_VERSIONS_04,
)
from slither.formatters.attributes.const_functions import custom_format
@ -49,6 +53,8 @@ All the calls to `get` revert, breaking Bob's smart contract execution."""
"Ensure the attributes of contracts compiled prior to Solidity 0.5.0 are correct."
)
VULNERABLE_SOLC_VERSIONS = ALL_SOLC_VERSIONS_04
def _detect(self):
"""Detect the constant function using assembly code
@ -57,8 +63,6 @@ All the calls to `get` revert, breaking Bob's smart contract execution."""
list: {'vuln', 'filename,'contract','func','#varsWritten'}
"""
results = []
if self.compilation_unit.solc_version and self.compilation_unit.solc_version >= "0.5.0":
return results
for c in self.contracts:
for f in c.functions:
if f.contract_declarer != c:

@ -2,7 +2,11 @@
Module detecting constant functions
Recursively check the called functions
"""
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
ALL_SOLC_VERSIONS_04,
)
from slither.formatters.attributes.const_functions import custom_format
@ -49,6 +53,8 @@ All the calls to `get` revert, breaking Bob's smart contract execution."""
"Ensure that attributes of contracts compiled prior to Solidity 0.5.0 are correct."
)
VULNERABLE_SOLC_VERSIONS = ALL_SOLC_VERSIONS_04
def _detect(self):
"""Detect the constant function changing the state
@ -57,8 +63,6 @@ All the calls to `get` revert, breaking Bob's smart contract execution."""
list: {'vuln', 'filename,'contract','func','#varsWritten'}
"""
results = []
if self.compilation_unit.solc_version and self.compilation_unit.solc_version >= "0.5.0":
return results
for c in self.contracts:
for f in c.functions:
if f.contract_declarer != c:

@ -2,23 +2,15 @@
Module detecting dangerous conversion to enum
"""
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
make_solc_versions,
)
from slither.slithir.operations import TypeConversion
from slither.core.declarations.enum import Enum
def _uses_vulnerable_solc_version(version):
"""Detect if used compiler version is 0.4.[0|1|2|3|4]
Args:
version (solc version used)
Returns:
Bool
"""
if version in ["0.4.0", "0.4.1", "0.4.2", "0.4.3", "0.4.4"]:
return True
return False
def _detect_dangerous_enum_conversions(contract):
"""Detect dangerous conversion to enum by checking IR
Args:
@ -54,11 +46,11 @@ class EnumConversion(AbstractDetector):
```solidity
pragma solidity 0.4.2;
contract Test{
enum E{a}
function bug(uint a) public returns(E){
return E(a);
return E(a);
}
}
```
@ -67,12 +59,11 @@ Attackers can trigger unexpected behaviour by calling `bug(1)`."""
WIKI_RECOMMENDATION = "Use a recent compiler version. If `solc` <`0.4.5` is required, check the `enum` conversion range."
VULNERABLE_SOLC_VERSIONS = make_solc_versions(4, 0, 4)
def _detect(self):
"""Detect dangerous conversion to enum"""
results = []
# If solc version >= 0.4.5 then return
if not _uses_vulnerable_solc_version(self.compilation_unit.solc_version):
return results
for c in self.compilation_unit.contracts:
ret = _detect_dangerous_enum_conversions(c)

@ -2,7 +2,11 @@
Module detecting public mappings with nested variables (returns incorrect values prior to 0.5.x)
"""
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
ALL_SOLC_VERSIONS_04,
)
from slither.core.solidity_types.mapping_type import MappingType
from slither.core.solidity_types.user_defined_type import UserDefinedType
from slither.core.declarations.structure import Structure
@ -62,6 +66,8 @@ class PublicMappingNested(AbstractDetector):
WIKI_EXPLOIT_SCENARIO = """Bob interacts with a contract that has a public mapping with nested structures. The values returned by the mapping are incorrect, breaking Bob's usage"""
WIKI_RECOMMENDATION = "Do not use public mapping with nested structures."
VULNERABLE_SOLC_VERSIONS = ALL_SOLC_VERSIONS_04
def _detect(self):
"""
Detect public mappings with nested variables (returns incorrect values prior to 0.5.x)
@ -72,14 +78,6 @@ class PublicMappingNested(AbstractDetector):
"""
results = []
if self.compilation_unit.solc_version >= "0.5.0":
return []
if self.compilation_unit.solc_version and self.compilation_unit.solc_version.startswith(
"0.5."
):
return []
for contract in self.contracts:
public_nested_mappings = detect_public_nested_mappings(contract)
if public_nested_mappings:

@ -2,7 +2,11 @@
Module detecting re-used base constructors in inheritance hierarchy.
"""
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
ALL_SOLC_VERSIONS_04,
)
# Helper: adds explicitly called constructors with arguments to the results lookup.
@ -71,6 +75,8 @@ The constructor of `A` is called multiple times in `D` and `E`:
WIKI_RECOMMENDATION = "Remove the duplicate constructor call."
VULNERABLE_SOLC_VERSIONS = ALL_SOLC_VERSIONS_04
def _detect_explicitly_called_base_constructors(self, contract):
"""
Detects explicitly calls to base constructors with arguments in the inheritance hierarchy.
@ -126,10 +132,6 @@ The constructor of `A` is called multiple times in `D` and `E`:
results = []
# The bug is not possible with solc >= 0.5.0
if not self.compilation_unit.solc_version.startswith("0.4."):
return []
# Loop for each contract
for contract in self.contracts:

@ -2,7 +2,11 @@
Module detecting ABIEncoderV2 array bug
"""
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
make_solc_versions,
)
from slither.core.solidity_types import ArrayType
from slither.core.solidity_types import UserDefinedType
from slither.core.variables.local_variable import LocalVariable
@ -13,38 +17,6 @@ from slither.slithir.operations import EventCall
from slither.slithir.operations import HighLevelCall
from slither.utils.utils import unroll
vulnerable_solc_versions = [
"0.4.7",
"0.4.8",
"0.4.9",
"0.4.10",
"0.4.11",
"0.4.12",
"0.4.13",
"0.4.14",
"0.4.15",
"0.4.16",
"0.4.17",
"0.4.18",
"0.4.19",
"0.4.20",
"0.4.21",
"0.4.22",
"0.4.23",
"0.4.24",
"0.4.25",
"0.5.0",
"0.5.1",
"0.5.2",
"0.5.3",
"0.5.4",
"0.5.5",
"0.5.6",
"0.5.7",
"0.5.8",
"0.5.9",
]
class ABIEncoderV2Array(AbstractDetector):
"""
@ -80,6 +52,8 @@ contract A {
WIKI_RECOMMENDATION = "Use a compiler >= `0.5.10`."
VULNERABLE_SOLC_VERSIONS = make_solc_versions(4, 7, 25) + make_solc_versions(5, 0, 9)
@staticmethod
def _detect_storage_abiencoderv2_arrays(contract):
"""
@ -130,10 +104,6 @@ contract A {
"""
results = []
# Check if vulnerable solc versions are used
if self.compilation_unit.solc_version not in vulnerable_solc_versions:
return results
# Check if pragma experimental ABIEncoderV2 is used
if not any(
(p.directive[0] == "experimental" and p.directive[1] == "ABIEncoderV2")

@ -2,7 +2,11 @@
Module detecting storage signed integer array bug
"""
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
make_solc_versions,
)
from slither.core.cfg.node import NodeType
from slither.core.solidity_types import ArrayType
from slither.core.solidity_types.elementary_type import Int, ElementaryType
@ -11,39 +15,6 @@ from slither.core.variables.state_variable import StateVariable
from slither.slithir.operations.assignment import Assignment
from slither.slithir.operations.init_array import InitArray
vulnerable_solc_versions = [
"0.4.7",
"0.4.8",
"0.4.9",
"0.4.10",
"0.4.11",
"0.4.12",
"0.4.13",
"0.4.14",
"0.4.15",
"0.4.16",
"0.4.17",
"0.4.18",
"0.4.19",
"0.4.20",
"0.4.21",
"0.4.22",
"0.4.23",
"0.4.24",
"0.4.25",
"0.5.0",
"0.5.1",
"0.5.2",
"0.5.3",
"0.5.4",
"0.5.5",
"0.5.6",
"0.5.7",
"0.5.8",
"0.5.9",
"0.5.10",
]
class StorageSignedIntegerArray(AbstractDetector):
"""
@ -61,7 +32,7 @@ class StorageSignedIntegerArray(AbstractDetector):
WIKI_TITLE = "Storage Signed Integer Array"
# region wiki_description
WIKI_DESCRIPTION = """`solc` versions `0.4.7`-`0.5.10` contain [a compiler bug](https://blog.ethereum.org/2019/06/25/solidity-storage-array-bugs)
WIKI_DESCRIPTION = """`solc` versions `0.4.7`-`0.5.9` contain [a compiler bug](https://blog.ethereum.org/2019/06/25/solidity-storage-array-bugs)
leading to incorrect values in signed integer arrays."""
# endregion wiki_description
@ -84,6 +55,8 @@ contract A {
WIKI_RECOMMENDATION = "Use a compiler version >= `0.5.10`."
VULNERABLE_SOLC_VERSIONS = make_solc_versions(4, 7, 25) + make_solc_versions(5, 0, 9)
@staticmethod
def _is_vulnerable_type(ir):
"""
@ -140,8 +113,6 @@ contract A {
Detect storage signed integer array init/assignment
"""
results = []
if self.compilation_unit.solc_version not in vulnerable_solc_versions:
return results
for contract in self.contracts:
storage_signed_integer_arrays = self.detect_storage_signed_integer_arrays(contract)
for function, node in storage_signed_integer_arrays:

@ -2,44 +2,15 @@
Module detecting uninitialized function pointer calls in constructors
"""
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
make_solc_versions,
)
from slither.slithir.operations import InternalDynamicCall, OperationWithLValue
from slither.slithir.variables import ReferenceVariable
from slither.slithir.variables.variable import SlithIRVariable
vulnerable_solc_versions = [
"0.4.5",
"0.4.6",
"0.4.7",
"0.4.8",
"0.4.9",
"0.4.10",
"0.4.11",
"0.4.12",
"0.4.13",
"0.4.14",
"0.4.15",
"0.4.16",
"0.4.17",
"0.4.18",
"0.4.19",
"0.4.20",
"0.4.21",
"0.4.22",
"0.4.23",
"0.4.24",
"0.4.25",
"0.5.0",
"0.5.1",
"0.5.2",
"0.5.3",
"0.5.4",
"0.5.5",
"0.5.6",
"0.5.7",
"0.5.8",
]
def _get_variables_entrance(function):
"""
@ -110,6 +81,8 @@ The call to `a(10)` will lead to unexpected behavior because function pointer `a
"Initialize function pointers before calling. Avoid function pointers if possible."
)
VULNERABLE_SOLC_VERSIONS = make_solc_versions(4, 5, 25) + make_solc_versions(5, 0, 8)
@staticmethod
def _detect_uninitialized_function_ptr_in_constructor(contract):
"""
@ -134,10 +107,6 @@ The call to `a(10)` will lead to unexpected behavior because function pointer `a
"""
results = []
# Check if vulnerable solc versions are used
if self.compilation_unit.solc_version not in vulnerable_solc_versions:
return results
for contract in self.compilation_unit.contracts:
contract_info = ["Contract ", contract, " \n"]
nodes = self._detect_uninitialized_function_ptr_in_constructor(contract)

@ -14,7 +14,7 @@ class ArbitrarySendErc20NoPermit(AbstractDetector):
IMPACT = DetectorClassification.HIGH
CONFIDENCE = DetectorClassification.HIGH
WIKI = "https://github.com/trailofbits/slither/wiki/Detector-Documentation#arbitrary-send-erc20"
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#arbitrary-from-in-transferfrom"
WIKI_TITLE = "Arbitrary `from` in transferFrom"
WIKI_DESCRIPTION = "Detect when `msg.sender` is not used as `from` in transferFrom."

@ -14,7 +14,7 @@ class ArbitrarySendErc20Permit(AbstractDetector):
IMPACT = DetectorClassification.HIGH
CONFIDENCE = DetectorClassification.MEDIUM
WIKI = "https://github.com/trailofbits/slither/wiki/Detector-Documentation#arbitrary-send-erc20-permit"
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#arbitrary-from-in-transferfrom-used-with-permit"
WIKI_TITLE = "Arbitrary `from` in transferFrom used with permit"
WIKI_DESCRIPTION = (

@ -0,0 +1,136 @@
import logging
import uuid
from typing import List, Union
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.utils import codex
from slither.utils.output import Output, SupportedOutput
logger = logging.getLogger("Slither")
VULN_FOUND = "VULN_FOUND"
class Codex(AbstractDetector):
"""
Use codex to detect vulnerability
"""
ARGUMENT = "codex"
HELP = "Use Codex to find vulnerabilities."
IMPACT = DetectorClassification.HIGH
CONFIDENCE = DetectorClassification.LOW
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#codex"
WIKI_TITLE = "Codex"
WIKI_DESCRIPTION = "Use [codex](https://openai.com/blog/openai-codex/) to find vulnerabilities"
# region wiki_exploit_scenario
WIKI_EXPLOIT_SCENARIO = """N/A"""
# endregion wiki_exploit_scenario
WIKI_RECOMMENDATION = "Review codex's message."
def _run_codex(self, logging_file: str, prompt: str) -> str:
"""
Handle the codex logic
Args:
logging_file (str): file where to log the queries
prompt (str): prompt to send to codex
Returns:
codex answer (str)
"""
openai_module = codex.openai_module() # type: ignore
if openai_module is None:
return ""
if self.slither.codex_log:
codex.log_codex(logging_file, "Q: " + prompt)
answer = ""
res = {}
try:
res = openai_module.Completion.create(
prompt=prompt,
model=self.slither.codex_model,
temperature=self.slither.codex_temperature,
max_tokens=self.slither.codex_max_tokens,
)
except Exception as e: # pylint: disable=broad-except
logger.info("OpenAI request failed: " + str(e))
# """ OpenAI completion response shape example:
# {
# "choices": [
# {
# "finish_reason": "stop",
# "index": 0,
# "logprobs": null,
# "text": "VULNERABILITIES:. The withdraw() function does not check..."
# }
# ],
# "created": 1670357537,
# "id": "cmpl-6KYaXdA6QIisHlTMM7RCJ1nR5wTKx",
# "model": "text-davinci-003",
# "object": "text_completion",
# "usage": {
# "completion_tokens": 80,
# "prompt_tokens": 249,
# "total_tokens": 329
# }
# } """
if res:
if self.slither.codex_log:
codex.log_codex(logging_file, "A: " + str(res))
else:
codex.log_codex(logging_file, "A: Codex failed")
if res.get("choices", []) and VULN_FOUND in res["choices"][0].get("text", ""):
# remove VULN_FOUND keyword and cleanup
answer = (
res["choices"][0]["text"]
.replace(VULN_FOUND, "")
.replace("\n", "")
.replace(": ", "")
)
return answer
def _detect(self) -> List[Output]:
results: List[Output] = []
if not self.slither.codex_enabled:
return []
logging_file = str(uuid.uuid4())
for contract in self.compilation_unit.contracts:
if (
self.slither.codex_contracts != "all"
and contract.name not in self.slither.codex_contracts.split(",")
):
continue
prompt = f"Analyze this Solidity contract and find the vulnerabilities. If you find any vulnerabilities, begin the response with {VULN_FOUND}\n"
src_mapping = contract.source_mapping
content = contract.compilation_unit.core.source_code[src_mapping.filename.absolute]
start = src_mapping.start
end = src_mapping.start + src_mapping.length
prompt += content[start:end]
answer = self._run_codex(logging_file, prompt)
if answer:
info: List[Union[str, SupportedOutput]] = [
"Codex detected a potential bug in ",
contract,
"\n",
answer,
"\n",
]
new_result = self.generate_result(info)
results.append(new_result)
return results

@ -5,7 +5,13 @@ from slither.core.declarations.structure import Structure
from slither.core.solidity_types.array_type import ArrayType
from slither.core.solidity_types.user_defined_type import UserDefinedType
from slither.core.variables.variable import Variable
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
ALL_SOLC_VERSIONS_04,
ALL_SOLC_VERSIONS_05,
make_solc_versions,
)
from slither.formatters.functions.external_function import custom_format
from slither.slithir.operations import InternalCall, InternalDynamicCall
from slither.slithir.operations import SolidityCall
@ -31,6 +37,10 @@ class ExternalFunction(AbstractDetector):
WIKI_DESCRIPTION = "`public` functions that are never called by the contract should be declared `external`, and its immutable parameters should be located in `calldata` to save gas."
WIKI_RECOMMENDATION = "Use the `external` attribute for functions never called from the contract, and change the location of immutable parameters to `calldata` to save gas."
VULNERABLE_SOLC_VERSIONS = (
ALL_SOLC_VERSIONS_04 + ALL_SOLC_VERSIONS_05 + make_solc_versions(6, 0, 8)
)
@staticmethod
def detect_functions_called(contract: Contract) -> List[Function]:
"""Returns a list of InternallCall, SolidityCall
@ -134,15 +144,6 @@ class ExternalFunction(AbstractDetector):
def _detect(self) -> List[Output]: # pylint: disable=too-many-locals,too-many-branches
results: List[Output] = []
# After solc 0.6.9, calldata arguments are allowed in public functions
if self.compilation_unit.solc_version >= "0.7." or self.compilation_unit.solc_version in [
"0.6.9",
"0.6.10",
"0.6.11",
"0.6.12",
]:
return results
# Create a set to track contracts with dynamic calls. All contracts with dynamic calls could potentially be
# calling functions internally, and thus we can't assume any function in such contracts isn't called by them.
dynamic_call_contracts: Set[Contract] = set()

@ -48,7 +48,7 @@ contract Buggy{
def _analyze_function(self, function: Function, contract: Contract) -> List[Output]:
results = []
for state_variable_written in function.state_variables_written:
for state_variable_written in function.all_state_variables_written():
if state_variable_written.write_protection:
for function_sig in state_variable_written.write_protection:
function_protection = contract.get_function_from_signature(function_sig)

@ -5,31 +5,32 @@
Iterate over all the nodes of the graph until reaching a fixpoint
"""
from collections import defaultdict
from typing import Set, Dict, Union
from typing import Set, Dict, List, Tuple, Optional
from slither.core.cfg.node import NodeType, Node
from slither.core.declarations import Function
from slither.core.declarations import Function, Contract
from slither.core.expressions import UnaryOperation, UnaryOperationType
from slither.core.variables.variable import Variable
from slither.detectors.abstract_detector import AbstractDetector
from slither.slithir.operations import Call, EventCall
from slither.slithir.operations import Call, EventCall, Operation
from slither.utils.output import Output
def union_dict(d1, d2):
def union_dict(d1: Dict, d2: Dict) -> Dict:
d3 = {k: d1.get(k, set()) | d2.get(k, set()) for k in set(list(d1.keys()) + list(d2.keys()))}
return defaultdict(set, d3)
def dict_are_equal(d1, d2):
def dict_are_equal(d1: Dict, d2: Dict) -> bool:
if set(list(d1.keys())) != set(list(d2.keys())):
return False
return all(set(d1[k]) == set(d2[k]) for k in d1.keys())
def is_subset(
new_info: Dict[Union[Variable, Node], Set[Node]],
old_info: Dict[Union[Variable, Node], Set[Node]],
):
new_info: Dict,
old_info: Dict,
) -> bool:
for k in new_info.keys():
if k not in old_info:
return False
@ -38,7 +39,7 @@ def is_subset(
return True
def to_hashable(d: Dict[Node, Set[Node]]):
def to_hashable(d: Dict[Node, Set[Node]]) -> Tuple:
list_tuple = list(
tuple((k, tuple(sorted(values, key=lambda x: x.node_id)))) for k, values in d.items()
)
@ -46,7 +47,7 @@ def to_hashable(d: Dict[Node, Set[Node]]):
class AbstractState:
def __init__(self):
def __init__(self) -> None:
# send_eth returns the list of calls sending value
# calls returns the list of calls that can callback
# read returns the variable read
@ -106,7 +107,9 @@ class AbstractState:
"""
return self._events
def merge_fathers(self, node, skip_father, detector):
def merge_fathers(
self, node: Node, skip_father: Optional[Node], detector: "Reentrancy"
) -> None:
for father in node.fathers:
if detector.KEY in father.context:
self._send_eth = union_dict(
@ -131,7 +134,7 @@ class AbstractState:
father.context[detector.KEY].reads_prior_calls,
)
def analyze_node(self, node, detector):
def analyze_node(self, node: Node, detector: "Reentrancy") -> bool:
state_vars_read: Dict[Variable, Set[Node]] = defaultdict(
set, {v: {node} for v in node.state_variables_read}
)
@ -175,13 +178,13 @@ class AbstractState:
return contains_call
def add(self, fathers):
def add(self, fathers: "AbstractState") -> None:
self._send_eth = union_dict(self._send_eth, fathers.send_eth)
self._calls = union_dict(self._calls, fathers.calls)
self._reads = union_dict(self._reads, fathers.reads)
self._reads_prior_calls = union_dict(self._reads_prior_calls, fathers.reads_prior_calls)
def does_not_bring_new_info(self, new_info):
def does_not_bring_new_info(self, new_info: "AbstractState") -> bool:
if is_subset(new_info.calls, self.calls):
if is_subset(new_info.send_eth, self.send_eth):
if is_subset(new_info.reads, self.reads):
@ -190,7 +193,7 @@ class AbstractState:
return False
def _filter_if(node):
def _filter_if(node: Node) -> bool:
"""
Check if the node is a condtional node where
there is an external call checked
@ -201,10 +204,8 @@ def _filter_if(node):
This will work only on naive implementation
"""
return (
isinstance(node.expression, UnaryOperation)
and node.expression.type == UnaryOperationType.BANG
)
expression = node.expression
return isinstance(expression, UnaryOperation) and expression.type == UnaryOperationType.BANG
class Reentrancy(AbstractDetector):
@ -214,7 +215,7 @@ class Reentrancy(AbstractDetector):
# allowing inherited classes to define different behaviors
# For example reentrancy_no_gas consider Send and Transfer as reentrant functions
@staticmethod
def can_callback(ir):
def can_callback(ir: Operation) -> bool:
"""
Detect if the node contains a call that can
be used to re-entrance
@ -228,13 +229,13 @@ class Reentrancy(AbstractDetector):
return isinstance(ir, Call) and ir.can_reenter()
@staticmethod
def can_send_eth(ir):
def can_send_eth(ir: Operation) -> bool:
"""
Detect if the node can send eth
"""
return isinstance(ir, Call) and ir.can_send_eth()
def _explore(self, node, visited, skip_father=None):
def _explore(self, node: Optional[Node], skip_father: Optional[Node] = None) -> None:
"""
Explore the CFG and look for re-entrancy
Heuristic: There is a re-entrancy if a state variable is written
@ -245,11 +246,9 @@ class Reentrancy(AbstractDetector):
if node.context is not empty, and variables are written, a re-entrancy is possible
"""
if node in visited:
if node is None:
return
visited = visited + [node]
fathers_context = AbstractState()
fathers_context.merge_fathers(node, skip_father, self)
@ -271,26 +270,26 @@ class Reentrancy(AbstractDetector):
if contains_call and node.type in [NodeType.IF, NodeType.IFLOOP]:
if _filter_if(node):
son = sons[0]
self._explore(son, visited, node)
self._explore(son, skip_father=node)
sons = sons[1:]
else:
son = sons[1]
self._explore(son, visited, node)
self._explore(son, skip_father=node)
sons = [sons[0]]
for son in sons:
self._explore(son, visited)
self._explore(son)
def detect_reentrancy(self, contract):
def detect_reentrancy(self, contract: Contract) -> None:
for function in contract.functions_and_modifiers_declared:
if not function.is_constructor:
if function.is_implemented:
if self.KEY in function.context:
continue
self._explore(function.entry_point, [])
self._explore(function.entry_point)
function.context[self.KEY] = True
def _detect(self):
def _detect(self) -> List[Output]:
""""""
# if a node was already visited by another path
# we will only explore it if the traversal brings

@ -5,13 +5,14 @@
Iterate over all the nodes of the graph until reaching a fixpoint
"""
from collections import namedtuple, defaultdict
from typing import List
from typing import List, Dict, Set
from slither.detectors.abstract_detector import DetectorClassification
from .reentrancy import Reentrancy, to_hashable
from ...utils.output import Output
FindingKey = namedtuple("FindingKey", ["function", "calls", "send_eth"])
FindingValue = namedtuple("FindingValue", ["variable", "node", "nodes"])
FindingValue = namedtuple("FindingValue", ["variable", "node", "nodes", "cross_functions"])
class ReentrancyEth(Reentrancy):
@ -52,9 +53,10 @@ Bob uses the re-entrancy bug to call `withdrawBalance` two times, and withdraw m
STANDARD_JSON = False
def find_reentrancies(self):
result = defaultdict(set)
def find_reentrancies(self) -> Dict[FindingKey, Set[FindingValue]]:
result: Dict[FindingKey, Set[FindingValue]] = defaultdict(set)
for contract in self.contracts: # pylint: disable=too-many-nested-blocks
variables_used_in_reentrancy = contract.state_variables_used_in_reentrant_targets
for f in contract.functions_and_modifiers_declared:
for node in f.nodes:
# dead code
@ -72,9 +74,15 @@ Bob uses the re-entrancy bug to call `withdrawBalance` two times, and withdraw m
v,
node,
tuple(sorted(nodes, key=lambda x: x.node_id)),
tuple(
sorted(
variables_used_in_reentrancy[v], key=lambda x: str(x)
)
),
)
for (v, nodes) in node.context[self.KEY].written.items()
if v in node.context[self.KEY].reads_prior_calls[c]
and (f.is_reentrant or v in variables_used_in_reentrancy)
}
if read_then_written:
@ -88,7 +96,7 @@ Bob uses the re-entrancy bug to call `withdrawBalance` two times, and withdraw m
result[finding_key] |= set(read_then_written)
return result
def _detect(self): # pylint: disable=too-many-branches
def _detect(self) -> List[Output]: # pylint: disable=too-many-branches,too-many-locals
""""""
super()._detect()
@ -98,10 +106,11 @@ Bob uses the re-entrancy bug to call `withdrawBalance` two times, and withdraw m
result_sorted = sorted(list(reentrancies.items()), key=lambda x: x[0].function.name)
varsWritten: List[FindingValue]
for (func, calls, send_eth), varsWritten in result_sorted:
varsWrittenSet: Set[FindingValue]
for (func, calls, send_eth), varsWrittenSet in result_sorted:
calls = sorted(list(set(calls)), key=lambda x: x[0].node_id)
send_eth = sorted(list(set(send_eth)), key=lambda x: x[0].node_id)
varsWritten = sorted(varsWritten, key=lambda x: (x.variable.name, x.node.node_id))
varsWritten = sorted(varsWrittenSet, key=lambda x: (x.variable.name, x.node.node_id))
info = ["Reentrancy in ", func, ":\n"]
info += ["\tExternal calls:\n"]
@ -123,6 +132,14 @@ Bob uses the re-entrancy bug to call `withdrawBalance` two times, and withdraw m
for other_node in finding_value.nodes:
if other_node != finding_value.node:
info += ["\t\t- ", other_node, "\n"]
if finding_value.cross_functions:
info += [
"\t",
finding_value.variable,
" can be used in cross function reentrancies:\n",
]
for cross in finding_value.cross_functions:
info += ["\t- ", cross, "\n"]
# Create our JSON result
res = self.generate_result(info)

@ -52,6 +52,8 @@ If `d.()` re-enters, the `Counter` events will be shown in an incorrect order, w
result = defaultdict(set)
for contract in self.contracts:
for f in contract.functions_and_modifiers_declared:
if not f.is_reentrant:
continue
for node in f.nodes:
# dead code
if self.KEY not in node.context:

@ -5,12 +5,14 @@
Iterate over all the nodes of the graph until reaching a fixpoint
"""
from collections import namedtuple, defaultdict
from typing import Dict, Set, List
from slither.detectors.abstract_detector import DetectorClassification
from .reentrancy import Reentrancy, to_hashable
from ...utils.output import Output
FindingKey = namedtuple("FindingKey", ["function", "calls"])
FindingValue = namedtuple("FindingValue", ["variable", "node", "nodes"])
FindingValue = namedtuple("FindingValue", ["variable", "node", "nodes", "cross_functions"])
class ReentrancyReadBeforeWritten(Reentrancy):
@ -49,9 +51,11 @@ Do not report reentrancies that involve Ether (see `reentrancy-eth`)."""
STANDARD_JSON = False
def find_reentrancies(self):
result = defaultdict(set)
# pylint: disable=too-many-locals
def find_reentrancies(self) -> Dict[FindingKey, Set[FindingValue]]:
result: Dict[FindingKey, Set[FindingValue]] = defaultdict(set)
for contract in self.contracts: # pylint: disable=too-many-nested-blocks
variables_used_in_reentrancy = contract.state_variables_used_in_reentrant_targets
for f in contract.functions_and_modifiers_declared:
for node in f.nodes:
# dead code
@ -67,9 +71,15 @@ Do not report reentrancies that involve Ether (see `reentrancy-eth`)."""
v,
node,
tuple(sorted(nodes, key=lambda x: x.node_id)),
tuple(
sorted(
variables_used_in_reentrancy[v], key=lambda x: str(x)
)
),
)
for (v, nodes) in node.context[self.KEY].written.items()
if v in node.context[self.KEY].reads_prior_calls[c]
and (f.is_reentrant or v in variables_used_in_reentrancy)
}
# We found a potential re-entrancy bug
@ -82,7 +92,7 @@ Do not report reentrancies that involve Ether (see `reentrancy-eth`)."""
result[finding_key] |= read_then_written
return result
def _detect(self): # pylint: disable=too-many-branches
def _detect(self) -> List[Output]: # pylint: disable=too-many-branches
""""""
super()._detect()
@ -91,9 +101,11 @@ Do not report reentrancies that involve Ether (see `reentrancy-eth`)."""
results = []
result_sorted = sorted(list(reentrancies.items()), key=lambda x: x[0].function.name)
for (func, calls), varsWritten in result_sorted:
varsWritten: List[FindingValue]
varsWrittenSet: Set[FindingValue]
for (func, calls), varsWrittenSet in result_sorted:
calls = sorted(list(set(calls)), key=lambda x: x[0].node_id)
varsWritten = sorted(varsWritten, key=lambda x: (x.variable.name, x.node.node_id))
varsWritten = sorted(varsWrittenSet, key=lambda x: (x.variable.name, x.node.node_id))
info = ["Reentrancy in ", func, ":\n"]
@ -109,6 +121,14 @@ Do not report reentrancies that involve Ether (see `reentrancy-eth`)."""
for other_node in finding_value.nodes:
if other_node != finding_value.node:
info += ["\t\t- ", other_node, "\n"]
if finding_value.cross_functions:
info += [
"\t",
finding_value.variable,
" can be used in cross function reentrancies:\n",
]
for cross in finding_value.cross_functions:
info += ["\t- ", cross, "\n"]
# Create our JSON result
res = self.generate_result(info)

@ -2,7 +2,12 @@
Module detecting assignment of array length
"""
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
ALL_SOLC_VERSIONS_04,
ALL_SOLC_VERSIONS_05,
)
from slither.core.cfg.node import NodeType
from slither.slithir.operations import Assignment, Length
from slither.slithir.variables.reference import ReferenceVariable
@ -103,14 +108,13 @@ Note that storage slots here are indexed via a hash of the indexers; nonetheless
Otherwise, thoroughly review the contract to ensure a user-controlled variable cannot reach an array length assignment."""
# endregion wiki_recommendation
VULNERABLE_SOLC_VERSIONS = ALL_SOLC_VERSIONS_04 + ALL_SOLC_VERSIONS_05
def _detect(self):
"""
Detect array length assignments
"""
results = []
# Starting from 0.6 .length is read only
if self.compilation_unit.solc_version >= "0.6.":
return results
for contract in self.contracts:
array_length_assignments = detect_array_length_assignment(contract)
if array_length_assignments:

@ -152,7 +152,7 @@ class DivideBeforeMultiply(AbstractDetector):
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply"
WIKI_TITLE = "Divide before multiply"
WIKI_DESCRIPTION = """Solidity integer division might truncate. As a result, performing multiplication before division can sometimes avoid loss of precision."""
WIKI_DESCRIPTION = """Solidity's integer division truncates. Thus, performing division before multiplication can lead to precision loss."""
# region wiki_exploit_scenario
WIKI_EXPLOIT_SCENARIO = """

@ -9,7 +9,7 @@ from slither.utils.myprettytable import MyPrettyTable
class FunctionIds(AbstractPrinter):
ARGUMENT = "function-id"
HELP = "Print the keccack256 signature of the functions"
HELP = "Print the keccak256 signature of the functions"
WIKI = "https://github.com/trailofbits/slither/wiki/Printer-documentation#function-id"

@ -83,6 +83,14 @@ class Slither(SlitherCore): # pylint: disable=too-many-instance-attributes
self.line_prefix = kwargs.get("change_line_prefix", "#")
# Indicate if Codex related features should be used
self.codex_enabled = kwargs.get("codex", False)
self.codex_contracts = kwargs.get("codex_contracts", "all")
self.codex_model = kwargs.get("codex_model", "text-davinci-003")
self.codex_temperature = kwargs.get("codex_temperature", 0)
self.codex_max_tokens = kwargs.get("codex_max_tokens", 300)
self.codex_log = kwargs.get("codex_log", False)
self._parsers: List[SlitherCompilationUnitSolc] = []
try:
if isinstance(target, CryticCompile):

@ -0,0 +1,53 @@
import logging
import os
from pathlib import Path
logger = logging.getLogger("Slither")
# TODO: investigate how to set the correct return type
# So that the other modules can work with openai
def openai_module(): # type: ignore
"""
Return the openai module
Consider checking the usage of open (slither.codex_enabled) before using this function
Returns:
Optional[the openai module]
"""
try:
# pylint: disable=import-outside-toplevel
import openai
api_key = os.getenv("OPENAI_API_KEY")
if api_key is None:
logger.info(
"Please provide an Open API Key in OPENAI_API_KEY (https://beta.openai.com/account/api-keys)"
)
return None
openai.api_key = api_key
except ImportError:
logger.info("OpenAI was not installed") # type: ignore
logger.info('run "pip install openai"')
return None
return openai
def log_codex(filename: str, prompt: str) -> None:
"""
Log the prompt in crytic/export/codex/filename
Append to the file
Args:
filename: filename to write to
prompt: prompt to write
Returns:
None
"""
Path("crytic_export/codex").mkdir(parents=True, exist_ok=True)
with open(Path("crytic_export/codex", filename), "a", encoding="utf8") as file:
file.write(prompt)
file.write("\n")

@ -29,6 +29,12 @@ JSON_OUTPUT_TYPES = [
# Those are the flags shared by the command line and the config file
defaults_flag_in_config = {
"codex": False,
"codex_contracts": "all",
"codex_model": "text-davinci-003",
"codex_temperature": 0,
"codex_max_tokens": 300,
"codex_log": False,
"detectors_to_run": "all",
"printers_to_run": None,
"detectors_to_exclude": None,

@ -1,4 +1,4 @@
import sha3
from Crypto.Hash import keccak
def get_function_id(sig: str) -> int:
@ -9,6 +9,6 @@ def get_function_id(sig: str) -> int:
Return:
(int)
"""
s = sha3.keccak_256()
s.update(sig.encode("utf-8"))
return int("0x" + s.hexdigest()[:8], 16)
digest = keccak.new(digest_bits=256)
digest.update(sig.encode("utf-8"))
return int("0x" + digest.hexdigest()[:8], 16)

@ -33,3 +33,22 @@ contract ReentrancyAndWrite{
}
}
contract Internal {
/// @custom:security write-protection="onlyOwner()"
address owner;
modifier onlyOwner(){
// lets assume there is an access control
_;
}
function buggy() public {
internal_write();
}
function internal_write() internal {
owner = msg.sender;
}
}

@ -1,5 +1,188 @@
[
[
{
"elements": [
{
"type": "function",
"name": "buggy",
"source_mapping": {
"start": 938,
"length": 57,
"filename_relative": "tests/detectors/protected-vars/0.8.2/comment.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/protected-vars/0.8.2/comment.sol",
"is_dependency": false,
"lines": [
47,
48,
49
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "Internal",
"source_mapping": {
"start": 742,
"length": 331,
"filename_relative": "tests/detectors/protected-vars/0.8.2/comment.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/protected-vars/0.8.2/comment.sol",
"is_dependency": false,
"lines": [
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55
],
"starting_column": 1,
"ending_column": 0
}
},
"signature": "buggy()"
}
},
{
"type": "function",
"name": "onlyOwner",
"source_mapping": {
"start": 844,
"length": 88,
"filename_relative": "tests/detectors/protected-vars/0.8.2/comment.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/protected-vars/0.8.2/comment.sol",
"is_dependency": false,
"lines": [
42,
43,
44,
45
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "Internal",
"source_mapping": {
"start": 742,
"length": 331,
"filename_relative": "tests/detectors/protected-vars/0.8.2/comment.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/protected-vars/0.8.2/comment.sol",
"is_dependency": false,
"lines": [
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55
],
"starting_column": 1,
"ending_column": 0
}
},
"signature": "onlyOwner()"
}
},
{
"type": "variable",
"name": "owner",
"source_mapping": {
"start": 822,
"length": 13,
"filename_relative": "tests/detectors/protected-vars/0.8.2/comment.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/protected-vars/0.8.2/comment.sol",
"is_dependency": false,
"lines": [
38
],
"starting_column": 5,
"ending_column": 18
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "Internal",
"source_mapping": {
"start": 742,
"length": 331,
"filename_relative": "tests/detectors/protected-vars/0.8.2/comment.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/protected-vars/0.8.2/comment.sol",
"is_dependency": false,
"lines": [
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55
],
"starting_column": 1,
"ending_column": 0
}
}
}
}
],
"description": "Internal.buggy() (tests/detectors/protected-vars/0.8.2/comment.sol#47-49) should have Internal.onlyOwner() (tests/detectors/protected-vars/0.8.2/comment.sol#42-45) to protect Internal.owner (tests/detectors/protected-vars/0.8.2/comment.sol#38)\n",
"markdown": "[Internal.buggy()](tests/detectors/protected-vars/0.8.2/comment.sol#L47-L49) should have [Internal.onlyOwner()](tests/detectors/protected-vars/0.8.2/comment.sol#L42-L45) to protect [Internal.owner](tests/detectors/protected-vars/0.8.2/comment.sol#L38)\n",
"first_markdown_element": "tests/detectors/protected-vars/0.8.2/comment.sol#L47-L49",
"id": "347d5dbdb03710066bc29d7772156fe5ff3d3371fa4eee4839ee221a1d0de0a4",
"check": "protected-vars",
"impact": "High",
"confidence": "High"
},
{
"elements": [
{

File diff suppressed because one or more lines are too long

@ -4,23 +4,22 @@
"elements": [
{
"type": "function",
"name": "withdrawBalance",
"name": "withdrawBalance_nested",
"source_mapping": {
"start": 656,
"length": 314,
"start": 2465,
"length": 246,
"filename_relative": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"is_dependency": false,
"lines": [
24,
25,
26,
27,
28,
29,
30,
31
74,
75,
76,
77,
78,
79,
80
],
"starting_column": 5,
"ending_column": 6
@ -122,45 +121,44 @@
"ending_column": 2
}
},
"signature": "withdrawBalance()"
"signature": "withdrawBalance_nested()"
}
},
{
"type": "node",
"name": "! (msg.sender.call.value(userBalance[msg.sender])())",
"name": "msg.sender.call.value(amount / 2)()",
"source_mapping": {
"start": 839,
"length": 53,
"start": 2620,
"length": 33,
"filename_relative": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"is_dependency": false,
"lines": [
27
77
],
"starting_column": 13,
"ending_column": 66
"ending_column": 46
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance",
"name": "withdrawBalance_nested",
"source_mapping": {
"start": 656,
"length": 314,
"start": 2465,
"length": 246,
"filename_relative": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"is_dependency": false,
"lines": [
24,
25,
26,
27,
28,
29,
30,
31
74,
75,
76,
77,
78,
79,
80
],
"starting_column": 5,
"ending_column": 6
@ -262,7 +260,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance()"
"signature": "withdrawBalance_nested()"
}
}
},
@ -274,38 +272,37 @@
"type": "node",
"name": "userBalance[msg.sender] = 0",
"source_mapping": {
"start": 936,
"start": 2667,
"length": 27,
"filename_relative": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"is_dependency": false,
"lines": [
30
78
],
"starting_column": 9,
"ending_column": 36
"starting_column": 13,
"ending_column": 40
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance",
"name": "withdrawBalance_nested",
"source_mapping": {
"start": 656,
"length": 314,
"start": 2465,
"length": 246,
"filename_relative": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"is_dependency": false,
"lines": [
24,
25,
26,
27,
28,
29,
30,
31
74,
75,
76,
77,
78,
79,
80
],
"starting_column": 5,
"ending_column": 6
@ -407,7 +404,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance()"
"signature": "withdrawBalance_nested()"
}
}
},
@ -417,10 +414,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#24-31):\n\tExternal calls:\n\t- ! (msg.sender.call.value(userBalance[msg.sender])()) (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#27)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = 0 (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#30)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L24-L31):\n\tExternal calls:\n\t- [! (msg.sender.call.value(userBalance[msg.sender])())](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L27)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = 0](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L30)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L24-L31",
"id": "759a5ea5deb597f6ca748c9b27656dee01b1e4b634365a68b918bf10518662e8",
"description": "Reentrancy in Reentrancy.withdrawBalance_nested() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#74-80):\n\tExternal calls:\n\t- msg.sender.call.value(amount / 2)() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#77)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = 0 (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#78)\n\tReentrancy.userBalance (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#4) can be used in cross function reentrancies:\n\t- Reentrancy.addToBalance() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#10-12)\n\t- Reentrancy.constructor() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#15-22)\n\t- Reentrancy.getBalance(address) (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#6-8)\n\t- Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#24-31)\n\t- Reentrancy.withdrawBalance_fixed() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#33-41)\n\t- Reentrancy.withdrawBalance_fixed_2() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#43-50)\n\t- Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#52-60)\n\t- Reentrancy.withdrawBalance_fixed_4() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#61-72)\n\t- Reentrancy.withdrawBalance_nested() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#74-80)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance_nested()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L74-L80):\n\tExternal calls:\n\t- [msg.sender.call.value(amount / 2)()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L77)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = 0](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L78)\n\t[Reentrancy.userBalance](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L4) can be used in cross function reentrancies:\n\t- [Reentrancy.addToBalance()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L10-L12)\n\t- [Reentrancy.constructor()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L15-L22)\n\t- [Reentrancy.getBalance(address)](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L6-L8)\n\t- [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L24-L31)\n\t- [Reentrancy.withdrawBalance_fixed()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L33-L41)\n\t- [Reentrancy.withdrawBalance_fixed_2()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L43-L50)\n\t- [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L52-L60)\n\t- [Reentrancy.withdrawBalance_fixed_4()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L61-L72)\n\t- [Reentrancy.withdrawBalance_nested()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L74-L80)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L74-L80",
"id": "5853108dfdb4138662a85fbd17c35511950298872f89c124f1869942c6c4e880",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"
@ -429,22 +426,23 @@
"elements": [
{
"type": "function",
"name": "withdrawBalance_nested",
"name": "withdrawBalance",
"source_mapping": {
"start": 2465,
"length": 246,
"start": 656,
"length": 314,
"filename_relative": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"is_dependency": false,
"lines": [
74,
75,
76,
77,
78,
79,
80
24,
25,
26,
27,
28,
29,
30,
31
],
"starting_column": 5,
"ending_column": 6
@ -546,44 +544,45 @@
"ending_column": 2
}
},
"signature": "withdrawBalance_nested()"
"signature": "withdrawBalance()"
}
},
{
"type": "node",
"name": "msg.sender.call.value(amount / 2)()",
"name": "! (msg.sender.call.value(userBalance[msg.sender])())",
"source_mapping": {
"start": 2620,
"length": 33,
"start": 839,
"length": 53,
"filename_relative": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"is_dependency": false,
"lines": [
77
27
],
"starting_column": 13,
"ending_column": 46
"ending_column": 66
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance_nested",
"name": "withdrawBalance",
"source_mapping": {
"start": 2465,
"length": 246,
"start": 656,
"length": 314,
"filename_relative": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"is_dependency": false,
"lines": [
74,
75,
76,
77,
78,
79,
80
24,
25,
26,
27,
28,
29,
30,
31
],
"starting_column": 5,
"ending_column": 6
@ -685,7 +684,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance_nested()"
"signature": "withdrawBalance()"
}
}
},
@ -697,37 +696,38 @@
"type": "node",
"name": "userBalance[msg.sender] = 0",
"source_mapping": {
"start": 2667,
"start": 936,
"length": 27,
"filename_relative": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"is_dependency": false,
"lines": [
78
30
],
"starting_column": 13,
"ending_column": 40
"starting_column": 9,
"ending_column": 36
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance_nested",
"name": "withdrawBalance",
"source_mapping": {
"start": 2465,
"length": 246,
"start": 656,
"length": 314,
"filename_relative": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol",
"is_dependency": false,
"lines": [
74,
75,
76,
77,
78,
79,
80
24,
25,
26,
27,
28,
29,
30,
31
],
"starting_column": 5,
"ending_column": 6
@ -829,7 +829,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance_nested()"
"signature": "withdrawBalance()"
}
}
},
@ -839,10 +839,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdrawBalance_nested() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#74-80):\n\tExternal calls:\n\t- msg.sender.call.value(amount / 2)() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#77)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = 0 (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#78)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance_nested()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L74-L80):\n\tExternal calls:\n\t- [msg.sender.call.value(amount / 2)()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L77)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = 0](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L78)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L74-L80",
"id": "cc27a0e36ba51b1a24ae1df9b9f2ec9e67afedd649839a3302b6f9e08987c7d8",
"description": "Reentrancy in Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#24-31):\n\tExternal calls:\n\t- ! (msg.sender.call.value(userBalance[msg.sender])()) (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#27)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = 0 (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#30)\n\tReentrancy.userBalance (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#4) can be used in cross function reentrancies:\n\t- Reentrancy.addToBalance() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#10-12)\n\t- Reentrancy.constructor() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#15-22)\n\t- Reentrancy.getBalance(address) (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#6-8)\n\t- Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#24-31)\n\t- Reentrancy.withdrawBalance_fixed() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#33-41)\n\t- Reentrancy.withdrawBalance_fixed_2() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#43-50)\n\t- Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#52-60)\n\t- Reentrancy.withdrawBalance_fixed_4() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#61-72)\n\t- Reentrancy.withdrawBalance_nested() (tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#74-80)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L24-L31):\n\tExternal calls:\n\t- [! (msg.sender.call.value(userBalance[msg.sender])())](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L27)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = 0](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L30)\n\t[Reentrancy.userBalance](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L4) can be used in cross function reentrancies:\n\t- [Reentrancy.addToBalance()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L10-L12)\n\t- [Reentrancy.constructor()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L15-L22)\n\t- [Reentrancy.getBalance(address)](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L6-L8)\n\t- [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L24-L31)\n\t- [Reentrancy.withdrawBalance_fixed()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L33-L41)\n\t- [Reentrancy.withdrawBalance_fixed_2()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L43-L50)\n\t- [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L52-L60)\n\t- [Reentrancy.withdrawBalance_fixed_4()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L61-L72)\n\t- [Reentrancy.withdrawBalance_nested()](tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L74-L80)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.4.25/reentrancy.sol#L24-L31",
"id": "8746b87cbc0fcd59a17ae20018967719c6ebc9fca41c6a128e5ac18dd4ee27cc",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"

@ -428,10 +428,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#22-29):\n\tExternal calls:\n\t- require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender])) (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#24)\n\tExternal calls sending eth:\n\t- msg.sender.transfer(eth_deposed[token][msg.sender]) (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#23)\n\tState variables written after the call(s):\n\t- eth_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#26)\n\t- token_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#27)\n",
"markdown": "Reentrancy in [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L22-L29):\n\tExternal calls:\n\t- [require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender]))](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L24)\n\tExternal calls sending eth:\n\t- [msg.sender.transfer(eth_deposed[token][msg.sender])](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L23)\n\tState variables written after the call(s):\n\t- [eth_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L26)\n\t- [token_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L27)\n",
"description": "Reentrancy in Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#22-29):\n\tExternal calls:\n\t- require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender])) (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#24)\n\tExternal calls sending eth:\n\t- msg.sender.transfer(eth_deposed[token][msg.sender]) (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#23)\n\tState variables written after the call(s):\n\t- eth_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#26)\n\tReentrancy.eth_deposed (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#10) can be used in cross function reentrancies:\n\t- Reentrancy.deposit_eth(address) (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#13-15)\n\t- Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#22-29)\n\t- token_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#27)\n\tReentrancy.token_deposed (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#11) can be used in cross function reentrancies:\n\t- Reentrancy.deposit_token(address,uint256) (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#17-20)\n\t- Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#22-29)\n",
"markdown": "Reentrancy in [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L22-L29):\n\tExternal calls:\n\t- [require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender]))](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L24)\n\tExternal calls sending eth:\n\t- [msg.sender.transfer(eth_deposed[token][msg.sender])](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L23)\n\tState variables written after the call(s):\n\t- [eth_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L26)\n\t[Reentrancy.eth_deposed](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L10) can be used in cross function reentrancies:\n\t- [Reentrancy.deposit_eth(address)](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L13-L15)\n\t- [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L22-L29)\n\t- [token_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L27)\n\t[Reentrancy.token_deposed](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L11) can be used in cross function reentrancies:\n\t- [Reentrancy.deposit_token(address,uint256)](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L17-L20)\n\t- [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L22-L29)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.4.25/reentrancy_indirect.sol#L22-L29",
"id": "8a2174b6a3476b6e52f3cdac7e85b44337e3b7d7df2b2504c5a75b8e2a00ea7f",
"id": "7ff6a788e1559497246f084096fd10a9fd3a7d30de1b89ac896b7600ba32710d",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"

@ -4,25 +4,24 @@
"elements": [
{
"type": "function",
"name": "withdrawBalance_fixed_3",
"name": "withdrawBalance",
"source_mapping": {
"start": 1839,
"length": 393,
"start": 703,
"length": 357,
"filename_relative": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"is_dependency": false,
"lines": [
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
25,
26,
27,
28,
29,
30,
31,
32,
33
],
"starting_column": 5,
"ending_column": 6
@ -107,47 +106,46 @@
"ending_column": 2
}
},
"signature": "withdrawBalance_fixed_3()"
"signature": "withdrawBalance()"
}
},
{
"type": "node",
"name": "(ret,mem) = msg.sender.call.value(amount)()",
"name": "(ret,mem) = msg.sender.call.value(userBalance[msg.sender])()",
"source_mapping": {
"start": 2084,
"length": 64,
"start": 882,
"length": 81,
"filename_relative": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"is_dependency": false,
"lines": [
60
28
],
"starting_column": 9,
"ending_column": 73
"ending_column": 90
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance_fixed_3",
"name": "withdrawBalance",
"source_mapping": {
"start": 1839,
"length": 393,
"start": 703,
"length": 357,
"filename_relative": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"is_dependency": false,
"lines": [
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
25,
26,
27,
28,
29,
30,
31,
32,
33
],
"starting_column": 5,
"ending_column": 6
@ -232,7 +230,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance_fixed_3()"
"signature": "withdrawBalance()"
}
}
},
@ -242,42 +240,41 @@
},
{
"type": "node",
"name": "userBalance[msg.sender] = amount",
"name": "userBalance[msg.sender] = 0",
"source_mapping": {
"start": 2183,
"length": 32,
"start": 1026,
"length": 27,
"filename_relative": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"is_dependency": false,
"lines": [
62
32
],
"starting_column": 13,
"ending_column": 45
"starting_column": 9,
"ending_column": 36
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance_fixed_3",
"name": "withdrawBalance",
"source_mapping": {
"start": 1839,
"length": 393,
"start": 703,
"length": 357,
"filename_relative": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"is_dependency": false,
"lines": [
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
25,
26,
27,
28,
29,
30,
31,
32,
33
],
"starting_column": 5,
"ending_column": 6
@ -362,7 +359,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance_fixed_3()"
"signature": "withdrawBalance()"
}
}
},
@ -372,10 +369,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#55-64):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call.value(amount)() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#60)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = amount (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#62)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L55-L64):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call.value(amount)()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L60)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = amount](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L62)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L55-L64",
"id": "b1d5762a3d9738215079d50da4bf0ecdc8eddd575b7f8686bdbfa3d101adf809",
"description": "Reentrancy in Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#25-33):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call.value(userBalance[msg.sender])() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#28)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = 0 (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#32)\n\tReentrancy.userBalance (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#4) can be used in cross function reentrancies:\n\t- Reentrancy.addToBalance() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#10-12)\n\t- Reentrancy.constructor() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#15-23)\n\t- Reentrancy.getBalance(address) (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#6-8)\n\t- Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#25-33)\n\t- Reentrancy.withdrawBalance_fixed() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#35-44)\n\t- Reentrancy.withdrawBalance_fixed_2() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#46-53)\n\t- Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#55-64)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L25-L33):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call.value(userBalance[msg.sender])()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L28)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = 0](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L32)\n\t[Reentrancy.userBalance](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L4) can be used in cross function reentrancies:\n\t- [Reentrancy.addToBalance()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L10-L12)\n\t- [Reentrancy.constructor()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L15-L23)\n\t- [Reentrancy.getBalance(address)](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L6-L8)\n\t- [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L25-L33)\n\t- [Reentrancy.withdrawBalance_fixed()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L35-L44)\n\t- [Reentrancy.withdrawBalance_fixed_2()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L46-L53)\n\t- [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L55-L64)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L25-L33",
"id": "1fec5eddc1a1f7c95bbaa72099c7f36d9c8768271ba1bb51b2ece7f2dab1a175",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"
@ -384,24 +381,25 @@
"elements": [
{
"type": "function",
"name": "withdrawBalance",
"name": "withdrawBalance_fixed_3",
"source_mapping": {
"start": 703,
"length": 357,
"start": 1839,
"length": 393,
"filename_relative": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"is_dependency": false,
"lines": [
25,
26,
27,
28,
29,
30,
31,
32,
33
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
],
"starting_column": 5,
"ending_column": 6
@ -486,46 +484,47 @@
"ending_column": 2
}
},
"signature": "withdrawBalance()"
"signature": "withdrawBalance_fixed_3()"
}
},
{
"type": "node",
"name": "(ret,mem) = msg.sender.call.value(userBalance[msg.sender])()",
"name": "(ret,mem) = msg.sender.call.value(amount)()",
"source_mapping": {
"start": 882,
"length": 81,
"start": 2084,
"length": 64,
"filename_relative": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"is_dependency": false,
"lines": [
28
60
],
"starting_column": 9,
"ending_column": 90
"ending_column": 73
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance",
"name": "withdrawBalance_fixed_3",
"source_mapping": {
"start": 703,
"length": 357,
"start": 1839,
"length": 393,
"filename_relative": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"is_dependency": false,
"lines": [
25,
26,
27,
28,
29,
30,
31,
32,
33
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
],
"starting_column": 5,
"ending_column": 6
@ -610,7 +609,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance()"
"signature": "withdrawBalance_fixed_3()"
}
}
},
@ -620,41 +619,42 @@
},
{
"type": "node",
"name": "userBalance[msg.sender] = 0",
"name": "userBalance[msg.sender] = amount",
"source_mapping": {
"start": 1026,
"length": 27,
"start": 2183,
"length": 32,
"filename_relative": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"is_dependency": false,
"lines": [
32
62
],
"starting_column": 9,
"ending_column": 36
"starting_column": 13,
"ending_column": 45
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance",
"name": "withdrawBalance_fixed_3",
"source_mapping": {
"start": 703,
"length": 357,
"start": 1839,
"length": 393,
"filename_relative": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol",
"is_dependency": false,
"lines": [
25,
26,
27,
28,
29,
30,
31,
32,
33
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
],
"starting_column": 5,
"ending_column": 6
@ -739,7 +739,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance()"
"signature": "withdrawBalance_fixed_3()"
}
}
},
@ -749,10 +749,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#25-33):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call.value(userBalance[msg.sender])() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#28)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = 0 (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#32)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L25-L33):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call.value(userBalance[msg.sender])()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L28)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = 0](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L32)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L25-L33",
"id": "e2dcb62d8ffcc2636bab0fee518b4a79c760f2974c39950214749fc78bebc9de",
"description": "Reentrancy in Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#55-64):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call.value(amount)() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#60)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = amount (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#62)\n\tReentrancy.userBalance (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#4) can be used in cross function reentrancies:\n\t- Reentrancy.addToBalance() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#10-12)\n\t- Reentrancy.constructor() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#15-23)\n\t- Reentrancy.getBalance(address) (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#6-8)\n\t- Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#25-33)\n\t- Reentrancy.withdrawBalance_fixed() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#35-44)\n\t- Reentrancy.withdrawBalance_fixed_2() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#46-53)\n\t- Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#55-64)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L55-L64):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call.value(amount)()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L60)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = amount](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L62)\n\t[Reentrancy.userBalance](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L4) can be used in cross function reentrancies:\n\t- [Reentrancy.addToBalance()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L10-L12)\n\t- [Reentrancy.constructor()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L15-L23)\n\t- [Reentrancy.getBalance(address)](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L6-L8)\n\t- [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L25-L33)\n\t- [Reentrancy.withdrawBalance_fixed()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L35-L44)\n\t- [Reentrancy.withdrawBalance_fixed_2()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L46-L53)\n\t- [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L55-L64)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.5.16/reentrancy.sol#L55-L64",
"id": "c1a4b6379bd0137d705b0e1994021e4478445b98ba4d23c547338f09e2213ef0",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"

@ -428,10 +428,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#22-29):\n\tExternal calls:\n\t- require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender])) (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#24)\n\tExternal calls sending eth:\n\t- msg.sender.transfer(eth_deposed[token][msg.sender]) (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#23)\n\tState variables written after the call(s):\n\t- eth_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#26)\n\t- token_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#27)\n",
"markdown": "Reentrancy in [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L22-L29):\n\tExternal calls:\n\t- [require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender]))](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L24)\n\tExternal calls sending eth:\n\t- [msg.sender.transfer(eth_deposed[token][msg.sender])](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L23)\n\tState variables written after the call(s):\n\t- [eth_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L26)\n\t- [token_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L27)\n",
"description": "Reentrancy in Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#22-29):\n\tExternal calls:\n\t- require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender])) (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#24)\n\tExternal calls sending eth:\n\t- msg.sender.transfer(eth_deposed[token][msg.sender]) (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#23)\n\tState variables written after the call(s):\n\t- eth_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#26)\n\tReentrancy.eth_deposed (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#10) can be used in cross function reentrancies:\n\t- Reentrancy.deposit_eth(address) (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#13-15)\n\t- Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#22-29)\n\t- token_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#27)\n\tReentrancy.token_deposed (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#11) can be used in cross function reentrancies:\n\t- Reentrancy.deposit_token(address,uint256) (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#17-20)\n\t- Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#22-29)\n",
"markdown": "Reentrancy in [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L22-L29):\n\tExternal calls:\n\t- [require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender]))](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L24)\n\tExternal calls sending eth:\n\t- [msg.sender.transfer(eth_deposed[token][msg.sender])](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L23)\n\tState variables written after the call(s):\n\t- [eth_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L26)\n\t[Reentrancy.eth_deposed](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L10) can be used in cross function reentrancies:\n\t- [Reentrancy.deposit_eth(address)](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L13-L15)\n\t- [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L22-L29)\n\t- [token_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L27)\n\t[Reentrancy.token_deposed](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L11) can be used in cross function reentrancies:\n\t- [Reentrancy.deposit_token(address,uint256)](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L17-L20)\n\t- [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L22-L29)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.5.16/reentrancy_indirect.sol#L22-L29",
"id": "b409436e604deed3ecb1b621a908db6ddbd69754315b41a9806919d8348391d9",
"id": "52cd1e82b29830aa25a1ea1bbc1b35c0e3097eab1f2922b4ecc98eae8f1ed225",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"

@ -4,24 +4,25 @@
"elements": [
{
"type": "function",
"name": "withdrawBalance",
"name": "withdrawBalance_fixed_3",
"source_mapping": {
"start": 707,
"length": 357,
"start": 1843,
"length": 393,
"filename_relative": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"is_dependency": false,
"lines": [
25,
26,
27,
28,
29,
30,
31,
32,
33
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
],
"starting_column": 5,
"ending_column": 6
@ -106,46 +107,47 @@
"ending_column": 2
}
},
"signature": "withdrawBalance()"
"signature": "withdrawBalance_fixed_3()"
}
},
{
"type": "node",
"name": "(ret,mem) = msg.sender.call.value(userBalance[msg.sender])()",
"name": "(ret,mem) = msg.sender.call.value(amount)()",
"source_mapping": {
"start": 886,
"length": 81,
"start": 2088,
"length": 64,
"filename_relative": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"is_dependency": false,
"lines": [
28
60
],
"starting_column": 9,
"ending_column": 90
"ending_column": 73
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance",
"name": "withdrawBalance_fixed_3",
"source_mapping": {
"start": 707,
"length": 357,
"start": 1843,
"length": 393,
"filename_relative": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"is_dependency": false,
"lines": [
25,
26,
27,
28,
29,
30,
31,
32,
33
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
],
"starting_column": 5,
"ending_column": 6
@ -230,7 +232,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance()"
"signature": "withdrawBalance_fixed_3()"
}
}
},
@ -240,41 +242,42 @@
},
{
"type": "node",
"name": "userBalance[msg.sender] = 0",
"name": "userBalance[msg.sender] = amount",
"source_mapping": {
"start": 1030,
"length": 27,
"start": 2187,
"length": 32,
"filename_relative": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"is_dependency": false,
"lines": [
32
62
],
"starting_column": 9,
"ending_column": 36
"starting_column": 13,
"ending_column": 45
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance",
"name": "withdrawBalance_fixed_3",
"source_mapping": {
"start": 707,
"length": 357,
"start": 1843,
"length": 393,
"filename_relative": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"is_dependency": false,
"lines": [
25,
26,
27,
28,
29,
30,
31,
32,
33
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
],
"starting_column": 5,
"ending_column": 6
@ -359,7 +362,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance()"
"signature": "withdrawBalance_fixed_3()"
}
}
},
@ -369,10 +372,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#25-33):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call.value(userBalance[msg.sender])() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#28)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = 0 (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#32)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L25-L33):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call.value(userBalance[msg.sender])()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L28)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = 0](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L32)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L25-L33",
"id": "2ae23f335df95d0f5c56d214774a6afc507773d057c4ca44f2eb4eff0e2ebe98",
"description": "Reentrancy in Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#55-64):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call.value(amount)() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#60)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = amount (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#62)\n\tReentrancy.userBalance (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#4) can be used in cross function reentrancies:\n\t- Reentrancy.addToBalance() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#10-12)\n\t- Reentrancy.constructor() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#15-23)\n\t- Reentrancy.getBalance(address) (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#6-8)\n\t- Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#25-33)\n\t- Reentrancy.withdrawBalance_fixed() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#35-44)\n\t- Reentrancy.withdrawBalance_fixed_2() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#46-53)\n\t- Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#55-64)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L55-L64):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call.value(amount)()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L60)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = amount](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L62)\n\t[Reentrancy.userBalance](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L4) can be used in cross function reentrancies:\n\t- [Reentrancy.addToBalance()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L10-L12)\n\t- [Reentrancy.constructor()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L15-L23)\n\t- [Reentrancy.getBalance(address)](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L6-L8)\n\t- [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L25-L33)\n\t- [Reentrancy.withdrawBalance_fixed()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L35-L44)\n\t- [Reentrancy.withdrawBalance_fixed_2()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L46-L53)\n\t- [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L55-L64)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L55-L64",
"id": "bc199b4c8749cb08649e2084ac891e0cb098640e2752bf319ffa79d99ee10cdb",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"
@ -381,25 +384,24 @@
"elements": [
{
"type": "function",
"name": "withdrawBalance_fixed_3",
"name": "withdrawBalance",
"source_mapping": {
"start": 1843,
"length": 393,
"start": 707,
"length": 357,
"filename_relative": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"is_dependency": false,
"lines": [
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
25,
26,
27,
28,
29,
30,
31,
32,
33
],
"starting_column": 5,
"ending_column": 6
@ -484,47 +486,46 @@
"ending_column": 2
}
},
"signature": "withdrawBalance_fixed_3()"
"signature": "withdrawBalance()"
}
},
{
"type": "node",
"name": "(ret,mem) = msg.sender.call.value(amount)()",
"name": "(ret,mem) = msg.sender.call.value(userBalance[msg.sender])()",
"source_mapping": {
"start": 2088,
"length": 64,
"start": 886,
"length": 81,
"filename_relative": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"is_dependency": false,
"lines": [
60
28
],
"starting_column": 9,
"ending_column": 73
"ending_column": 90
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance_fixed_3",
"name": "withdrawBalance",
"source_mapping": {
"start": 1843,
"length": 393,
"start": 707,
"length": 357,
"filename_relative": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"is_dependency": false,
"lines": [
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
25,
26,
27,
28,
29,
30,
31,
32,
33
],
"starting_column": 5,
"ending_column": 6
@ -609,7 +610,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance_fixed_3()"
"signature": "withdrawBalance()"
}
}
},
@ -619,42 +620,41 @@
},
{
"type": "node",
"name": "userBalance[msg.sender] = amount",
"name": "userBalance[msg.sender] = 0",
"source_mapping": {
"start": 2187,
"length": 32,
"start": 1030,
"length": 27,
"filename_relative": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"is_dependency": false,
"lines": [
62
32
],
"starting_column": 13,
"ending_column": 45
"starting_column": 9,
"ending_column": 36
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdrawBalance_fixed_3",
"name": "withdrawBalance",
"source_mapping": {
"start": 1843,
"length": 393,
"start": 707,
"length": 357,
"filename_relative": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol",
"is_dependency": false,
"lines": [
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
25,
26,
27,
28,
29,
30,
31,
32,
33
],
"starting_column": 5,
"ending_column": 6
@ -739,7 +739,7 @@
"ending_column": 2
}
},
"signature": "withdrawBalance_fixed_3()"
"signature": "withdrawBalance()"
}
}
},
@ -749,10 +749,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#55-64):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call.value(amount)() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#60)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = amount (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#62)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L55-L64):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call.value(amount)()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L60)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = amount](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L62)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L55-L64",
"id": "c4d2dd489fd8bc396119bdd7e5a73c3782cf5fa27171112104e34b2f3ccf37c4",
"description": "Reentrancy in Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#25-33):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call.value(userBalance[msg.sender])() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#28)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = 0 (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#32)\n\tReentrancy.userBalance (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#4) can be used in cross function reentrancies:\n\t- Reentrancy.addToBalance() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#10-12)\n\t- Reentrancy.constructor() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#15-23)\n\t- Reentrancy.getBalance(address) (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#6-8)\n\t- Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#25-33)\n\t- Reentrancy.withdrawBalance_fixed() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#35-44)\n\t- Reentrancy.withdrawBalance_fixed_2() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#46-53)\n\t- Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#55-64)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L25-L33):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call.value(userBalance[msg.sender])()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L28)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = 0](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L32)\n\t[Reentrancy.userBalance](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L4) can be used in cross function reentrancies:\n\t- [Reentrancy.addToBalance()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L10-L12)\n\t- [Reentrancy.constructor()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L15-L23)\n\t- [Reentrancy.getBalance(address)](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L6-L8)\n\t- [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L25-L33)\n\t- [Reentrancy.withdrawBalance_fixed()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L35-L44)\n\t- [Reentrancy.withdrawBalance_fixed_2()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L46-L53)\n\t- [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L55-L64)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.6.11/reentrancy.sol#L25-L33",
"id": "c8c4106c11c4f1fc4a76fc18e91bb3132d5b8d95d94c707453f64be98f1efa8d",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"

@ -428,10 +428,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#22-29):\n\tExternal calls:\n\t- require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender])) (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#24)\n\tExternal calls sending eth:\n\t- msg.sender.transfer(eth_deposed[token][msg.sender]) (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#23)\n\tState variables written after the call(s):\n\t- eth_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#26)\n\t- token_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#27)\n",
"markdown": "Reentrancy in [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L22-L29):\n\tExternal calls:\n\t- [require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender]))](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L24)\n\tExternal calls sending eth:\n\t- [msg.sender.transfer(eth_deposed[token][msg.sender])](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L23)\n\tState variables written after the call(s):\n\t- [eth_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L26)\n\t- [token_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L27)\n",
"description": "Reentrancy in Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#22-29):\n\tExternal calls:\n\t- require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender])) (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#24)\n\tExternal calls sending eth:\n\t- msg.sender.transfer(eth_deposed[token][msg.sender]) (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#23)\n\tState variables written after the call(s):\n\t- eth_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#26)\n\tReentrancy.eth_deposed (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#10) can be used in cross function reentrancies:\n\t- Reentrancy.deposit_eth(address) (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#13-15)\n\t- Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#22-29)\n\t- token_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#27)\n\tReentrancy.token_deposed (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#11) can be used in cross function reentrancies:\n\t- Reentrancy.deposit_token(address,uint256) (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#17-20)\n\t- Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#22-29)\n",
"markdown": "Reentrancy in [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L22-L29):\n\tExternal calls:\n\t- [require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender]))](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L24)\n\tExternal calls sending eth:\n\t- [msg.sender.transfer(eth_deposed[token][msg.sender])](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L23)\n\tState variables written after the call(s):\n\t- [eth_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L26)\n\t[Reentrancy.eth_deposed](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L10) can be used in cross function reentrancies:\n\t- [Reentrancy.deposit_eth(address)](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L13-L15)\n\t- [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L22-L29)\n\t- [token_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L27)\n\t[Reentrancy.token_deposed](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L11) can be used in cross function reentrancies:\n\t- [Reentrancy.deposit_token(address,uint256)](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L17-L20)\n\t- [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L22-L29)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.6.11/reentrancy_indirect.sol#L22-L29",
"id": "592ad3a6f86cbf4b9e9e1c21c6345d8616f0e6e8a85c7e9ab283b5b0a1271c71",
"id": "f892080cd6edb9d73d435cd8c4cea16e1b65098abf2a0df5debcd493787f6654",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"

@ -372,10 +372,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#55-64):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call{value: amount}() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#60)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = amount (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#62)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L55-L64):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call{value: amount}()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L60)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = amount](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L62)\n",
"description": "Reentrancy in Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#55-64):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call{value: amount}() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#60)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = amount (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#62)\n\tReentrancy.userBalance (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#4) can be used in cross function reentrancies:\n\t- Reentrancy.addToBalance() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#10-12)\n\t- Reentrancy.constructor() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#15-23)\n\t- Reentrancy.getBalance(address) (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#6-8)\n\t- Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#25-33)\n\t- Reentrancy.withdrawBalance_fixed() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#35-44)\n\t- Reentrancy.withdrawBalance_fixed_2() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#46-53)\n\t- Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#55-64)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L55-L64):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call{value: amount}()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L60)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = amount](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L62)\n\t[Reentrancy.userBalance](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L4) can be used in cross function reentrancies:\n\t- [Reentrancy.addToBalance()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L10-L12)\n\t- [Reentrancy.constructor()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L15-L23)\n\t- [Reentrancy.getBalance(address)](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L6-L8)\n\t- [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L25-L33)\n\t- [Reentrancy.withdrawBalance_fixed()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L35-L44)\n\t- [Reentrancy.withdrawBalance_fixed_2()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L46-L53)\n\t- [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L55-L64)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L55-L64",
"id": "d68cc7cd493eca1fda517423f6f6ad0a5671d0bbea1d80ec0cb403ca66d5d4b8",
"id": "75d254de1c95646a633659a0bb8c1cd874b1a83f8bdba6fda28e9092be76beeb",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"
@ -749,10 +749,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#25-33):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call{value: userBalance[msg.sender]}() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#28)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = 0 (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#32)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L25-L33):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call{value: userBalance[msg.sender]}()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L28)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = 0](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L32)\n",
"description": "Reentrancy in Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#25-33):\n\tExternal calls:\n\t- (ret,mem) = msg.sender.call{value: userBalance[msg.sender]}() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#28)\n\tState variables written after the call(s):\n\t- userBalance[msg.sender] = 0 (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#32)\n\tReentrancy.userBalance (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#4) can be used in cross function reentrancies:\n\t- Reentrancy.addToBalance() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#10-12)\n\t- Reentrancy.constructor() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#15-23)\n\t- Reentrancy.getBalance(address) (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#6-8)\n\t- Reentrancy.withdrawBalance() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#25-33)\n\t- Reentrancy.withdrawBalance_fixed() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#35-44)\n\t- Reentrancy.withdrawBalance_fixed_2() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#46-53)\n\t- Reentrancy.withdrawBalance_fixed_3() (tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#55-64)\n",
"markdown": "Reentrancy in [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L25-L33):\n\tExternal calls:\n\t- [(ret,mem) = msg.sender.call{value: userBalance[msg.sender]}()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L28)\n\tState variables written after the call(s):\n\t- [userBalance[msg.sender] = 0](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L32)\n\t[Reentrancy.userBalance](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L4) can be used in cross function reentrancies:\n\t- [Reentrancy.addToBalance()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L10-L12)\n\t- [Reentrancy.constructor()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L15-L23)\n\t- [Reentrancy.getBalance(address)](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L6-L8)\n\t- [Reentrancy.withdrawBalance()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L25-L33)\n\t- [Reentrancy.withdrawBalance_fixed()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L35-L44)\n\t- [Reentrancy.withdrawBalance_fixed_2()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L46-L53)\n\t- [Reentrancy.withdrawBalance_fixed_3()](tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L55-L64)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.7.6/reentrancy.sol#L25-L33",
"id": "df77aefe86b51d596b1dba22bde98d85390038724420e61fb18579fd90af852c",
"id": "a20a04b25c124d64a595c2dec1a37f745f1594c4f0461622c558d66911ea5235",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"

@ -428,10 +428,10 @@
}
}
],
"description": "Reentrancy in Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#22-29):\n\tExternal calls:\n\t- require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender])) (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#24)\n\tExternal calls sending eth:\n\t- msg.sender.transfer(eth_deposed[token][msg.sender]) (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#23)\n\tState variables written after the call(s):\n\t- eth_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#26)\n\t- token_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#27)\n",
"markdown": "Reentrancy in [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L22-L29):\n\tExternal calls:\n\t- [require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender]))](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L24)\n\tExternal calls sending eth:\n\t- [msg.sender.transfer(eth_deposed[token][msg.sender])](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L23)\n\tState variables written after the call(s):\n\t- [eth_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L26)\n\t- [token_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L27)\n",
"description": "Reentrancy in Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#22-29):\n\tExternal calls:\n\t- require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender])) (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#24)\n\tExternal calls sending eth:\n\t- msg.sender.transfer(eth_deposed[token][msg.sender]) (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#23)\n\tState variables written after the call(s):\n\t- eth_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#26)\n\tReentrancy.eth_deposed (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#10) can be used in cross function reentrancies:\n\t- Reentrancy.deposit_eth(address) (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#13-15)\n\t- Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#22-29)\n\t- token_deposed[token][msg.sender] = 0 (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#27)\n\tReentrancy.token_deposed (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#11) can be used in cross function reentrancies:\n\t- Reentrancy.deposit_token(address,uint256) (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#17-20)\n\t- Reentrancy.withdraw(address) (tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#22-29)\n",
"markdown": "Reentrancy in [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L22-L29):\n\tExternal calls:\n\t- [require(bool)(Token(token).transfer(msg.sender,token_deposed[token][msg.sender]))](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L24)\n\tExternal calls sending eth:\n\t- [msg.sender.transfer(eth_deposed[token][msg.sender])](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L23)\n\tState variables written after the call(s):\n\t- [eth_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L26)\n\t[Reentrancy.eth_deposed](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L10) can be used in cross function reentrancies:\n\t- [Reentrancy.deposit_eth(address)](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L13-L15)\n\t- [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L22-L29)\n\t- [token_deposed[token][msg.sender] = 0](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L27)\n\t[Reentrancy.token_deposed](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L11) can be used in cross function reentrancies:\n\t- [Reentrancy.deposit_token(address,uint256)](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L17-L20)\n\t- [Reentrancy.withdraw(address)](tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L22-L29)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.7.6/reentrancy_indirect.sol#L22-L29",
"id": "24fc47678720105e363d9594b5bcec35f854903103c3c4a4ca82d9b4fb5348c3",
"id": "8aacbf836cda179a2f29017ba3fb238dbb3e88837efd207cd07622e5c746f56a",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"

@ -0,0 +1,22 @@
interface Receiver{
function send_funds() payable external;
}
contract TestWithBug{
mapping(address => uint) balances;
function withdraw(uint amount) public{
require(amount <= balances[msg.sender]);
Receiver(msg.sender).send_funds{value: amount}();
balances[msg.sender] -= amount;
}
// slither-disable-start all
function withdrawFiltered(uint amount) public{
require(amount <= balances[msg.sender]);
Receiver(msg.sender).send_funds{value: amount}();
balances[msg.sender] -= amount;
}
// slither-disable-end all
}

@ -0,0 +1,231 @@
[
[
{
"elements": [
{
"type": "function",
"name": "withdraw",
"source_mapping": {
"start": 133,
"length": 194,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"is_dependency": false,
"lines": [
8,
9,
10,
11,
12
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBug",
"source_mapping": {
"start": 67,
"length": 534,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"is_dependency": false,
"lines": [
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw(uint256)"
}
},
{
"type": "node",
"name": "Receiver(msg.sender).send_funds{value: amount}()",
"source_mapping": {
"start": 231,
"length": 48,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"is_dependency": false,
"lines": [
10
],
"starting_column": 10,
"ending_column": 58
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdraw",
"source_mapping": {
"start": 133,
"length": 194,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"is_dependency": false,
"lines": [
8,
9,
10,
11,
12
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBug",
"source_mapping": {
"start": 67,
"length": 534,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"is_dependency": false,
"lines": [
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw(uint256)"
}
}
},
"additional_fields": {
"underlying_type": "external_calls"
}
},
{
"type": "node",
"name": "balances[msg.sender] -= amount",
"source_mapping": {
"start": 290,
"length": 30,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"is_dependency": false,
"lines": [
11
],
"starting_column": 10,
"ending_column": 40
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdraw",
"source_mapping": {
"start": 133,
"length": 194,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"is_dependency": false,
"lines": [
8,
9,
10,
11,
12
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBug",
"source_mapping": {
"start": 67,
"length": 534,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol",
"is_dependency": false,
"lines": [
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw(uint256)"
}
}
},
"additional_fields": {
"underlying_type": "variables_written",
"variable_name": "balances"
}
}
],
"description": "Reentrancy in TestWithBug.withdraw(uint256) (tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#8-12):\n\tExternal calls:\n\t- Receiver(msg.sender).send_funds{value: amount}() (tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#10)\n\tState variables written after the call(s):\n\t- balances[msg.sender] -= amount (tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#11)\n\tTestWithBug.balances (tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#6) can be used in cross function reentrancies:\n\t- TestWithBug.withdraw(uint256) (tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#8-12)\n\t- TestWithBug.withdrawFiltered(uint256) (tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#15-19)\n",
"markdown": "Reentrancy in [TestWithBug.withdraw(uint256)](tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#L8-L12):\n\tExternal calls:\n\t- [Receiver(msg.sender).send_funds{value: amount}()](tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#L10)\n\tState variables written after the call(s):\n\t- [balances[msg.sender] -= amount](tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#L11)\n\t[TestWithBug.balances](tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#L6) can be used in cross function reentrancies:\n\t- [TestWithBug.withdraw(uint256)](tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#L8-L12)\n\t- [TestWithBug.withdrawFiltered(uint256)](tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#L15-L19)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_filtered_comments.sol#L8-L12",
"id": "176d2b5b09c260c72fd638ff8b5db4709df3ff3eb253daa1cfde254c8299fb94",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"
}
]
]

@ -0,0 +1,151 @@
interface Receiver{
function send_funds() payable external;
}
contract TestWithBug{
mapping(address => uint) balances;
modifier nonReentrant(){
_;
}
function withdraw(uint amount) nonReentrant public{
require(amount <= balances[msg.sender]);
Receiver(msg.sender).send_funds{value: amount}();
balances[msg.sender] -= amount;
}
function withdraw_all() public{
uint amount = balances[msg.sender];
balances[msg.sender] = 0;
Receiver(msg.sender).send_funds{value: amount}();
}
}
contract TestWithoutBug{
mapping(address => uint) balances;
modifier nonReentrant(){
_;
}
function withdraw(uint amount) nonReentrant public{
require(amount <= balances[msg.sender]);
Receiver(msg.sender).send_funds{value: amount}();
balances[msg.sender] -= amount;
}
function withdraw_all() nonReentrant public{
uint amount = balances[msg.sender];
balances[msg.sender] = 0;
Receiver(msg.sender).send_funds{value: amount}();
}
}
contract TestWithBugInternal{
mapping(address => uint) balances;
modifier nonReentrant(){
_;
}
function withdraw(uint amount) nonReentrant public{
withdraw_internal(amount);
}
function withdraw_internal(uint amount) internal{
require(amount <= balances[msg.sender]);
Receiver(msg.sender).send_funds{value: amount}();
balances[msg.sender] -= amount;
}
function withdraw_all() public{
withdraw_all_internal();
}
function withdraw_all_internal() internal {
uint amount = balances[msg.sender];
balances[msg.sender] = 0;
Receiver(msg.sender).send_funds{value: amount}();
}
}
contract TestWithoutBugInternal{
mapping(address => uint) balances;
modifier nonReentrant(){
_;
}
function withdraw(uint amount) nonReentrant public{
withdraw_internal(amount);
}
function withdraw_internal(uint amount) internal{
require(amount <= balances[msg.sender]);
Receiver(msg.sender).send_funds{value: amount}();
balances[msg.sender] -= amount;
}
function withdraw_all() nonReentrant public{
withdraw_all_internal();
}
function withdraw_all_internal() internal {
uint amount = balances[msg.sender];
balances[msg.sender] = 0;
Receiver(msg.sender).send_funds{value: amount}();
}
}
contract TestBugWithPublicVariable{
mapping(address => uint) public balances;
modifier nonReentrant(){
_;
}
function withdraw(uint amount) nonReentrant public{
withdraw_internal(amount);
}
function withdraw_internal(uint amount) internal{
require(amount <= balances[msg.sender]);
Receiver(msg.sender).send_funds{value: amount}();
balances[msg.sender] -= amount;
}
}
contract TestWithBugNonReentrantRead{
mapping(address => uint) balances;
modifier nonReentrant(){
_;
}
function withdraw(uint amount) nonReentrant public{
require(amount <= balances[msg.sender]);
Receiver(msg.sender).send_funds{value: amount}();
balances[msg.sender] -= amount;
}
// Simulate a reentrancy that allows to read variable in a potential incorrect state during a reentrancy
// This is more likely to impact protocol like reentrancy
function read() public returns(uint){
uint amount = balances[msg.sender];
return amount;
}
}

@ -0,0 +1,981 @@
[
[
{
"elements": [
{
"type": "function",
"name": "withdraw",
"source_mapping": {
"start": 3089,
"length": 207,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
138,
139,
140,
141,
142
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBugNonReentrantRead",
"source_mapping": {
"start": 2959,
"length": 629,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
130,
131,
132,
133,
134,
135,
136,
137,
138,
139,
140,
141,
142,
143,
144,
145,
146,
147,
148,
149,
150,
151
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw(uint256)"
}
},
{
"type": "node",
"name": "Receiver(msg.sender).send_funds{value: amount}()",
"source_mapping": {
"start": 3200,
"length": 48,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
140
],
"starting_column": 10,
"ending_column": 58
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdraw",
"source_mapping": {
"start": 3089,
"length": 207,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
138,
139,
140,
141,
142
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBugNonReentrantRead",
"source_mapping": {
"start": 2959,
"length": 629,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
130,
131,
132,
133,
134,
135,
136,
137,
138,
139,
140,
141,
142,
143,
144,
145,
146,
147,
148,
149,
150,
151
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw(uint256)"
}
}
},
"additional_fields": {
"underlying_type": "external_calls"
}
},
{
"type": "node",
"name": "balances[msg.sender] -= amount",
"source_mapping": {
"start": 3259,
"length": 30,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
141
],
"starting_column": 10,
"ending_column": 40
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdraw",
"source_mapping": {
"start": 3089,
"length": 207,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
138,
139,
140,
141,
142
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBugNonReentrantRead",
"source_mapping": {
"start": 2959,
"length": 629,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
130,
131,
132,
133,
134,
135,
136,
137,
138,
139,
140,
141,
142,
143,
144,
145,
146,
147,
148,
149,
150,
151
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw(uint256)"
}
}
},
"additional_fields": {
"underlying_type": "variables_written",
"variable_name": "balances"
}
}
],
"description": "Reentrancy in TestWithBugNonReentrantRead.withdraw(uint256) (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#138-142):\n\tExternal calls:\n\t- Receiver(msg.sender).send_funds{value: amount}() (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#140)\n\tState variables written after the call(s):\n\t- balances[msg.sender] -= amount (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#141)\n\tTestWithBugNonReentrantRead.balances (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#132) can be used in cross function reentrancies:\n\t- TestWithBugNonReentrantRead.read() (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#146-149)\n",
"markdown": "Reentrancy in [TestWithBugNonReentrantRead.withdraw(uint256)](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L138-L142):\n\tExternal calls:\n\t- [Receiver(msg.sender).send_funds{value: amount}()](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L140)\n\tState variables written after the call(s):\n\t- [balances[msg.sender] -= amount](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L141)\n\t[TestWithBugNonReentrantRead.balances](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L132) can be used in cross function reentrancies:\n\t- [TestWithBugNonReentrantRead.read()](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L146-L149)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L138-L142",
"id": "0b2149d8ea8554c24092bad5ce3061d661d4f0447d5d96716893538474bca40f",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"
},
{
"elements": [
{
"type": "function",
"name": "withdraw_internal",
"source_mapping": {
"start": 1320,
"length": 205,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
62,
63,
64,
65,
66
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBugInternal",
"source_mapping": {
"start": 1100,
"length": 698,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw_internal(uint256)"
}
},
{
"type": "node",
"name": "Receiver(msg.sender).send_funds{value: amount}()",
"source_mapping": {
"start": 1429,
"length": 48,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
64
],
"starting_column": 10,
"ending_column": 58
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdraw_internal",
"source_mapping": {
"start": 1320,
"length": 205,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
62,
63,
64,
65,
66
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBugInternal",
"source_mapping": {
"start": 1100,
"length": 698,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw_internal(uint256)"
}
}
},
"additional_fields": {
"underlying_type": "external_calls"
}
},
{
"type": "node",
"name": "balances[msg.sender] -= amount",
"source_mapping": {
"start": 1488,
"length": 30,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
65
],
"starting_column": 10,
"ending_column": 40
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdraw_internal",
"source_mapping": {
"start": 1320,
"length": 205,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
62,
63,
64,
65,
66
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBugInternal",
"source_mapping": {
"start": 1100,
"length": 698,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw_internal(uint256)"
}
}
},
"additional_fields": {
"underlying_type": "variables_written",
"variable_name": "balances"
}
}
],
"description": "Reentrancy in TestWithBugInternal.withdraw_internal(uint256) (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#62-66):\n\tExternal calls:\n\t- Receiver(msg.sender).send_funds{value: amount}() (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#64)\n\tState variables written after the call(s):\n\t- balances[msg.sender] -= amount (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#65)\n\tTestWithBugInternal.balances (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#52) can be used in cross function reentrancies:\n\t- TestWithBugInternal.withdraw_all_internal() (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#72-76)\n",
"markdown": "Reentrancy in [TestWithBugInternal.withdraw_internal(uint256)](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L62-L66):\n\tExternal calls:\n\t- [Receiver(msg.sender).send_funds{value: amount}()](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L64)\n\tState variables written after the call(s):\n\t- [balances[msg.sender] -= amount](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L65)\n\t[TestWithBugInternal.balances](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L52) can be used in cross function reentrancies:\n\t- [TestWithBugInternal.withdraw_all_internal()](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L72-L76)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L62-L66",
"id": "7d618f027540d61d9af79a3a9475677476d1c4d7ad1be68ff8026f6c0d4cdc82",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"
},
{
"elements": [
{
"type": "function",
"name": "withdraw_internal",
"source_mapping": {
"start": 2749,
"length": 205,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
122,
123,
124,
125,
126
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestBugWithPublicVariable",
"source_mapping": {
"start": 2516,
"length": 441,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
110,
111,
112,
113,
114,
115,
116,
117,
118,
119,
120,
121,
122,
123,
124,
125,
126,
127,
128
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw_internal(uint256)"
}
},
{
"type": "node",
"name": "Receiver(msg.sender).send_funds{value: amount}()",
"source_mapping": {
"start": 2858,
"length": 48,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
124
],
"starting_column": 10,
"ending_column": 58
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdraw_internal",
"source_mapping": {
"start": 2749,
"length": 205,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
122,
123,
124,
125,
126
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestBugWithPublicVariable",
"source_mapping": {
"start": 2516,
"length": 441,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
110,
111,
112,
113,
114,
115,
116,
117,
118,
119,
120,
121,
122,
123,
124,
125,
126,
127,
128
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw_internal(uint256)"
}
}
},
"additional_fields": {
"underlying_type": "external_calls"
}
},
{
"type": "node",
"name": "balances[msg.sender] -= amount",
"source_mapping": {
"start": 2917,
"length": 30,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
125
],
"starting_column": 10,
"ending_column": 40
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdraw_internal",
"source_mapping": {
"start": 2749,
"length": 205,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
122,
123,
124,
125,
126
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestBugWithPublicVariable",
"source_mapping": {
"start": 2516,
"length": 441,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
110,
111,
112,
113,
114,
115,
116,
117,
118,
119,
120,
121,
122,
123,
124,
125,
126,
127,
128
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw_internal(uint256)"
}
}
},
"additional_fields": {
"underlying_type": "variables_written",
"variable_name": "balances"
}
}
],
"description": "Reentrancy in TestBugWithPublicVariable.withdraw_internal(uint256) (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#122-126):\n\tExternal calls:\n\t- Receiver(msg.sender).send_funds{value: amount}() (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#124)\n\tState variables written after the call(s):\n\t- balances[msg.sender] -= amount (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#125)\n\tTestBugWithPublicVariable.balances (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#112) can be used in cross function reentrancies:\n\t- TestBugWithPublicVariable.balances (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#112)\n",
"markdown": "Reentrancy in [TestBugWithPublicVariable.withdraw_internal(uint256)](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L122-L126):\n\tExternal calls:\n\t- [Receiver(msg.sender).send_funds{value: amount}()](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L124)\n\tState variables written after the call(s):\n\t- [balances[msg.sender] -= amount](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L125)\n\t[TestBugWithPublicVariable.balances](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L112) can be used in cross function reentrancies:\n\t- [TestBugWithPublicVariable.balances](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L112)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L122-L126",
"id": "a3e52c882aa9fb88119aa3507f4158436bfe3f1abee0828665afa41213587097",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"
},
{
"elements": [
{
"type": "function",
"name": "withdraw",
"source_mapping": {
"start": 181,
"length": 207,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
13,
14,
15,
16,
17
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBug",
"source_mapping": {
"start": 67,
"length": 506,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw(uint256)"
}
},
{
"type": "node",
"name": "Receiver(msg.sender).send_funds{value: amount}()",
"source_mapping": {
"start": 292,
"length": 48,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
15
],
"starting_column": 10,
"ending_column": 58
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdraw",
"source_mapping": {
"start": 181,
"length": 207,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
13,
14,
15,
16,
17
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBug",
"source_mapping": {
"start": 67,
"length": 506,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw(uint256)"
}
}
},
"additional_fields": {
"underlying_type": "external_calls"
}
},
{
"type": "node",
"name": "balances[msg.sender] -= amount",
"source_mapping": {
"start": 351,
"length": 30,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
16
],
"starting_column": 10,
"ending_column": 40
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "withdraw",
"source_mapping": {
"start": 181,
"length": 207,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
13,
14,
15,
16,
17
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "TestWithBug",
"source_mapping": {
"start": 67,
"length": 506,
"filename_relative": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol",
"is_dependency": false,
"lines": [
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "withdraw(uint256)"
}
}
},
"additional_fields": {
"underlying_type": "variables_written",
"variable_name": "balances"
}
}
],
"description": "Reentrancy in TestWithBug.withdraw(uint256) (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#13-17):\n\tExternal calls:\n\t- Receiver(msg.sender).send_funds{value: amount}() (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#15)\n\tState variables written after the call(s):\n\t- balances[msg.sender] -= amount (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#16)\n\tTestWithBug.balances (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#7) can be used in cross function reentrancies:\n\t- TestWithBug.withdraw_all() (tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#19-23)\n",
"markdown": "Reentrancy in [TestWithBug.withdraw(uint256)](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L13-L17):\n\tExternal calls:\n\t- [Receiver(msg.sender).send_funds{value: amount}()](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L15)\n\tState variables written after the call(s):\n\t- [balances[msg.sender] -= amount](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L16)\n\t[TestWithBug.balances](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L7) can be used in cross function reentrancies:\n\t- [TestWithBug.withdraw_all()](tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L19-L23)\n",
"first_markdown_element": "tests/detectors/reentrancy-eth/0.8.10/reentrancy_with_non_reentrant.sol#L13-L17",
"id": "bcfa65e776908d618f202fa48f03dde3fbf8397b752d2e8cc3c8e46019e9e174",
"check": "reentrancy-eth",
"impact": "High",
"confidence": "Medium"
}
]
]

File diff suppressed because one or more lines are too long

@ -4,22 +4,21 @@
"elements": [
{
"type": "function",
"name": "bad0",
"name": "bad1",
"source_mapping": {
"start": 326,
"length": 153,
"start": 485,
"length": 158,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
16,
17,
18,
19,
20,
21,
22
24,
25,
26,
27,
28,
29
],
"starting_column": 5,
"ending_column": 6
@ -78,44 +77,43 @@
"ending_column": 2
}
},
"signature": "bad0()"
"signature": "bad1(address)"
}
},
{
"type": "node",
"name": "! (msg.sender.call())",
"name": "success = msg.sender.call()",
"source_mapping": {
"start": 391,
"length": 20,
"start": 560,
"length": 34,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
18
26
],
"starting_column": 13,
"ending_column": 33
"starting_column": 9,
"ending_column": 43
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad0",
"name": "bad1",
"source_mapping": {
"start": 326,
"length": 153,
"start": 485,
"length": 158,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
16,
17,
18,
19,
20,
21,
22
24,
25,
26,
27,
28,
29
],
"starting_column": 5,
"ending_column": 6
@ -174,7 +172,7 @@
"ending_column": 2
}
},
"signature": "bad0()"
"signature": "bad1(address)"
}
}
},
@ -184,39 +182,38 @@
},
{
"type": "node",
"name": "notCalled = false",
"name": "bad0()",
"source_mapping": {
"start": 455,
"length": 17,
"start": 630,
"length": 6,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
21
28
],
"starting_column": 9,
"ending_column": 26
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad0",
"name": "bad1",
"source_mapping": {
"start": 326,
"length": 153,
"start": 485,
"length": 158,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
16,
17,
18,
19,
20,
21,
22
24,
25,
26,
27,
28,
29
],
"starting_column": 5,
"ending_column": 6
@ -275,138 +272,49 @@
"ending_column": 2
}
},
"signature": "bad0()"
"signature": "bad1(address)"
}
}
},
"additional_fields": {
"underlying_type": "variables_written",
"variable_name": "notCalled"
"underlying_type": "external_calls"
}
}
],
"description": "Reentrancy in ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#16-22):\n\tExternal calls:\n\t- ! (msg.sender.call()) (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#21)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L16-L22):\n\tExternal calls:\n\t- [! (msg.sender.call())](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L21)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L16-L22",
"id": "296bbfc5c41b40046e8fc0563e89099df3ff17caf0bd3ff8dde0271aacd8d981",
"check": "reentrancy-no-eth",
"impact": "Medium",
"confidence": "Medium"
},
{
"elements": [
},
{
"type": "function",
"name": "bad1",
"type": "node",
"name": "! (msg.sender.call())",
"source_mapping": {
"start": 485,
"length": 158,
"start": 391,
"length": 20,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
24,
25,
26,
27,
28,
29
18
],
"starting_column": 5,
"ending_column": 6
"starting_column": 13,
"ending_column": 33
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "ReentrancyWrite",
"type": "function",
"name": "bad0",
"source_mapping": {
"start": 28,
"length": 776,
"start": 326,
"length": 153,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "bad1(address)"
}
},
{
"type": "node",
"name": "success = msg.sender.call()",
"source_mapping": {
"start": 560,
"length": 34,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
26
],
"starting_column": 9,
"ending_column": 43
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 485,
"length": 158,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
24,
25,
26,
27,
28,
29
22
],
"starting_column": 5,
"ending_column": 6
@ -465,12 +373,12 @@
"ending_column": 2
}
},
"signature": "bad1(address)"
"signature": "bad0()"
}
}
},
"additional_fields": {
"underlying_type": "external_calls"
"underlying_type": "external_calls_sending_eth"
}
},
{
@ -570,24 +478,25 @@
}
},
"additional_fields": {
"underlying_type": "external_calls"
"underlying_type": "variables_written",
"variable_name": "notCalled"
}
},
{
"type": "node",
"name": "! (msg.sender.call())",
"name": "notCalled = false",
"source_mapping": {
"start": 391,
"length": 20,
"start": 455,
"length": 17,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
18
21
],
"starting_column": 13,
"ending_column": 33
"starting_column": 9,
"ending_column": 26
},
"type_specific_fields": {
"parent": {
@ -671,43 +580,135 @@
}
},
"additional_fields": {
"underlying_type": "external_calls_sending_eth"
"underlying_type": "variables_written",
"variable_name": "notCalled"
}
},
}
],
"description": "Reentrancy in ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#24-29):\n\tExternal calls:\n\t- success = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#26)\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#28)\n\t\t- ! (msg.sender.call()) (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#28)\n\t\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#21)\n\tReentrancyWrite.notCalled (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#4) can be used in cross function reentrancies:\n\t- ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#16-22)\n\t- ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#24-29)\n\t- ReentrancyWrite.constructor(address) (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#7-14)\n\t- ReentrancyWrite.good() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#31-37)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L24-L29):\n\tExternal calls:\n\t- [success = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L26)\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L28)\n\t\t- [! (msg.sender.call())](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L28)\n\t\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L21)\n\t[ReentrancyWrite.notCalled](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L4) can be used in cross function reentrancies:\n\t- [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L16-L22)\n\t- [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L24-L29)\n\t- [ReentrancyWrite.constructor(address)](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L7-L14)\n\t- [ReentrancyWrite.good()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L31-L37)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L24-L29",
"id": "3abbc9e8f73096dd53d7a40513439b00f2bcfb9c594446c25eb8f0845a83f634",
"check": "reentrancy-no-eth",
"impact": "Medium",
"confidence": "Medium"
},
{
"elements": [
{
"type": "node",
"name": "bad0()",
"type": "function",
"name": "bad0",
"source_mapping": {
"start": 630,
"length": 6,
"start": 326,
"length": 153,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
28
16,
17,
18,
19,
20,
21,
22
],
"starting_column": 9,
"ending_column": 15
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad1",
"type": "contract",
"name": "ReentrancyWrite",
"source_mapping": {
"start": 485,
"length": 158,
"start": 28,
"length": 776,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "bad0()"
}
},
{
"type": "node",
"name": "! (msg.sender.call())",
"source_mapping": {
"start": 391,
"length": 20,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
18
],
"starting_column": 13,
"ending_column": 33
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad0",
"source_mapping": {
"start": 326,
"length": 153,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol",
"is_dependency": false,
"lines": [
16,
17,
18,
19,
20,
21,
22
],
"starting_column": 5,
"ending_column": 6
@ -766,13 +767,12 @@
"ending_column": 2
}
},
"signature": "bad1(address)"
"signature": "bad0()"
}
}
},
"additional_fields": {
"underlying_type": "variables_written",
"variable_name": "notCalled"
"underlying_type": "external_calls"
}
},
{
@ -878,10 +878,10 @@
}
}
],
"description": "Reentrancy in ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#24-29):\n\tExternal calls:\n\t- success = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#26)\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#28)\n\t\t- ! (msg.sender.call()) (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#28)\n\t\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#21)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L24-L29):\n\tExternal calls:\n\t- [success = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L26)\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L28)\n\t\t- [! (msg.sender.call())](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L28)\n\t\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L21)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L24-L29",
"id": "93b771e9737b42c786392b01e24457616ec7e54b5dd7714c96a1e67b9dd535f3",
"description": "Reentrancy in ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#16-22):\n\tExternal calls:\n\t- ! (msg.sender.call()) (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#21)\n\tReentrancyWrite.notCalled (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#4) can be used in cross function reentrancies:\n\t- ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#16-22)\n\t- ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#24-29)\n\t- ReentrancyWrite.constructor(address) (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#7-14)\n\t- ReentrancyWrite.good() (tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#31-37)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L16-L22):\n\tExternal calls:\n\t- [! (msg.sender.call())](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L21)\n\t[ReentrancyWrite.notCalled](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L4) can be used in cross function reentrancies:\n\t- [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L16-L22)\n\t- [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L24-L29)\n\t- [ReentrancyWrite.constructor(address)](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L7-L14)\n\t- [ReentrancyWrite.good()](tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L31-L37)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.4.25/reentrancy-write.sol#L16-L22",
"id": "849ca5d32a80a76091f9049ebde3e9267a1c1bc22fd11197246e748b56a31f3b",
"check": "reentrancy-no-eth",
"impact": "Medium",
"confidence": "Medium"

@ -599,10 +599,10 @@
}
}
],
"description": "Reentrancy in ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#25-30):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#27)\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#29)\n\t\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#29)\n\t\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#22)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L25-L30):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L27)\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L29)\n\t\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L29)\n\t\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L22)\n",
"description": "Reentrancy in ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#25-30):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#27)\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#29)\n\t\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#29)\n\t\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#22)\n\tReentrancyWrite.notCalled (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#4) can be used in cross function reentrancies:\n\t- ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#16-23)\n\t- ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#25-30)\n\t- ReentrancyWrite.constructor(address) (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#7-14)\n\t- ReentrancyWrite.good() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#32-39)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L25-L30):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L27)\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L29)\n\t\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L29)\n\t\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L22)\n\t[ReentrancyWrite.notCalled](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L4) can be used in cross function reentrancies:\n\t- [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L16-L23)\n\t- [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L25-L30)\n\t- [ReentrancyWrite.constructor(address)](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L7-L14)\n\t- [ReentrancyWrite.good()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L32-L39)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L25-L30",
"id": "9fbfafd0d47ce4f4ead524570f382093c186c4e9e5e96ce0067fce3ffb6dc74a",
"id": "80cbbc2ca9b1ec618f677d49ad8c55c3e7b458a8f8f2d5083e5388dabf526d6f",
"check": "reentrancy-no-eth",
"impact": "Medium",
"confidence": "Medium"
@ -901,10 +901,10 @@
}
}
],
"description": "Reentrancy in ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#16-23):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#22)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L16-L23):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L22)\n",
"description": "Reentrancy in ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#16-23):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#22)\n\tReentrancyWrite.notCalled (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#4) can be used in cross function reentrancies:\n\t- ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#16-23)\n\t- ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#25-30)\n\t- ReentrancyWrite.constructor(address) (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#7-14)\n\t- ReentrancyWrite.good() (tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#32-39)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L16-L23):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L22)\n\t[ReentrancyWrite.notCalled](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L4) can be used in cross function reentrancies:\n\t- [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L16-L23)\n\t- [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L25-L30)\n\t- [ReentrancyWrite.constructor(address)](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L7-L14)\n\t- [ReentrancyWrite.good()](tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L32-L39)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.5.16/reentrancy-write.sol#L16-L23",
"id": "c9ba81d76d46579f9e78ac96b1aae43b71f2d4a96d4c47b2fab9831bf0f15a8f",
"id": "aec3401a9ebdcd0961e5a0f704379be83fc18e5c8ea5e98641b0ea1783184a3d",
"check": "reentrancy-no-eth",
"impact": "Medium",
"confidence": "Medium"

@ -294,10 +294,10 @@
}
}
],
"description": "Reentrancy in ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#16-23):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#22)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L16-L23):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L22)\n",
"description": "Reentrancy in ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#16-23):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#22)\n\tReentrancyWrite.notCalled (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#4) can be used in cross function reentrancies:\n\t- ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#16-23)\n\t- ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#25-30)\n\t- ReentrancyWrite.constructor(address) (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#7-14)\n\t- ReentrancyWrite.good() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#32-39)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L16-L23):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L22)\n\t[ReentrancyWrite.notCalled](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L4) can be used in cross function reentrancies:\n\t- [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L16-L23)\n\t- [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L25-L30)\n\t- [ReentrancyWrite.constructor(address)](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L7-L14)\n\t- [ReentrancyWrite.good()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L32-L39)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L16-L23",
"id": "6d19938cb98129ec5abb0fcde1a08ea92c6ab0125e210a1d4c10f27e9a9419cb",
"id": "92d6df62568c8094a9c5cd5c7e4c7162054281244d3d3a1d4efe7df14d18a35a",
"check": "reentrancy-no-eth",
"impact": "Medium",
"confidence": "Medium"
@ -901,10 +901,10 @@
}
}
],
"description": "Reentrancy in ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#25-30):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#27)\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#29)\n\t\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#29)\n\t\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#22)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L25-L30):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L27)\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L29)\n\t\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L29)\n\t\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L22)\n",
"description": "Reentrancy in ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#25-30):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#27)\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#29)\n\t\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#18)\n\tState variables written after the call(s):\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#29)\n\t\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#22)\n\tReentrancyWrite.notCalled (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#4) can be used in cross function reentrancies:\n\t- ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#16-23)\n\t- ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#25-30)\n\t- ReentrancyWrite.constructor(address) (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#7-14)\n\t- ReentrancyWrite.good() (tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#32-39)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L25-L30):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L27)\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L29)\n\t\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L18)\n\tState variables written after the call(s):\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L29)\n\t\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L22)\n\t[ReentrancyWrite.notCalled](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L4) can be used in cross function reentrancies:\n\t- [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L16-L23)\n\t- [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L25-L30)\n\t- [ReentrancyWrite.constructor(address)](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L7-L14)\n\t- [ReentrancyWrite.good()](tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L32-L39)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.6.11/reentrancy-write.sol#L25-L30",
"id": "dfc70c3670d28f163af1fd624da8ace78193a8309e4c442462e7bc96e88eeae1",
"id": "b0372b9d2879e62eb13c185a89ae1e80653ef3339cb5521630a9717e1592100e",
"check": "reentrancy-no-eth",
"impact": "Medium",
"confidence": "Medium"

@ -4,21 +4,23 @@
"elements": [
{
"type": "function",
"name": "bad1",
"name": "bad0",
"source_mapping": {
"start": 577,
"length": 161,
"start": 383,
"length": 188,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
29,
30,
31,
32,
33,
34
20,
21,
22,
23,
24,
25,
26,
27
],
"starting_column": 5,
"ending_column": 6
@ -79,21 +81,21 @@
"ending_column": 2
}
},
"signature": "bad1(address)"
"signature": "bad0()"
}
},
{
"type": "node",
"name": "(success) = msg.sender.call()",
"source_mapping": {
"start": 652,
"start": 444,
"length": 37,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
31
22
],
"starting_column": 9,
"ending_column": 46
@ -101,21 +103,23 @@
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad1",
"name": "bad0",
"source_mapping": {
"start": 577,
"length": 161,
"start": 383,
"length": 188,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
29,
30,
31,
32,
33,
34
20,
21,
22,
23,
24,
25,
26,
27
],
"starting_column": 5,
"ending_column": 6
@ -176,7 +180,7 @@
"ending_column": 2
}
},
"signature": "bad1(address)"
"signature": "bad0()"
}
}
},
@ -186,38 +190,40 @@
},
{
"type": "node",
"name": "bad0()",
"name": "notCalled = false",
"source_mapping": {
"start": 725,
"length": 6,
"start": 547,
"length": 17,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
33
26
],
"starting_column": 9,
"ending_column": 15
"ending_column": 26
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad1",
"name": "bad0",
"source_mapping": {
"start": 577,
"length": 161,
"start": 383,
"length": 188,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
29,
30,
31,
32,
33,
34
20,
21,
22,
23,
24,
25,
26,
27
],
"starting_column": 5,
"ending_column": 6
@ -278,42 +284,72 @@
"ending_column": 2
}
},
"signature": "bad1(address)"
"signature": "bad0()"
}
}
},
"additional_fields": {
"underlying_type": "external_calls"
"underlying_type": "variables_written",
"variable_name": "notCalled"
}
},
}
],
"description": "Reentrancy in ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#20-27):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#22)\n\tState variables written after the call(s):\n\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#26)\n\tReentrancyWrite.notCalled (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#8) can be used in cross function reentrancies:\n\t- ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#20-27)\n\t- ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#29-34)\n\t- ReentrancyWrite.constructor(address) (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#11-18)\n\t- ReentrancyWrite.good() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#36-43)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L20-L27):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L22)\n\tState variables written after the call(s):\n\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L26)\n\t[ReentrancyWrite.notCalled](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L8) can be used in cross function reentrancies:\n\t- [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L20-L27)\n\t- [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L29-L34)\n\t- [ReentrancyWrite.constructor(address)](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L11-L18)\n\t- [ReentrancyWrite.good()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L36-L43)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L20-L27",
"id": "24a6dbb0286f86f1dac424bdc447262dcbfda1a1c637c4c0f21885b82eb9af24",
"check": "reentrancy-no-eth",
"impact": "Medium",
"confidence": "Medium"
},
{
"elements": [
{
"type": "node",
"name": "(success) = msg.sender.call()",
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 444,
"length": 37,
"start": 577,
"length": 161,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
22
29,
30,
31,
32,
33,
34
],
"starting_column": 9,
"ending_column": 46
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad0",
"type": "contract",
"name": "ReentrancyWrite",
"source_mapping": {
"start": 383,
"length": 188,
"start": 82,
"length": 852,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
@ -321,7 +357,67 @@
24,
25,
26,
27
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "bad1(address)"
}
},
{
"type": "node",
"name": "(success) = msg.sender.call()",
"source_mapping": {
"start": 652,
"length": 37,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
31
],
"starting_column": 9,
"ending_column": 46
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 577,
"length": 161,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
29,
30,
31,
32,
33,
34
],
"starting_column": 5,
"ending_column": 6
@ -382,12 +478,12 @@
"ending_column": 2
}
},
"signature": "bad0()"
"signature": "bad1(address)"
}
}
},
"additional_fields": {
"underlying_type": "external_calls_sending_eth"
"underlying_type": "external_calls"
}
},
{
@ -489,25 +585,24 @@
}
},
"additional_fields": {
"underlying_type": "variables_written",
"variable_name": "notCalled"
"underlying_type": "external_calls"
}
},
{
"type": "node",
"name": "notCalled = false",
"name": "(success) = msg.sender.call()",
"source_mapping": {
"start": 547,
"length": 17,
"start": 444,
"length": 37,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
26
22
],
"starting_column": 9,
"ending_column": 26
"ending_column": 46
},
"type_specific_fields": {
"parent": {
@ -594,139 +689,43 @@
}
},
"additional_fields": {
"underlying_type": "variables_written",
"variable_name": "notCalled"
"underlying_type": "external_calls_sending_eth"
}
}
],
"description": "Reentrancy in ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#29-34):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#31)\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#33)\n\t\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#22)\n\tState variables written after the call(s):\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#33)\n\t\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#26)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L29-L34):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L31)\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L33)\n\t\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L22)\n\tState variables written after the call(s):\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L33)\n\t\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L26)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L29-L34",
"id": "11273f8e5ccbb848ea0de9b7c15e3fb66deb7c061265f88b8aa7646eed935c0e",
"check": "reentrancy-no-eth",
"impact": "Medium",
"confidence": "Medium"
},
{
"elements": [
},
{
"type": "function",
"name": "bad0",
"type": "node",
"name": "bad0()",
"source_mapping": {
"start": 383,
"length": 188,
"start": 725,
"length": 6,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
20,
21,
22,
23,
24,
25,
26,
27
33
],
"starting_column": 5,
"ending_column": 6
"starting_column": 9,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "ReentrancyWrite",
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 82,
"length": 852,
"start": 577,
"length": 161,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "bad0()"
}
},
{
"type": "node",
"name": "(success) = msg.sender.call()",
"source_mapping": {
"start": 444,
"length": 37,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
22
],
"starting_column": 9,
"ending_column": 46
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad0",
"source_mapping": {
"start": 383,
"length": 188,
"filename_relative": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol",
"is_dependency": false,
"lines": [
20,
21,
22,
23,
24,
25,
26,
27
34
],
"starting_column": 5,
"ending_column": 6
@ -787,12 +786,13 @@
"ending_column": 2
}
},
"signature": "bad0()"
"signature": "bad1(address)"
}
}
},
"additional_fields": {
"underlying_type": "external_calls"
"underlying_type": "variables_written",
"variable_name": "notCalled"
}
},
{
@ -901,10 +901,10 @@
}
}
],
"description": "Reentrancy in ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#20-27):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#22)\n\tState variables written after the call(s):\n\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#26)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L20-L27):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L22)\n\tState variables written after the call(s):\n\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L26)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L20-L27",
"id": "ef995e89d54c7b577af2ca26540e01da65ac0e2466d6d7a58e4d11e9211b12a4",
"description": "Reentrancy in ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#29-34):\n\tExternal calls:\n\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#31)\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#33)\n\t\t- (success) = msg.sender.call() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#22)\n\tState variables written after the call(s):\n\t- bad0() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#33)\n\t\t- notCalled = false (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#26)\n\tReentrancyWrite.notCalled (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#8) can be used in cross function reentrancies:\n\t- ReentrancyWrite.bad0() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#20-27)\n\t- ReentrancyWrite.bad1(address) (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#29-34)\n\t- ReentrancyWrite.constructor(address) (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#11-18)\n\t- ReentrancyWrite.good() (tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#36-43)\n",
"markdown": "Reentrancy in [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L29-L34):\n\tExternal calls:\n\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L31)\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L33)\n\t\t- [(success) = msg.sender.call()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L22)\n\tState variables written after the call(s):\n\t- [bad0()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L33)\n\t\t- [notCalled = false](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L26)\n\t[ReentrancyWrite.notCalled](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L8) can be used in cross function reentrancies:\n\t- [ReentrancyWrite.bad0()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L20-L27)\n\t- [ReentrancyWrite.bad1(address)](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L29-L34)\n\t- [ReentrancyWrite.constructor(address)](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L11-L18)\n\t- [ReentrancyWrite.good()](tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L36-L43)\n",
"first_markdown_element": "tests/detectors/reentrancy-no-eth/0.7.6/reentrancy-write.sol#L29-L34",
"id": "e8259d1bbe21b2c12ea23f8ed1c67b9a8f63a1828d3b91db1f7b78ddd43ef7d6",
"check": "reentrancy-no-eth",
"impact": "Medium",
"confidence": "Medium"

@ -1,506 +1,3 @@
[
[
{
"elements": [
{
"type": "contract",
"name": "A",
"source_mapping": {
"start": 25,
"length": 2256,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45
],
"starting_column": 1,
"ending_column": 2
}
},
{
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 601,
"length": 170,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
15,
16,
17
],
"starting_column": 3,
"ending_column": 4
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "A",
"source_mapping": {
"start": 25,
"length": 2256,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "bad1(int128[3])"
}
},
{
"type": "node",
"name": "intArray = userArray",
"source_mapping": {
"start": 746,
"length": 20,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
16
],
"starting_column": 5,
"ending_column": 25
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 601,
"length": 170,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
15,
16,
17
],
"starting_column": 3,
"ending_column": 4
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "A",
"source_mapping": {
"start": 25,
"length": 2256,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "bad1(int128[3])"
}
}
}
}
],
"description": "Contract A (tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#3-45) \n\t- Function A.bad1(int128[3]) (tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#15-17)\n\t\t- intArray = userArray (tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#16) has a storage signed integer array assignment\n",
"markdown": "Contract [A](tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#L3-L45) \n\t- Function [A.bad1(int128[3])](tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#L15-L17)\n\t\t- [intArray = userArray](tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#L16) has a storage signed integer array assignment\n",
"first_markdown_element": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#L3-L45",
"id": "7ba5efbfb61ba63a7ac01d376a0cede2fda18c2a2d8604c4a82cccec92ae2bdb",
"check": "storage-array",
"impact": "High",
"confidence": "Medium"
},
{
"elements": [
{
"type": "contract",
"name": "A",
"source_mapping": {
"start": 25,
"length": 2256,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45
],
"starting_column": 1,
"ending_column": 2
}
},
{
"type": "function",
"name": "bad0",
"source_mapping": {
"start": 355,
"length": 132,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
10,
11,
12
],
"starting_column": 3,
"ending_column": 4
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "A",
"source_mapping": {
"start": 25,
"length": 2256,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "bad0()"
}
},
{
"type": "node",
"name": "intArray = (- 1,- 2,- 3)",
"source_mapping": {
"start": 384,
"length": 23,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
11
],
"starting_column": 5,
"ending_column": 28
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad0",
"source_mapping": {
"start": 355,
"length": 132,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
10,
11,
12
],
"starting_column": 3,
"ending_column": 4
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "A",
"source_mapping": {
"start": 25,
"length": 2256,
"filename_relative": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol",
"is_dependency": false,
"lines": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45
],
"starting_column": 1,
"ending_column": 2
}
},
"signature": "bad0()"
}
}
}
}
],
"description": "Contract A (tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#3-45) \n\t- Function A.bad0() (tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#10-12)\n\t\t- intArray = (- 1,- 2,- 3) (tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#11) has a storage signed integer array assignment\n",
"markdown": "Contract [A](tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#L3-L45) \n\t- Function [A.bad0()](tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#L10-L12)\n\t\t- [intArray = (- 1,- 2,- 3)](tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#L11) has a storage signed integer array assignment\n",
"first_markdown_element": "tests/detectors/storage-array/0.5.10/storage_signed_integer_array.sol#L3-L45",
"id": "da870be9a396bc52d2f6f8caeb00e6b8809ad1b6fb4c24a019568257b3404a2f",
"check": "storage-array",
"impact": "High",
"confidence": "Medium"
}
]
[]
]

@ -362,6 +362,10 @@ ALL_TEST_OBJECTS = [
"DAO.sol",
"0.4.25",
),
# Test the nonReentrant filtering
Test(all_detectors.ReentrancyEth, "reentrancy_with_non_reentrant.sol", "0.8.10"),
# Test parse_ignore_comments
Test(all_detectors.ReentrancyEth, "reentrancy_filtered_comments.sol", "0.8.10"),
Test(
all_detectors.UninitializedStorageVars,
"uninitialized_storage_pointer.sol",

@ -244,6 +244,7 @@ def test_functions():
def test_function_can_send_eth():
solc_select.switch_global_version("0.6.12", always_install=True)
slither = Slither("tests/test_function.sol")
compilation_unit = slither.compilation_units[0]
functions = compilation_unit.get_contract_from_name("TestFunctionCanSendEth")[
@ -266,6 +267,22 @@ def test_function_can_send_eth():
assert functions["highlevel_call_via_external()"].can_send_eth() is False
def test_reentrant():
solc_select.switch_global_version("0.8.10", always_install=True)
slither = Slither("tests/test_function_reentrant.sol")
compilation_unit = slither.compilation_units[0]
functions = compilation_unit.get_contract_from_name("TestReentrant")[
0
].available_functions_as_dict()
assert functions["is_reentrant()"].is_reentrant
assert not functions["is_non_reentrant()"].is_reentrant
assert not functions["internal_and_not_reentrant()"].is_reentrant
assert not functions["internal_and_not_reentrant2()"].is_reentrant
assert functions["internal_and_could_be_reentrant()"].is_reentrant
assert functions["internal_and_reentrant()"].is_reentrant
def test_public_variable() -> None:
solc_select.switch_global_version("0.6.12", always_install=True)
slither = Slither("tests/test_function.sol")

@ -0,0 +1,36 @@
contract TestReentrant{
modifier nonReentrant(){
_;
}
function is_reentrant() public{
internal_and_could_be_reentrant();
internal_and_reentrant();
}
function is_non_reentrant() nonReentrant() public{
internal_and_could_be_reentrant();
internal_and_not_reentrant2();
}
function internal_and_not_reentrant() nonReentrant() internal{
}
function internal_and_not_reentrant2() internal{
}
// Called by a protected and unprotected function
function internal_and_could_be_reentrant() internal{
}
// Called by a protected and unprotected function
function internal_and_reentrant() internal{
}
}
Loading…
Cancel
Save