diff --git a/mev_inspect/inspect_block.py b/mev_inspect/inspect_block.py index c6e58c6..e22d8d3 100644 --- a/mev_inspect/inspect_block.py +++ b/mev_inspect/inspect_block.py @@ -32,6 +32,7 @@ from mev_inspect.crud.liquidations import ( ) from mev_inspect.miner_payments import get_miner_payments from mev_inspect.punks import get_punk_bid_acceptances, get_punk_bids, get_punk_snipes +from mev_inspect.sandwiches import get_sandwiches from mev_inspect.swaps import get_swaps from mev_inspect.transfers import get_transfers from mev_inspect.liquidations import get_liquidations @@ -99,6 +100,11 @@ async def inspect_block( delete_liquidations_for_block(inspect_db_session, block_number) write_liquidations(inspect_db_session, liquidations) + sandwiches = get_sandwiches(swaps) + logger.info(f"Block: {block_number} -- Found {len(sandwiches)} sandwiches") + for sandwich in sandwiches: + print(sandwich.json(indent=4)) + punk_bids = get_punk_bids(classified_traces) punk_bid_acceptances = get_punk_bid_acceptances(classified_traces) diff --git a/mev_inspect/sandwiches.py b/mev_inspect/sandwiches.py new file mode 100644 index 0000000..346d39e --- /dev/null +++ b/mev_inspect/sandwiches.py @@ -0,0 +1,51 @@ +from typing import List + +from mev_inspect.schemas.sandwiches import Sandwich +from mev_inspect.schemas.swaps import Swap + + +def get_sandwiches(swaps: List[Swap]) -> List[Sandwich]: + ordered_swaps = list( + sorted( + swaps, + key=lambda swap: (swap.transaction_position, swap.trace_address), + ) + ) + + sandwiches: List[Sandwich] = [] + + for index, front_swap in enumerate(ordered_swaps): + sandwicher_address = front_swap.from_address + rest_swaps = ordered_swaps[index:] + + sandwiched_swaps = [] + + for other_swap in rest_swaps: + if other_swap.transaction_hash == front_swap.transaction_hash: + continue + + if other_swap.contract_address == front_swap.contract_address: + if ( + other_swap.token_in_address == front_swap.token_in_address + and other_swap.token_out_address == front_swap.token_out_address + and other_swap.from_address != sandwicher_address + ): + sandwiched_swaps.append(other_swap) + elif ( + other_swap.token_out_address == front_swap.token_in_address + and other_swap.token_in_address == front_swap.token_out_address + and other_swap.from_address == sandwicher_address + ): + sandwiches.append( + Sandwich( + block_number=front_swap.block_number, + sandwicher_address=sandwicher_address, + frontrun_transaction_hash=front_swap.transaction_hash, + backrun_transaction_hash=other_swap.transaction_hash, + sandwiched_swaps=sandwiched_swaps, + ) + ) + + break + + return sandwiches diff --git a/mev_inspect/schemas/sandwiches.py b/mev_inspect/schemas/sandwiches.py new file mode 100644 index 0000000..0405026 --- /dev/null +++ b/mev_inspect/schemas/sandwiches.py @@ -0,0 +1,13 @@ +from typing import List + +from pydantic import BaseModel + +from .swaps import Swap + + +class Sandwich(BaseModel): + block_number: int + sandwicher_address: str + frontrun_transaction_hash: str + backrun_transaction_hash: str + sandwiched_swaps: List[Swap]