Compare commits
14 Commits
main
...
balancer-s
Author | SHA1 | Date | |
---|---|---|---|
|
80711c1586 | ||
|
25fc22e576 | ||
|
db78372c3e | ||
|
771df11093 | ||
|
508847b8df | ||
|
da83fe27fc | ||
|
244be7e990 | ||
|
7236215a20 | ||
|
31ffc20a52 | ||
|
0311b715ce | ||
|
4005ec8aac | ||
|
72569a576a | ||
|
790fbee002 | ||
|
1201623c1f |
1
cache/12498502-new.json
vendored
Normal file
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
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
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
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
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
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
105
liquidation_inspector.py
Normal 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
|
@ -13,6 +13,7 @@ ABI_DIRECTORY_PATH = THIS_FILE_DIRECTORY / "abis"
|
||||
|
||||
|
||||
def get_abi(abi_name: str, protocol: Optional[Protocol]) -> Optional[ABI]:
|
||||
|
||||
abi_filename = f"{abi_name}.json"
|
||||
abi_path = (
|
||||
ABI_DIRECTORY_PATH / abi_filename
|
||||
|
File diff suppressed because one or more lines are too long
@ -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 = [
|
||||
*UNISWAP_V3_CONTRACT_SPECS,
|
||||
*UNISWAPPY_V2_CONTRACT_SPECS,
|
||||
*AAVE_CONTRACT_SPECS,
|
||||
ERC20_SPEC,
|
||||
UNISWAP_V3_POOL_SPEC,
|
||||
UNISWAPPY_V2_PAIR_SPEC,
|
||||
|
@ -11,12 +11,15 @@ class Classification(Enum):
|
||||
swap = "swap"
|
||||
burn = "burn"
|
||||
transfer = "transfer"
|
||||
liquidate = "liquidate"
|
||||
|
||||
|
||||
class Protocol(Enum):
|
||||
uniswap_v2 = "uniswap_v2"
|
||||
uniswap_v3 = "uniswap_v3"
|
||||
sushiswap = "sushiswap"
|
||||
aave = "aave"
|
||||
balancer = "balancer"
|
||||
|
||||
|
||||
class ClassifiedTrace(BaseModel):
|
||||
|
22
mev_inspect/schemas/strategy.py
Normal file
22
mev_inspect/schemas/strategy.py
Normal 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]
|
Loading…
x
Reference in New Issue
Block a user