Merge pull request #89 from flashbots/aTokens
Add received_token_address to liquidations
This commit is contained in:
commit
c6c45b4ab0
@ -0,0 +1,27 @@
|
|||||||
|
"""Add received_collateral_address to liquidations
|
||||||
|
|
||||||
|
Revision ID: 205ce02374b3
|
||||||
|
Revises: c8363617aa07
|
||||||
|
Create Date: 2021-10-04 19:52:40.017084
|
||||||
|
|
||||||
|
"""
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "205ce02374b3"
|
||||||
|
down_revision = "c8363617aa07"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.add_column(
|
||||||
|
"liquidations",
|
||||||
|
sa.Column("received_token_address", sa.String(256), nullable=True),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_column("liquidations", "received_token_address")
|
@ -1,4 +1,4 @@
|
|||||||
from typing import List
|
from typing import List, Tuple, Optional
|
||||||
|
|
||||||
from mev_inspect.traces import (
|
from mev_inspect.traces import (
|
||||||
get_child_traces,
|
get_child_traces,
|
||||||
@ -11,8 +11,10 @@ from mev_inspect.schemas.classified_traces import (
|
|||||||
Protocol,
|
Protocol,
|
||||||
)
|
)
|
||||||
|
|
||||||
from mev_inspect.schemas.liquidations import Liquidation
|
|
||||||
from mev_inspect.transfers import get_transfer
|
from mev_inspect.transfers import get_transfer
|
||||||
|
from mev_inspect.schemas.transfers import Transfer
|
||||||
|
from mev_inspect.schemas.liquidations import Liquidation
|
||||||
|
|
||||||
AAVE_CONTRACT_ADDRESSES: List[str] = [
|
AAVE_CONTRACT_ADDRESSES: List[str] = [
|
||||||
# AAVE Proxy
|
# AAVE Proxy
|
||||||
@ -24,7 +26,10 @@ AAVE_CONTRACT_ADDRESSES: List[str] = [
|
|||||||
# AAVE V2 WETH
|
# AAVE V2 WETH
|
||||||
"0x030ba81f1c18d280636f32af80b9aad02cf0854e",
|
"0x030ba81f1c18d280636f32af80b9aad02cf0854e",
|
||||||
# AAVE AMM Market DAI
|
# AAVE AMM Market DAI
|
||||||
"0x79bE75FFC64DD58e66787E4Eae470c8a1FD08ba4",
|
"0x79be75ffc64dd58e66787e4eae470c8a1fd08ba4",
|
||||||
|
# AAVE i
|
||||||
|
"0x030ba81f1c18d280636f32af80b9aad02cf0854e",
|
||||||
|
"0xbcca60bb61934080951369a648fb03df4f96263c",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -52,7 +57,10 @@ def get_aave_liquidations(
|
|||||||
trace.transaction_hash, trace.trace_address, traces
|
trace.transaction_hash, trace.trace_address, traces
|
||||||
)
|
)
|
||||||
|
|
||||||
received_amount = _get_liquidator_payback(child_traces, liquidator)
|
(
|
||||||
|
received_token_address,
|
||||||
|
received_amount,
|
||||||
|
) = _get_payback_token_and_amount(trace, child_traces, liquidator)
|
||||||
|
|
||||||
liquidations.append(
|
liquidations.append(
|
||||||
Liquidation(
|
Liquidation(
|
||||||
@ -63,6 +71,7 @@ def get_aave_liquidations(
|
|||||||
debt_purchase_amount=trace.inputs["_purchaseAmount"],
|
debt_purchase_amount=trace.inputs["_purchaseAmount"],
|
||||||
protocol=Protocol.aave,
|
protocol=Protocol.aave,
|
||||||
received_amount=received_amount,
|
received_amount=received_amount,
|
||||||
|
received_token_address=received_token_address,
|
||||||
transaction_hash=trace.transaction_hash,
|
transaction_hash=trace.transaction_hash,
|
||||||
trace_address=trace.trace_address,
|
trace_address=trace.trace_address,
|
||||||
block_number=trace.block_number,
|
block_number=trace.block_number,
|
||||||
@ -71,19 +80,25 @@ def get_aave_liquidations(
|
|||||||
return liquidations
|
return liquidations
|
||||||
|
|
||||||
|
|
||||||
def _get_liquidator_payback(
|
def _get_payback_token_and_amount(
|
||||||
child_traces: List[ClassifiedTrace], liquidator: str
|
liquidation: DecodedCallTrace, child_traces: List[ClassifiedTrace], liquidator: str
|
||||||
) -> int:
|
) -> Tuple[str, int]:
|
||||||
for child in child_traces:
|
|
||||||
if child.classification == Classification.transfer:
|
|
||||||
|
|
||||||
child_transfer = get_transfer(child)
|
"""Look for and return liquidator payback from liquidation"""
|
||||||
|
|
||||||
|
for child in child_traces:
|
||||||
|
|
||||||
|
if child.classification == Classification.transfer and isinstance(
|
||||||
|
child, DecodedCallTrace
|
||||||
|
):
|
||||||
|
|
||||||
|
child_transfer: Optional[Transfer] = get_transfer(child)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
child_transfer is not None
|
child_transfer is not None
|
||||||
and child_transfer.to_address == liquidator
|
and child_transfer.to_address == liquidator
|
||||||
and child.from_address in AAVE_CONTRACT_ADDRESSES
|
and child.from_address in AAVE_CONTRACT_ADDRESSES
|
||||||
):
|
):
|
||||||
return child_transfer.amount
|
return child_transfer.token_address, child_transfer.amount
|
||||||
|
|
||||||
return 0
|
return liquidation.inputs["_collateral"], 0
|
||||||
|
615
mev_inspect/abis/aave/aTokens.json
Normal file
615
mev_inspect/abis/aave/aTokens.json
Normal file
@ -0,0 +1,615 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Approval",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "from",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "index",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "BalanceTransfer",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "from",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "target",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "index",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Burn",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "underlyingAsset",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "pool",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "treasury",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "incentivesController",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint8",
|
||||||
|
"name": "aTokenDecimals",
|
||||||
|
"type": "uint8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "string",
|
||||||
|
"name": "aTokenName",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "string",
|
||||||
|
"name": "aTokenSymbol",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "bytes",
|
||||||
|
"name": "params",
|
||||||
|
"type": "bytes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Initialized",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "from",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "index",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Mint",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "from",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Transfer",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"name": "UNDERLYING_ASSET_ADDRESS",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "allowance",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "approve",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "account",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "balanceOf",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "user",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "receiverOfUnderlying",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "index",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "burn",
|
||||||
|
"outputs": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"name": "getIncentivesController",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "contract IAaveIncentivesController",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "user",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "getScaledUserBalanceAndSupply",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "user",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "handleRepayment",
|
||||||
|
"outputs": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "contract ILendingPool",
|
||||||
|
"name": "pool",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "treasury",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "underlyingAsset",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "contract IAaveIncentivesController",
|
||||||
|
"name": "incentivesController",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint8",
|
||||||
|
"name": "aTokenDecimals",
|
||||||
|
"type": "uint8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "string",
|
||||||
|
"name": "aTokenName",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "string",
|
||||||
|
"name": "aTokenSymbol",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "bytes",
|
||||||
|
"name": "params",
|
||||||
|
"type": "bytes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "initialize",
|
||||||
|
"outputs": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "user",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "index",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "mint",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "index",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "mintToTreasury",
|
||||||
|
"outputs": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "user",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "scaledBalanceOf",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"name": "scaledTotalSupply",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"name": "totalSupply",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "recipient",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transfer",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "sender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "recipient",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transferFrom",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "from",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transferOnLiquidation",
|
||||||
|
"outputs": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "user",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transferUnderlyingTo",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
]
|
@ -1,10 +1,28 @@
|
|||||||
from mev_inspect.schemas.classified_traces import (
|
from mev_inspect.schemas.classified_traces import (
|
||||||
Protocol,
|
Protocol,
|
||||||
)
|
)
|
||||||
|
|
||||||
from mev_inspect.schemas.classifiers import (
|
from mev_inspect.schemas.classifiers import (
|
||||||
ClassifierSpec,
|
ClassifierSpec,
|
||||||
|
DecodedCallTrace,
|
||||||
|
TransferClassifier,
|
||||||
LiquidationClassifier,
|
LiquidationClassifier,
|
||||||
)
|
)
|
||||||
|
from mev_inspect.schemas.transfers import Transfer
|
||||||
|
|
||||||
|
|
||||||
|
class AaveTransferClassifier(TransferClassifier):
|
||||||
|
@staticmethod
|
||||||
|
def get_transfer(trace: DecodedCallTrace) -> Transfer:
|
||||||
|
return Transfer(
|
||||||
|
block_number=trace.block_number,
|
||||||
|
transaction_hash=trace.transaction_hash,
|
||||||
|
trace_address=trace.trace_address,
|
||||||
|
amount=trace.inputs["value"],
|
||||||
|
to_address=trace.inputs["to"],
|
||||||
|
from_address=trace.inputs["from"],
|
||||||
|
token_address=trace.to_address,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
AAVE_SPEC = ClassifierSpec(
|
AAVE_SPEC = ClassifierSpec(
|
||||||
@ -15,4 +33,13 @@ AAVE_SPEC = ClassifierSpec(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
AAVE_CLASSIFIER_SPECS = [AAVE_SPEC]
|
ATOKENS_SPEC = ClassifierSpec(
|
||||||
|
abi_name="aTokens",
|
||||||
|
protocol=Protocol.aave,
|
||||||
|
classifiers={
|
||||||
|
"transferOnLiquidation(address,address,uint256)": AaveTransferClassifier,
|
||||||
|
"transferFrom(address,address,uint256)": AaveTransferClassifier,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
AAVE_CLASSIFIER_SPECS = [AAVE_SPEC, ATOKENS_SPEC]
|
||||||
|
@ -12,6 +12,7 @@ class LiquidationModel(Base):
|
|||||||
debt_token_address = Column(String, nullable=False)
|
debt_token_address = Column(String, nullable=False)
|
||||||
debt_purchase_amount = Column(Numeric, nullable=False)
|
debt_purchase_amount = Column(Numeric, nullable=False)
|
||||||
received_amount = Column(Numeric, nullable=False)
|
received_amount = Column(Numeric, nullable=False)
|
||||||
|
received_token_address = Column(String, nullable=False)
|
||||||
protocol = Column(String, nullable=True)
|
protocol = Column(String, nullable=True)
|
||||||
transaction_hash = Column(String, primary_key=True)
|
transaction_hash = Column(String, primary_key=True)
|
||||||
trace_address = Column(ARRAY(Integer), primary_key=True)
|
trace_address = Column(ARRAY(Integer), primary_key=True)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import List
|
from typing import List, Optional
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from mev_inspect.schemas.classified_traces import Protocol
|
from mev_inspect.schemas.classified_traces import Protocol
|
||||||
|
|
||||||
@ -10,6 +10,7 @@ class Liquidation(BaseModel):
|
|||||||
debt_token_address: str
|
debt_token_address: str
|
||||||
debt_purchase_amount: int
|
debt_purchase_amount: int
|
||||||
received_amount: int
|
received_amount: int
|
||||||
|
received_token_address: Optional[str]
|
||||||
protocol: Protocol
|
protocol: Protocol
|
||||||
transaction_hash: str
|
transaction_hash: str
|
||||||
trace_address: List[int]
|
trace_address: List[int]
|
||||||
|
1
tests/blocks/13370850.json
Normal file
1
tests/blocks/13370850.json
Normal file
File diff suppressed because one or more lines are too long
1
tests/blocks/13376024.json
Normal file
1
tests/blocks/13376024.json
Normal file
File diff suppressed because one or more lines are too long
@ -22,6 +22,7 @@ def test_single_weth_liquidation():
|
|||||||
debt_token_address="0xdac17f958d2ee523a2206206994597c13d831ec7",
|
debt_token_address="0xdac17f958d2ee523a2206206994597c13d831ec7",
|
||||||
debt_purchase_amount=26503300291,
|
debt_purchase_amount=26503300291,
|
||||||
received_amount=8182733924513576561,
|
received_amount=8182733924513576561,
|
||||||
|
received_token_address="0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
|
||||||
protocol=Protocol.aave,
|
protocol=Protocol.aave,
|
||||||
transaction_hash=transaction_hash,
|
transaction_hash=transaction_hash,
|
||||||
trace_address=[1, 1, 6],
|
trace_address=[1, 1, 6],
|
||||||
@ -52,6 +53,7 @@ def test_single_liquidation():
|
|||||||
debt_token_address="0xdac17f958d2ee523a2206206994597c13d831ec7",
|
debt_token_address="0xdac17f958d2ee523a2206206994597c13d831ec7",
|
||||||
debt_purchase_amount=1069206535,
|
debt_purchase_amount=1069206535,
|
||||||
received_amount=2657946947610159065393,
|
received_amount=2657946947610159065393,
|
||||||
|
received_token_address="0x80fb784b7ed66730e8b1dbd9820afd29931aab03",
|
||||||
protocol=Protocol.aave,
|
protocol=Protocol.aave,
|
||||||
transaction_hash=transaction_hash,
|
transaction_hash=transaction_hash,
|
||||||
trace_address=[0, 7, 1, 0, 6],
|
trace_address=[0, 7, 1, 0, 6],
|
||||||
@ -67,6 +69,37 @@ def test_single_liquidation():
|
|||||||
_assert_equal_list_of_liquidations(result, liquidations)
|
_assert_equal_list_of_liquidations(result, liquidations)
|
||||||
|
|
||||||
|
|
||||||
|
def test_single_liquidation_with_atoken_payback():
|
||||||
|
|
||||||
|
transaction_hash = (
|
||||||
|
"0xde551a73e813f1a1e5c843ac2c6a0e40d71618f4040bb7d0cd7cf7b2b6cf4633"
|
||||||
|
)
|
||||||
|
block_number = 13376024
|
||||||
|
|
||||||
|
liquidations = [
|
||||||
|
Liquidation(
|
||||||
|
liquidated_user="0x3d2b6eacd1bca51af57ed8b3ff9ef0bd8ee8c56d",
|
||||||
|
liquidator_user="0x887668f2dc9612280243f2a6ef834cecf456654e",
|
||||||
|
collateral_token_address="0x514910771af9ca656af840dff83e8264ecf986ca",
|
||||||
|
debt_token_address="0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
|
||||||
|
debt_purchase_amount=767615458043667978,
|
||||||
|
received_amount=113993647930952952550,
|
||||||
|
received_token_address="0xa06bc25b5805d5f8d82847d191cb4af5a3e873e0",
|
||||||
|
protocol=Protocol.aave,
|
||||||
|
transaction_hash=transaction_hash,
|
||||||
|
trace_address=[2],
|
||||||
|
block_number=block_number,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
block = load_test_block(block_number)
|
||||||
|
trace_classifier = TraceClassifier()
|
||||||
|
classified_traces = trace_classifier.classify(block.traces)
|
||||||
|
result = get_aave_liquidations(classified_traces)
|
||||||
|
|
||||||
|
_assert_equal_list_of_liquidations(result, liquidations)
|
||||||
|
|
||||||
|
|
||||||
def test_multiple_liquidations_in_block():
|
def test_multiple_liquidations_in_block():
|
||||||
|
|
||||||
transaction1 = "0xedd062c3a728db4b114f2e83cac281d19a9f753e36afa8a35cdbdf1e1dd5d017"
|
transaction1 = "0xedd062c3a728db4b114f2e83cac281d19a9f753e36afa8a35cdbdf1e1dd5d017"
|
||||||
@ -81,6 +114,7 @@ def test_multiple_liquidations_in_block():
|
|||||||
debt_token_address="0x4fabb145d64652a948d72533023f6e7a623c7c53",
|
debt_token_address="0x4fabb145d64652a948d72533023f6e7a623c7c53",
|
||||||
debt_purchase_amount=457700000000000000000,
|
debt_purchase_amount=457700000000000000000,
|
||||||
received_amount=10111753901939162887,
|
received_amount=10111753901939162887,
|
||||||
|
received_token_address="0x514910771af9ca656af840dff83e8264ecf986ca",
|
||||||
protocol=Protocol.aave,
|
protocol=Protocol.aave,
|
||||||
transaction_hash=transaction1,
|
transaction_hash=transaction1,
|
||||||
trace_address=[],
|
trace_address=[],
|
||||||
@ -94,6 +128,7 @@ def test_multiple_liquidations_in_block():
|
|||||||
debt_token_address="0x0000000000085d4780b73119b644ae5ecd22b376",
|
debt_token_address="0x0000000000085d4780b73119b644ae5ecd22b376",
|
||||||
debt_purchase_amount=497030000000000000000,
|
debt_purchase_amount=497030000000000000000,
|
||||||
received_amount=21996356316098208090,
|
received_amount=21996356316098208090,
|
||||||
|
received_token_address="0x514910771af9ca656af840dff83e8264ecf986ca",
|
||||||
protocol=Protocol.aave,
|
protocol=Protocol.aave,
|
||||||
transaction_hash=transaction2,
|
transaction_hash=transaction2,
|
||||||
trace_address=[],
|
trace_address=[],
|
||||||
@ -107,6 +142,7 @@ def test_multiple_liquidations_in_block():
|
|||||||
debt_token_address="0x57ab1ec28d129707052df4df418d58a2d46d5f51",
|
debt_token_address="0x57ab1ec28d129707052df4df418d58a2d46d5f51",
|
||||||
debt_purchase_amount=447810000000000000000,
|
debt_purchase_amount=447810000000000000000,
|
||||||
received_amount=121531358145247546,
|
received_amount=121531358145247546,
|
||||||
|
received_token_address="0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2",
|
||||||
protocol=Protocol.aave,
|
protocol=Protocol.aave,
|
||||||
transaction_hash=transaction3,
|
transaction_hash=transaction3,
|
||||||
trace_address=[],
|
trace_address=[],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user