Swamps, transfers, tests imp

This commit is contained in:
Gui Heise 2021-08-27 13:20:50 -04:00
parent 0f3070a08a
commit 27d71014bf
11 changed files with 181 additions and 100 deletions

View File

@ -1,8 +1,7 @@
from itertools import groupby
from typing import List, Optional
from mev_inspect.schemas.arbitrages import Arbitrage
from mev_inspect.schemas.swaps import Swap
from mev_inspect.schemas.classified_traces import Swap, Arbitrage
def get_arbitrages(swaps: List[Swap]) -> List[Arbitrage]:

View File

@ -2,7 +2,7 @@ from typing import List
from pydantic import BaseModel
from .swaps import Swap
from .classified_traces import Swap
class Arbitrage(BaseModel):

View File

@ -45,11 +45,8 @@ class TraceType(Enum):
class Trace(CamelModel):
action: dict
block_hash: str
block_number: int
result: Optional[dict]
subtraces: int
trace_address: List[int]
transaction_hash: Optional[str]
transaction_position: Optional[int]

View File

@ -1,9 +1,14 @@
from enum import Enum
from typing import Any, Dict, List, Optional
from pydantic import BaseModel
from .blocks import TraceType
from .blocks import Trace
from .utils import CamelModel
# -------- Enums ------------------------------------------------------------------------------
class Classification(Enum):
@ -23,23 +28,29 @@ class Protocol(Enum):
curve = "curve"
class ClassifiedTrace(BaseModel):
# -------- Trace Models ------------------------------------------------------------------------------
class ClassifiedTrace(Trace):
transaction_hash: str
block_number: int
trace_type: TraceType
trace_address: List[int]
classification: Classification
protocol: Optional[Protocol]
abi_name: Optional[str]
function_name: Optional[str]
function_signature: Optional[str]
inputs: Optional[Dict[str, Any]]
error: Optional[str]
block_hash: Optional[str]
subtraces: Optional[int]
action: Optional[dict]
to_address: Optional[str]
from_address: Optional[str]
gas: Optional[int]
value: Optional[int]
gas_used: Optional[int]
error: Optional[str]
protocol: Optional[Protocol]
function_name: Optional[str]
function_signature: Optional[str]
inputs: Optional[Dict[str, Any]]
abi_name: Optional[str]
class Config:
json_encoders = {
@ -49,6 +60,135 @@ class ClassifiedTrace(BaseModel):
}
class Call(ClassifiedTrace):
to_address: str
from_address: str
inputs: Dict[str, Any]
class ClassifiedCall(ClassifiedTrace):
gas: Optional[int]
gas_used: Optional[int]
function_name: Optional[str]
function_signature: Optional[str]
abi_name: str
class Config:
json_encoders = {
# a little lazy but fine for now
# this is used for bytes value inputs
bytes: lambda b: b.hex(),
}
# -------- Swaps ------------------------------------------------------------------------------
class Swap(BaseModel):
abi_name: str
transaction_hash: str
block_number: int
trace_address: List[int]
protocol: Optional[Protocol]
pool_address: str
from_address: str
to_address: str
token_in_address: str
token_in_amount: int
token_out_address: str
token_out_amount: int
error: Optional[str]
class Arbitrage(BaseModel):
swaps: List[Swap]
block_number: int
transaction_hash: str
account_address: str
profit_token_address: str
start_amount: int
end_amount: int
profit_amount: int
# -------- Transfers------------------------------------------------------------------------------
class Transfer(BaseModel):
transaction_hash: str
trace_address: List[int]
from_address: str
to_address: str
amount: int
token_address: str
@classmethod
def from_trace(cls, trace: ClassifiedTrace) -> "Transfer":
if trace.classification != Classification.transfer or trace.inputs is None:
raise ValueError("Invalid transfer")
if trace.protocol == Protocol.weth:
return cls(
transaction_hash=trace.transaction_hash,
trace_address=trace.trace_address,
amount=trace.inputs["wad"],
to_address=trace.inputs["dst"],
from_address=trace.from_address,
token_address=trace.to_address,
)
else:
return cls(
transaction_hash=trace.transaction_hash,
trace_address=trace.trace_address,
amount=trace.inputs["amount"],
to_address=trace.inputs["recipient"],
from_address=trace.inputs.get("sender", trace.from_address),
token_address=trace.to_address,
)
# -------- Liquidations ------------------------------------------------------------------------------
class LiquidationType(Enum):
compound_v2_ceth_liquidation = "compound_v2_ceth_liquidation"
compound_v2_ctoken_liquidation = "compound_v2_ctoken_liquidation" # TODO: add logic to handle ctoken liquidations
class LiquidationStatus(Enum):
seized = "seized" # succesfully completed
check = "check" # just a liquidation check. i.e searcher only checks if opportunity is still available and reverts accordingly
out_of_gas = "out_of_gas" # tx ran out of gas
class LiquidationCollateralSource(Enum):
aave_flashloan = "aave_flashloan"
dydx_flashloan = "dydx_flashloan"
uniswap_flashloan = "uniswap_flashloan"
searcher_eoa = "searcher_eoa" # searchers own funds
searcher_contract = "searcher_contract"
other = "other"
class Liquidation(CamelModel):
tx_hash: str
borrower: str # account that got liquidated
collateral_provided: str # collateral provided by searcher, 'ether' or token contract address
collateral_provided_amount: int # amount of collateral provided
asset_seized: str # asset that was given to searcher at a discount upon liquidation
asset_seized_amount: int # amount of asset that was given to searcher upon liquidation
profit_in_eth: int # profit estimated by strategy inspector
tokenflow_estimate_in_eth: int # profit estimated by tokenflow
tokenflow_diff: int # diff between tokenflow and strategy inspector
status: LiquidationStatus
type: LiquidationType
collateral_source: LiquidationCollateralSource
# -------- Config ------------------------------------------------------------------------------
class ClassifierSpec(BaseModel):
abi_name: str
protocol: Optional[Protocol] = None

