-
Notifications
You must be signed in to change notification settings - Fork 266
Adjust sandwiches calculation #307
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,32 +42,57 @@ def _get_sandwich_starting_with_swap( | |
]: | ||
return None | ||
|
||
for other_swap in rest_swaps: | ||
if other_swap.transaction_hash == front_swap.transaction_hash: | ||
for back_swap in rest_swaps: | ||
if back_swap.transaction_hash == front_swap.transaction_hash: | ||
continue | ||
|
||
if other_swap.contract_address == front_swap.contract_address: | ||
if back_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 | ||
back_swap.token_in_address == front_swap.token_in_address | ||
and back_swap.token_out_address == front_swap.token_out_address | ||
and back_swap.from_address != sandwicher_address | ||
): | ||
sandwiched_swaps.append(other_swap) | ||
sandwiched_swaps.append(back_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 | ||
back_swap.token_out_address == front_swap.token_in_address | ||
and back_swap.token_in_address == front_swap.token_out_address | ||
and back_swap.from_address == sandwicher_address | ||
): | ||
if len(sandwiched_swaps) > 0: | ||
profit_amount: float | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this formula needs some documentation in the code. Explain a little what is happening in here, and if you can put a math formula in clearer syntax than python code that would be nice. @gheise how do we know if the formula is correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks for pointing that out, the reasons for this are mathematically expressible. I will add further detail on the PR about why i chose this formula and what it means, but i think we should leave this out of the code |
||
if back_swap.token_in_amount == 0 and back_swap.error is None: | ||
raise ValueError("Backrun cannot swap 0 tokens") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This error doesn't have a test case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't expect this to ever happen on chain; i added this here to be explicit about the assumption that the back swap must be ruled out in the case this value is 0 as to avoid a DivisionByZero error, so test coverage here would not be meaningful |
||
if back_swap.token_in_amount == front_swap.token_out_amount: | ||
profit_amount = ( | ||
back_swap.token_out_amount - front_swap.token_in_amount | ||
) | ||
|
||
if back_swap.token_in_amount > front_swap.token_out_amount: | ||
exchange_rate = ( | ||
front_swap.token_out_amount / back_swap.token_in_amount | ||
) | ||
profit_amount = ( | ||
exchange_rate * back_swap.token_out_amount | ||
- front_swap.token_in_amount | ||
) | ||
|
||
if back_swap.token_in_amount < front_swap.token_out_amount: | ||
exchange_rate = ( | ||
back_swap.token_in_amount / front_swap.token_out_amount | ||
) | ||
profit_amount = ( | ||
back_swap.token_out_amount | ||
- exchange_rate * front_swap.token_in_amount | ||
) | ||
|
||
return Sandwich( | ||
block_number=front_swap.block_number, | ||
sandwicher_address=sandwicher_address, | ||
frontrun_swap=front_swap, | ||
backrun_swap=other_swap, | ||
backrun_swap=back_swap, | ||
sandwiched_swaps=sandwiched_swaps, | ||
profit_token_address=front_swap.token_in_address, | ||
profit_amount=other_swap.token_out_amount | ||
- front_swap.token_in_amount, | ||
profit_amount=profit_amount, | ||
) | ||
|
||
return None |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from typing import List | ||
|
||
from mev_inspect.classifiers.trace import TraceClassifier | ||
from mev_inspect.sandwiches import get_sandwiches | ||
from mev_inspect.schemas.sandwiches import Sandwich | ||
from mev_inspect.schemas.swaps import Swap | ||
from mev_inspect.swaps import get_swaps | ||
from tests.utils import load_test_block | ||
|
||
|
||
def test_back_heavy_sandwich_profits(trace_classifier: TraceClassifier): | ||
block_number = 13699765 | ||
expected_sandwicher = "0x51399b32cd0186bb32230e24167489f3b2f47870" | ||
expected_token_address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" | ||
expected_profit_amount = -435805264121298944 | ||
|
||
block = load_test_block(block_number) | ||
classified_traces = trace_classifier.classify(block.traces) | ||
swaps: List[Swap] = get_swaps(classified_traces) | ||
result: List[Sandwich] = get_sandwiches(swaps) | ||
|
||
for observed_sandwich in result: | ||
if observed_sandwich.sandwicher_address == expected_sandwicher: | ||
assert expected_token_address == observed_sandwich.profit_token_address | ||
assert expected_profit_amount == observed_sandwich.profit_amount | ||
|
||
|
||
def test_front_heavy_sandwich_profits(trace_classifier: TraceClassifier): | ||
block_number = 14659109 | ||
expected_sandwicher = "0x01ff6318440f7d5553a82294d78262d5f5084eff" | ||
expected_token_address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" | ||
expected_profit_amount = -180511102573164864 | ||
|
||
block = load_test_block(block_number) | ||
classified_traces = trace_classifier.classify(block.traces) | ||
swaps: List[Swap] = get_swaps(classified_traces) | ||
result: List[Sandwich] = get_sandwiches(swaps) | ||
|
||
for observed_sandwich in result: | ||
if observed_sandwich.sandwicher_address == expected_sandwicher: | ||
assert expected_token_address == observed_sandwich.profit_token_address | ||
assert expected_profit_amount == observed_sandwich.profit_amount |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⭐ for the rename.