Skip to content

Commit

Permalink
Create cow_amm_lp_and_tvl_4047078.sql (#17)
Browse files Browse the repository at this point in the history
* Create cow_amm_lp_and_tvl_4047078

The query find the relevant cow amm pool, get lp token balance based on the incoming and outgoing transfers. 

Then we use the exciting materialized table to calculate TVL for the same pool.

* add gitignore for .env to present for pushing secret

* Adding fixes to the CoW AMM query

* Adding .sql to the query name

* Addressing comments

* Addressing sqlfluff issues

* Addressing sqlfluff issues

* Addressing additional comments

* Alligning sqlfluff file with the uniswap pr

* Adding comments

* Calculation fix

* Only one pool per token pair

* Additional condition

* wip

* use tvl_by_tx subquery and other simplification/performance improvements

* improve lookback

---------

Co-authored-by: Felix Leupold <[email protected]>
  • Loading branch information
olgafetisova and fleupold authored Sep 12, 2024
1 parent 49eca5d commit 9e43d66
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
4 changes: 4 additions & 0 deletions cow_amm/.sqlfluff
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[sqlfluff:templater:jinja:context]
start='2024-08-08 00:00'
token_a='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
token_b='0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
134 changes: 134 additions & 0 deletions cowamm/profitability/10k_growth/cow_4047078.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
-- Computes the TVL, lp token total supply and lp token price of a CoW AMM 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

-- 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
),

-- Finds the CoW AMM pool address given tokens specified in query parameters (regardless of order)
cow_amm_pool as (
select
created_at,
address
from query_3959044
where ((token_1_address = {{token_a}} and token_2_address = {{token_b}}) or (token_2_address = {{token_a}} and token_1_address = {{token_b}}))
order by 1 desc
limit 1
),

-- per day lp token total supply changes of the CoW AMM pool by looking at burn/mint events
lp_balance_delta as (
select
date(evt_block_time) as "day",
sum(case when "from" = 0x0000000000000000000000000000000000000000 then value else -value end) as lp_supply
from erc20_ethereum.evt_transfer
where
contract_address in (select address from cow_amm_pool)
and ("from" = 0x0000000000000000000000000000000000000000 or "to" = 0x0000000000000000000000000000000000000000)
group by 1
),

lp_total_supply_incomplete as (
select
day,
lp_supply,
sum(lp_supply) over (order by day) as total_lp
from lp_balance_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
-- performance optimisation: this assumes one week prior to start there was at least one lp supply change event
and lp.day >= (select start from lp_total_supply_start)
)
where latest = 1
),

tvl_by_tx as (
select
*,
rank() over (partition by date(block_time) order by block_time desc) as latest
from "query_4059700(token_a='{{token_a}}', token_b='{{token_b}}')"
where pool = (select address from cow_amm_pool)
-- performance optimisation: this assumes one week prior to start there was at least one tvl change event
and block_time >= timestamp '{{start}}' - interval '7' day
),

tvl as (
select
day,
tvl
from (
-- join full date range with potentially incomplete data. This results in many rows per day (all total tvl on or before that day)
-- rank() is then used to order join candidates by recency (rank = 1 is the latest tvl)
select
date_range.day,
tvl,
rank() over (partition by (date_range.day) order by tvl.block_time desc) as latest
from date_range
inner join tvl_by_tx as tvl
on date_range.day >= date(tvl.block_time)
-- performance optimisation: only look at the last update of the day
and tvl.latest = 1
)
where latest = 1
),

-- With this we can plot the lp token price (tvl/lp total supply) over time
final as (
select
tvl.day,
tvl,
total_lp,
tvl / total_lp as lp_token_price
from tvl
inner join lp_total_supply as lp
on tvl.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 final
where day = timestamp '{{start}}'
) * lp_token_price as current_value_of_investment
from final
where day >= timestamp '{{start}}'
order by 1 desc

0 comments on commit 9e43d66

Please sign in to comment.