diff --git a/slither/detectors/attributes/locked_ether.py b/slither/detectors/attributes/locked_ether.py index 682224f02..c0ea08953 100644 --- a/slither/detectors/attributes/locked_ether.py +++ b/slither/detectors/attributes/locked_ether.py @@ -38,10 +38,10 @@ class LockedEther(AbstractDetector): def detect(self): results = [] - for contract in self.slither.contracts_derived: + for contract in sorted(self.slither.contracts_derived, key=lambda c: c.name): if contract.is_signature_only(): continue - funcs_payable = [function for function in contract.functions if function.payable] + funcs_payable = [function for function in sorted(contract.functions, key=lambda x: x.name) if function.payable] if funcs_payable: if self.do_no_send_ether(contract): txt = "Contract locked ether in {}, Contract {}, Functions {}" diff --git a/slither/detectors/examples/backdoor.py b/slither/detectors/examples/backdoor.py index 9e29724f9..1543e70f6 100644 --- a/slither/detectors/examples/backdoor.py +++ b/slither/detectors/examples/backdoor.py @@ -14,9 +14,9 @@ class Backdoor(AbstractDetector): def detect(self): ret = [] - for contract in self.slither.contracts_derived: + for contract in sorted(self.slither.contracts_derived, key=lambda c: c.name): # Check if a function has 'backdoor' in its name - for f in contract.functions: + for f in sorted(contract.functions, key=lambda x: x.name): if 'backdoor' in f.name: # Info to be printed info = 'Backdoor function found in {}.{}'.format(contract.name, f.name) diff --git a/slither/detectors/functions/arbitrary_send.py b/slither/detectors/functions/arbitrary_send.py index 920351d41..594c6ce78 100644 --- a/slither/detectors/functions/arbitrary_send.py +++ b/slither/detectors/functions/arbitrary_send.py @@ -33,7 +33,7 @@ class ArbitrarySend(AbstractDetector): @staticmethod def arbitrary_send(func): - """ + """ """ if func.is_protected(): return [] @@ -94,9 +94,9 @@ class ArbitrarySend(AbstractDetector): taint = SolidityVariableComposed('msg.sender') run_taint_variable(self.slither, taint) - for c in self.contracts: + for c in sorted(self.contracts, key=lambda c: c.name): arbitrary_send = self.detect_arbitrary_send(c) - for (func, nodes) in arbitrary_send: + for (func, nodes) in sorted(arbitrary_send, key=lambda v: v[0].name): func_name = func.name calls_str = [str(node.expression) for node in nodes] diff --git a/slither/detectors/functions/external_function.py b/slither/detectors/functions/external_function.py index 99ffe40fe..c5d860201 100644 --- a/slither/detectors/functions/external_function.py +++ b/slither/detectors/functions/external_function.py @@ -46,14 +46,14 @@ class ExternalFunction(AbstractDetector): public_function_calls = [] - for contract in self.slither.contracts_derived: + for contract in sorted(self.slither.contracts_derived, key=lambda c: c.name): if self._contains_internal_dynamic_call(contract): continue func_list = self.detect_functions_called(contract) public_function_calls.extend(func_list) - for func in [f for f in contract.functions if f.visibility == 'public' and\ + for func in [f for f in sorted(contract.functions, key=lambda x: x.name) if f.visibility == 'public' and\ not f in public_function_calls and\ not f.is_constructor]: func_name = func.name diff --git a/slither/detectors/functions/suicidal.py b/slither/detectors/functions/suicidal.py index 41b6f9bc5..156aa569f 100644 --- a/slither/detectors/functions/suicidal.py +++ b/slither/detectors/functions/suicidal.py @@ -51,9 +51,9 @@ class Suicidal(AbstractDetector): """ Detect the suicidal functions """ results = [] - for c in self.contracts: + for c in sorted(self.contracts, key=lambda c: c.name): functions = self.detect_suicidal(c) - for func in functions: + for func in sorted(functions, key=lambda x: x.name): func_name = func.name txt = "Suicidal function in {} Contract: {}, Function: {}" diff --git a/slither/detectors/naming_convention/naming_convention.py b/slither/detectors/naming_convention/naming_convention.py index f3312c1f0..36d928983 100644 --- a/slither/detectors/naming_convention/naming_convention.py +++ b/slither/detectors/naming_convention/naming_convention.py @@ -42,7 +42,7 @@ class NamingConvention(AbstractDetector): def detect(self): results = [] - for contract in self.contracts: + for contract in sorted(self.contracts, key=lambda c: c.name): if not self.is_cap_words(contract.name): info = "Contract '{}' is not in CapWords".format(contract.name) @@ -53,7 +53,7 @@ class NamingConvention(AbstractDetector): 'contract': contract.name, 'sourceMapping': contract.source_mapping}) - for struct in contract.structures: + for struct in sorted(contract.structures, key=lambda x: x.name): if struct.contract != contract: continue @@ -67,7 +67,7 @@ class NamingConvention(AbstractDetector): 'struct': struct.name, 'sourceMapping': struct.source_mapping}) - for event in contract.events: + for event in sorted(contract.events, key=lambda x: x.name): if event.contract != contract: continue @@ -81,7 +81,7 @@ class NamingConvention(AbstractDetector): 'event': event.name, 'sourceMapping': event.source_mapping}) - for func in contract.functions: + for func in sorted(contract.functions, key=lambda x: x.name): if func.contract != contract: continue @@ -95,7 +95,7 @@ class NamingConvention(AbstractDetector): 'function': func.name, 'sourceMapping': func.source_mapping}) - for argument in func.parameters: + for argument in sorted(func.parameters, key=lambda x: x.name): if argument in func.variables_read_or_written: correct_naming = self.is_mixed_case(argument.name) else: @@ -112,7 +112,7 @@ class NamingConvention(AbstractDetector): 'argument': argument.name, 'sourceMapping': argument.source_mapping}) - for var in contract.state_variables: + for var in sorted(contract.state_variables, key=lambda x: x.name): if var.contract != contract: continue @@ -158,7 +158,7 @@ class NamingConvention(AbstractDetector): 'variable': var.name, 'sourceMapping': var.source_mapping}) - for enum in contract.enums: + for enum in sorted(contract.enums, key=lambda x: x.name): if enum.contract != contract: continue @@ -172,7 +172,7 @@ class NamingConvention(AbstractDetector): 'enum': enum.name, 'sourceMapping': enum.source_mapping}) - for modifier in contract.modifiers: + for modifier in sorted(contract.modifiers, key=lambda x: x.name): if modifier.contract != contract: continue diff --git a/slither/detectors/operations/low_level_calls.py b/slither/detectors/operations/low_level_calls.py index ec0f546a7..11ce2c89b 100644 --- a/slither/detectors/operations/low_level_calls.py +++ b/slither/detectors/operations/low_level_calls.py @@ -39,9 +39,9 @@ class LowLevelCalls(AbstractDetector): """ Detect the functions that use low level calls """ results = [] - for c in self.contracts: + for c in sorted(self.contracts, key=lambda c: c.name): values = self.detect_low_level_calls(c) - for func, nodes in values: + for func, nodes in sorted(values, key=lambda v: v[0].name): func_name = func.name info = "Low level call in %s, Contract: %s, Function: %s" % (self.filename, c.name, diff --git a/slither/detectors/reentrancy/reentrancy.py b/slither/detectors/reentrancy/reentrancy.py index e5c9966a7..15325feb2 100644 --- a/slither/detectors/reentrancy/reentrancy.py +++ b/slither/detectors/reentrancy/reentrancy.py @@ -176,7 +176,7 @@ class Reentrancy(AbstractDetector): results = [] - for (contract, func, calls, send_eth), varsWritten in self.result.items(): + for (contract, func, calls, send_eth), varsWritten in sorted(self.result.items(), key=lambda x: (x[0][0], x[0][1], str(list(x[0][2])) )): varsWritten_str = list(set([str(x) for x in list(varsWritten)])) calls_str = list(set([str(x.expression) for x in list(calls)])) send_eth_str = list(set([str(x.expression) for x in list(send_eth)])) diff --git a/slither/detectors/shadowing/shadowing_functions.py b/slither/detectors/shadowing/shadowing_functions.py index 60d9677df..cecdc4b57 100644 --- a/slither/detectors/shadowing/shadowing_functions.py +++ b/slither/detectors/shadowing/shadowing_functions.py @@ -37,10 +37,10 @@ class ShadowingFunctionsDetection(AbstractDetector): """ results = [] - for c in self.contracts: + for c in sorted(self.contracts, key=lambda c: c.name): shadowing = self.detect_shadowing(c) if shadowing: - for contract, funcs in shadowing.items(): + for contract, funcs in sorted(shadowing.items(), key=lambda x: (x[0].name, str(list(x[1])))): results.append({'vuln': self.vuln_name, 'filename': self.filename, 'contractShadower': c.name, diff --git a/slither/detectors/statements/assembly.py b/slither/detectors/statements/assembly.py index 93e9ea598..85ffbe934 100644 --- a/slither/detectors/statements/assembly.py +++ b/slither/detectors/statements/assembly.py @@ -39,9 +39,9 @@ class Assembly(AbstractDetector): """ Detect the functions that use inline assembly """ results = [] - for c in self.contracts: + for c in sorted(self.contracts, key=lambda c: c.name): values = self.detect_assembly(c) - for func, nodes in values: + for func, nodes in sorted(values, key=lambda v: v[0].name): func_name = func.name info = "Assembly in %s, Contract: %s, Function: %s" % (self.filename, c.name, diff --git a/slither/detectors/statements/tx_origin.py b/slither/detectors/statements/tx_origin.py index f5c474f8f..fe2f5dc53 100644 --- a/slither/detectors/statements/tx_origin.py +++ b/slither/detectors/statements/tx_origin.py @@ -45,9 +45,9 @@ class TxOrigin(AbstractDetector): """ Detect the functions that use tx.origin in a conditional node """ results = [] - for c in self.contracts: + for c in sorted(self.contracts, key=lambda c: c.name): values = self.detect_tx_origin(c) - for func, nodes in values: + for func, nodes in sorted(values, key=lambda v: v[0].name): func_name = func.name info = "tx.origin in %s, Contract: %s, Function: %s" % (self.filename, c.name, diff --git a/slither/detectors/variables/possible_const_state_variables.py b/slither/detectors/variables/possible_const_state_variables.py index e19a389d1..4bcb0f3f4 100644 --- a/slither/detectors/variables/possible_const_state_variables.py +++ b/slither/detectors/variables/possible_const_state_variables.py @@ -54,12 +54,12 @@ class ConstCandidateStateVars(AbstractDetector): """ Detect state variables that could be const """ results = [] - for c in self.slither.contracts_derived: + for c in sorted(self.slither.contracts_derived, key=lambda c: c.name): const_candidates = self.detect_const_candidates(c) if const_candidates: variables_by_contract = defaultdict(list) - for state_var in const_candidates: + for state_var in sorted(const_candidates, key=lambda x: (x.contract.name, x.name)): variables_by_contract[state_var.contract.name].append(state_var) for contract, variables in variables_by_contract.items(): diff --git a/slither/detectors/variables/uninitialized_state_variables.py b/slither/detectors/variables/uninitialized_state_variables.py index 86f54b048..17abb4a28 100644 --- a/slither/detectors/variables/uninitialized_state_variables.py +++ b/slither/detectors/variables/uninitialized_state_variables.py @@ -69,9 +69,9 @@ class UninitializedStateVarsDetection(AbstractDetector): dict: [contract name] = set(state variable uninitialized) """ results = [] - for c in self.slither.contracts_derived: + for c in sorted(self.slither.contracts_derived, key=lambda c: c.name): ret = self.detect_uninitialized(c) - for variable, functions in ret: + for variable, functions in sorted(ret, key=lambda r: str(r[0])): info = "Uninitialized state variable in %s, " % self.filename + \ "Contract: %s, Variable: %s, Used in %s" % (c.name, str(variable), diff --git a/slither/detectors/variables/uninitialized_storage_variables.py b/slither/detectors/variables/uninitialized_storage_variables.py index 37201b33c..eef4ef4d6 100644 --- a/slither/detectors/variables/uninitialized_storage_variables.py +++ b/slither/detectors/variables/uninitialized_storage_variables.py @@ -79,7 +79,7 @@ class UninitializedStorageVars(AbstractDetector): function.entry_point.context[self.key] = uninitialized_storage_variables self._detect_uninitialized(function, function.entry_point, []) - for(function, uninitialized_storage_variable) in self.results: + for(function, uninitialized_storage_variable) in sorted(self.results, key=lambda r: (r[0].contract.name, r[0].name, r[1].name)): var_name = uninitialized_storage_variable.name info = "Uninitialized storage variables in %s, " % self.filename + \ diff --git a/slither/detectors/variables/unused_state_variables.py b/slither/detectors/variables/unused_state_variables.py index 5be36163e..c9ec84c03 100644 --- a/slither/detectors/variables/unused_state_variables.py +++ b/slither/detectors/variables/unused_state_variables.py @@ -30,7 +30,7 @@ class UnusedStateVars(AbstractDetector): """ Detect unused state variables """ results = [] - for c in self.slither.contracts_derived: + for c in sorted(self.slither.contracts_derived, key=lambda c: c.name): unusedVars = self.detect_unused(c) if unusedVars: unusedVarsName = [v.name for v in unusedVars]