issue=Issue("CALL with gas to dynamic address","Warning")
issue.description="The function "+call.node.function_name+" contains a call.value() to "
description="The function "+call.node.function_name+" contains a call.value() to "
target=str(call.to)
is_valid=False
@ -32,9 +31,9 @@ def execute(statespace):
if("calldata"intargetor"caller"intarget):
if("calldata"intarget):
issue.description+="an address provided as a function argument. "
description+="an address provided as a function argument. "
else:
issue.description+="the address of the transaction sender. "
description+="the address of the transaction sender. "
is_valid=True
else:
@ -49,7 +48,7 @@ def execute(statespace):
ifs.tainted:
issue.description+= \
description+= \
"an address found at storage position "+str(index)+".\n"+ \
"This storage position can be written to by calling the function '"+s.node.function_name+"'.\n" \
"Verify that the contract address cannot be set by untrusted users.\n"
@ -62,7 +61,10 @@ def execute(statespace):
continue
ifis_valid:
issue.description+="The available gas is forwarded to the called contract.\nMake sure that the logic of the calling contract is not adversely affected if the called contract misbehaves (e.g. reentrancy)."
description+="The available gas is forwarded to the called contract.\nMake sure that the logic of the calling contract is not adversely affected if the called contract misbehaves (e.g. reentrancy)."
issue=Issue(call.node.module_name,call.node.function_name,call.addr,"CALL with gas to dynamic address","Warning",description)
issue=Issue("CALLDATA forwarded with delegatecall()","Informational")
issue=Issue(call.node.module_name,call.node.function_name,call.addr,"CALLDATA forwarded with delegatecall()","Informational")
issue.description= \
"The contract '"+str(call.node.module_name)+"' forwards its calldata via DELEGATECALL in its fallback function. " \
"This means that any function in the called contract can be executed. Note that the callee contract will have access to the storage of the calling contract.\n"
issue.description+="\nThere is a check on storage index "+str(index)+". This storage index can be written to by calling the function '"+s.node.function_name+"'."
description+="\nThere is a check on storage index "+str(index)+". This storage index can be written to by calling the function '"+s.node.function_name+"'."
"The function "+call.node.function_name+"in contract '"+call.node.module_name+"'contains a call to "+receiver+".\n" \
"The function "+call.node.function_name+" contains a call to "+receiver+".\n" \
"The return value of this call is not checked. Note that the function will continue to execute with a return value of '0' if the called contract throws."
logging.debug("[UNCHECKED_SUICIDE] suicide in function "+node.function_name)
issue=Issue("Unchecked SUICIDE","Warning")
issue.description="The function "+node.function_name+" executes the SUICIDE instruction."
description="The function "+node.function_name+" executes the SUICIDE instruction."
state=node.states[instruction['address']]
to=state.stack.pop()
if("caller"instr(to)):
issue.description+="\nThe remaining Ether is sent to the caller's address.\n"
description+="\nThe remaining Ether is sent to the caller's address.\n"
elif("storage"instr(to)):
issue.description+="\nThe remaining Ether is sent to a stored address\n"
description+="\nThe remaining Ether is sent to a stored address\n"
elif("calldata"instr(to)):
issue.description+="\nThe remaining Ether is sent to an address provided as a function argument."
description+="\nThe remaining Ether is sent to an address provided as a function argument."
elif(type(to)==BitVecNumRef):
issue.description+="\nThe remaining Ether is sent to: "+hex(to.as_long())
description+="\nThe remaining Ether is sent to: "+hex(to.as_long())
else:
issue.description+="\nThe remaining Ether is sent to: "+str(to)+"\n"
description+="\nThe remaining Ether is sent to: "+str(to)+"\n"
constrained=False
can_solve=True
@ -68,7 +67,7 @@ def execute(statespace):
forsinstatespace.sstors[index]:
ifs.tainted:
issue.description+="\nThere is a check on storage index "+str(index)+". This storage index can be written to by calling the function '"+s.node.function_name+"'."
description+="\nThere is a check on storage index "+str(index)+". This storage index can be written to by calling the function '"+s.node.function_name+"'."
break
ifnotoverwrite:
@ -90,17 +89,21 @@ def execute(statespace):
ifnotconstrained:
issue.description+="\nIt seems that this function can be called without restrictions."
description+="\nIt seems that this function can be called without restrictions."