View File

@ -1,21 +0,0 @@
from typing import List, Optional
from pydantic import BaseModel
from mev_inspect.schemas.classified_traces import Protocol
class Swap(BaseModel):
abi_name: str
transaction_hash: str
block_number: int
trace_address: List[int]
protocol: Optional[Protocol]
pool_address: str
from_address: str
to_address: str
token_in_address: str
token_in_amount: int
token_out_address: str
token_out_amount: int
error: Optional[str]

View File

@ -1,57 +0,0 @@
from typing import List, TypeVar
from pydantic import BaseModel
from .classified_traces import Classification, ClassifiedTrace, Protocol
class Transfer(BaseModel):
transaction_hash: str
trace_address: List[int]
from_address: str
to_address: str
amount: int
# To preserve the specific Transfer type
TransferGeneric = TypeVar("TransferGeneric", bound="Transfer")
class EthTransfer(Transfer):
@classmethod
def from_trace(cls, trace: ClassifiedTrace) -> "EthTransfer":
return cls(
transaction_hash=trace.transaction_hash,
trace_address=trace.trace_address,
amount=trace.value,
to_address=trace.to_address,
from_address=trace.from_address,
)
class ERC20Transfer(Transfer):
token_address: str
@classmethod
def from_trace(cls, trace: ClassifiedTrace) -> "ERC20Transfer":
if trace.classification != Classification.transfer or trace.inputs is None:
raise ValueError("Invalid transfer")
if trace.protocol == Protocol.weth:
return cls(
transaction_hash=trace.transaction_hash,
trace_address=trace.trace_address,
amount=trace.inputs["wad"],
to_address=trace.inputs["dst"],
from_address=trace.from_address,
token_address=trace.to_address,
)
else:
return cls(
transaction_hash=trace.transaction_hash,
trace_address=trace.trace_address,
amount=trace.inputs["amount"],
to_address=trace.inputs["recipient"],
from_address=trace.inputs.get("sender", trace.from_address),
token_address=trace.to_address,
)

View File

@ -3,10 +3,16 @@ from typing import List, Optional
from mev_inspect.schemas.classified_traces import (
ClassifiedTrace,
Classification,
Swap,
Transfer,
)
<<<<<<< HEAD
from mev_inspect.schemas.swaps import Swap
from mev_inspect.schemas.transfers import ERC20Transfer
from mev_inspect.traces import get_traces_by_transaction_hash
=======
>>>>>>> Swamps, transfers, tests imp
from mev_inspect.transfers import (
get_child_transfers,
filter_transfers,

View File

@ -1,7 +1,15 @@
from typing import Dict, List, Optional, Sequence
<<<<<<< HEAD
from mev_inspect.schemas.classified_traces import Classification, ClassifiedTrace
from mev_inspect.schemas.transfers import ERC20Transfer, EthTransfer, TransferGeneric
=======
from mev_inspect.schemas.classified_traces import (
Classification,
ClassifiedTrace,
Transfer,
)
>>>>>>> Swamps, transfers, tests imp
from mev_inspect.traces import is_child_trace_address, get_child_traces

View File

@ -1,7 +1,12 @@
from typing import List
from mev_inspect.schemas.blocks import TraceType
from mev_inspect.schemas.classified_traces import Classification, ClassifiedTrace
from mev_inspect.schemas.classified_traces import (
Classification,
ClassifiedTrace,
Call,
ClassifiedCall,
)
def make_transfer_trace(
@ -13,10 +18,10 @@ def make_transfer_trace(
token_address: str,
amount: int,
):
return ClassifiedTrace(
return Call(
transaction_hash=transaction_hash,
block_number=block_number,
trace_type=TraceType.call,
type=TraceType.call,
trace_address=trace_address,
classification=Classification.transfer,
from_address=from_address,
@ -38,10 +43,10 @@ def make_swap_trace(
recipient_address: str,
recipient_input_key: str,
):
return ClassifiedTrace(
return ClassifiedCall(
transaction_hash=transaction_hash,
block_number=block_number,
trace_type=TraceType.call,
type=TraceType.call,
trace_address=trace_address,
classification=Classification.swap,
from_address=from_address,
@ -59,7 +64,7 @@ def make_unknown_trace(
return ClassifiedTrace(
transaction_hash=transaction_hash,
block_number=block_number,
trace_type=TraceType.call,
type=TraceType.call,
trace_address=trace_address,
classification=Classification.unknown,
)

View File

@ -1,5 +1,5 @@
from mev_inspect.arbitrages import get_arbitrages
from mev_inspect.schemas.swaps import Swap
from mev_inspect.schemas.classified_traces import Swap
from mev_inspect.swaps import (
UNISWAP_V2_PAIR_ABI_NAME,
UNISWAP_V3_POOL_ABI_NAME,

View File

@ -1,4 +1,8 @@
<<<<<<< HEAD
from mev_inspect.schemas.transfers import ERC20Transfer
=======
from mev_inspect.schemas.classified_traces import Transfer
>>>>>>> Swamps, transfers, tests imp
from mev_inspect.transfers import remove_child_transfers_of_transfers