Merge pull request #84 from trailofbits/dev-refactor-json

Refactor json output
pull/86/head
Feist Josselin 6 years ago committed by GitHub
commit 6322e201f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      scripts/tests_generate_expected_json.sh
  2. 6
      scripts/travis_test.sh
  3. 34
      slither/detectors/abstract_detector.py
  4. 30
      slither/detectors/attributes/const_functions.py
  5. 10
      slither/detectors/attributes/constant_pragma.py
  6. 9
      slither/detectors/attributes/locked_ether.py
  7. 9
      slither/detectors/attributes/old_solc.py
  8. 12
      slither/detectors/examples/backdoor.py
  9. 12
      slither/detectors/functions/arbitrary_send.py
  10. 32
      slither/detectors/functions/complex_function.py
  11. 9
      slither/detectors/functions/external_function.py
  12. 8
      slither/detectors/functions/suicidal.py
  13. 111
      slither/detectors/naming_convention/naming_convention.py
  14. 15
      slither/detectors/operations/low_level_calls.py
  15. 10
      slither/detectors/operations/unused_return_values.py
  16. 35
      slither/detectors/reentrancy/reentrancy.py
  17. 16
      slither/detectors/statements/assembly.py
  18. 16
      slither/detectors/statements/controlled_delegatecall.py
  19. 11
      slither/detectors/statements/tx_origin.py
  20. 14
      slither/detectors/variables/possible_const_state_variables.py
  21. 17
      slither/detectors/variables/uninitialized_local_variables.py
  22. 14
      slither/detectors/variables/uninitialized_state_variables.py
  23. 14
      slither/detectors/variables/uninitialized_storage_variables.py
  24. 11
      slither/detectors/variables/unused_state_variables.py
  25. 68
      tests/expected_json/arbitrary_send.arbitrary-send.json
  26. 26
      tests/expected_json/backdoor.backdoor.json
  27. 28
      tests/expected_json/backdoor.suicidal.json
  28. 120
      tests/expected_json/const_state_variables.constable-states.json
  29. 98
      tests/expected_json/constant.constant-function.json
  30. 60
      tests/expected_json/controlled_delegatecall.controlled-delegatecall.json
  31. 122
      tests/expected_json/external_function.external-function.json
  32. 40
      tests/expected_json/inline_assembly_contract.assembly.json
  33. 82
      tests/expected_json/inline_assembly_library.assembly.json
  34. 29
      tests/expected_json/locked_ether.locked-ether.json
  35. 31
      tests/expected_json/low_level_calls.low-level-calls.json
  36. 393
      tests/expected_json/naming_convention.naming-convention.json
  37. 20
      tests/expected_json/old_solc.sol.json.solc-version.json
  38. 40
      tests/expected_json/pragma.0.4.24.pragma.json
  39. 76
      tests/expected_json/reentrancy.reentrancy.json
  40. 64
      tests/expected_json/tx_origin.tx-origin.json
  41. 168
      tests/expected_json/uninitialized.uninitialized-state.json
  42. 32
      tests/expected_json/uninitialized_local_variable.uninitialized-local.json
  43. 32
      tests/expected_json/uninitialized_storage_pointer.uninitialized-storage.json
  44. 57
      tests/expected_json/unused_return.unused-return.json
  45. 26
      tests/expected_json/unused_state.unused-state.json

@ -38,5 +38,6 @@ generate_expected_json(){
#generate_expected_json tests/naming_convention.sol "naming-convention"
#generate_expected_json tests/uninitialized_local_variable.sol "uninitialized-local"
#generate_expected_json tests/controlled_delegatecall.sol "controlled-delegatecall"
generate_expected_json tests/constant.sol "constant-function"
#generate_expected_json tests/constant.sol "constant-function"
#generate_expected_json tests/unused_return.sol "unused-return"

@ -12,6 +12,11 @@ test_slither(){
# run slither detector on input file and save output as json
slither "$1" --disable-solc-warnings --detect "$2" --json "$DIR/tmp-test.json"
if [ $? -eq 255 ]
then
echo "Slither crashed"
exit -1
fi
# convert json file to pretty print and write to destination folder
python "$DIR/pretty_print_and_sort_json.py" "$DIR/tmp-test.json" "$actual"
@ -87,7 +92,6 @@ test_slither tests/naming_convention.sol "naming-convention"
#test_slither tests/complex_func.sol "complex-function"
test_slither tests/controlled_delegatecall.sol "controlled-delegatecall"
test_slither tests/constant.sol "constant-function"
# TODO: update to the new testing framework
test_slither tests/unused_return.sol "unused-return"

@ -79,3 +79,37 @@ class AbstractDetector(metaclass=abc.ABCMeta):
@property
def color(self):
return classification_colors[self.IMPACT]
def generate_json_result(self):
return {'check': self.ARGUMENT}
@staticmethod
def add_variable_to_json(variable, d):
assert 'variable' not in d
d['variable'] = {'name': variable.name, 'source_mapping': variable.source_mapping}
@staticmethod
def add_variables_to_json(variables, d):
assert 'variables' not in d
d['variables'] = [{'name': variable.name,
'source_mapping': variable.source_mapping}
for variable in variables]
@staticmethod
def add_function_to_json(function, d):
assert 'function' not in d
d['function'] = {'name': function.name, 'source_mapping': function.source_mapping}
@staticmethod
def add_functions_to_json(functions, d):
assert 'functions' not in d
d['functions'] = [{'name': function.name,
'source_mapping': function.source_mapping}
for function in functions]
@staticmethod
def add_nodes_to_json(nodes, d):
assert 'expressions' not in d
d['expressions'] = [{'expression': str(node.expression),
'source_mapping': node.source_mapping}
for node in nodes]

@ -35,14 +35,11 @@ class ConstantFunctions(AbstractDetector):
info = '{}.{} ({}) is declared {} but contains assembly code\n'
info = info.format(f.contract.name, f.name, f.source_mapping_str, attr)
self.log(info)
sourceMapping = [f.source_mapping]
results.append({'vuln': 'ConstFunction',
'sourceMapping': sourceMapping,
'filename': self.filename,
'contract': c.name,
'function_name': f.name,
'contains_assembly': True,
'varsWritten': []})
json = self.generate_json_result()
self.add_function_to_json(f, json)
json['variables'] = []
json['contains_assembly'] = True
results.append(json)
variables_written = f.all_state_variables_written()
if variables_written:
@ -51,13 +48,14 @@ class ConstantFunctions(AbstractDetector):
info = info.format(f.contract.name, f.name, f.source_mapping_str, attr)
for variable_written in variables_written:
info += '\t- {}.{}\n'.format(variable_written.contract.name,
variable_written.name)
variable_written.name)
self.log(info)
results.append({'vuln': 'ConstFunction',
'sourceMapping': f.source_mapping,
'filename': self.filename,
'contract': c.name,
'function_name': f.name,
'contains_assembly': False,
'varsWritten': [str(x) for x in variables_written]})
json = self.generate_json_result()
self.add_function_to_json(f, json)
self.add_variables_to_json(variables_written, json)
json['contains_assembly'] = False
results.append(json)
return results

@ -30,10 +30,10 @@ class ConstantPragma(AbstractDetector):
info += "\t- {} declares {}\n".format(p.source_mapping_str, str(p))
self.log(info)
source = [p.source_mapping for p in pragma]
results.append({'vuln': 'ConstantPragma',
'versions': versions,
'sourceMapping': source})
json = self.generate_json_result()
# follow the same format than add_nodes_to_json
json['expressions'] = [{'expression': p.version,
'source_mapping': p.source_mapping} for p in pragma]
results.append(json)
return results

@ -56,11 +56,8 @@ class LockedEther(AbstractDetector):
[f.name for f in funcs_payable])
self.log(info)
source = [f.source_mapping for f in funcs_payable]
results.append({'vuln': 'LockedEther',
'functions_payable' : [f.name for f in funcs_payable],
'contract': contract.name,
'sourceMapping': source})
json = self.generate_json_result()
self.add_functions_to_json(funcs_payable, json)
results.append(json)
return results

