mirror of https://github.com/crytic/slither
commit
63dbe8d747
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,17 @@ |
||||
from typing import TYPE_CHECKING |
||||
|
||||
if TYPE_CHECKING: |
||||
from slither.core.declarations import Event |
||||
|
||||
|
||||
class ChildEvent: |
||||
def __init__(self): |
||||
super(ChildEvent, self).__init__() |
||||
self._event = None |
||||
|
||||
def set_event(self, event): |
||||
def set_event(self, event: "Event"): |
||||
self._event = event |
||||
|
||||
@property |
||||
def event(self): |
||||
def event(self) -> "Event": |
||||
return self._event |
||||
|
@ -1,12 +1,17 @@ |
||||
from typing import TYPE_CHECKING |
||||
|
||||
if TYPE_CHECKING: |
||||
from slither.core.expressions.expression import Expression |
||||
|
||||
|
||||
class ChildExpression: |
||||
def __init__(self): |
||||
super(ChildExpression, self).__init__() |
||||
self._expression = None |
||||
|
||||
def set_expression(self, expression): |
||||
def set_expression(self, expression: "Expression"): |
||||
self._expression = expression |
||||
|
||||
@property |
||||
def expression(self): |
||||
def expression(self) -> "Expression": |
||||
return self._expression |
||||
|
@ -1,12 +1,17 @@ |
||||
from typing import TYPE_CHECKING |
||||
|
||||
if TYPE_CHECKING: |
||||
from slither.core.declarations import Function |
||||
|
||||
|
||||
class ChildFunction: |
||||
def __init__(self): |
||||
super(ChildFunction, self).__init__() |
||||
self._function = None |
||||
|
||||
def set_function(self, function): |
||||
def set_function(self, function: "Function"): |
||||
self._function = function |
||||
|
||||
@property |
||||
def function(self): |
||||
def function(self) -> "Function": |
||||
return self._function |
||||
|
@ -1,13 +1,17 @@ |
||||
from typing import TYPE_CHECKING |
||||
|
||||
if TYPE_CHECKING: |
||||
from slither.core.declarations import Contract |
||||
|
||||
class ChildInheritance: |
||||
|
||||
class ChildInheritance: |
||||
def __init__(self): |
||||
super(ChildInheritance, self).__init__() |
||||
self._contract_declarer = None |
||||
|
||||
def set_contract_declarer(self, contract): |
||||
def set_contract_declarer(self, contract: "Contract"): |
||||
self._contract_declarer = contract |
||||
|
||||
@property |
||||
def contract_declarer(self): |
||||
def contract_declarer(self) -> "Contract": |
||||
return self._contract_declarer |
||||
|
@ -1,24 +1,31 @@ |
||||
from typing import TYPE_CHECKING |
||||
|
||||
if TYPE_CHECKING: |
||||
from slither import Slither |
||||
from slither.core.cfg.node import Node |
||||
from slither.core.declarations import Function, Contract |
||||
|
||||
|
||||
class ChildNode(object): |
||||
def __init__(self): |
||||
super(ChildNode, self).__init__() |
||||
self._node = None |
||||
|
||||
def set_node(self, node): |
||||
def set_node(self, node: "Node"): |
||||
self._node = node |
||||
|
||||
@property |
||||
def node(self): |
||||
def node(self) -> "Node": |
||||
return self._node |
||||
|
||||
@property |
||||
def function(self): |
||||
def function(self) -> "Function": |
||||
return self.node.function |
||||
|
||||
@property |
||||
def contract(self): |
||||
def contract(self) -> "Contract": |
||||
return self.node.function.contract |
||||
|
||||
@property |
||||
def slither(self): |
||||
return self.contract.slither |
||||
def slither(self) -> "Slither": |
||||
return self.contract.slither |
||||
|
@ -1,13 +1,17 @@ |
||||
from typing import TYPE_CHECKING |
||||
|
||||
if TYPE_CHECKING: |
||||
from slither import Slither |
||||
|
||||
class ChildSlither: |
||||
|
||||
class ChildSlither: |
||||
def __init__(self): |
||||
super(ChildSlither, self).__init__() |
||||
self._slither = None |
||||
|
||||
def set_slither(self, slither): |
||||
def set_slither(self, slither: "Slither"): |
||||
self._slither = slither |
||||
|
||||
@property |
||||
def slither(self): |
||||
def slither(self) -> "Slither": |
||||
return self._slither |
||||
|
@ -1,13 +1,17 @@ |
||||
from typing import TYPE_CHECKING |
||||
|
||||
if TYPE_CHECKING: |
||||
from slither.core.declarations import Structure |
||||
|
||||
class ChildStructure: |
||||
|
||||
class ChildStructure: |
||||
def __init__(self): |
||||
super(ChildStructure, self).__init__() |
||||
self._structure = None |
||||
|
||||
def set_structure(self, structure): |
||||
def set_structure(self, structure: "Structure"): |
||||
self._structure = structure |
||||
|
||||
@property |
||||
def structure(self): |
||||
def structure(self) -> "Structure": |
||||
return self._structure |
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,37 +1,39 @@ |
||||
from typing import List |
||||
|
||||
from slither.core.source_mapping.source_mapping import SourceMapping |
||||
|
||||
class Pragma(SourceMapping): |
||||
|
||||
def __init__(self, directive): |
||||
class Pragma(SourceMapping): |
||||
def __init__(self, directive: List[str]): |
||||
super(Pragma, self).__init__() |
||||
self._directive = directive |
||||
|
||||
@property |
||||
def directive(self): |
||||
''' |
||||
def directive(self) -> List[str]: |
||||
""" |
||||
list(str) |
||||
''' |
||||
""" |
||||
return self._directive |
||||
|
||||
@property |
||||
def version(self): |
||||
return ''.join(self.directive[1:]) |
||||
def version(self) -> str: |
||||
return "".join(self.directive[1:]) |
||||
|
||||
@property |
||||
def name(self): |
||||
def name(self) -> str: |
||||
return self.version |
||||
|
||||
@property |
||||
def is_solidity_version(self): |
||||
def is_solidity_version(self) -> bool: |
||||
if len(self._directive) > 0: |
||||
return self._directive[0].lower() == 'solidity' |
||||
return self._directive[0].lower() == "solidity" |
||||
return False |
||||
|
||||
@property |
||||
def is_abi_encoder_v2(self): |
||||
def is_abi_encoder_v2(self) -> bool: |
||||
if len(self._directive) == 2: |
||||
return self._directive[0] == 'experimental' and self._directive[1] == 'ABIEncoderV2' |
||||
return self._directive[0] == "experimental" and self._directive[1] == "ABIEncoderV2" |
||||
return False |
||||
|
||||
def __str__(self): |
||||
return 'pragma '+''.join(self.directive) |
||||
return "pragma " + "".join(self.directive) |
||||
|
@ -1,3 +1,5 @@ |
||||
from slither.exceptions import SlitherException |
||||
|
||||
class SlitherCoreError(SlitherException): pass |
||||
|
||||
class SlitherCoreError(SlitherException): |
||||
pass |
||||
|
@ -1,111 +1,118 @@ |
||||
import logging |
||||
from enum import Enum |
||||
from typing import Optional, TYPE_CHECKING, List |
||||
|
||||
from slither.core.expressions.expression_typed import ExpressionTyped |
||||
from slither.core.expressions.expression import Expression |
||||
from slither.core.exceptions import SlitherCoreError |
||||
|
||||
if TYPE_CHECKING: |
||||
from slither.core.solidity_types.type import Type |
||||
|
||||
logger = logging.getLogger("AssignmentOperation") |
||||
|
||||
class AssignmentOperationType: |
||||
ASSIGN = 0 # = |
||||
ASSIGN_OR = 1 # |= |
||||
ASSIGN_CARET = 2 # ^= |
||||
ASSIGN_AND = 3 # &= |
||||
ASSIGN_LEFT_SHIFT = 4 # <<= |
||||
ASSIGN_RIGHT_SHIFT = 5 # >>= |
||||
ASSIGN_ADDITION = 6 # += |
||||
ASSIGN_SUBTRACTION = 7 # -= |
||||
ASSIGN_MULTIPLICATION = 8 # *= |
||||
ASSIGN_DIVISION = 9 # /= |
||||
ASSIGN_MODULO = 10 # %= |
||||
|
||||
class AssignmentOperationType(Enum): |
||||
ASSIGN = 0 # = |
||||
ASSIGN_OR = 1 # |= |
||||
ASSIGN_CARET = 2 # ^= |
||||
ASSIGN_AND = 3 # &= |
||||
ASSIGN_LEFT_SHIFT = 4 # <<= |
||||
ASSIGN_RIGHT_SHIFT = 5 # >>= |
||||
ASSIGN_ADDITION = 6 # += |
||||
ASSIGN_SUBTRACTION = 7 # -= |
||||
ASSIGN_MULTIPLICATION = 8 # *= |
||||
ASSIGN_DIVISION = 9 # /= |
||||
ASSIGN_MODULO = 10 # %= |
||||
|
||||
@staticmethod |
||||
def get_type(operation_type): |
||||
if operation_type == '=': |
||||
def get_type(operation_type: "AssignmentOperationType"): |
||||
if operation_type == "=": |
||||
return AssignmentOperationType.ASSIGN |
||||
if operation_type == '|=': |
||||
if operation_type == "|=": |
||||
return AssignmentOperationType.ASSIGN_OR |
||||
if operation_type == '^=': |
||||
if operation_type == "^=": |
||||
return AssignmentOperationType.ASSIGN_CARET |
||||
if operation_type == '&=': |
||||
if operation_type == "&=": |
||||
return AssignmentOperationType.ASSIGN_AND |
||||
if operation_type == '<<=': |
||||
if operation_type == "<<=": |
||||
return AssignmentOperationType.ASSIGN_LEFT_SHIFT |
||||
if operation_type == '>>=': |
||||
if operation_type == ">>=": |
||||
return AssignmentOperationType.ASSIGN_RIGHT_SHIFT |
||||
if operation_type == '+=': |
||||
if operation_type == "+=": |
||||
return AssignmentOperationType.ASSIGN_ADDITION |
||||
if operation_type == '-=': |
||||
if operation_type == "-=": |
||||
return AssignmentOperationType.ASSIGN_SUBTRACTION |
||||
if operation_type == '*=': |
||||
if operation_type == "*=": |
||||
return AssignmentOperationType.ASSIGN_MULTIPLICATION |
||||
if operation_type == '/=': |
||||
if operation_type == "/=": |
||||
return AssignmentOperationType.ASSIGN_DIVISION |
||||
if operation_type == '%=': |
||||
if operation_type == "%=": |
||||
return AssignmentOperationType.ASSIGN_MODULO |
||||
|
||||
raise SlitherCoreError('get_type: Unknown operation type {})'.format(operation_type)) |
||||
raise SlitherCoreError("get_type: Unknown operation type {})".format(operation_type)) |
||||
|
||||
@staticmethod |
||||
def str(operation_type): |
||||
if operation_type == AssignmentOperationType.ASSIGN: |
||||
return '=' |
||||
if operation_type == AssignmentOperationType.ASSIGN_OR: |
||||
return '|=' |
||||
if operation_type == AssignmentOperationType.ASSIGN_CARET: |
||||
return '^=' |
||||
if operation_type == AssignmentOperationType.ASSIGN_AND: |
||||
return '&=' |
||||
if operation_type == AssignmentOperationType.ASSIGN_LEFT_SHIFT: |
||||
return '<<=' |
||||
if operation_type == AssignmentOperationType.ASSIGN_RIGHT_SHIFT: |
||||
return '>>=' |
||||
if operation_type == AssignmentOperationType.ASSIGN_ADDITION: |
||||
return '+=' |
||||
if operation_type == AssignmentOperationType.ASSIGN_SUBTRACTION: |
||||
return '-=' |
||||
if operation_type == AssignmentOperationType.ASSIGN_MULTIPLICATION: |
||||
return '*=' |
||||
if operation_type == AssignmentOperationType.ASSIGN_DIVISION: |
||||
return '/=' |
||||
if operation_type == AssignmentOperationType.ASSIGN_MODULO: |
||||
return '%=' |
||||
|
||||
raise SlitherCoreError('str: Unknown operation type {})'.format(operation_type)) |
||||
def __str__(self): |
||||
if self == AssignmentOperationType.ASSIGN: |
||||
return "=" |
||||
if self == AssignmentOperationType.ASSIGN_OR: |
||||
return "|=" |
||||
if self == AssignmentOperationType.ASSIGN_CARET: |
||||
return "^=" |
||||
if self == AssignmentOperationType.ASSIGN_AND: |
||||
return "&=" |
||||
if self == AssignmentOperationType.ASSIGN_LEFT_SHIFT: |
||||
return "<<=" |
||||
if self == AssignmentOperationType.ASSIGN_RIGHT_SHIFT: |
||||
return ">>=" |
||||
if self == AssignmentOperationType.ASSIGN_ADDITION: |
||||
return "+=" |
||||
if self == AssignmentOperationType.ASSIGN_SUBTRACTION: |
||||
return "-=" |
||||
if self == AssignmentOperationType.ASSIGN_MULTIPLICATION: |
||||
return "*=" |
||||
if self == AssignmentOperationType.ASSIGN_DIVISION: |
||||
return "/=" |
||||
if self == AssignmentOperationType.ASSIGN_MODULO: |
||||
return "%=" |
||||
raise SlitherCoreError("str: Unknown operation type {})".format(self)) |
||||
|
||||
class AssignmentOperation(ExpressionTyped): |
||||
|
||||
def __init__(self, left_expression, right_expression, expression_type, expression_return_type): |
||||
class AssignmentOperation(ExpressionTyped): |
||||
def __init__( |
||||
self, |
||||
left_expression: Expression, |
||||
right_expression: Expression, |
||||
expression_type: AssignmentOperationType, |
||||
expression_return_type: Optional["Type"], |
||||
): |
||||
assert isinstance(left_expression, Expression) |
||||
assert isinstance(right_expression, Expression) |
||||
super(AssignmentOperation, self).__init__() |
||||
left_expression.set_lvalue() |
||||
self._expressions = [left_expression, right_expression] |
||||
self._type = expression_type |
||||
self._expression_return_type = expression_return_type |
||||
self._expression_return_type: Optional["Type"] = expression_return_type |
||||
|
||||
@property |
||||
def expressions(self): |
||||
def expressions(self) -> List[Expression]: |
||||
return self._expressions |
||||
|
||||
@property |
||||
def expression_return_type(self): |
||||
def expression_return_type(self) -> Optional["Type"]: |
||||
return self._expression_return_type |
||||
|
||||
@property |
||||
def expression_left(self): |
||||
def expression_left(self) -> Expression: |
||||
return self._expressions[0] |
||||
|
||||
@property |
||||
def expression_right(self): |
||||
def expression_right(self) -> Expression: |
||||
return self._expressions[1] |
||||
|
||||
@property |
||||
def type(self): |
||||
def type(self) -> AssignmentOperationType: |
||||
return self._type |
||||
|
||||
@property |
||||
def type_str(self): |
||||
return AssignmentOperationType.str(self._type) |
||||
|
||||
def __str__(self): |
||||
return str(self.expression_left) + " "+ self.type_str + " " + str(self.expression_right) |
||||
return str(self.expression_left) + " " + str(self.type) + " " + str(self.expression_right) |
||||
|
@ -1,145 +1,144 @@ |
||||
import logging |
||||
from enum import Enum |
||||
from typing import List |
||||
|
||||
from slither.core.expressions.expression_typed import ExpressionTyped |
||||
from slither.core.expressions.expression import Expression |
||||
from slither.core.exceptions import SlitherCoreError |
||||
|
||||
|
||||
logger = logging.getLogger("BinaryOperation") |
||||
|
||||
class BinaryOperationType: |
||||
POWER = 0 # ** |
||||
MULTIPLICATION = 1 # * |
||||
DIVISION = 2 # / |
||||
MODULO = 3 # % |
||||
ADDITION = 4 # + |
||||
SUBTRACTION = 5 # - |
||||
LEFT_SHIFT = 6 # << |
||||
RIGHT_SHIFT = 7 # >>> |
||||
AND = 8 # & |
||||
CARET = 9 # ^ |
||||
OR = 10 # | |
||||
LESS = 11 # < |
||||
GREATER = 12 # > |
||||
LESS_EQUAL = 13 # <= |
||||
GREATER_EQUAL = 14 # >= |
||||
EQUAL = 15 # == |
||||
NOT_EQUAL = 16 # != |
||||
ANDAND = 17 # && |
||||
OROR = 18 # || |
||||
|
||||
class BinaryOperationType(Enum): |
||||
POWER = 0 # ** |
||||
MULTIPLICATION = 1 # * |
||||
DIVISION = 2 # / |
||||
MODULO = 3 # % |
||||
ADDITION = 4 # + |
||||
SUBTRACTION = 5 # - |
||||
LEFT_SHIFT = 6 # << |
||||
RIGHT_SHIFT = 7 # >>> |
||||
AND = 8 # & |
||||
CARET = 9 # ^ |
||||
OR = 10 # | |
||||
LESS = 11 # < |
||||
GREATER = 12 # > |
||||
LESS_EQUAL = 13 # <= |
||||
GREATER_EQUAL = 14 # >= |
||||
EQUAL = 15 # == |
||||
NOT_EQUAL = 16 # != |
||||
ANDAND = 17 # && |
||||
OROR = 18 # || |
||||
|
||||
@staticmethod |
||||
def get_type(operation_type): |
||||
if operation_type == '**': |
||||
def get_type(operation_type: "BinaryOperation"): |
||||
if operation_type == "**": |
||||
return BinaryOperationType.POWER |
||||
if operation_type == '*': |
||||
if operation_type == "*": |
||||
return BinaryOperationType.MULTIPLICATION |
||||
if operation_type == '/': |
||||
if operation_type == "/": |
||||
return BinaryOperationType.DIVISION |
||||
if operation_type == '%': |
||||
if operation_type == "%": |
||||
return BinaryOperationType.MODULO |
||||
if operation_type == '+': |
||||
if operation_type == "+": |
||||
return BinaryOperationType.ADDITION |
||||
if operation_type == '-': |
||||
if operation_type == "-": |
||||
return BinaryOperationType.SUBTRACTION |
||||
if operation_type == '<<': |
||||
if operation_type == "<<": |
||||
return BinaryOperationType.LEFT_SHIFT |
||||
if operation_type == '>>': |
||||
if operation_type == ">>": |
||||
return BinaryOperationType.RIGHT_SHIFT |
||||
if operation_type == '&': |
||||
if operation_type == "&": |
||||
return BinaryOperationType.AND |
||||
if operation_type == '^': |
||||
if operation_type == "^": |
||||
return BinaryOperationType.CARET |
||||
if operation_type == '|': |
||||
if operation_type == "|": |
||||
return BinaryOperationType.OR |
||||
if operation_type == '<': |
||||
if operation_type == "<": |
||||
return BinaryOperationType.LESS |
||||
if operation_type == '>': |
||||
if operation_type == ">": |
||||
return BinaryOperationType.GREATER |
||||
if operation_type == '<=': |
||||
if operation_type == "<=": |
||||
return BinaryOperationType.LESS_EQUAL |
||||
if operation_type == '>=': |
||||
if operation_type == ">=": |
||||
return BinaryOperationType.GREATER_EQUAL |
||||
if operation_type == '==': |
||||
if operation_type == "==": |
||||
return BinaryOperationType.EQUAL |
||||
if operation_type == '!=': |
||||
if operation_type == "!=": |
||||
return BinaryOperationType.NOT_EQUAL |
||||
if operation_type == '&&': |
||||
if operation_type == "&&": |
||||
return BinaryOperationType.ANDAND |
||||
if operation_type == '||': |
||||
if operation_type == "||": |
||||
return BinaryOperationType.OROR |
||||
|
||||
raise SlitherCoreError('get_type: Unknown operation type {})'.format(operation_type)) |
||||
raise SlitherCoreError("get_type: Unknown operation type {})".format(operation_type)) |
||||
|
||||
@staticmethod |
||||
def str(operation_type): |
||||
if operation_type == BinaryOperationType.POWER: |
||||
return '**' |
||||
if operation_type == BinaryOperationType.MULTIPLICATION: |
||||
return '*' |
||||
if operation_type == BinaryOperationType.DIVISION: |
||||
return '/' |
||||
if operation_type == BinaryOperationType.MODULO: |
||||
return '%' |
||||
if operation_type == BinaryOperationType.ADDITION: |
||||
return '+' |
||||
if operation_type == BinaryOperationType.SUBTRACTION: |
||||
return '-' |
||||
if operation_type == BinaryOperationType.LEFT_SHIFT: |
||||
return '<<' |
||||
if operation_type == BinaryOperationType.RIGHT_SHIFT: |
||||
return '>>' |
||||
if operation_type == BinaryOperationType.AND: |
||||
return '&' |
||||
if operation_type == BinaryOperationType.CARET: |
||||
return '^' |
||||
if operation_type == BinaryOperationType.OR: |
||||
return '|' |
||||
if operation_type == BinaryOperationType.LESS: |
||||
return '<' |
||||
if operation_type == BinaryOperationType.GREATER: |
||||
return '>' |
||||
if operation_type == BinaryOperationType.LESS_EQUAL: |
||||
return '<=' |
||||
if operation_type == BinaryOperationType.GREATER_EQUAL: |
||||
return '>=' |
||||
if operation_type == BinaryOperationType.EQUAL: |
||||
return '==' |
||||
if operation_type == BinaryOperationType.NOT_EQUAL: |
||||
return '!=' |
||||
if operation_type == BinaryOperationType.ANDAND: |
||||
return '&&' |
||||
if operation_type == BinaryOperationType.OROR: |
||||
return '||' |
||||
raise SlitherCoreError('str: Unknown operation type {})'.format(operation_type)) |
||||
def __str__(self): |
||||
if self == BinaryOperationType.POWER: |
||||
return "**" |
||||
if self == BinaryOperationType.MULTIPLICATION: |
||||
return "*" |
||||
if self == BinaryOperationType.DIVISION: |
||||
return "/" |
||||
if self == BinaryOperationType.MODULO: |
||||
return "%" |
||||
if self == BinaryOperationType.ADDITION: |
||||
return "+" |
||||
if self == BinaryOperationType.SUBTRACTION: |
||||
return "-" |
||||
if self == BinaryOperationType.LEFT_SHIFT: |
||||
return "<<" |
||||
if self == BinaryOperationType.RIGHT_SHIFT: |
||||
return ">>" |
||||
if self == BinaryOperationType.AND: |
||||
return "&" |
||||
if self == BinaryOperationType.CARET: |
||||
return "^" |
||||
if self == BinaryOperationType.OR: |
||||
return "|" |
||||
if self == BinaryOperationType.LESS: |
||||
return "<" |
||||
if self == BinaryOperationType.GREATER: |
||||
return ">" |
||||
if self == BinaryOperationType.LESS_EQUAL: |
||||
return "<=" |
||||
if self == BinaryOperationType.GREATER_EQUAL: |
||||
return ">=" |
||||
if self == BinaryOperationType.EQUAL: |
||||
return "==" |
||||
if self == BinaryOperationType.NOT_EQUAL: |
||||
return "!=" |
||||
if self == BinaryOperationType.ANDAND: |
||||
return "&&" |
||||
if self == BinaryOperationType.OROR: |
||||
return "||" |
||||
raise SlitherCoreError("str: Unknown operation type {})".format(self)) |
||||
|
||||
class BinaryOperation(ExpressionTyped): |
||||
|
||||
class BinaryOperation(ExpressionTyped): |
||||
def __init__(self, left_expression, right_expression, expression_type): |
||||
assert isinstance(left_expression, Expression) |
||||
assert isinstance(right_expression, Expression) |
||||
super(BinaryOperation, self).__init__() |
||||
self._expressions = [left_expression, right_expression] |
||||
self._type = expression_type |
||||
self._type: BinaryOperationType = expression_type |
||||
|
||||
@property |
||||
def expressions(self): |
||||
def expressions(self) -> List[Expression]: |
||||
return self._expressions |
||||
|
||||
@property |
||||
def expression_left(self): |
||||
def expression_left(self) -> Expression: |
||||
return self._expressions[0] |
||||
|
||||
@property |
||||
def expression_right(self): |
||||
def expression_right(self) -> Expression: |
||||
return self._expressions[1] |
||||
|
||||
@property |
||||
def type(self): |
||||
def type(self) -> BinaryOperationType: |
||||
return self._type |
||||
|
||||
@property |
||||
def type_str(self): |
||||
return BinaryOperationType.str(self._type) |
||||
|
||||
def __str__(self): |
||||
return str(self.expression_left) + ' ' + self.type_str + ' ' + str(self.expression_right) |
||||
|
||||
return str(self.expression_left) + " " + str(self.type) + " " + str(self.expression_right) |
||||
|
@ -1,32 +1,40 @@ |
||||
from typing import List |
||||
|
||||
from .expression import Expression |
||||
|
||||
class ConditionalExpression(Expression): |
||||
|
||||
class ConditionalExpression(Expression): |
||||
def __init__(self, if_expression, then_expression, else_expression): |
||||
assert isinstance(if_expression, Expression) |
||||
assert isinstance(then_expression, Expression) |
||||
assert isinstance(else_expression, Expression) |
||||
super(ConditionalExpression, self).__init__() |
||||
self._if_expression = if_expression |
||||
self._then_expression = then_expression |
||||
self._else_expression = else_expression |
||||
self._if_expression: Expression = if_expression |
||||
self._then_expression: Expression = then_expression |
||||
self._else_expression: Expression = else_expression |
||||
|
||||
@property |
||||
def expressions(self): |
||||
def expressions(self) -> List[Expression]: |
||||
return [self._if_expression, self._then_expression, self._else_expression] |
||||
|
||||
@property |
||||
def if_expression(self): |
||||
def if_expression(self) -> Expression: |
||||
return self._if_expression |
||||
|
||||
@property |
||||
def else_expression(self): |
||||
def else_expression(self) -> Expression: |
||||
return self._else_expression |
||||
|
||||
@property |
||||
def then_expression(self): |
||||
def then_expression(self) -> Expression: |
||||
return self._then_expression |
||||
|
||||
def __str__(self): |
||||
return 'if ' + str(self._if_expression) + ' then ' + str(self._then_expression) + ' else ' + str(self._else_expression) |
||||
|
||||
return ( |
||||
"if " |
||||
+ str(self._if_expression) |
||||
+ " then " |
||||
+ str(self._then_expression) |
||||
+ " else " |
||||
+ str(self._else_expression) |
||||
) |
||||
|
@ -1,32 +1,36 @@ |
||||
from typing import List, TYPE_CHECKING |
||||
|
||||
from slither.core.expressions.expression_typed import ExpressionTyped |
||||
from slither.core.solidity_types.type import Type |
||||
|
||||
|
||||
class IndexAccess(ExpressionTyped): |
||||
if TYPE_CHECKING: |
||||
from slither.core.expressions.expression import Expression |
||||
from slither.core.solidity_types.type import Type |
||||
|
||||
|
||||
class IndexAccess(ExpressionTyped): |
||||
def __init__(self, left_expression, right_expression, index_type): |
||||
super(IndexAccess, self).__init__() |
||||
self._expressions = [left_expression, right_expression] |
||||
# TODO type of undexAccess is not always a Type |
||||
# assert isinstance(index_type, Type) |
||||
self._type = index_type |
||||
# assert isinstance(index_type, Type) |
||||
self._type: "Type" = index_type |
||||
|
||||
@property |
||||
def expressions(self): |
||||
def expressions(self) -> List["Expression"]: |
||||
return self._expressions |
||||
|
||||
@property |
||||
def expression_left(self): |
||||
def expression_left(self) -> "Expression": |
||||
return self._expressions[0] |
||||
|
||||
@property |
||||
def expression_right(self): |
||||
def expression_right(self) -> "Expression": |
||||
return self._expressions[1] |
||||
|
||||
@property |
||||
def type(self): |
||||
def type(self) -> "Type": |
||||
return self._type |
||||
|
||||
def __str__(self): |
||||
return str(self.expression_left) + '[' + str(self.expression_right) + ']' |
||||
|
||||
return str(self.expression_left) + "[" + str(self.expression_right) + "]" |
||||
|
@ -1,29 +1,33 @@ |
||||
from typing import TYPE_CHECKING |
||||
|
||||
from slither.core.expressions.expression import Expression |
||||
from slither.core.expressions.expression_typed import ExpressionTyped |
||||
|
||||
if TYPE_CHECKING: |
||||
from slither.core.solidity_types.type import Type |
||||
|
||||
class MemberAccess(ExpressionTyped): |
||||
|
||||
class MemberAccess(ExpressionTyped): |
||||
def __init__(self, member_name, member_type, expression): |
||||
# assert isinstance(member_type, Type) |
||||
# TODO member_type is not always a Type |
||||
assert isinstance(expression, Expression) |
||||
super(MemberAccess, self).__init__() |
||||
self._type = member_type |
||||
self._member_name = member_name |
||||
self._expression = expression |
||||
self._type: "Type" = member_type |
||||
self._member_name: str = member_name |
||||
self._expression: Expression = expression |
||||
|
||||
@property |
||||
def expression(self): |
||||
def expression(self) -> Expression: |
||||
return self._expression |
||||
|
||||
@property |
||||
def member_name(self): |
||||
def member_name(self) -> str: |
||||
return self._member_name |
||||
|
||||
@property |
||||
def type(self): |
||||
def type(self) -> "Type": |
||||
return self._type |
||||
|
||||
def __str__(self): |
||||
return str(self.expression) + '.' + self.member_name |
||||
return str(self.expression) + "." + self.member_name |
||||
|
@ -1,23 +1,23 @@ |
||||
from slither.core.expressions.expression import Expression |
||||
from slither.core.solidity_types.type import Type |
||||
|
||||
|
||||
class NewArray(Expression): |
||||
|
||||
# note: dont conserve the size of the array if provided |
||||
def __init__(self, depth, array_type): |
||||
super(NewArray, self).__init__() |
||||
assert isinstance(array_type, Type) |
||||
self._depth = depth |
||||
self._array_type = array_type |
||||
self._depth: int = depth |
||||
self._array_type: Type = array_type |
||||
|
||||
@property |
||||
def array_type(self): |
||||
def array_type(self) -> Type: |
||||
return self._array_type |
||||
|
||||
@property |
||||
def depth(self): |
||||
def depth(self) -> int: |
||||
return self._depth |
||||
|
||||
def __str__(self): |
||||
return 'new ' + str(self._array_type) + '[]'* self._depth |
||||
|
||||
return "new " + str(self._array_type) + "[]" * self._depth |
||||
|
@ -1,17 +1,16 @@ |
||||
from slither.core.expressions.expression import Expression |
||||
from slither.core.solidity_types.elementary_type import ElementaryType |
||||
|
||||
class NewElementaryType(Expression): |
||||
|
||||
class NewElementaryType(Expression): |
||||
def __init__(self, new_type): |
||||
assert isinstance(new_type, ElementaryType) |
||||
super(NewElementaryType, self).__init__() |
||||
self._type = new_type |
||||
|
||||
@property |
||||
def type(self): |
||||
def type(self) -> ElementaryType: |
||||
return self._type |
||||
|
||||
def __str__(self): |
||||
return 'new ' + str(self._type) |
||||
|
||||
return "new " + str(self._type) |
||||
|
@ -1,4 +1,6 @@ |
||||
from slither.core.expressions.expression import Expression |
||||
from slither.core.expressions.call_expression import CallExpression |
||||
|
||||
class SuperCallExpression(CallExpression): pass |
||||
|
||||
class SuperCallExpression(CallExpression): |
||||
pass |
||||
|
@ -1,8 +1,6 @@ |
||||
from slither.core.expressions.expression_typed import ExpressionTyped |
||||
from slither.core.expressions.identifier import Identifier |
||||
|
||||
class SuperIdentifier(Identifier): |
||||
|
||||
class SuperIdentifier(Identifier): |
||||
def __str__(self): |
||||
return 'super.' + str(self._value) |
||||
|
||||
return "super." + str(self._value) |
||||
|
@ -1,17 +1,18 @@ |
||||
from typing import List |
||||
|
||||
from slither.core.expressions.expression import Expression |
||||
|
||||
class TupleExpression(Expression): |
||||
|
||||
class TupleExpression(Expression): |
||||
def __init__(self, expressions): |
||||
assert all(isinstance(x, Expression) for x in expressions if x) |
||||
super(TupleExpression, self).__init__() |
||||
self._expressions = expressions |
||||
|
||||
@property |
||||
def expressions(self): |
||||
def expressions(self) -> List[Expression]: |
||||
return self._expressions |
||||
|
||||
def __str__(self): |
||||
expressions_str = [str(e) for e in self.expressions] |
||||
return '(' + ','.join(expressions_str) + ')' |
||||
|
||||
return "(" + ",".join(expressions_str) + ")" |
||||
|
@ -1,114 +1,121 @@ |
||||
import logging |
||||
from enum import Enum |
||||
|
||||
from slither.core.expressions.expression_typed import ExpressionTyped |
||||
from slither.core.expressions.expression import Expression |
||||
from slither.core.exceptions import SlitherCoreError |
||||
|
||||
logger = logging.getLogger("UnaryOperation") |
||||
|
||||
class UnaryOperationType: |
||||
BANG = 0 # ! |
||||
TILD = 1 # ~ |
||||
DELETE = 2 # delete |
||||
PLUSPLUS_PRE = 3 # ++ |
||||
MINUSMINUS_PRE = 4 # -- |
||||
PLUSPLUS_POST = 5 # ++ |
||||
MINUSMINUS_POST = 6 # -- |
||||
PLUS_PRE = 7 # for stuff like uint(+1) |
||||
MINUS_PRE = 8 # for stuff like uint(-1) |
||||
|
||||
class UnaryOperationType(Enum): |
||||
BANG = 0 # ! |
||||
TILD = 1 # ~ |
||||
DELETE = 2 # delete |
||||
PLUSPLUS_PRE = 3 # ++ |
||||
MINUSMINUS_PRE = 4 # -- |
||||
PLUSPLUS_POST = 5 # ++ |
||||
MINUSMINUS_POST = 6 # -- |
||||
PLUS_PRE = 7 # for stuff like uint(+1) |
||||
MINUS_PRE = 8 # for stuff like uint(-1) |
||||
|
||||
@staticmethod |
||||
def get_type(operation_type, isprefix): |
||||
if isprefix: |
||||
if operation_type == '!': |
||||
if operation_type == "!": |
||||
return UnaryOperationType.BANG |
||||
if operation_type == '~': |
||||
if operation_type == "~": |
||||
return UnaryOperationType.TILD |
||||
if operation_type == 'delete': |
||||
if operation_type == "delete": |
||||
return UnaryOperationType.DELETE |
||||
if operation_type == '++': |
||||
if operation_type == "++": |
||||
return UnaryOperationType.PLUSPLUS_PRE |
||||
if operation_type == '--': |
||||
if operation_type == "--": |
||||
return UnaryOperationType.MINUSMINUS_PRE |
||||
if operation_type == '+': |
||||
if operation_type == "+": |
||||
return UnaryOperationType.PLUS_PRE |
||||
if operation_type == '-': |
||||
if operation_type == "-": |
||||
return UnaryOperationType.MINUS_PRE |
||||
else: |
||||
if operation_type == '++': |
||||
if operation_type == "++": |
||||
return UnaryOperationType.PLUSPLUS_POST |
||||
if operation_type == '--': |
||||
if operation_type == "--": |
||||
return UnaryOperationType.MINUSMINUS_POST |
||||
raise SlitherCoreError('get_type: Unknown operation type {}'.format(operation_type)) |
||||
raise SlitherCoreError("get_type: Unknown operation type {}".format(operation_type)) |
||||
|
||||
@staticmethod |
||||
def str(operation_type): |
||||
if operation_type == UnaryOperationType.BANG: |
||||
return '!' |
||||
if operation_type == UnaryOperationType.TILD: |
||||
return '~' |
||||
if operation_type == UnaryOperationType.DELETE: |
||||
return 'delete' |
||||
if operation_type == UnaryOperationType.PLUS_PRE: |
||||
return '+' |
||||
if operation_type == UnaryOperationType.MINUS_PRE: |
||||
return '-' |
||||
if operation_type in [UnaryOperationType.PLUSPLUS_PRE, UnaryOperationType.PLUSPLUS_POST]: |
||||
return '++' |
||||
if operation_type in [UnaryOperationType.MINUSMINUS_PRE, UnaryOperationType.MINUSMINUS_POST]: |
||||
return '--' |
||||
def __str__(self): |
||||
if self == UnaryOperationType.BANG: |
||||
return "!" |
||||
if self == UnaryOperationType.TILD: |
||||
return "~" |
||||
if self == UnaryOperationType.DELETE: |
||||
return "delete" |
||||
if self == UnaryOperationType.PLUS_PRE: |
||||
return "+" |
||||
if self == UnaryOperationType.MINUS_PRE: |
||||
return "-" |
||||
if self in [UnaryOperationType.PLUSPLUS_PRE, UnaryOperationType.PLUSPLUS_POST]: |
||||
return "++" |
||||
if self in [ |
||||
UnaryOperationType.MINUSMINUS_PRE, |
||||
UnaryOperationType.MINUSMINUS_POST, |
||||
]: |
||||
return "--" |
||||
|
||||
raise SlitherCoreError('str: Unknown operation type {}'.format(operation_type)) |
||||
raise SlitherCoreError("str: Unknown operation type {}".format(self)) |
||||
|
||||
@staticmethod |
||||
def is_prefix(operation_type): |
||||
if operation_type in [UnaryOperationType.BANG, |
||||
UnaryOperationType.TILD, |
||||
UnaryOperationType.DELETE, |
||||
UnaryOperationType.PLUSPLUS_PRE, |
||||
UnaryOperationType.MINUSMINUS_PRE, |
||||
UnaryOperationType.PLUS_PRE, |
||||
UnaryOperationType.MINUS_PRE]: |
||||
if operation_type in [ |
||||
UnaryOperationType.BANG, |
||||
UnaryOperationType.TILD, |
||||
UnaryOperationType.DELETE, |
||||
UnaryOperationType.PLUSPLUS_PRE, |
||||
UnaryOperationType.MINUSMINUS_PRE, |
||||
UnaryOperationType.PLUS_PRE, |
||||
UnaryOperationType.MINUS_PRE, |
||||
]: |
||||
return True |
||||
elif operation_type in [UnaryOperationType.PLUSPLUS_POST, UnaryOperationType.MINUSMINUS_POST]: |
||||
elif operation_type in [ |
||||
UnaryOperationType.PLUSPLUS_POST, |
||||
UnaryOperationType.MINUSMINUS_POST, |
||||
]: |
||||
return False |
||||
|
||||
raise SlitherCoreError('is_prefix: Unknown operation type {}'.format(operation_type)) |
||||
raise SlitherCoreError("is_prefix: Unknown operation type {}".format(operation_type)) |
||||
|
||||
class UnaryOperation(ExpressionTyped): |
||||
|
||||
class UnaryOperation(ExpressionTyped): |
||||
def __init__(self, expression, expression_type): |
||||
assert isinstance(expression, Expression) |
||||
super(UnaryOperation, self).__init__() |
||||
self._expression = expression |
||||
self._type = expression_type |
||||
if expression_type in [UnaryOperationType.DELETE, |
||||
UnaryOperationType.PLUSPLUS_PRE, |
||||
UnaryOperationType.MINUSMINUS_PRE, |
||||
UnaryOperationType.PLUSPLUS_POST, |
||||
UnaryOperationType.MINUSMINUS_POST, |
||||
UnaryOperationType.PLUS_PRE, |
||||
UnaryOperationType.MINUS_PRE]: |
||||
self._expression: Expression = expression |
||||
self._type: UnaryOperationType = expression_type |
||||
if expression_type in [ |
||||
UnaryOperationType.DELETE, |
||||
UnaryOperationType.PLUSPLUS_PRE, |
||||
UnaryOperationType.MINUSMINUS_PRE, |
||||
UnaryOperationType.PLUSPLUS_POST, |
||||
UnaryOperationType.MINUSMINUS_POST, |
||||
UnaryOperationType.PLUS_PRE, |
||||
UnaryOperationType.MINUS_PRE, |
||||
]: |
||||
expression.set_lvalue() |
||||
|
||||
@property |
||||
def expression(self): |
||||
def expression(self) -> Expression: |
||||
return self._expression |
||||
|
||||
@property |
||||
def type_str(self): |
||||
return UnaryOperationType.str(self._type) |
||||
|
||||
@property |
||||
def type(self): |
||||
def type(self) -> UnaryOperationType: |
||||
return self._type |
||||
|
||||
@property |
||||
def is_prefix(self): |
||||
def is_prefix(self) -> bool: |
||||
return UnaryOperationType.is_prefix(self._type) |
||||
|
||||
def __str__(self): |
||||
if self.is_prefix: |
||||
return self.type_str + ' ' + str(self._expression) |
||||
return str(self.type) + " " + str(self._expression) |
||||
else: |
||||
return str(self._expression) + ' ' + self.type_str |
||||
|
||||
return str(self._expression) + " " + str(self.type) |
||||
|
@ -1,3 +1,5 @@ |
||||
from slither.core.source_mapping.source_mapping import SourceMapping |
||||
|
||||
class Type(SourceMapping): pass |
||||
|
||||
class Type(SourceMapping): |
||||
pass |
||||
|
@ -1,23 +1,29 @@ |
||||
from typing import TYPE_CHECKING |
||||
|
||||
from slither.core.solidity_types.type import Type |
||||
|
||||
if TYPE_CHECKING: |
||||
from slither.core.declarations.contract import Contract |
||||
|
||||
|
||||
# Use to model the Type(X) function, which returns an undefined type |
||||
# https://solidity.readthedocs.io/en/latest/units-and-global-variables.html#type-information |
||||
class TypeInformation(Type): |
||||
def __init__(self, c): |
||||
from slither.core.declarations.contract import Contract |
||||
|
||||
assert isinstance(c, (Contract)) |
||||
assert isinstance(c, Contract) |
||||
super(TypeInformation, self).__init__() |
||||
self._type = c |
||||
|
||||
@property |
||||
def type(self): |
||||
def type(self) -> "Contract": |
||||
return self._type |
||||
|
||||
def __str__(self): |
||||
return f'type({self.type.name})' |
||||
return f"type({self.type.name})" |
||||
|
||||
def __eq__(self, other): |
||||
if not isinstance(other, TypeInformation): |
||||
return False |
||||
return self.type == other.type |
||||
return self.type == other.type |
||||
|
@ -1,16 +1,20 @@ |
||||
from .variable import Variable |
||||
from slither.core.children.child_event import ChildEvent |
||||
|
||||
|
||||
class EventVariable(ChildEvent, Variable): |
||||
def __init__(self): |
||||
super(EventVariable, self).__init__() |
||||
self._indexed = False |
||||
|
||||
@property |
||||
def indexed(self): |
||||
def indexed(self) -> bool: |
||||
""" |
||||
Indicates whether the event variable is indexed in the bloom filter. |
||||
:return: Returns True if the variable is indexed in bloom filter, False otherwise. |
||||
""" |
||||
return self._indexed |
||||
|
||||
@indexed.setter |
||||
def indexed(self, is_indexed: bool): |
||||
self._indexed = is_indexed |
||||
|
@ -1,5 +1,6 @@ |
||||
from .variable import Variable |
||||
from slither.core.children.child_structure import ChildStructure |
||||
|
||||
class StructureVariable(ChildStructure, Variable): pass |
||||
|
||||
class StructureVariable(ChildStructure, Variable): |
||||
pass |
||||
|
@ -1,68 +1,64 @@ |
||||
from typing import Optional, Dict |
||||
|
||||
from slither.core.cfg.node import Node |
||||
from slither.core.cfg.node import NodeType |
||||
from slither.core.expressions.assignment_operation import ( |
||||
AssignmentOperation, |
||||
AssignmentOperationType, |
||||
) |
||||
from slither.core.expressions.identifier import Identifier |
||||
from slither.solc_parsing.expressions.expression_parsing import parse_expression |
||||
from slither.visitors.expression.find_calls import FindCalls |
||||
from slither.visitors.expression.read_var import ReadVar |
||||
from slither.visitors.expression.write_var import WriteVar |
||||
from slither.visitors.expression.find_calls import FindCalls |
||||
|
||||
from slither.visitors.expression.export_values import ExportValues |
||||
from slither.core.declarations.solidity_variables import SolidityVariable, SolidityFunction |
||||
from slither.core.declarations.function import Function |
||||
|
||||
from slither.core.variables.state_variable import StateVariable |
||||
|
||||
from slither.core.expressions.identifier import Identifier |
||||
from slither.core.expressions.assignment_operation import AssignmentOperation, AssignmentOperationType |
||||
|
||||
class NodeSolc(Node): |
||||
class NodeSolc: |
||||
def __init__(self, node: Node): |
||||
self._unparsed_expression: Optional[Dict] = None |
||||
self._node = node |
||||
|
||||
def __init__(self, nodeType, nodeId): |
||||
super(NodeSolc, self).__init__(nodeType, nodeId) |
||||
self._unparsed_expression = None |
||||
@property |
||||
def underlying_node(self) -> Node: |
||||
return self._node |
||||
|
||||
def add_unparsed_expression(self, expression): |
||||
def add_unparsed_expression(self, expression: Dict): |
||||
assert self._unparsed_expression is None |
||||
self._unparsed_expression = expression |
||||
|
||||
def analyze_expressions(self, caller_context): |
||||
if self.type == NodeType.VARIABLE and not self._expression: |
||||
self._expression = self.variable_declaration.expression |
||||
if self._node.type == NodeType.VARIABLE and not self._node.expression: |
||||
self._node.add_expression(self._node.variable_declaration.expression) |
||||
if self._unparsed_expression: |
||||
expression = parse_expression(self._unparsed_expression, caller_context) |
||||
self._expression = expression |
||||
self._unparsed_expression = None |
||||
self._node.add_expression(expression) |
||||
# self._unparsed_expression = None |
||||
|
||||
if self.expression: |
||||
if self._node.expression: |
||||
|
||||
if self.type == NodeType.VARIABLE: |
||||
if self._node.type == NodeType.VARIABLE: |
||||
# Update the expression to be an assignement to the variable |
||||
#print(self.variable_declaration) |
||||
_expression = AssignmentOperation(Identifier(self.variable_declaration), |
||||
self.expression, |
||||
AssignmentOperationType.ASSIGN, |
||||
self.variable_declaration.type) |
||||
_expression.set_offset(self.expression.source_mapping, self.slither) |
||||
self._expression = _expression |
||||
|
||||
expression = self.expression |
||||
pp = ReadVar(expression) |
||||
self._expression_vars_read = pp.result() |
||||
|
||||
# self._vars_read = [item for sublist in vars_read for item in sublist] |
||||
# self._state_vars_read = [x for x in self.variables_read if\ |
||||
# isinstance(x, (StateVariable))] |
||||
# self._solidity_vars_read = [x for x in self.variables_read if\ |
||||
# isinstance(x, (SolidityVariable))] |
||||
|
||||
pp = WriteVar(expression) |
||||
self._expression_vars_written = pp.result() |
||||
_expression = AssignmentOperation( |
||||
Identifier(self._node.variable_declaration), |
||||
self._node.expression, |
||||
AssignmentOperationType.ASSIGN, |
||||
self._node.variable_declaration.type, |
||||
) |
||||
_expression.set_offset(self._node.expression.source_mapping, self._node.slither) |
||||
self._node.add_expression(_expression, bypass_verif_empty=True) |
||||
|
||||
# self._vars_written = [item for sublist in vars_written for item in sublist] |
||||
# self._state_vars_written = [x for x in self.variables_written if\ |
||||
# isinstance(x, StateVariable)] |
||||
expression = self._node.expression |
||||
read_var = ReadVar(expression) |
||||
self._node.variables_read_as_expression = read_var.result() |
||||
|
||||
pp = FindCalls(expression) |
||||
self._expression_calls = pp.result() |
||||
self._external_calls_as_expressions = [c for c in self.calls_as_expression if not isinstance(c.called, Identifier)] |
||||
self._internal_calls_as_expressions = [c for c in self.calls_as_expression if isinstance(c.called, Identifier)] |
||||
write_var = WriteVar(expression) |
||||
self._node.variables_written_as_expression = write_var.result() |
||||
|
||||
find_call = FindCalls(expression) |
||||
self._node.calls_as_expression = find_call.result() |
||||
self._node.external_calls_as_expressions = [ |
||||
c for c in self._node.calls_as_expression if not isinstance(c.called, Identifier) |
||||
] |
||||
self._node.internal_calls_as_expressions = [ |
||||
c for c in self._node.calls_as_expression if isinstance(c.called, Identifier) |
||||
] |
||||
|
@ -1,43 +1,55 @@ |
||||
""" |
||||
Event module |
||||
""" |
||||
from typing import TYPE_CHECKING, Dict |
||||
|
||||
from slither.core.variables.event_variable import EventVariable |
||||
from slither.solc_parsing.variables.event_variable import EventVariableSolc |
||||
from slither.core.declarations.event import Event |
||||
|
||||
class EventSolc(Event): |
||||
if TYPE_CHECKING: |
||||
from slither.solc_parsing.declarations.contract import ContractSolc |
||||
|
||||
|
||||
class EventSolc: |
||||
""" |
||||
Event class |
||||
""" |
||||
|
||||
def __init__(self, event, contract): |
||||
super(EventSolc, self).__init__() |
||||
self._contract = contract |
||||
def __init__(self, event: Event, event_data: Dict, contract_parser: "ContractSolc"): |
||||
|
||||
self._event = event |
||||
event.set_contract(contract_parser.underlying_contract) |
||||
self._parser_contract = contract_parser |
||||
|
||||
self._elems = [] |
||||
if self.is_compact_ast: |
||||
self._name = event['name'] |
||||
elems = event['parameters'] |
||||
assert elems['nodeType'] == 'ParameterList' |
||||
self._elemsNotParsed = elems['parameters'] |
||||
self._event.name = event_data["name"] |
||||
elems = event_data["parameters"] |
||||
assert elems["nodeType"] == "ParameterList" |
||||
self._elemsNotParsed = elems["parameters"] |
||||
else: |
||||
self._name = event['attributes']['name'] |
||||
elems = event['children'][0] |
||||
self._event.name = event_data["attributes"]["name"] |
||||
elems = event_data["children"][0] |
||||
|
||||
assert elems['name'] == 'ParameterList' |
||||
if 'children' in elems: |
||||
self._elemsNotParsed = elems['children'] |
||||
assert elems["name"] == "ParameterList" |
||||
if "children" in elems: |
||||
self._elemsNotParsed = elems["children"] |
||||
else: |
||||
self._elemsNotParsed = [] |
||||
|
||||
@property |
||||
def is_compact_ast(self): |
||||
return self.contract.is_compact_ast |
||||
def is_compact_ast(self) -> bool: |
||||
return self._parser_contract.is_compact_ast |
||||
|
||||
def analyze(self, contract): |
||||
def analyze(self, contract: "ContractSolc"): |
||||
for elem_to_parse in self._elemsNotParsed: |
||||
elem = EventVariableSolc(elem_to_parse) |
||||
elem.analyze(contract) |
||||
self._elems.append(elem) |
||||
elem = EventVariable() |
||||
# Todo: check if the source offset is always here |
||||
if "src" in elem_to_parse: |
||||
elem.set_offset(elem_to_parse["src"], self._parser_contract.slither) |
||||
elem_parser = EventVariableSolc(elem, elem_to_parse) |
||||
elem_parser.analyze(contract) |
||||
|
||||
self._elemsNotParsed = [] |
||||
self._event.elems.append(elem) |
||||
|
||||
self._elemsNotParsed = [] |
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,9 @@ |
||||
from slither.exceptions import SlitherException |
||||
|
||||
class ParsingError(SlitherException): pass |
||||
|
||||
class VariableNotFound(SlitherException): pass |
||||
class ParsingError(SlitherException): |
||||
pass |
||||
|
||||
|
||||
class VariableNotFound(SlitherException): |
||||
pass |
||||
|
@ -1,5 +1,15 @@ |
||||
from typing import Dict |
||||
|
||||
from slither.solc_parsing.variables.variable_declaration import VariableDeclarationSolc |
||||
from slither.core.variables.function_type_variable import FunctionTypeVariable |
||||
|
||||
class FunctionTypeVariableSolc(VariableDeclarationSolc, FunctionTypeVariable): pass |
||||
|
||||
class FunctionTypeVariableSolc(VariableDeclarationSolc): |
||||
def __init__(self, variable: FunctionTypeVariable, variable_data: Dict): |
||||
super(FunctionTypeVariableSolc, self).__init__(variable, variable_data) |
||||
|
||||
@property |
||||
def underlying_variable(self) -> FunctionTypeVariable: |
||||
# Todo: Not sure how to overcome this with mypy |
||||
assert isinstance(self._variable, FunctionTypeVariable) |
||||
return self._variable |
||||
|
@ -1,11 +1,16 @@ |
||||
from typing import Dict |
||||
|
||||
from .variable_declaration import VariableDeclarationSolc |
||||
from slither.core.variables.local_variable_init_from_tuple import LocalVariableInitFromTuple |
||||
|
||||
class LocalVariableInitFromTupleSolc(VariableDeclarationSolc, LocalVariableInitFromTuple): |
||||
|
||||
def __init__(self, var, index): |
||||
super(LocalVariableInitFromTupleSolc, self).__init__(var) |
||||
self._tuple_index = index |
||||
|
||||
class LocalVariableInitFromTupleSolc(VariableDeclarationSolc): |
||||
def __init__(self, variable: LocalVariableInitFromTuple, variable_data: Dict, index: int): |
||||
super(LocalVariableInitFromTupleSolc, self).__init__(variable, variable_data) |
||||
variable.tuple_index = index |
||||
|
||||
@property |
||||
def underlying_variable(self) -> LocalVariableInitFromTuple: |
||||
# Todo: Not sure how to overcome this with mypy |
||||
assert isinstance(self._variable, LocalVariableInitFromTuple) |
||||
return self._variable |
||||
|
@ -1,5 +1,15 @@ |
||||
from typing import Dict |
||||
|
||||
from .variable_declaration import VariableDeclarationSolc |
||||
from slither.core.variables.state_variable import StateVariable |
||||
|
||||
class StateVariableSolc(VariableDeclarationSolc, StateVariable): pass |
||||
|
||||
class StateVariableSolc(VariableDeclarationSolc): |
||||
def __init__(self, variable: StateVariable, variable_data: Dict): |
||||
super(StateVariableSolc, self).__init__(variable, variable_data) |
||||
|
||||
@property |
||||
def underlying_variable(self) -> StateVariable: |
||||
# Todo: Not sure how to overcome this with mypy |
||||
assert isinstance(self._variable, StateVariable) |
||||
return self._variable |
||||
|
@ -1,5 +1,15 @@ |
||||
from typing import Dict |
||||
|
||||
from .variable_declaration import VariableDeclarationSolc |
||||
from slither.core.variables.structure_variable import StructureVariable |
||||
|
||||
class StructureVariableSolc(VariableDeclarationSolc, StructureVariable): pass |
||||
|
||||
class StructureVariableSolc(VariableDeclarationSolc): |
||||
def __init__(self, variable: StructureVariable, variable_data: Dict): |
||||
super(StructureVariableSolc, self).__init__(variable, variable_data) |
||||
|
||||
@property |
||||
def underlying_variable(self) -> StructureVariable: |
||||
# Todo: Not sure how to overcome this with mypy |
||||
assert isinstance(self._variable, StructureVariable) |
||||
return self._variable |
||||
|
@ -1,65 +1,76 @@ |
||||
from slither.tools.properties.properties.properties import Property, PropertyType, PropertyReturn, PropertyCaller |
||||
from slither.tools.properties.properties.properties import ( |
||||
Property, |
||||
PropertyType, |
||||
PropertyReturn, |
||||
PropertyCaller, |
||||
) |
||||
|
||||
ERC20_CONFIG = [ |
||||
|
||||
Property(name='init_total_supply()', |
||||
description='The total supply is correctly initialized.', |
||||
content=''' |
||||
\t\treturn this.totalSupply() >= 0 && this.totalSupply() == initialTotalSupply;''', |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ANY), |
||||
|
||||
Property(name='init_owner_balance()', |
||||
description="Owner's balance is correctly initialized.", |
||||
content=''' |
||||
\t\treturn initialBalance_owner == this.balanceOf(crytic_owner);''', |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ANY), |
||||
|
||||
Property(name='init_user_balance()', |
||||
description="User's balance is correctly initialized.", |
||||
content=''' |
||||
\t\treturn initialBalance_user == this.balanceOf(crytic_user);''', |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ANY), |
||||
|
||||
Property(name='init_attacker_balance()', |
||||
description="Attacker's balance is correctly initialized.", |
||||
content=''' |
||||
\t\treturn initialBalance_attacker == this.balanceOf(crytic_attacker);''', |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ANY), |
||||
|
||||
Property(name='init_caller_balance()', |
||||
description="All the users have a positive balance.", |
||||
content=''' |
||||
\t\treturn this.balanceOf(msg.sender) >0 ;''', |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ALL), |
||||
|
||||
Property( |
||||
name="init_total_supply()", |
||||
description="The total supply is correctly initialized.", |
||||
content=""" |
||||
\t\treturn this.totalSupply() >= 0 && this.totalSupply() == initialTotalSupply;""", |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ANY, |
||||
), |
||||
Property( |
||||
name="init_owner_balance()", |
||||
description="Owner's balance is correctly initialized.", |
||||
content=""" |
||||
\t\treturn initialBalance_owner == this.balanceOf(crytic_owner);""", |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ANY, |
||||
), |
||||
Property( |
||||
name="init_user_balance()", |
||||
description="User's balance is correctly initialized.", |
||||
content=""" |
||||
\t\treturn initialBalance_user == this.balanceOf(crytic_user);""", |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ANY, |
||||
), |
||||
Property( |
||||
name="init_attacker_balance()", |
||||
description="Attacker's balance is correctly initialized.", |
||||
content=""" |
||||
\t\treturn initialBalance_attacker == this.balanceOf(crytic_attacker);""", |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ANY, |
||||
), |
||||
Property( |
||||
name="init_caller_balance()", |
||||
description="All the users have a positive balance.", |
||||
content=""" |
||||
\t\treturn this.balanceOf(msg.sender) >0 ;""", |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ALL, |
||||
), |
||||
# Note: there is a potential overflow on the addition, but we dont consider it |
||||
Property(name='init_total_supply_is_balances()', |
||||
description="The total supply is the user and owner balance.", |
||||
content=''' |
||||
\t\treturn this.balanceOf(crytic_owner) + this.balanceOf(crytic_user) + this.balanceOf(crytic_attacker) == this.totalSupply();''', |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ANY), |
||||
] |
||||
Property( |
||||
name="init_total_supply_is_balances()", |
||||
description="The total supply is the user and owner balance.", |
||||
content=""" |
||||
\t\treturn this.balanceOf(crytic_owner) + this.balanceOf(crytic_user) + this.balanceOf(crytic_attacker) == this.totalSupply();""", |
||||
type=PropertyType.CODE_QUALITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=False, |
||||
caller=PropertyCaller.ANY, |
||||
), |
||||
] |
||||
|
@ -1,13 +1,20 @@ |
||||
from slither.tools.properties.properties.properties import PropertyType, PropertyReturn, Property, PropertyCaller |
||||
from slither.tools.properties.properties.properties import ( |
||||
PropertyType, |
||||
PropertyReturn, |
||||
Property, |
||||
PropertyCaller, |
||||
) |
||||
|
||||
ERC20_NotMintable = [ |
||||
Property(name='crytic_supply_constant_ERC20PropertiesNotMintable()', |
||||
description='The total supply does not increase.', |
||||
content=''' |
||||
\t\treturn initialTotalSupply >= totalSupply();''', |
||||
type=PropertyType.MEDIUM_SEVERITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=True, |
||||
caller=PropertyCaller.ANY), |
||||
Property( |
||||
name="crytic_supply_constant_ERC20PropertiesNotMintable()", |
||||
description="The total supply does not increase.", |
||||
content=""" |
||||
\t\treturn initialTotalSupply >= totalSupply();""", |
||||
type=PropertyType.MEDIUM_SEVERITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=True, |
||||
caller=PropertyCaller.ANY, |
||||
), |
||||
] |
||||
|
@ -1,14 +1,20 @@ |
||||
from slither.tools.properties.properties.properties import Property, PropertyType, PropertyReturn, PropertyCaller |
||||
from slither.tools.properties.properties.properties import ( |
||||
Property, |
||||
PropertyType, |
||||
PropertyReturn, |
||||
PropertyCaller, |
||||
) |
||||
|
||||
ERC20_NotMintableNotBurnable = [ |
||||
|
||||
Property(name='crytic_supply_constant_ERC20PropertiesNotMintableNotBurnable()', |
||||
description='The total supply does not change.', |
||||
content=''' |
||||
\t\treturn initialTotalSupply == this.totalSupply();''', |
||||
type=PropertyType.MEDIUM_SEVERITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=True, |
||||
caller=PropertyCaller.ANY), |
||||
] |
||||
Property( |
||||
name="crytic_supply_constant_ERC20PropertiesNotMintableNotBurnable()", |
||||
description="The total supply does not change.", |
||||
content=""" |
||||
\t\treturn initialTotalSupply == this.totalSupply();""", |
||||
type=PropertyType.MEDIUM_SEVERITY, |
||||
return_type=PropertyReturn.SUCCESS, |
||||
is_unit_test=True, |
||||
is_property_test=True, |
||||
caller=PropertyCaller.ANY, |
||||
), |
||||
] |
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue