Compare commits

...

14 Commits

Author SHA1 Message Date
Guilherme Peyrelongue Heise
80711c1586 Removed debugger 2021-08-11 11:05:11 -04:00
Guilherme Peyrelongue Heise
25fc22e576 WIP 2021-08-11 11:02:00 -04:00
Guilherme Peyrelongue Heise
db78372c3e WIP 2021-08-11 09:27:42 -04:00
Guilherme Peyrelongue Heise
771df11093 adjusted profit calculation 2021-08-10 12:11:11 -04:00
Guilherme Peyrelongue Heise
508847b8df TODO 2021-08-06 02:21:46 -04:00
Guilherme Peyrelongue Heise
da83fe27fc output for testing 2021-08-06 02:17:37 -04:00
Guilherme Peyrelongue Heise
244be7e990 liquidation data type and inspector clean up 2021-08-06 02:07:28 -04:00
Guilherme Peyrelongue Heise
7236215a20 fixed profit calculation and return object 2021-08-05 20:49:56 -04:00
Guilherme Peyrelongue Heise
31ffc20a52 Bug fixes, changed underlying to reserve 2021-08-04 17:15:42 -04:00
Guilherme Peyrelongue Heise
0311b715ce added strat 2021-08-04 17:08:42 -04:00
Guilherme Peyrelongue Heise
4005ec8aac fixed inspector functionality, added strategy data type and aave address provider 2021-08-04 17:07:46 -04:00
Guilherme Peyrelongue Heise
72569a576a fix broken aave classifier spec 2021-08-03 16:40:35 -04:00
Guilherme Peyrelongue Heise
790fbee002 Added data types 2021-08-03 16:37:35 -04:00
Guilherme Peyrelongue Heise
1201623c1f Added liquidation_inspector.py, aave protocol and classifier spec 2021-08-03 16:37:35 -04:00
13 changed files with 153 additions and 0 deletions

1
cache/12498502-new.json vendored Normal file

File diff suppressed because one or more lines are too long

1
cache/12498513-new.json vendored Normal file

File diff suppressed because one or more lines are too long

1
cache/12932986-new.json vendored Normal file

File diff suppressed because one or more lines are too long

1
cache/12972264-new.json vendored Normal file

File diff suppressed because one or more lines are too long

1
cache/13002906-new.json vendored Normal file

File diff suppressed because one or more lines are too long

1
cache/13004256-new.json vendored Normal file

File diff suppressed because one or more lines are too long

105
liquidation_inspector.py Normal file
View File

@ -0,0 +1,105 @@
# Internal imports
from mev_inspect import utils
from mev_inspect.config import load_config
from mev_inspect.schemas.blocks import NestedTrace, TraceType
from mev_inspect.schemas.classified_traces import Classification, ClassifiedTrace
from mev_inspect.schemas.strategy import StrategyType, Strategy, Liquidation
from mev_inspect.classifier_specs import CLASSIFIER_SPECS
from mev_inspect.trace_classifier import TraceClassifier
from mev_inspect import block
# External Libraries
import json
import pandas as pd
from typing import Optional
from web3 import Web3
from typing import List, Optional
# TODO: adjust profit to new model
# unit test
# coinbase check / collateral source
liquidations = []
result = []
# Protocol contract address must be in included, below is AaveLendingPoolCoreV1
addrs = ['0x3dfd23A6c5E8BbcFc9581d2E864a68feb6a076d3']
# Used to remove double-counted 'from' transfers
from_doubles = []
transfers_to = []
transfers_from = []
# Inspect list of classified traces and identify liquidation
def find_liquidations(traces: List[ClassifiedTrace]):
tx = []
# For each trace
for count, trace in enumerate(traces):
# Check for liquidation and register trace and unique liquidator
if (
trace.classification == Classification.liquidate and
trace.transaction_hash not in tx
):
liquidations.append(trace)
addrs.append(trace.from_address)
tx.append(trace.transaction_hash)
# Found liquidation, now parse inputs for data
for i in trace.inputs:
if(i == '_purchaseAmount'):
liquidation_amount = trace.inputs[i]
elif (i == '_collateral'):
collateral_type = trace.inputs[i]
#This will be the address of the sent token
elif (i == '_reserve'):
reserve = trace.inputs[i]
#This will be the address of the received token
elif(i == '_user'):
liquidated_usr = trace.inputs[i]
# Register liquidation
result.append(
Liquidation(collateral_type=collateral_type,
collateral_amount=liquidation_amount,
collateral_source="",
reserve=reserve,
strategy=StrategyType.liquidation,
protocols=[trace.protocol],)
)
# Check for transfer from a liquidator
elif (
trace.classification == Classification.transfer and
'sender' in trace.inputs and
trace.inputs['sender'] in addrs and
trace.transaction_hash not in from_doubles
):
#Add the transfer
liquidator = next(addrs[i] for i in range(len(addrs)) if trace.inputs['sender'] == addrs[i])
transfers_from.append(["from", liquidator, trace.transaction_hash, trace.inputs['amount']])
from_doubles.append(trace.transaction_hash)
# Check for transfer to a liquidator
elif (
trace.classification == Classification.transfer and
trace.inputs['recipient'] in addrs
):
#Add the transfer
liquidator = next(addrs[i] for i in range(len(addrs)) if trace.inputs['recipient'] == addrs[i])
transfers_to.append(["to", liquidator, trace.transaction_hash, trace.inputs['amount']])
for count, trace in enumerate(liquidations):
tx = trace.transaction_hash
#convert token to ETH
#profit = transfers[count][2] - transfers[count+1][2]
#for count, trace in enumerate(transfers_to):
#profits.append({"liquidator" : transfers_to[count][1],
#"transaction" : transfers_to[count][2],
#"profit" : transfers_to[count][3] - transfers_from[count][3]})
return result