@ -33,9 +33,10 @@ class OldSolc(AbstractDetector):
info += "\t- {} declares {}\n".format(p.source_mapping_str, str(p))
self.log(info)
source = [p.source_mapping for p in pragma]
results.append({'vuln': 'OldPragma',
'pragma': [p.version for p in old_pragma],
'sourceMapping': source})
json = self.generate_json_result()
# follow the same format than add_nodes_to_json
json['expressions'] = [{'expression': p.version,
'source_mapping': p.source_mapping} for p in old_pragma]
results.append(json)
return results

@ -12,7 +12,7 @@ class Backdoor(AbstractDetector):
CONFIDENCE = DetectorClassification.HIGH
def detect(self):
ret = []
results = []
for contract in self.slither.contracts_derived:
# Check if a function has 'backdoor' in its name
@ -23,8 +23,10 @@ class Backdoor(AbstractDetector):
info = info.format(contract.name, f.name, f.source_mapping_str)
# Print the info
self.log(info)
# Add the result in ret
source = f.source_mapping
ret.append({'vuln': 'backdoor', 'contract': contract.name, 'sourceMapping' : source})
# Add the result in result
json = self.generate_json_result()
self.add_function_to_json(f, json)
results.append(json)
return ret
return results

@ -100,7 +100,6 @@ class ArbitrarySend(AbstractDetector):
for c in self.contracts:
arbitrary_send = self.detect_arbitrary_send(c)
for (func, nodes) in arbitrary_send:
calls_str = [str(node.expression) for node in nodes]
info = "{}.{} ({}) sends eth to arbirary user\n"
info = info.format(func.contract.name,
@ -112,13 +111,10 @@ class ArbitrarySend(AbstractDetector):
self.log(info)
source_mapping = [node.source_mapping for node in nodes]
results.append({'vuln': 'ArbitrarySend',
'sourceMapping': source_mapping,
'filename': self.filename,
'contract': func.contract.name,
'function': func.name,
'calls': calls_str})
json = self.generate_json_result()
self.add_function_to_json(func, json)
self.add_nodes_to_json(nodes, json)
results.append(json)
return results

@ -3,7 +3,7 @@ from slither.core.declarations.solidity_variables import (SolidityFunction,
from slither.detectors.abstract_detector import (AbstractDetector,
DetectorClassification)
from slither.slithir.operations import (HighLevelCall,
LowLevelCall,
LowLevelCall,
LibraryCall)
from slither.utils.code_complexity import compute_cyclomatic_complexity
@ -33,7 +33,7 @@ class ComplexFunction(AbstractDetector):
@staticmethod
def detect_complex_func(func):
def detect_complex_func(func):
"""Detect the cyclomatic complexity of the contract functions
shouldn't be greater than 7
"""
@ -60,7 +60,7 @@ class ComplexFunction(AbstractDetector):
"func": func,
"cause": ComplexFunction.CAUSE_EXTERNAL_CALL
})
"""Checks the number of the state variables written
shouldn't be greater than 10
"""
@ -74,13 +74,13 @@ class ComplexFunction(AbstractDetector):
def detect_complex(self, contract):
ret = []
for func in contract.all_functions_called:
result = self.detect_complex_func(func)
ret.extend(result)
return ret
def detect(self):
results = []
@ -89,9 +89,8 @@ class ComplexFunction(AbstractDetector):
for issue in issues:
func, cause = issue.values()
func_name = func.name
txt = "Complex function in {}\n\t- {}.{} ({})\n"
txt = "{}.{} ({}) is a complex function:\n"
if cause == self.CAUSE_EXTERNAL_CALL:
txt += "\t- Reason: High number of external calls"
@ -100,17 +99,18 @@ class ComplexFunction(AbstractDetector):
if cause == self.CAUSE_STATE_VARS:
txt += "\t- Reason: High number of modified state variables"
info = txt.format(self.filename,
contract.name,
func_name,
func.source_mapping_str)
info = txt.format(func.contract.name,
func.name,
func.source_mapping_str)
info = info + "\n"
self.log(info)
results.append({'vuln': 'ComplexFunc',
'sourceMapping': func.source_mapping,
'filename': self.filename,
'contract': contract.name,
'function': func_name})
json = self.generate_json_result()
self.add_function_to_json(func, json)
json['high_number_of_external_calls'] = cause == self.CAUSE_EXTERNAL_CALL
json['high_number_of_branches'] = cause == self.CAUSE_CYCLOMATIC
json['high_number_of_state_variables'] = cause == self.CAUSE_STATE_VARS
results.append(json)
return results

@ -64,11 +64,10 @@ class ExternalFunction(AbstractDetector):
func.name,
func.source_mapping_str)
all_info += info
results.append({'vuln': 'ExternalFunc',
'sourceMapping': func.source_mapping,
'filename': self.filename,
'contract': func.contract.name,
'function': func.name})
json = self.generate_json_result()
self.add_function_to_json(func, json)
results.append(json)
if all_info != '':
self.log(all_info)
return results

@ -64,10 +64,8 @@ class Suicidal(AbstractDetector):
self.log(info)
results.append({'vuln': 'SuicidalFunc',
'sourceMapping': func.source_mapping,
'filename': self.filename,
'contract': c.name,
'function': func.name})
json = self.generate_json_result()
self.add_function_to_json(func, json)
results.append(json)
return results

