diff --git a/src/constants.py b/src/constants.py index 4ff3884d..d1d9d1e4 100644 --- a/src/constants.py +++ b/src/constants.py @@ -54,12 +54,3 @@ # Real Web3 Instance web3 = Web3(Web3.HTTPProvider(NODE_URL)) - -RECOGNIZED_BONDING_POOLS = [ - "('0x8353713b6D2F728Ed763a04B886B16aAD2b16eBD', 'Gnosis', " - "'0x6c642cafcbd9d8383250bb25f67ae409147f78b2')", - "('0x5d4020b9261F01B6f8a45db929704b0Ad6F5e9E6', 'CoW Services', " - "'0x423cec87f19f0778f549846e0801ee267a917935')", - "('0xC96569Dc132ebB6694A5f0b781B33f202Da8AcE8', 'Project Blanc', " - "'0xCa99e3Fc7B51167eaC363a3Af8C9A185852D1622')", -] diff --git a/src/fetch/dune.py b/src/fetch/dune.py index 62b75c0c..7d2e8edd 100644 --- a/src/fetch/dune.py +++ b/src/fetch/dune.py @@ -6,8 +6,6 @@ from dune_client.query import QueryBase from dune_client.types import QueryParameter, DuneRecord -from src.constants import RECOGNIZED_BONDING_POOLS -from src.fetch.token_list import get_trusted_tokens from src.logger import set_log from src.models.accounting_period import AccountingPeriod from src.queries import QUERIES, QueryData @@ -85,14 +83,12 @@ def get_vouches(self) -> list[DuneRecord]: """ Fetches & Returns Parsed Results for VouchRegistry query. """ - pool_values = ",\n".join(RECOGNIZED_BONDING_POOLS) return self._get_query_results( query=self._parameterized_query( query_data=QUERIES["VOUCH_REGISTRY"], params=[ - QueryParameter.date_type("EndTime", self.period.end), - QueryParameter.text_type("BondingPoolData", pool_values), - QueryParameter.enum_type("VOUCH_CTE_NAME", "valid_vouches"), + QueryParameter.date_type("end_time", self.period.end), + QueryParameter.enum_type("vouch_cte_name", "valid_vouches"), ], ) ) @@ -102,11 +98,7 @@ def get_period_slippage(self, job_id: Optional[str] = None) -> list[DuneRecord]: Executes & Fetches results of slippage query per solver for specified accounting period. Returns a class representation of the results as two lists (positive & negative). """ - token_list = get_trusted_tokens() - params = self._period_params() + [ - QueryParameter.text_type("TxHash", "0x"), - QueryParameter.text_type("TokenList", ",".join(token_list)), - ] + params = self._period_params() # trigger dashboard update self.dune.execute( self._parameterized_query(QUERIES["DASHBOARD_SLIPPAGE"], params=params) @@ -114,12 +106,7 @@ def get_period_slippage(self, job_id: Optional[str] = None) -> list[DuneRecord]: return self._get_query_results( self._parameterized_query( - QUERIES["PERIOD_SLIPPAGE"], - params=self._period_params() - + [ - QueryParameter.text_type("TxHash", "0x"), - QueryParameter.text_type("TokenList", ",".join(token_list)), - ], + QUERIES["PERIOD_SLIPPAGE"], params=self._period_params() ), job_id, ) @@ -128,12 +115,9 @@ def get_service_fee_status(self) -> list[DuneRecord]: """ Fetches & Returns Parsed Results for VouchRegistry query. """ - pool_values = ",\n".join(RECOGNIZED_BONDING_POOLS) return self._get_query_results( query=self._parameterized_query( query_data=QUERIES["SERVICE_FEE_STATUS"], - params=[ - QueryParameter.text_type("BondingPoolData", pool_values), - ], + params=[], ) ) diff --git a/src/fetch/payouts.py b/src/fetch/payouts.py index 46ec7a8d..a291393a 100644 --- a/src/fetch/payouts.py +++ b/src/fetch/payouts.py @@ -23,8 +23,6 @@ from src.pg_client import MultiInstanceDBFetcher from src.utils.print_store import Category -PERIOD_BUDGET_COW = 250000 * 10**18 -CONSISTENCY_REWARD_CAP_ETH = 6 * 10**18 QUOTE_REWARD_COW = 6 * 10**18 QUOTE_REWARD_CAP_ETH = 6 * 10**14 SERVICE_FEE_FACTOR = Fraction(15, 100) @@ -35,8 +33,6 @@ "solver", "primary_reward_eth", "primary_reward_cow", - "secondary_reward_eth", - "secondary_reward_cow", "quote_reward_cow", "protocol_fee_eth", "network_fee_eth", @@ -53,8 +49,6 @@ NUMERICAL_COLUMNS = [ "primary_reward_eth", "primary_reward_cow", - "secondary_reward_cow", - "secondary_reward_eth", "quote_reward_cow", "protocol_fee_eth", ] @@ -81,15 +75,12 @@ def __init__( # pylint: disable=too-many-arguments reward_target: Address, bonding_pool: Address, primary_reward_eth: int, - secondary_reward_eth: int, slippage_eth: int, primary_reward_cow: int, - secondary_reward_cow: int, quote_reward_cow: int, service_fee: bool, ): - assert secondary_reward_eth >= 0, "invalid secondary_reward_eth" - assert secondary_reward_cow >= 0, "invalid secondary_reward_cow" + assert quote_reward_cow >= 0, "invalid quote_reward_cow" self.solver = solver @@ -99,8 +90,6 @@ def __init__( # pylint: disable=too-many-arguments self.slippage_eth = slippage_eth self.primary_reward_eth = primary_reward_eth self.primary_reward_cow = primary_reward_cow - self.secondary_reward_eth = secondary_reward_eth - self.secondary_reward_cow = secondary_reward_cow self.quote_reward_cow = quote_reward_cow self.service_fee = service_fee @@ -114,7 +103,7 @@ def from_series(cls, frame: Series) -> RewardAndPenaltyDatum: ) solver = frame["solver"] reward_target = frame["reward_target"] - bonding_pool = frame["pool"] + bonding_pool = frame["pool_address"] if reward_target is None: logging.warning(f"solver {solver} without reward_target. Using solver") reward_target = solver @@ -127,8 +116,6 @@ def from_series(cls, frame: Series) -> RewardAndPenaltyDatum: slippage_eth=slippage, primary_reward_eth=int(frame["primary_reward_eth"]), primary_reward_cow=int(frame["primary_reward_cow"]), - secondary_reward_eth=int(frame["secondary_reward_eth"]), - secondary_reward_cow=int(frame["secondary_reward_cow"]), quote_reward_cow=int(frame["quote_reward_cow"]), service_fee=bool(frame["service_fee"]), ) @@ -139,17 +126,11 @@ def total_outgoing_eth(self) -> int: def total_cow_reward(self) -> int: """Total outgoing COW token reward""" - return int( - self.reward_scaling() - * (self.primary_reward_cow + self.secondary_reward_cow) - ) + return int(self.reward_scaling() * self.primary_reward_cow) def total_eth_reward(self) -> int: """Total outgoing ETH reward""" - return int( - self.reward_scaling() - * (self.primary_reward_eth + self.secondary_reward_eth) - ) + return int(self.reward_scaling() * self.primary_reward_eth) def reward_scaling(self) -> Fraction: """Scaling factor for service fee @@ -198,7 +179,7 @@ def as_payouts(self) -> list[Transfer]: # Note that; # reimbursement_eth + reward_eth # = self.total_eth_reward() + self.exec_cost + self.slippage_eth - # = self.payment_eth + self.secondary_reward_eth + self.slippage_eth + # = self.payment_eth + self.slippage_eth # = self.total_outgoing_eth() # >= 0 (because not self.is_overdraft()) try: @@ -288,32 +269,10 @@ def extend_payment_df(pdf: DataFrame, converter: TokenConversion) -> DataFrame: Extending the basic columns returned by SQL Query with some after-math: - reward_eth as difference of payment and execution_cost - reward_cow as conversion from ETH to cow. - - secondary_reward (as the remaining reward after all has been distributed) - This is evaluated in both ETH and COW (for different use cases). """ # Note that this can be negative! pdf["primary_reward_cow"] = pdf["primary_reward_eth"].apply(converter.eth_to_token) - secondary_allocation = max( - min( - PERIOD_BUDGET_COW - pdf["primary_reward_cow"].sum(), - converter.eth_to_token(CONSISTENCY_REWARD_CAP_ETH), - ), - 0, - ) - participation_total = pdf["num_participating_batches"].sum() - if participation_total == 0: - # Due to CIP-48 we will stop counting participation. This workaround avoids - # division by zero as the num_participation_batches is set to zero for all - # solvers after CIP-48. - participation_total = 1 - pdf["secondary_reward_cow"] = ( - secondary_allocation * pdf["num_participating_batches"] / participation_total - ) - pdf["secondary_reward_eth"] = pdf["secondary_reward_cow"].apply( - converter.token_to_eth - ) - # Pandas has poor support for large integers, must cast the constant to float here, # otherwise the dtype would be inferred as int64 (which overflows). pdf["quote_reward_cow"] = ( @@ -545,13 +504,11 @@ def construct_payouts( partner_fee_tax_wei = total_partner_fee_wei_untaxed - total_partner_fee_wei_taxed performance_reward = complete_payout_df["primary_reward_cow"].sum() - participation_reward = complete_payout_df["secondary_reward_cow"].sum() quote_reward = complete_payout_df["quote_reward_cow"].sum() dune.log_saver.print( "Payment breakdown (ignoring service fees):\n" f"Performance Reward: {performance_reward / 10 ** 18:.4f}\n" - f"Participation Reward: {participation_reward / 10 ** 18:.4f}\n" f"Quote Reward: {quote_reward / 10 ** 18:.4f}\n" f"Protocol Fees: {final_protocol_fee_wei / 10 ** 18:.4f}\n" f"Partner Fees Tax: {partner_fee_tax_wei / 10 ** 18:.4f}\n" diff --git a/src/models/accounting_period.py b/src/models/accounting_period.py index 8c7f7247..ac02a67e 100644 --- a/src/models/accounting_period.py +++ b/src/models/accounting_period.py @@ -33,8 +33,8 @@ def __hash__(self) -> int: def as_query_params(self) -> list[QueryParameter]: """Returns commonly used (StartTime, EndTime) query parameters""" return [ - QueryParameter.date_type("StartTime", self.start), - QueryParameter.date_type("EndTime", self.end), + QueryParameter.date_type("start_time", self.start), + QueryParameter.date_type("end_time", self.end), ] def dashboard_url(self) -> str: diff --git a/tests/unit/test_payouts.py b/tests/unit/test_payouts.py index 2802acad..e52f1c17 100644 --- a/tests/unit/test_payouts.py +++ b/tests/unit/test_payouts.py @@ -58,12 +58,7 @@ def setUp(self) -> None: -10000000000000000.00000, 0.00000, ] - self.batch_participation = [ - 7, - 2, - 7, - 6, - ] + self.protocol_fee_eth = [ 1000000000000000.0, 2000000000000000.0, @@ -86,7 +81,6 @@ def test_extend_payment_df(self): "solver": self.solvers, "num_quotes": self.num_quotes, "primary_reward_eth": self.primary_reward_eth, - "num_participating_batches": self.batch_participation, "protocol_fee_eth": self.protocol_fee_eth, "network_fee_eth": self.network_fee_eth, } @@ -101,7 +95,6 @@ def test_extend_payment_df(self): -10000000000000000.00000, 0.00000, ], - "num_participating_batches": self.batch_participation, "protocol_fee_eth": self.protocol_fee_eth, "network_fee_eth": self.network_fee_eth, "primary_reward_cow": [ @@ -110,18 +103,6 @@ def test_extend_payment_df(self): -10000000000000000000.0, 0.0, ], - "secondary_reward_cow": [ - 1909090909090909000000.00000, - 545454545454545440000.00000, - 1909090909090909000000.00000, - 1636363636363636200000.00000, - ], - "secondary_reward_eth": [ - 1909090909090909000.00000, - 545454545454545440.00000, - 1909090909090909000.00000, - 1636363636363636200.00000, - ], "quote_reward_cow": [ 0.00000, 0.00000, @@ -150,13 +131,10 @@ def test_validate_df_columns(self): { "solver": [], "payment_eth": [], - "num_participating_batches": [], "protocol_fee_eth": [], "network_fee_eth": [], "primary_reward_eth": [], "primary_reward_cow": [], - "secondary_reward_cow": [], - "secondary_reward_eth": [], "quote_reward_cow": [], } ) @@ -213,7 +191,6 @@ def test_construct_payouts(self): "solver": self.solvers, "num_quotes": self.num_quotes, "primary_reward_eth": self.primary_reward_eth, - "num_participating_batches": self.batch_participation, "protocol_fee_eth": self.protocol_fee_eth, "network_fee_eth": self.network_fee_eth, } @@ -250,7 +227,6 @@ def test_construct_payouts(self): "solver": self.solvers, "num_quotes": self.num_quotes, "primary_reward_eth": [600000000000000.0, 1.2e16, -1e16, 0.0], - "num_participating_batches": [7, 2, 7, 6], "protocol_fee_eth": [ 1000000000000000.0, 2000000000000000.0, @@ -269,18 +245,6 @@ def test_construct_payouts(self): -10000000000000000000.0, 0.0, ], - "secondary_reward_cow": [ - 1909090909090909000000.00000, - 545454545454545440000.00000, - 1909090909090909000000.00000, - 1636363636363636200000.00000, - ], - "secondary_reward_eth": [ - 1909090909090909000.00000, - 545454545454545440.00000, - 1909090909090909000.00000, - 1636363636363636200.00000, - ], "quote_reward_cow": [ 0.00000, 0.00000, @@ -321,18 +285,6 @@ def test_prepare_transfers(self): -10000000000000000000.0, 0.0, ], - "secondary_reward_cow": [ - 6.363636363636364e16, - 1.818181818181818e16, - 6.363636363636364e16, - 5.454545454545454e16, - ], - "secondary_reward_eth": [ - 63636363636363.0, - 18181818181818.0, - 63636363636363.0, - 54545454545454.0, - ], "quote_reward_cow": [ 0.00000, 0.00000, @@ -347,7 +299,7 @@ def test_prepare_transfers(self): "0x0000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000008", ], - "pool": [ + "pool_address": [ "0x0000000000000000000000000000000000000025", "0x0000000000000000000000000000000000000026", "0x0000000000000000000000000000000000000026", @@ -376,12 +328,12 @@ def test_prepare_transfers(self): Transfer( token=Token(COW_TOKEN_ADDRESS), recipient=Address(self.reward_targets[0]), - amount_wei=663636363636363640, + amount_wei=600000000000000000, ), Transfer( token=Token(COW_TOKEN_ADDRESS), recipient=Address(self.reward_targets[1]), - amount_wei=12018181818181818180, + amount_wei=12000000000000000000, ), Transfer( token=Token(COW_TOKEN_ADDRESS), @@ -393,11 +345,6 @@ def test_prepare_transfers(self): recipient=Address(self.reward_targets[3]), amount_wei=int(180000000000000000000 * (1 - SERVICE_FEE_FACTOR)), ), - Transfer( - token=Token(COW_TOKEN_ADDRESS), - recipient=Address(self.reward_targets[3]), - amount_wei=int(54545454545454544 * (1 - SERVICE_FEE_FACTOR)), - ), Transfer( token=None, recipient=PROTOCOL_FEE_SAFE, @@ -413,7 +360,7 @@ def test_prepare_transfers(self): Overdraft( period, account=Address(self.solvers[2]), - wei=9936363636363638, + wei=10000000000000001, name="S_3", ) ], @@ -432,7 +379,6 @@ def setUp(self) -> None: def sample_record( self, primary_reward: int, - secondary_reward: int, slippage: int, num_quotes: int, service_fee: bool = False, @@ -445,36 +391,30 @@ def sample_record( bonding_pool=self.bonding_pool, primary_reward_eth=primary_reward, primary_reward_cow=primary_reward * self.conversion_rate, - secondary_reward_eth=secondary_reward, - secondary_reward_cow=secondary_reward * self.conversion_rate, slippage_eth=slippage, quote_reward_cow=QUOTE_REWARD_COW * num_quotes, service_fee=service_fee, ) def test_invalid_input(self): - """Test that negative and secondary and quote rewards throw an error.""" - - # invalid secondary reward - with self.assertRaises(AssertionError): - self.sample_record(0, -1, 0, 0) + """Test that negative and quote rewards throw an error.""" # invalid quote reward with self.assertRaises(AssertionError): - self.sample_record(0, 0, 0, -1) + self.sample_record(0, 0, -1) - def test_reward_datum_0_0_0_0(self): + def test_reward_datum_0_0_0(self): """Without data there is no payout and no overdraft.""" - test_datum = self.sample_record(0, 0, 0, 0) + test_datum = self.sample_record(0, 0, 0) self.assertFalse(test_datum.is_overdraft()) self.assertEqual(test_datum.as_payouts(), []) - def test_reward_datum_pm1_0_0_0(self): + def test_reward_datum_pm1_0_0(self): """Primary reward only.""" # positive reward is paid in COW primary_reward = 1 - test_datum = self.sample_record(primary_reward, 0, 0, 0) + test_datum = self.sample_record(primary_reward, 0, 0) self.assertFalse(test_datum.is_overdraft()) self.assertEqual( test_datum.as_payouts(), @@ -489,16 +429,16 @@ def test_reward_datum_pm1_0_0_0(self): # negative reward gives overdraft primary_reward = -1 - test_datum = self.sample_record(primary_reward, 0, 0, 0) + test_datum = self.sample_record(primary_reward, 0, 0) self.assertTrue(test_datum.is_overdraft()) self.assertEqual(test_datum.as_payouts(), []) - def test_reward_datum_0_0_pm1_0(self): + def test_reward_datum_0_pm1_0(self): """Slippag only.""" # positive slippage is paid in ETH slippage = 1 - test_datum = self.sample_record(0, 0, slippage, 0) + test_datum = self.sample_record(0, slippage, 0) self.assertFalse(test_datum.is_overdraft()) self.assertEqual( test_datum.as_payouts(), @@ -507,14 +447,14 @@ def test_reward_datum_0_0_pm1_0(self): # negative slippage gives overdraft slippage = -1 - test_datum = self.sample_record(0, 0, slippage, 0) + test_datum = self.sample_record(0, slippage, 0) self.assertTrue(test_datum.is_overdraft()) self.assertEqual(test_datum.as_payouts(), []) - def test_reward_datum_0_0_0_1(self): + def test_reward_datum_0_0_1(self): """Quote rewards only.""" num_quotes = 1 - test_datum = self.sample_record(0, 0, 0, num_quotes) + test_datum = self.sample_record(0, 0, num_quotes) self.assertFalse(test_datum.is_overdraft()) self.assertEqual( test_datum.as_payouts(), @@ -527,10 +467,10 @@ def test_reward_datum_0_0_0_1(self): ], ) - def test_reward_datum_4_2_1_0(self): + def test_reward_datum_4_1_0(self): """COW payment for rewards, ETH payment for slippage.""" - primary_reward, secondary_reward, slippage, num_quotes = 4, 2, 1, 0 - test_datum = self.sample_record(primary_reward, secondary_reward, slippage, 0) + primary_reward, slippage, num_quotes = 4, 1, 0 + test_datum = self.sample_record(primary_reward, slippage, 0) self.assertFalse(test_datum.is_overdraft()) self.assertEqual( test_datum.as_payouts(), @@ -543,16 +483,15 @@ def test_reward_datum_4_2_1_0(self): Transfer( token=self.cow_token, recipient=self.reward_target, - amount_wei=(primary_reward + secondary_reward) - * self.conversion_rate, + amount_wei=(primary_reward) * self.conversion_rate, ), ], ) def test_reward_datum_slippage_reduces_reward(self): """Negative slippage reduces COW reward.""" - primary_reward, secondary_reward, slippage, num_quotes = 4, 2, -1, 0 - test_datum = self.sample_record(primary_reward, secondary_reward, slippage, 0) + primary_reward, slippage, num_quotes = 4, -1, 0 + test_datum = self.sample_record(primary_reward, slippage, 0) self.assertFalse(test_datum.is_overdraft()) self.assertEqual( test_datum.as_payouts(), @@ -560,26 +499,25 @@ def test_reward_datum_slippage_reduces_reward(self): Transfer( token=self.cow_token, recipient=self.reward_target, - amount_wei=(primary_reward + secondary_reward + slippage) - * self.conversion_rate, + amount_wei=(primary_reward + slippage) * self.conversion_rate, ), ], ) def test_reward_datum_slippage_exceeds_reward(self): """Negative slippage leads to overtraft.""" - primary_reward, participation, slippage = 1, 2, -4 - test_datum = self.sample_record(primary_reward, participation, slippage, 0) + primary_reward, slippage = 1, -4 + test_datum = self.sample_record(primary_reward, slippage, 0) self.assertTrue(test_datum.is_overdraft()) self.assertEqual(test_datum.as_payouts(), []) def test_reward_datum_reward_reduces_slippage(self): """Negative reward reduces ETH slippage payment.""" - primary_reward, secondary_reward, slippage = -2, 1, 3 - test_datum = self.sample_record(primary_reward, secondary_reward, slippage, 0) + primary_reward, slippage = -2, 3 + test_datum = self.sample_record(primary_reward, slippage, 0) self.assertEqual( test_datum.total_outgoing_eth(), - primary_reward + secondary_reward + slippage, + primary_reward + slippage, ) self.assertEqual( test_datum.as_payouts(), @@ -597,7 +535,6 @@ def test_performance_reward_service_fee(self): primary_reward, num_quotes, service_fee = 100, 0, True test_datum = self.sample_record( primary_reward=primary_reward, - secondary_reward=0, slippage=0, num_quotes=num_quotes, service_fee=service_fee, @@ -620,7 +557,6 @@ def test_quote_reward_service_fee(self): primary_reward, num_quotes, service_fee = 0, 100, True test_datum = self.sample_record( primary_reward=primary_reward, - secondary_reward=0, slippage=0, num_quotes=num_quotes, service_fee=service_fee,