Merge branch 'dev' into dev-fix-usingfor

pull/1378/head
Simone 2 years ago
commit fe2b0cacf1
  1. 2
      .github/workflows/pip-audit.yml
  2. 4
      setup.py
  3. 17
      slither/core/declarations/contract.py
  4. 1
      slither/core/declarations/solidity_variables.py
  5. 116
      slither/core/scope/scope.py
  6. 1
      slither/detectors/all_detectors.py
  7. 2
      slither/detectors/attributes/constant_pragma.py
  8. 3
      slither/detectors/naming_convention/naming_convention.py
  9. 60
      slither/detectors/variables/var_read_using_this.py
  10. 4
      slither/printers/functions/authorization.py
  11. 6
      slither/printers/summary/data_depenency.py
  12. 18
      slither/printers/summary/evm.py
  13. 18
      slither/printers/summary/function.py
  14. 2
      slither/printers/summary/modifier_calls.py
  15. 2
      slither/printers/summary/require_calls.py
  16. 19
      slither/slithir/convert.py
  17. 1
      slither/slithir/operations/__init__.py
  18. 27
      slither/slithir/operations/push.py
  19. 5
      slither/slithir/utils/ssa.py
  20. 21
      slither/solc_parsing/declarations/contract.py
  21. 4
      slither/solc_parsing/declarations/function.py
  22. 2
      slither/solc_parsing/declarations/modifier.py
  23. 7
      slither/solc_parsing/slither_compilation_unit_solc.py
  24. 3
      slither/tools/similarity/encode.py
  25. 109
      slither/tools/upgradeability/__main__.py
  26. 2
      slither/tools/upgradeability/checks/variables_order.py
  27. 174
      slither/utils/expression_manipulations.py
  28. BIN
      tests/ast-parsing/compile/top-level-struct-0.8.0.sol-0.8.0-compact.zip
  29. 3
      tests/ast-parsing/expected/top-level-struct-0.8.0.sol-0.8.0-compact.json
  30. 18
      tests/ast-parsing/top-level-struct-0.8.0.sol
  31. 16
      tests/custom_comments/upgrade.sol
  32. 2
      tests/detectors/naming-convention/0.4.25/naming_convention.sol
  33. 300
      tests/detectors/naming-convention/0.4.25/naming_convention.sol.0.4.25.NamingConvention.json
  34. 2
      tests/detectors/naming-convention/0.5.16/naming_convention.sol
  35. 300
      tests/detectors/naming-convention/0.5.16/naming_convention.sol.0.5.16.NamingConvention.json
  36. 2
      tests/detectors/naming-convention/0.6.11/naming_convention.sol
  37. 300
      tests/detectors/naming-convention/0.6.11/naming_convention.sol.0.6.11.NamingConvention.json
  38. 2
      tests/detectors/naming-convention/0.7.6/naming_convention.sol
  39. 300
      tests/detectors/naming-convention/0.7.6/naming_convention.sol.0.7.6.NamingConvention.json
  40. 33
      tests/detectors/var-read-using-this/0.4.25/var_read_using_this.sol
  41. 3
      tests/detectors/var-read-using-this/0.4.25/var_read_using_this.sol.0.4.25.VarReadUsingThis.json
  42. 39
      tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol
  43. 736
      tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol.0.5.16.VarReadUsingThis.json
  44. 39
      tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol
  45. 736
      tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol.0.6.11.VarReadUsingThis.json
  46. 39
      tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol
  47. 736
      tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol.0.7.6.VarReadUsingThis.json
  48. 39
      tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol
  49. 736
      tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol.0.8.15.VarReadUsingThis.json
  50. 18
      tests/slithir/ternary_expressions.sol
  51. 4
      tests/slithir/test_ternary_expressions.py
  52. 6
      tests/source_unit/foundry.toml
  53. 1
      tests/source_unit/lib/forge-std
  54. 12
      tests/source_unit/script/Counter.s.sol
  55. 14
      tests/source_unit/src/Counter.sol
  56. 5
      tests/source_unit/src/Counter2.sol
  57. 24
      tests/source_unit/test/Counter.t.sol
  58. 1
      tests/test_ast_parsing.py
  59. 21
      tests/test_detectors.py
  60. 29
      tests/test_features.py
  61. 31
      tests/test_source_unit.py

@ -26,7 +26,7 @@ jobs:
python -m venv /tmp/pip-audit-env
source /tmp/pip-audit-env/bin/activate
python -m pip install --upgrade pip
python -m pip install --upgrade pip setuptools wheel
python -m pip install .
- name: Run pip-audit