@ -48,13 +48,15 @@ class NamingConvention(AbstractDetector):
for contract in self.contracts:
if not self.is_cap_words(contract.name):
info = "Contract '{}' ({}) is not in CapWords\n".format(contract.name, contract.source_mapping_str)
info = "Contract '{}' ({}) is not in CapWords\n".format(contract.name,
contract.source_mapping_str)
all_info += info
results.append({'vuln': 'NamingConvention',
'filename': self.filename,
'contract': contract.name,
'sourceMapping': contract.source_mapping})
results.append({'check': self.ARGUMENT,
'type': 'contract',
'convention':'CapWords',
'name':{'name': contract.name,
'source_mapping': contract.source_mapping}})
for struct in contract.structures:
if struct.contract != contract:
@ -65,11 +67,12 @@ class NamingConvention(AbstractDetector):
info = info.format(struct.contract.name, struct.name, struct.source_mapping_str)
all_info += info
results.append({'vuln': 'NamingConvention',
'filename': self.filename,
'contract': contract.name,
'struct': struct.name,
'sourceMapping': struct.source_mapping})
results.append({'check': self.ARGUMENT,
'type': 'structure',
'convention':'CapWords',
'name':{'name': struct.name,
'source_mapping': struct.source_mapping}})
for event in contract.events:
if event.contract != contract:
@ -80,11 +83,12 @@ class NamingConvention(AbstractDetector):
info = info.format(event.contract.name, event.name, event.source_mapping_str)
all_info += info
results.append({'vuln': 'NamingConvention',
'filename': self.filename,
'contract': contract.name,
'event': event.name,
'sourceMapping': event.source_mapping})
results.append({'check': self.ARGUMENT,
'type': 'event',
'convention':'CapWords',
'name':{'name': event.name,
'source_mapping': event.source_mapping}})
for func in contract.functions:
if func.contract != contract:
@ -95,11 +99,11 @@ class NamingConvention(AbstractDetector):
info = info.format(func.contract.name, func.name, func.source_mapping_str)
all_info += info
results.append({'vuln': 'NamingConvention',
'filename': self.filename,
'contract': contract.name,
'function': func.name,
'sourceMapping': func.source_mapping})
results.append({'check': self.ARGUMENT,
'type': 'function',
'convention':'mixedCase',
'name':{'name': func.name,
'source_mapping': func.source_mapping}})
for argument in func.parameters:
if argument in func.variables_read_or_written:
@ -114,13 +118,11 @@ class NamingConvention(AbstractDetector):
argument.source_mapping_str)
all_info += info
results.append({'vuln': 'NamingConvention',
'filename': self.filename,
'contract': contract.name,
'function': func.name,
'argument': argument.name,
'sourceMapping': argument.source_mapping})
results.append({'check': self.ARGUMENT,
'type': 'parameter',
'convention':'mixedCase',
'name':{'name': argument.name,
'source_mapping': argument.source_mapping}})
for var in contract.state_variables:
if var.contract != contract:
@ -132,11 +134,11 @@ class NamingConvention(AbstractDetector):
info = info.format(var.contract.name, var.name, var.source_mapping_str)
all_info += info
results.append({'vuln': 'NamingConvention',
'filename': self.filename,
'contract': contract.name,
'constant': var.name,
'sourceMapping': var.source_mapping})
results.append({'check': self.ARGUMENT,
'type': 'variable',
'convention':'l_O_I_should_not_be_used',
'name':{'name': var.name,
'source_mapping': var.source_mapping}})
if var.is_constant is True:
# For ERC20 compatibility
@ -148,11 +150,11 @@ class NamingConvention(AbstractDetector):
info = info.format(var.contract.name, var.name, var.source_mapping_str)
all_info += info
results.append({'vuln': 'NamingConvention',
'filename': self.filename,
'contract': contract.name,
'constant': var.name,
'sourceMapping': var.source_mapping})
results.append({'check': self.ARGUMENT,
'type': 'variable_constant',
'convention':'UPPER_CASE_WITH_UNDERSCORES',
'name':{'name': var.name,
'source_mapping': var.source_mapping}})
else:
if var.visibility == 'private':
correct_naming = self.is_mixed_case_with_underscore(var.name)
@ -163,12 +165,11 @@ class NamingConvention(AbstractDetector):
info = info.format(var.contract.name, var.name, var.source_mapping_str)
all_info += info
results.append({'vuln': 'NamingConvention',
'filename': self.filename,
'contract': contract.name,
'variable': var.name,
'sourceMapping': var.source_mapping})
results.append({'check': self.ARGUMENT,
'type': 'variable',
'convention':'mixedCase',
'name':{'name': var.name,
'source_mapping': var.source_mapping}})
for enum in contract.enums:
if enum.contract != contract:
@ -179,11 +180,11 @@ class NamingConvention(AbstractDetector):
info = info.format(enum.contract.name, enum.name, enum.source_mapping_str)
all_info += info
results.append({'vuln': 'NamingConvention',
'filename': self.filename,
'contract': contract.name,
'enum': enum.name,
'sourceMapping': enum.source_mapping})
results.append({'check': self.ARGUMENT,
'type': 'enum',
'convention':'CapWords',
'name':{'name': enum.name,
'source_mapping': enum.source_mapping}})
for modifier in contract.modifiers:
if modifier.contract != contract:
@ -191,14 +192,16 @@ class NamingConvention(AbstractDetector):
if not self.is_mixed_case(modifier.name):
info = "Modifier '{}.{}' ({}) is not in mixedCase\n"
info = info.format(modifier.contract.name, modifier.name, modifier.source_mapping_str)
info = info.format(modifier.contract.name,
modifier.name,
modifier.source_mapping_str)
all_info += info
results.append({'vuln': 'NamingConvention',
'filename': self.filename,
'contract': contract.name,
'modifier': modifier.name,
'sourceMapping': modifier.source_mapping})
results.append({'check': self.ARGUMENT,
'type': 'modifier',
'convention':'mixedCase',
'name':{'name': modifier.name,
'source_mapping': modifier.source_mapping}})
if all_info != '':
self.log(all_info)

@ -45,17 +45,18 @@ class LowLevelCalls(AbstractDetector):
for c in self.contracts:
values = self.detect_low_level_calls(c)
for func, nodes in values:
info = "Low level call in {}.{} ({})\n"
info = "Low level call in {}.{} ({}):\n"
info = info.format(func.contract.name, func.name, func.source_mapping_str)
for node in nodes:
info += "\t-{} {}\n".format(str(node.expression), node.source_mapping_str)
all_info += info
sourceMapping = [n.source_mapping for n in nodes]
json = self.generate_json_result()
self.add_function_to_json(func, json)
self.add_nodes_to_json(nodes, json)
results.append(json)
results.append({'vuln': 'Low level call',
'sourceMapping': sourceMapping,
'filename': self.filename,
'contract': func.contract.name,
'function': func.name})
if all_info != '':
self.log(all_info)

@ -60,11 +60,9 @@ class UnusedReturnValues(AbstractDetector):
info += "\t-{} ({})\n".format(node.expression, node.source_mapping_str)
self.log(info)
sourceMapping = [v.source_mapping for v in unused_return]
json = self.generate_json_result()
self.add_function_to_json(f, json)
self.add_nodes_to_json(unused_return, json)
results.append(json)
results.append({'vuln': 'UnusedReturn',
'sourceMapping': sourceMapping,
'filename': self.filename,
'contract': c.name,
'expressions':[str(n.expression) for n in unused_return]})
return results

