mirror of https://github.com/ConsenSys/mythril
commit
adec5f608e
@ -1,77 +1,100 @@ |
|||||||
"""This module contains the class used to represent state-change constraints in |
"""This module contains the class used to represent state-change constraints in |
||||||
the call graph.""" |
the call graph.""" |
||||||
|
|
||||||
|
from mythril.laser.smt import Solver, Bool |
||||||
|
|
||||||
|
from typing import Iterable, List, Optional |
||||||
|
from z3 import unsat |
||||||
|
|
||||||
|
|
||||||
class Constraints(list): |
class Constraints(list): |
||||||
"""This class should maintain a solver and it's constraints, This class |
"""This class should maintain a solver and it's constraints, This class |
||||||
tries to make the Constraints() object as a simple list of constraints with |
tries to make the Constraints() object as a simple list of constraints with |
||||||
some background processing. |
some background processing. |
||||||
|
|
||||||
TODO: add the solver to this class after callback refactor |
|
||||||
""" |
""" |
||||||
|
|
||||||
def __init__(self, constraint_list=None, solver=None, possibility=None): |
def __init__( |
||||||
|
self, |
||||||
|
constraint_list: Optional[List[Bool]] = None, |
||||||
|
is_possible: Optional[bool] = None, |
||||||
|
) -> None: |
||||||
""" |
""" |
||||||
|
|
||||||
:param constraint_list: |
:param constraint_list: List of constraints |
||||||
:param solver: |
:param is_possible: Whether it is possible to satisfy the constraints or not |
||||||
:param possibility: |
|
||||||
""" |
""" |
||||||
super(Constraints, self).__init__(constraint_list or []) |
super(Constraints, self).__init__(constraint_list or []) |
||||||
self.solver = solver |
self._default_timeout = 100 |
||||||
self.__possibility = possibility |
self._is_possible = is_possible |
||||||
|
|
||||||
def check_possibility(self): |
@property |
||||||
|
def is_possible(self) -> bool: |
||||||
""" |
""" |
||||||
|
:return: True/False based on the existence of solution of constraints |
||||||
:return: |
|
||||||
""" |
""" |
||||||
return True |
if self._is_possible is not None: |
||||||
|
return self._is_possible |
||||||
|
solver = Solver() |
||||||
|
solver.set_timeout(self._default_timeout) |
||||||
|
for constraint in self[:]: |
||||||
|
solver.add(constraint) |
||||||
|
self._is_possible = solver.check() != unsat |
||||||
|
return self._is_possible |
||||||
|
|
||||||
def append(self, constraint): |
def append(self, constraint: Bool) -> None: |
||||||
""" |
""" |
||||||
|
|
||||||
:param constraint: |
:param constraint: The constraint to be appended |
||||||
""" |
""" |
||||||
super(Constraints, self).append(constraint) |
super(Constraints, self).append(constraint) |
||||||
|
self._is_possible = None |
||||||
|
|
||||||
def pop(self, index=-1): |
def pop(self, index: int = -1) -> None: |
||||||
""" |
""" |
||||||
|
|
||||||
:param index: |
:param index: Index to be popped from the list |
||||||
""" |
""" |
||||||
raise NotImplementedError |
raise NotImplementedError |
||||||
|
|
||||||
def __copy__(self): |
@property |
||||||
|
def as_list(self) -> List[Bool]: |
||||||
|
""" |
||||||
|
:return: returns the list of constraints |
||||||
|
""" |
||||||
|
return self[:] |
||||||
|
|
||||||
|
def __copy__(self) -> "Constraints": |
||||||
""" |
""" |
||||||
|
|
||||||
:return: |
:return: The copied constraint List |
||||||
""" |
""" |
||||||
constraint_list = super(Constraints, self).copy() |
constraint_list = super(Constraints, self).copy() |
||||||
return Constraints(constraint_list) |
return Constraints(constraint_list, is_possible=self._is_possible) |
||||||
|
|
||||||
def __deepcopy__(self, memodict=None): |
def __deepcopy__(self, memodict=None) -> "Constraints": |
||||||
""" |
""" |
||||||
|
|
||||||
:param memodict: |
:param memodict: |
||||||
:return: |
:return: The copied constraint List |
||||||
""" |
""" |
||||||
return self.__copy__() |
return self.__copy__() |
||||||
|
|
||||||
def __add__(self, constraints): |
def __add__(self, constraints: List[Bool]) -> "Constraints": |
||||||
""" |
""" |
||||||
|
|
||||||
:param constraints: |
:param constraints: |
||||||
:return: |
:return: the new list after the + operation |
||||||
""" |
""" |
||||||
constraints_list = super(Constraints, self).__add__(constraints) |
constraints_list = super(Constraints, self).__add__(constraints) |
||||||
return Constraints(constraint_list=constraints_list) |
return Constraints(constraint_list=constraints_list, is_possible=None) |
||||||
|
|
||||||
def __iadd__(self, constraints): |
def __iadd__(self, constraints: Iterable[Bool]) -> "Constraints": |
||||||
""" |
""" |
||||||
|
|
||||||
:param constraints: |
:param constraints: |
||||||
:return: |
:return: |
||||||
""" |
""" |
||||||
super(Constraints, self).__iadd__(constraints) |
super(Constraints, self).__iadd__(constraints) |
||||||
|
self._is_possible = None |
||||||
return self |
return self |
||||||
|
Loading…
Reference in new issue