View File

@ -13,6 +13,7 @@ ABI_DIRECTORY_PATH = THIS_FILE_DIRECTORY / "abis"
def get_abi(abi_name: str, protocol: Optional[Protocol]) -> Optional[ABI]: def get_abi(abi_name: str, protocol: Optional[Protocol]) -> Optional[ABI]:
abi_filename = f"{abi_name}.json" abi_filename = f"{abi_name}.json"
abi_path = ( abi_path = (
ABI_DIRECTORY_PATH / abi_filename ABI_DIRECTORY_PATH / abi_filename

File diff suppressed because one or more lines are too long

View File

@ -99,10 +99,25 @@ ERC20_SPEC = ClassifierSpec(
}, },
) )
AAVE_CONTRACT_SPECS = [
ClassifierSpec(
abi_name="AaveLendingPool",
protocol= Protocol.aave,
classifications={
"liquidationCall(address,address,address,uint256,bool)": Classification.liquidate,},
),
ClassifierSpec(
abi_name="AaveLendingPoolAddressProvider",
protocol= Protocol.aave,
valid_contract_addresses=['0x24a42fD28C976A61Df5D00D0599C34c4f90748c8'],
),
]
CLASSIFIER_SPECS = [ CLASSIFIER_SPECS = [
*UNISWAP_V3_CONTRACT_SPECS, *UNISWAP_V3_CONTRACT_SPECS,
*UNISWAPPY_V2_CONTRACT_SPECS, *UNISWAPPY_V2_CONTRACT_SPECS,
*AAVE_CONTRACT_SPECS,
ERC20_SPEC, ERC20_SPEC,
UNISWAP_V3_POOL_SPEC, UNISWAP_V3_POOL_SPEC,
UNISWAPPY_V2_PAIR_SPEC, UNISWAPPY_V2_PAIR_SPEC,

View File

@ -11,12 +11,15 @@ class Classification(Enum):
swap = "swap" swap = "swap"
burn = "burn" burn = "burn"
transfer = "transfer" transfer = "transfer"
liquidate = "liquidate"
class Protocol(Enum): class Protocol(Enum):
uniswap_v2 = "uniswap_v2" uniswap_v2 = "uniswap_v2"
uniswap_v3 = "uniswap_v3" uniswap_v3 = "uniswap_v3"
sushiswap = "sushiswap" sushiswap = "sushiswap"
aave = "aave"
balancer = "balancer"
class ClassifiedTrace(BaseModel): class ClassifiedTrace(BaseModel):

View File

@ -0,0 +1,22 @@
from typing import Optional, List
from enum import Enum
from pydantic import BaseModel
from .classified_traces import ClassifiedTrace, Protocol
class StrategyType(Enum):
arbitrage = "arbitrage"
liquidation = "liquidation"
class Strategy(BaseModel):
strategy: StrategyType
protocols: List[Protocol]
class Liquidation(Strategy):
collateral_type: str
collateral_amount: int
collateral_source: str
reserve: str
class LiquidationData(Liquidation):
profit: float
traces: List[ClassifiedTrace]