@ -128,7 +128,7 @@ class Reentrancy(AbstractDetector):
if isinstance(internal_call, Function):
state_vars_written += internal_call.all_state_variables_written()
read_then_written = [(v, node.source_mapping_str) for v in state_vars_written if v in node.context[self.key]['read']]
read_then_written = [(v, node) for v in state_vars_written if v in node.context[self.key]['read']]
node.context[self.key]['read'] = list(set(node.context[self.key]['read'] + node.state_variables_read))
# If a state variables was read and is then written, there is a dangerous call and
@ -194,21 +194,26 @@ class Reentrancy(AbstractDetector):
for call_info in send_eth:
info += '\t- {} ({})\n'.format(call_info.expression, call_info.source_mapping_str)
info += '\tState variables written after the call(s):\n'
for (v, mapping) in varsWritten:
info += '\t- {} ({})\n'.format(v, mapping)
for (v, node) in varsWritten:
info += '\t- {} ({})\n'.format(v, node.source_mapping_str)
self.log(info)
source = [v.source_mapping for (v,_) in varsWritten]
source += [node.source_mapping for node in calls]
source += [node.source_mapping for node in send_eth]
results.append({'vuln': 'Reentrancy',
'sourceMapping': source,
'filename': self.filename,
'contract': func.contract.name,
'function': func.name,
'calls': [str(x.expression) for x in calls],
'send_eth': [str(x.expression) for x in send_eth],
'varsWritten': [str(x) for (x,_) in varsWritten]})
sending_eth_json = []
if calls != send_eth:
sending_eth_json = [{'expression': str(call_info.expression),
'source_mapping': call_info.source_mapping}
for call_info in calls]
json = self.generate_json_result()
self.add_function_to_json(func, json)
json['external_calls'] = [{'expression': str(call_info.expression),
'source_mapping': call_info.source_mapping}
for call_info in calls]
json['external_calls_sending_eth'] = sending_eth_json
json['variables_written'] = [{'name': v.name,
'expression': str(node.expression),
'source_mapping': node.source_mapping}
for (v, node) in varsWritten]
results.append(json)
return results

@ -49,15 +49,17 @@ class Assembly(AbstractDetector):
for func, nodes in values:
info = "{}.{} uses assembly ({})\n"
info = info.format(func.contract.name, func.name, func.source_mapping_str)
all_info += info
sourceMapping = [n.source_mapping for n in nodes]
for node in nodes:
info += "\t- {}\n".format(node.source_mapping_str)
all_info += info
results.append({'vuln': 'Assembly',
'sourceMapping': sourceMapping,
'filename': self.filename,
'contract': func.contract.name,
'function': func.name})
json = self.generate_json_result()
self.add_function_to_json(func, json)
json['assembly'] = [{'source_mapping': node.source_mapping}
for node in nodes]
results.append(json)
if all_info != '':
self.log(all_info)

@ -23,7 +23,7 @@ class ControlledDelegateCall(AbstractDetector):
return ret
def detect(self):
ret = []
results = []
for contract in self.slither.contracts:
for f in contract.functions:
@ -34,12 +34,12 @@ class ControlledDelegateCall(AbstractDetector):
info = '{}.{} ({}) uses delegatecall to a input-controlled function id\n'
info = info.format(contract.name, f.name, f.source_mapping_str)
for node in nodes:
info += '\t{} ({})'.format(node.expression, node.source_mapping_str)
info += '\t{} ({})\n'.format(node.expression, node.source_mapping_str)
self.log(info)
source = [f.source_mapping] + [node.source_mapping for node in nodes]
ret.append({'vuln': 'controlled_delegatecall',
'contract': contract.name,
'function':f.name,
'sourceMapping' : source})
return ret
json = self.generate_json_result()
self.add_function_to_json(f, json)
self.add_nodes_to_json(nodes, json)
results.append(json)
return results

@ -58,12 +58,9 @@ class TxOrigin(AbstractDetector):
self.log(info)
sourceMapping = [n.source_mapping for n in nodes]
results.append({'vuln': 'TxOrigin',
'sourceMapping': sourceMapping,
'filename': self.filename,
'contract': func.contract.name,
'function': func.name})
json = self.generate_json_result()
self.add_function_to_json(func, json)
self.add_nodes_to_json(nodes, json)
results.append(json)
return results

@ -66,17 +66,15 @@ class ConstCandidateStateVars(AbstractDetector):
variables_by_contract[state_var.contract.name].append(state_var)
for contract, variables in variables_by_contract.items():
variable_names = [v.name for v in variables]
for v in variables:
all_info += "{}.{} should be constant ({})\n".format(contract, v.name, v.source_mapping_str)
all_info += "{}.{} should be constant ({})\n".format(contract,
v.name,
v.source_mapping_str)
sourceMapping = [v.source_mapping for v in const_candidates]
json = self.generate_json_result()
self.add_variables_to_json(variables, json)
results.append(json)
results.append({'vuln': 'ConstStateVariableCandidates',
'sourceMapping': sourceMapping,
'filename': self.filename,
'contract': c.name,
'unusedVars': variable_names})
if all_info != '':
self.log(all_info)
return results

@ -86,17 +86,16 @@ class UninitializedLocalVars(AbstractDetector):
var_name = uninitialized_local_variable.name
info = "{} in {}.{} ({}) is a local variable never initialiazed\n"
info = info.format(var_name, function.contract.name, function.name, uninitialized_local_variable.source_mapping_str)
info = info.format(var_name,
function.contract.name,
function.name,
uninitialized_local_variable.source_mapping_str)
self.log(info)
source = [function.source_mapping, uninitialized_local_variable.source_mapping]
results.append({'vuln': 'UninitializedLocalVars',
'sourceMapping': source,
'filename': self.filename,
'contract': function.contract.name,
'function': function.name,
'variable': var_name})
json = self.generate_json_result()
self.add_variable_to_json(uninitialized_local_variable, json)
self.add_function_to_json(function, json)
results.append(json)
return results

@ -75,7 +75,9 @@ class UninitializedStateVarsDetection(AbstractDetector):
ret = self.detect_uninitialized(c)
for variable, functions in ret:
info = "{}.{} ({}) is never initialized. It is used in:\n"
info = info.format(variable.contract.name, variable.name, variable.source_mapping_str)
info = info.format(variable.contract.name,
variable.name,
variable.source_mapping_str)
for f in functions:
info += "\t- {} ({})\n".format(f.name, f.source_mapping_str)
self.log(info)
@ -83,11 +85,9 @@ class UninitializedStateVarsDetection(AbstractDetector):
source = [variable.source_mapping]
source += [f.source_mapping for f in functions]
results.append({'vuln': 'UninitializedStateVars',
'sourceMapping': source,
'filename': self.filename,
'contract': c.name,
'functions': [str(f) for f in functions],
'variable': str(variable)})
json = self.generate_json_result()
self.add_variable_to_json(variable, json)
self.add_functions_to_json(functions, json)
results.append(json)
return results

@ -88,13 +88,11 @@ class UninitializedStorageVars(AbstractDetector):
self.log(info)
source = [function.source_mapping, uninitialized_storage_variable.source_mapping]
results.append({'vuln': 'UninitializedStorageVars',
'sourceMapping': source,
'filename': self.filename,
'contract': function.contract.name,
'function': function.name,
'variable': var_name})
json = self.generate_json_result()
self.add_variable_to_json(uninitialized_storage_variable, json)
self.add_function_to_json(function, json)
results.append(json)
return results

@ -36,7 +36,6 @@ class UnusedStateVars(AbstractDetector):
for c in self.slither.contracts_derived:
unusedVars = self.detect_unused(c)
if unusedVars:
unusedVarsName = [v.name for v in unusedVars]
info = ''
for var in unusedVars:
info += "{}.{} ({}) is never used in {}\n".format(var.contract.name,
@ -45,13 +44,11 @@ class UnusedStateVars(AbstractDetector):
c.name)
all_info += info
sourceMapping = [v.source_mapping for v in unusedVars]
results.append({'vuln': 'unusedStateVars',
'sourceMapping': sourceMapping,
'filename': self.filename,
'contract': c.name,
'unusedVars': unusedVarsName})
json = self.generate_json_result()
self.add_variables_to_json(unusedVars, json)
results.append(json)
if all_info != '':
self.log(all_info)
return results

