2022-05-08 02:37:24 -07:00

141 lines
5.4 KiB
Python

from typing import List, Optional
from mev_inspect.classifiers.helpers import get_debt_transfer, get_received_transfer
from mev_inspect.schemas.classifiers import (
Classification,
ClassifiedTrace,
ClassifierSpec,
DecodedCallTrace,
LiquidationClassifier,
SeizeClassifier,
)
from mev_inspect.schemas.liquidations import Liquidation
from mev_inspect.schemas.prices import ETH_TOKEN_ADDRESS
from mev_inspect.schemas.traces import Protocol
from mev_inspect.schemas.transfers import Transfer
CYETH_TOKEN_ADDRESS = "0x41c84c0e2ee0b740cf0d31f63f3b6f627dc6b393"
class IronBankLiquidationClassifier(LiquidationClassifier):
@staticmethod
def parse_liquidation(
liquidation_trace: DecodedCallTrace,
child_transfers: List[Transfer],
child_traces: List[ClassifiedTrace],
) -> Optional[Liquidation]:
liquidator = liquidation_trace.from_address
liquidated = liquidation_trace.inputs["borrower"]
debt_token_address = liquidation_trace.to_address
received_token_address = liquidation_trace.inputs["cTokenCollateral"]
debt_purchase_amount = None
received_amount = None
debt_purchase_amount, debt_token_address = (
(liquidation_trace.value, ETH_TOKEN_ADDRESS)
if debt_token_address == CYETH_TOKEN_ADDRESS
and liquidation_trace.value != 0
else (liquidation_trace.inputs["repayAmount"], CYETH_TOKEN_ADDRESS)
)
debt_transfer = get_debt_transfer(liquidator, child_transfers)
received_transfer = get_received_transfer(liquidator, child_transfers)
seize_trace = _get_seize_call(child_traces)
if debt_transfer is not None:
debt_token_address = debt_transfer.token_address
debt_purchase_amount = debt_transfer.amount
if received_transfer is not None:
received_token_address = received_transfer.token_address
received_amount = received_transfer.amount
elif seize_trace is not None and seize_trace.inputs is not None:
received_amount = seize_trace.inputs["seizeTokens"]
if received_amount is None:
return None
return Liquidation(
liquidated_user=liquidated,
debt_token_address=debt_token_address,
liquidator_user=liquidator,
debt_purchase_amount=debt_purchase_amount,
protocol=liquidation_trace.protocol,
received_amount=received_amount,
received_token_address=received_token_address,
transaction_hash=liquidation_trace.transaction_hash,
trace_address=liquidation_trace.trace_address,
block_number=liquidation_trace.block_number,
error=liquidation_trace.error,
)
return None
IRONBANK_CYETH_SPEC = ClassifierSpec(
abi_name="CYEther",
protocol=Protocol.ironbank,
valid_contract_addresses=["0x41c84c0e2EE0b740Cf0d31F63f3B6F627DC6b393"],
classifiers={
"liquidateBorrow(address,address)": IronBankLiquidationClassifier,
"seize(address,address,uint256)": SeizeClassifier,
},
)
IRONBANK_CTOKEN_SPEC = ClassifierSpec(
abi_name="CYToken",
protocol=Protocol.ironbank,
valid_contract_addresses=[
"0x41c84c0e2ee0b740cf0d31f63f3b6f627dc6b393", # cyWETH
"0x8e595470ed749b85c6f7669de83eae304c2ec68f", # cyDAI
"0xe7bff2da8a2f619c2586fb83938fa56ce803aa16", # cyLINK
"0xfa3472f7319477c9bfecdd66e4b948569e7621b9", # cyYFI
"0x12a9cc33a980daa74e00cc2d1a0e74c57a93d12c", # cySNX
"0x8fc8bfd80d6a9f17fb98a373023d72531792b431", # cyWBTC
"0x48759f220ed983db51fa7a8c0d2aab8f3ce4166a", # cyUSDT
"0x76eb2fe28b36b3ee97f3adae0c69606eedb2a37c", # cyUDSC
"0xa7c4054afd3dbbbf5bfe80f41862b89ea05c9806", # cySUSD
"0xa8caea564811af0e92b1e044f3edd18fa9a73e4f", # cyEURS
"0xca55f9c4e77f7b8524178583b0f7c798de17fd54", # cySEUR
"0x7736ffb07104c0c400bb0cc9a7c228452a732992", # cyDPI
"0xbddeb563e90f6cbf168a7cda4927806477e5b6c6", # cyUSDP
"0xFEEB92386A055E2eF7C2B598c872a4047a7dB59F", # cyUNI
"0x226F3738238932BA0dB2319a8117D9555446102f", # cySUSHI
"0xB8c5af54bbDCc61453144CF472A9276aE36109F9", # cyCRV
"0x30190a3B52b5AB1daF70D46D72536F5171f22340", # cyAAVE
"0x9e8E207083ffd5BDc3D99A1F32D1e6250869C1A9", # iMIM
"0xE0B57FEEd45e7D908f2d0DaCd26F113Cf26715BF", # iCVX
"0xd2b0D3594427e0c57C39e3455E2FB2dFED1e0B99", # iAPE
"0x00e5c0774A5F065c285068170b20393925C84BF3", # cyEUR
"0x3c9f5385c288cE438Ed55620938A4B967c080101", # cyKRW
"0x215F34af6557A6598DbdA9aa11cc556F5AE264B1", # cyJPY
"0x86BBD9ac8B9B44C95FFc6BAAe58E25033B7548AA", # cyAUD
"0xecaB2C76f1A8359A06fAB5fA0CEea51280A97eCF", # cyGBP
"0x1b3E95E8ECF7A7caB6c4De1b344F94865aBD12d5", # cyCHF
"0x672473908587b10e65DAB177Dbaeadcbb30BF40B", # cyZAR
],
classifiers={
"liquidateBorrow(address,uint256,address)": IronBankLiquidationClassifier,
"seize(address,address,uint256)": SeizeClassifier,
},
)
IRONBANK_CLASSIFIER_SPECS: List[ClassifierSpec] = [
IRONBANK_CYETH_SPEC,
IRONBANK_CTOKEN_SPEC,
]
def _get_seize_call(traces: List[ClassifiedTrace]) -> Optional[ClassifiedTrace]:
"""Find the call to `seize` in the child traces (successful liquidation)"""
for trace in traces:
if trace.classification == Classification.seize:
return trace
return None