@ -14,8 +14,8 @@ setup(
install_requires=[
"prettytable>=0.7.2",
"pycryptodome>=3.4.6",
"crytic-compile>=0.2.4",
# "crytic-compile@git+https://github.com/crytic/crytic-compile.git@master#egg=crytic-compile",
# "crytic-compile>=0.2.4",
"crytic-compile@git+https://github.com/crytic/crytic-compile.git@dev#egg=crytic-compile",
],
extras_require={
"dev": [

@ -89,6 +89,7 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
self._is_upgradeable: Optional[bool] = None
self._is_upgradeable_proxy: Optional[bool] = None
self._upgradeable_version: Optional[str] = None
self.is_top_level = False # heavily used, so no @property
@ -1243,6 +1244,10 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
break
return self._is_upgradeable
@is_upgradeable.setter
def is_upgradeable(self, upgradeable: bool):
self._is_upgradeable = upgradeable
@property
def is_upgradeable_proxy(self) -> bool:
from slither.core.cfg.node import NodeType
@ -1268,6 +1273,18 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
return self._is_upgradeable_proxy
return self._is_upgradeable_proxy
@is_upgradeable_proxy.setter
def is_upgradeable_proxy(self, upgradeable_proxy: bool):
self._is_upgradeable_proxy = upgradeable_proxy
@property
def upgradeable_version(self) -> Optional[str]:
return self._upgradeable_version
@upgradeable_version.setter
def upgradeable_version(self, version_name: str):
self._upgradeable_version = version_name
# endregion
###################################################################################
###################################################################################

@ -70,6 +70,7 @@ SOLIDITY_FUNCTIONS: Dict[str, List[str]] = {
"abi.encodePacked()": ["bytes"],
"abi.encodeWithSelector()": ["bytes"],
"abi.encodeWithSignature()": ["bytes"],
"abi.encodeCall()": ["bytes"],
"bytes.concat()": ["bytes"],
"string.concat()": ["string"],
# abi.decode returns an a list arbitrary types

@ -1,4 +1,7 @@
from typing import List, Any, Dict, Optional, Union, Set
from typing import List, Any, Dict, Optional, Union, Set, TypeVar, Callable
from crytic_compile import CompilationUnit
from crytic_compile.source_unit import SourceUnit
from crytic_compile.utils.naming import Filename
from slither.core.declarations import Contract, Import, Pragma
@ -103,6 +106,117 @@ class FileScope:
return self.contracts.get(name.name, None)
return self.contracts.get(name, None)
AbstractReturnType = TypeVar("AbstractReturnType")
def _generic_source_unit_getter(
self,
crytic_compile_compilation_unit: CompilationUnit,
name: str,
getter: Callable[[SourceUnit], Dict[str, AbstractReturnType]],
) -> Optional[AbstractReturnType]:
assert self.filename in crytic_compile_compilation_unit.source_units
source_unit = crytic_compile_compilation_unit.source_unit(self.filename)
if name in getter(source_unit):
return getter(source_unit)[name]
for scope in self.accessible_scopes:
source_unit = crytic_compile_compilation_unit.source_unit(scope.filename)
if name in getter(source_unit):
return getter(source_unit)[name]
return None
def bytecode_init(
self, crytic_compile_compilation_unit: CompilationUnit, contract_name: str
) -> Optional[str]:
"""
Return the init bytecode
Args:
crytic_compile_compilation_unit:
contract_name:
Returns:
"""
getter: Callable[[SourceUnit], Dict[str, str]] = lambda x: x.bytecodes_init
return self._generic_source_unit_getter(
crytic_compile_compilation_unit, contract_name, getter
)
def bytecode_runtime(
self, crytic_compile_compilation_unit: CompilationUnit, contract_name: str
) -> Optional[str]:
"""
Return the runtime bytecode
Args:
crytic_compile_compilation_unit:
contract_name:
Returns:
"""
getter: Callable[[SourceUnit], Dict[str, str]] = lambda x: x.bytecodes_runtime
return self._generic_source_unit_getter(
crytic_compile_compilation_unit, contract_name, getter
)
def srcmap_init(
self, crytic_compile_compilation_unit: CompilationUnit, contract_name: str
) -> Optional[List[str]]:
"""
Return the init scrmap
Args:
crytic_compile_compilation_unit:
contract_name:
Returns:
"""
getter: Callable[[SourceUnit], Dict[str, List[str]]] = lambda x: x.srcmaps_init
return self._generic_source_unit_getter(
crytic_compile_compilation_unit, contract_name, getter
)
def srcmap_runtime(
self, crytic_compile_compilation_unit: CompilationUnit, contract_name: str
) -> Optional[List[str]]:
"""
Return the runtime srcmap
Args:
crytic_compile_compilation_unit:
contract_name:
Returns:
"""
getter: Callable[[SourceUnit], Dict[str, List[str]]] = lambda x: x.srcmaps_runtime
return self._generic_source_unit_getter(
crytic_compile_compilation_unit, contract_name, getter
)
def abi(self, crytic_compile_compilation_unit: CompilationUnit, contract_name: str) -> Any:
"""
Return the abi
Args:
crytic_compile_compilation_unit:
contract_name:
Returns:
"""
getter: Callable[[SourceUnit], Dict[str, List[str]]] = lambda x: x.abis
return self._generic_source_unit_getter(
crytic_compile_compilation_unit, contract_name, getter
)
# region Built in definitions
###################################################################################
###################################################################################

@ -3,6 +3,7 @@ from .examples.backdoor import Backdoor
from .variables.uninitialized_state_variables import UninitializedStateVarsDetection
from .variables.uninitialized_storage_variables import UninitializedStorageVars
from .variables.uninitialized_local_variables import UninitializedLocalVars
from .variables.var_read_using_this import VarReadUsingThis
from .attributes.constant_pragma import ConstantPragma
from .attributes.incorrect_solc import IncorrectSolc
from .attributes.locked_ether import LockedEther

@ -32,7 +32,7 @@ class ConstantPragma(AbstractDetector):
info = ["Different versions of Solidity are used:\n"]
info += [f"\t- Version used: {[str(v) for v in versions]}\n"]
for p in pragma:
for p in sorted(pragma, key=lambda x: x.version):
info += ["\t- ", p, "\n"]
res = self.generate_result(info)

@ -119,11 +119,10 @@ Solidity defines a [naming convention](https://solidity.readthedocs.io/en/v0.4.2
for var in contract.state_variables_declared:
if self.should_avoid_name(var.name):
if not self.is_upper_case_with_underscores(var.name):
info = [
"Variable ",
var,
" used l, O, I, which should not be used\n",
" is single letter l, O, or I, which should not be used\n",
]
res = self.generate_result(info)

@ -0,0 +1,60 @@
from typing import List
from slither.core.cfg.node import Node
from slither.core.declarations import Function, SolidityVariable
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.slithir.operations.high_level_call import HighLevelCall
class VarReadUsingThis(AbstractDetector):
ARGUMENT = "var-read-using-this"
HELP = "Contract reads its own variable using `this`"
IMPACT = DetectorClassification.OPTIMIZATION
CONFIDENCE = DetectorClassification.HIGH
WIKI = "https://github.com/crytic/slither/wiki/Vulnerabilities-Description#public-variable-read-in-external-context"
WIKI_TITLE = "Public variable read in external context"
WIKI_DESCRIPTION = "The contract reads its own variable using `this`, adding overhead of an unnecessary STATICCALL."
WIKI_EXPLOIT_SCENARIO = """
```solidity
contract C {
mapping(uint => address) public myMap;
function test(uint x) external returns(address) {
return this.myMap(x);
}
}
```
"""
WIKI_RECOMMENDATION = "Read the variable directly from storage instead of calling the contract."
def _detect(self):
results = []
for c in self.contracts:
for func in c.functions:
for node in self._detect_var_read_using_this(func):
info = [
"The function ",
func,
" reads ",
node,
" with `this` which adds an extra STATICCALL.\n",
]
json = self.generate_result(info)
results.append(json)
return results
@staticmethod
def _detect_var_read_using_this(func: Function) -> List[Node]:
results: List[Node] = []
for node in func.nodes:
for ir in node.irs:
if isinstance(ir, HighLevelCall):
if (
ir.destination == SolidityVariable("this")
and ir.is_static_call()
and ir.function.visibility == "public"
):
results.append(node)
return sorted(results, key=lambda x: x.node_id)

@ -54,8 +54,8 @@ class PrinterWrittenVariablesAndAuthorization(AbstractPrinter):
table.add_row(
[
function.name,
str(state_variables_written),
str(msg_sender_condition),
str(sorted(state_variables_written)),
str(sorted(msg_sender_condition)),
]
)
all_tables.append((contract.name, table))

@ -42,7 +42,7 @@ class DataDependency(AbstractPrinter):
txt += f"\nContract {c.name}\n"
table = MyPrettyTable(["Variable", "Dependencies"])
for v in c.state_variables:
table.add_row([v.name, _get(v, c)])
table.add_row([v.name, sorted(_get(v, c))])
txt += str(table)
@ -51,9 +51,9 @@ class DataDependency(AbstractPrinter):
txt += f"\nFunction {f.full_name}\n"
table = MyPrettyTable(["Variable", "Dependencies"])
for v in f.variables:
table.add_row([v.name, _get(v, f)])
table.add_row([v.name, sorted(_get(v, f))])
for v in c.state_variables:
table.add_row([v.canonical_name, _get(v, f)])
table.add_row([v.canonical_name, sorted(_get(v, f))])
txt += str(table)
self.info(txt)

@ -21,14 +21,8 @@ def _extract_evm_info(slither):
CFG = load_evm_cfg_builder()
for contract in slither.contracts_derived:
contract_bytecode_runtime = (
contract.compilation_unit.crytic_compile_compilation_unit.bytecode_runtime(
contract.name
)
)
contract_srcmap_runtime = (
contract.compilation_unit.crytic_compile_compilation_unit.srcmap_runtime(contract.name)
)
contract_bytecode_runtime = contract.scope.bytecode_runtime(contract.name)
contract_srcmap_runtime = contract.scope.srcmap_runtime(contract.name)
cfg = CFG(contract_bytecode_runtime)
evm_info["cfg", contract.name] = cfg
evm_info["mapping", contract.name] = generate_source_to_evm_ins_mapping(
@ -38,12 +32,8 @@ def _extract_evm_info(slither):
contract.source_mapping.filename.absolute,
)
contract_bytecode_init = (
contract.compilation_unit.crytic_compile_compilation_unit.bytecode_init(contract.name)
)
contract_srcmap_init = (
contract.compilation_unit.crytic_compile_compilation_unit.srcmap_init(contract.name)
)
contract_bytecode_init = contract.scope.bytecode_init(contract.name)
contract_srcmap_init = contract.scope.srcmap_init(contract.name)
cfg_init = CFG(contract_bytecode_init)
evm_info["cfg_init", contract.name] = cfg_init

@ -60,15 +60,15 @@ class FunctionSummary(AbstractPrinter):
internal_calls,
external_calls,
) in func_summaries:
read = self._convert(read)
write = self._convert(write)
internal_calls = self._convert(internal_calls)
external_calls = self._convert(external_calls)
read = self._convert(sorted(read))
write = self._convert(sorted(write))
internal_calls = self._convert(sorted(internal_calls))
external_calls = self._convert(sorted(external_calls))
table.add_row(
[
f_name,
visi,
modifiers,
sorted(modifiers),
read,
write,
internal_calls,
@ -96,10 +96,10 @@ class FunctionSummary(AbstractPrinter):
internal_calls,
external_calls,
) in modif_summaries:
read = self._convert(read)
write = self._convert(write)
internal_calls = self._convert(internal_calls)
external_calls = self._convert(external_calls)
read = self._convert(sorted(read))
write = self._convert(sorted(write))
internal_calls = self._convert(sorted(internal_calls))
external_calls = self._convert(sorted(external_calls))
table.add_row([f_name, visi, read, write, internal_calls, external_calls])
txt += "\n\n" + str(table)
txt += "\n"

@ -35,7 +35,7 @@ class Modifiers(AbstractPrinter):
for (_, call) in function.all_library_calls():
if isinstance(call, Function):
modifiers += call.modifiers
table.add_row([function.name, [m.name for m in set(modifiers)]])
table.add_row([function.name, sorted([m.name for m in set(modifiers)])])
txt += "\n" + str(table)
self.info(txt)
all_txt += txt

@ -48,7 +48,7 @@ class RequireOrAssert(AbstractPrinter):
table.add_row(
[
function.name,
self._convert([str(m.expression) for m in set(require)]),
self._convert(sorted([str(m.expression) for m in set(require)])),
]
)
txt += "\n" + str(table)

@ -61,7 +61,6 @@ from slither.slithir.operations import (
NewElementaryType,
NewStructure,
OperationWithLValue,
Push,
Return,
Send,
SolidityCall,
@ -456,19 +455,25 @@ def propagate_type_and_convert_call(result, node):
return result
def _convert_type_contract(ir, compilation_unit: "SlitherCompilationUnit"):
def _convert_type_contract(ir: Member) -> Assignment:
assert isinstance(ir.variable_left.type, TypeInformation)
contract = ir.variable_left.type.type
scope = ir.node.file_scope
if ir.variable_right == "creationCode":
bytecode = compilation_unit.crytic_compile_compilation_unit.bytecode_init(contract.name)
bytecode = scope.bytecode_init(
ir.node.compilation_unit.crytic_compile_compilation_unit, contract.name
)
assignment = Assignment(ir.lvalue, Constant(str(bytecode)), ElementaryType("bytes"))
assignment.set_expression(ir.expression)
assignment.set_node(ir.node)
assignment.lvalue.set_type(ElementaryType("bytes"))
return assignment
if ir.variable_right == "runtimeCode":
bytecode = compilation_unit.crytic_compile_compilation_unit.bytecode_runtime(contract.name)
bytecode = scope.bytecode_runtime(
ir.node.compilation_unit.crytic_compile_compilation_unit, contract.name
)
assignment = Assignment(ir.lvalue, Constant(str(bytecode)), ElementaryType("bytes"))
assignment.set_expression(ir.expression)
assignment.set_node(ir.node)
@ -681,7 +686,7 @@ def propagate_types(ir, node: "Node"): # pylint: disable=too-many-locals
if isinstance(ir.variable_left, TemporaryVariable) and isinstance(
ir.variable_left.type, TypeInformation
):
return _convert_type_contract(ir, node.function.compilation_unit)
return _convert_type_contract(ir)
left = ir.variable_left
t = None
ir_func = ir.function
@ -752,9 +757,6 @@ def propagate_types(ir, node: "Node"): # pylint: disable=too-many-locals
ir.lvalue.set_type(ir.type)
elif isinstance(ir, NewStructure):
ir.lvalue.set_type(UserDefinedType(ir.structure))
elif isinstance(ir, Push):
# No change required
pass
elif isinstance(ir, Send):
ir.lvalue.set_type(ElementaryType("bool"))
elif isinstance(ir, SolidityCall):
@ -1152,6 +1154,7 @@ def can_be_solidity_func(ir) -> bool:
"encodePacked",
"encodeWithSelector",
"encodeWithSignature",
"encodeCall",
"decode",
]

@ -18,7 +18,6 @@ from .new_elementary_type import NewElementaryType
from .new_contract import NewContract
from .new_structure import NewStructure
from .operation import Operation
from .push import Push
from .return_operation import Return
from .send import Send
from .solidity_call import SolidityCall

@ -1,27 +0,0 @@
from slither.core.declarations import Function
from slither.slithir.operations.lvalue import OperationWithLValue
from slither.slithir.utils.utils import is_valid_lvalue, is_valid_rvalue
class Push(OperationWithLValue):
def __init__(self, array, value):
super().__init__()
assert is_valid_rvalue(value) or isinstance(value, Function)
assert is_valid_lvalue(array)
self._value = value
self._lvalue = array
@property
def read(self):
return [self._value]
@property
def array(self):
return self._lvalue
@property
def value(self):
return self._value
def __str__(self):
return f"PUSH {self.value} in {self.lvalue}"

@ -36,7 +36,6 @@ from slither.slithir.operations import (
OperationWithLValue,
Phi,
PhiCallback,
Push,
Return,
Send,
SolidityCall,
@ -780,10 +779,6 @@ def copy_ir(ir, *instances):
return new_ir
if isinstance(ir, Nop):
return Nop()
if isinstance(ir, Push):
array = get_variable(ir, lambda x: x.array, *instances)
lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
return Push(array, lvalue)
if isinstance(ir, Return):
values = get_rec_values(ir, lambda x: x.values, *instances)
return Return(values)

@ -1,4 +1,5 @@
import logging
import re
from typing import List, Dict, Callable, TYPE_CHECKING, Union, Set
from slither.core.declarations import Modifier, Event, EnumContract, StructureContract, Function
@ -65,8 +66,10 @@ class ContractSolc(CallerContextExpression):
# Export info
if self.is_compact_ast:
self._contract.name = self._data["name"]
self._handle_comment(self._data)
else:
self._contract.name = self._data["attributes"][self.get_key()]
self._handle_comment(self._data["attributes"])
self._contract.id = self._data["id"]
@ -741,6 +744,24 @@ class ContractSolc(CallerContextExpression):
self._usingForNotParsed = []
self._customErrorParsed = []
def _handle_comment(self, attributes: Dict) -> None:
if (
"documentation" in attributes
and attributes["documentation"] is not None
and "text" in attributes["documentation"]
):
candidates = attributes["documentation"]["text"].replace("\n", ",").split(",")
for candidate in candidates:
if "@custom:security isDelegatecallProxy" in candidate:
self._contract.is_upgradeable_proxy = True
if "@custom:security isUpgradeable" in candidate:
self._contract.is_upgradeable = True
version_name = re.search(r"@custom:version name=([\w-]+)", candidate)
if version_name:
self._contract.upgradeable_version = version_name.group(1)
# endregion
###################################################################################
###################################################################################

@ -308,7 +308,7 @@ class FunctionSolc(CallerContextExpression):
for node_parser in self._node_to_yulobject.values():
node_parser.analyze_expressions()
self._filter_ternary()
self._rewrite_ternary_as_if_else()
self._remove_alone_endif()
@ -1336,7 +1336,7 @@ class FunctionSolc(CallerContextExpression):
###################################################################################
###################################################################################
def _filter_ternary(self) -> bool:
def _rewrite_ternary_as_if_else(self) -> bool:
ternary_found = True
updated = False
while ternary_found:

@ -87,7 +87,7 @@ class ModifierSolc(FunctionSolc):
for node in self._node_to_nodesolc.values():
node.analyze_expressions(self)
self._filter_ternary()
self._rewrite_ternary_as_if_else()
self._remove_alone_endif()
# self._analyze_read_write()

@ -26,6 +26,7 @@ from slither.solc_parsing.declarations.structure_top_level import StructureTopLe
from slither.solc_parsing.declarations.using_for_top_level import UsingForTopLevelSolc
from slither.solc_parsing.exceptions import VariableNotFound
from slither.solc_parsing.variables.top_level_variable import TopLevelVariableSolc
from slither.solc_parsing.declarations.caller_context import CallerContextExpression
logging.basicConfig()
logger = logging.getLogger("SlitherSolcParsing")
@ -59,7 +60,7 @@ def _handle_import_aliases(
scope.renaming[local_name] = original_name
class SlitherCompilationUnitSolc:
class SlitherCompilationUnitSolc(CallerContextExpression):
# pylint: disable=no-self-use,too-many-instance-attributes
def __init__(self, compilation_unit: SlitherCompilationUnit):
super().__init__()
@ -98,6 +99,10 @@ class SlitherCompilationUnitSolc:
def underlying_contract_to_parser(self) -> Dict[Contract, ContractSolc]:
return self._underlying_contract_to_parser
@property
def slither_parser(self) -> "SlitherCompilationUnitSolc":
return self
###################################################################################
###################################################################################
# region AST

@ -31,7 +31,6 @@ from slither.slithir.operations import (
NewContract,
NewElementaryType,
SolidityCall,
Push,
Delete,
EventCall,
LibraryCall,
@ -163,8 +162,6 @@ def encode_ir(ir): # pylint: disable=too-many-branches
return f"new_array({ntype(ir.array_type)})"
if isinstance(ir, NewElementaryType):
return f"new_elementary({ntype(ir.type)})"
if isinstance(ir, Push):
return f"push({encode_ir(ir.value)},{encode_ir(ir.lvalue)})"
if isinstance(ir, Delete):
return f"delete({encode_ir(ir.lvalue)},{encode_ir(ir.variable)})"
if isinstance(ir, SolidityCall):

@ -14,7 +14,10 @@ from slither.exceptions import SlitherException
from slither.utils.colors import red
from slither.utils.output import output_to_json
from slither.tools.upgradeability.checks import all_checks
from slither.tools.upgradeability.checks.abstract_checks import AbstractCheck
from slither.tools.upgradeability.checks.abstract_checks import (
AbstractCheck,
CheckClassification,
)
from slither.tools.upgradeability.utils.command_line import (
output_detectors_json,
output_wiki,
@ -27,12 +30,14 @@ logger: logging.Logger = logging.getLogger("Slither")
logger.setLevel(logging.INFO)
def parse_args() -> argparse.Namespace:
def parse_args(check_classes: List[Type[AbstractCheck]]) -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Slither Upgradeability Checks. For usage information see https://github.com/crytic/slither/wiki/Upgradeability-Checks.",
usage="slither-check-upgradeability contract.sol ContractName",
)
group_checks = parser.add_argument_group("Checks")
parser.add_argument("contract.sol", help="Codebase to analyze")
parser.add_argument("ContractName", help="Contract name (logic contract)")
@ -51,7 +56,16 @@ def parse_args() -> argparse.Namespace:
default=False,
)
parser.add_argument(
group_checks.add_argument(
"--detect",
help="Comma-separated list of detectors, defaults to all, "
f"available detectors: {', '.join(d.ARGUMENT for d in check_classes)}",
action="store",
dest="detectors_to_run",
default="all",
)
group_checks.add_argument(
"--list-detectors",
help="List available detectors",
action=ListDetectors,
@ -59,6 +73,42 @@ def parse_args() -> argparse.Namespace:
default=False,
)
group_checks.add_argument(
"--exclude",
help="Comma-separated list of detectors that should be excluded",
action="store",
dest="detectors_to_exclude",
default=None,
)
group_checks.add_argument(
"--exclude-informational",
help="Exclude informational impact analyses",
action="store_true",
default=False,
)
group_checks.add_argument(
"--exclude-low",
help="Exclude low impact analyses",
action="store_true",
default=False,
)
group_checks.add_argument(
"--exclude-medium",
help="Exclude medium impact analyses",
action="store_true",
default=False,
)
group_checks.add_argument(
"--exclude-high",
help="Exclude high impact analyses",
action="store_true",
default=False,
)
parser.add_argument(
"--markdown-root",
help="URL for markdown generation",
@ -104,6 +154,43 @@ def _get_checks() -> List[Type[AbstractCheck]]:
return detectors
def choose_checks(
args: argparse.Namespace, all_check_classes: List[Type[AbstractCheck]]
) -> List[Type[AbstractCheck]]:
detectors_to_run = []
detectors = {d.ARGUMENT: d for d in all_check_classes}
if args.detectors_to_run == "all":
detectors_to_run = all_check_classes
if args.detectors_to_exclude:
detectors_excluded = args.detectors_to_exclude.split(",")
for detector in detectors:
if detector in detectors_excluded:
detectors_to_run.remove(detectors[detector])
else:
for detector in args.detectors_to_run.split(","):
if detector in detectors:
detectors_to_run.append(detectors[detector])
else:
raise Exception(f"Error: {detector} is not a detector")
detectors_to_run = sorted(detectors_to_run, key=lambda x: x.IMPACT)
return detectors_to_run
if args.exclude_informational:
detectors_to_run = [
d for d in detectors_to_run if d.IMPACT != CheckClassification.INFORMATIONAL
]
if args.exclude_low:
detectors_to_run = [d for d in detectors_to_run if d.IMPACT != CheckClassification.LOW]
if args.exclude_medium:
detectors_to_run = [d for d in detectors_to_run if d.IMPACT != CheckClassification.MEDIUM]
if args.exclude_high:
detectors_to_run = [d for d in detectors_to_run if d.IMPACT != CheckClassification.HIGH]
# detectors_to_run = sorted(detectors_to_run, key=lambda x: x.IMPACT)
return detectors_to_run
class ListDetectors(argparse.Action): # pylint: disable=too-few-public-methods
def __call__(
self, parser: Any, *args: Any, **kwargs: Any
@ -200,11 +287,11 @@ def main() -> None:
"detectors": [],
}
args = parse_args()
detectors = _get_checks()
args = parse_args(detectors)
detectors_to_run = choose_checks(args, detectors)
v1_filename = vars(args)["contract.sol"]
number_detectors_run = 0
detectors = _get_checks()
try:
variable1 = Slither(v1_filename, **vars(args))
@ -219,7 +306,7 @@ def main() -> None:
return
v1_contract = v1_contracts[0]
detectors_results, number_detectors = _checks_on_contract(detectors, v1_contract)
detectors_results, number_detectors = _checks_on_contract(detectors_to_run, v1_contract)
json_results["detectors"] += detectors_results
number_detectors_run += number_detectors
@ -242,7 +329,7 @@ def main() -> None:
json_results["proxy-present"] = True
detectors_results, number_detectors = _checks_on_contract_and_proxy(
detectors, v1_contract, proxy_contract
detectors_to_run, v1_contract, proxy_contract
)
json_results["detectors"] += detectors_results
number_detectors_run += number_detectors
@ -267,19 +354,19 @@ def main() -> None:
if proxy_contract:
detectors_results, _ = _checks_on_contract_and_proxy(
detectors, v2_contract, proxy_contract
detectors_to_run, v2_contract, proxy_contract
)
json_results["detectors"] += detectors_results
detectors_results, number_detectors = _checks_on_contract_update(
detectors, v1_contract, v2_contract
detectors_to_run, v1_contract, v2_contract
)
json_results["detectors"] += detectors_results
number_detectors_run += number_detectors
# If there is a V2, we run the contract-only check on the V2
detectors_results, number_detectors = _checks_on_contract(detectors, v2_contract)
detectors_results, number_detectors = _checks_on_contract(detectors_to_run, v2_contract)
json_results["detectors"] += detectors_results
number_detectors_run += number_detectors

@ -236,7 +236,7 @@ Avoid variables in the proxy. If a variable is in the proxy, ensure it has the s
if len(order2) <= len(order1):
return []
idx = len(order2) - len(order1)
idx = len(order1)
while idx < len(order2):
variable2 = order2[idx]

@ -23,20 +23,29 @@ from slither.all_exceptions import SlitherException
# pylint: disable=protected-access
def f_expressions(
e: AssignmentOperation, x: Union[Identifier, Literal, MemberAccess, IndexAccess]
e: Union[AssignmentOperation, BinaryOperation, TupleExpression],
x: Union[Identifier, Literal, MemberAccess, IndexAccess],
) -> None:
e._expressions.append(x)
def f_call(e, x):
def f_call(e: CallExpression, x):
e._arguments.append(x)
def f_expression(e, x):
def f_call_value(e: CallExpression, x):
e._value = x
def f_call_gas(e: CallExpression, x):
e._gas = x
def f_expression(e: Union[TypeConversion, UnaryOperation, MemberAccess], x):
e._expression = x
def f_called(e, x):
def f_called(e: CallExpression, x):
e._called = x
@ -53,13 +62,20 @@ class SplitTernaryExpression:
self.condition = None
self.copy_expression(expression, self.true_expression, self.false_expression)
def apply_copy(
def conditional_not_ahead(
self,
next_expr: Expression,
true_expression: Union[AssignmentOperation, MemberAccess],
false_expression: Union[AssignmentOperation, MemberAccess],
f: Callable,
) -> bool:
# look ahead for parenthetical expression (.. ? .. : ..)
if (
isinstance(next_expr, TupleExpression)
and len(next_expr.expressions) == 1
and isinstance(next_expr.expressions[0], ConditionalExpression)
):
next_expr = next_expr.expressions[0]
if isinstance(next_expr, ConditionalExpression):
f(true_expression, copy.copy(next_expr.then_expression))
@ -71,7 +87,6 @@ class SplitTernaryExpression:
f(false_expression, copy.copy(next_expr))
return True
# pylint: disable=too-many-branches
def copy_expression(
self, expression: Expression, true_expression: Expression, false_expression: Expression
) -> None:
@ -87,27 +102,47 @@ class SplitTernaryExpression:
):
return
# case of lib
# (.. ? .. : ..).add
if isinstance(expression, MemberAccess):
if isinstance(expression, (AssignmentOperation, BinaryOperation, TupleExpression)):
true_expression._expressions = []
false_expression._expressions = []
self.convert_expressions(expression, true_expression, false_expression)
elif isinstance(expression, CallExpression):
next_expr = expression.called
self.convert_call_expression(expression, next_expr, true_expression, false_expression)
elif isinstance(expression, (TypeConversion, UnaryOperation, MemberAccess)):
next_expr = expression.expression
if self.apply_copy(next_expr, true_expression, false_expression, f_expression):
if self.conditional_not_ahead(
next_expr, true_expression, false_expression, f_expression
):
self.copy_expression(
next_expr, true_expression.expression, false_expression.expression
expression.expression,
true_expression.expression,
false_expression.expression,
)
elif isinstance(expression, (AssignmentOperation, BinaryOperation, TupleExpression)):
true_expression._expressions = []
false_expression._expressions = []
else:
raise SlitherException(
f"Ternary operation not handled {expression}({type(expression)})"
)
def convert_expressions(
self,
expression: Union[AssignmentOperation, BinaryOperation, TupleExpression],
true_expression: Expression,
false_expression: Expression,
) -> None:
for next_expr in expression.expressions:
# TODO: can we get rid of `NoneType` expressions in `TupleExpression`?
# montyly: this might happen with unnamed tuple (ex: (,,,) = f()), but it needs to be checked
if next_expr:
if isinstance(next_expr, IndexAccess):
# create an index access for each branch
if isinstance(next_expr.expression_right, ConditionalExpression):
next_expr = _handle_ternary_access(
next_expr, true_expression, false_expression
)
if self.apply_copy(next_expr, true_expression, false_expression, f_expressions):
self.convert_index_access(next_expr, true_expression, false_expression)
if self.conditional_not_ahead(
next_expr, true_expression, false_expression, f_expressions
):
# always on last arguments added
self.copy_expression(
next_expr,
@ -115,68 +150,67 @@ class SplitTernaryExpression:
false_expression.expressions[-1],
)
elif isinstance(expression, CallExpression):
next_expr = expression.called
def convert_index_access(
self, next_expr: IndexAccess, true_expression: Expression, false_expression: Expression
) -> None:
# create an index access for each branch
# x[if cond ? 1 : 2] -> if cond { x[1] } else { x[2] }
for expr in next_expr.expressions:
if self.conditional_not_ahead(expr, true_expression, false_expression, f_expressions):
self.copy_expression(
expr,
true_expression.expressions[-1],
false_expression.expressions[-1],
)
def convert_call_expression(
self,
expression: CallExpression,
next_expr: Expression,
true_expression: Expression,
false_expression: Expression,
) -> None:
# case of lib
# (.. ? .. : ..).add
if self.apply_copy(next_expr, true_expression, false_expression, f_called):
if self.conditional_not_ahead(next_expr, true_expression, false_expression, f_called):
self.copy_expression(next_expr, true_expression.called, false_expression.called)
true_expression._arguments = []
false_expression._arguments = []
for next_expr in expression.arguments:
if self.apply_copy(next_expr, true_expression, false_expression, f_call):
# always on last arguments added
# In order to handle ternaries in both call options, gas and value, we return early if the
# conditional is not ahead to rewrite both ternaries (see `_rewrite_ternary_as_if_else`).
if expression.call_gas:
# case of (..).func{gas: .. ? .. : ..}()
next_expr = expression.call_gas
if self.conditional_not_ahead(next_expr, true_expression, false_expression, f_call_gas):
self.copy_expression(
next_expr,
true_expression.arguments[-1],
false_expression.arguments[-1],
true_expression.call_gas,
false_expression.call_gas,
)
else:
return
elif isinstance(expression, (TypeConversion, UnaryOperation)):
next_expr = expression.expression
if self.apply_copy(next_expr, true_expression, false_expression, f_expression):
if expression.call_value:
# case of (..).func{value: .. ? .. : ..}()
next_expr = expression.call_value
if self.conditional_not_ahead(
next_expr, true_expression, false_expression, f_call_value
):
self.copy_expression(
expression.expression,
true_expression.expression,
false_expression.expression,
next_expr,
true_expression.call_value,
false_expression.call_value,
)
else:
raise SlitherException(
f"Ternary operation not handled {expression}({type(expression)})"
)
return
def _handle_ternary_access(
next_expr: IndexAccess,
true_expression: AssignmentOperation,
false_expression: AssignmentOperation,
):
"""
Conditional ternary accesses are split into two accesses, one true and one false
E.g. x[if cond ? 1 : 2] -> if cond { x[1] } else { x[2] }
"""
true_index_access = IndexAccess(
next_expr.expression_left,
next_expr.expression_right.then_expression,
next_expr.type,
)
false_index_access = IndexAccess(
next_expr.expression_left,
next_expr.expression_right.else_expression,
next_expr.type,
)
true_expression._arguments = []
false_expression._arguments = []
f_expressions(
true_expression,
true_index_access,
)
f_expressions(
false_expression,
false_index_access,
for expr in expression.arguments:
if self.conditional_not_ahead(expr, true_expression, false_expression, f_call):
# always on last arguments added
self.copy_expression(
expr,
true_expression.arguments[-1],
false_expression.arguments[-1],
)
return next_expr.expression_right

@ -0,0 +1,18 @@
struct my_struct {
uint[][] a; // works fine
uint[][3] b; // works fine
uint[3][] c; // fails
uint[3][3] d; // fails
uint[2**20] e; // works fine
}
contract BaseContract{
struct my_struct_2 {
uint[][] f; // works fine
uint[][3] g; // works fine
uint[3][] h; // works fine
uint[3][3] i; // works fine
uint[2**20] j; // works fine
}
uint[3][] k; // works fine
}

@ -0,0 +1,16 @@
/// @custom:security isDelegatecallProxy
contract Proxy{
}
/// @custom:security isUpgradeable
/// @custom:version name=version-0
contract V0{
}
/// @custom:security isUpgradeable
/// @custom:version name=version_1
contract V1{
}

@ -65,6 +65,8 @@ contract T {
uint constant M = 1;
uint l = 1;
uint O = 1;
uint I = 1;
}
contract ParameterNameEmptyString {

@ -98,6 +98,207 @@
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "I",
"source_mapping": {
"start": 932,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"is_dependency": false,
"lines": [
69
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "mixedCase"
}
}
],
"description": "Variable T.I (tests/detectors/naming-convention/0.4.25/naming_convention.sol#69) is not in mixedCase\n",
"markdown": "Variable [T.I](tests/detectors/naming-convention/0.4.25/naming_convention.sol#L69) is not in mixedCase\n",
"first_markdown_element": "tests/detectors/naming-convention/0.4.25/naming_convention.sol#L69",
"id": "12df12bbda2059673d356e5c32ec4e8a037a3821c9fa42b831a9144437cb79f9",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "I",
"source_mapping": {
"start": 932,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"is_dependency": false,
"lines": [
69
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "l_O_I_should_not_be_used"
}
}
],
"description": "Variable T.I (tests/detectors/naming-convention/0.4.25/naming_convention.sol#69) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.I](tests/detectors/naming-convention/0.4.25/naming_convention.sol#L69) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.4.25/naming_convention.sol#L69",
"id": "2ac65aa5bb560436d64f16e164aaab90dbbf38d683bfdfdfb42eeb225fc51759",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "O",
"source_mapping": {
"start": 916,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"is_dependency": false,
"lines": [
68
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "mixedCase"
}
}
],
"description": "Variable T.O (tests/detectors/naming-convention/0.4.25/naming_convention.sol#68) is not in mixedCase\n",
"markdown": "Variable [T.O](tests/detectors/naming-convention/0.4.25/naming_convention.sol#L68) is not in mixedCase\n",
"first_markdown_element": "tests/detectors/naming-convention/0.4.25/naming_convention.sol#L68",
"id": "2de986dda91f7c7e3a51470aa43abfa2c6fd363b742d1bbd38d5287ae179b83a",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
@ -505,7 +706,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
@ -525,7 +726,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -573,7 +776,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
@ -593,7 +796,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -715,16 +920,16 @@
"elements": [
{
"type": "variable",
"name": "l",
"name": "O",
"source_mapping": {
"start": 900,
"start": 916,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"is_dependency": false,
"lines": [
67
68
],
"starting_column": 5,
"ending_column": 15
@ -735,7 +940,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
@ -755,7 +960,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -768,10 +975,10 @@
}
}
],
"description": "Variable T.l (tests/detectors/naming-convention/0.4.25/naming_convention.sol#67) used l, O, I, which should not be used\n",
"markdown": "Variable [T.l](tests/detectors/naming-convention/0.4.25/naming_convention.sol#L67) used l, O, I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.4.25/naming_convention.sol#L67",
"id": "b595f9e6d03b8b501b7c4a9bf8ff0ad9bf11448a25f53d63ab5031c95f8ae89c",
"description": "Variable T.O (tests/detectors/naming-convention/0.4.25/naming_convention.sol#68) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.O](tests/detectors/naming-convention/0.4.25/naming_convention.sol#L68) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.4.25/naming_convention.sol#L68",
"id": "b341001642225c62eae76fef9879c80003b3134b3bc627d9b1912ebcd190304b",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
@ -975,6 +1182,73 @@
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "l",
"source_mapping": {
"start": 900,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"is_dependency": false,
"lines": [
67
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.4.25/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "l_O_I_should_not_be_used"
}
}
],
"description": "Variable T.l (tests/detectors/naming-convention/0.4.25/naming_convention.sol#67) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.l](tests/detectors/naming-convention/0.4.25/naming_convention.sol#L67) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.4.25/naming_convention.sol#L67",
"id": "cb8668afe6ed1284c935ac95f8f9cb1407f96226fe741e7310d104d5f10a0fc6",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{

@ -65,6 +65,8 @@ contract T {
uint constant M = 1;
uint l = 1;
uint O = 1;
uint I = 1;
}
contract ParameterNameEmptyString {

@ -98,6 +98,207 @@
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "I",
"source_mapping": {
"start": 932,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"is_dependency": false,
"lines": [
69
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "mixedCase"
}
}
],
"description": "Variable T.I (tests/detectors/naming-convention/0.5.16/naming_convention.sol#69) is not in mixedCase\n",
"markdown": "Variable [T.I](tests/detectors/naming-convention/0.5.16/naming_convention.sol#L69) is not in mixedCase\n",
"first_markdown_element": "tests/detectors/naming-convention/0.5.16/naming_convention.sol#L69",
"id": "12df12bbda2059673d356e5c32ec4e8a037a3821c9fa42b831a9144437cb79f9",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "I",
"source_mapping": {
"start": 932,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"is_dependency": false,
"lines": [
69
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "l_O_I_should_not_be_used"
}
}
],
"description": "Variable T.I (tests/detectors/naming-convention/0.5.16/naming_convention.sol#69) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.I](tests/detectors/naming-convention/0.5.16/naming_convention.sol#L69) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.5.16/naming_convention.sol#L69",
"id": "2ac65aa5bb560436d64f16e164aaab90dbbf38d683bfdfdfb42eeb225fc51759",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "O",
"source_mapping": {
"start": 916,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"is_dependency": false,
"lines": [
68
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "mixedCase"
}
}
],
"description": "Variable T.O (tests/detectors/naming-convention/0.5.16/naming_convention.sol#68) is not in mixedCase\n",
"markdown": "Variable [T.O](tests/detectors/naming-convention/0.5.16/naming_convention.sol#L68) is not in mixedCase\n",
"first_markdown_element": "tests/detectors/naming-convention/0.5.16/naming_convention.sol#L68",
"id": "2de986dda91f7c7e3a51470aa43abfa2c6fd363b742d1bbd38d5287ae179b83a",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
@ -505,7 +706,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
@ -525,7 +726,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -573,7 +776,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
@ -593,7 +796,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -715,16 +920,16 @@
"elements": [
{
"type": "variable",
"name": "l",
"name": "O",
"source_mapping": {
"start": 900,
"start": 916,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"is_dependency": false,
"lines": [
67
68
],
"starting_column": 5,
"ending_column": 15
@ -735,7 +940,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
@ -755,7 +960,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -768,10 +975,10 @@
}
}
],
"description": "Variable T.l (tests/detectors/naming-convention/0.5.16/naming_convention.sol#67) used l, O, I, which should not be used\n",
"markdown": "Variable [T.l](tests/detectors/naming-convention/0.5.16/naming_convention.sol#L67) used l, O, I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.5.16/naming_convention.sol#L67",
"id": "b595f9e6d03b8b501b7c4a9bf8ff0ad9bf11448a25f53d63ab5031c95f8ae89c",
"description": "Variable T.O (tests/detectors/naming-convention/0.5.16/naming_convention.sol#68) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.O](tests/detectors/naming-convention/0.5.16/naming_convention.sol#L68) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.5.16/naming_convention.sol#L68",
"id": "b341001642225c62eae76fef9879c80003b3134b3bc627d9b1912ebcd190304b",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
@ -975,6 +1182,73 @@
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "l",
"source_mapping": {
"start": 900,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"is_dependency": false,
"lines": [
67
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.5.16/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "l_O_I_should_not_be_used"
}
}
],
"description": "Variable T.l (tests/detectors/naming-convention/0.5.16/naming_convention.sol#67) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.l](tests/detectors/naming-convention/0.5.16/naming_convention.sol#L67) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.5.16/naming_convention.sol#L67",
"id": "cb8668afe6ed1284c935ac95f8f9cb1407f96226fe741e7310d104d5f10a0fc6",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{

@ -65,6 +65,8 @@ contract T {
uint constant M = 1;
uint l = 1;
uint O = 1;
uint I = 1;
}
contract ParameterNameEmptyString {

@ -98,6 +98,207 @@
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "I",
"source_mapping": {
"start": 932,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"is_dependency": false,
"lines": [
69
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "mixedCase"
}
}
],
"description": "Variable T.I (tests/detectors/naming-convention/0.6.11/naming_convention.sol#69) is not in mixedCase\n",
"markdown": "Variable [T.I](tests/detectors/naming-convention/0.6.11/naming_convention.sol#L69) is not in mixedCase\n",
"first_markdown_element": "tests/detectors/naming-convention/0.6.11/naming_convention.sol#L69",
"id": "12df12bbda2059673d356e5c32ec4e8a037a3821c9fa42b831a9144437cb79f9",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "I",
"source_mapping": {
"start": 932,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"is_dependency": false,
"lines": [
69
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "l_O_I_should_not_be_used"
}
}
],
"description": "Variable T.I (tests/detectors/naming-convention/0.6.11/naming_convention.sol#69) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.I](tests/detectors/naming-convention/0.6.11/naming_convention.sol#L69) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.6.11/naming_convention.sol#L69",
"id": "2ac65aa5bb560436d64f16e164aaab90dbbf38d683bfdfdfb42eeb225fc51759",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "O",
"source_mapping": {
"start": 916,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"is_dependency": false,
"lines": [
68
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "mixedCase"
}
}
],
"description": "Variable T.O (tests/detectors/naming-convention/0.6.11/naming_convention.sol#68) is not in mixedCase\n",
"markdown": "Variable [T.O](tests/detectors/naming-convention/0.6.11/naming_convention.sol#L68) is not in mixedCase\n",
"first_markdown_element": "tests/detectors/naming-convention/0.6.11/naming_convention.sol#L68",
"id": "2de986dda91f7c7e3a51470aa43abfa2c6fd363b742d1bbd38d5287ae179b83a",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
@ -505,7 +706,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
@ -525,7 +726,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -573,7 +776,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
@ -593,7 +796,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -715,16 +920,16 @@
"elements": [
{
"type": "variable",
"name": "l",
"name": "O",
"source_mapping": {
"start": 900,
"start": 916,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"is_dependency": false,
"lines": [
67
68
],
"starting_column": 5,
"ending_column": 15
@ -735,7 +940,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
@ -755,7 +960,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -768,10 +975,10 @@
}
}
],
"description": "Variable T.l (tests/detectors/naming-convention/0.6.11/naming_convention.sol#67) used l, O, I, which should not be used\n",
"markdown": "Variable [T.l](tests/detectors/naming-convention/0.6.11/naming_convention.sol#L67) used l, O, I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.6.11/naming_convention.sol#L67",
"id": "b595f9e6d03b8b501b7c4a9bf8ff0ad9bf11448a25f53d63ab5031c95f8ae89c",
"description": "Variable T.O (tests/detectors/naming-convention/0.6.11/naming_convention.sol#68) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.O](tests/detectors/naming-convention/0.6.11/naming_convention.sol#L68) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.6.11/naming_convention.sol#L68",
"id": "b341001642225c62eae76fef9879c80003b3134b3bc627d9b1912ebcd190304b",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
@ -975,6 +1182,73 @@
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "l",
"source_mapping": {
"start": 900,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"is_dependency": false,
"lines": [
67
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.6.11/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "l_O_I_should_not_be_used"
}
}
],
"description": "Variable T.l (tests/detectors/naming-convention/0.6.11/naming_convention.sol#67) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.l](tests/detectors/naming-convention/0.6.11/naming_convention.sol#L67) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.6.11/naming_convention.sol#L67",
"id": "cb8668afe6ed1284c935ac95f8f9cb1407f96226fe741e7310d104d5f10a0fc6",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{

@ -65,6 +65,8 @@ contract T {
uint constant M = 1;
uint l = 1;
uint O = 1;
uint I = 1;
}
contract ParameterNameEmptyString {

@ -98,6 +98,207 @@
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "I",
"source_mapping": {
"start": 932,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"is_dependency": false,
"lines": [
69
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "mixedCase"
}
}
],
"description": "Variable T.I (tests/detectors/naming-convention/0.7.6/naming_convention.sol#69) is not in mixedCase\n",
"markdown": "Variable [T.I](tests/detectors/naming-convention/0.7.6/naming_convention.sol#L69) is not in mixedCase\n",
"first_markdown_element": "tests/detectors/naming-convention/0.7.6/naming_convention.sol#L69",
"id": "12df12bbda2059673d356e5c32ec4e8a037a3821c9fa42b831a9144437cb79f9",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "I",
"source_mapping": {
"start": 932,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"is_dependency": false,
"lines": [
69
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "l_O_I_should_not_be_used"
}
}
],
"description": "Variable T.I (tests/detectors/naming-convention/0.7.6/naming_convention.sol#69) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.I](tests/detectors/naming-convention/0.7.6/naming_convention.sol#L69) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.7.6/naming_convention.sol#L69",
"id": "2ac65aa5bb560436d64f16e164aaab90dbbf38d683bfdfdfb42eeb225fc51759",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "O",
"source_mapping": {
"start": 916,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"is_dependency": false,
"lines": [
68
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "mixedCase"
}
}
],
"description": "Variable T.O (tests/detectors/naming-convention/0.7.6/naming_convention.sol#68) is not in mixedCase\n",
"markdown": "Variable [T.O](tests/detectors/naming-convention/0.7.6/naming_convention.sol#L68) is not in mixedCase\n",
"first_markdown_element": "tests/detectors/naming-convention/0.7.6/naming_convention.sol#L68",
"id": "2de986dda91f7c7e3a51470aa43abfa2c6fd363b742d1bbd38d5287ae179b83a",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
@ -505,7 +706,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
@ -525,7 +726,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -573,7 +776,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
@ -593,7 +796,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -715,16 +920,16 @@
"elements": [
{
"type": "variable",
"name": "l",
"name": "O",
"source_mapping": {
"start": 900,
"start": 916,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"is_dependency": false,
"lines": [
67
68
],
"starting_column": 5,
"ending_column": 15
@ -735,7 +940,7 @@
"name": "T",
"source_mapping": {
"start": 692,
"length": 221,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
@ -755,7 +960,9 @@
65,
66,
67,
68
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
@ -768,10 +975,10 @@
}
}
],
"description": "Variable T.l (tests/detectors/naming-convention/0.7.6/naming_convention.sol#67) used l, O, I, which should not be used\n",
"markdown": "Variable [T.l](tests/detectors/naming-convention/0.7.6/naming_convention.sol#L67) used l, O, I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.7.6/naming_convention.sol#L67",
"id": "b595f9e6d03b8b501b7c4a9bf8ff0ad9bf11448a25f53d63ab5031c95f8ae89c",
"description": "Variable T.O (tests/detectors/naming-convention/0.7.6/naming_convention.sol#68) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.O](tests/detectors/naming-convention/0.7.6/naming_convention.sol#L68) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.7.6/naming_convention.sol#L68",
"id": "b341001642225c62eae76fef9879c80003b3134b3bc627d9b1912ebcd190304b",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
@ -975,6 +1182,73 @@
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{
"type": "variable",
"name": "l",
"source_mapping": {
"start": 900,
"length": 10,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"is_dependency": false,
"lines": [
67
],
"starting_column": 5,
"ending_column": 15
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "T",
"source_mapping": {
"start": 692,
"length": 253,
"filename_relative": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/naming-convention/0.7.6/naming_convention.sol",
"is_dependency": false,
"lines": [
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
"starting_column": 1,
"ending_column": 2
}
}
},
"additional_fields": {
"target": "variable",
"convention": "l_O_I_should_not_be_used"
}
}
],
"description": "Variable T.l (tests/detectors/naming-convention/0.7.6/naming_convention.sol#67) is single letter l, O, or I, which should not be used\n",
"markdown": "Variable [T.l](tests/detectors/naming-convention/0.7.6/naming_convention.sol#L67) is single letter l, O, or I, which should not be used\n",
"first_markdown_element": "tests/detectors/naming-convention/0.7.6/naming_convention.sol#L67",
"id": "cb8668afe6ed1284c935ac95f8f9cb1407f96226fe741e7310d104d5f10a0fc6",
"check": "naming-convention",
"impact": "Informational",
"confidence": "High"
},
{
"elements": [
{

@ -0,0 +1,33 @@
contract VarReadUsingThis {
address public erc20;
mapping(uint => address) public myMap;
function bad1(uint x) external returns(address) {
return this.myMap(x);
}
function bad2() external returns(address) {
return this.erc20();
}
function bad3() external returns(address) {
if (this.erc20() == address(0)) revert();
}
function bad4() internal returns(address) {
for (uint x; x < 10; x++) {
address local = this.erc20();
}
}
function good1(uint x) external returns(address) {
return myMap[x];
}
function good2() external returns(address) {
return erc20;
}
function good3() external returns(address) {
if (erc20 == address(0)) revert();
}
function good4() internal returns(address) {
for (uint x; x < 10; x++) {
address local = erc20;
}
}
}

@ -0,0 +1,39 @@
contract VarReadUsingThis {
address public erc20;
mapping(uint => address) public myMap;
function bad1(uint x) external returns(address) {
return this.myMap(x);
}
function bad2() external returns(address) {
return this.erc20();
}
function bad3() external returns(address) {
if (this.erc20() == address(0)) revert();
}
function bad4() internal returns(address) {
for (uint x; x < 10; x++) {
address local = this.erc20();
}
}
function good1(uint x) external returns(address) {
return myMap[x];
}
function good2() external returns(address) {
return erc20;
}
function good3() external returns(address) {
if (erc20 == address(0)) revert();
}
function good4() internal returns(address) {
for (uint x; x < 10; x++) {
address local = erc20;
}
}
function mapExternal(uint x) external view returns(address) {
return myMap[x];
}
function good5(uint x) external returns(address) {
this.mapExternal(x);
}
}

@ -0,0 +1,736 @@
[
[
{
"elements": [
{
"type": "function",
"name": "bad3",
"source_mapping": {
"start": 275,
"length": 99,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
11,
12,
13
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1107,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad3()"
}
},
{
"type": "node",
"name": "this.erc20() == address(0)",
"source_mapping": {
"start": 331,
"length": 26,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
12
],
"starting_column": 13,
"ending_column": 39
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad3",
"source_mapping": {
"start": 275,
"length": 99,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
11,
12,
13
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1107,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad3()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad3() (tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#11-13) reads this.erc20() == address(0) (tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#12) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad3()](tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L11-L13) reads [this.erc20() == address(0)](tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L12) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L11-L13",
"id": "5556888563fa21301c242d57fbd8e08a35fc5d67171a88b9a2737c14be9c6f7f",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad2",
"source_mapping": {
"start": 192,
"length": 78,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
8,
9,
10
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1107,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad2()"
}
},
{
"type": "node",
"name": "this.erc20()",
"source_mapping": {
"start": 244,
"length": 19,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
9
],
"starting_column": 9,
"ending_column": 28
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad2",
"source_mapping": {
"start": 192,
"length": 78,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
8,
9,
10
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1107,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad2()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad2() (tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#8-10) reads this.erc20() (tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#9) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad2()](tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L8-L10) reads [this.erc20()](tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L9) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L8-L10",
"id": "a55229af8750117389299ed9f759d5036882a2396a52087bb2a42c5ed8abaec1",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 102,
"length": 85,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
5,
6,
7
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1107,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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(uint256)"
}
},
{
"type": "node",
"name": "this.myMap(x)",
"source_mapping": {
"start": 160,
"length": 20,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
6
],
"starting_column": 9,
"ending_column": 29
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 102,
"length": 85,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
5,
6,
7
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1107,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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(uint256)"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad1(uint256) (tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#5-7) reads this.myMap(x) (tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#6) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad1(uint256)](tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L5-L7) reads [this.myMap(x)](tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L6) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L5-L7",
"id": "e810f17bcfdf391a48e66ef70c4aafcc205c882b28d0588b26f1d45742580df6",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad4",
"source_mapping": {
"start": 379,
"length": 138,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
14,
15,
16,
17,
18
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1107,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad4()"
}
},
{
"type": "node",
"name": "local = this.erc20()",
"source_mapping": {
"start": 471,
"length": 28,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
16
],
"starting_column": 13,
"ending_column": 41
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad4",
"source_mapping": {
"start": 379,
"length": 138,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
14,
15,
16,
17,
18
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1107,
"filename_relative": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad4()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad4() (tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#14-18) reads local = this.erc20() (tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#16) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad4()](tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L14-L18) reads [local = this.erc20()](tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L16) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol#L14-L18",
"id": "fe997df3fdea17b13139a239ecdcdb64a2f6482aa9dacc62f845ef30591c8e4c",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
}
]
]

@ -0,0 +1,39 @@
contract VarReadUsingThis {
address public erc20;
mapping(uint => address) public myMap;
function bad1(uint x) external returns(address) {
return this.myMap(x);
}
function bad2() external returns(address) {
return this.erc20();
}
function bad3() external returns(address) {
if (this.erc20() == address(0)) revert();
}
function bad4() internal returns(address) {
for (uint x; x < 10; x++) {
address local = this.erc20();
}
}
function good1(uint x) external returns(address) {
return myMap[x];
}
function good2() external returns(address) {
return erc20;
}
function good3() external returns(address) {
if (erc20 == address(0)) revert();
}
function good4() internal returns(address) {
for (uint x; x < 10; x++) {
address local = erc20;
}
}
function mapExternal(uint x) external view returns(address) {
return myMap[x];
}
function good5(uint x) external returns(address) {
this.mapExternal(x);
}
}

@ -0,0 +1,736 @@
[
[
{
"elements": [
{
"type": "function",
"name": "bad3",
"source_mapping": {
"start": 275,
"length": 99,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
11,
12,
13
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad3()"
}
},
{
"type": "node",
"name": "this.erc20() == address(0)",
"source_mapping": {
"start": 331,
"length": 26,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
12
],
"starting_column": 13,
"ending_column": 39
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad3",
"source_mapping": {
"start": 275,
"length": 99,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
11,
12,
13
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad3()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad3() (tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#11-13) reads this.erc20() == address(0) (tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#12) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad3()](tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L11-L13) reads [this.erc20() == address(0)](tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L12) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L11-L13",
"id": "314f90a4989ea75cc274e1f5f46036968c2ecdaaf8fa84913e7db4ef1ffe5bb8",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad4",
"source_mapping": {
"start": 379,
"length": 138,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
14,
15,
16,
17,
18
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad4()"
}
},
{
"type": "node",
"name": "local = this.erc20()",
"source_mapping": {
"start": 471,
"length": 28,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
16
],
"starting_column": 13,
"ending_column": 41
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad4",
"source_mapping": {
"start": 379,
"length": 138,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
14,
15,
16,
17,
18
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad4()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad4() (tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#14-18) reads local = this.erc20() (tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#16) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad4()](tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L14-L18) reads [local = this.erc20()](tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L16) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L14-L18",
"id": "5fd3f1f78f3532107d7e111d84310f3a0fa374fa407e43951d70fd00a752f76f",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 102,
"length": 85,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
5,
6,
7
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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(uint256)"
}
},
{
"type": "node",
"name": "this.myMap(x)",
"source_mapping": {
"start": 160,
"length": 20,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
6
],
"starting_column": 9,
"ending_column": 29
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 102,
"length": 85,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
5,
6,
7
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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(uint256)"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad1(uint256) (tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#5-7) reads this.myMap(x) (tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#6) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad1(uint256)](tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L5-L7) reads [this.myMap(x)](tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L6) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L5-L7",
"id": "a30c3d8ddb468d865fa69afe5b7b83164fc1a332933d4661765cc3781896c7cf",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad2",
"source_mapping": {
"start": 192,
"length": 78,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
8,
9,
10
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad2()"
}
},
{
"type": "node",
"name": "this.erc20()",
"source_mapping": {
"start": 244,
"length": 19,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
9
],
"starting_column": 9,
"ending_column": 28
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad2",
"source_mapping": {
"start": 192,
"length": 78,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
8,
9,
10
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad2()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad2() (tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#8-10) reads this.erc20() (tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#9) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad2()](tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L8-L10) reads [this.erc20()](tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L9) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.6.11/var_read_using_this.sol#L8-L10",
"id": "ccc77ba655d341c0461ca4f4040afe19c379b2333e52648b12f793aaf7f0ead8",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
}
]
]

@ -0,0 +1,39 @@
contract VarReadUsingThis {
address public erc20;
mapping(uint => address) public myMap;
function bad1(uint x) external returns(address) {
return this.myMap(x);
}
function bad2() external returns(address) {
return this.erc20();
}
function bad3() external returns(address) {
if (this.erc20() == address(0)) revert();
}
function bad4() internal returns(address) {
for (uint x; x < 10; x++) {
address local = this.erc20();
}
}
function good1(uint x) external returns(address) {
return myMap[x];
}
function good2() external returns(address) {
return erc20;
}
function good3() external returns(address) {
if (erc20 == address(0)) revert();
}
function good4() internal returns(address) {
for (uint x; x < 10; x++) {
address local = erc20;
}
}
function mapExternal(uint x) external view returns(address) {
return myMap[x];
}
function good5(uint x) external returns(address) {
this.mapExternal(x);
}
}

@ -0,0 +1,736 @@
[
[
{
"elements": [
{
"type": "function",
"name": "bad3",
"source_mapping": {
"start": 275,
"length": 99,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
11,
12,
13
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad3()"
}
},
{
"type": "node",
"name": "this.erc20() == address(0)",
"source_mapping": {
"start": 331,
"length": 26,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
12
],
"starting_column": 13,
"ending_column": 39
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad3",
"source_mapping": {
"start": 275,
"length": 99,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
11,
12,
13
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad3()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad3() (tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#11-13) reads this.erc20() == address(0) (tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#12) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad3()](tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L11-L13) reads [this.erc20() == address(0)](tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L12) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L11-L13",
"id": "1a8ed403cb8c6104a99c9dabdfb64e55282eaedf2c2d8b20fd3b366c49443639",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad2",
"source_mapping": {
"start": 192,
"length": 78,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
8,
9,
10
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad2()"
}
},
{
"type": "node",
"name": "this.erc20()",
"source_mapping": {
"start": 244,
"length": 19,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
9
],
"starting_column": 9,
"ending_column": 28
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad2",
"source_mapping": {
"start": 192,
"length": 78,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
8,
9,
10
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad2()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad2() (tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#8-10) reads this.erc20() (tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#9) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad2()](tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L8-L10) reads [this.erc20()](tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L9) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L8-L10",
"id": "5bddf45a7f968094e163217be36e0cf17b7455740755eec53a1e7b0a44fe63ac",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 102,
"length": 85,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
5,
6,
7
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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(uint256)"
}
},
{
"type": "node",
"name": "this.myMap(x)",
"source_mapping": {
"start": 160,
"length": 20,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
6
],
"starting_column": 9,
"ending_column": 29
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 102,
"length": 85,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
5,
6,
7
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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(uint256)"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad1(uint256) (tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#5-7) reads this.myMap(x) (tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#6) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad1(uint256)](tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L5-L7) reads [this.myMap(x)](tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L6) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L5-L7",
"id": "924c227bf74e70dda261578563193b90b60b70a1ad043716e1d98cbc49b87ceb",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad4",
"source_mapping": {
"start": 379,
"length": 138,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
14,
15,
16,
17,
18
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad4()"
}
},
{
"type": "node",
"name": "local = this.erc20()",
"source_mapping": {
"start": 471,
"length": 28,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
16
],
"starting_column": 13,
"ending_column": 41
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad4",
"source_mapping": {
"start": 379,
"length": 138,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
14,
15,
16,
17,
18
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad4()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad4() (tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#14-18) reads local = this.erc20() (tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#16) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad4()](tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L14-L18) reads [local = this.erc20()](tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L16) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.7.6/var_read_using_this.sol#L14-L18",
"id": "e9b34de7b565a0e63e55b9c74eaf9a265c7f4c8ef866d7b7db17b815393f0477",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
}
]
]

@ -0,0 +1,39 @@
contract VarReadUsingThis {
address public erc20;
mapping(uint => address) public myMap;
function bad1(uint x) external returns(address) {
return this.myMap(x);
}
function bad2() external returns(address) {
return this.erc20();
}
function bad3() external returns(address) {
if (this.erc20() == address(0)) revert();
}
function bad4() internal returns(address) {
for (uint x; x < 10; x++) {
address local = this.erc20();
}
}
function good1(uint x) external returns(address) {
return myMap[x];
}
function good2() external returns(address) {
return erc20;
}
function good3() external returns(address) {
if (erc20 == address(0)) revert();
}
function good4() internal returns(address) {
for (uint x; x < 10; x++) {
address local = erc20;
}
}
function mapExternal(uint x) external view returns(address) {
return myMap[x];
}
function good5(uint x) external returns(address) {
this.mapExternal(x);
}
}

@ -0,0 +1,736 @@
[
[
{
"elements": [
{
"type": "function",
"name": "bad2",
"source_mapping": {
"start": 192,
"length": 78,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
8,
9,
10
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad2()"
}
},
{
"type": "node",
"name": "this.erc20()",
"source_mapping": {
"start": 244,
"length": 19,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
9
],
"starting_column": 9,
"ending_column": 28
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad2",
"source_mapping": {
"start": 192,
"length": 78,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
8,
9,
10
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad2()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad2() (tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#8-10) reads this.erc20() (tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#9) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad2()](tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L8-L10) reads [this.erc20()](tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L9) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L8-L10",
"id": "4e297ea309b8865f782db6a53fdaf5aaf37f768158deb69d2ec6106a8e7b8afd",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 102,
"length": 85,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
5,
6,
7
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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(uint256)"
}
},
{
"type": "node",
"name": "this.myMap(x)",
"source_mapping": {
"start": 160,
"length": 20,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
6
],
"starting_column": 9,
"ending_column": 29
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 102,
"length": 85,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
5,
6,
7
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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(uint256)"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad1(uint256) (tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#5-7) reads this.myMap(x) (tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#6) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad1(uint256)](tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L5-L7) reads [this.myMap(x)](tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L6) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L5-L7",
"id": "ce4d740b2da0b9b71f2dd3dd1c0903124f7be34009ede12a43dc33c6f28b9d28",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad3",
"source_mapping": {
"start": 275,
"length": 99,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
11,
12,
13
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad3()"
}
},
{
"type": "node",
"name": "this.erc20() == address(0)",
"source_mapping": {
"start": 331,
"length": 26,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
12
],
"starting_column": 13,
"ending_column": 39
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad3",
"source_mapping": {
"start": 275,
"length": 99,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
11,
12,
13
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad3()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad3() (tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#11-13) reads this.erc20() == address(0) (tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#12) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad3()](tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L11-L13) reads [this.erc20() == address(0)](tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L12) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L11-L13",
"id": "d4602ee9be1e60f8ae80e6d0a867b532cb2ddef0ba44b25af8808a0ac5a6b828",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
},
{
"elements": [
{
"type": "function",
"name": "bad4",
"source_mapping": {
"start": 379,
"length": 138,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
14,
15,
16,
17,
18
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad4()"
}
},
{
"type": "node",
"name": "local = this.erc20()",
"source_mapping": {
"start": 471,
"length": 28,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
16
],
"starting_column": 13,
"ending_column": 41
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad4",
"source_mapping": {
"start": 379,
"length": 138,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
14,
15,
16,
17,
18
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "VarReadUsingThis",
"source_mapping": {
"start": 1,
"length": 1103,
"filename_relative": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol",
"is_dependency": false,
"lines": [
2,
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": "bad4()"
}
}
}
}
],
"description": "The function VarReadUsingThis.bad4() (tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#14-18) reads local = this.erc20() (tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#16) with `this` which adds an extra STATICCALL.\n",
"markdown": "The function [VarReadUsingThis.bad4()](tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L14-L18) reads [local = this.erc20()](tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L16) with `this` which adds an extra STATICCALL.\n",
"first_markdown_element": "tests/detectors/var-read-using-this/0.8.15/var_read_using_this.sol#L14-L18",
"id": "fec10ba084a6322d0fbb895e6c7ca6bca380b48a54d2ecae92a017b8b41242bf",
"check": "var-read-using-this",
"impact": "Optimization",
"confidence": "High"
}
]
]

@ -1,3 +1,7 @@
interface Test {
function test() external payable returns (uint);
function testTuple() external payable returns (uint, uint);
}
contract C {
// TODO
// 1) support variable declarations
@ -21,4 +25,18 @@ contract C {
function d(bool cond, bytes calldata x) external {
bytes1 a = x[cond ? 1 : 2];
}
function e(address one, address two) public {
uint x = Test(one).test{value: msg.sender == two ? 1 : 2, gas: true ? 2 : gasleft()}();
}
// Parenthetical expression
function f(address one, address two) public {
uint x = Test(one).test{value: msg.sender == two ? 1 : 2, gas: true ? (1 == 1 ? 1 : 2) : gasleft()}();
}
// Unused tuple variable
function g(address one) public {
(, uint x) = Test(one).testTuple();
}
}

@ -9,10 +9,10 @@ def test_ternary_conversions() -> None:
slither = Slither("./tests/slithir/ternary_expressions.sol")
for contract in slither.contracts:
for function in contract.functions:
for node in function.nodes:
if node.type in [NodeType.IF, NodeType.IFLOOP]:
vars_declared = 0
vars_assigned = 0
for node in function.nodes:
if node.type in [NodeType.IF, NodeType.IFLOOP]:
# Iterate over true and false son
for inner_node in node.sons:

@ -0,0 +1,6 @@
[profile.default]
src = 'src'
out = 'out'
libs = ['lib']
# See more config options https://github.com/foundry-rs/foundry/tree/master/config

@ -0,0 +1 @@
Subproject commit eb980e1d4f0e8173ec27da77297ae411840c8ccb

@ -0,0 +1,12 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import "forge-std/Script.sol";
contract CounterScript is Script {
function setUp() public {}
function run() public {
vm.broadcast();
}
}

@ -0,0 +1,14 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
contract Counter {
uint256 public number;
function setNumber(uint256 newNumber) public {
number = newNumber;
}
function increment() public {
number++;
}
}

@ -0,0 +1,5 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
contract Counter {
}

@ -0,0 +1,24 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import "forge-std/Test.sol";
import "../src/Counter.sol";
contract CounterTest is Test {
Counter public counter;
function setUp() public {
counter = new Counter();
counter.setNumber(0);
}
function testIncrement() public {
counter.increment();
assertEq(counter.number(), 1);
}
function testSetNumber(uint256 x) public {
counter.setNumber(x);
assertEq(counter.number(), x);
}
}

@ -434,6 +434,7 @@ ALL_TESTS = [
Test("using-for-functions-list-4-0.8.0.sol", ["0.8.15"]),
Test("using-for-global-0.8.0.sol", ["0.8.15"]),
Test("library_event-0.8.16.sol", ["0.8.16"]),
Test("top-level-struct-0.8.0.sol", ["0.8.0"]),
]
# create the output folder if needed
try:

@ -1557,6 +1557,27 @@ ALL_TEST_OBJECTS = [
"permit_domain_state_var_collision.sol",
"0.8.0",
),
Test(
all_detectors.VarReadUsingThis,
"var_read_using_this.sol",
"0.4.25",
),
Test(
all_detectors.VarReadUsingThis,
"var_read_using_this.sol",
"0.5.16",
),
Test(all_detectors.VarReadUsingThis, "var_read_using_this.sol", "0.6.11"),
Test(
all_detectors.VarReadUsingThis,
"var_read_using_this.sol",
"0.7.6",
),
Test(
all_detectors.VarReadUsingThis,
"var_read_using_this.sol",
"0.8.15",
),
]

@ -10,7 +10,7 @@ from slither.detectors.abstract_detector import AbstractDetector
from slither.slithir.operations import LibraryCall
def _run_all_detectors(slither: Slither):
def _run_all_detectors(slither: Slither) -> None:
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)]
@ -20,7 +20,7 @@ def _run_all_detectors(slither: Slither):
slither.run_detectors()
def test_node():
def test_node() -> None:
# hardhat must have been installed in tests/test_node_modules
# For the CI its done through the github action config
@ -28,7 +28,7 @@ def test_node():
_run_all_detectors(slither)
def test_collision():
def test_collision() -> None:
standard_json = SolcStandardJson()
standard_json.add_source_file("./tests/collisions/a.sol")
@ -40,12 +40,12 @@ def test_collision():
_run_all_detectors(slither)
def test_cycle():
def test_cycle() -> None:
slither = Slither("./tests/test_cyclic_import/a.sol")
_run_all_detectors(slither)
def test_funcion_id_rec_structure():
def test_funcion_id_rec_structure() -> None:
solc_select.switch_global_version("0.8.0", always_install=True)
slither = Slither("./tests/function_ids/rec_struct-0.8.sol")
for compilation_unit in slither.compilation_units:
@ -53,6 +53,25 @@ def test_funcion_id_rec_structure():
assert function.solidity_signature
def test_upgradeable_comments() -> None:
solc_select.switch_global_version("0.8.10", always_install=True)
slither = Slither("./tests/custom_comments/upgrade.sol")
compilation_unit = slither.compilation_units[0]
proxy = compilation_unit.get_contract_from_name("Proxy")[0]
assert proxy.is_upgradeable_proxy
v0 = compilation_unit.get_contract_from_name("V0")[0]
assert v0.is_upgradeable
print(v0.upgradeable_version)
assert v0.upgradeable_version == "version-0"
v1 = compilation_unit.get_contract_from_name("V1")[0]
assert v0.is_upgradeable
assert v1.upgradeable_version == "version_1"
def test_using_for_top_level_same_name() -> None:
slither = Slither("./tests/ast-parsing/using-for-3-0.8.0.sol")
contract_c = slither.get_contract_from_name("C")[0]

@ -0,0 +1,31 @@
from slither import Slither
def test_contract_info() -> None:
slither = Slither("./tests/source_unit")
assert len(slither.compilation_units) == 1
compilation_unit = slither.compilation_units[0]
for source_unit in compilation_unit.crytic_compile_compilation_unit.source_units.values():
source_unit.remove_metadata()
counter_sol = compilation_unit.crytic_compile.filename_lookup(
"tests/source_unit/src/Counter.sol"
)
assert (
compilation_unit.scopes[counter_sol].bytecode_init(
compilation_unit.crytic_compile_compilation_unit, "Counter"
)
== "608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fe"
)
counter2_sol = compilation_unit.crytic_compile.filename_lookup(
"tests/source_unit/src/Counter2.sol"
)
assert (
compilation_unit.scopes[counter2_sol].bytecode_init(
compilation_unit.crytic_compile_compilation_unit, "Counter"
)
== "6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfe"
)
Loading…
Cancel
Save