@ -1,40 +1,60 @@
[
{
"calls": [
"msg.sender.send(this.balance)"
],
"contract": "Test",
"filename": "tests/arbitrary_send.sol",
"function": "direct",
"sourceMapping": [
"check": "arbitrary-send",
"expressions": [
{
"expression": "msg.sender.send(this.balance)",
"source_mapping": {
"filename": "tests/arbitrary_send.sol",
"length": 29,
"lines": [
12
],
"start": 174
}
}
],
"function": {
"name": "direct",
"source_mapping": {
"filename": "tests/arbitrary_send.sol",
"length": 29,
"length": 63,
"lines": [
12
11,
12,
13
],
"start": 174
"start": 147
}
],
"vuln": "ArbitrarySend"
}
},
{
"calls": [
"destination.send(this.balance)"
],
"contract": "Test",
"filename": "tests/arbitrary_send.sol",
"function": "indirect",
"sourceMapping": [
"check": "arbitrary-send",
"expressions": [
{
"expression": "destination.send(this.balance)",
"source_mapping": {
"filename": "tests/arbitrary_send.sol",
"length": 30,
"lines": [
20
],
"start": 307
}
}
],
"function": {
"name": "indirect",
"source_mapping": {
"filename": "tests/arbitrary_send.sol",
"length": 30,
"length": 66,
"lines": [
20
19,
20,
21
],
"start": 307
"start": 278
}
],
"vuln": "ArbitrarySend"
}
}
]

@ -1,16 +1,18 @@
[
{
"contract": "C",
"sourceMapping": {
"filename": "tests/backdoor.sol",
"length": 74,
"lines": [
5,
6,
7
],
"start": 43
},
"vuln": "backdoor"
"check": "backdoor",
"function": {
"name": "i_am_a_backdoor",
"source_mapping": {
"filename": "tests/backdoor.sol",
"length": 74,
"lines": [
5,
6,
7
],
"start": 43
}
}
}
]

@ -1,18 +1,18 @@
[
{
"contract": "C",
"filename": "tests/backdoor.sol",
"function": "i_am_a_backdoor",
"sourceMapping": {
"filename": "tests/backdoor.sol",
"length": 74,
"lines": [
5,
6,
7
],
"start": 43
},
"vuln": "SuicidalFunc"
"check": "suicidal",
"function": {
"name": "i_am_a_backdoor",
"source_mapping": {
"filename": "tests/backdoor.sol",
"length": 74,
"lines": [
5,
6,
7
],
"start": 43
}
}
}
]

