diff --git a/src/models/order_rewards_schema.py b/src/models/order_rewards_schema.py index c3271b29..79b87392 100644 --- a/src/models/order_rewards_schema.py +++ b/src/models/order_rewards_schema.py @@ -35,6 +35,8 @@ def from_pdf_to_dune_records(cls, rewards_df: DataFrame) -> list[dict[str, Any]] "quote_buy_amount": str(row["quote_buy_amount"]), "quote_gas_cost": float(row["quote_gas_cost"]), "quote_sell_token_price": float(row["quote_sell_token_price"]), + "partner_fee_recipient": row["partner_fee_recipient"], + "protocol_fee_kind": row["protocol_fee_kind"], }, } for row in rewards_df.to_dict(orient="records") diff --git a/src/sql/orderbook/barn_order_rewards.sql b/src/sql/orderbook/barn_order_rewards.sql index e81f5d4e..229ea5ae 100644 --- a/src/sql/orderbook/barn_order_rewards.sql +++ b/src/sql/orderbook/barn_order_rewards.sql @@ -56,7 +56,8 @@ order_surplus AS ( CASE WHEN o.kind = 'sell' THEN o.buy_token WHEN o.kind = 'buy' THEN o.sell_token - END AS surplus_token + END AS surplus_token, + ad.full_app_data as app_data FROM settlements s JOIN settlement_scores ss -- contains block_deadline @@ -70,6 +71,8 @@ order_surplus AS ( AND s.auction_id = oe.auction_id LEFT OUTER JOIN order_quotes oq -- contains quote amounts ON o.uid = oq.order_uid + LEFT OUTER JOIN app_data ad -- contains full app data + on o.app_data = ad.contract_app_data WHERE ss.block_deadline >= {{start_block}} -- since this table filtered on block_deadline is joined with another table filtered on block_number @@ -88,6 +91,8 @@ order_protocol_fee AS ( os.observed_fee, os.surplus, os.surplus_token, + convert_from(os.app_data, 'UTF8')::JSONB->'metadata'->'partnerFee'->>'recipient' as partner_fee_recipient, + fp.kind as protocol_fee_kind, CASE WHEN fp.kind = 'surplus' THEN CASE WHEN os.kind = 'sell' THEN @@ -151,6 +156,8 @@ order_protocol_fee_prices AS ( opf.surplus, opf.protocol_fee, opf.protocol_fee_token, + opf.partner_fee_recipient, + opf.protocol_fee_kind, CASE WHEN opf.sell_token != opf.protocol_fee_token THEN (opf.sell_amount - opf.observed_fee) / opf.buy_amount * opf.protocol_fee ELSE opf.protocol_fee @@ -214,7 +221,9 @@ select cast(oq.sell_amount as numeric(78, 0)) :: text as quote_sell_amount, cast(oq.buy_amount as numeric(78, 0)) :: text as quote_buy_amount, oq.gas_amount * oq.gas_price as quote_gas_cost, - oq.sell_token_price as quote_sell_token_price + oq.sell_token_price as quote_sell_token_price, + opfp.partner_fee_recipient as partner_fee_recipient, + opfp.protocol_fee_kind from trade_hashes left outer join order_execution o on trade_hashes.order_uid = o.order_uid diff --git a/src/sql/orderbook/prod_order_rewards.sql b/src/sql/orderbook/prod_order_rewards.sql index adb2aafd..229ea5ae 100644 --- a/src/sql/orderbook/prod_order_rewards.sql +++ b/src/sql/orderbook/prod_order_rewards.sql @@ -56,7 +56,8 @@ order_surplus AS ( CASE WHEN o.kind = 'sell' THEN o.buy_token WHEN o.kind = 'buy' THEN o.sell_token - END AS surplus_token + END AS surplus_token, + ad.full_app_data as app_data FROM settlements s JOIN settlement_scores ss -- contains block_deadline @@ -70,8 +71,12 @@ order_surplus AS ( AND s.auction_id = oe.auction_id LEFT OUTER JOIN order_quotes oq -- contains quote amounts ON o.uid = oq.order_uid + LEFT OUTER JOIN app_data ad -- contains full app data + on o.app_data = ad.contract_app_data WHERE ss.block_deadline >= {{start_block}} + -- since this table filtered on block_deadline is joined with another table filtered on block_number + -- the bound for this table need to be a bit looser. AND ss.block_deadline <= {{end_block}} + 100 ), order_protocol_fee AS ( @@ -86,6 +91,8 @@ order_protocol_fee AS ( os.observed_fee, os.surplus, os.surplus_token, + convert_from(os.app_data, 'UTF8')::JSONB->'metadata'->'partnerFee'->>'recipient' as partner_fee_recipient, + fp.kind as protocol_fee_kind, CASE WHEN fp.kind = 'surplus' THEN CASE WHEN os.kind = 'sell' THEN @@ -149,6 +156,8 @@ order_protocol_fee_prices AS ( opf.surplus, opf.protocol_fee, opf.protocol_fee_token, + opf.partner_fee_recipient, + opf.protocol_fee_kind, CASE WHEN opf.sell_token != opf.protocol_fee_token THEN (opf.sell_amount - opf.observed_fee) / opf.buy_amount * opf.protocol_fee ELSE opf.protocol_fee @@ -212,7 +221,9 @@ select cast(oq.sell_amount as numeric(78, 0)) :: text as quote_sell_amount, cast(oq.buy_amount as numeric(78, 0)) :: text as quote_buy_amount, oq.gas_amount * oq.gas_price as quote_gas_cost, - oq.sell_token_price as quote_sell_token_price + oq.sell_token_price as quote_sell_token_price, + opfp.partner_fee_recipient as partner_fee_recipient, + opfp.protocol_fee_kind from trade_hashes left outer join order_execution o on trade_hashes.order_uid = o.order_uid diff --git a/tests/integration/test_fetch_orderbook.py b/tests/integration/test_fetch_orderbook.py index f526085e..5e5d2026 100644 --- a/tests/integration/test_fetch_orderbook.py +++ b/tests/integration/test_fetch_orderbook.py @@ -146,6 +146,24 @@ def test_get_order_rewards(self): 1.0, 1.0, ], + "partner_fee_recipient": [ + None, + None, + None, + None, + None, + None, + None, + ], + "protocol_fee_kind": [ + None, + None, + "surplus", + None, + None, + None, + None, + ], } ) @@ -314,6 +332,84 @@ def test_get_batch_rewards(self): ) self.assertIsNone(pd.testing.assert_frame_equal(expected, rewards_df)) + def test_get_order_rewards_with_integrator_fee(self): + block_range = BlockRange(19581572, 19581581) + rewards_df = OrderbookFetcher.get_order_rewards(block_range) + expected = pd.DataFrame( + { + "block_number": [ + 19581573, + 19581573, + 19581579, + ], + "order_uid": [ + "0x0f6c83ff144aabed918417f61a92672165bba9b1c90f078fedfc10c2c16d03d09fa3c00a92ec5f96b1ad2527ab41b3932efeda58660e7959", + "0xac38b37c7821b1c0f0fd631912d7b19581c305c4bdca84dcb6d862da6cf8591cf9d7adfb5bc41283d67db9d71add65162e242f62660e7c82", + "0xc9c870decab00c1335babef5a3009186671b1bc69131c7338a4ecb2ed14831c321a01f63b263d93e124471e456578024121a6b78660e7a5b", + ], + "solver": [ + "0x4339889fd9dfca20a423fba011e9dff1c856caeb", + "0x4339889fd9dfca20a423fba011e9dff1c856caeb", + "0xc74b656bd2ebe313d26d1ac02bcf95b137d1c857", + ], + "quote_solver": [ + "0x16c473448e770ff647c69cbe19e28528877fba1b", + "0x16c473448e770ff647c69cbe19e28528877fba1b", + "0x16c473448e770ff647c69cbe19e28528877fba1b", + ], + "tx_hash": [ + "0x13315e833ed3204db3320e3e8d213c84ab21e55e715847514d78198af4f68861", + "0x13315e833ed3204db3320e3e8d213c84ab21e55e715847514d78198af4f68861", + "0x962af6dbd9940249b8a795b48c0c4cbc04c0444555bb5b16fd4d824261e282bf", + ], + "surplus_fee": [ + "958869097252287", + "29812970679943659325", + "31963685928336242096", + ], + "amount": [0.0, 0.0, 0.0], + "protocol_fee": ["346011", "0", "0"], + "protocol_fee_token": [ + "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + ], + "protocol_fee_native_price": [ + 299379646.7519555, + 299379646.7519555, + 299379646.7519555, + ], + "quote_sell_amount": [ + "11177061073424246", + "30000000000000000000000", + "667000000000000000000", + ], + "quote_buy_amount": ["37147277", "22954359609", "358516953"], + "quote_gas_cost": [ + 3605211063076992.0, + 1982659477433822.0, + 2865645675046151.0, + ], + "quote_sell_token_price": [ + 1.0, + 0.000234609143374563, + 0.000160802298220274, + ], + "partner_fee_recipient": [ + "0x9FA3c00a92Ec5f96B1Ad2527ab41B3932EFEDa58", + None, + None, + ], + "protocol_fee_kind": [ + "volume", + "priceimprovement", + "priceimprovement", + ], + } + ) + + self.assertIsNone(pd.testing.assert_frame_equal(expected, rewards_df)) + if __name__ == "__main__": unittest.main() diff --git a/tests/unit/test_order_rewards_schema.py b/tests/unit/test_order_rewards_schema.py index 667351be..3de05930 100644 --- a/tests/unit/test_order_rewards_schema.py +++ b/tests/unit/test_order_rewards_schema.py @@ -27,6 +27,8 @@ def test_order_rewards_transformation(self): 12000000000000000, ], "quote_sell_token_price": [1.0, 250000000, 100000000000000.0], + "partner_fee_recipient": [None, "0x81", None], + "protocol_fee_kind": [None, "volume", "priceimprovement"], } ) @@ -48,6 +50,8 @@ def test_order_rewards_transformation(self): "quote_buy_amount": "1000", "quote_gas_cost": 5000000000000000.15, "quote_sell_token_price": 1.0, + "partner_fee_recipient": None, + "protocol_fee_kind": None, }, }, { @@ -66,6 +70,8 @@ def test_order_rewards_transformation(self): "quote_buy_amount": "2000", "quote_gas_cost": 6000000000000000, "quote_sell_token_price": 250000000, + "partner_fee_recipient": "0x81", + "protocol_fee_kind": "volume", }, }, { @@ -84,6 +90,8 @@ def test_order_rewards_transformation(self): "quote_buy_amount": "10", "quote_gas_cost": 12000000000000000, "quote_sell_token_price": 100000000000000.0, + "partner_fee_recipient": None, + "protocol_fee_kind": "priceimprovement", }, }, ],