mirror of https://github.com/crytic/slither
Merge pull request #732 from crytic/dev-19-new-detectors
Open source 19 new bug detectorspull/733/head
commit
bb1c1fbbad
@ -0,0 +1,60 @@ |
|||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.slithir.operations import Binary, BinaryType |
||||||
|
from slither.slithir.variables import Constant |
||||||
|
|
||||||
|
|
||||||
|
class ShiftParameterMixup(AbstractDetector): |
||||||
|
""" |
||||||
|
Check for cases where a return(a,b) is used in an assembly function that also returns two variables |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "incorrect-shift" |
||||||
|
HELP = "The order of parameters in a shift instruction is incorrect." |
||||||
|
IMPACT = DetectorClassification.HIGH |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#shift-parameter-mixup" |
||||||
|
|
||||||
|
WIKI_TITLE = "Incorrect shift in assembly." |
||||||
|
WIKI_DESCRIPTION = "Detect if the values in a shift operation are reversed" |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract C { |
||||||
|
function f() internal returns (uint a) { |
||||||
|
assembly { |
||||||
|
a := shr(a, 8) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
The shift statement will right-shift the constant 8 by `a` bits""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = "Swap the order of parameters." |
||||||
|
|
||||||
|
def _check_function(self, f): |
||||||
|
results = [] |
||||||
|
|
||||||
|
for node in f.nodes: |
||||||
|
for ir in node.irs: |
||||||
|
if isinstance(ir, Binary) and ir.type in [ |
||||||
|
BinaryType.LEFT_SHIFT, |
||||||
|
BinaryType.RIGHT_SHIFT, |
||||||
|
]: |
||||||
|
if isinstance(ir.variable_left, Constant): |
||||||
|
info = [f, " contains an incorrect shift operation: ", node, "\n"] |
||||||
|
json = self.generate_result(info) |
||||||
|
|
||||||
|
results.append(json) |
||||||
|
return results |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
results = [] |
||||||
|
for c in self.contracts: |
||||||
|
for f in c.functions: |
||||||
|
if f.contract_declarer != c: |
||||||
|
continue |
||||||
|
|
||||||
|
if f.contains_assembly: |
||||||
|
results += self._check_function(f) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,138 @@ |
|||||||
|
""" |
||||||
|
Module detecting unimplemented interfaces |
||||||
|
|
||||||
|
Collect all the interfaces |
||||||
|
Check for contracts which implement all interface functions but do not explicitly derive from those interfaces. |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
|
||||||
|
|
||||||
|
class MissingInheritance(AbstractDetector): |
||||||
|
""" |
||||||
|
Unimplemented interface detector |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "missing-inheritance" |
||||||
|
HELP = "Missing inheritance" |
||||||
|
IMPACT = DetectorClassification.INFORMATIONAL |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#missing-inheritance" |
||||||
|
WIKI_TITLE = "Missing inheritance" |
||||||
|
WIKI_DESCRIPTION = "Detect missing inheritance." |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
interface ISomething { |
||||||
|
function f1() external returns(uint); |
||||||
|
} |
||||||
|
|
||||||
|
contract Something { |
||||||
|
function f1() external returns(uint){ |
||||||
|
return 42; |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
`Something` should inherit from `ISomething`. |
||||||
|
""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = "Inherit from the missing interface or contract." |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def detect_unimplemented_interface(contract, interfaces): |
||||||
|
""" |
||||||
|
Detects if contract intends to implement one of the interfaces but does not explicitly do so by deriving from it |
||||||
|
:param contract: The contract to check |
||||||
|
:param interfaces: List of all the interfaces |
||||||
|
:return: Interfaces likely intended to implement by the contract |
||||||
|
""" |
||||||
|
|
||||||
|
intended_interfaces = [] |
||||||
|
sigs_contract = {f.full_name for f in contract.functions_entry_points} |
||||||
|
|
||||||
|
if not sigs_contract: |
||||||
|
return intended_interfaces |
||||||
|
|
||||||
|
for interface in interfaces: |
||||||
|
# If contract already inherits from interface, skip that interface |
||||||
|
if interface in contract.inheritance: |
||||||
|
continue |
||||||
|
|
||||||
|
sigs_interface = {f.full_name for f in interface.functions_entry_points} |
||||||
|
|
||||||
|
# Contract should implement all the functions of the intended interface |
||||||
|
if not sigs_interface.issubset(sigs_contract): |
||||||
|
continue |
||||||
|
|
||||||
|
# A parent contract inherited should not implement a superset of intended interface |
||||||
|
# This is because in the following: |
||||||
|
# interface ERC20_interface: |
||||||
|
# - balanceOf(uint) -> uint |
||||||
|
# - transfer(address, address) -> bool |
||||||
|
# contract ForeignToken: |
||||||
|
# - balanceOf(uint) -> uint |
||||||
|
# contract MyERC20Implementation is ERC20_interface |
||||||
|
# |
||||||
|
# We do not want MyERC20Implementation to be declared as missing ForeignToken interface |
||||||
|
intended_interface_is_subset_parent = False |
||||||
|
for parent in contract.inheritance: |
||||||
|
sigs_parent = {f.full_name for f in parent.functions_entry_points} |
||||||
|
if sigs_interface.issubset(sigs_parent): |
||||||
|
intended_interface_is_subset_parent = True |
||||||
|
break |
||||||
|
|
||||||
|
if not intended_interface_is_subset_parent: |
||||||
|
# Should not be a subset of an earlier determined intended_interface or derive from it |
||||||
|
intended_interface_is_subset_intended = False |
||||||
|
for intended_interface in intended_interfaces: |
||||||
|
sigs_intended_interface = { |
||||||
|
f.full_name for f in intended_interface.functions_entry_points |
||||||
|
} |
||||||
|
if ( |
||||||
|
sigs_interface.issubset(sigs_intended_interface) |
||||||
|
or interface in intended_interface.inheritance |
||||||
|
): |
||||||
|
intended_interface_is_subset_intended = True |
||||||
|
break |
||||||
|
|
||||||
|
# If superset of an earlier determined intended_interface or derives from it, |
||||||
|
# remove the intended_interface |
||||||
|
if ( |
||||||
|
sigs_intended_interface.issubset(sigs_interface) |
||||||
|
or intended_interface in interface.inheritance |
||||||
|
): |
||||||
|
intended_interfaces.remove(intended_interface) |
||||||
|
|
||||||
|
if not intended_interface_is_subset_intended: |
||||||
|
intended_interfaces.append(interface) |
||||||
|
|
||||||
|
return intended_interfaces |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
"""Detect unimplemented interfaces |
||||||
|
Returns: |
||||||
|
list: {'contract'} |
||||||
|
""" |
||||||
|
|
||||||
|
# Collect all the interfaces |
||||||
|
# Here interface can be "interface" from solidity, or contracts with only functions declaration |
||||||
|
# Skip interfaces without functions |
||||||
|
interfaces = [ |
||||||
|
contract |
||||||
|
for contract in self.slither.contracts |
||||||
|
if contract.is_signature_only() |
||||||
|
and any(not f.is_constructor_variables for f in contract.functions) |
||||||
|
] |
||||||
|
|
||||||
|
# Check derived contracts for missing interface implementations |
||||||
|
results = [] |
||||||
|
for contract in self.slither.contracts_derived: |
||||||
|
# Skip interfaces |
||||||
|
if contract in interfaces: |
||||||
|
continue |
||||||
|
intended_interfaces = self.detect_unimplemented_interface(contract, interfaces) |
||||||
|
for interface in intended_interfaces: |
||||||
|
info = [contract, " should inherit from ", interface, "\n"] |
||||||
|
res = self.generate_result(info) |
||||||
|
results.append(res) |
||||||
|
return results |
@ -0,0 +1,160 @@ |
|||||||
|
""" |
||||||
|
Detects the passing of arrays located in memory to functions which expect to modify arrays via storage reference. |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.core.solidity_types.array_type import ArrayType |
||||||
|
from slither.core.variables.state_variable import StateVariable |
||||||
|
from slither.core.variables.local_variable import LocalVariable |
||||||
|
from slither.slithir.operations.high_level_call import HighLevelCall |
||||||
|
from slither.slithir.operations.internal_call import InternalCall |
||||||
|
|
||||||
|
|
||||||
|
class ArrayByReference(AbstractDetector): |
||||||
|
""" |
||||||
|
Detects passing of arrays located in memory to functions which expect to modify arrays via storage reference. |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "array-by-reference" |
||||||
|
HELP = "Modifying storage array by value" |
||||||
|
IMPACT = DetectorClassification.HIGH |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#modifying-storage-array-by-value" |
||||||
|
|
||||||
|
WIKI_TITLE = "Modifying storage array by value" |
||||||
|
WIKI_DESCRIPTION = ( |
||||||
|
"Detect arrays passed to a function that expects reference to a storage array" |
||||||
|
) |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract Memory { |
||||||
|
uint[1] public x; // storage |
||||||
|
|
||||||
|
function f() public { |
||||||
|
f1(x); // update x |
||||||
|
f2(x); // do not update x |
||||||
|
} |
||||||
|
|
||||||
|
function f1(uint[1] storage arr) internal { // by reference |
||||||
|
arr[0] = 1; |
||||||
|
} |
||||||
|
|
||||||
|
function f2(uint[1] arr) internal { // by value |
||||||
|
arr[0] = 2; |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Bob calls `f()`. Bob assumes that at the end of the call `x[0]` is 2, but it is 1. |
||||||
|
As a result, Bob's usage of the contract is incorrect.""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = "Ensure the correct usage of `memory` and `storage` in the function parameters. Make all the locations explicit." |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def get_funcs_modifying_array_params(contracts): |
||||||
|
""" |
||||||
|
Obtains a set of functions which take arrays not located in storage as parameters, and writes to them. |
||||||
|
:param contracts: The collection of contracts to check functions in. |
||||||
|
:return: A set of functions which take an array not located in storage as a parameter and writes to it. |
||||||
|
""" |
||||||
|
# Initialize our resulting set of functions which modify non-reference array parameters |
||||||
|
results = set() |
||||||
|
|
||||||
|
# Loop through all functions in all contracts. |
||||||
|
for contract in contracts: |
||||||
|
for function in contract.functions_declared: |
||||||
|
|
||||||
|
# Skip any constructor functions. |
||||||
|
if function.is_constructor: |
||||||
|
continue |
||||||
|
|
||||||
|
# Determine if this function takes an array as a parameter and the location isn't storage. |
||||||
|
# If it has been written to, we know this sets an non-storage-ref array. |
||||||
|
for param in function.parameters: |
||||||
|
if isinstance(param.type, ArrayType) and param.location != "storage": |
||||||
|
if param in function.variables_written: |
||||||
|
results.add(function) |
||||||
|
break |
||||||
|
|
||||||
|
return results |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def detect_calls_passing_ref_to_function(contracts, array_modifying_funcs): |
||||||
|
""" |
||||||
|
Obtains all calls passing storage arrays by value to a function which cannot write to them successfully. |
||||||
|
:param contracts: The collection of contracts to check for problematic calls in. |
||||||
|
:param array_modifying_funcs: The collection of functions which take non-storage arrays as input and writes to |
||||||
|
them. |
||||||
|
:return: A list of tuples (calling_node, affected_argument, invoked_function) which denote all problematic |
||||||
|
nodes invoking a function with some storage array argument where the invoked function seemingly attempts to |
||||||
|
write to the array unsuccessfully. |
||||||
|
""" |
||||||
|
# Define our resulting array. |
||||||
|
results = [] |
||||||
|
|
||||||
|
# Verify we have functions in our list to check for. |
||||||
|
if not array_modifying_funcs: |
||||||
|
return results |
||||||
|
|
||||||
|
# Loop for each node in each function/modifier in each contract |
||||||
|
# pylint: disable=too-many-nested-blocks |
||||||
|
for contract in contracts: |
||||||
|
for function in contract.functions_and_modifiers_declared: |
||||||
|
for node in function.nodes: |
||||||
|
|
||||||
|
# If this node has no expression, skip it. |
||||||
|
if not node.expression: |
||||||
|
continue |
||||||
|
|
||||||
|
for ir in node.irs: |
||||||
|
# Verify this is a high level call. |
||||||
|
if not isinstance(ir, (HighLevelCall, InternalCall)): |
||||||
|
continue |
||||||
|
|
||||||
|
# Verify this references a function in our array modifying functions collection. |
||||||
|
if ir.function not in array_modifying_funcs: |
||||||
|
continue |
||||||
|
|
||||||
|
# Verify one of these parameters is an array in storage. |
||||||
|
for arg in ir.arguments: |
||||||
|
# Verify this argument is a variable that is an array type. |
||||||
|
if not isinstance(arg, (StateVariable, LocalVariable)): |
||||||
|
continue |
||||||
|
if not isinstance(arg.type, ArrayType): |
||||||
|
continue |
||||||
|
|
||||||
|
# If it is a state variable OR a local variable referencing storage, we add it to the list. |
||||||
|
if isinstance(arg, StateVariable) or ( |
||||||
|
isinstance(arg, LocalVariable) and arg.location == "storage" |
||||||
|
): |
||||||
|
results.append((node, arg, ir.function)) |
||||||
|
return results |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
""" |
||||||
|
Detects passing of arrays located in memory to functions which expect to modify arrays via storage reference. |
||||||
|
:return: The JSON results of the detector, which contains the calling_node, affected_argument_variable and |
||||||
|
invoked_function for each result found. |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
array_modifying_funcs = self.get_funcs_modifying_array_params(self.contracts) |
||||||
|
problematic_calls = self.detect_calls_passing_ref_to_function( |
||||||
|
self.contracts, array_modifying_funcs |
||||||
|
) |
||||||
|
|
||||||
|
if problematic_calls: |
||||||
|
for calling_node, affected_argument, invoked_function in problematic_calls: |
||||||
|
info = [ |
||||||
|
calling_node.function, |
||||||
|
" passes array ", |
||||||
|
affected_argument, |
||||||
|
"by reference to ", |
||||||
|
invoked_function, |
||||||
|
"which only takes arrays by value\n", |
||||||
|
] |
||||||
|
|
||||||
|
res = self.generate_result(info) |
||||||
|
results.append(res) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,84 @@ |
|||||||
|
""" |
||||||
|
Module detecting dangerous conversion to enum |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.slithir.operations import TypeConversion |
||||||
|
from slither.core.declarations.enum import Enum |
||||||
|
|
||||||
|
|
||||||
|
def _uses_vulnerable_solc_version(version): |
||||||
|
"""Detect if used compiler version is 0.4.[0|1|2|3|4] |
||||||
|
Args: |
||||||
|
version (solc version used) |
||||||
|
Returns: |
||||||
|
Bool |
||||||
|
""" |
||||||
|
if version in ["0.4.0", "0.4.1", "0.4.2", "0.4.3", "0.4.4"]: |
||||||
|
return True |
||||||
|
return False |
||||||
|
|
||||||
|
|
||||||
|
def _detect_dangerous_enum_conversions(contract): |
||||||
|
"""Detect dangerous conversion to enum by checking IR |
||||||
|
Args: |
||||||
|
contract (Contract) |
||||||
|
Returns: |
||||||
|
list[(node, variable)] (Nodes where a variable is being converted into enum) |
||||||
|
""" |
||||||
|
return [ |
||||||
|
(n, ir.variable) |
||||||
|
for f in contract.functions_declared |
||||||
|
for n in f.nodes |
||||||
|
for ir in n.irs |
||||||
|
if isinstance(ir, TypeConversion) and isinstance(ir.type.type, Enum) |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
class EnumConversion(AbstractDetector): |
||||||
|
""" |
||||||
|
Detect dangerous conversion to enum |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "enum-conversion" |
||||||
|
HELP = "Detect dangerous enum conversion" |
||||||
|
IMPACT = DetectorClassification.MEDIUM |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-enum-conversion" |
||||||
|
WIKI_TITLE = "Dangerous enum conversion" |
||||||
|
WIKI_DESCRIPTION = "Detect out-of-range `enum` conversion (`solc` < `0.4.5`)." |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
pragma solidity 0.4.2; |
||||||
|
contract Test{ |
||||||
|
|
||||||
|
enum E{a} |
||||||
|
|
||||||
|
function bug(uint a) public returns(E){ |
||||||
|
return E(a); |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
Attackers can trigger unexpected behaviour by calling `bug(1)`.""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = "Use a recent compiler version. If `solc` <`0.4.5` is required, check the `enum` conversion range." |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
"""Detect dangerous conversion to enum""" |
||||||
|
results = [] |
||||||
|
# If solc version >= 0.4.5 then return |
||||||
|
if not _uses_vulnerable_solc_version(self.slither.solc_version): |
||||||
|
return results |
||||||
|
|
||||||
|
for c in self.slither.contracts: |
||||||
|
ret = _detect_dangerous_enum_conversions(c) |
||||||
|
for node, var in ret: |
||||||
|
func_info = [node, " has a dangerous enum conversion\n"] |
||||||
|
# Output each node with the function info header as a separate result. |
||||||
|
variable_info = ["\t- Variable: ", var, f" of type: {str(var.type)}\n"] |
||||||
|
node_info = ["\t- Enum conversion: ", node, "\n"] |
||||||
|
json = self.generate_result(func_info + variable_info + node_info) |
||||||
|
results.append(json) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,62 @@ |
|||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
|
||||||
|
|
||||||
|
class MultipleConstructorSchemes(AbstractDetector): |
||||||
|
""" |
||||||
|
Module detecting multiple constructors in the same contract. |
||||||
|
(This was possible prior to Solidity 0.4.23, using old and new constructor schemes). |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "multiple-constructors" |
||||||
|
HELP = "Multiple constructor schemes" |
||||||
|
IMPACT = DetectorClassification.HIGH |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = ( |
||||||
|
"https://github.com/crytic/slither/wiki/Detector-Documentation#multiple-constructor-schemes" |
||||||
|
) |
||||||
|
|
||||||
|
WIKI_TITLE = "Multiple constructor schemes" |
||||||
|
WIKI_DESCRIPTION = ( |
||||||
|
"Detect multiple constructor definitions in the same contract (using new and old schemes)." |
||||||
|
) |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract A { |
||||||
|
uint x; |
||||||
|
constructor() public { |
||||||
|
x = 0; |
||||||
|
} |
||||||
|
function A() public { |
||||||
|
x = 1; |
||||||
|
} |
||||||
|
|
||||||
|
function test() public returns(uint) { |
||||||
|
return x; |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
In Solidity [0.4.22](https://github.com/ethereum/solidity/releases/tag/v0.4.23), a contract with both constructor schemes will compile. The first constructor will take precedence over the second, which may be unintended.""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = "Only declare one constructor, preferably using the new scheme `constructor(...)` instead of `function <contractName>(...)`." |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
""" |
||||||
|
Detect multiple constructor schemes in the same contract |
||||||
|
:return: Returns a list of contract JSON result, where each result contains all constructor definitions. |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
for contract in self.contracts: |
||||||
|
# Obtain any constructors defined in this contract |
||||||
|
constructors = [f for f in contract.constructors if f.contract_declarer == contract] |
||||||
|
|
||||||
|
# If there is more than one, we encountered the described issue occurring. |
||||||
|
if constructors and len(constructors) > 1: |
||||||
|
info = [contract, " contains multiple constructors in the same contract:\n"] |
||||||
|
for constructor in constructors: |
||||||
|
info += ["\t- ", constructor, "\n"] |
||||||
|
|
||||||
|
res = self.generate_result(info) |
||||||
|
results.append(res) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,89 @@ |
|||||||
|
""" |
||||||
|
Module detecting public mappings with nested variables (returns incorrect values prior to 0.5.x) |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.core.solidity_types.mapping_type import MappingType |
||||||
|
from slither.core.solidity_types.user_defined_type import UserDefinedType |
||||||
|
from slither.core.declarations.structure import Structure |
||||||
|
|
||||||
|
|
||||||
|
def detect_public_nested_mappings(contract): |
||||||
|
""" |
||||||
|
Detect any state variables that are initialized from an immediate function call (prior to constructor run). |
||||||
|
:param contract: The contract to detect state variable definitions for. |
||||||
|
:return: A list of all state variables defined in the given contract that meet the specified criteria. |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
|
||||||
|
for state_variable in contract.variables: |
||||||
|
# Verify this variable is defined in this contract |
||||||
|
if state_variable.contract != contract: |
||||||
|
continue |
||||||
|
|
||||||
|
# Verify this is a public mapping |
||||||
|
if state_variable.visibility != "public" or not isinstance( |
||||||
|
state_variable.type, MappingType |
||||||
|
): |
||||||
|
continue |
||||||
|
|
||||||
|
# Verify the value type is a user defined type (struct) |
||||||
|
if not isinstance(state_variable.type.type_to, UserDefinedType) or not isinstance( |
||||||
|
state_variable.type.type_to.type, Structure |
||||||
|
): |
||||||
|
continue |
||||||
|
|
||||||
|
# Obtain the struct |
||||||
|
struct_type = state_variable.type.type_to.type |
||||||
|
for struct_member in struct_type.elems.values(): |
||||||
|
if isinstance(struct_member.type, UserDefinedType) and isinstance( |
||||||
|
struct_member.type.type, Structure |
||||||
|
): |
||||||
|
results.append(state_variable) |
||||||
|
break |
||||||
|
|
||||||
|
return results |
||||||
|
|
||||||
|
|
||||||
|
class PublicMappingNested(AbstractDetector): |
||||||
|
""" |
||||||
|
Detects public mappings with nested variables (returns incorrect values prior to 0.5.x) |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "public-mappings-nested" |
||||||
|
HELP = "Public mappings with nested variables" |
||||||
|
IMPACT = DetectorClassification.HIGH |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#public-mappings-with-nested-variables" |
||||||
|
|
||||||
|
WIKI_TITLE = "Public mappings with nested variables" |
||||||
|
WIKI_DESCRIPTION = "Prior to Solidity 0.5, a public mapping with nested structures returned [incorrect values](https://github.com/ethereum/solidity/issues/5520)." |
||||||
|
WIKI_EXPLOIT_SCENARIO = """Bob interacts with a contract that has a public mapping with nested structures. The values returned by the mapping are incorrect, breaking Bob's usage""" |
||||||
|
WIKI_RECOMMENDATION = "Do not use public mapping with nested structures." |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
""" |
||||||
|
Detect public mappings with nested variables (returns incorrect values prior to 0.5.x) |
||||||
|
|
||||||
|
Returns: |
||||||
|
list: {'vuln', 'filename,'contract','func', 'public_nested_mappings'} |
||||||
|
|
||||||
|
""" |
||||||
|
results = [] |
||||||
|
|
||||||
|
for p in self.slither.pragma_directives: |
||||||
|
if "0.5.0" in p.version and not "<0.5.0" in p.version: |
||||||
|
return [] |
||||||
|
if self.slither.solc_version and self.slither.solc_version.startswith("0.5."): |
||||||
|
return [] |
||||||
|
|
||||||
|
for contract in self.contracts: |
||||||
|
public_nested_mappings = detect_public_nested_mappings(contract) |
||||||
|
if public_nested_mappings: |
||||||
|
for public_nested_mapping in public_nested_mappings: |
||||||
|
info = [public_nested_mapping, " is a public mapping with nested variables\n"] |
||||||
|
json = self.generate_result(info) |
||||||
|
results.append(json) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,157 @@ |
|||||||
|
""" |
||||||
|
Module detecting re-used base constructors in inheritance hierarchy. |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
|
||||||
|
|
||||||
|
# Helper: adds explicitly called constructors with arguments to the results lookup. |
||||||
|
def _add_constructors_with_args( |
||||||
|
base_constructors, called_by_constructor, current_contract, results |
||||||
|
): |
||||||
|
for explicit_base_constructor in base_constructors: |
||||||
|
if len(explicit_base_constructor.parameters) > 0: |
||||||
|
if explicit_base_constructor not in results: |
||||||
|
results[explicit_base_constructor] = [] |
||||||
|
results[explicit_base_constructor] += [(current_contract, called_by_constructor)] |
||||||
|
|
||||||
|
|
||||||
|
class ReusedBaseConstructor(AbstractDetector): |
||||||
|
""" |
||||||
|
Re-used base constructors |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "reused-constructor" |
||||||
|
HELP = "Reused base constructor" |
||||||
|
IMPACT = DetectorClassification.MEDIUM |
||||||
|
# The confidence is medium, because prior Solidity 0.4.22, we cant differentiate |
||||||
|
# contract C is A() { |
||||||
|
# to |
||||||
|
# contract C is A { |
||||||
|
CONFIDENCE = DetectorClassification.MEDIUM |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#reused-base-constructors" |
||||||
|
|
||||||
|
WIKI_TITLE = "Reused base constructors" |
||||||
|
WIKI_DESCRIPTION = "Detects if the same base constructor is called with arguments from two different locations in the same inheritance hierarchy." |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
pragma solidity ^0.4.0; |
||||||
|
|
||||||
|
contract A{ |
||||||
|
uint num = 5; |
||||||
|
constructor(uint x) public{ |
||||||
|
num += x; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract B is A{ |
||||||
|
constructor() A(2) public { /* ... */ } |
||||||
|
} |
||||||
|
|
||||||
|
contract C is A { |
||||||
|
constructor() A(3) public { /* ... */ } |
||||||
|
} |
||||||
|
|
||||||
|
contract D is B, C { |
||||||
|
constructor() public { /* ... */ } |
||||||
|
} |
||||||
|
|
||||||
|
contract E is B { |
||||||
|
constructor() A(1) public { /* ... */ } |
||||||
|
} |
||||||
|
``` |
||||||
|
The constructor of `A` is called multiple times in `D` and `E`: |
||||||
|
- `D` inherits from `B` and `C`, both of which construct `A`. |
||||||
|
- `E` only inherits from `B`, but `B` and `E` construct `A`. |
||||||
|
.""" |
||||||
|
WIKI_RECOMMENDATION = "Remove the duplicate constructor call." |
||||||
|
|
||||||
|
def _detect_explicitly_called_base_constructors(self, contract): |
||||||
|
""" |
||||||
|
Detects explicitly calls to base constructors with arguments in the inheritance hierarchy. |
||||||
|
:param contract: The contract to detect explicit calls to a base constructor with arguments to. |
||||||
|
:return: Dictionary of function:list(tuple): { constructor : [(invoking_contract, called_by_constructor]} |
||||||
|
""" |
||||||
|
results = dict() |
||||||
|
|
||||||
|
# Create a set to track all completed contracts |
||||||
|
processed_contracts = set() |
||||||
|
queued_contracts = [contract] + contract.inheritance |
||||||
|
|
||||||
|
# Loop until there are no queued contracts left. |
||||||
|
while len(queued_contracts) > 0: |
||||||
|
|
||||||
|
# Pop a contract off the front of the queue, if it has already been processed, we stop. |
||||||
|
current_contract = queued_contracts.pop(0) |
||||||
|
if current_contract in processed_contracts: |
||||||
|
continue |
||||||
|
|
||||||
|
# Add this contract to the processed contracts |
||||||
|
processed_contracts.add(current_contract) |
||||||
|
|
||||||
|
# Prior Solidity 0.4.22, the constructor would appear two times |
||||||
|
# Leading to several FPs |
||||||
|
# As the result, we might miss some TPs if the reused is due to the constructor called |
||||||
|
# In the contract definition |
||||||
|
if self.slither.solc_version >= "0.4.22": |
||||||
|
# Find all base constructors explicitly called from the contract definition with arguments. |
||||||
|
_add_constructors_with_args( |
||||||
|
current_contract.explicit_base_constructor_calls, |
||||||
|
False, |
||||||
|
current_contract, |
||||||
|
results, |
||||||
|
) |
||||||
|
|
||||||
|
# Find all base constructors explicitly called from the constructor definition with arguments. |
||||||
|
if current_contract.constructors_declared: |
||||||
|
_add_constructors_with_args( |
||||||
|
current_contract.constructors_declared.explicit_base_constructor_calls, |
||||||
|
True, |
||||||
|
current_contract, |
||||||
|
results, |
||||||
|
) |
||||||
|
|
||||||
|
return results |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
""" |
||||||
|
Detect reused base constructors. |
||||||
|
:return: Returns a list of JSON results. |
||||||
|
""" |
||||||
|
|
||||||
|
results = [] |
||||||
|
|
||||||
|
# The bug is not possible with solc >= 0.5.0 |
||||||
|
if not self.slither.solc_version.startswith("0.4."): |
||||||
|
return [] |
||||||
|
|
||||||
|
# Loop for each contract |
||||||
|
for contract in self.contracts: |
||||||
|
|
||||||
|
# Detect all locations which all underlying base constructors with arguments were called from. |
||||||
|
called_base_constructors = self._detect_explicitly_called_base_constructors(contract) |
||||||
|
for base_constructor, call_list in called_base_constructors.items(): |
||||||
|
# Only report if there are multiple calls to the same base constructor. |
||||||
|
if len(call_list) <= 1: |
||||||
|
continue |
||||||
|
|
||||||
|
# Generate data to output. |
||||||
|
info = [ |
||||||
|
contract, |
||||||
|
" gives base constructor ", |
||||||
|
base_constructor, |
||||||
|
" arguments more than once in inheritance hierarchy:\n", |
||||||
|
] |
||||||
|
|
||||||
|
for (calling_contract, called_by_constructor) in call_list: |
||||||
|
info += [ |
||||||
|
"\t- From ", |
||||||
|
calling_contract, |
||||||
|
f" {'constructor' if called_by_constructor else 'contract'} definition\n", |
||||||
|
] |
||||||
|
|
||||||
|
res = self.generate_result(info) |
||||||
|
results.append(res) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,150 @@ |
|||||||
|
""" |
||||||
|
Module detecting ABIEncoderV2 array bug |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.core.solidity_types import ArrayType |
||||||
|
from slither.core.solidity_types import UserDefinedType |
||||||
|
from slither.core.variables.local_variable import LocalVariable |
||||||
|
from slither.core.variables.state_variable import StateVariable |
||||||
|
from slither.slithir.operations import SolidityCall |
||||||
|
from slither.core.declarations.solidity_variables import SolidityFunction |
||||||
|
from slither.slithir.operations import EventCall |
||||||
|
from slither.slithir.operations import HighLevelCall |
||||||
|
from slither.utils.utils import unroll |
||||||
|
|
||||||
|
vulnerable_solc_versions = [ |
||||||
|
"0.4.7", |
||||||
|
"0.4.8", |
||||||
|
"0.4.9", |
||||||
|
"0.4.10", |
||||||
|
"0.4.11", |
||||||
|
"0.4.12", |
||||||
|
"0.4.13", |
||||||
|
"0.4.14", |
||||||
|
"0.4.15", |
||||||
|
"0.4.16", |
||||||
|
"0.4.17", |
||||||
|
"0.4.18", |
||||||
|
"0.4.19", |
||||||
|
"0.4.20", |
||||||
|
"0.4.21", |
||||||
|
"0.4.22", |
||||||
|
"0.4.23", |
||||||
|
"0.4.24", |
||||||
|
"0.4.25", |
||||||
|
"0.5.0", |
||||||
|
"0.5.1", |
||||||
|
"0.5.2", |
||||||
|
"0.5.3", |
||||||
|
"0.5.4", |
||||||
|
"0.5.5", |
||||||
|
"0.5.6", |
||||||
|
"0.5.7", |
||||||
|
"0.5.8", |
||||||
|
"0.5.9", |
||||||
|
"0.5.10", |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
class ABIEncoderV2Array(AbstractDetector): |
||||||
|
""" |
||||||
|
Detects Storage ABIEncoderV2 array bug |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "abiencoderv2-array" |
||||||
|
HELP = "Storage abiencoderv2 array" |
||||||
|
IMPACT = DetectorClassification.HIGH |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = ( |
||||||
|
"https://github.com/crytic/slither/wiki/Detector-Documentation#storage-abiencoderv2-array" |
||||||
|
) |
||||||
|
WIKI_TITLE = "Storage ABIEncoderV2 Array" |
||||||
|
WIKI_DESCRIPTION = """`solc` versions `0.4.7`-`0.5.10` contain a [compiler bug](https://blog.ethereum.org/2019/06/25/solidity-storage-array-bugs.) leading to incorrect ABI encoder usage.""" |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract A { |
||||||
|
uint[2][3] bad_arr = [[1, 2], [3, 4], [5, 6]]; |
||||||
|
|
||||||
|
/* Array of arrays passed to abi.encode is vulnerable */ |
||||||
|
function bad() public { |
||||||
|
bytes memory b = abi.encode(bad_arr); |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
`abi.encode(bad_arr)` in a call to `bad()` will incorrectly encode the array as `[[1, 2], [2, 3], [3, 4]]` and lead to unintended behavior. |
||||||
|
""" |
||||||
|
WIKI_RECOMMENDATION = "Use a compiler >= `0.5.10`." |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def _detect_storage_abiencoderv2_arrays(contract): |
||||||
|
""" |
||||||
|
Detects and returns all nodes with storage-allocated abiencoderv2 arrays of arrays/structs in abi.encode, events or external calls |
||||||
|
:param contract: Contract to detect within |
||||||
|
:return: A list of tuples with (function, node) where function node has storage-allocated abiencoderv2 arrays of arrays/structs |
||||||
|
""" |
||||||
|
# Create our result set. |
||||||
|
results = set() |
||||||
|
|
||||||
|
# Loop for each function and modifier. |
||||||
|
# pylint: disable=too-many-nested-blocks |
||||||
|
for function in contract.functions_and_modifiers_declared: |
||||||
|
# Loop every node, looking for storage-allocated array of arrays/structs |
||||||
|
# in arguments to abi.encode, events or external calls |
||||||
|
for node in function.nodes: |
||||||
|
for ir in node.irs: |
||||||
|
# Call to abi.encode() |
||||||
|
if ( |
||||||
|
isinstance(ir, SolidityCall) |
||||||
|
and ir.function == SolidityFunction("abi.encode()") |
||||||
|
or |
||||||
|
# Call to emit event |
||||||
|
# Call to external function |
||||||
|
isinstance(ir, (EventCall, HighLevelCall)) |
||||||
|
): |
||||||
|
for arg in unroll(ir.arguments): |
||||||
|
# Check if arguments are storage allocated arrays of arrays/structs |
||||||
|
if ( |
||||||
|
isinstance(arg.type, ArrayType) |
||||||
|
# Storage allocated |
||||||
|
and ( |
||||||
|
isinstance(arg, StateVariable) |
||||||
|
or (isinstance(arg, LocalVariable) and arg.is_storage) |
||||||
|
) |
||||||
|
# Array of arrays or structs |
||||||
|
and isinstance(arg.type.type, (ArrayType, UserDefinedType)) |
||||||
|
): |
||||||
|
results.add((function, node)) |
||||||
|
break |
||||||
|
|
||||||
|
# Return the resulting set of tuples |
||||||
|
return results |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
""" |
||||||
|
Detect ABIEncoderV2 array bug |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
|
||||||
|
# Check if vulnerable solc versions are used |
||||||
|
if self.slither.solc_version not in vulnerable_solc_versions: |
||||||
|
return results |
||||||
|
|
||||||
|
# Check if pragma experimental ABIEncoderV2 is used |
||||||
|
if not any( |
||||||
|
(p.directive[0] == "experimental" and p.directive[1] == "ABIEncoderV2") |
||||||
|
for p in self.slither.pragma_directives |
||||||
|
): |
||||||
|
return results |
||||||
|
|
||||||
|
# Check for storage-allocated abiencoderv2 arrays of arrays/structs |
||||||
|
# in arguments of abi.encode, events or external calls |
||||||
|
for contract in self.contracts: |
||||||
|
storage_abiencoderv2_arrays = self._detect_storage_abiencoderv2_arrays(contract) |
||||||
|
for function, node in storage_abiencoderv2_arrays: |
||||||
|
info = ["Function ", function, " trigger an abi encoding bug:\n\t- ", node, "\n"] |
||||||
|
res = self.generate_result(info) |
||||||
|
results.append(res) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,147 @@ |
|||||||
|
""" |
||||||
|
Module detecting storage signed integer array bug |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.core.cfg.node import NodeType |
||||||
|
from slither.core.solidity_types import ArrayType |
||||||
|
from slither.core.solidity_types.elementary_type import Int, ElementaryType |
||||||
|
from slither.core.variables.local_variable import LocalVariable |
||||||
|
from slither.core.variables.state_variable import StateVariable |
||||||
|
from slither.slithir.operations.assignment import Assignment |
||||||
|
from slither.slithir.operations.init_array import InitArray |
||||||
|
|
||||||
|
vulnerable_solc_versions = [ |
||||||
|
"0.4.7", |
||||||
|
"0.4.8", |
||||||
|
"0.4.9", |
||||||
|
"0.4.10", |
||||||
|
"0.4.11", |
||||||
|
"0.4.12", |
||||||
|
"0.4.13", |
||||||
|
"0.4.14", |
||||||
|
"0.4.15", |
||||||
|
"0.4.16", |
||||||
|
"0.4.17", |
||||||
|
"0.4.18", |
||||||
|
"0.4.19", |
||||||
|
"0.4.20", |
||||||
|
"0.4.21", |
||||||
|
"0.4.22", |
||||||
|
"0.4.23", |
||||||
|
"0.4.24", |
||||||
|
"0.4.25", |
||||||
|
"0.5.0", |
||||||
|
"0.5.1", |
||||||
|
"0.5.2", |
||||||
|
"0.5.3", |
||||||
|
"0.5.4", |
||||||
|
"0.5.5", |
||||||
|
"0.5.6", |
||||||
|
"0.5.7", |
||||||
|
"0.5.8", |
||||||
|
"0.5.9", |
||||||
|
"0.5.10", |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
class StorageSignedIntegerArray(AbstractDetector): |
||||||
|
""" |
||||||
|
Storage signed integer array |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "storage-array" |
||||||
|
HELP = "Signed storage integer array compiler bug" |
||||||
|
IMPACT = DetectorClassification.HIGH |
||||||
|
CONFIDENCE = DetectorClassification.MEDIUM |
||||||
|
|
||||||
|
WIKI = ( |
||||||
|
"https://github.com/crytic/slither/wiki/Detector-Documentation#storage-signed-integer-array" |
||||||
|
) |
||||||
|
WIKI_TITLE = "Storage Signed Integer Array" |
||||||
|
WIKI_DESCRIPTION = """`solc` versions `0.4.7`-`0.5.10` contain [a compiler bug](https://blog.ethereum.org/2019/06/25/solidity-storage-array-bugs) |
||||||
|
leading to incorrect values in signed integer arrays.""" |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract A { |
||||||
|
int[3] ether_balances; // storage signed integer array |
||||||
|
function bad0() private { |
||||||
|
// ... |
||||||
|
ether_balances = [-1, -1, -1]; |
||||||
|
// ... |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
`bad0()` uses a (storage-allocated) signed integer array state variable to store the ether balances of three accounts. |
||||||
|
`-1` is supposed to indicate uninitialized values but the Solidity bug makes these as `1`, which could be exploited by the accounts. |
||||||
|
""" |
||||||
|
WIKI_RECOMMENDATION = "Use a compiler version >= `0.5.10`." |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def _is_vulnerable_type(ir): |
||||||
|
""" |
||||||
|
Detect if the IR lvalue is a vulnerable type |
||||||
|
Must be a storage allocation, and an array of Int |
||||||
|
Assume the IR is a InitArray, or an Assignement to an ArrayType |
||||||
|
""" |
||||||
|
# Storage allocation |
||||||
|
# Base type is signed integer |
||||||
|
return ( |
||||||
|
( |
||||||
|
isinstance(ir.lvalue, StateVariable) |
||||||
|
or (isinstance(ir.lvalue, LocalVariable) and ir.lvalue.is_storage) |
||||||
|
) |
||||||
|
and isinstance(ir.lvalue.type.type, ElementaryType) |
||||||
|
and ir.lvalue.type.type.type in Int |
||||||
|
) |
||||||
|
|
||||||
|
def detect_storage_signed_integer_arrays(self, contract): |
||||||
|
""" |
||||||
|
Detects and returns all nodes with storage-allocated signed integer array init/assignment |
||||||
|
:param contract: Contract to detect within |
||||||
|
:return: A list of tuples with (function, node) where function node has storage-allocated signed integer array init/assignment |
||||||
|
""" |
||||||
|
# Create our result set. |
||||||
|
results = set() |
||||||
|
|
||||||
|
# Loop for each function and modifier. |
||||||
|
for function in contract.functions_and_modifiers_declared: |
||||||
|
# Loop for every node in this function, looking for storage-allocated |
||||||
|
# signed integer array initializations/assignments |
||||||
|
for node in function.nodes: |
||||||
|
if node.type == NodeType.EXPRESSION: |
||||||
|
for ir in node.irs: |
||||||
|
# Storage-allocated signed integer array initialization expression |
||||||
|
if isinstance(ir, InitArray) and self._is_vulnerable_type(ir): |
||||||
|
results.add((function, node)) |
||||||
|
# Assignment expression with lvalue being a storage-allocated signed integer array and |
||||||
|
# rvalue being a signed integer array of different base type than lvalue |
||||||
|
if ( |
||||||
|
isinstance(ir, Assignment) |
||||||
|
and isinstance(ir.lvalue.type, ArrayType) |
||||||
|
and self._is_vulnerable_type(ir) |
||||||
|
# Base type is signed integer and lvalue base type is different from rvalue base type |
||||||
|
and ir.lvalue.type.type != ir.rvalue.type.type |
||||||
|
): |
||||||
|
results.add((function, node)) |
||||||
|
|
||||||
|
# Return the resulting set of tuples |
||||||
|
return results |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
""" |
||||||
|
Detect storage signed integer array init/assignment |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
if self.slither.solc_version not in vulnerable_solc_versions: |
||||||
|
return results |
||||||
|
for contract in self.contracts: |
||||||
|
storage_signed_integer_arrays = self.detect_storage_signed_integer_arrays(contract) |
||||||
|
for function, node in storage_signed_integer_arrays: |
||||||
|
contract_info = ["Contract ", contract, " \n"] |
||||||
|
function_info = ["\t- Function ", function, "\n"] |
||||||
|
node_info = ["\t\t- ", node, " has a storage signed integer array assignment\n"] |
||||||
|
res = self.generate_result(contract_info + function_info + node_info) |
||||||
|
results.append(res) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,149 @@ |
|||||||
|
""" |
||||||
|
Module detecting uninitialized function pointer calls in constructors |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.slithir.operations import InternalDynamicCall, OperationWithLValue |
||||||
|
from slither.slithir.variables import ReferenceVariable |
||||||
|
from slither.slithir.variables.variable import SlithIRVariable |
||||||
|
|
||||||
|
vulnerable_solc_versions = [ |
||||||
|
"0.4.5", |
||||||
|
"0.4.6", |
||||||
|
"0.4.7", |
||||||
|
"0.4.8", |
||||||
|
"0.4.9", |
||||||
|
"0.4.10", |
||||||
|
"0.4.11", |
||||||
|
"0.4.12", |
||||||
|
"0.4.13", |
||||||
|
"0.4.14", |
||||||
|
"0.4.15", |
||||||
|
"0.4.16", |
||||||
|
"0.4.17", |
||||||
|
"0.4.18", |
||||||
|
"0.4.19", |
||||||
|
"0.4.20", |
||||||
|
"0.4.21", |
||||||
|
"0.4.22", |
||||||
|
"0.4.23", |
||||||
|
"0.4.24", |
||||||
|
"0.4.25", |
||||||
|
"0.5.0", |
||||||
|
"0.5.1", |
||||||
|
"0.5.2", |
||||||
|
"0.5.3", |
||||||
|
"0.5.4", |
||||||
|
"0.5.5", |
||||||
|
"0.5.6", |
||||||
|
"0.5.7", |
||||||
|
"0.5.8", |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
def _get_variables_entrance(function): |
||||||
|
""" |
||||||
|
Return the first SSA variables of the function |
||||||
|
Catpure the phi operation at the entry point |
||||||
|
""" |
||||||
|
ret = [] |
||||||
|
if function.entry_point: |
||||||
|
for ir_ssa in function.entry_point.irs_ssa: |
||||||
|
if isinstance(ir_ssa, OperationWithLValue): |
||||||
|
ret.append(ir_ssa.lvalue) |
||||||
|
return ret |
||||||
|
|
||||||
|
|
||||||
|
def _is_vulnerable(node, variables_entrance): |
||||||
|
""" |
||||||
|
Vulnerable if an IR ssa: |
||||||
|
- It is an internal dynamic call |
||||||
|
- The destination has not an index of 0 |
||||||
|
- The destination is not in the allowed variable |
||||||
|
""" |
||||||
|
for ir_ssa in node.irs_ssa: |
||||||
|
if isinstance(ir_ssa, InternalDynamicCall): |
||||||
|
destination = ir_ssa.function |
||||||
|
# If it is a reference variable, destination should be the origin variable |
||||||
|
# Note: this will create FN if one of the field of a structure is updated, while not begin |
||||||
|
# the field of the function pointer. This should be fixed once we have the IR refactoring |
||||||
|
if isinstance(destination, ReferenceVariable): |
||||||
|
destination = destination.points_to_origin |
||||||
|
if isinstance(destination, SlithIRVariable) and ir_ssa.function.index == 0: |
||||||
|
return True |
||||||
|
if destination in variables_entrance: |
||||||
|
return True |
||||||
|
return False |
||||||
|
|
||||||
|
|
||||||
|
class UninitializedFunctionPtrsConstructor(AbstractDetector): |
||||||
|
""" |
||||||
|
Uninitialized function pointer calls in constructors |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "uninitialized-fptr-cst" |
||||||
|
HELP = "Uninitialized function pointer calls in constructors" |
||||||
|
IMPACT = DetectorClassification.LOW |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-function-pointers-in-constructors" |
||||||
|
WIKI_TITLE = "Uninitialized function pointers in constructors" |
||||||
|
WIKI_DESCRIPTION = "solc versions `0.4.5`-`0.4.26` and `0.5.0`-`0.5.8` contain a compiler bug leading to unexpected behavior when calling uninitialized function pointers in constructors." |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract bad0 { |
||||||
|
|
||||||
|
constructor() public { |
||||||
|
/* Uninitialized function pointer */ |
||||||
|
function(uint256) internal returns(uint256) a; |
||||||
|
a(10); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
``` |
||||||
|
The call to `a(10)` will lead to unexpected behavior because function pointer `a` is not initialized in the constructor.""" |
||||||
|
WIKI_RECOMMENDATION = ( |
||||||
|
"Initialize function pointers before calling. Avoid function pointers if possible." |
||||||
|
) |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def _detect_uninitialized_function_ptr_in_constructor(contract): |
||||||
|
""" |
||||||
|
Detect uninitialized function pointer calls in constructors |
||||||
|
:param contract: The contract of interest for detection |
||||||
|
:return: A list of nodes with uninitialized function pointer calls in the constructor of given contract |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
constructor = contract.constructors_declared |
||||||
|
if constructor: |
||||||
|
variables_entrance = _get_variables_entrance(constructor) |
||||||
|
results = [ |
||||||
|
node for node in constructor.nodes if _is_vulnerable(node, variables_entrance) |
||||||
|
] |
||||||
|
return results |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
""" |
||||||
|
Detect uninitialized function pointer calls in constructors of contracts |
||||||
|
Returns: |
||||||
|
list: ['uninitialized function pointer calls in constructors'] |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
|
||||||
|
# Check if vulnerable solc versions are used |
||||||
|
if self.slither.solc_version not in vulnerable_solc_versions: |
||||||
|
return results |
||||||
|
|
||||||
|
for contract in self.slither.contracts: |
||||||
|
contract_info = ["Contract ", contract, " \n"] |
||||||
|
nodes = self._detect_uninitialized_function_ptr_in_constructor(contract) |
||||||
|
for node in nodes: |
||||||
|
node_info = [ |
||||||
|
"\t ", |
||||||
|
node, |
||||||
|
" is an unintialized function pointer call in a constructor\n", |
||||||
|
] |
||||||
|
json = self.generate_result(contract_info + node_info) |
||||||
|
results.append(json) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,105 @@ |
|||||||
|
""" |
||||||
|
Module detecting unimplemented functions |
||||||
|
Recursively check the called functions |
||||||
|
|
||||||
|
Collect all the implemented and unimplemented functions of all the contracts |
||||||
|
Check for unimplemented functions that are never implemented |
||||||
|
Consider public state variables as implemented functions |
||||||
|
Do not consider fallback function or constructor |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
|
||||||
|
# Since 0.5.1, Solidity allows creating state variable matching a function signature. |
||||||
|
older_solc_versions = ["0.5.0"] + ["0.4." + str(x) for x in range(0, 27)] |
||||||
|
|
||||||
|
|
||||||
|
class UnimplementedFunctionDetection(AbstractDetector): |
||||||
|
""" |
||||||
|
Unimplemented functions detector |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "unimplemented-functions" |
||||||
|
HELP = "Unimplemented functions" |
||||||
|
IMPACT = DetectorClassification.INFORMATIONAL |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#unimplemented-functions" |
||||||
|
|
||||||
|
WIKI_TITLE = "Unimplemented functions" |
||||||
|
WIKI_DESCRIPTION = "Detect functions that are not implemented on derived-most contracts." |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
interface BaseInterface { |
||||||
|
function f1() external returns(uint); |
||||||
|
function f2() external returns(uint); |
||||||
|
} |
||||||
|
|
||||||
|
interface BaseInterface2 { |
||||||
|
function f3() external returns(uint); |
||||||
|
} |
||||||
|
|
||||||
|
contract DerivedContract is BaseInterface, BaseInterface2 { |
||||||
|
function f1() external returns(uint){ |
||||||
|
return 42; |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
`DerivedContract` does not implement `BaseInterface.f2` or `BaseInterface2.f3`. |
||||||
|
As a result, the contract will not properly compile. |
||||||
|
All unimplemented functions must be implemented on a contract that is meant to be used.""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = "Implement all unimplemented functions in any contract you intend to use directly (not simply inherit from)." |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def _match_state_variable(contract, f): |
||||||
|
return any(s.full_name == f.full_name for s in contract.state_variables) |
||||||
|
|
||||||
|
def _detect_unimplemented_function(self, contract): |
||||||
|
""" |
||||||
|
Detects any function definitions which are not implemented in the given contract. |
||||||
|
:param contract: The contract to search unimplemented functions for. |
||||||
|
:return: A list of functions which are not implemented. |
||||||
|
""" |
||||||
|
|
||||||
|
# If it's simply a contract signature, we have no functions. |
||||||
|
if contract.is_signature_only(): |
||||||
|
return set() |
||||||
|
|
||||||
|
# Populate our unimplemented functions set with any functions not implemented in this contract, excluding the |
||||||
|
# fallback function and constructor. |
||||||
|
unimplemented = set() |
||||||
|
for f in contract.all_functions_called: |
||||||
|
if ( |
||||||
|
not f.is_implemented |
||||||
|
and not f.is_constructor |
||||||
|
and not f.is_fallback |
||||||
|
and not f.is_constructor_variables |
||||||
|
): |
||||||
|
if self.slither.solc_version not in older_solc_versions: |
||||||
|
# Since 0.5.1, Solidity allows creating state variable matching a function signature |
||||||
|
if not self._match_state_variable(contract, f): |
||||||
|
unimplemented.add(f) |
||||||
|
else: |
||||||
|
unimplemented.add(f) |
||||||
|
return unimplemented |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
"""Detect unimplemented functions |
||||||
|
|
||||||
|
Recursively visit the calls |
||||||
|
Returns: |
||||||
|
list: {'vuln', 'filename,'contract','func'} |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
for contract in self.slither.contracts_derived: |
||||||
|
functions = self._detect_unimplemented_function(contract) |
||||||
|
if functions: |
||||||
|
info = [contract, " does not implement functions:\n"] |
||||||
|
|
||||||
|
for function in sorted(functions, key=lambda x: x.full_name): |
||||||
|
info += ["\t- ", function, "\n"] |
||||||
|
|
||||||
|
res = self.generate_result(info) |
||||||
|
results.append(res) |
||||||
|
return results |
@ -0,0 +1,122 @@ |
|||||||
|
""" |
||||||
|
Module detecting bad PRNG due to the use of block.timestamp, now or blockhash (block.blockhash) as a source of randomness |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.analyses.data_dependency.data_dependency import is_dependent_ssa |
||||||
|
from slither.core.declarations.solidity_variables import ( |
||||||
|
SolidityVariable, |
||||||
|
SolidityFunction, |
||||||
|
SolidityVariableComposed, |
||||||
|
) |
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.slithir.operations import BinaryType, Binary |
||||||
|
from slither.slithir.operations import SolidityCall |
||||||
|
|
||||||
|
|
||||||
|
def collect_return_values_of_bad_PRNG_functions(f): |
||||||
|
""" |
||||||
|
Return the return-values of calls to blockhash() |
||||||
|
Args: |
||||||
|
f (Function) |
||||||
|
Returns: |
||||||
|
list(values) |
||||||
|
""" |
||||||
|
values_returned = [] |
||||||
|
for n in f.nodes: |
||||||
|
for ir in n.irs_ssa: |
||||||
|
if ( |
||||||
|
isinstance(ir, SolidityCall) |
||||||
|
and ir.function == SolidityFunction("blockhash(uint256)") |
||||||
|
and ir.lvalue |
||||||
|
): |
||||||
|
values_returned.append(ir.lvalue) |
||||||
|
return values_returned |
||||||
|
|
||||||
|
|
||||||
|
def contains_bad_PRNG_sources(func, blockhash_ret_values): |
||||||
|
""" |
||||||
|
Check if any node in function has a modulus operator and the first operand is dependent on block.timestamp, now or blockhash() |
||||||
|
Returns: |
||||||
|
(nodes) |
||||||
|
""" |
||||||
|
ret = set() |
||||||
|
# pylint: disable=too-many-nested-blocks |
||||||
|
for node in func.nodes: |
||||||
|
for ir in node.irs_ssa: |
||||||
|
if isinstance(ir, Binary) and ir.type == BinaryType.MODULO: |
||||||
|
if is_dependent_ssa( |
||||||
|
ir.variable_left, SolidityVariableComposed("block.timestamp"), func.contract |
||||||
|
) or is_dependent_ssa(ir.variable_left, SolidityVariable("now"), func.contract): |
||||||
|
ret.add(node) |
||||||
|
break |
||||||
|
|
||||||
|
for ret_val in blockhash_ret_values: |
||||||
|
if is_dependent_ssa(ir.variable_left, ret_val, func.contract): |
||||||
|
ret.add(node) |
||||||
|
break |
||||||
|
return list(ret) |
||||||
|
|
||||||
|
|
||||||
|
def detect_bad_PRNG(contract): |
||||||
|
""" |
||||||
|
Args: |
||||||
|
contract (Contract) |
||||||
|
Returns: |
||||||
|
list((Function), (list (Node))) |
||||||
|
""" |
||||||
|
blockhash_ret_values = [] |
||||||
|
for f in contract.functions: |
||||||
|
blockhash_ret_values += collect_return_values_of_bad_PRNG_functions(f) |
||||||
|
ret = [] |
||||||
|
for f in contract.functions: |
||||||
|
bad_prng_nodes = contains_bad_PRNG_sources(f, blockhash_ret_values) |
||||||
|
if bad_prng_nodes: |
||||||
|
ret.append((f, bad_prng_nodes)) |
||||||
|
return ret |
||||||
|
|
||||||
|
|
||||||
|
class BadPRNG(AbstractDetector): |
||||||
|
""" |
||||||
|
Detect weak PRNG due to a modulo operation on block.timestamp, now or blockhash |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "weak-prng" |
||||||
|
HELP = "Weak PRNG" |
||||||
|
IMPACT = DetectorClassification.HIGH |
||||||
|
CONFIDENCE = DetectorClassification.MEDIUM |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#weak-PRNG" |
||||||
|
|
||||||
|
WIKI_TITLE = "Weak PRNG" |
||||||
|
WIKI_DESCRIPTION = "Weak PRNG due to a modulo on `block.timestamp`, `now` or `blockhash`. These can be influenced by miners to some extent so they should be avoided." |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract Game { |
||||||
|
|
||||||
|
uint reward_determining_number; |
||||||
|
|
||||||
|
function guessing() external{ |
||||||
|
reward_determining_number = uint256(block.blockhash(10000)) % 10; |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
Eve is a miner. Eve calls `guessing` and re-orders the block containing the transaction. |
||||||
|
As a result, Eve wins the game.""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = ( |
||||||
|
"Do not use `block.timestamp`, `now` or `blockhash` as a source of randomness" |
||||||
|
) |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
"""Detect bad PRNG due to the use of block.timestamp, now or blockhash (block.blockhash) as a source of randomness""" |
||||||
|
results = [] |
||||||
|
for c in self.slither.contracts_derived: |
||||||
|
values = detect_bad_PRNG(c) |
||||||
|
for func, nodes in values: |
||||||
|
|
||||||
|
for node in nodes: |
||||||
|
info = [func, ' uses a weak PRNG: "', node, '" \n'] |
||||||
|
res = self.generate_result(info) |
||||||
|
results.append(res) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,118 @@ |
|||||||
|
""" |
||||||
|
Module detecting assignment of array length |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.core.cfg.node import NodeType |
||||||
|
from slither.slithir.operations import Assignment, Length |
||||||
|
from slither.slithir.variables.reference import ReferenceVariable |
||||||
|
from slither.slithir.operations.binary import Binary |
||||||
|
from slither.analyses.data_dependency.data_dependency import is_tainted |
||||||
|
|
||||||
|
|
||||||
|
def detect_array_length_assignment(contract): |
||||||
|
""" |
||||||
|
Detects and returns all nodes which assign array length. |
||||||
|
:param contract: Contract to detect assignment within. |
||||||
|
:return: A list of tuples with (Variable, node) where Variable references an array whose length was set by node. |
||||||
|
""" |
||||||
|
|
||||||
|
# Create our result set. |
||||||
|
results = set() |
||||||
|
|
||||||
|
# Loop for each function and modifier. |
||||||
|
# pylint: disable=too-many-nested-blocks |
||||||
|
for function in contract.functions_and_modifiers_declared: |
||||||
|
# Define a set of reference variables which refer to array length. |
||||||
|
array_length_refs = set() |
||||||
|
|
||||||
|
# Loop for every node in this function, looking for expressions where array length references are made, |
||||||
|
# and subsequent expressions where array length references are assigned to. |
||||||
|
for node in function.nodes: |
||||||
|
if node.type == NodeType.EXPRESSION: |
||||||
|
for ir in node.irs: |
||||||
|
|
||||||
|
# First we look for the member access for 'length', for which a reference is created. |
||||||
|
# We add the reference to our list of array length references. |
||||||
|
if isinstance(ir, Length): # a |
||||||
|
# if ir.variable_right == "length": |
||||||
|
array_length_refs.add(ir.lvalue) |
||||||
|
|
||||||
|
# If we have an assignment/binary operation, verify the left side refers to a reference variable |
||||||
|
# which is in our list or array length references. (Array length is being assigned to). |
||||||
|
elif isinstance(ir, (Assignment, Binary)): |
||||||
|
if isinstance(ir.lvalue, ReferenceVariable): |
||||||
|
if ir.lvalue in array_length_refs and any( |
||||||
|
is_tainted(v, contract) for v in ir.read |
||||||
|
): |
||||||
|
# the taint is not precise enough yet |
||||||
|
# as a result, REF_0 = REF_0 + 1 |
||||||
|
# where REF_0 points to a LENGTH operation |
||||||
|
# is considered as tainted |
||||||
|
if ir.lvalue in ir.read: |
||||||
|
continue |
||||||
|
results.add(node) |
||||||
|
break |
||||||
|
|
||||||
|
# Return the resulting set of nodes which set array length. |
||||||
|
return results |
||||||
|
|
||||||
|
|
||||||
|
class ArrayLengthAssignment(AbstractDetector): |
||||||
|
""" |
||||||
|
Array length assignment |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "controlled-array-length" |
||||||
|
HELP = "Tainted array length assignment" |
||||||
|
IMPACT = DetectorClassification.HIGH |
||||||
|
CONFIDENCE = DetectorClassification.MEDIUM |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#array-length-assignment" |
||||||
|
|
||||||
|
WIKI_TITLE = "Array Length Assignment" |
||||||
|
WIKI_DESCRIPTION = """Detects the direct assignment of an array's length.""" |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract A { |
||||||
|
uint[] testArray; // dynamic size array |
||||||
|
|
||||||
|
function f(uint usersCount) public { |
||||||
|
// ... |
||||||
|
testArray.length = usersCount; |
||||||
|
// ... |
||||||
|
} |
||||||
|
|
||||||
|
function g(uint userIndex, uint val) public { |
||||||
|
// ... |
||||||
|
testArray[userIndex] = val; |
||||||
|
// ... |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
Contract storage/state-variables are indexed by a 256-bit integer. |
||||||
|
The user can set the array length to `2**256-1` in order to index all storage slots. |
||||||
|
In the example above, one could call the function `f` to set the array length, then call the function `g` to control any storage slot desired. |
||||||
|
Note that storage slots here are indexed via a hash of the indexers; nonetheless, all storage will still be accessible and could be controlled by the attacker.""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = """Do not allow array lengths to be set directly set; instead, opt to add values as needed. |
||||||
|
Otherwise, thoroughly review the contract to ensure a user-controlled variable cannot reach an array length assignment.""" |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
""" |
||||||
|
Detect array length assignments |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
for contract in self.contracts: |
||||||
|
array_length_assignments = detect_array_length_assignment(contract) |
||||||
|
if array_length_assignments: |
||||||
|
contract_info = [ |
||||||
|
contract, |
||||||
|
" contract sets array length with a user-controlled value:\n", |
||||||
|
] |
||||||
|
for node in array_length_assignments: |
||||||
|
node_info = contract_info + ["\t- ", node, "\n"] |
||||||
|
res = self.generate_result(node_info) |
||||||
|
results.append(res) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,83 @@ |
|||||||
|
""" |
||||||
|
Module detecting state changes in assert calls |
||||||
|
""" |
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.slithir.operations.internal_call import InternalCall |
||||||
|
|
||||||
|
|
||||||
|
def detect_assert_state_change(contract): |
||||||
|
""" |
||||||
|
Detects and returns all nodes with assert calls that change contract state from within the invariant |
||||||
|
:param contract: Contract to detect |
||||||
|
:return: A list of nodes with assert calls that change contract state from within the invariant |
||||||
|
""" |
||||||
|
|
||||||
|
# Create our result set. |
||||||
|
# List of tuples (function, node) |
||||||
|
results = [] |
||||||
|
|
||||||
|
# Loop for each function and modifier. |
||||||
|
for function in contract.functions_declared + contract.modifiers_declared: |
||||||
|
for node in function.nodes: |
||||||
|
# Detect assert() calls |
||||||
|
if any(c.name == "assert(bool)" for c in node.internal_calls) and ( |
||||||
|
# Detect direct changes to state |
||||||
|
node.state_variables_written |
||||||
|
or |
||||||
|
# Detect changes to state via function calls |
||||||
|
any( |
||||||
|
ir |
||||||
|
for ir in node.irs |
||||||
|
if isinstance(ir, InternalCall) and ir.function.state_variables_written |
||||||
|
) |
||||||
|
): |
||||||
|
results.append((function, node)) |
||||||
|
|
||||||
|
# Return the resulting set of nodes |
||||||
|
return results |
||||||
|
|
||||||
|
|
||||||
|
class AssertStateChange(AbstractDetector): |
||||||
|
""" |
||||||
|
Assert state change |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "assert-state-change" |
||||||
|
HELP = "Assert state change" |
||||||
|
IMPACT = DetectorClassification.INFORMATIONAL |
||||||
|
CONFIDENCE = DetectorClassification.INFORMATIONAL |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#assert-state-change" |
||||||
|
WIKI_TITLE = "Assert state shange" |
||||||
|
WIKI_DESCRIPTION = """Incorrect use of `assert()`. See Solidity best [practices](https://solidity.readthedocs.io/en/latest/control-structures.html#id4).""" |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract A { |
||||||
|
|
||||||
|
uint s_a; |
||||||
|
|
||||||
|
function bad() public { |
||||||
|
assert((s_a += 1) > 10); |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
The assert in `bad()` increments the state variable `s_a` while checking for the condition. |
||||||
|
""" |
||||||
|
WIKI_RECOMMENDATION = """Use `require` for invariants modifying the state.""" |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
""" |
||||||
|
Detect assert calls that change state from within the invariant |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
for contract in self.contracts: |
||||||
|
assert_state_change = detect_assert_state_change(contract) |
||||||
|
for (func, node) in assert_state_change: |
||||||
|
info = [func, " has an assert() call which possibly changes state.\n"] |
||||||
|
info += ["\t-", node, "\n"] |
||||||
|
info += [ |
||||||
|
"Consider using require() or change the invariant to not modify the state.\n" |
||||||
|
] |
||||||
|
res = self.generate_result(info) |
||||||
|
results.append(res) |
||||||
|
return results |
@ -0,0 +1,94 @@ |
|||||||
|
from slither.core.cfg.node import NodeType |
||||||
|
from slither.core.solidity_types.array_type import ArrayType |
||||||
|
from slither.core.solidity_types.mapping_type import MappingType |
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
|
||||||
|
|
||||||
|
class CostlyOperationsInLoop(AbstractDetector): |
||||||
|
|
||||||
|
ARGUMENT = "costly-loop" |
||||||
|
HELP = "Costly operations in a loop" |
||||||
|
IMPACT = DetectorClassification.INFORMATIONAL |
||||||
|
# Overall the detector seems precise, but it does not take into account |
||||||
|
# case where there are external calls or internal calls that might read the state |
||||||
|
# variable changes. In these cases the optimization should not be applied |
||||||
|
CONFIDENCE = DetectorClassification.MEDIUM |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#costly-operations-inside-a-loop" |
||||||
|
|
||||||
|
WIKI_TITLE = "Costly operations inside a loop" |
||||||
|
WIKI_DESCRIPTION = ( |
||||||
|
"Costly operations inside a loop might waste gas, so optimizations are justified." |
||||||
|
) |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract CostlyOperationsInLoop{ |
||||||
|
|
||||||
|
uint loop_count = 100; |
||||||
|
uint state_variable=0; |
||||||
|
|
||||||
|
function bad() external{ |
||||||
|
for (uint i=0; i < loop_count; i++){ |
||||||
|
state_variable++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function good() external{ |
||||||
|
uint local_variable = state_variable; |
||||||
|
for (uint i=0; i < loop_count; i++){ |
||||||
|
local_variable++; |
||||||
|
} |
||||||
|
state_variable = local_variable; |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
Incrementing `state_variable` in a loop incurs a lot of gas because of expensive `SSTOREs`, which might lead to an `out-of-gas`.""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = "Use a local variable to hold the loop computation result." |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def costly_operations_in_loop(node, in_loop, visited, ret): |
||||||
|
if node in visited: |
||||||
|
return |
||||||
|
# shared visited |
||||||
|
visited.append(node) |
||||||
|
|
||||||
|
if node.type == NodeType.STARTLOOP: |
||||||
|
in_loop = True |
||||||
|
elif node.type == NodeType.ENDLOOP: |
||||||
|
in_loop = False |
||||||
|
|
||||||
|
if in_loop: |
||||||
|
sv_written = node.state_variables_written |
||||||
|
for sv in sv_written: |
||||||
|
# Ignore Array/Mapping/Struct types for now |
||||||
|
if isinstance(sv.type, (ArrayType, MappingType)): |
||||||
|
continue |
||||||
|
ret.append(node) |
||||||
|
break |
||||||
|
|
||||||
|
for son in node.sons: |
||||||
|
CostlyOperationsInLoop.costly_operations_in_loop(son, in_loop, visited, ret) |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def detect_costly_operations_in_loop(contract): |
||||||
|
ret = [] |
||||||
|
for f in contract.functions + contract.modifiers: |
||||||
|
if f.contract_declarer == contract and f.is_implemented: |
||||||
|
CostlyOperationsInLoop.costly_operations_in_loop(f.entry_point, False, [], ret) |
||||||
|
|
||||||
|
return ret |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
"""""" |
||||||
|
results = [] |
||||||
|
for c in self.slither.contracts_derived: |
||||||
|
values = self.detect_costly_operations_in_loop(c) |
||||||
|
for node in values: |
||||||
|
func = node.function |
||||||
|
info = [func, " has costly operations inside a loop:\n"] |
||||||
|
info += ["\t- ", node, "\n"] |
||||||
|
res = self.generate_result(info) |
||||||
|
results.append(res) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,82 @@ |
|||||||
|
""" |
||||||
|
Detect deletion on structure containing a mapping |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.core.declarations import Structure |
||||||
|
from slither.core.solidity_types import MappingType, UserDefinedType |
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.slithir.operations import Delete |
||||||
|
|
||||||
|
|
||||||
|
class MappingDeletionDetection(AbstractDetector): |
||||||
|
""" |
||||||
|
Mapping deletion detector |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "mapping-deletion" |
||||||
|
HELP = "Deletion on mapping containing a structure" |
||||||
|
IMPACT = DetectorClassification.MEDIUM |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#deletion-on-mapping-containing-a-structure" |
||||||
|
|
||||||
|
WIKI_TITLE = "Deletion on mapping containing a structure" |
||||||
|
WIKI_DESCRIPTION = "A deletion in a structure containing a mapping will not delete the mapping (see the [Solidity documentation](https://solidity.readthedocs.io/en/latest/types.html##delete)). The remaining data may be used to compromise the contract." |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
struct BalancesStruct{ |
||||||
|
address owner; |
||||||
|
mapping(address => uint) balances; |
||||||
|
} |
||||||
|
mapping(address => BalancesStruct) public stackBalance; |
||||||
|
|
||||||
|
function remove() internal{ |
||||||
|
delete stackBalance[msg.sender]; |
||||||
|
} |
||||||
|
``` |
||||||
|
`remove` deletes an item of `stackBalance`. |
||||||
|
The mapping `balances` is never deleted, so `remove` does not work as intended.""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = ( |
||||||
|
"Use a lock mechanism instead of a deletion to disable structure containing a mapping." |
||||||
|
) |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def detect_mapping_deletion(contract): |
||||||
|
"""Detect deletion on structure containing a mapping |
||||||
|
|
||||||
|
Returns: |
||||||
|
list (function, structure, node) |
||||||
|
""" |
||||||
|
ret = [] |
||||||
|
# pylint: disable=too-many-nested-blocks |
||||||
|
for f in contract.functions: |
||||||
|
for node in f.nodes: |
||||||
|
for ir in node.irs: |
||||||
|
if isinstance(ir, Delete): |
||||||
|
value = ir.variable |
||||||
|
if isinstance(value.type, UserDefinedType) and isinstance( |
||||||
|
value.type.type, Structure |
||||||
|
): |
||||||
|
st = value.type.type |
||||||
|
if any(isinstance(e.type, MappingType) for e in st.elems.values()): |
||||||
|
ret.append((f, st, node)) |
||||||
|
return ret |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
"""Detect mapping deletion |
||||||
|
|
||||||
|
Returns: |
||||||
|
list: {'vuln', 'filename,'contract','func','struct''} |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
for c in self.contracts: |
||||||
|
mapping = MappingDeletionDetection.detect_mapping_deletion(c) |
||||||
|
for (func, struct, node) in mapping: |
||||||
|
info = [func, " deletes ", struct, " which contains a mapping:\n"] |
||||||
|
info += ["\t-", node, "\n"] |
||||||
|
|
||||||
|
res = self.generate_result(info) |
||||||
|
results.append(res) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,88 @@ |
|||||||
|
""" |
||||||
|
Module detecting redundant statements. |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.core.cfg.node import NodeType |
||||||
|
from slither.core.expressions.elementary_type_name_expression import ElementaryTypeNameExpression |
||||||
|
from slither.core.expressions.identifier import Identifier |
||||||
|
|
||||||
|
|
||||||
|
class RedundantStatements(AbstractDetector): |
||||||
|
""" |
||||||
|
Use of Redundant Statements |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "redundant-statements" |
||||||
|
HELP = "Redundant statements" |
||||||
|
IMPACT = DetectorClassification.INFORMATIONAL |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#redundant-statements" |
||||||
|
|
||||||
|
WIKI_TITLE = "Redundant Statements" |
||||||
|
WIKI_DESCRIPTION = "Detect the usage of redundant statements that have no effect." |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract RedundantStatementsContract { |
||||||
|
|
||||||
|
constructor() public { |
||||||
|
uint; // Elementary Type Name |
||||||
|
bool; // Elementary Type Name |
||||||
|
RedundantStatementsContract; // Identifier |
||||||
|
} |
||||||
|
|
||||||
|
function test() public returns (uint) { |
||||||
|
uint; // Elementary Type Name |
||||||
|
assert; // Identifier |
||||||
|
test; // Identifier |
||||||
|
return 777; |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
Each commented line references types/identifiers, but performs no action with them, so no code will be generated for such statements and they can be removed.""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = "Remove redundant statements if they congest code but offer no value." |
||||||
|
|
||||||
|
# This is a disallowed list of tuple (node.type, type(node.expression)) |
||||||
|
REDUNDANT_TOP_LEVEL_EXPRESSIONS = (ElementaryTypeNameExpression, Identifier) |
||||||
|
|
||||||
|
def detect_redundant_statements_contract(self, contract): |
||||||
|
"""Detects the usage of redundant statements in a contract. |
||||||
|
|
||||||
|
Returns: |
||||||
|
list: nodes""" |
||||||
|
results = [] |
||||||
|
|
||||||
|
# Loop through all functions + modifiers defined explicitly in this contract. |
||||||
|
for function in contract.functions_and_modifiers_declared: |
||||||
|
|
||||||
|
# Loop through each node in this function. |
||||||
|
for node in function.nodes: |
||||||
|
if node.expression: |
||||||
|
if node.type == NodeType.EXPRESSION and isinstance( |
||||||
|
node.expression, self.REDUNDANT_TOP_LEVEL_EXPRESSIONS |
||||||
|
): |
||||||
|
results.append(node) |
||||||
|
|
||||||
|
return results |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
"""Detect redundant statements |
||||||
|
|
||||||
|
Recursively visit the calls |
||||||
|
Returns: |
||||||
|
list: {'vuln', 'filename,'contract','func', 'redundant_statements'} |
||||||
|
|
||||||
|
""" |
||||||
|
results = [] |
||||||
|
for contract in self.contracts: |
||||||
|
redundant_statements = self.detect_redundant_statements_contract(contract) |
||||||
|
if redundant_statements: |
||||||
|
|
||||||
|
for redundant_statement in redundant_statements: |
||||||
|
info = ['Redundant expression "', redundant_statement, '" in', contract, "\n"] |
||||||
|
json = self.generate_result(info) |
||||||
|
results.append(json) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,107 @@ |
|||||||
|
""" |
||||||
|
Module detecting state variables initializing from an immediate function call (prior to constructor run). |
||||||
|
""" |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
from slither.visitors.expression.export_values import ExportValues |
||||||
|
from slither.core.declarations.function import Function |
||||||
|
from slither.core.variables.state_variable import StateVariable |
||||||
|
|
||||||
|
|
||||||
|
def detect_function_init_state_vars(contract): |
||||||
|
""" |
||||||
|
Detect any state variables that are initialized from an immediate function call (prior to constructor run). |
||||||
|
:param contract: The contract to detect state variable definitions for. |
||||||
|
:return: A list of all state variables defined in the given contract that meet the specified criteria. |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
|
||||||
|
# Loop for each state variable explicitly defined in this contract. |
||||||
|
for state_variable in contract.variables: |
||||||
|
|
||||||
|
# Skip this variable if it is inherited and not explicitly defined in this contract definition. |
||||||
|
if state_variable.contract != contract: |
||||||
|
continue |
||||||
|
|
||||||
|
# If it has an expression, we try to break it down to identify if it contains a function call, or reference |
||||||
|
# to a non-constant state variable. |
||||||
|
if state_variable.expression: |
||||||
|
exported_values = ExportValues(state_variable.expression).result() |
||||||
|
for exported_value in exported_values: |
||||||
|
if ( |
||||||
|
isinstance(exported_value, StateVariable) and not exported_value.is_constant |
||||||
|
) or (isinstance(exported_value, Function) and not exported_value.pure): |
||||||
|
results.append(state_variable) |
||||||
|
break |
||||||
|
|
||||||
|
return results |
||||||
|
|
||||||
|
|
||||||
|
class FunctionInitializedState(AbstractDetector): |
||||||
|
""" |
||||||
|
State variables initializing from an immediate function call (prior to constructor run). |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "function-init-state" |
||||||
|
HELP = "Function initializing state variables" |
||||||
|
IMPACT = DetectorClassification.INFORMATIONAL |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#function-initializing-state-variables" |
||||||
|
|
||||||
|
WIKI_TITLE = "Function Initializing State" |
||||||
|
WIKI_DESCRIPTION = "Detects the immediate initialization of state variables through function calls that are not pure/constant, or that use non-constant state variable." |
||||||
|
WIKI_EXPLOIT_SCENARIO = """ |
||||||
|
```solidity |
||||||
|
contract StateVarInitFromFunction { |
||||||
|
|
||||||
|
uint public v = set(); // Initialize from function (sets to 77) |
||||||
|
uint public w = 5; |
||||||
|
uint public x = set(); // Initialize from function (sets to 88) |
||||||
|
address public shouldntBeReported = address(8); |
||||||
|
|
||||||
|
constructor(){ |
||||||
|
// The constructor is run after all state variables are initialized. |
||||||
|
} |
||||||
|
|
||||||
|
function set() public returns(uint) { |
||||||
|
// If this function is being used to initialize a state variable declared |
||||||
|
// before w, w will be zero. If it is declared after w, w will be set. |
||||||
|
if(w == 0) { |
||||||
|
return 77; |
||||||
|
} |
||||||
|
|
||||||
|
return 88; |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
In this case, users might intend a function to return a value a state variable can initialize with, without realizing the context for the contract is not fully initialized. |
||||||
|
In the example above, the same function sets two different values for state variables because it checks a state variable that is not yet initialized in one case, and is initialized in the other. |
||||||
|
Special care must be taken when initializing state variables from an immediate function call so as not to incorrectly assume the state is initialized. |
||||||
|
""" |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = "Remove any initialization of state variables via non-constant state variables or function calls. If variables must be set upon contract deployment, locate initialization in the constructor instead." |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
""" |
||||||
|
Detect state variables defined from an immediate function call (pre-contract deployment). |
||||||
|
|
||||||
|
Recursively visit the calls |
||||||
|
Returns: |
||||||
|
list: {'vuln', 'filename,'contract','func', 'shadow'} |
||||||
|
|
||||||
|
""" |
||||||
|
results = [] |
||||||
|
for contract in self.contracts: |
||||||
|
state_variables = detect_function_init_state_vars(contract) |
||||||
|
if state_variables: |
||||||
|
for state_variable in state_variables: |
||||||
|
info = [ |
||||||
|
state_variable, |
||||||
|
" is set pre-construction with a non-constant function or state variable:\n", |
||||||
|
] |
||||||
|
info += [f"\t- {state_variable.expression}\n"] |
||||||
|
json = self.generate_result(info) |
||||||
|
results.append(json) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,86 @@ |
|||||||
|
""" |
||||||
|
Check for state variables too similar |
||||||
|
Do not check contract inheritance |
||||||
|
""" |
||||||
|
import difflib |
||||||
|
|
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
|
||||||
|
|
||||||
|
class SimilarVarsDetection(AbstractDetector): |
||||||
|
""" |
||||||
|
Variable similar detector |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = "similar-names" |
||||||
|
HELP = "Variable names are too similar" |
||||||
|
IMPACT = DetectorClassification.INFORMATIONAL |
||||||
|
CONFIDENCE = DetectorClassification.MEDIUM |
||||||
|
|
||||||
|
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#variable-names-are-too-similar" |
||||||
|
|
||||||
|
WIKI_TITLE = "Variable names too similar" |
||||||
|
WIKI_DESCRIPTION = "Detect variables with names that are too similar." |
||||||
|
WIKI_EXPLOIT_SCENARIO = "Bob uses several variables with similar names. As a result, his code is difficult to review." |
||||||
|
WIKI_RECOMMENDATION = "Prevent variables from having similar names." |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def similar(seq1, seq2): |
||||||
|
"""Test the name similarity |
||||||
|
|
||||||
|
Two name are similar if difflib.SequenceMatcher on the lowercase |
||||||
|
version of the name is greater than 0.90 |
||||||
|
See: https://docs.python.org/2/library/difflib.html |
||||||
|
Args: |
||||||
|
seq1 (str): first name |
||||||
|
seq2 (str): second name |
||||||
|
Returns: |
||||||
|
bool: true if names are similar |
||||||
|
""" |
||||||
|
if len(seq1) != len(seq2): |
||||||
|
return False |
||||||
|
val = difflib.SequenceMatcher(a=seq1.lower(), b=seq2.lower()).ratio() |
||||||
|
ret = val > 0.90 |
||||||
|
return ret |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def detect_sim(contract): |
||||||
|
"""Detect variables with similar name |
||||||
|
|
||||||
|
Returns: |
||||||
|
bool: true if variables have similar name |
||||||
|
""" |
||||||
|
all_var = [x.variables for x in contract.functions] |
||||||
|
all_var = [x for l in all_var for x in l] |
||||||
|
|
||||||
|
contract_var = contract.variables |
||||||
|
|
||||||
|
all_var = set(all_var + contract_var) |
||||||
|
|
||||||
|
ret = [] |
||||||
|
for v1 in all_var: |
||||||
|
for v2 in all_var: |
||||||
|
if v1.name.lower() != v2.name.lower(): |
||||||
|
if SimilarVarsDetection.similar(v1.name, v2.name): |
||||||
|
if (v2, v1) not in ret: |
||||||
|
ret.append((v1, v2)) |
||||||
|
|
||||||
|
return set(ret) |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
"""Detect similar variables name |
||||||
|
|
||||||
|
Returns: |
||||||
|
list: {'vuln', 'filename,'contract','vars'} |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
for c in self.contracts: |
||||||
|
allVars = self.detect_sim(c) |
||||||
|
if allVars: |
||||||
|
for (v1, v2) in sorted(allVars, key=lambda x: (x[0].name, x[1].name)): |
||||||
|
v_left = v1 if v1.name < v2.name else v2 |
||||||
|
v_right = v2 if v_left == v1 else v1 |
||||||
|
info = ["Variable ", v_left, " is too similar to ", v_right, "\n"] |
||||||
|
json = self.generate_result(info) |
||||||
|
results.append(json) |
||||||
|
return results |
@ -0,0 +1,99 @@ |
|||||||
|
pragma experimental ABIEncoderV2; |
||||||
|
|
||||||
|
contract A { |
||||||
|
|
||||||
|
struct S { |
||||||
|
uint i; |
||||||
|
} |
||||||
|
|
||||||
|
uint[2][3] bad_arr = [[1, 2], [3, 4], [5, 6]]; |
||||||
|
uint[3] good_arr = [1, 2, 3]; |
||||||
|
S[3] s; |
||||||
|
|
||||||
|
event event1_bad(uint[2][3] bad_arr); |
||||||
|
event event1_good(uint[3] good_arr); |
||||||
|
event event2_bad(S[3] s); |
||||||
|
|
||||||
|
function bad0_external(uint [2][3] arr1) external { |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of arrays passed to an external function is vulnerable */ |
||||||
|
function bad0() public { |
||||||
|
this.bad0_external(bad_arr); |
||||||
|
} |
||||||
|
|
||||||
|
function bad1_external (S[3] s1) external { |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of structs passed to an external function is vulnerable */ |
||||||
|
function bad1 (S[3] s1) public { |
||||||
|
this.bad1_external(s); |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of arrays passed to abi.encode is vulnerable */ |
||||||
|
function bad2() public { |
||||||
|
bytes memory b = abi.encode(bad_arr); |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of structs passed to abi.encode is vulnerable */ |
||||||
|
function bad3() public { |
||||||
|
bytes memory b = abi.encode(s); |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of arrays passed to an event emit is vulnerable */ |
||||||
|
function bad4() public { |
||||||
|
emit event1_bad(bad_arr); |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of structs passed to an event emit is vulnerable */ |
||||||
|
function bad5() public { |
||||||
|
emit event2_bad(s); |
||||||
|
} |
||||||
|
|
||||||
|
function good0_public (uint[2][3] arr1) public { |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of arrays passed to a public function is benign */ |
||||||
|
function good0() public { |
||||||
|
good0_public(bad_arr); |
||||||
|
} |
||||||
|
|
||||||
|
function good1_public (S[3] s1) public { |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of structs passed to a public function is benign */ |
||||||
|
function good1 (S[3] s1) { |
||||||
|
good1_public(s); |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of arrays in-memory passed to abi.encode is benign */ |
||||||
|
function good2() public { |
||||||
|
uint8 [2][3] memory bad_arr_mem = [[1, 2], [3, 4], [5, 6]]; |
||||||
|
bytes memory b = abi.encode(bad_arr_mem); |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of structs in-memory passed to abi.encode is benign */ |
||||||
|
function good3() public { |
||||||
|
S[3] memory s_mem; |
||||||
|
bytes memory b = abi.encode(s_mem); |
||||||
|
} |
||||||
|
|
||||||
|
function good4_external(uint[3] arr1) external { |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of elementary types passed to external function is benign */ |
||||||
|
function good4() public { |
||||||
|
this.good4_external(good_arr); |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of elementary types passed to abi.encode is benign */ |
||||||
|
function good5() public { |
||||||
|
bytes memory b = abi.encode(good_arr); |
||||||
|
} |
||||||
|
|
||||||
|
/* Array of elementary types passed to event emit is benign */ |
||||||
|
function good6() public { |
||||||
|
emit event1_good(good_arr); |
||||||
|
} |
||||||
|
|
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,51 @@ |
|||||||
|
contract C { |
||||||
|
uint[1] public x; |
||||||
|
|
||||||
|
function f() public { |
||||||
|
setByRef(x); // can set x. |
||||||
|
setByValue(x); // cannot set x. |
||||||
|
uint test = 1 + setByValueAndReturn(x); // cannot set x. |
||||||
|
} |
||||||
|
|
||||||
|
function g() public { |
||||||
|
uint[1] storage y = x; |
||||||
|
setByRef(y); // can set y. |
||||||
|
setByValue(y); // cannot set y. |
||||||
|
uint test = 1 + setByValueAndReturn(y); // cannot set y. |
||||||
|
} |
||||||
|
|
||||||
|
function setByRef(uint[1] storage arr) internal { |
||||||
|
arr[0] = 1; |
||||||
|
} |
||||||
|
|
||||||
|
function setByValue(uint[1] arr) public { |
||||||
|
arr[0] = 2; |
||||||
|
} |
||||||
|
|
||||||
|
function setByValueAndReturn(uint[1] arr) public returns(uint) { |
||||||
|
arr[0] = 2; |
||||||
|
return arr[0]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract D { |
||||||
|
// Struct definition |
||||||
|
struct TestStruct { |
||||||
|
uint[1] x; |
||||||
|
} |
||||||
|
|
||||||
|
// State Variables |
||||||
|
TestStruct ts; |
||||||
|
uint[1] x; |
||||||
|
|
||||||
|
// Functions |
||||||
|
function f() public { |
||||||
|
C c = new C(); |
||||||
|
c.setByValue(ts.x); // cannot set x. |
||||||
|
uint test = 1 + c.setByValueAndReturn(ts.x); // cannot set x. |
||||||
|
c.setByValue(x); // cannot set x. |
||||||
|
test = 1 + c.setByValueAndReturn(x); // cannot set x. |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,39 @@ |
|||||||
|
contract A { |
||||||
|
|
||||||
|
uint s_a; |
||||||
|
|
||||||
|
/* Direct state change in assert is NOT ok */ |
||||||
|
function bad0() public { |
||||||
|
assert((s_a += 1) > 10); |
||||||
|
} |
||||||
|
|
||||||
|
/* Direct state change in assert is NOT ok */ |
||||||
|
function bad1(uint256 a) public { |
||||||
|
assert((s_a += a) > 10); |
||||||
|
} |
||||||
|
|
||||||
|
/* State change via functions calls in assert is NOT ok */ |
||||||
|
function bad2_callee() public returns (bool) { |
||||||
|
return (s_a += 1) > 10; |
||||||
|
} |
||||||
|
function bad2() public { |
||||||
|
assert(bad2_callee()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* Parameter use is ok */ |
||||||
|
function good0(uint256 a) public { |
||||||
|
assert(a > 10); |
||||||
|
} |
||||||
|
|
||||||
|
/* Parameter change is ok */ |
||||||
|
function good1(uint256 a) public { |
||||||
|
assert((a += 1) > 10); |
||||||
|
} |
||||||
|
|
||||||
|
/* State change in require is ok */ |
||||||
|
function good2(uint256 a) public { |
||||||
|
require(a == (s_a += 1)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,568 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad0", |
||||||
|
"source_mapping": { |
||||||
|
"start": 77, |
||||||
|
"length": 57, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "bad0()" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "assert(bool)((s_a += 1) > 10)", |
||||||
|
"source_mapping": { |
||||||
|
"start": 106, |
||||||
|
"length": 23, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
7 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 28 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad0", |
||||||
|
"source_mapping": { |
||||||
|
"start": 77, |
||||||
|
"length": 57, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "bad0()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "A.bad0() (tests/detectors/assert-state-change/assert_state_change.sol#6-8) has an assert() call which possibly changes state.\n\t-assert(bool)((s_a += 1) > 10) (tests/detectors/assert-state-change/assert_state_change.sol#7)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"markdown": "[A.bad0()](tests/detectors/assert-state-change/assert_state_change.sol#L6-L8) has an assert() call which possibly changes state.\n\t-[assert(bool)((s_a += 1) > 10)](tests/detectors/assert-state-change/assert_state_change.sol#L7)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"id": "a4f5ea904ad28f8c83aa1bab8284b485e1fe638545b500ca0c8a0fa8e442203e", |
||||||
|
"check": "assert-state-change", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "Informational" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 186, |
||||||
|
"length": 66, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
11, |
||||||
|
12, |
||||||
|
13 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "assert(bool)((s_a += a) > 10)", |
||||||
|
"source_mapping": { |
||||||
|
"start": 224, |
||||||
|
"length": 23, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
12 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 28 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 186, |
||||||
|
"length": 66, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
11, |
||||||
|
12, |
||||||
|
13 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "A.bad1(uint256) (tests/detectors/assert-state-change/assert_state_change.sol#11-13) has an assert() call which possibly changes state.\n\t-assert(bool)((s_a += a) > 10) (tests/detectors/assert-state-change/assert_state_change.sol#12)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"markdown": "[A.bad1(uint256)](tests/detectors/assert-state-change/assert_state_change.sol#L11-L13) has an assert() call which possibly changes state.\n\t-[assert(bool)((s_a += a) > 10)](tests/detectors/assert-state-change/assert_state_change.sol#L12)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"id": "2b42e9f701ebd94656a026702bf90f31c62710a301600e0c05cfed04bfefabf9", |
||||||
|
"check": "assert-state-change", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "Informational" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad2", |
||||||
|
"source_mapping": { |
||||||
|
"start": 398, |
||||||
|
"length": 55, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
19, |
||||||
|
20, |
||||||
|
21 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "assert(bool)(bad2_callee())", |
||||||
|
"source_mapping": { |
||||||
|
"start": 427, |
||||||
|
"length": 21, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
20 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 26 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad2", |
||||||
|
"source_mapping": { |
||||||
|
"start": 398, |
||||||
|
"length": 55, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
19, |
||||||
|
20, |
||||||
|
21 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "A.bad2() (tests/detectors/assert-state-change/assert_state_change.sol#19-21) has an assert() call which possibly changes state.\n\t-assert(bool)(bad2_callee()) (tests/detectors/assert-state-change/assert_state_change.sol#20)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"markdown": "[A.bad2()](tests/detectors/assert-state-change/assert_state_change.sol#L19-L21) has an assert() call which possibly changes state.\n\t-[assert(bool)(bad2_callee())](tests/detectors/assert-state-change/assert_state_change.sol#L20)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"id": "a72f3e7eef408be55123fbf5c290bfd20aed4f095d659f5df0857d64d61df011", |
||||||
|
"check": "assert-state-change", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "Informational" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,568 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad0", |
||||||
|
"source_mapping": { |
||||||
|
"start": 77, |
||||||
|
"length": 57, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "bad0()" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "assert(bool)((s_a += 1) > 10)", |
||||||
|
"source_mapping": { |
||||||
|
"start": 106, |
||||||
|
"length": 23, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
7 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 28 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad0", |
||||||
|
"source_mapping": { |
||||||
|
"start": 77, |
||||||
|
"length": 57, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "bad0()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "A.bad0() (tests/detectors/assert-state-change/assert_state_change.sol#6-8) has an assert() call which possibly changes state.\n\t-assert(bool)((s_a += 1) > 10) (tests/detectors/assert-state-change/assert_state_change.sol#7)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"markdown": "[A.bad0()](tests/detectors/assert-state-change/assert_state_change.sol#L6-L8) has an assert() call which possibly changes state.\n\t-[assert(bool)((s_a += 1) > 10)](tests/detectors/assert-state-change/assert_state_change.sol#L7)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"id": "a4f5ea904ad28f8c83aa1bab8284b485e1fe638545b500ca0c8a0fa8e442203e", |
||||||
|
"check": "assert-state-change", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "Informational" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 186, |
||||||
|
"length": 66, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
11, |
||||||
|
12, |
||||||
|
13 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "assert(bool)((s_a += a) > 10)", |
||||||
|
"source_mapping": { |
||||||
|
"start": 224, |
||||||
|
"length": 23, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
12 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 28 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 186, |
||||||
|
"length": 66, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
11, |
||||||
|
12, |
||||||
|
13 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "A.bad1(uint256) (tests/detectors/assert-state-change/assert_state_change.sol#11-13) has an assert() call which possibly changes state.\n\t-assert(bool)((s_a += a) > 10) (tests/detectors/assert-state-change/assert_state_change.sol#12)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"markdown": "[A.bad1(uint256)](tests/detectors/assert-state-change/assert_state_change.sol#L11-L13) has an assert() call which possibly changes state.\n\t-[assert(bool)((s_a += a) > 10)](tests/detectors/assert-state-change/assert_state_change.sol#L12)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"id": "2b42e9f701ebd94656a026702bf90f31c62710a301600e0c05cfed04bfefabf9", |
||||||
|
"check": "assert-state-change", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "Informational" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad2", |
||||||
|
"source_mapping": { |
||||||
|
"start": 398, |
||||||
|
"length": 55, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
19, |
||||||
|
20, |
||||||
|
21 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "assert(bool)(bad2_callee())", |
||||||
|
"source_mapping": { |
||||||
|
"start": 427, |
||||||
|
"length": 21, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
20 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 26 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad2", |
||||||
|
"source_mapping": { |
||||||
|
"start": 398, |
||||||
|
"length": 55, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
19, |
||||||
|
20, |
||||||
|
21 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 759, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/assert-state-change/assert_state_change.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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": "A.bad2() (tests/detectors/assert-state-change/assert_state_change.sol#19-21) has an assert() call which possibly changes state.\n\t-assert(bool)(bad2_callee()) (tests/detectors/assert-state-change/assert_state_change.sol#20)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"markdown": "[A.bad2()](tests/detectors/assert-state-change/assert_state_change.sol#L19-L21) has an assert() call which possibly changes state.\n\t-[assert(bool)(bad2_callee())](tests/detectors/assert-state-change/assert_state_change.sol#L20)\nConsider using require() or change the invariant to not modify the state.\n", |
||||||
|
"id": "a72f3e7eef408be55123fbf5c290bfd20aed4f095d659f5df0857d64d61df011", |
||||||
|
"check": "assert-state-change", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "Informational" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,168 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 134, |
||||||
|
"length": 84, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/boolean-equality/boolean-equality.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/boolean-equality/boolean-equality.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
8, |
||||||
|
9, |
||||||
|
10 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "MyConc", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 573, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/boolean-equality/boolean-equality.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/boolean-equality/boolean-equality.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad1(bool)" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "(b == true)", |
||||||
|
"source_mapping": { |
||||||
|
"start": 193, |
||||||
|
"length": 18, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/boolean-equality/boolean-equality.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/boolean-equality/boolean-equality.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
9 |
||||||
|
], |
||||||
|
"starting_column": 9, |
||||||
|
"ending_column": 27 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 134, |
||||||
|
"length": 84, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/boolean-equality/boolean-equality.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/boolean-equality/boolean-equality.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
8, |
||||||
|
9, |
||||||
|
10 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "MyConc", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 573, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/boolean-equality/boolean-equality.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/boolean-equality/boolean-equality.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad1(bool)" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "MyConc.bad1(bool) (tests/detectors/boolean-equality/boolean-equality.sol#8-10) compares to a boolean constant:\n\t-(b == true) (tests/detectors/boolean-equality/boolean-equality.sol#9)\n", |
||||||
|
"markdown": "[MyConc.bad1(bool)](tests/detectors/boolean-equality/boolean-equality.sol#L8-L10) compares to a boolean constant:\n\t-[(b == true)](tests/detectors/boolean-equality/boolean-equality.sol#L9)\n", |
||||||
|
"id": "62abb2589dfdb591044c10941ebc076ca56579e64bb3076c82c3acc761805495", |
||||||
|
"check": "boolean-equal", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,46 @@ |
|||||||
|
contract ArrayLengthAssignment { |
||||||
|
uint x; |
||||||
|
uint120[] arr; |
||||||
|
uint120[] arr2; |
||||||
|
uint256[] arr3; |
||||||
|
constructor() public { |
||||||
|
x = 7; |
||||||
|
} |
||||||
|
|
||||||
|
struct TestStructWithArray { |
||||||
|
uint[] x; |
||||||
|
uint[][] y; |
||||||
|
} |
||||||
|
struct TestStructWithStructWithArray { |
||||||
|
TestStructWithArray subStruct; |
||||||
|
uint[] z; |
||||||
|
} |
||||||
|
|
||||||
|
TestStructWithArray a; |
||||||
|
TestStructWithStructWithArray b; |
||||||
|
|
||||||
|
function f(uint param, uint param2) public { |
||||||
|
x += 1; |
||||||
|
if(x > 3) { |
||||||
|
arr.length = 7; |
||||||
|
arr.length = param; |
||||||
|
} |
||||||
|
else{ |
||||||
|
// Array length that is incremented/decremented should not be found. |
||||||
|
x = arr2.length++; |
||||||
|
x = 7 + 3; |
||||||
|
} |
||||||
|
|
||||||
|
// Array length setting in structs should not be detected too. |
||||||
|
a.x.length++; |
||||||
|
a.x.length = param; |
||||||
|
|
||||||
|
|
||||||
|
// Array length setting in embedded structs should not be detected too. |
||||||
|
b.subStruct.x.length--; |
||||||
|
b.subStruct.x.length = param + 1; |
||||||
|
|
||||||
|
arr3[0] = param2; |
||||||
|
arr3.length++; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,604 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "ArrayLengthAssignment", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 1055, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45, |
||||||
|
46 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "b.subStruct.x.length = param + 1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 964, |
||||||
|
"length": 32, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
41 |
||||||
|
], |
||||||
|
"starting_column": 9, |
||||||
|
"ending_column": 41 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "f", |
||||||
|
"source_mapping": { |
||||||
|
"start": 406, |
||||||
|
"length": 647, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "ArrayLengthAssignment", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 1055, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45, |
||||||
|
46 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "f(uint256,uint256)" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "ArrayLengthAssignment (tests/detectors/controlled-array-length/array_length_assignment.sol#1-46) contract sets array length with a user-controlled value:\n\t- b.subStruct.x.length = param + 1 (tests/detectors/controlled-array-length/array_length_assignment.sol#41)\n", |
||||||
|
"markdown": "[ArrayLengthAssignment](tests/detectors/controlled-array-length/array_length_assignment.sol#L1-L46) contract sets array length with a user-controlled value:\n\t- [b.subStruct.x.length = param + 1](tests/detectors/controlled-array-length/array_length_assignment.sol#L41)\n", |
||||||
|
"id": "15164b2025ba6106829ae6e7baa9a73e931c0aa3e16a8d95ee30158667b4b7f5", |
||||||
|
"check": "controlled-array-length", |
||||||
|
"impact": "High", |
||||||
|
"confidence": "Medium" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "ArrayLengthAssignment", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 1055, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45, |
||||||
|
46 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "arr.length = param", |
||||||
|
"source_mapping": { |
||||||
|
"start": 527, |
||||||
|
"length": 18, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
26 |
||||||
|
], |
||||||
|
"starting_column": 13, |
||||||
|
"ending_column": 31 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "f", |
||||||
|
"source_mapping": { |
||||||
|
"start": 406, |
||||||
|
"length": 647, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "ArrayLengthAssignment", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 1055, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45, |
||||||
|
46 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "f(uint256,uint256)" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "ArrayLengthAssignment (tests/detectors/controlled-array-length/array_length_assignment.sol#1-46) contract sets array length with a user-controlled value:\n\t- arr.length = param (tests/detectors/controlled-array-length/array_length_assignment.sol#26)\n", |
||||||
|
"markdown": "[ArrayLengthAssignment](tests/detectors/controlled-array-length/array_length_assignment.sol#L1-L46) contract sets array length with a user-controlled value:\n\t- [arr.length = param](tests/detectors/controlled-array-length/array_length_assignment.sol#L26)\n", |
||||||
|
"id": "cb96ef1555863b421997853215ad3533faaffd35215987c6a2ebf21716d9bd1a", |
||||||
|
"check": "controlled-array-length", |
||||||
|
"impact": "High", |
||||||
|
"confidence": "Medium" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "ArrayLengthAssignment", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 1055, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45, |
||||||
|
46 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "a.x.length = param", |
||||||
|
"source_mapping": { |
||||||
|
"start": 818, |
||||||
|
"length": 18, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
36 |
||||||
|
], |
||||||
|
"starting_column": 9, |
||||||
|
"ending_column": 27 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "f", |
||||||
|
"source_mapping": { |
||||||
|
"start": 406, |
||||||
|
"length": 647, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "ArrayLengthAssignment", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 1055, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/controlled-array-length/array_length_assignment.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45, |
||||||
|
46 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "f(uint256,uint256)" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "ArrayLengthAssignment (tests/detectors/controlled-array-length/array_length_assignment.sol#1-46) contract sets array length with a user-controlled value:\n\t- a.x.length = param (tests/detectors/controlled-array-length/array_length_assignment.sol#36)\n", |
||||||
|
"markdown": "[ArrayLengthAssignment](tests/detectors/controlled-array-length/array_length_assignment.sol#L1-L46) contract sets array length with a user-controlled value:\n\t- [a.x.length = param](tests/detectors/controlled-array-length/array_length_assignment.sol#L36)\n", |
||||||
|
"id": "6a72386e40ef24dd02adf92179022559e26da5e66be4bb925d02756f90f38953", |
||||||
|
"check": "controlled-array-length", |
||||||
|
"impact": "High", |
||||||
|
"confidence": "Medium" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,35 @@ |
|||||||
|
pragma solidity ^0.4.24; |
||||||
|
|
||||||
|
contract CostlyOperationsInLoop{ |
||||||
|
|
||||||
|
uint loop_count = 100; |
||||||
|
uint state_variable=0; |
||||||
|
mapping (uint=>uint) map; |
||||||
|
uint[100] arr; |
||||||
|
|
||||||
|
function bad() external{ |
||||||
|
for (uint i=0; i < loop_count; i++){ |
||||||
|
state_variable++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function ignore_for_now1() external { |
||||||
|
for (uint i=0; i < 100; i++){ |
||||||
|
map[i] = i+1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function ignore_for_now2() external { |
||||||
|
for (uint i=0; i < 100; i++){ |
||||||
|
arr[i] = i+1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function good() external{ |
||||||
|
uint local_variable = state_variable; |
||||||
|
for (uint i=0; i < loop_count; i++){ |
||||||
|
local_variable++; |
||||||
|
} |
||||||
|
state_variable = local_variable; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,184 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad", |
||||||
|
"source_mapping": { |
||||||
|
"start": 252, |
||||||
|
"length": 373, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "CostlyOperationsInLoop", |
||||||
|
"source_mapping": { |
||||||
|
"start": 26, |
||||||
|
"length": 1081, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad()" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "state_variable ++", |
||||||
|
"source_mapping": { |
||||||
|
"start": 410, |
||||||
|
"length": 16, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
12 |
||||||
|
], |
||||||
|
"starting_column": 7, |
||||||
|
"ending_column": 23 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad", |
||||||
|
"source_mapping": { |
||||||
|
"start": 252, |
||||||
|
"length": 373, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "CostlyOperationsInLoop", |
||||||
|
"source_mapping": { |
||||||
|
"start": 26, |
||||||
|
"length": 1081, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "CostlyOperationsInLoop.bad() (tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol#10-14) has costly operations inside a loop:\n\t- state_variable ++ (tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol#12)\n", |
||||||
|
"markdown": "[CostlyOperationsInLoop.bad()](tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol#L10-L14) has costly operations inside a loop:\n\t- [state_variable ++](tests/detectors/costly-loop/multiple_costly_operations_in_loop.sol#L12)\n", |
||||||
|
"id": "245dbe07302f785326efd84e8b711d1691f045726e1098601f7e1058f1e72b2a", |
||||||
|
"check": "costly-loop", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "Medium" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,46 @@ |
|||||||
|
// This tests the detection of initializing a state variable using a non-constant function call or state variable. |
||||||
|
|
||||||
|
contract StateVarInitFromFunction { |
||||||
|
|
||||||
|
uint public v = set(); // should be flagged, initialized from function (sets to 77) |
||||||
|
uint public w = 5; |
||||||
|
uint public x = set(); // should be flagged, initialized from function (sets to 88) |
||||||
|
|
||||||
|
uint public y1 = 5 + get(); // should be flagged, initialized from function (in expression) |
||||||
|
uint public y2 = (10 + (5 + get())); // should be flagged, initialized from function (in expression) |
||||||
|
|
||||||
|
uint public z1 = 5 + getPure(); // should not be flagged, is a pure function |
||||||
|
uint public z2 = (10 + (5 + getPure())); // should not be flagged, is a pure function |
||||||
|
|
||||||
|
uint constant public c1 = 40; |
||||||
|
uint public z3 = c1 + 5; // should not be flagged, references a constant |
||||||
|
uint public z4 = z3 + 5; // should be flagged, uses a non-constant state variable. |
||||||
|
|
||||||
|
address public shouldntBeReported = address(8); // should not be flagged, not a *real* function call. |
||||||
|
uint public constructorV; |
||||||
|
uint public constructorX; |
||||||
|
|
||||||
|
constructor(){ |
||||||
|
// By the time this code is hit, all state variable initialization has completed. |
||||||
|
constructorV = v; |
||||||
|
constructorX = x; |
||||||
|
} |
||||||
|
|
||||||
|
function set() public returns(uint) { |
||||||
|
// If this function is being used to initialize a state variable before w, w will be zero. |
||||||
|
// If it is declared after w, w will be set. |
||||||
|
if(w == 0) { |
||||||
|
return 77; |
||||||
|
} |
||||||
|
|
||||||
|
return 88; |
||||||
|
} |
||||||
|
|
||||||
|
function get() public returns(uint) { |
||||||
|
return 55; |
||||||
|
} |
||||||
|
|
||||||
|
function getPure() public pure returns(uint) { |
||||||
|
return 55; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,464 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "variable", |
||||||
|
"name": "v", |
||||||
|
"source_mapping": { |
||||||
|
"start": 157, |
||||||
|
"length": 21, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
5 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 26 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "StateVarInitFromFunction", |
||||||
|
"source_mapping": { |
||||||
|
"start": 116, |
||||||
|
"length": 1567, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45, |
||||||
|
46, |
||||||
|
47 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "StateVarInitFromFunction.v (tests/detectors/function-init-state/function_init_state_variables.sol#5) is set pre-construction with a non-constant function or state variable:\n\t- set()\n", |
||||||
|
"markdown": "[StateVarInitFromFunction.v](tests/detectors/function-init-state/function_init_state_variables.sol#L5) is set pre-construction with a non-constant function or state variable:\n\t- set()\n", |
||||||
|
"id": "4b87ea4c0a3b72be79ffde12c56c9dc7440445b79ff4b228e0937b3a05540e4b", |
||||||
|
"check": "function-init-state", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "variable", |
||||||
|
"name": "x", |
||||||
|
"source_mapping": { |
||||||
|
"start": 268, |
||||||
|
"length": 21, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
7 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 26 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "StateVarInitFromFunction", |
||||||
|
"source_mapping": { |
||||||
|
"start": 116, |
||||||
|
"length": 1567, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45, |
||||||
|
46, |
||||||
|
47 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "StateVarInitFromFunction.x (tests/detectors/function-init-state/function_init_state_variables.sol#7) is set pre-construction with a non-constant function or state variable:\n\t- set()\n", |
||||||
|
"markdown": "[StateVarInitFromFunction.x](tests/detectors/function-init-state/function_init_state_variables.sol#L7) is set pre-construction with a non-constant function or state variable:\n\t- set()\n", |
||||||
|
"id": "adfa394934c8669a556cfa10c364fe526dd1e295a63959e1e88fe84a919ef354", |
||||||
|
"check": "function-init-state", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "variable", |
||||||
|
"name": "y1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 357, |
||||||
|
"length": 26, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
9 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 31 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "StateVarInitFromFunction", |
||||||
|
"source_mapping": { |
||||||
|
"start": 116, |
||||||
|
"length": 1567, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45, |
||||||
|
46, |
||||||
|
47 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "StateVarInitFromFunction.y1 (tests/detectors/function-init-state/function_init_state_variables.sol#9) is set pre-construction with a non-constant function or state variable:\n\t- 5 + get()\n", |
||||||
|
"markdown": "[StateVarInitFromFunction.y1](tests/detectors/function-init-state/function_init_state_variables.sol#L9) is set pre-construction with a non-constant function or state variable:\n\t- 5 + get()\n", |
||||||
|
"id": "b26f83c06e9aca87637dea02a0f4080fd4226c1ed90c6c2c63da85cb142d67ab", |
||||||
|
"check": "function-init-state", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "variable", |
||||||
|
"name": "y2", |
||||||
|
"source_mapping": { |
||||||
|
"start": 453, |
||||||
|
"length": 35, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
10 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 40 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "StateVarInitFromFunction", |
||||||
|
"source_mapping": { |
||||||
|
"start": 116, |
||||||
|
"length": 1567, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45, |
||||||
|
46, |
||||||
|
47 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "StateVarInitFromFunction.y2 (tests/detectors/function-init-state/function_init_state_variables.sol#10) is set pre-construction with a non-constant function or state variable:\n\t- (10 + (5 + get()))\n", |
||||||
|
"markdown": "[StateVarInitFromFunction.y2](tests/detectors/function-init-state/function_init_state_variables.sol#L10) is set pre-construction with a non-constant function or state variable:\n\t- (10 + (5 + get()))\n", |
||||||
|
"id": "b6e231b9b735794e00b73dddb86b2ba8f7a738d916c99f302fb32b1095c67472", |
||||||
|
"check": "function-init-state", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "variable", |
||||||
|
"name": "z4", |
||||||
|
"source_mapping": { |
||||||
|
"start": 842, |
||||||
|
"length": 23, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
17 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 28 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "StateVarInitFromFunction", |
||||||
|
"source_mapping": { |
||||||
|
"start": 116, |
||||||
|
"length": 1567, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/function-init-state/function_init_state_variables.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45, |
||||||
|
46, |
||||||
|
47 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "StateVarInitFromFunction.z4 (tests/detectors/function-init-state/function_init_state_variables.sol#17) is set pre-construction with a non-constant function or state variable:\n\t- z3 + 5\n", |
||||||
|
"markdown": "[StateVarInitFromFunction.z4](tests/detectors/function-init-state/function_init_state_variables.sol#L17) is set pre-construction with a non-constant function or state variable:\n\t- z3 + 5\n", |
||||||
|
"id": "8b7eb9ab16397c2f23479d2c3043a675ab5e2b1da07e2697631812d6d7b68525", |
||||||
|
"check": "function-init-state", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,43 @@ |
|||||||
|
pragma solidity ^0.4.24; |
||||||
|
|
||||||
|
library Lib{ |
||||||
|
|
||||||
|
struct MyStruct{ |
||||||
|
mapping(address => uint) maps; |
||||||
|
} |
||||||
|
|
||||||
|
function deleteSt(MyStruct[1] storage st){ |
||||||
|
delete st[0]; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
contract Balances { |
||||||
|
|
||||||
|
struct BalancesStruct{ |
||||||
|
address owner; |
||||||
|
mapping(address => uint) balances; |
||||||
|
} |
||||||
|
|
||||||
|
mapping(uint => BalancesStruct) public stackBalance; |
||||||
|
function createBalance(uint idx) public { |
||||||
|
require(stackBalance[idx].owner == 0); |
||||||
|
stackBalance[idx] = BalancesStruct(msg.sender); |
||||||
|
} |
||||||
|
|
||||||
|
function deleteBalance(uint idx) public { |
||||||
|
require(stackBalance[idx].owner == msg.sender); |
||||||
|
delete stackBalance[idx]; |
||||||
|
} |
||||||
|
|
||||||
|
function setBalance(uint idx, address addr, uint val) public { |
||||||
|
require(stackBalance[idx].owner == msg.sender); |
||||||
|
|
||||||
|
stackBalance[idx].balances[addr] = val; |
||||||
|
} |
||||||
|
|
||||||
|
function getBalance(uint idx, address addr) public view returns(uint){ |
||||||
|
return stackBalance[idx].balances[addr]; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,425 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "deleteSt", |
||||||
|
"source_mapping": { |
||||||
|
"start": 111, |
||||||
|
"length": 70, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
9, |
||||||
|
10, |
||||||
|
11 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Lib", |
||||||
|
"source_mapping": { |
||||||
|
"start": 26, |
||||||
|
"length": 158, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "deleteSt(Lib.MyStruct[1])" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "struct", |
||||||
|
"name": "MyStruct", |
||||||
|
"source_mapping": { |
||||||
|
"start": 44, |
||||||
|
"length": 61, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
5, |
||||||
|
6, |
||||||
|
7 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Lib", |
||||||
|
"source_mapping": { |
||||||
|
"start": 26, |
||||||
|
"length": 158, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "delete st[0]", |
||||||
|
"source_mapping": { |
||||||
|
"start": 162, |
||||||
|
"length": 12, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
10 |
||||||
|
], |
||||||
|
"starting_column": 9, |
||||||
|
"ending_column": 21 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "deleteSt", |
||||||
|
"source_mapping": { |
||||||
|
"start": 111, |
||||||
|
"length": 70, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
9, |
||||||
|
10, |
||||||
|
11 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Lib", |
||||||
|
"source_mapping": { |
||||||
|
"start": 26, |
||||||
|
"length": 158, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "deleteSt(Lib.MyStruct[1])" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Lib.deleteSt(Lib.MyStruct[1]) (tests/detectors/mapping-deletion/MappingDeletion.sol#9-11) deletes Lib.MyStruct (tests/detectors/mapping-deletion/MappingDeletion.sol#5-7) which contains a mapping:\n\t-delete st[0] (tests/detectors/mapping-deletion/MappingDeletion.sol#10)\n", |
||||||
|
"markdown": "[Lib.deleteSt(Lib.MyStruct[1])](tests/detectors/mapping-deletion/MappingDeletion.sol#L9-L11) deletes [Lib.MyStruct](tests/detectors/mapping-deletion/MappingDeletion.sol#L5-L7) which contains a mapping:\n\t-[delete st[0]](tests/detectors/mapping-deletion/MappingDeletion.sol#L10)\n", |
||||||
|
"id": "d618551637c257938461c33070c5339207b75de2bb11ff88d92bd9679252f307", |
||||||
|
"check": "mapping-deletion", |
||||||
|
"impact": "Medium", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "deleteBalance", |
||||||
|
"source_mapping": { |
||||||
|
"start": 541, |
||||||
|
"length": 137, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Balances", |
||||||
|
"source_mapping": { |
||||||
|
"start": 186, |
||||||
|
"length": 825, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "deleteBalance(uint256)" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "struct", |
||||||
|
"name": "BalancesStruct", |
||||||
|
"source_mapping": { |
||||||
|
"start": 215, |
||||||
|
"length": 94, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Balances", |
||||||
|
"source_mapping": { |
||||||
|
"start": 186, |
||||||
|
"length": 825, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "delete stackBalance[idx]", |
||||||
|
"source_mapping": { |
||||||
|
"start": 647, |
||||||
|
"length": 24, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
30 |
||||||
|
], |
||||||
|
"starting_column": 9, |
||||||
|
"ending_column": 33 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "deleteBalance", |
||||||
|
"source_mapping": { |
||||||
|
"start": 541, |
||||||
|
"length": 137, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Balances", |
||||||
|
"source_mapping": { |
||||||
|
"start": 186, |
||||||
|
"length": 825, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/mapping-deletion/MappingDeletion.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "deleteBalance(uint256)" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Balances.deleteBalance(uint256) (tests/detectors/mapping-deletion/MappingDeletion.sol#28-31) deletes Balances.BalancesStruct (tests/detectors/mapping-deletion/MappingDeletion.sol#17-20) which contains a mapping:\n\t-delete stackBalance[idx] (tests/detectors/mapping-deletion/MappingDeletion.sol#30)\n", |
||||||
|
"markdown": "[Balances.deleteBalance(uint256)](tests/detectors/mapping-deletion/MappingDeletion.sol#L28-L31) deletes [Balances.BalancesStruct](tests/detectors/mapping-deletion/MappingDeletion.sol#L17-L20) which contains a mapping:\n\t-[delete stackBalance[idx]](tests/detectors/mapping-deletion/MappingDeletion.sol#L30)\n", |
||||||
|
"id": "a1e8bc34ec8ef7969409701b3c851749c4ba00dcbbef2cabcdf7e3f49724034e", |
||||||
|
"check": "mapping-deletion", |
||||||
|
"impact": "Medium", |
||||||
|
"confidence": "High" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,72 @@ |
|||||||
|
/* Interfaces */ |
||||||
|
interface ISomething0 { |
||||||
|
function sth1(uint256) external; |
||||||
|
} |
||||||
|
|
||||||
|
interface ISomething1 { |
||||||
|
function sth1(uint256) external; |
||||||
|
function sth2(bytes calldata) external; |
||||||
|
} |
||||||
|
|
||||||
|
interface ISomething2 { |
||||||
|
function sth(uint256) external; |
||||||
|
} |
||||||
|
|
||||||
|
interface ISomething3 { |
||||||
|
function sth1(uint256) external; |
||||||
|
function sth2(bool) external; |
||||||
|
} |
||||||
|
|
||||||
|
interface ISomething4 { |
||||||
|
function sth1(uint256) external; |
||||||
|
function sth2(bool) external; |
||||||
|
function sth3(bytes calldata) external; |
||||||
|
} |
||||||
|
|
||||||
|
interface ISomething5 { |
||||||
|
function sth(uint256) external; |
||||||
|
function sth1(uint256) external; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Contracts */ |
||||||
|
|
||||||
|
contract bad0 { // forgets to say it is ISomething1 |
||||||
|
function sth1(uint256 x) external {} |
||||||
|
function sth2(bytes calldata y) external {} |
||||||
|
} |
||||||
|
|
||||||
|
contract bad1 { // forgets to say it is ISomething4 |
||||||
|
function sth1(uint256 x) external {} |
||||||
|
function sth2(bool b) external {} |
||||||
|
function sth3(bytes calldata y) external {} |
||||||
|
} |
||||||
|
|
||||||
|
contract bad2 is ISomething3 { // forgets to say it is ISomething4 which is a superset of ISomething3 |
||||||
|
function sth1(uint256 x) external {} |
||||||
|
function sth2(bool b) external {} |
||||||
|
function sth3(bytes calldata y) external {} |
||||||
|
} |
||||||
|
|
||||||
|
contract good0 is ISomething2 { |
||||||
|
function sth(uint256 x) external {} |
||||||
|
} |
||||||
|
|
||||||
|
/* Implements ISomething5 which is a superset of ISomething0 and ISomething2 */ |
||||||
|
contract good1 is ISomething5 { |
||||||
|
function sth(uint256 x) external {} |
||||||
|
function sth1(uint256 x) external {} |
||||||
|
} |
||||||
|
|
||||||
|
/* good2_i is not an Interface because sth5 is not external */ |
||||||
|
contract bad3_i { |
||||||
|
function sth4(uint256 x) external; |
||||||
|
function sth5(uint256 x) public; |
||||||
|
} |
||||||
|
|
||||||
|
contract bad3 { |
||||||
|
function sth4(uint256 x) external {} |
||||||
|
function sth5(uint256 x) public {} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,3 @@ |
|||||||
|
[ |
||||||
|
[] |
||||||
|
] |
@ -0,0 +1,785 @@ |
|||||||
|
JSON AST (compact format): |
||||||
|
|
||||||
|
|
||||||
|
======= multiple-constructors.sol ======= |
||||||
|
{ |
||||||
|
"absolutePath" : "multiple-constructors.sol", |
||||||
|
"exportedSymbols" : |
||||||
|
{ |
||||||
|
"A" : |
||||||
|
[ |
||||||
|
54 |
||||||
|
] |
||||||
|
}, |
||||||
|
"id" : 55, |
||||||
|
"nodeType" : "SourceUnit", |
||||||
|
"nodes" : |
||||||
|
[ |
||||||
|
{ |
||||||
|
"id" : 1, |
||||||
|
"literals" : |
||||||
|
[ |
||||||
|
"solidity", |
||||||
|
"0.4", |
||||||
|
".22" |
||||||
|
], |
||||||
|
"nodeType" : "PragmaDirective", |
||||||
|
"src" : "0:23:0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"baseContracts" : [], |
||||||
|
"contractDependencies" : [], |
||||||
|
"contractKind" : "contract", |
||||||
|
"documentation" : null, |
||||||
|
"fullyImplemented" : true, |
||||||
|
"id" : 54, |
||||||
|
"linearizedBaseContracts" : |
||||||
|
[ |
||||||
|
54 |
||||||
|
], |
||||||
|
"name" : "A", |
||||||
|
"nodeType" : "ContractDefinition", |
||||||
|
"nodes" : |
||||||
|
[ |
||||||
|
{ |
||||||
|
"constant" : false, |
||||||
|
"id" : 5, |
||||||
|
"name" : "x", |
||||||
|
"nodeType" : "VariableDeclaration", |
||||||
|
"scope" : 54, |
||||||
|
"src" : "41:9:0", |
||||||
|
"stateVariable" : true, |
||||||
|
"storageLocation" : "default", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_array$_t_uint256_$2_storage", |
||||||
|
"typeString" : "uint256[2]" |
||||||
|
}, |
||||||
|
"typeName" : |
||||||
|
{ |
||||||
|
"baseType" : |
||||||
|
{ |
||||||
|
"id" : 2, |
||||||
|
"name" : "uint", |
||||||
|
"nodeType" : "ElementaryTypeName", |
||||||
|
"src" : "41:4:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
"id" : 4, |
||||||
|
"length" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"hexValue" : "32", |
||||||
|
"id" : 3, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : false, |
||||||
|
"kind" : "number", |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "Literal", |
||||||
|
"src" : "46:1:0", |
||||||
|
"subdenomination" : null, |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : null, |
||||||
|
"typeString" : null |
||||||
|
}, |
||||||
|
"value" : "2" |
||||||
|
}, |
||||||
|
"nodeType" : "ArrayTypeName", |
||||||
|
"src" : "41:7:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_array$_t_uint256_$2_storage_ptr", |
||||||
|
"typeString" : "uint256[2]" |
||||||
|
} |
||||||
|
}, |
||||||
|
"value" : null, |
||||||
|
"visibility" : "internal" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"body" : |
||||||
|
{ |
||||||
|
"id" : 20, |
||||||
|
"nodeType" : "Block", |
||||||
|
"src" : "76:45:0", |
||||||
|
"statements" : |
||||||
|
[ |
||||||
|
{ |
||||||
|
"expression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"id" : 12, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : false, |
||||||
|
"lValueRequested" : false, |
||||||
|
"leftHandSide" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"baseExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"id" : 8, |
||||||
|
"name" : "x", |
||||||
|
"nodeType" : "Identifier", |
||||||
|
"overloadedDeclarations" : [], |
||||||
|
"referencedDeclaration" : 5, |
||||||
|
"src" : "86:1:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_array$_t_uint256_$2_storage", |
||||||
|
"typeString" : "uint256[2] storage ref" |
||||||
|
} |
||||||
|
}, |
||||||
|
"id" : 10, |
||||||
|
"indexExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"hexValue" : "30", |
||||||
|
"id" : 9, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : true, |
||||||
|
"kind" : "number", |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "Literal", |
||||||
|
"src" : "88:1:0", |
||||||
|
"subdenomination" : null, |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_rational_0_by_1", |
||||||
|
"typeString" : "int_const 0" |
||||||
|
}, |
||||||
|
"value" : "0" |
||||||
|
}, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : true, |
||||||
|
"isPure" : false, |
||||||
|
"lValueRequested" : true, |
||||||
|
"nodeType" : "IndexAccess", |
||||||
|
"src" : "86:4:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
"nodeType" : "Assignment", |
||||||
|
"operator" : "=", |
||||||
|
"rightHandSide" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"hexValue" : "3838", |
||||||
|
"id" : 11, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : true, |
||||||
|
"kind" : "number", |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "Literal", |
||||||
|
"src" : "93:2:0", |
||||||
|
"subdenomination" : null, |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_rational_88_by_1", |
||||||
|
"typeString" : "int_const 88" |
||||||
|
}, |
||||||
|
"value" : "88" |
||||||
|
}, |
||||||
|
"src" : "86:9:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
"id" : 13, |
||||||
|
"nodeType" : "ExpressionStatement", |
||||||
|
"src" : "86:9:0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"id" : 18, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : false, |
||||||
|
"lValueRequested" : false, |
||||||
|
"leftHandSide" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"baseExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"id" : 14, |
||||||
|
"name" : "x", |
||||||
|
"nodeType" : "Identifier", |
||||||
|
"overloadedDeclarations" : [], |
||||||
|
"referencedDeclaration" : 5, |
||||||
|
"src" : "105:1:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_array$_t_uint256_$2_storage", |
||||||
|
"typeString" : "uint256[2] storage ref" |
||||||
|
} |
||||||
|
}, |
||||||
|
"id" : 16, |
||||||
|
"indexExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"hexValue" : "31", |
||||||
|
"id" : 15, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : true, |
||||||
|
"kind" : "number", |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "Literal", |
||||||
|
"src" : "107:1:0", |
||||||
|
"subdenomination" : null, |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_rational_1_by_1", |
||||||
|
"typeString" : "int_const 1" |
||||||
|
}, |
||||||
|
"value" : "1" |
||||||
|
}, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : true, |
||||||
|
"isPure" : false, |
||||||
|
"lValueRequested" : true, |
||||||
|
"nodeType" : "IndexAccess", |
||||||
|
"src" : "105:4:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
"nodeType" : "Assignment", |
||||||
|
"operator" : "=", |
||||||
|
"rightHandSide" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"hexValue" : "3939", |
||||||
|
"id" : 17, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : true, |
||||||
|
"kind" : "number", |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "Literal", |
||||||
|
"src" : "112:2:0", |
||||||
|
"subdenomination" : null, |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_rational_99_by_1", |
||||||
|
"typeString" : "int_const 99" |
||||||
|
}, |
||||||
|
"value" : "99" |
||||||
|
}, |
||||||
|
"src" : "105:9:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
"id" : 19, |
||||||
|
"nodeType" : "ExpressionStatement", |
||||||
|
"src" : "105:9:0" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"documentation" : null, |
||||||
|
"id" : 21, |
||||||
|
"implemented" : true, |
||||||
|
"isConstructor" : true, |
||||||
|
"isDeclaredConst" : false, |
||||||
|
"modifiers" : [], |
||||||
|
"name" : "A", |
||||||
|
"nodeType" : "FunctionDefinition", |
||||||
|
"parameters" : |
||||||
|
{ |
||||||
|
"id" : 6, |
||||||
|
"nodeType" : "ParameterList", |
||||||
|
"parameters" : [], |
||||||
|
"src" : "66:2:0" |
||||||
|
}, |
||||||
|
"payable" : false, |
||||||
|
"returnParameters" : |
||||||
|
{ |
||||||
|
"id" : 7, |
||||||
|
"nodeType" : "ParameterList", |
||||||
|
"parameters" : [], |
||||||
|
"src" : "76:0:0" |
||||||
|
}, |
||||||
|
"scope" : 54, |
||||||
|
"src" : "56:65:0", |
||||||
|
"stateMutability" : "nonpayable", |
||||||
|
"superFunction" : null, |
||||||
|
"visibility" : "public" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"body" : |
||||||
|
{ |
||||||
|
"id" : 36, |
||||||
|
"nodeType" : "Block", |
||||||
|
"src" : "147:45:0", |
||||||
|
"statements" : |
||||||
|
[ |
||||||
|
{ |
||||||
|
"expression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"id" : 28, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : false, |
||||||
|
"lValueRequested" : false, |
||||||
|
"leftHandSide" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"baseExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"id" : 24, |
||||||
|
"name" : "x", |
||||||
|
"nodeType" : "Identifier", |
||||||
|
"overloadedDeclarations" : [], |
||||||
|
"referencedDeclaration" : 5, |
||||||
|
"src" : "157:1:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_array$_t_uint256_$2_storage", |
||||||
|
"typeString" : "uint256[2] storage ref" |
||||||
|
} |
||||||
|
}, |
||||||
|
"id" : 26, |
||||||
|
"indexExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"hexValue" : "30", |
||||||
|
"id" : 25, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : true, |
||||||
|
"kind" : "number", |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "Literal", |
||||||
|
"src" : "159:1:0", |
||||||
|
"subdenomination" : null, |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_rational_0_by_1", |
||||||
|
"typeString" : "int_const 0" |
||||||
|
}, |
||||||
|
"value" : "0" |
||||||
|
}, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : true, |
||||||
|
"isPure" : false, |
||||||
|
"lValueRequested" : true, |
||||||
|
"nodeType" : "IndexAccess", |
||||||
|
"src" : "157:4:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
"nodeType" : "Assignment", |
||||||
|
"operator" : "=", |
||||||
|
"rightHandSide" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"hexValue" : "3636", |
||||||
|
"id" : 27, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : true, |
||||||
|
"kind" : "number", |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "Literal", |
||||||
|
"src" : "164:2:0", |
||||||
|
"subdenomination" : null, |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_rational_66_by_1", |
||||||
|
"typeString" : "int_const 66" |
||||||
|
}, |
||||||
|
"value" : "66" |
||||||
|
}, |
||||||
|
"src" : "157:9:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
"id" : 29, |
||||||
|
"nodeType" : "ExpressionStatement", |
||||||
|
"src" : "157:9:0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"id" : 34, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : false, |
||||||
|
"lValueRequested" : false, |
||||||
|
"leftHandSide" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"baseExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"id" : 30, |
||||||
|
"name" : "x", |
||||||
|
"nodeType" : "Identifier", |
||||||
|
"overloadedDeclarations" : [], |
||||||
|
"referencedDeclaration" : 5, |
||||||
|
"src" : "176:1:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_array$_t_uint256_$2_storage", |
||||||
|
"typeString" : "uint256[2] storage ref" |
||||||
|
} |
||||||
|
}, |
||||||
|
"id" : 32, |
||||||
|
"indexExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"hexValue" : "31", |
||||||
|
"id" : 31, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : true, |
||||||
|
"kind" : "number", |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "Literal", |
||||||
|
"src" : "178:1:0", |
||||||
|
"subdenomination" : null, |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_rational_1_by_1", |
||||||
|
"typeString" : "int_const 1" |
||||||
|
}, |
||||||
|
"value" : "1" |
||||||
|
}, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : true, |
||||||
|
"isPure" : false, |
||||||
|
"lValueRequested" : true, |
||||||
|
"nodeType" : "IndexAccess", |
||||||
|
"src" : "176:4:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
"nodeType" : "Assignment", |
||||||
|
"operator" : "=", |
||||||
|
"rightHandSide" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"hexValue" : "3737", |
||||||
|
"id" : 33, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : true, |
||||||
|
"kind" : "number", |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "Literal", |
||||||
|
"src" : "183:2:0", |
||||||
|
"subdenomination" : null, |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_rational_77_by_1", |
||||||
|
"typeString" : "int_const 77" |
||||||
|
}, |
||||||
|
"value" : "77" |
||||||
|
}, |
||||||
|
"src" : "176:9:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
"id" : 35, |
||||||
|
"nodeType" : "ExpressionStatement", |
||||||
|
"src" : "176:9:0" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"documentation" : null, |
||||||
|
"id" : 37, |
||||||
|
"implemented" : true, |
||||||
|
"isConstructor" : true, |
||||||
|
"isDeclaredConst" : false, |
||||||
|
"modifiers" : [], |
||||||
|
"name" : "", |
||||||
|
"nodeType" : "FunctionDefinition", |
||||||
|
"parameters" : |
||||||
|
{ |
||||||
|
"id" : 22, |
||||||
|
"nodeType" : "ParameterList", |
||||||
|
"parameters" : [], |
||||||
|
"src" : "137:2:0" |
||||||
|
}, |
||||||
|
"payable" : false, |
||||||
|
"returnParameters" : |
||||||
|
{ |
||||||
|
"id" : 23, |
||||||
|
"nodeType" : "ParameterList", |
||||||
|
"parameters" : [], |
||||||
|
"src" : "147:0:0" |
||||||
|
}, |
||||||
|
"scope" : 54, |
||||||
|
"src" : "126:66:0", |
||||||
|
"stateMutability" : "nonpayable", |
||||||
|
"superFunction" : null, |
||||||
|
"visibility" : "public" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"body" : |
||||||
|
{ |
||||||
|
"id" : 52, |
||||||
|
"nodeType" : "Block", |
||||||
|
"src" : "241:36:0", |
||||||
|
"statements" : |
||||||
|
[ |
||||||
|
{ |
||||||
|
"expression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"components" : |
||||||
|
[ |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"baseExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"id" : 44, |
||||||
|
"name" : "x", |
||||||
|
"nodeType" : "Identifier", |
||||||
|
"overloadedDeclarations" : [], |
||||||
|
"referencedDeclaration" : 5, |
||||||
|
"src" : "259:1:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_array$_t_uint256_$2_storage", |
||||||
|
"typeString" : "uint256[2] storage ref" |
||||||
|
} |
||||||
|
}, |
||||||
|
"id" : 46, |
||||||
|
"indexExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"hexValue" : "30", |
||||||
|
"id" : 45, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : true, |
||||||
|
"kind" : "number", |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "Literal", |
||||||
|
"src" : "261:1:0", |
||||||
|
"subdenomination" : null, |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_rational_0_by_1", |
||||||
|
"typeString" : "int_const 0" |
||||||
|
}, |
||||||
|
"value" : "0" |
||||||
|
}, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : true, |
||||||
|
"isPure" : false, |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "IndexAccess", |
||||||
|
"src" : "259:4:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"baseExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"id" : 47, |
||||||
|
"name" : "x", |
||||||
|
"nodeType" : "Identifier", |
||||||
|
"overloadedDeclarations" : [], |
||||||
|
"referencedDeclaration" : 5, |
||||||
|
"src" : "265:1:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_array$_t_uint256_$2_storage", |
||||||
|
"typeString" : "uint256[2] storage ref" |
||||||
|
} |
||||||
|
}, |
||||||
|
"id" : 49, |
||||||
|
"indexExpression" : |
||||||
|
{ |
||||||
|
"argumentTypes" : null, |
||||||
|
"hexValue" : "31", |
||||||
|
"id" : 48, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : true, |
||||||
|
"kind" : "number", |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "Literal", |
||||||
|
"src" : "267:1:0", |
||||||
|
"subdenomination" : null, |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_rational_1_by_1", |
||||||
|
"typeString" : "int_const 1" |
||||||
|
}, |
||||||
|
"value" : "1" |
||||||
|
}, |
||||||
|
"isConstant" : false, |
||||||
|
"isLValue" : true, |
||||||
|
"isPure" : false, |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "IndexAccess", |
||||||
|
"src" : "265:4:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"id" : 50, |
||||||
|
"isConstant" : false, |
||||||
|
"isInlineArray" : false, |
||||||
|
"isLValue" : false, |
||||||
|
"isPure" : false, |
||||||
|
"lValueRequested" : false, |
||||||
|
"nodeType" : "TupleExpression", |
||||||
|
"src" : "258:12:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_tuple$_t_uint256_$_t_uint256_$", |
||||||
|
"typeString" : "tuple(uint256,uint256)" |
||||||
|
} |
||||||
|
}, |
||||||
|
"functionReturnParameters" : 43, |
||||||
|
"id" : 51, |
||||||
|
"nodeType" : "Return", |
||||||
|
"src" : "251:19:0" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"documentation" : null, |
||||||
|
"id" : 53, |
||||||
|
"implemented" : true, |
||||||
|
"isConstructor" : false, |
||||||
|
"isDeclaredConst" : false, |
||||||
|
"modifiers" : [], |
||||||
|
"name" : "test", |
||||||
|
"nodeType" : "FunctionDefinition", |
||||||
|
"parameters" : |
||||||
|
{ |
||||||
|
"id" : 38, |
||||||
|
"nodeType" : "ParameterList", |
||||||
|
"parameters" : [], |
||||||
|
"src" : "211:2:0" |
||||||
|
}, |
||||||
|
"payable" : false, |
||||||
|
"returnParameters" : |
||||||
|
{ |
||||||
|
"id" : 43, |
||||||
|
"nodeType" : "ParameterList", |
||||||
|
"parameters" : |
||||||
|
[ |
||||||
|
{ |
||||||
|
"constant" : false, |
||||||
|
"id" : 40, |
||||||
|
"name" : "", |
||||||
|
"nodeType" : "VariableDeclaration", |
||||||
|
"scope" : 53, |
||||||
|
"src" : "229:4:0", |
||||||
|
"stateVariable" : false, |
||||||
|
"storageLocation" : "default", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
}, |
||||||
|
"typeName" : |
||||||
|
{ |
||||||
|
"id" : 39, |
||||||
|
"name" : "uint", |
||||||
|
"nodeType" : "ElementaryTypeName", |
||||||
|
"src" : "229:4:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
"value" : null, |
||||||
|
"visibility" : "internal" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"constant" : false, |
||||||
|
"id" : 42, |
||||||
|
"name" : "", |
||||||
|
"nodeType" : "VariableDeclaration", |
||||||
|
"scope" : 53, |
||||||
|
"src" : "235:4:0", |
||||||
|
"stateVariable" : false, |
||||||
|
"storageLocation" : "default", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
}, |
||||||
|
"typeName" : |
||||||
|
{ |
||||||
|
"id" : 41, |
||||||
|
"name" : "uint", |
||||||
|
"nodeType" : "ElementaryTypeName", |
||||||
|
"src" : "235:4:0", |
||||||
|
"typeDescriptions" : |
||||||
|
{ |
||||||
|
"typeIdentifier" : "t_uint256", |
||||||
|
"typeString" : "uint256" |
||||||
|
} |
||||||
|
}, |
||||||
|
"value" : null, |
||||||
|
"visibility" : "internal" |
||||||
|
} |
||||||
|
], |
||||||
|
"src" : "228:12:0" |
||||||
|
}, |
||||||
|
"scope" : 54, |
||||||
|
"src" : "198:79:0", |
||||||
|
"stateMutability" : "nonpayable", |
||||||
|
"superFunction" : null, |
||||||
|
"visibility" : "public" |
||||||
|
} |
||||||
|
], |
||||||
|
"scope" : 55, |
||||||
|
"src" : "24:255:0" |
||||||
|
} |
||||||
|
], |
||||||
|
"src" : "0:280:0" |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
// This is used to test detection of public mappings with nested variables. This was an issue in Solidity 0.4.x. |
||||||
|
pragma solidity ^0.4.0; |
||||||
|
|
||||||
|
contract Bug { |
||||||
|
|
||||||
|
struct innerStruct { |
||||||
|
uint x; |
||||||
|
} |
||||||
|
|
||||||
|
struct outerStruct { |
||||||
|
innerStruct inner; |
||||||
|
} |
||||||
|
|
||||||
|
mapping(uint => outerStruct) public testMapping; |
||||||
|
mapping(uint => uint) public testMapping2; |
||||||
|
mapping(uint => address) public testMapping3; |
||||||
|
|
||||||
|
constructor() public { |
||||||
|
testMapping[0].inner.x = 42; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract Test{ |
||||||
|
|
||||||
|
function f() public returns(uint){ |
||||||
|
Bug b = new Bug(); |
||||||
|
return b.testMapping(0).x; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "variable", |
||||||
|
"name": "testMapping", |
||||||
|
"source_mapping": { |
||||||
|
"start": 265, |
||||||
|
"length": 47, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/public-mappings-nested/public_mappings_nested.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/public-mappings-nested/public_mappings_nested.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
14 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 52 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Bug", |
||||||
|
"source_mapping": { |
||||||
|
"start": 138, |
||||||
|
"length": 345, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/public-mappings-nested/public_mappings_nested.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/public-mappings-nested/public_mappings_nested.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Bug.testMapping (tests/detectors/public-mappings-nested/public_mappings_nested.sol#14) is a public mapping with nested variables\n", |
||||||
|
"markdown": "[Bug.testMapping](tests/detectors/public-mappings-nested/public_mappings_nested.sol#L14) is a public mapping with nested variables\n", |
||||||
|
"id": "100978112524def620b003331f34b2b51eb78cae6f7eb2793d9671b4b7bb858a", |
||||||
|
"check": "public-mappings-nested", |
||||||
|
"impact": "High", |
||||||
|
"confidence": "High" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,17 @@ |
|||||||
|
// This tests for redundant top-level expressions in statements. |
||||||
|
|
||||||
|
contract RedundantStatementsContract { |
||||||
|
|
||||||
|
constructor() public { |
||||||
|
uint; |
||||||
|
bool; |
||||||
|
RedundantStatementsContract; |
||||||
|
} |
||||||
|
|
||||||
|
function test() public returns (uint) { |
||||||
|
uint; |
||||||
|
assert; |
||||||
|
test; |
||||||
|
return 777; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,733 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "uint256", |
||||||
|
"source_mapping": { |
||||||
|
"start": 141, |
||||||
|
"length": 4, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
6 |
||||||
|
], |
||||||
|
"starting_column": 9, |
||||||
|
"ending_column": 13 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "constructor", |
||||||
|
"source_mapping": { |
||||||
|
"start": 110, |
||||||
|
"length": 93, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "constructor()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Redundant expression \"uint256 (tests/detectors/redundant-statements/redundant_statements.sol#6)\" inRedundantStatementsContract (tests/detectors/redundant-statements/redundant_statements.sol#3-18)\n", |
||||||
|
"markdown": "Redundant expression \"[uint256](tests/detectors/redundant-statements/redundant_statements.sol#L6)\" in[RedundantStatementsContract](tests/detectors/redundant-statements/redundant_statements.sol#L3-L18)\n", |
||||||
|
"id": "cff54481eae76053f9cae0d4f77a2e5092461dc3fcb9e4e2f8605afb6aa832aa", |
||||||
|
"check": "redundant-statements", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "bool", |
||||||
|
"source_mapping": { |
||||||
|
"start": 155, |
||||||
|
"length": 4, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
7 |
||||||
|
], |
||||||
|
"starting_column": 9, |
||||||
|
"ending_column": 13 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "constructor", |
||||||
|
"source_mapping": { |
||||||
|
"start": 110, |
||||||
|
"length": 93, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "constructor()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Redundant expression \"bool (tests/detectors/redundant-statements/redundant_statements.sol#7)\" inRedundantStatementsContract (tests/detectors/redundant-statements/redundant_statements.sol#3-18)\n", |
||||||
|
"markdown": "Redundant expression \"[bool](tests/detectors/redundant-statements/redundant_statements.sol#L7)\" in[RedundantStatementsContract](tests/detectors/redundant-statements/redundant_statements.sol#L3-L18)\n", |
||||||
|
"id": "bd643774adde96fa093cf2ec70d9a80fc2999dba8b61b60d0df19366003d74d5", |
||||||
|
"check": "redundant-statements", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 169, |
||||||
|
"length": 27, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
8 |
||||||
|
], |
||||||
|
"starting_column": 9, |
||||||
|
"ending_column": 36 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "constructor", |
||||||
|
"source_mapping": { |
||||||
|
"start": 110, |
||||||
|
"length": 93, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "constructor()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Redundant expression \"RedundantStatementsContract (tests/detectors/redundant-statements/redundant_statements.sol#8)\" inRedundantStatementsContract (tests/detectors/redundant-statements/redundant_statements.sol#3-18)\n", |
||||||
|
"markdown": "Redundant expression \"[RedundantStatementsContract](tests/detectors/redundant-statements/redundant_statements.sol#L8)\" in[RedundantStatementsContract](tests/detectors/redundant-statements/redundant_statements.sol#L3-L18)\n", |
||||||
|
"id": "d93991180e8fe3accc3157f286d3a6781ed5c03398d68c0b9fde918a01d65ede", |
||||||
|
"check": "redundant-statements", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "uint256", |
||||||
|
"source_mapping": { |
||||||
|
"start": 257, |
||||||
|
"length": 4, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
12 |
||||||
|
], |
||||||
|
"starting_column": 9, |
||||||
|
"ending_column": 13 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "test", |
||||||
|
"source_mapping": { |
||||||
|
"start": 209, |
||||||
|
"length": 109, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "test()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Redundant expression \"uint256 (tests/detectors/redundant-statements/redundant_statements.sol#12)\" inRedundantStatementsContract (tests/detectors/redundant-statements/redundant_statements.sol#3-18)\n", |
||||||
|
"markdown": "Redundant expression \"[uint256](tests/detectors/redundant-statements/redundant_statements.sol#L12)\" in[RedundantStatementsContract](tests/detectors/redundant-statements/redundant_statements.sol#L3-L18)\n", |
||||||
|
"id": "262267538723f822ebe065e5976738ef3f564c791aaddb26867d202602de1eea", |
||||||
|
"check": "redundant-statements", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "assert(bool)", |
||||||
|
"source_mapping": { |
||||||
|
"start": 271, |
||||||
|
"length": 6, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
13 |
||||||
|
], |
||||||
|
"starting_column": 9, |
||||||
|
"ending_column": 15 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "test", |
||||||
|
"source_mapping": { |
||||||
|
"start": 209, |
||||||
|
"length": 109, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "test()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Redundant expression \"assert(bool) (tests/detectors/redundant-statements/redundant_statements.sol#13)\" inRedundantStatementsContract (tests/detectors/redundant-statements/redundant_statements.sol#3-18)\n", |
||||||
|
"markdown": "Redundant expression \"[assert(bool)](tests/detectors/redundant-statements/redundant_statements.sol#L13)\" in[RedundantStatementsContract](tests/detectors/redundant-statements/redundant_statements.sol#L3-L18)\n", |
||||||
|
"id": "00295b0d55ceb6d73eec5a4905d137edf751e11c951252b54cd42c43ace68ffd", |
||||||
|
"check": "redundant-statements", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "test", |
||||||
|
"source_mapping": { |
||||||
|
"start": 287, |
||||||
|
"length": 4, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
14 |
||||||
|
], |
||||||
|
"starting_column": 9, |
||||||
|
"ending_column": 13 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "test", |
||||||
|
"source_mapping": { |
||||||
|
"start": 209, |
||||||
|
"length": 109, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "test()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "RedundantStatementsContract", |
||||||
|
"source_mapping": { |
||||||
|
"start": 66, |
||||||
|
"length": 254, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/redundant-statements/redundant_statements.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 0 |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Redundant expression \"test (tests/detectors/redundant-statements/redundant_statements.sol#14)\" inRedundantStatementsContract (tests/detectors/redundant-statements/redundant_statements.sol#3-18)\n", |
||||||
|
"markdown": "Redundant expression \"[test](tests/detectors/redundant-statements/redundant_statements.sol#L14)\" in[RedundantStatementsContract](tests/detectors/redundant-statements/redundant_statements.sol#L3-L18)\n", |
||||||
|
"id": "ac50e063af6ebd33a702aa136415f7babc5fef3dc5212730b054d8a089b04e23", |
||||||
|
"check": "redundant-statements", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,37 @@ |
|||||||
|
contract A{ |
||||||
|
uint num = 5; |
||||||
|
constructor(uint x) public{ |
||||||
|
num += x; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract B is A{ |
||||||
|
constructor(uint y) A(y * 3) public{ |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract C is B{ |
||||||
|
constructor(uint y) A(y * 2) public{ |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract D is B(1), C(1) { |
||||||
|
constructor() B(3) C(2) public { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract E is B(1), C, D() { |
||||||
|
constructor() B(1) C(2) D() public { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
contract F is B { |
||||||
|
constructor() A(1) public { |
||||||
|
|
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,45 @@ |
|||||||
|
pragma solidity ^0.5.8; |
||||||
|
|
||||||
|
contract A { |
||||||
|
|
||||||
|
int[3] intArray; // storage signed integer array |
||||||
|
uint[3] uintArray; // storage unsigned integer array |
||||||
|
|
||||||
|
|
||||||
|
/* Signed integer array initializations with literal arrays are vulnerable */ |
||||||
|
function bad0() public { |
||||||
|
intArray = [-1, -2, -3]; |
||||||
|
} |
||||||
|
|
||||||
|
/* Signed integer array assignments are vulnerable if the base types are different e.g. int256 vs int128 */ |
||||||
|
function bad1(int128[3] memory userArray) public { |
||||||
|
intArray = userArray; |
||||||
|
} |
||||||
|
|
||||||
|
/* Unsigned Int array initializations are not vulnerable */ |
||||||
|
function good0() public { |
||||||
|
uintArray = [0, 1, 2]; |
||||||
|
} |
||||||
|
|
||||||
|
/* Unsigned Int array assignments are not vulnerable */ |
||||||
|
function good1(uint[3] memory userArray) public { |
||||||
|
uintArray = userArray; |
||||||
|
} |
||||||
|
|
||||||
|
/* Assigning individual array elements are not vulnerable */ |
||||||
|
function good2() public { |
||||||
|
intArray[1] = -1; |
||||||
|
} |
||||||
|
|
||||||
|
/* Assignment between two signed integer arrays of same base type int256 are not vulnerable */ |
||||||
|
function good3(int[3] memory userArray) public { |
||||||
|
intArray = userArray; |
||||||
|
} |
||||||
|
|
||||||
|
/* Array literal initialization of in-memory signed integer arrays are not vulnerable */ |
||||||
|
function good4() public { |
||||||
|
int8[3] memory memIntArray; |
||||||
|
memIntArray = [-1, -2, -3]; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
[ |
||||||
|
[] |
||||||
|
] |
@ -0,0 +1,516 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 25, |
||||||
|
"length": 2256, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad0", |
||||||
|
"source_mapping": { |
||||||
|
"start": 355, |
||||||
|
"length": 132, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
10, |
||||||
|
11, |
||||||
|
12 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 25, |
||||||
|
"length": 2256, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad0()" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "intArray = (- 1,- 2,- 3)", |
||||||
|
"source_mapping": { |
||||||
|
"start": 384, |
||||||
|
"length": 23, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
11 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 28 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad0", |
||||||
|
"source_mapping": { |
||||||
|
"start": 355, |
||||||
|
"length": 132, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
10, |
||||||
|
11, |
||||||
|
12 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 25, |
||||||
|
"length": 2256, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad0()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Contract A (tests/detectors/storage-array/storage_signed_integer_array.sol#3-45) \n\t- Function A.bad0() (tests/detectors/storage-array/storage_signed_integer_array.sol#10-12)\n\t\t- intArray = (- 1,- 2,- 3) (tests/detectors/storage-array/storage_signed_integer_array.sol#11) has a storage signed integer array assignment\n", |
||||||
|
"markdown": "Contract [A](tests/detectors/storage-array/storage_signed_integer_array.sol#L3-L45) \n\t- Function [A.bad0()](tests/detectors/storage-array/storage_signed_integer_array.sol#L10-L12)\n\t\t- [intArray = (- 1,- 2,- 3)](tests/detectors/storage-array/storage_signed_integer_array.sol#L11) has a storage signed integer array assignment\n", |
||||||
|
"id": "9301f6205d07f9bc40477e940ab7093092a8616caab1c78a2b84412ff6dd2eb1", |
||||||
|
"check": "storage-array", |
||||||
|
"impact": "High", |
||||||
|
"confidence": "Medium" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 25, |
||||||
|
"length": 2256, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 601, |
||||||
|
"length": 170, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
15, |
||||||
|
16, |
||||||
|
17 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 25, |
||||||
|
"length": 2256, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad1(int128[3])" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "intArray = userArray", |
||||||
|
"source_mapping": { |
||||||
|
"start": 746, |
||||||
|
"length": 20, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 25 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 601, |
||||||
|
"length": 170, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
15, |
||||||
|
16, |
||||||
|
17 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "A", |
||||||
|
"source_mapping": { |
||||||
|
"start": 25, |
||||||
|
"length": 2256, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/storage-array/storage_signed_integer_array.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21, |
||||||
|
22, |
||||||
|
23, |
||||||
|
24, |
||||||
|
25, |
||||||
|
26, |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42, |
||||||
|
43, |
||||||
|
44, |
||||||
|
45 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad1(int128[3])" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Contract A (tests/detectors/storage-array/storage_signed_integer_array.sol#3-45) \n\t- Function A.bad1(int128[3]) (tests/detectors/storage-array/storage_signed_integer_array.sol#15-17)\n\t\t- intArray = userArray (tests/detectors/storage-array/storage_signed_integer_array.sol#16) has a storage signed integer array assignment\n", |
||||||
|
"markdown": "Contract [A](tests/detectors/storage-array/storage_signed_integer_array.sol#L3-L45) \n\t- Function [A.bad1(int128[3])](tests/detectors/storage-array/storage_signed_integer_array.sol#L15-L17)\n\t\t- [intArray = userArray](tests/detectors/storage-array/storage_signed_integer_array.sol#L16) has a storage signed integer array assignment\n", |
||||||
|
"id": "e91a19803d53092184a9c091054f1ef371c8e5f9db15c5be6979bc4d06b70362", |
||||||
|
"check": "storage-array", |
||||||
|
"impact": "High", |
||||||
|
"confidence": "Medium" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,41 @@ |
|||||||
|
interface BaseInterface { |
||||||
|
function f1() external returns(uint); |
||||||
|
function f2() external returns(uint); |
||||||
|
} |
||||||
|
|
||||||
|
interface BaseInterface2 { |
||||||
|
function f3() external returns(uint); |
||||||
|
} |
||||||
|
|
||||||
|
contract DerivedContract_bad0 is BaseInterface, BaseInterface2 { |
||||||
|
function f1() external returns(uint){ |
||||||
|
return 42; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract AbstractContract_bad1 { |
||||||
|
function f1() external returns(uint); |
||||||
|
function f2() external returns(uint){ |
||||||
|
return 42; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract BaseInterface3 { |
||||||
|
function get(uint) external returns(uint); |
||||||
|
} |
||||||
|
|
||||||
|
contract DerivedContract_bad2 is BaseInterface3 { |
||||||
|
// the mapping type get(uint => bool) does NOT match the function get(uint) => uint |
||||||
|
mapping(uint => bool) public get; |
||||||
|
function f1() external returns(uint){ |
||||||
|
return 42; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract DerivedContract_good is BaseInterface3 { |
||||||
|
// In solc >= 0.5.1, the mapping type get(uint => uint) matches the function get(uint) => uint |
||||||
|
mapping(uint => uint) public get; |
||||||
|
function f1() external returns(uint){ |
||||||
|
return 42; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,346 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "DerivedContract_bad0", |
||||||
|
"source_mapping": { |
||||||
|
"start": 185, |
||||||
|
"length": 133, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "f2", |
||||||
|
"source_mapping": { |
||||||
|
"start": 72, |
||||||
|
"length": 37, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 42 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BaseInterface", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 111, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
2, |
||||||
|
3, |
||||||
|
4 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "f2()" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "f3", |
||||||
|
"source_mapping": { |
||||||
|
"start": 144, |
||||||
|
"length": 37, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
7 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 42 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BaseInterface2", |
||||||
|
"source_mapping": { |
||||||
|
"start": 113, |
||||||
|
"length": 70, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "f3()" |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "DerivedContract_bad0 (tests/detectors/unimplemented-functions/unimplemented.sol#10-14) does not implement functions:\n\t- BaseInterface.f2() (tests/detectors/unimplemented-functions/unimplemented.sol#3)\n\t- BaseInterface2.f3() (tests/detectors/unimplemented-functions/unimplemented.sol#7)\n", |
||||||
|
"markdown": "[DerivedContract_bad0](tests/detectors/unimplemented-functions/unimplemented.sol#L10-L14) does not implement functions:\n\t- [BaseInterface.f2()](tests/detectors/unimplemented-functions/unimplemented.sol#L3)\n\t- [BaseInterface2.f3()](tests/detectors/unimplemented-functions/unimplemented.sol#L7)\n", |
||||||
|
"id": "8614d351f7aac0c05e8df6ef7c89c6b46a2b8acf6295c9d5a886ff6489c74a41", |
||||||
|
"check": "unimplemented-functions", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "AbstractContract_bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 320, |
||||||
|
"length": 143, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "f1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 357, |
||||||
|
"length": 37, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
17 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 42 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "AbstractContract_bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 320, |
||||||
|
"length": 143, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
16, |
||||||
|
17, |
||||||
|
18, |
||||||
|
19, |
||||||
|
20, |
||||||
|
21 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "f1()" |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "AbstractContract_bad1 (tests/detectors/unimplemented-functions/unimplemented.sol#16-21) does not implement functions:\n\t- AbstractContract_bad1.f1() (tests/detectors/unimplemented-functions/unimplemented.sol#17)\n", |
||||||
|
"markdown": "[AbstractContract_bad1](tests/detectors/unimplemented-functions/unimplemented.sol#L16-L21) does not implement functions:\n\t- [AbstractContract_bad1.f1()](tests/detectors/unimplemented-functions/unimplemented.sol#L17)\n", |
||||||
|
"id": "adc202df4717efc4e19b549c0e623a79fac759a36bffb5d5e4aac401e33375d7", |
||||||
|
"check": "unimplemented-functions", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "DerivedContract_bad2", |
||||||
|
"source_mapping": { |
||||||
|
"start": 541, |
||||||
|
"length": 232, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
27, |
||||||
|
28, |
||||||
|
29, |
||||||
|
30, |
||||||
|
31, |
||||||
|
32, |
||||||
|
33 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "get", |
||||||
|
"source_mapping": { |
||||||
|
"start": 495, |
||||||
|
"length": 42, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
24 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 47 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BaseInterface3", |
||||||
|
"source_mapping": { |
||||||
|
"start": 465, |
||||||
|
"length": 74, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
23, |
||||||
|
24, |
||||||
|
25 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "get(uint256)" |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "DerivedContract_bad2 (tests/detectors/unimplemented-functions/unimplemented.sol#27-33) does not implement functions:\n\t- BaseInterface3.get(uint256) (tests/detectors/unimplemented-functions/unimplemented.sol#24)\n", |
||||||
|
"markdown": "[DerivedContract_bad2](tests/detectors/unimplemented-functions/unimplemented.sol#L27-L33) does not implement functions:\n\t- [BaseInterface3.get(uint256)](tests/detectors/unimplemented-functions/unimplemented.sol#L24)\n", |
||||||
|
"id": "31915d2f480e24ddd054de973440a02abdac0ccd6332c47cd4eb8d836d3fddda", |
||||||
|
"check": "unimplemented-functions", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "DerivedContract_good", |
||||||
|
"source_mapping": { |
||||||
|
"start": 775, |
||||||
|
"length": 243, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "get", |
||||||
|
"source_mapping": { |
||||||
|
"start": 495, |
||||||
|
"length": 42, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
24 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 47 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BaseInterface3", |
||||||
|
"source_mapping": { |
||||||
|
"start": 465, |
||||||
|
"length": 74, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/unimplemented-functions/unimplemented.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
23, |
||||||
|
24, |
||||||
|
25 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "get(uint256)" |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "DerivedContract_good (tests/detectors/unimplemented-functions/unimplemented.sol#35-41) does not implement functions:\n\t- BaseInterface3.get(uint256) (tests/detectors/unimplemented-functions/unimplemented.sol#24)\n", |
||||||
|
"markdown": "[DerivedContract_good](tests/detectors/unimplemented-functions/unimplemented.sol#L35-L41) does not implement functions:\n\t- [BaseInterface3.get(uint256)](tests/detectors/unimplemented-functions/unimplemented.sol#L24)\n", |
||||||
|
"id": "08d3e8a72b5da6d189acb46ecd36f00787a87812727526a0cae248a2bac348fc", |
||||||
|
"check": "unimplemented-functions", |
||||||
|
"impact": "Informational", |
||||||
|
"confidence": "High" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,136 @@ |
|||||||
|
pragma solidity 0.5.8; |
||||||
|
|
||||||
|
contract bad0 { |
||||||
|
constructor() public { |
||||||
|
/* Uninitialized function pointer */ |
||||||
|
function(uint256) internal returns(uint256) a; |
||||||
|
a(10); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract bad1 { |
||||||
|
constructor() public { |
||||||
|
/* Uninitialized function pointer but external visibility */ |
||||||
|
/* Although the Solidity bug report does not specify external visibility, we believe both internal/external may be vulnerable */ |
||||||
|
function(uint256) external returns(uint256) b; |
||||||
|
b(10); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract bad2 { |
||||||
|
struct S { |
||||||
|
/* Uninitialized function pointer within a struct*/ |
||||||
|
function(uint256) internal returns(uint256) a; |
||||||
|
} |
||||||
|
constructor() public { |
||||||
|
S memory s; |
||||||
|
s.a(10); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract bad3 { |
||||||
|
/* Uninitialized state variable function pointer written-to after call */ |
||||||
|
function(uint256) internal returns(uint256) a; |
||||||
|
|
||||||
|
constructor() public { |
||||||
|
a(10); |
||||||
|
a = foo; |
||||||
|
} |
||||||
|
function foo(uint256 i) internal returns(uint256) { |
||||||
|
return(i); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract good0 { |
||||||
|
constructor() public { |
||||||
|
/* Uninitialized function pointer but not called */ |
||||||
|
function(uint256) internal returns(uint256) a; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract good1 { |
||||||
|
constructor() public { |
||||||
|
/* Initialized function pointer */ |
||||||
|
function(uint256) internal returns(uint256) a = foo; |
||||||
|
a(10); |
||||||
|
} |
||||||
|
function foo(uint256 i) internal returns(uint256) { |
||||||
|
return(i); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract good2 { |
||||||
|
constructor() public { |
||||||
|
} |
||||||
|
function foo(uint256 i) internal returns(uint256) { |
||||||
|
/* Uninitialized function pointer but not in constructor */ |
||||||
|
function(uint256) internal returns(uint256) a; |
||||||
|
a(10); |
||||||
|
return(i); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract good3 { |
||||||
|
constructor() public { |
||||||
|
/* Normal function call */ |
||||||
|
foo(10); |
||||||
|
} |
||||||
|
function foo(uint256 i) internal returns(uint256) { |
||||||
|
return(i); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract good4 { |
||||||
|
struct S { |
||||||
|
uint S_i; |
||||||
|
} |
||||||
|
constructor() public { |
||||||
|
/* Uninitialized variables of other types but not function pointer */ |
||||||
|
uint i; |
||||||
|
address addr; |
||||||
|
uint[] memory arr; |
||||||
|
S memory s; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract good5 { |
||||||
|
constructor() public { |
||||||
|
/* Uninitialized local function pointer written to later */ |
||||||
|
function(uint256) internal returns(uint256) a; |
||||||
|
a = foo; |
||||||
|
a(10); |
||||||
|
} |
||||||
|
function foo(uint256 i) internal returns(uint256) { |
||||||
|
return(i); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract good6 { |
||||||
|
/* Uninitialized state variable function pointer written to later */ |
||||||
|
function(uint256) internal returns(uint256) a; |
||||||
|
|
||||||
|
constructor() public { |
||||||
|
a = foo; |
||||||
|
a(10); |
||||||
|
} |
||||||
|
function foo(uint256 i) internal returns(uint256) { |
||||||
|
return(i); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract good7 { |
||||||
|
struct S { |
||||||
|
/* Uninitialized function pointer within a struct*/ |
||||||
|
function(uint256) internal returns(uint256) a; |
||||||
|
} |
||||||
|
|
||||||
|
constructor() public { |
||||||
|
S memory s; |
||||||
|
s.a = foo; |
||||||
|
s.a(10); |
||||||
|
} |
||||||
|
|
||||||
|
function foo(uint256 i) internal returns(uint256) { |
||||||
|
return(i); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,325 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "bad0", |
||||||
|
"source_mapping": { |
||||||
|
"start": 24, |
||||||
|
"length": 149, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "a(10)", |
||||||
|
"source_mapping": { |
||||||
|
"start": 161, |
||||||
|
"length": 5, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
7 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 10 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "constructor", |
||||||
|
"source_mapping": { |
||||||
|
"start": 42, |
||||||
|
"length": 129, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "bad0", |
||||||
|
"source_mapping": { |
||||||
|
"start": 24, |
||||||
|
"length": 149, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "constructor()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Contract bad0 (tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#3-9) \n\t a(10) (tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#7) is an unintialized function pointer call in a constructor\n", |
||||||
|
"markdown": "Contract [bad0](tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#L3-L9) \n\t [a(10)](tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#L7) is an unintialized function pointer call in a constructor\n", |
||||||
|
"id": "6e9480c70e9d054243bb478398b26663f05444b4b9b858109d67f9c63dbbc3e2", |
||||||
|
"check": "uninitialized-fptr-cst", |
||||||
|
"impact": "Low", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 175, |
||||||
|
"length": 306, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "b(10)", |
||||||
|
"source_mapping": { |
||||||
|
"start": 469, |
||||||
|
"length": 5, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 10 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "constructor", |
||||||
|
"source_mapping": { |
||||||
|
"start": 193, |
||||||
|
"length": 286, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 175, |
||||||
|
"length": 306, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16, |
||||||
|
17, |
||||||
|
18 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "constructor()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Contract bad1 (tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#11-18) \n\t b(10) (tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#16) is an unintialized function pointer call in a constructor\n", |
||||||
|
"markdown": "Contract [bad1](tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#L11-L18) \n\t [b(10)](tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#L16) is an unintialized function pointer call in a constructor\n", |
||||||
|
"id": "b0a15c051d9962762902c5565802334898e572e98018b42b85a89b45208c50d2", |
||||||
|
"check": "uninitialized-fptr-cst", |
||||||
|
"impact": "Low", |
||||||
|
"confidence": "High" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "contract", |
||||||
|
"name": "bad3", |
||||||
|
"source_mapping": { |
||||||
|
"start": 684, |
||||||
|
"length": 269, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "a(10)", |
||||||
|
"source_mapping": { |
||||||
|
"start": 855, |
||||||
|
"length": 5, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
36 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 10 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "constructor", |
||||||
|
"source_mapping": { |
||||||
|
"start": 828, |
||||||
|
"length": 50, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38 |
||||||
|
], |
||||||
|
"starting_column": 3, |
||||||
|
"ending_column": 4 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "bad3", |
||||||
|
"source_mapping": { |
||||||
|
"start": 684, |
||||||
|
"length": 269, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
31, |
||||||
|
32, |
||||||
|
33, |
||||||
|
34, |
||||||
|
35, |
||||||
|
36, |
||||||
|
37, |
||||||
|
38, |
||||||
|
39, |
||||||
|
40, |
||||||
|
41, |
||||||
|
42 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "constructor()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "Contract bad3 (tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#31-42) \n\t a(10) (tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#36) is an unintialized function pointer call in a constructor\n", |
||||||
|
"markdown": "Contract [bad3](tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#L31-L42) \n\t [a(10)](tests/detectors/uninitialized-fptr-cst/uninitialized_function_ptr_constructor.sol#L36) is an unintialized function pointer call in a constructor\n", |
||||||
|
"id": "1f12cc039e869f6f13be8a85e2d98a53212dc95e859908a9188dd6b152fb804f", |
||||||
|
"check": "uninitialized-fptr-cst", |
||||||
|
"impact": "Low", |
||||||
|
"confidence": "High" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
@ -0,0 +1,28 @@ |
|||||||
|
contract BadPRNG{ |
||||||
|
event Time(uint); |
||||||
|
|
||||||
|
function bad0() external{ |
||||||
|
uint i = block.timestamp % 10; |
||||||
|
} |
||||||
|
|
||||||
|
function bad1() external{ |
||||||
|
uint i = now % 10; |
||||||
|
} |
||||||
|
|
||||||
|
function bad2() external{ |
||||||
|
uint i = uint256(blockhash(10000)) % 10; |
||||||
|
} |
||||||
|
|
||||||
|
function foo() public returns (uint) { |
||||||
|
return(uint256(blockhash(10000))); |
||||||
|
} |
||||||
|
|
||||||
|
function bad3() external{ |
||||||
|
uint i = foo() % 10; |
||||||
|
} |
||||||
|
|
||||||
|
function good() external{ |
||||||
|
emit Time(block.timestamp); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,660 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad0", |
||||||
|
"source_mapping": { |
||||||
|
"start": 45, |
||||||
|
"length": 68, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
4, |
||||||
|
5, |
||||||
|
6 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BadPRNG", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 499, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad0()" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "i = block.timestamp % 10", |
||||||
|
"source_mapping": { |
||||||
|
"start": 77, |
||||||
|
"length": 29, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
5 |
||||||
|
], |
||||||
|
"starting_column": 7, |
||||||
|
"ending_column": 36 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad0", |
||||||
|
"source_mapping": { |
||||||
|
"start": 45, |
||||||
|
"length": 68, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
4, |
||||||
|
5, |
||||||
|
6 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BadPRNG", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 499, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad0()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "BadPRNG.bad0() (tests/detectors/weak-prng/bad_prng.sol#4-6) uses a weak PRNG: \"i = block.timestamp % 10 (tests/detectors/weak-prng/bad_prng.sol#5)\" \n", |
||||||
|
"markdown": "[BadPRNG.bad0()](tests/detectors/weak-prng/bad_prng.sol#L4-L6) uses a weak PRNG: \"[i = block.timestamp % 10](tests/detectors/weak-prng/bad_prng.sol#L5)\" \n", |
||||||
|
"id": "af624d9c7f3f688c1bad5ecaee81085e0d5cde4e6a55de34ff93684527619748", |
||||||
|
"check": "weak-prng", |
||||||
|
"impact": "High", |
||||||
|
"confidence": "Medium" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 122, |
||||||
|
"length": 56, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
8, |
||||||
|
9, |
||||||
|
10 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BadPRNG", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 499, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad1()" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "i = now % 10", |
||||||
|
"source_mapping": { |
||||||
|
"start": 154, |
||||||
|
"length": 17, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
9 |
||||||
|
], |
||||||
|
"starting_column": 7, |
||||||
|
"ending_column": 24 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad1", |
||||||
|
"source_mapping": { |
||||||
|
"start": 122, |
||||||
|
"length": 56, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
8, |
||||||
|
9, |
||||||
|
10 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BadPRNG", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 499, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad1()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "BadPRNG.bad1() (tests/detectors/weak-prng/bad_prng.sol#8-10) uses a weak PRNG: \"i = now % 10 (tests/detectors/weak-prng/bad_prng.sol#9)\" \n", |
||||||
|
"markdown": "[BadPRNG.bad1()](tests/detectors/weak-prng/bad_prng.sol#L8-L10) uses a weak PRNG: \"[i = now % 10](tests/detectors/weak-prng/bad_prng.sol#L9)\" \n", |
||||||
|
"id": "fe07d1e4f27274570cfb85530c1cbf7fb7a9004f475b91d1a3762452b017e1b9", |
||||||
|
"check": "weak-prng", |
||||||
|
"impact": "High", |
||||||
|
"confidence": "Medium" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad2", |
||||||
|
"source_mapping": { |
||||||
|
"start": 184, |
||||||
|
"length": 78, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
12, |
||||||
|
13, |
||||||
|
14 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BadPRNG", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 499, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad2()" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "i = uint256(blockhash(uint256)(10000)) % 10", |
||||||
|
"source_mapping": { |
||||||
|
"start": 216, |
||||||
|
"length": 39, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
13 |
||||||
|
], |
||||||
|
"starting_column": 7, |
||||||
|
"ending_column": 46 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad2", |
||||||
|
"source_mapping": { |
||||||
|
"start": 184, |
||||||
|
"length": 78, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
12, |
||||||
|
13, |
||||||
|
14 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BadPRNG", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 499, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad2()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "BadPRNG.bad2() (tests/detectors/weak-prng/bad_prng.sol#12-14) uses a weak PRNG: \"i = uint256(blockhash(uint256)(10000)) % 10 (tests/detectors/weak-prng/bad_prng.sol#13)\" \n", |
||||||
|
"markdown": "[BadPRNG.bad2()](tests/detectors/weak-prng/bad_prng.sol#L12-L14) uses a weak PRNG: \"[i = uint256(blockhash(uint256)(10000)) % 10](tests/detectors/weak-prng/bad_prng.sol#L13)\" \n", |
||||||
|
"id": "100d285386f797a469c6797fcce41350b1984f7e7aab1532580d9b69a774b6f5", |
||||||
|
"check": "weak-prng", |
||||||
|
"impact": "High", |
||||||
|
"confidence": "Medium" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "bad3", |
||||||
|
"source_mapping": { |
||||||
|
"start": 363, |
||||||
|
"length": 58, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
20, |
||||||
|
21, |
||||||
|
22 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BadPRNG", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 499, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad3()" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "node", |
||||||
|
"name": "i = foo() % 10", |
||||||
|
"source_mapping": { |
||||||
|
"start": 395, |
||||||
|
"length": 19, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
21 |
||||||
|
], |
||||||
|
"starting_column": 7, |
||||||
|
"ending_column": 26 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "function", |
||||||
|
"name": "bad3", |
||||||
|
"source_mapping": { |
||||||
|
"start": 363, |
||||||
|
"length": 58, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
20, |
||||||
|
21, |
||||||
|
22 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 6 |
||||||
|
}, |
||||||
|
"type_specific_fields": { |
||||||
|
"parent": { |
||||||
|
"type": "contract", |
||||||
|
"name": "BadPRNG", |
||||||
|
"source_mapping": { |
||||||
|
"start": 0, |
||||||
|
"length": 499, |
||||||
|
"filename_used": "/GENERIC_PATH", |
||||||
|
"filename_relative": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"filename_absolute": "/GENERIC_PATH", |
||||||
|
"filename_short": "tests/detectors/weak-prng/bad_prng.sol", |
||||||
|
"is_dependency": false, |
||||||
|
"lines": [ |
||||||
|
1, |
||||||
|
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 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
"signature": "bad3()" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"description": "BadPRNG.bad3() (tests/detectors/weak-prng/bad_prng.sol#20-22) uses a weak PRNG: \"i = foo() % 10 (tests/detectors/weak-prng/bad_prng.sol#21)\" \n", |
||||||
|
"markdown": "[BadPRNG.bad3()](tests/detectors/weak-prng/bad_prng.sol#L20-L22) uses a weak PRNG: \"[i = foo() % 10](tests/detectors/weak-prng/bad_prng.sol#L21)\" \n", |
||||||
|
"id": "a382f093e54d2c7beb2c10b3537790371f4b95545c48d1300fd25d20717d137a", |
||||||
|
"check": "weak-prng", |
||||||
|
"impact": "High", |
||||||
|
"confidence": "Medium" |
||||||
|
} |
||||||
|
] |
||||||
|
] |
Loading…
Reference in new issue