@ -1,88 +1,56 @@
[
{
"contract": "B",
"filename": "tests/const_state_variables.sol",
"sourceMapping": [
{
"filename": "tests/const_state_variables.sol",
"length": 20,
"lines": [
10
],
"start": 235
},
{
"filename": "tests/const_state_variables.sol",
"length": 20,
"lines": [
14
],
"start": 331
"check": "constable-states",
"variables": [
{
"name": "myFriendsAddress",
"source_mapping": {
"filename": "tests/const_state_variables.sol",
"length": 76,
"lines": [
7
],
"start": 130
}
},
{
"filename": "tests/const_state_variables.sol",
"length": 76,
"lines": [
7
],
"start": 130
"name": "test",
"source_mapping": {
"filename": "tests/const_state_variables.sol",
"length": 20,
"lines": [
10
],
"start": 235
}
},
{
"filename": "tests/const_state_variables.sol",
"length": 76,
"lines": [
26
],
"start": 494
"name": "text2",
"source_mapping": {
"filename": "tests/const_state_variables.sol",
"length": 20,
"lines": [
14
],
"start": 331
}
}
],
"unusedVars": [
"myFriendsAddress",
"test",
"text2"
],
"vuln": "ConstStateVariableCandidates"
]
},
{
"contract": "B",
"filename": "tests/const_state_variables.sol",
"sourceMapping": [
{
"filename": "tests/const_state_variables.sol",
"length": 20,
"lines": [
10
],
"start": 235
},
{
"filename": "tests/const_state_variables.sol",
"length": 20,
"lines": [
14
],
"start": 331
},
{
"filename": "tests/const_state_variables.sol",
"length": 76,
"lines": [
7
],
"start": 130
},
{
"filename": "tests/const_state_variables.sol",
"length": 76,
"lines": [
26
],
"start": 494
"check": "constable-states",
"variables": [
{
"name": "mySistersAddress",
"source_mapping": {
"filename": "tests/const_state_variables.sol",
"length": 76,
"lines": [
26
],
"start": 494
}
}
],
"unusedVars": [
"mySistersAddress"
],
"vuln": "ConstStateVariableCandidates"
]
}
]

@ -1,51 +1,70 @@
[
{
"check": "constant-function",
"contains_assembly": false,
"contract": "Constant",
"filename": "tests/constant.sol",
"function_name": "test_constant_bug",
"sourceMapping": {
"filename": "tests/constant.sol",
"length": 66,
"lines": [
9,
10,
11
],
"start": 113
"function": {
"name": "test_view_bug",
"source_mapping": {
"filename": "tests/constant.sol",
"length": 58,
"lines": [
5,
6,
7
],
"start": 45
}
},
"varsWritten": [
"a"
],
"vuln": "ConstFunction"
"variables": [
{
"name": "a",
"source_mapping": {
"filename": "tests/constant.sol",
"length": 6,
"lines": [
3
],
"start": 28
}
}
]
},
{
"check": "constant-function",
"contains_assembly": false,
"contract": "Constant",
"filename": "tests/constant.sol",
"function_name": "test_view_bug",
"sourceMapping": {
"filename": "tests/constant.sol",
"length": 58,
"lines": [
5,
6,
7
],
"start": 45
"function": {
"name": "test_constant_bug",
"source_mapping": {
"filename": "tests/constant.sol",
"length": 66,
"lines": [
9,
10,
11
],
"start": 113
}
},
"varsWritten": [
"a"
],
"vuln": "ConstFunction"
"variables": [
{
"name": "a",
"source_mapping": {
"filename": "tests/constant.sol",
"length": 6,
"lines": [
3
],
"start": 28
}
}
]
},
{
"check": "constant-function",
"contains_assembly": true,
"contract": "Constant",
"filename": "tests/constant.sol",
"function_name": "test_assembly_bug",
"sourceMapping": [
{
"function": {
"name": "test_assembly_bug",
"source_mapping": {
"filename": "tests/constant.sol",
"length": 66,
"lines": [
@ -55,8 +74,7 @@
],
"start": 324
}
],
"varsWritten": [],
"vuln": "ConstFunction"
},
"variables": []
}
]

@ -1,17 +1,22 @@
[
{
"contract": "C",
"function": "bad_delegate_call",
"sourceMapping": [
{
"filename": "tests/controlled_delegatecall.sol",
"length": 27,
"lines": [
10
],
"start": 178
},
"check": "controlled-delegatecall",
"expressions": [
{
"expression": "addr_bad.delegatecall(data)",
"source_mapping": {
"filename": "tests/controlled_delegatecall.sol",
"length": 27,
"lines": [
10
],
"start": 178
}
}
],
"function": {
"name": "bad_delegate_call",
"source_mapping": {
"filename": "tests/controlled_delegatecall.sol",
"length": 120,
"lines": [
@ -22,22 +27,26 @@
],
"start": 92
}
],
"vuln": "controlled_delegatecall"
}
},
{
"contract": "C",
"function": "bad_delegate_call2",
"sourceMapping": [
{
"filename": "tests/controlled_delegatecall.sol",
"length": 36,
"lines": [
19
],
"start": 356
},
"check": "controlled-delegatecall",
"expressions": [
{
"expression": "addr_bad.delegatecall(func_id,data)",
"source_mapping": {
"filename": "tests/controlled_delegatecall.sol",
"length": 36,
"lines": [
19
],
"start": 356
}
}
],
"function": {
"name": "bad_delegate_call2",
"source_mapping": {
"filename": "tests/controlled_delegatecall.sol",
"length": 92,
"lines": [
@ -47,7 +56,6 @@
],
"start": 307
}
],
"vuln": "controlled_delegatecall"
}
}
]

@ -1,71 +1,71 @@
[
{
"contract": "ContractWithFunctionNotCalled",
"filename": "tests/external_function.sol",
"function": "funcNotCalled",
"sourceMapping": {
"filename": "tests/external_function.sol",
"length": 40,
"lines": [
21,
22,
23
],
"start": 351
},
"vuln": "ExternalFunc"
"check": "external-function",
"function": {
"name": "funcNotCalled3",
"source_mapping": {
"filename": "tests/external_function.sol",
"length": 41,
"lines": [
13,
14,
15
],
"start": 257
}
}
},
{
"contract": "ContractWithFunctionNotCalled",
"filename": "tests/external_function.sol",
"function": "funcNotCalled2",
"sourceMapping": {
"filename": "tests/external_function.sol",
"length": 41,
"lines": [
17,
18,
19
],
"start": 304
},
"vuln": "ExternalFunc"
"check": "external-function",
"function": {
"name": "funcNotCalled2",
"source_mapping": {
"filename": "tests/external_function.sol",
"length": 41,
"lines": [
17,
18,
19
],
"start": 304
}
}
},
{
"contract": "ContractWithFunctionNotCalled",
"filename": "tests/external_function.sol",
"function": "funcNotCalled3",
"sourceMapping": {
"filename": "tests/external_function.sol",
"length": 41,
"lines": [
13,
14,
15
],
"start": 257
},
"vuln": "ExternalFunc"
"check": "external-function",
"function": {
"name": "funcNotCalled",
"source_mapping": {
"filename": "tests/external_function.sol",
"length": 40,
"lines": [
21,
22,
23
],
"start": 351
}
}
},
{
"contract": "ContractWithFunctionNotCalled2",
"filename": "tests/external_function.sol",
"function": "funcNotCalled",
"sourceMapping": {
"filename": "tests/external_function.sol",
"length": 304,
"lines": [
32,
33,
34,
35,
36,
37,
38,
39
],
"start": 552
},
"vuln": "ExternalFunc"
"check": "external-function",
"function": {
"name": "funcNotCalled",
"source_mapping": {
"filename": "tests/external_function.sol",
"length": 304,
"lines": [
32,
33,
34,
35,
36,
37,
38,
39
],
"start": 552
}
}
}
]

@ -1,13 +1,38 @@
[
{
"contract": "GetCode",
"filename": "tests/inline_assembly_contract.sol",
"function": "at",
"sourceMapping": [
"assembly": [
{
"source_mapping": {
"filename": "tests/inline_assembly_contract.sol",
"length": 628,
"lines": [
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20
],
"start": 191
}
}
],
"check": "assembly",
"function": {
"name": "at",
"source_mapping": {
"filename": "tests/inline_assembly_contract.sol",
"length": 628,
"length": 700,
"lines": [
6,
7,
8,
9,
@ -23,9 +48,8 @@
19,
20
],
"start": 191
"start": 119
}
],
"vuln": "Assembly"
}
}
]

@ -1,32 +1,81 @@
[
{
"contract": "VectorSum",
"filename": "tests/inline_assembly_library.sol",
"function": "sumAsm",
"sourceMapping": [
"assembly": [
{
"source_mapping": {
"filename": "tests/inline_assembly_library.sol",
"length": 114,
"lines": [
18,
19,
20,
21
],
"start": 720
}
}
],
"check": "assembly",
"function": {
"name": "sumAsm",
"source_mapping": {
"filename": "tests/inline_assembly_library.sol",
"length": 114,
"length": 247,
"lines": [
16,
17,
18,
19,
20,
21
21,
22
],
"start": 720
"start": 593
}
],
"vuln": "Assembly"
}
},
{
"contract": "VectorSum",
"filename": "tests/inline_assembly_library.sol",
"function": "sumPureAsm",
"sourceMapping": [
"assembly": [
{
"source_mapping": {
"filename": "tests/inline_assembly_library.sol",
"length": 677,
"lines": [
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47
],
"start": 1000
}
}
],
"check": "assembly",
"function": {
"name": "sumPureAsm",
"source_mapping": {
"filename": "tests/inline_assembly_library.sol",
"length": 677,
"length": 754,
"lines": [
25,
26,
27,
28,
@ -50,9 +99,8 @@
46,
47
],
"start": 1000
"start": 923
}
],
"vuln": "Assembly"
}
}
]

@ -1,21 +1,20 @@
[
{
"contract": "OnlyLocked",
"functions_payable": [
"receive"
],
"sourceMapping": [
"check": "locked-ether",
"functions": [
{
"filename": "tests/locked_ether.sol",
"length": 72,
"lines": [
4,
5,
6
],
"start": 47
"name": "receive",
"source_mapping": {
"filename": "tests/locked_ether.sol",
"length": 72,
"lines": [
4,
5,
6
],
"start": 47
}
}
],
"vuln": "LockedEther"
]
}
]

@ -1,18 +1,31 @@
[
{
"contract": "Sender",
"filename": "tests/low_level_calls.sol",
"function": "send",
"sourceMapping": [
"check": "low-level-calls",
"expressions": [
{
"expression": "_receiver.call.value(msg.value).gas(7777)()",
"source_mapping": {
"filename": "tests/low_level_calls.sol",
"length": 43,
"lines": [
6
],
"start": 100
}
}
],
"function": {
"name": "send",
"source_mapping": {
"filename": "tests/low_level_calls.sol",
"length": 43,
"length": 101,
"lines": [
6
5,
6,
7
],
"start": 100
"start": 49
}
],
"vuln": "Low level call"
}
}
]

@ -1,223 +1,246 @@
[
{
"contract": "T",
"filename": "tests/naming_convention.sol",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 17,
"lines": [
56
],
"start": 695
"check": "naming-convention",
"convention": "CapWords",
"name": {
"name": "naming",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 598,
"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,
48
],
"start": 26
}
},
"variable": "_myPublicVar",
"vuln": "NamingConvention"
"type": "contract"
},
{
"contract": "naming",
"filename": "tests/naming_convention.sol",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 598,
"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,
48
],
"start": 26
"check": "naming-convention",
"convention": "CapWords",
"name": {
"name": "numbers",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 23,
"lines": [
6
],
"start": 77
}
},
"vuln": "NamingConvention"
"type": "enum"
},
{
"contract": "naming",
"filename": "tests/naming_convention.sol",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 16,
"lines": [
11
],
"start": 183
"check": "naming-convention",
"convention": "CapWords",
"name": {
"name": "event_",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 19,
"lines": [
23
],
"start": 303
}
},
"variable": "Var_One",
"vuln": "NamingConvention"
"type": "event"
},
{
"contract": "naming",
"filename": "tests/naming_convention.sol",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 20,
"lines": [
14,
15,
16
],
"start": 227
"check": "naming-convention",
"convention": "CapWords",
"name": {
"name": "test",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 20,
"lines": [
14,
15,
16
],
"start": 227
}
},
"struct": "test",
"vuln": "NamingConvention"
"type": "structure"
},
{
"contract": "naming",
"filename": "tests/naming_convention.sol",
"modifier": "CantDo",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 36,
"lines": [
41,
42,
43
],
"start": 545
"check": "naming-convention",
"convention": "UPPER_CASE_WITH_UNDERSCORES",
"name": {
"name": "MY_other_CONSTANT",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 35,
"lines": [
9
],
"start": 141
}
},
"vuln": "NamingConvention"
"type": "variable_constant"
},
{
"contract": "naming",
"filename": "tests/naming_convention.sol",
"function": "GetOne",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 71,
"lines": [
30,
31,
32,
33
],
"start": 405
"check": "naming-convention",
"convention": "l_O_I_should_not_be_used",
"name": {
"name": "l",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 10,
"lines": [
67
],
"start": 847
}
},
"vuln": "NamingConvention"
"type": "variable"
},
{
"contract": "naming",
"event": "event_",
"filename": "tests/naming_convention.sol",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 19,
"lines": [
23
],
"start": 303
"check": "naming-convention",
"convention": "mixedCase",
"name": {
"name": "GetOne",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 71,
"lines": [
30,
31,
32,
33
],
"start": 405
}
},
"vuln": "NamingConvention"
"type": "function"
},
{
"contract": "naming",
"enum": "numbers",
"filename": "tests/naming_convention.sol",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 23,
"lines": [
6
],
"start": 77
"check": "naming-convention",
"convention": "mixedCase",
"name": {
"name": "CantDo",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 36,
"lines": [
41,
42,
43
],
"start": 545
}
},
"vuln": "NamingConvention"
"type": "modifier"
},
{
"constant": "MY_other_CONSTANT",
"contract": "naming",
"filename": "tests/naming_convention.sol",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 35,
"lines": [
9
],
"start": 141
"check": "naming-convention",
"convention": "mixedCase",
"name": {
"name": "Number2",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 12,
"lines": [
35
],
"start": 512
}
},
"vuln": "NamingConvention"
"type": "parameter"
},
{
"constant": "l",
"contract": "T",
"filename": "tests/naming_convention.sol",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 10,
"lines": [
67
],
"start": 847
"check": "naming-convention",
"convention": "mixedCase",
"name": {
"name": "_used",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 10,
"lines": [
59
],
"start": 748
}
},
"vuln": "NamingConvention"
"type": "parameter"
},
{
"argument": "Number2",
"contract": "naming",
"filename": "tests/naming_convention.sol",
"function": "setInt",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 12,
"lines": [
35
],
"start": 512
"check": "naming-convention",
"convention": "mixedCase",
"name": {
"name": "Var_One",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 16,
"lines": [
11
],
"start": 183
}
},
"vuln": "NamingConvention"
"type": "variable"
},
{
"argument": "_used",
"contract": "T",
"filename": "tests/naming_convention.sol",
"function": "test",
"sourceMapping": {
"filename": "tests/naming_convention.sol",
"length": 10,
"lines": [
59
],
"start": 748
"check": "naming-convention",
"convention": "mixedCase",
"name": {
"name": "_myPublicVar",
"source_mapping": {
"filename": "tests/naming_convention.sol",
"length": 17,
"lines": [
56
],
"start": 695
}
},
"vuln": "NamingConvention"
"type": "variable"
}
]

