From c2187307836feb9a2c713d22a3066a28b785bde8 Mon Sep 17 00:00:00 2001 From: Josselin Date: Fri, 26 Oct 2018 17:07:17 +0100 Subject: [PATCH 1/5] Update printers description --- README.md | 15 ++++++++------- slither/printers/call/call_graph.py | 2 +- slither/printers/functions/authorization.py | 2 +- slither/printers/inheritance/inheritance.py | 2 +- slither/printers/inheritance/inheritance_graph.py | 2 +- slither/printers/summary/contract.py | 2 +- slither/printers/summary/function.py | 2 +- slither/printers/summary/slithir.py | 2 +- 8 files changed, 15 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index ceb053040..f78def51e 100644 --- a/README.md +++ b/README.md @@ -71,13 +71,14 @@ To run a printer, use `--printers` and a comma-separated list of printers. Num | Printer | Description --- | --- | --- -1 | `call-graph` | the call graph -2 | `contract-summary` | a summary of the contract -3 | `function-summary` | the summary of the functions -4 | `inheritance` | the inheritance relation between contracts -5 | `inheritance-graph` | the inheritance graph -6 | `slithir` | the slithIR -7 | `vars-and-auth` | state variables written and the authorization of the functions +1 | `call-graph` | Export the call-graph of the contracts to a dot file +2 | `contract-summary` | Print a summary of the contracts +3 | `function-summary` | Print a summary of the functions +4 | `inheritance` | Print the inheritance relations between contracts +5 | `inheritance-graph` | Export the inheritance graph of each contract to a dot file +6 | `slithir` | Print the slithIR representation of the functions +7 | `vars-and-auth` | Print the state variables written and the authorization of the functions + ## How to install diff --git a/slither/printers/call/call_graph.py b/slither/printers/call/call_graph.py index 18058c6c6..bc446180d 100644 --- a/slither/printers/call/call_graph.py +++ b/slither/printers/call/call_graph.py @@ -40,7 +40,7 @@ def _node(node, label=None): class PrinterCallGraph(AbstractPrinter): ARGUMENT = 'call-graph' - HELP = 'the call graph' + HELP = 'Export the call-graph of the contracts to a dot file' def __init__(self, slither, logger): super(PrinterCallGraph, self).__init__(slither, logger) diff --git a/slither/printers/functions/authorization.py b/slither/printers/functions/authorization.py index 5880d6c11..ff1666331 100644 --- a/slither/printers/functions/authorization.py +++ b/slither/printers/functions/authorization.py @@ -9,7 +9,7 @@ from slither.core.declarations.function import Function class PrinterWrittenVariablesAndAuthorization(AbstractPrinter): ARGUMENT = 'vars-and-auth' - HELP = 'the state variables written and the authorization of the functions' + HELP = 'Print the state variables written and the authorization of the functions' @staticmethod def get_msg_sender_checks(function): diff --git a/slither/printers/inheritance/inheritance.py b/slither/printers/inheritance/inheritance.py index 3d8c0ad63..d7b4a6b11 100644 --- a/slither/printers/inheritance/inheritance.py +++ b/slither/printers/inheritance/inheritance.py @@ -10,7 +10,7 @@ from slither.utils.colors import blue, green class PrinterInheritance(AbstractPrinter): ARGUMENT = 'inheritance' - HELP = 'the inheritance relation between contracts' + HELP = 'Print the inheritance relations between contracts' def _get_child_contracts(self, base): # Generate function to get all child contracts of a base contract diff --git a/slither/printers/inheritance/inheritance_graph.py b/slither/printers/inheritance/inheritance_graph.py index 680bb8ed8..f76e9fb07 100644 --- a/slither/printers/inheritance/inheritance_graph.py +++ b/slither/printers/inheritance/inheritance_graph.py @@ -12,7 +12,7 @@ from slither.printers.abstract_printer import AbstractPrinter class PrinterInheritanceGraph(AbstractPrinter): ARGUMENT = 'inheritance-graph' - HELP = 'the inheritance graph' + HELP = 'Export the inheritance graph of each contract to a dot file' def __init__(self, slither, logger): super(PrinterInheritanceGraph, self).__init__(slither, logger) diff --git a/slither/printers/summary/contract.py b/slither/printers/summary/contract.py index bbcf1e9b3..51409ce91 100644 --- a/slither/printers/summary/contract.py +++ b/slither/printers/summary/contract.py @@ -8,7 +8,7 @@ from slither.utils.colors import blue, green, magenta class ContractSummary(AbstractPrinter): ARGUMENT = 'contract-summary' - HELP = 'a summary of the contract' + HELP = 'Print a summary of the contracts' def output(self, _filename): """ diff --git a/slither/printers/summary/function.py b/slither/printers/summary/function.py index 1fca36b68..a56552035 100644 --- a/slither/printers/summary/function.py +++ b/slither/printers/summary/function.py @@ -8,7 +8,7 @@ from slither.printers.abstract_printer import AbstractPrinter class FunctionSummary(AbstractPrinter): ARGUMENT = 'function-summary' - HELP = 'the summary of the functions' + HELP = 'Print a summary of the functions' @staticmethod def _convert(l): diff --git a/slither/printers/summary/slithir.py b/slither/printers/summary/slithir.py index 472bfbda6..755dfd169 100644 --- a/slither/printers/summary/slithir.py +++ b/slither/printers/summary/slithir.py @@ -8,7 +8,7 @@ from slither.utils.colors import blue, green, magenta class PrinterSlithIR(AbstractPrinter): ARGUMENT = 'slithir' - HELP = 'the slithIR' + HELP = 'Print the slithIR representation of the functions' def output(self, _filename): """ From 519a8698db4a627540c6d4da32c0142a86419b66 Mon Sep 17 00:00:00 2001 From: Josselin Date: Fri, 26 Oct 2018 17:09:08 +0100 Subject: [PATCH 2/5] Dont show the backdoor detector example in --list-detectors --- slither/utils/command_line.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/slither/utils/command_line.py b/slither/utils/command_line.py index 8ef40df9f..7233b541e 100644 --- a/slither/utils/command_line.py +++ b/slither/utils/command_line.py @@ -43,6 +43,9 @@ def output_detectors(detector_classes): detectors_list = [] for detector in detector_classes: argument = detector.ARGUMENT + # dont show the backdoor example + if argument == 'backdoor': + continue help_info = detector.HELP impact = detector.IMPACT confidence = classification_txt[detector.CONFIDENCE] From 452811e1ee79ce7af6f4dac2f23d66cdb1f9bf2b Mon Sep 17 00:00:00 2001 From: Josselin Date: Fri, 26 Oct 2018 17:17:29 +0100 Subject: [PATCH 3/5] ExternalFunction: exclude constructor --- slither/detectors/functions/external_function.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slither/detectors/functions/external_function.py b/slither/detectors/functions/external_function.py index d1b08a417..9cb19909b 100644 --- a/slither/detectors/functions/external_function.py +++ b/slither/detectors/functions/external_function.py @@ -54,7 +54,8 @@ class ExternalFunction(AbstractDetector): public_function_calls.extend(func_list) for func in [f for f in contract.functions if f.visibility == 'public' and\ - not f in public_function_calls]: + not f in public_function_calls and\ + not f.is_constructor]: func_name = func.name txt = "Public function in {} Contract: {}, Function: {} should be declared external" info = txt.format(self.filename, From 517a73ca33c824278ea915842486b097cace8f60 Mon Sep 17 00:00:00 2001 From: Josselin Date: Fri, 26 Oct 2018 17:34:52 +0100 Subject: [PATCH 4/5] Uninitialized state variable: remove var init at declaration --- slither/detectors/variables/uninitialized_state_variables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slither/detectors/variables/uninitialized_state_variables.py b/slither/detectors/variables/uninitialized_state_variables.py index 17d60e023..a7c6111ba 100644 --- a/slither/detectors/variables/uninitialized_state_variables.py +++ b/slither/detectors/variables/uninitialized_state_variables.py @@ -48,7 +48,7 @@ class UninitializedStateVarsDetection(AbstractDetector): def detect_uninitialized(self, contract): written_variables = self.written_variables(contract) return [(variable, contract.get_functions_reading_from_variable(variable)) - for variable in contract.state_variables if variable not in written_variables] + for variable in contract.state_variables if variable not in written_variables and not variable.expression] def detect(self): """ Detect uninitialized state variables From 12d0013095f8a49f7b13e7c9e31249d6fdaf37d0 Mon Sep 17 00:00:00 2001 From: Josselin Date: Fri, 26 Oct 2018 18:41:33 +0100 Subject: [PATCH 5/5] UninitializedStateVarsDetection: dont report unused variables SlithIr Printer: printer modifiers IRs SlithIR: fix missing condition conversion --- .../variables/uninitialized_state_variables.py | 12 +++++++++++- slither/printers/summary/slithir.py | 10 ++++++++++ slither/slithir/convert.py | 6 ++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/slither/detectors/variables/uninitialized_state_variables.py b/slither/detectors/variables/uninitialized_state_variables.py index a7c6111ba..427e3ad4a 100644 --- a/slither/detectors/variables/uninitialized_state_variables.py +++ b/slither/detectors/variables/uninitialized_state_variables.py @@ -45,10 +45,20 @@ class UninitializedStateVarsDetection(AbstractDetector): return ret + @staticmethod + def read_variables(contract): + ret = [] + for f in contract.all_functions_called + contract.modifiers: + ret += f.state_variables_read + return ret + def detect_uninitialized(self, contract): written_variables = self.written_variables(contract) + read_variables = self.read_variables(contract) return [(variable, contract.get_functions_reading_from_variable(variable)) - for variable in contract.state_variables if variable not in written_variables and not variable.expression] + for variable in contract.state_variables if variable not in written_variables and\ + not variable.expression and\ + variable in read_variables] def detect(self): """ Detect uninitialized state variables diff --git a/slither/printers/summary/slithir.py b/slither/printers/summary/slithir.py index 755dfd169..d48d3bf87 100644 --- a/slither/printers/summary/slithir.py +++ b/slither/printers/summary/slithir.py @@ -29,4 +29,14 @@ class PrinterSlithIR(AbstractPrinter): print('\t\tIRs:') for ir in node.irs: print('\t\t\t{}'.format(ir)) + for modifier in contract.modifiers: + if modifier.contract == contract: + print('\tModifier {}'.format(modifier.full_name)) + for node in modifier.nodes: + print(node) + if node.expression: + print('\t\tExpression: {}'.format(node.expression)) + print('\t\tIRs:') + for ir in node.irs: + print('\t\t\t{}'.format(ir)) self.info(txt) diff --git a/slither/slithir/convert.py b/slither/slithir/convert.py index 8e90c256c..ecffadfdd 100644 --- a/slither/slithir/convert.py +++ b/slither/slithir/convert.py @@ -636,6 +636,12 @@ def convert_expression(expression, node): if isinstance(expression, Identifier) and node.type == NodeType.RETURN: result = [Return(expression.value)] return result + if isinstance(expression, Literal) and node.type in [NodeType.IF, NodeType.IFLOOP]: + result = [Condition(Constant(expression.value))] + return result + if isinstance(expression, Identifier) and node.type in [NodeType.IF, NodeType.IFLOOP]: + result = [Condition(expression.value)] + return result visitor = ExpressionToSlithIR(expression) result = visitor.result()