Remove FP on locked_ether detector: follow through libraries calls to detect send of ethers (fix #163)

pull/169/head
Josselin 6 years ago
parent 77cd643360
commit 4a1252ad29
  1. 39
      slither/detectors/attributes/locked_ether.py

@ -5,7 +5,7 @@
from slither.detectors.abstract_detector import (AbstractDetector, from slither.detectors.abstract_detector import (AbstractDetector,
DetectorClassification) DetectorClassification)
from slither.slithir.operations import (HighLevelCall, LowLevelCall, Send, from slither.slithir.operations import (HighLevelCall, LowLevelCall, Send,
Transfer, NewContract) Transfer, NewContract, LibraryCall, InternalCall)
class LockedEther(AbstractDetector): class LockedEther(AbstractDetector):
@ -37,18 +37,31 @@ Every ethers send to `Locked` will be lost.'''
@staticmethod @staticmethod
def do_no_send_ether(contract): def do_no_send_ether(contract):
functions = contract.all_functions_called functions = contract.all_functions_called
for function in functions: to_explore = functions
calls = [c.name for c in function.internal_calls] explored = []
if 'suicide(address)' in calls or 'selfdestruct(address)' in calls: while to_explore:
return False functions = to_explore
for node in function.nodes: explored += to_explore
for ir in node.irs: to_explore = []
if isinstance(ir, (Send, Transfer, HighLevelCall, LowLevelCall, NewContract)): for function in functions:
if ir.call_value and ir.call_value != 0: calls = [c.name for c in function.internal_calls]
return False if 'suicide(address)' in calls or 'selfdestruct(address)' in calls:
if isinstance(ir, (LowLevelCall)): return False
if ir.function_name in ['delegatecall', 'callcode']: for node in function.nodes:
return False for ir in node.irs:
if isinstance(ir, (Send, Transfer, HighLevelCall, LowLevelCall, NewContract)):
if ir.call_value and ir.call_value != 0:
return False
if isinstance(ir, (LowLevelCall)):
if ir.function_name in ['delegatecall', 'callcode']:
return False
# If a new internal call or librarycall
# Add it to the list to explore
# InternalCall if to follow internal call in libraries
if isinstance(ir, (InternalCall, LibraryCall)):
if not ir.function in explored:
to_explore.append(ir.function)
return True return True

Loading…
Cancel
Save