Skip to content

Commit 4638492

Browse files
fhennekeharisang
andauthored
Add base query for analysing CIP 74 (#318)
* add base query for analysing cip 74 * typo and clarification Co-authored-by: Felix Henneke <felix.henneke@protonmail.com> * add other chains * add score * address minor suggestions * fix lint * use actual reward and uploaded volume fee * fix lint remove error from non-standard type --------- Co-authored-by: Haris Angelidakis <64154020+harisang@users.noreply.github.com> Co-authored-by: harisang <harisangelidakis@gmail.com>
1 parent 7697841 commit 4638492

2 files changed

Lines changed: 150 additions & 0 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[sqlfluff:templater:jinja:context]
2+
blockchain=ethereum
3+
start_time='2024-08-20 00:00:00'
4+
end_time='2024-08-27 00:00:00'
5+
volume_fee_bps_stable=2.0
6+
volume_fee_bps_variable=2.0
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
-- This query is the basis for experiments with capping rewards by a fraction of protocol fees
2+
--
3+
-- It is under version control in https://github.com/cowprotocol/dune-queries
4+
--
5+
-- Parameters:
6+
-- {{start_time}} - the timestamp for which the analysis should start (inclusively)
7+
-- {{end_time}} - the timestamp for which the analysis should end (exclusively)
8+
-- {{blockchain}} - network to run the analysis on
9+
-- {{volume_fee_bps_stable}} - fraction of volume charged as fee on correlated tokens
10+
-- {{volume_fee_bps_variable}} - fraction of volume charged as fee on uncorrelated tokens
11+
--
12+
-- The columns of the result are
13+
-- - time: time of the auction (deadline)
14+
-- - auction_id: id of the auction
15+
-- - solver: winning solver in that auction
16+
-- - xrate_type: either 'stable' for trades between highly correlated tokens, 'variable' for trades between uncorrelated tokens,
17+
-- None if a classification was not possible
18+
-- - protocol_fee: sum of protocol fees (excluding fees charged by partners) charged by a solver, in native token
19+
-- - volume: sum of volume of trades, in native token
20+
-- - new_protocol_fee: new protocol fee when changing the volume fee for some class of orders
21+
-- - score: sum of winning scores, in native token
22+
-- - uncapped_reward: uncapped second price reward for the solver in that auction
23+
-- - reward: current reward
24+
-- - new_reward: reward based on capping from above by new_protocol_fee, the original cap from below applies
25+
-- - old_reward: reward based on static caps
26+
-- - profit: protocol profit as difference of protocol fee and reward
27+
-- - new_profit: same as profit but for new reward and new protocol fee
28+
-- - reward_missed: amount a solver could have gotten from taking a cut instead of getting a capped reward;
29+
-- this is a measure of how much solvers can gain from acting strategically with their bidding
30+
-- - new_reward_missed: same as reward_missed but for new reward
31+
-- - old_reward_missed: same as reward_missed but for old reward
32+
33+
34+
with wrapped_native_token as (
35+
select
36+
case '{{blockchain}}'
37+
when 'ethereum' then 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 -- WETH
38+
when 'gnosis' then 0xe91d153e0b41518a2ce8dd3d7944fa863463a97d -- WXDAI
39+
when 'arbitrum' then 0x82af49447d8a07e3bd95bd0d56f35241523fbab1 -- WETH
40+
when 'base' then 0x4200000000000000000000000000000000000006 -- WETH
41+
when 'avalanche_c' then 0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7 -- WAVAX
42+
when 'polygon' then 0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270 -- WPOL
43+
when 'bnb' then 0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c -- WBNB
44+
end as native_token_address
45+
),
46+
47+
reward_caps as (
48+
select
49+
case '{{blockchain}}' --noqa: PRS, LT02
50+
when 'ethereum' then cast(0.012 * 1e18 as int256) -- 0.012 ETH
51+
when 'arbitrum' then cast(0.012 * 1e18 as int256) -- 0.012 ETH
52+
when 'base' then cast(0.012 * 1e18 as int256) -- 0.012 ETH
53+
when 'gnosis' then cast(10 * 1e18 as int256) -- 10 xDAI
54+
when 'avalanche_c' then cast(0.4 * 1e18 as int256) -- 0.4 AVAX
55+
when 'polygon' then cast(40 * 1e18 as int256) -- 40 POL
56+
when 'bnb' then cast(0.048 * 1e18 as int256) -- 0.048 BNB
57+
end as upper_cap,
58+
case '{{blockchain}}'
59+
when 'ethereum' then cast(0.01 * 1e18 as int256) -- 0.01 ETH
60+
when 'arbitrum' then cast(0.01 * 1e18 as int256) -- 0.01 ETH
61+
when 'base' then cast(0.01 * 1e18 as int256) -- 0.01 ETH
62+
when 'gnosis' then cast(10 * 1e18 as int256) -- 10 xDAI
63+
when 'avalanche_c' then cast(0.3 * 1e18 as int256) -- 0.3 AVAX
64+
when 'polygon' then cast(30 * 1e18 as int256) -- 30 POL
65+
when 'bnb' then cast(0.04 * 1e18 as int256) -- 0.04 BNB
66+
end as lower_cap
67+
),
68+
69+
per_solver_auction_data as (
70+
select
71+
b.time,
72+
rbd.auction_id,
73+
rbd.solver,
74+
rbd.uncapped_payment_native_token as uncapped_reward,
75+
rbd.capped_payment as reward,
76+
sum(rbd.winning_score) as score,
77+
coalesce(sum((rod.protocol_fee - coalesce(rod.partner_fee, 0)) * rod.protocol_fee_native_price), 0) as protocol_fee, -- this is the actual revenue of the protocol
78+
coalesce(sum(coalesce(rod.protocol_volume_fee, 0) * rod.protocol_fee_native_price), 0) as protocol_volume_fee,
79+
coalesce(sum(case when t.order_type = 'SELL' then t.atoms_bought * rod.protocol_fee_native_price else t.atoms_sold * rod.protocol_fee_native_price end), 0) as volume,
80+
bool_and(
81+
case
82+
when t.order_type = 'SELL' then abs((rod.protocol_fee_native_price * t.atoms_bought * p.price / 1e18) / coalesce(t.buy_value_usd, t.usd_value) - 1) < 0.2
83+
else abs((rod.protocol_fee_native_price * t.atoms_sold * p.price / 1e18) / coalesce(t.sell_value_usd, t.usd_value) - 1) < 0.2
84+
end
85+
) as native_prices_are_accurate,
86+
bool_or(t.tx_hash is not null) as at_least_partial_success, -- this implies that there is data on trades which makes checking native prices meaningful
87+
if(bool_and(st.ref_date is not null), 'stable', if(bool_and(t.sell_token_address is not null and st.ref_date is null), 'variable')) as xrate_type
88+
from "query_4351957(blockchain='{{blockchain}}')" as rbd
89+
left join "query_4364122(blockchain='{{blockchain}}')" as rod
90+
on rbd.auction_id = rod.auction_id and rbd.solver = rod.solver and rbd.tx_hash = rod.tx_hash
91+
left join cow_protocol_{{blockchain}}.trades as t
92+
on rod.order_uid = t.order_uid and rod.tx_hash = t.tx_hash
93+
left join {{blockchain}}.blocks as b
94+
on rbd.block_deadline = b.number
95+
left join prices.day as p
96+
on date_trunc('day', b.time) = p.timestamp
97+
and p.contract_address = (select * from wrapped_native_token)
98+
and p.blockchain = '{{blockchain}}'
99+
left join "query_5719467(blockchain='{{blockchain}}', start_date='{{start_time}}', end_date='{{end_time}}')" as st
100+
on t.sell_token_address = st.sell_token_address
101+
and t.buy_token_address = st.buy_token_address
102+
and t.block_date = date(st.ref_date)
103+
where b.time >= (timestamp '{{start_time}}') and b.time < (timestamp '{{end_time}}')
104+
group by 1, 2, 3, 4, 5
105+
),
106+
107+
rewards_per_auction as (
108+
select
109+
time,
110+
auction_id,
111+
solver,
112+
xrate_type,
113+
protocol_fee,
114+
protocol_volume_fee,
115+
volume,
116+
protocol_fee - protocol_volume_fee + (volume + protocol_volume_fee) * if(xrate_type = 'stable', {{volume_fee_bps_stable}}, {{volume_fee_bps_variable}}) / 1e4 as new_protocol_fee,
117+
score,
118+
uncapped_reward,
119+
reward
120+
from per_solver_auction_data
121+
where
122+
(
123+
native_prices_are_accurate -- this filters out cases where native prices are not accurate
124+
and uncapped_reward < volume -- this filters out cases where native prices were corrected but rewards are too large
125+
)
126+
or not at_least_partial_success -- this makes sure the filtering is only applied if some onchain data exists
127+
),
128+
129+
new_rewards_per_auction as (
130+
select
131+
*,
132+
least(new_protocol_fee, greatest(uncapped_reward, -(select lower_cap from reward_caps))) as new_reward,
133+
least((select upper_cap from reward_caps), greatest(uncapped_reward, -(select lower_cap from reward_caps))) as old_reward
134+
from rewards_per_auction
135+
)
136+
137+
select
138+
*,
139+
protocol_fee - reward as profit,
140+
new_protocol_fee - new_reward as new_profit,
141+
if(uncapped_reward >=0, uncapped_reward - reward, 0) as reward_missed,
142+
if(uncapped_reward >=0, uncapped_reward - new_reward, 0) as new_reward_missed,
143+
if(uncapped_reward >=0, uncapped_reward - old_reward, 0) as old_reward_missed
144+
from new_rewards_per_auction

0 commit comments

Comments
 (0)