diff --git a/cowamm/.sqlfluff b/cowamm/.sqlfluff index 423d6cf2..3591f7b7 100644 --- a/cowamm/.sqlfluff +++ b/cowamm/.sqlfluff @@ -8,3 +8,5 @@ start_time='2024-08-20 00:00:00' end_time='2024-08-27 00:00:00' results=final_results_per_solver,cow_surplus_per_batch cow_budget=30000 +number_of_pools=500 +competitor_end_time = 2100-01-01 diff --git a/cowamm/kpi/competitors/all_competitors_4335231.sql b/cowamm/kpi/competitors/all_competitors_4335231.sql new file mode 100644 index 00000000..002e2592 --- /dev/null +++ b/cowamm/kpi/competitors/all_competitors_4335231.sql @@ -0,0 +1,37 @@ +--Groups all competitors in one query +-- Parameters: +-- {{blockchain}}: The blockchain to query + +-- Uniswap, PancakeSwap, Sushiwap +select + contract_address, + tvl, + fee, + volume, + apr, + project, + case + when '{{blockchain}}' = 'ethereum' then 1 + when '{{blockchain}}' = 'gnosis' then 100 + when '{{blockchain}}' = 'arbitrum' then 8453 + when '{{blockchain}}' = 'arbitrum' then 42161 + end as chain_id +from "query_4304295(blockchain='{{blockchain}}')" + +union distinct + +--Curve +select + contract_address, + tvl, + fee, + volume, + apr, + 'curve' as project, + case + when '{{blockchain}}' = 'ethereum' then 1 + when '{{blockchain}}' = 'gnosis' then 100 + when '{{blockchain}}' = 'arbitrum' then 8453 + when '{{blockchain}}' = 'arbitrum' then 42161 + end as chain_id +from "query_4232873(blockchain='{{blockchain}}')" diff --git a/cowamm/kpi/competitors/curve/curve_kpis_4232873.sql b/cowamm/kpi/competitors/curve/curve_kpis_4232873.sql new file mode 100644 index 00000000..50b1f81d --- /dev/null +++ b/cowamm/kpi/competitors/curve/curve_kpis_4232873.sql @@ -0,0 +1,27 @@ +-- Computes volume, tvl and APR for Curve pools +-- APR is measured as the fees earned per $ invested, over the last 24 hours, projected over 1 year +-- Parameters: +-- {{blockchain}}: The blockchain to query +-- {{competitor_end_time}}: The end time of the time window (end_time - 1 day; end_time), defaults to now() +select + contract_address, + fee, + tvl, + sum(amount_usd) over (partition by contract_address order by latest_per_pool) as volume, + 365 * sum(amount_usd * fee / tvl) over (partition by contract_address order by latest_per_pool) as apr +-- The first call to 4232976 gets the tvl after each tx to compute volume/tvl +from "query_4232976(blockchain='{{blockchain}}')" as r +left join + ( --noqa: ST05 + select * + from curve.trades + where + block_time >= date_add('day', -1, (case when '{{competitor_end_time}}' = '2100-01-01' then now() else timestamp '{{competitor_end_time}}' end)) + ) as t + on + r.contract_address = t.project_contract_address + and r.tx_hash = t.tx_hash +where + latest_per_pool = 1 + -- This test avoids any possible issue with reconstructing the reserves of the pool + and tvl > 0 diff --git a/cowamm/kpi/competitors/curve/curve_largest_2token_pools_4232976.sql b/cowamm/kpi/competitors/curve/curve_largest_2token_pools_4232976.sql new file mode 100644 index 00000000..f6cfb9b7 --- /dev/null +++ b/cowamm/kpi/competitors/curve/curve_largest_2token_pools_4232976.sql @@ -0,0 +1,99 @@ +-- Finds all the curve pools with 2 tokens and their TVLs at every moment in time +-- For every pool that is currently one of the {{number_of_pools}} largest by TVL: +-- It returns their TVL at every moment in time +-- Parameters: +-- {{blockchain}}: The blockchain to query +-- {{number_of_pools}}: The number of largest pools to return + +with +-- filters pools with 2 tokens +pools as ( + select + pool_address as contract_address, + coin0 as token0, + coin1 as token1, + mid_fee * power(10, -10) as fee + from curvefi_{{blockchain}}.view_pools + -- Curve pools can have more than 2 token, if coin2 = 0x00 it means there are 2 tokens at most + where coin2 = 0x0000000000000000000000000000000000000000 +), + +-- finds all transfers in and out of the pools to rebuild the reserves +transfers as ( + select + p.contract_address, + token0, + token1, + evt_block_time as block_time, + evt_index, + evt_tx_hash as tx_hash, + fee, + case + when t.contract_address = token0 and "from" = p.contract_address then -value + when t.contract_address = token0 and to = p.contract_address then value else 0 + end as transfer0, + case + when t.contract_address = token1 and "from" = p.contract_address then -value + when t.contract_address = token1 and to = p.contract_address then value else 0 + end as transfer1 + from erc20_{{blockchain}}.evt_transfer as t + inner join pools as p + on + ( + t."from" = p.contract_address + or t.to = p.contract_address + ) + and (token0 = t.contract_address or token1 = t.contract_address) +), + +-- rebuilds the reserves from the transfers +-- ETH transfers are not considered +reserves as ( + select + contract_address, + token0, + token1, + tx_hash, + block_time, + fee, + sum(transfer0) over (partition by contract_address order by block_time, evt_index) as reserve0, + sum(transfer1) over (partition by contract_address order by block_time, evt_index) as reserve1, + row_number() over (partition by tx_hash, contract_address order by evt_index desc) as latest_per_tx, + row_number() over (partition by contract_address order by block_time desc) as latest_per_pool + from transfers +), + +-- finds the TVL of the pools +recent_tvl as ( + select + r.contract_address, + token0, + token1, + block_time, + tx_hash, + reserve0, + reserve1, + fee, + latest_per_pool, + (reserve0 * p0.price / pow(10, p0.decimals)) + (reserve1 * p1.price / pow(10, p1.decimals)) as tvl + from reserves as r + inner join prices.usd as p0 + on + date_trunc('minute', block_time) = p0.minute + and token0 = p0.contract_address + inner join prices.usd as p1 + on + date_trunc('minute', block_time) = p1.minute + and token1 = p1.contract_address + where latest_per_tx = 1 +) + + +select * from recent_tvl +where contract_address in ( + select contract_address + from recent_tvl + where latest_per_pool = 1 + order by tvl desc + limit {{number_of_pools}} +) diff --git a/cowamm/kpi/competitors/uni_swap_style/largest_uni_style_kpis_4304295.sql b/cowamm/kpi/competitors/uni_swap_style/largest_uni_style_kpis_4304295.sql new file mode 100644 index 00000000..fbecafbd --- /dev/null +++ b/cowamm/kpi/competitors/uni_swap_style/largest_uni_style_kpis_4304295.sql @@ -0,0 +1,100 @@ +-- Computes volume, tvl and APR for Uni Swap style pools (Uni, Pancake, Sushi) +-- APR is measured as the fees earned per $ invested, over the last 24 hours, projected over 1 year +-- Parameters: +-- {{blockchain}}: The blockchain to query +-- {{number_of_pools}}: The number of largest pools to return +-- {{competitor_end_time}}: The end time of the time window (end_time - 1 day; end_time), defaults to now() + +-- select the pool with the largest latest k +with pool as ( + select + pool_address as contract_address, + project, + token0, + token1, + tvl + from "query_4303563(blockchain='{{blockchain}}', number_of_pools = '{{number_of_pools}}')" +), + +syncs as ( + select + pool.*, + tx_hash as evt_tx_hash, + index as evt_index, + block_time as evt_block_time, + block_number as evt_block_number, + varbinary_to_uint256(substr(data, 1, 32)) as reserve0, + varbinary_to_uint256(substr(data, 33, 32)) as reserve1, + rank() over (partition by (logs.contract_address) order by block_time desc) as latest + from {{blockchain}}.logs + inner join pool + on logs.contract_address = pool.contract_address + where + block_time >= date_add('day', -1, (case when '{{competitor_end_time}}' = '2100-01-01' then now() else timestamp '{{competitor_end_time}}' end)) + and topic0 = 0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1 -- Sync +), + +swaps as ( + select + tx_hash as evt_tx_hash, + index as evt_index, + block_time as evt_block_time, + block_number as evt_block_number, + contract_address, + varbinary_to_uint256(substr(data, 1, 32)) as amount0In, + varbinary_to_uint256(substr(data, 33, 32)) as amount1In, + varbinary_to_uint256(substr(data, 65, 32)) as amount0Out, + varbinary_to_uint256(substr(data, 97, 32)) as amount1Out + from {{blockchain}}.logs + where + block_time >= date(date_add('day', -1, now())) + and topic0 = 0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822 -- Swap + and contract_address in (select contract_address from pool) +), + +-- gets the swapped volume and tvl at the time of the swap for each swap +tvl_volume_per_swap as ( + select + syncs.contract_address, + syncs.evt_block_time, + syncs.evt_tx_hash, + (amount0In * p0.price / pow(10, p0.decimals)) + (amount1In * p1.price / pow(10, p1.decimals)) as volume_in, + (amount0Out * p0.price / pow(10, p0.decimals)) + (amount1Out * p1.price / pow(10, p1.decimals)) as volume_out, + (reserve0 * p0.price / pow(10, p0.decimals)) + (reserve1 * p1.price / pow(10, p1.decimals)) as tvl + from syncs + inner join swaps + on + syncs.evt_tx_hash = swaps.evt_tx_hash + and syncs.contract_address = swaps.contract_address + and syncs.evt_index + 1 = swaps.evt_index + inner join pool + on syncs.contract_address = pool.contract_address + inner join prices.usd as p0 + on + date_trunc('minute', syncs.evt_block_time) = p0.minute + and syncs.token0 = p0.contract_address + inner join prices.usd as p1 + on + date_trunc('minute', syncs.evt_block_time) = p1.minute + and syncs.token1 = p1.contract_address +) + +select + pool.contract_address, + project, + case + when project = 'pancakeswap' then 0.0025 + else .003 + end as fee, + coalesce(sum((volume_in + volume_out) / 2), 0) as volume, + -- the average pool is conceptually unnecessary because the table pool has only one tvl per pool + -- but it is necessary for the group by statement + avg(pool.tvl) as tvl, + case + when project = 'pancakeswap' then coalesce(365 * sum((volume_in + volume_out) / 2 / t.tvl) * 0.0025, 0) + else coalesce(365 * sum((volume_in + volume_out) / 2 / t.tvl) * 0.003, 0) + end as apr +from pool +left join tvl_volume_per_swap as t + on pool.contract_address = t.contract_address +group by pool.contract_address, project diff --git a/cowamm/kpi/competitors/uni_swap_style/largest_uni_style_pools_4303563.sql b/cowamm/kpi/competitors/uni_swap_style/largest_uni_style_pools_4303563.sql new file mode 100644 index 00000000..5eb350e4 --- /dev/null +++ b/cowamm/kpi/competitors/uni_swap_style/largest_uni_style_pools_4303563.sql @@ -0,0 +1,64 @@ +-- Finds the largest Uni Style pools (Pancake, Sushi, Uni) and their TVLs +-- Parameters: +-- {{blockchain}}: The blockchain to query +-- {{number_of_pools}}: The number of largest pools to return + +with pools as ( + select + substr(data, 13, 20) as contract_address, + substr(topic1, 13, 20) as token0, + substr(topic2, 13, 20) as token1, + case + when contract_address = 0x1097053Fd2ea711dad45caCcc45EfF7548fCB362 then 'pancakeswap' + when contract_address = 0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f then 'uniswap' + when contract_address = 0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac then 'sushiswap' + end as project + from {{blockchain}}.logs + where + topic0 = 0x0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9 + and contract_address in + ( + 0x1097053Fd2ea711dad45caCcc45EfF7548fCB362, + 0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f, + 0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac + ) +), + +syncs as ( + select + pools.*, + tx_hash as evt_tx_hash, + index as evt_index, + block_number as evt_block_number, + date_trunc('minute', block_time) as evt_block_time, + varbinary_to_uint256(substr(data, 1, 32)) as reserve0, + varbinary_to_uint256(substr(data, 33, 32)) as reserve1, + rank() over (partition by (logs.contract_address) order by block_time desc, index asc) as latest + from {{blockchain}}.logs + inner join pools + on logs.contract_address = pools.contract_address + where + topic0 = 0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1 -- Sync +) + +select distinct + s.contract_address as pool_address, + project, + token0, + token1, + reserve0, + reserve1, + evt_block_time, + reserve0 * p0.price * power(10, -p0.decimals) + reserve1 * p1.price * power(10, -p1.decimals) as tvl +from syncs as s +inner join prices.usd as p0 + on + token0 = p0.contract_address + and p0.minute = evt_block_time +inner join prices.usd as p1 + on + token1 = p1.contract_address + and p1.minute = evt_block_time +where latest = 1 +order by tvl desc +limit {{number_of_pools}}