@ -1,16 +1,16 @@
[
{
"pragma": [
"0.4.21"
],
"sourceMapping": [
"check": "solc-version",
"expressions": [
{
"filename": "old_solc.sol",
"length": 23,
"lines": [],
"start": 0
"expression": "0.4.21",
"source_mapping": {
"filename": "old_solc.sol",
"length": 23,
"lines": [],
"start": 0
}
}
],
"vuln": "OldPragma"
]
}
]

@ -1,27 +1,29 @@
[
{
"sourceMapping": [
"check": "pragma",
"expressions": [
{
"filename": "tests/pragma.0.4.23.sol",
"length": 24,
"lines": [
1
],
"start": 0
"expression": "^0.4.23",
"source_mapping": {
"filename": "tests/pragma.0.4.23.sol",
"length": 24,
"lines": [
1
],
"start": 0
}
},
{
"filename": "tests/pragma.0.4.24.sol",
"length": 24,
"lines": [
1
],
"start": 0
"expression": "^0.4.24",
"source_mapping": {
"filename": "tests/pragma.0.4.24.sol",
"length": 24,
"lines": [
1
],
"start": 0
}
}
],
"versions": [
"^0.4.23",
"^0.4.24"
],
"vuln": "ConstantPragma"
]
}
]

@ -1,47 +1,53 @@
[
{
"calls": [
"! (msg.sender.call.value(userBalance[msg.sender])())"
],
"contract": "Reentrancy",
"filename": "tests/reentrancy.sol",
"function": "withdrawBalance",
"send_eth": [
"! (msg.sender.call.value(userBalance[msg.sender])())"
],
"sourceMapping": [
{
"filename": "tests/reentrancy.sol",
"length": 37,
"lines": [
4
],
"start": 52
},
"check": "reentrancy",
"external_calls": [
{
"expression": "! (msg.sender.call.value(userBalance[msg.sender])())",
"source_mapping": {
"filename": "tests/reentrancy.sol",
"length": 92,
"lines": [
17,
18,
19
],
"start": 478
}
}
],
"external_calls_sending_eth": [],
"function": {
"name": "withdrawBalance",
"source_mapping": {
"filename": "tests/reentrancy.sol",
"length": 92,
"length": 314,
"lines": [
14,
15,
16,
17,
18,
19
19,
20,
21
],
"start": 478
},
"start": 299
}
},
"variables_written": [
{
"filename": "tests/reentrancy.sol",
"length": 92,
"lines": [
17,
18,
19
],
"start": 478
"expression": "userBalance[msg.sender] = 0",
"name": "userBalance",
"source_mapping": {
"filename": "tests/reentrancy.sol",
"length": 27,
"lines": [
20
],
"start": 579
}
}
],
"varsWritten": [
"userBalance"
],
"vuln": "Reentrancy"
]
}
]

