-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/cowprotocol/dune-queries
- Loading branch information
Showing
11 changed files
with
545 additions
and
209 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,97 @@ | ||
-- This query computes how much surplus has been provided to CoW AMMs, when trading with other user orders | ||
-- as part of a CoW. For that, a CoW detector query is used (4025739(). Finally, the query computes the | ||
-- distribution of an amount {{budget}} of COW tokens to solvers, proportionally to the surplus generated | ||
-- distribution of an amount {{cow_budget}} of COW tokens to solvers, proportionally to the surplus generated | ||
-- via CoWs and pushed to CoW AMMs. | ||
-- Parameters: | ||
-- {{start_time}} - the start date timestamp for the accounting period (inclusively) | ||
-- {{end_time}} - the end date timestamp for the accounting period (exclusively) | ||
-- {{blockchain}} -- the chain we are interested in | ||
-- {{budget}} -- the amount of COW that needs to be distributed | ||
-- {{cow_budget}} -- the amount of COW that needs to be distributed | ||
|
||
with cow_amm_surplus as ( | ||
with cow_surplus_per_batch_ethereum as ( | ||
select | ||
tx_hash, | ||
case | ||
when token_1_transfer_usd > 0 then token_1_transfer_usd + (token_1_balance_usd - token_1_transfer_usd) * token_2_transfer_usd / token_2_balance_usd | ||
else token_2_transfer_usd + (token_2_balance_usd - token_2_transfer_usd) * token_1_transfer_usd / token_1_balance_usd | ||
end as surplus | ||
from dune.cowprotocol.result_balancer_cow_amm_base_query_v_2 | ||
where istrade | ||
'ethereum' as blockchain, | ||
cow_per_batch.block_time, | ||
cow_per_batch.tx_hash, | ||
solvers.name as solver_name, | ||
naive_cow, -- fraction of batch volume traded within a CoW | ||
trades.surplus_usd as surplus_in_usd, -- surplus of the executed CoW AMM order, expressed in USD | ||
naive_cow * trades.surplus_usd as realized_cow_surplus_in_usd -- surplus of the CoW AMM that is assumed to be generated via a CoW. | ||
from "query_4025739(blockchain='ethereum',start_time='{{start_time}}',end_time='{{end_time}}')" as cow_per_batch | ||
inner join cow_protocol_ethereum.trades as trades on cow_per_batch.tx_hash = trades.tx_hash | ||
inner join cow_protocol_ethereum.batches as batches on cow_per_batch.tx_hash = batches.tx_hash | ||
inner join cow_protocol_ethereum.solvers as solvers on batches.solver_address = solvers.address and solvers.active | ||
where trades.trader in (select address from query_3959044 where blockchain = 'ethereum') | ||
), | ||
|
||
cow_surplus_per_batch as ( | ||
cow_surplus_per_batch_gnosis as ( | ||
select | ||
'gnosis' as blockchain, | ||
cow_per_batch.block_time, | ||
cow_per_batch.tx_hash, | ||
solvers.name as solver_name, | ||
naive_cow, -- fraction of batch volume traded within a CoW | ||
trades.surplus_usd as surplus_in_usd, -- surplus of the executed CoW AMM order, expressed in USD | ||
naive_cow * trades.surplus_usd as realized_cow_surplus_in_usd -- surplus of the CoW AMM that is assumed to be generated via a CoW. | ||
from "query_4025739(blockchain='gnosis',start_time='{{start_time}}',end_time='{{end_time}}')" as cow_per_batch | ||
inner join cow_protocol_gnosis.trades as trades on cow_per_batch.tx_hash = trades.tx_hash | ||
inner join cow_protocol_gnosis.batches as batches on cow_per_batch.tx_hash = batches.tx_hash | ||
inner join cow_protocol_gnosis.solvers as solvers on batches.solver_address = solvers.address and solvers.active | ||
where trades.trader in (select address from query_3959044 where blockchain = 'gnosis') | ||
), | ||
|
||
cow_surplus_per_batch_arbitrum as ( | ||
select | ||
'arbitrum' as blockchain, | ||
cow_per_batch.block_time, | ||
cow_per_batch.tx_hash, | ||
solver_address, | ||
solvers.name as solver_name, | ||
naive_cow, -- fraction of batch volume traded within a CoW | ||
surplus as surplus_in_usd, -- surplus of the executed CoW AMM order, expressed in USD | ||
naive_cow * surplus as realized_cow_surplus_in_usd -- surplus of the CoW AMM that is assumed to be generated via a CoW. | ||
from "query_4025739(blockchain='{{blockchain}}',start_time='{{start_time}}',end_time='{{end_time}}')" as cow_per_batch | ||
inner join cow_amm_surplus on cow_per_batch.tx_hash = cow_amm_surplus.tx_hash | ||
inner join cow_protocol_{{blockchain}}.batches as b on cow_per_batch.tx_hash = b.tx_hash | ||
trades.surplus_usd as surplus_in_usd, -- surplus of the executed CoW AMM order, expressed in USD | ||
naive_cow * trades.surplus_usd as realized_cow_surplus_in_usd -- surplus of the CoW AMM that is assumed to be generated via a CoW. | ||
from "query_4025739(blockchain='arbitrum',start_time='{{start_time}}',end_time='{{end_time}}')" as cow_per_batch | ||
inner join cow_protocol_arbitrum.trades as trades on cow_per_batch.tx_hash = trades.tx_hash | ||
inner join cow_protocol_arbitrum.batches as batches on cow_per_batch.tx_hash = batches.tx_hash | ||
inner join cow_protocol_arbitrum.solvers as solvers on batches.solver_address = solvers.address and solvers.active | ||
where trades.trader in (select address from query_3959044 where blockchain = 'arbitrum') | ||
), | ||
|
||
aggregate_results_per_solver as ( | ||
cow_surplus_per_batch as ( | ||
select * from cow_surplus_per_batch_ethereum | ||
union all | ||
select * from cow_surplus_per_batch_gnosis | ||
union all | ||
select * from cow_surplus_per_batch_arbitrum | ||
), | ||
|
||
|
||
aggregate_result_per_solver as ( | ||
select | ||
name as solver_name, | ||
solver_name, | ||
sum(realized_cow_surplus_in_usd) as total_cow_surplus_in_usd | ||
from cow_surplus_per_batch | ||
inner join cow_protocol_{{blockchain}}.solvers as s on cow_surplus_per_batch.solver_address = s.address and s.active | ||
group by name | ||
group by solver_name | ||
), | ||
|
||
total_surplus as ( | ||
select sum(total_cow_surplus_in_usd) as total_surplus_in_usd from aggregate_results_per_solver | ||
|
||
---- final results | ||
|
||
reward_addresses as ( | ||
select | ||
solver as solver_address, | ||
reward_target, | ||
substring(solver_name, 6, 100) as solver_name | ||
from "query_1541516(end_time='{{end_time}}',vouch_cte_name='named_results')" | ||
), | ||
|
||
final_results_per_solver as ( | ||
select | ||
arps.solver_name, | ||
total_cow_surplus_in_usd, | ||
{{budget}} * arps.total_cow_surplus_in_usd / ts.total_surplus_in_usd as total_cow_reward | ||
from aggregate_results_per_solver as arps cross join total_surplus as ts | ||
select distinct | ||
a.solver_name, | ||
b.reward_target, | ||
a.total_cow_surplus_in_usd, | ||
{{cow_budget}} * a.total_cow_surplus_in_usd / (select sum(total_cow_surplus_in_usd) from aggregate_result_per_solver) as total_cow_reward | ||
from aggregate_result_per_solver as a | ||
inner join reward_addresses as b on a.solver_name = b.solver_name | ||
where a.total_cow_surplus_in_usd > 0 | ||
) | ||
|
||
select * from {{results}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
-- Computes the TVL, lp token total supply and lp token price of a uniswap pool over time | ||
-- Parameters | ||
-- {{token_a}} - either token of the desired uni pool | ||
-- {{token_b}} - other token of the desired uni pool | ||
-- {{start}} - date as of which the analysis should run | ||
-- {{blockchain}} - chain for which the query is running | ||
|
||
-- Given that we might not have records every day in the source data (e.g. not every day the lp supply may change), | ||
-- but still want to visualize development on a per day basis, we create an auxiliary table with one record per | ||
-- day between `start` and `now` | ||
with date_range as ( | ||
select t.day | ||
from | ||
unnest(sequence( | ||
date(timestamp '{{start}}'), | ||
date(now()) | ||
)) t (day) --noqa: AL01 | ||
), | ||
|
||
-- prefilter only relevant pools | ||
relevant_liquidity as ( | ||
select * | ||
from balancer.liquidity | ||
where | ||
token_address in ({{token_a}}, {{token_b}}) | ||
and pool_type <> 'balancer_cowswap_amm' | ||
and blockchain = '{{blockchain}}' | ||
and day = date(now()) | ||
), | ||
|
||
-- get the pool with the largest TVL | ||
pool as ( | ||
select | ||
l1.pool_address, | ||
l1.blockchain, | ||
l1.pool_liquidity_usd + l2.pool_liquidity_usd as tvl | ||
from relevant_liquidity as l1 | ||
inner join relevant_liquidity as l2 | ||
on | ||
l1.pool_address = l2.pool_address | ||
and l1.token_address = {{token_a}} | ||
and l2.token_address = {{token_b}} | ||
order by 3 desc | ||
limit 1 | ||
), | ||
|
||
-- per day lp token total supply changes of the uniswap pool by looking at burn/mint events | ||
lp_supply_delta as ( | ||
select | ||
date(evt_block_time) as "day", | ||
sum(case when "from" = 0x0000000000000000000000000000000000000000 then value else -value end) as delta | ||
from erc20_{{blockchain}}.evt_transfer | ||
where | ||
contract_address = (select pool_address from pool) | ||
and ("from" = 0x0000000000000000000000000000000000000000 or "to" = 0x0000000000000000000000000000000000000000) | ||
group by 1 | ||
), | ||
|
||
-- per day lp token total supply by summing up all deltas (may have missing records for some days) | ||
lp_total_supply_incomplete as ( | ||
select | ||
day, | ||
sum(delta) over (order by day) as total_lp | ||
from lp_supply_delta | ||
), | ||
|
||
-- performance optimisation: reduce the total range of the join below to the last value before the start period | ||
lp_total_supply_start as ( | ||
select max(day) as "start" | ||
from lp_total_supply_incomplete | ||
where day <= date(timestamp '{{start}}') | ||
), | ||
|
||
-- lp token total supply without date gaps | ||
lp_total_supply as ( | ||
select | ||
day, | ||
total_lp | ||
from ( | ||
-- join full date range with potentially incomplete data. This results in many rows per day (all total supplies on or before that day) | ||
-- rank() is then used to order join candidates by recency (rank = 1 is the latest lp supply) | ||
select | ||
date_range.day, | ||
total_lp, | ||
rank() over (partition by (date_range.day) order by lp.day desc) as latest | ||
from date_range | ||
inner join lp_total_supply_incomplete as lp | ||
on | ||
date_range.day >= lp.day | ||
and lp.day >= (select start from lp_total_supply_start) | ||
) | ||
where latest = 1 | ||
), | ||
|
||
-- Get tvl by multiplying day end reserves with their token's closing price | ||
tvl as ( | ||
select | ||
l.day, | ||
sum(token_balance * price_close) as tvl | ||
from balancer.liquidity as l | ||
inner join pool | ||
on | ||
l.pool_address = pool.pool_address | ||
and l.blockchain = pool.blockchain | ||
left join prices.usd_daily as p1 | ||
on | ||
l.blockchain = p1.blockchain | ||
and l.token_address = p1.contract_address | ||
and l.day = p1.day | ||
group by 1 | ||
), | ||
|
||
lp_token_price as ( | ||
select | ||
dr.day, | ||
tvl, | ||
total_lp, | ||
tvl / total_lp as lp_token_price | ||
from date_range as dr | ||
left join tvl | ||
on dr.day = tvl.day | ||
left join lp_total_supply as lp | ||
on dr.day = lp.day | ||
) | ||
|
||
-- Compute current value of initial investment together with other relevant output columns | ||
select | ||
day, | ||
tvl, | ||
total_lp, | ||
lp_token_price, | ||
( | ||
-- Assess initial investment in lp tokens | ||
select 10000 / lp_token_price as investment | ||
from lp_token_price | ||
where day = timestamp '{{start}}' | ||
) * lp_token_price as current_value_of_investment | ||
from lp_token_price | ||
order by 1 desc |
80 changes: 80 additions & 0 deletions
80
cowamm/profitability/invariant_growth/balancer_4106329.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
-- Computes the swap fee per $100 tvl for each day (aka its invariant growth) for a Balancer pool. | ||
-- Parameters | ||
-- {{token_a}} - either token of the desired uni pool | ||
-- {{token_b}} - other token of the desired uni pool | ||
-- {{start}} - date as of which the analysis should run | ||
-- {{blockchain}} - chain for which the query is running | ||
|
||
-- Limit the date range | ||
with date_range as ( | ||
select t.day | ||
from | ||
unnest(sequence( | ||
date(timestamp '{{start}}'), | ||
date(now()) | ||
)) t (day) --noqa: AL01 | ||
), | ||
|
||
-- prefilter only relevant pools | ||
relevant_liquidity as ( | ||
select * | ||
from balancer.liquidity | ||
where | ||
token_address in ({{token_a}}, {{token_b}}) | ||
and blockchain = '{{blockchain}}' | ||
and pool_type <> 'balancer_cowswap_amm' | ||
and day = date(now()) | ||
), | ||
|
||
-- get the pool with the largest TVL | ||
pool as ( | ||
select | ||
l1.pool_address, | ||
l1.blockchain, | ||
l1.pool_liquidity_usd + l2.pool_liquidity_usd as tvl | ||
from relevant_liquidity as l1 | ||
inner join relevant_liquidity as l2 | ||
on | ||
l1.pool_address = l2.pool_address | ||
and l1.token_address = {{token_a}} | ||
and l2.token_address = {{token_b}} | ||
order by tvl desc | ||
limit 1 | ||
), | ||
|
||
-- compute $ tvl using the same price feed we use for other reference pools | ||
-- (as the price feed that balance uses seems inaccurate) | ||
tvl as ( | ||
select | ||
l.day, | ||
l.pool_address, | ||
l.blockchain, | ||
sum(token_balance * price_close) as tvl | ||
from balancer.liquidity as l | ||
inner join pool | ||
on | ||
l.pool_address = pool.pool_address | ||
and l.blockchain = pool.blockchain | ||
left join prices.usd_daily as p1 | ||
on | ||
l.blockchain = p1.blockchain | ||
and l.token_address = p1.contract_address | ||
and l.day = p1.day | ||
group by l.day, l.pool_address, l.blockchain | ||
) | ||
|
||
select | ||
dr.day, | ||
swap_amount_usd as volume, | ||
fee_amount_usd as absolute_invariant_growth, | ||
tvl, | ||
fee_amount_usd / tvl as pct_invariant_growth | ||
from date_range as dr | ||
left join tvl | ||
on dr.day = tvl.day | ||
left join balancer.pools_metrics_daily as bal | ||
on | ||
dr.day = bal.block_date | ||
and project_contract_address = tvl.pool_address | ||
and tvl.blockchain = bal.blockchain | ||
order by dr.day desc |
Oops, something went wrong.