Skip to content

Commit

Permalink
update combinatorial auction test to new competition format
Browse files Browse the repository at this point in the history
- use `get_uid_trader` from `orderbook_api`
- remove dependency on web3api
- add more type information, which is required due to some function
  returning `Type | None` now
- remove using objective instead of surplus in case of small objective
  (the objective is not available from the competition endpoint anymore)
- remove old tests which used old competition data format
  • Loading branch information
fhenneke committed Dec 18, 2023
1 parent 01ce598 commit 1793fce
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 51 deletions.
46 changes: 12 additions & 34 deletions src/monitoring_tests/combinatorial_auction_surplus_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
from typing import Any
from fractions import Fraction
from src.monitoring_tests.base_test import BaseTest
from src.apis.web3api import Web3API
from src.apis.orderbookapi import OrderbookAPI
from src.models import Trade
from src.constants import SURPLUS_ABSOLUTE_DEVIATION_ETH


Expand All @@ -35,7 +33,6 @@ class CombinatorialAuctionSurplusTest(BaseTest):

def __init__(self) -> None:
super().__init__()
self.web3_api = Web3API()
self.orderbook_api = OrderbookAPI()

def run_combinatorial_auction(self, competition_data: dict[str, Any]) -> bool:
Expand All @@ -53,12 +50,15 @@ def run_combinatorial_auction(self, competition_data: dict[str, Any]) -> bool:
solutions = competition_data["solutions"]
winning_solution = competition_data["solutions"][-1]

aggregate_solutions = [
self.get_token_pairs_surplus(
aggregate_solutions: list[dict[tuple[str, str], Fraction]] = []
for solution in solutions:
aggregate_solution = self.get_token_pairs_surplus(
solution, competition_data["auction"]["prices"]
)
for solution in solutions
]
if aggregate_solution is None:
return False
aggregate_solutions.append(aggregate_solution)

winning_aggregate_solution = aggregate_solutions[-1]

baseline_surplus = self.compute_baseline_surplus(aggregate_solutions)
Expand Down Expand Up @@ -113,30 +113,16 @@ def run_combinatorial_auction(self, competition_data: dict[str, Any]) -> bool:

return True

def get_uid_trades(self, solution: dict[str, Any]) -> dict[str, Trade]:
"""Get a dictionary mapping UIDs to trades in a solution."""
calldata = solution["callData"]
settlement = self.web3_api.get_settlement_from_calldata(calldata)
trades = self.web3_api.get_trades(settlement)
trades_dict = {
solution["orders"][i]["id"]: trade for (i, trade) in enumerate(trades)
}
return trades_dict

def get_token_pairs_surplus(
self, solution: dict[str, Any], prices: dict[str, float]
) -> dict[tuple[str, str], Fraction]:
) -> dict[tuple[str, str], Fraction] | None:
"""Aggregate surplus of a solution on the different token pairs.
The result is a dict containing directed token pairs and the aggregated surplus on them.
Instead of surplus we use the minimum of surplus and the objective. This is more
conservative than just using objective. If fees are larger than costs, the objective is
larger than surplus and surplus is used for the comparison. If fees are larger than costs,
the objective is smaller than surplus and the objective is used instead of surplus for
filtering. This takes care of the case of solvers providing a lot of surplus but at really
large costs.
"""
trades_dict = self.get_uid_trades(solution)
trades_dict = self.orderbook_api.get_uid_trades(solution)
if trades_dict is None:
return None

surplus_dict: dict[tuple[str, str], Fraction] = {}
for uid in trades_dict:
trade = trades_dict[uid]
Expand All @@ -159,14 +145,6 @@ def get_token_pairs_surplus(
+ surplus_token_to_eth * trade.get_surplus()
)

# use the minimum of surplus and objective in case there is only one token pair
if len(surplus_dict) == 1:
for token_pair in surplus_dict:
surplus_dict[token_pair] = min(
surplus_dict[token_pair],
Fraction(solution["objective"]["total"]) / 10**18,
)

return surplus_dict

def compute_baseline_surplus(
Expand Down
19 changes: 2 additions & 17 deletions tests/e2e/combinatorial_auction_surplus_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,8 @@
class TestCombinatorialAuctionSurplus(unittest.TestCase):
def test_surplus(self) -> None:
surplus_test = CombinatorialAuctionSurplusTest()
# # Baseline EBBO error
# tx_hash = "0x4115f6f4abaea17f2ebef3a1e75c589c38cac048ff5116d406038e48ff7aeacd"
# # large settlement with bad execution for one of the orders
# tx_hash = "0xc22b1e4984b212e679d4af49c1622e7018c83d5e32ece590cf84a3e1950f9f18"
# # EBBO violations
# #
# tx_hash = "0x2ff69424f7bf8951ed5e7dd04b648380b0e73dbf7f0191c800651bc4b16a30c5"
# # combinatorial auction worse than current auction
# tx_hash = "0xb743b023ad838f04680fd321bf579c35931c4f886f664bd2b6e675c310a9c287"
# # combinatorial auction better than current auction
# tx_hash = "0x46639ae0e516bcad7b052fb6bfb6227d0aa2707e9882dd8d86bab2ab6aeee155"
# tx_hash = "0xe28b92ba73632d6b167fdb9bbfec10744ce208536901dd43379a6778c4408536"
# tx_hash = "0xad0ede9fd68481b8ef4722d069598898e01d61427ccb378ca4c82c772c6644e0"
# tx_hash = "0xead8f01e8e24fdc306fca8fcac5146edc22c27e49a7aad6134adc2ad50ba8581"
# tx_hash = "0x6200e744e5d6f9990271be53840c01044cc19f3a8526190e1eaac0bc5fefed85"
# uncovered bug with wrong scaling of objective
tx_hash = "0x97b2f8402d239e16b62b7cc2302ed77ac8fa40d63114ab6804041c9d3b9e6b81"
# CoW with liquidity order by Naive solver
tx_hash = "0x6b728195926e033ab92bbe7db51170c582ff57ba841aaaca3a9319cfe34491ff"
self.assertTrue(surplus_test.run(tx_hash))


Expand Down

0 comments on commit 1793fce

Please sign in to comment.