@ -1,36 +1,64 @@
[
{
"contract": "TxOrigin",
"filename": "tests/tx_origin.sol",
"function": "bug0",
"sourceMapping": [
"check": "tx-origin",
"expressions": [
{
"expression": "require(bool)(tx.origin == owner)",
"source_mapping": {
"filename": "tests/tx_origin.sol",
"length": 27,
"lines": [
10
],
"start": 140
}
}
],
"function": {
"name": "bug0",
"source_mapping": {
"filename": "tests/tx_origin.sol",
"length": 27,
"length": 60,
"lines": [
10
9,
10,
11
],
"start": 140
"start": 114
}
],
"vuln": "TxOrigin"
}
},
{
"contract": "TxOrigin",
"filename": "tests/tx_origin.sol",
"function": "bug2",
"sourceMapping": [
"check": "tx-origin",
"expressions": [
{
"expression": "tx.origin != owner",
"source_mapping": {
"filename": "tests/tx_origin.sol",
"length": 57,
"lines": [
14,
15,
16
],
"start": 206
}
}
],
"function": {
"name": "bug2",
"source_mapping": {
"filename": "tests/tx_origin.sol",
"length": 57,
"length": 89,
"lines": [
13,
14,
15,
16
16,
17
],
"start": 206
"start": 180
}
],
"vuln": "TxOrigin"
}
}
]

@ -1,120 +1,120 @@
[
{
"contract": "Test",
"filename": "tests/uninitialized.sol",
"check": "uninitialized-state",
"functions": [
"use"
],
"sourceMapping": [
{
"name": "transfer",
"source_mapping": {
"filename": "tests/uninitialized.sol",
"length": 82,
"lines": [
7,
8,
9
],
"start": 81
}
}
],
"variable": {
"name": "destination",
"source_mapping": {
"filename": "tests/uninitialized.sol",
"length": 34,
"length": 19,
"lines": [
15
5
],
"start": 189
},
"start": 55
}
}
},
{
"check": "uninitialized-state",
"functions": [
{
"name": "use",
"source_mapping": {
"filename": "tests/uninitialized.sol",
"length": 143,
"lines": [
23,
24,
25,
26
],
"start": 356
}
}
],
"variable": {
"name": "balances",
"source_mapping": {
"filename": "tests/uninitialized.sol",
"length": 143,
"length": 34,
"lines": [
23,
24,
25,
26
15
],
"start": 356
"start": 189
}
],
"variable": "balances",
"vuln": "UninitializedStateVars"
}
},
{
"contract": "Test2",
"filename": "tests/uninitialized.sol",
"check": "uninitialized-state",
"functions": [
"use"
],
"sourceMapping": [
{
"name": "use",
"source_mapping": {
"filename": "tests/uninitialized.sol",
"length": 117,
"lines": [
53,
54,
55,
56
],
"start": 875
}
}
],
"variable": {
"name": "st",
"source_mapping": {
"filename": "tests/uninitialized.sol",
"length": 15,
"lines": [
45
],
"start": 695
},
{
"filename": "tests/uninitialized.sol",
"length": 117,
"lines": [
53,
54,
55,
56
],
"start": 875
}
],
"variable": "st",
"vuln": "UninitializedStateVars"
}
},
{
"contract": "Test2",
"filename": "tests/uninitialized.sol",
"check": "uninitialized-state",
"functions": [
"init"
],
"sourceMapping": [
{
"name": "init",
"source_mapping": {
"filename": "tests/uninitialized.sol",
"length": 52,
"lines": [
49,
50,
51
],
"start": 817
}
}
],
"variable": {
"name": "v",
"source_mapping": {
"filename": "tests/uninitialized.sol",
"length": 6,
"lines": [
47
],
"start": 748
},
{
"filename": "tests/uninitialized.sol",
"length": 52,
"lines": [
49,
50,
51
],
"start": 817
}
],
"variable": "v",
"vuln": "UninitializedStateVars"
},
{
"contract": "Uninitialized",
"filename": "tests/uninitialized.sol",
"functions": [
"transfer"
],
"sourceMapping": [
{
"filename": "tests/uninitialized.sol",
"length": 19,
"lines": [
5
],
"start": 55
},
{
"filename": "tests/uninitialized.sol",
"length": 82,
"lines": [
7,
8,
9
],
"start": 81
}
],
"variable": "destination",
"vuln": "UninitializedStateVars"
}
}
]

@ -1,18 +1,9 @@
[
{
"contract": "Uninitialized",
"filename": "tests/uninitialized_local_variable.sol",
"function": "func",
"sourceMapping": [
{
"filename": "tests/uninitialized_local_variable.sol",
"length": 18,
"lines": [
4
],
"start": 77
},
{
"check": "uninitialized-local",
"function": {
"name": "func",
"source_mapping": {
"filename": "tests/uninitialized_local_variable.sol",
"length": 143,
"lines": [
@ -24,8 +15,17 @@
],
"start": 29
}
],
"variable": "uint_not_init",
"vuln": "UninitializedLocalVars"
},
"variable": {
"name": "uint_not_init",
"source_mapping": {
"filename": "tests/uninitialized_local_variable.sol",
"length": 18,
"lines": [
4
],
"start": 77
}
}
}
]

@ -1,18 +1,9 @@
[
{
"contract": "Uninitialized",
"filename": "tests/uninitialized_storage_pointer.sol",
"function": "func",
"sourceMapping": [
{
"filename": "tests/uninitialized_storage_pointer.sol",
"length": 9,
"lines": [
10
],
"start": 171
},
{
"check": "uninitialized-storage",
"function": {
"name": "func",
"source_mapping": {
"filename": "tests/uninitialized_storage_pointer.sol",
"length": 138,
"lines": [
@ -25,8 +16,17 @@
],
"start": 67
}
],
"variable": "st_bug",
"vuln": "UninitializedStorageVars"
},
"variable": {
"name": "st_bug",
"source_mapping": {
"filename": "tests/uninitialized_storage_pointer.sol",
"length": 9,
"lines": [
10
],
"start": 171
}
}
}
]

@ -1,29 +1,52 @@
[
{
"contract": "User",
"check": "unused-return",
"expressions": [
"a.add(0)",
"t.f()"
],
"filename": "tests/unused_return.sol",
"sourceMapping": [
{
"filename": "tests/unused_return.sol",
"length": 5,
"lines": [
18
],
"start": 263
"expression": "a.add(0)",
"source_mapping": {
"filename": "tests/unused_return.sol",
"length": 8,
"lines": [
22
],
"start": 337
}
},
{
"expression": "t.f()",
"source_mapping": {
"filename": "tests/unused_return.sol",
"length": 5,
"lines": [
18
],
"start": 263
}
}
],
"function": {
"name": "test",
"source_mapping": {
"filename": "tests/unused_return.sol",
"length": 8,
"length": 347,
"lines": [
22
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29
],
"start": 337
"start": 230
}
],
"vuln": "UnusedReturn"
}
}
]

@ -1,20 +1,18 @@
[
{
"contract": "B",
"filename": "tests/unused_state.sol",
"sourceMapping": [
"check": "unused-state",
"variables": [
{
"filename": "tests/unused_state.sol",
"length": 14,
"lines": [
4
],
"start": 42
"name": "unused",
"source_mapping": {
"filename": "tests/unused_state.sol",
"length": 14,
"lines": [
4
],
"start": 42
}
}
],
"unusedVars": [
"unused"
],
"vuln": "unusedStateVars"
]
}
]
Loading…
Cancel
Save