class: center, middle, inverse, title-slide # yearn.finance Analysis
### Omni Analytics Group --- ## Yearn Finance Yearn Finance is a suite of products in Decentralized Finance (DeFi) that provides lending aggregation, yield generation, and insurance on the Ethereum blockchain. The protocol is maintained by various independent developers and is governed by YFI holders. Their core products are **Vaults** and **Earn**. #### Vaults Capital pools that automatically generate yield based on opportunities present in the market. Vaults benefit users by socializing gas costs, automating the yield generation and rebalancing process, and automatically shifting capital as opportunities arise. End users also do not need to have a proficient knowledge of the underlying protocols involved or DeFi, thus the Vaults represent a passive-investing strategy. #### Earn The first Yearn product was a lending aggregator. Funds are shifted between dYdX, AAVE, and Compound automatically as interest rates change between these protocols. Users can deposit to these lending aggregator smart contracts via the Earn page. This product completely optimizes the interest accrual process for end-users to ensure they are obtaining the highest interest rates at all times among the platforms specified above. A useful fiat-world comparison to Yearn would be an investment manager like BlackRock -- except Yearn employs < 100 people, the investment management is entirely automated, and they earn you better yields! You can check out the project at https://yearn.finance/ --- ## Getting Started We will be using the following libraries: ```r library(data.table) library(ggplot2) library(lubridate) ``` The `data.table` library is a wrangling library like `tidyverse`, but focuses more on concise syntax patterns and *blazing fast speed*. It build on top of base data.frame operations. Check it out here: https://cran.r-project.org/web/packages/data.table/vignettes/datatable-intro.html <p align="center"> <img src="Cut_outs/Cut_out_17.png" width="200px" height="150px"> </p> --- ## The Data We will be using a data set obtained from Yearn themselves! Each row represents a transaction that interacted with the Yearn protocol. We have a number of different features containing metadata around the transaction. Let's read in the data. ```r yearn <- fread("08-fees-combined.csv") str(yearn) ``` ``` ## Classes 'data.table' and 'data.frame': 23508 obs. of 14 variables: ## $ timestamp : chr "8/15/2020 12:22" "8/15/2020 12:23" "8/15/2020 12:58" "8/15/2020 12:58" ... ## $ block_number : int 10664621 10664627 10664770 10664775 10664849 10664905 10664960 10665138 10665138 10665142 ... ## $ transaction_hash: chr "0x09e941c8112501e0aa09558d93a211e711312b5e6a9ab057a9869cf4d46ca7d2" "0x849b603609726e415c3e8d70eac33ad93137d10d8617eda417844ae9211e50e2" "0x939660735a1dcdd032e5ceda63ce5335d9982b7813046bcce5c32e5acb6d0d3b" "0x3698945a8a8d306056db7374679863fdff46a909456a6540708328b1831d2ded" ... ## $ vault : chr "0xACd43E627e64355f1861cEC6d3a6688B31a6F952" "0x5dbcF33D8c2E976c6b560249878e6F1491Bca25c" "0x2f08119C6f07c006695E079AAFc638b8789FAf18" "0x5dbcF33D8c2E976c6b560249878e6F1491Bca25c" ... ## $ token : chr "0x6B175474E89094C44Da98b954EedeAC495271d0F" "0xdF5e0e81Dff6FAF3A7e52BA697820c5e32D806A8" "0xdAC17F958D2ee523a2206206994597C13D831ec7" "0xdF5e0e81Dff6FAF3A7e52BA697820c5e32D806A8" ... ## $ strategy : chr "0xd643cf07344428770b84973e049A1c18B5d47edE" "0xa069E33994DcC24928D99f4BBEDa83AAeF00B5f3" "0x787C771035bDE631391ced5C083db424A4A64bD8" "0xa069E33994DcC24928D99f4BBEDa83AAeF00B5f3" ... ## $ recipient : chr "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52" "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52" "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52" "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52" ... ## $ fee_type : chr "harvest" "withdrawal" "harvest" "harvest" ... ## $ fee_dest : chr "rewards" "rewards" "rewards" "rewards" ... ## $ func : chr "harvest()" "withdraw(uint256)" "harvest()" "harvest()" ... ## $ token_price : num 1 1.05 1 1.05 1 ... ## $ amount_native : num 1.681 52.996 0.103 528.595 38.169 ... ## $ amount_usd : num 1.681 55.611 0.103 554.684 38.169 ... ## $ protocol : chr "v1" "v1" "v1" "v1" ... ## - attr(*, ".internal.selfref")=<externalptr> ``` --- ## Protocol Performance Analysis At Yearn, they've released 2 versions of their protocol: `v1` and `v2`. The protocol makes money by collecting management fees, so we're interested in seeing the amount of fees collected over time and comparing the two protocol versions. In order to do that, we need to create an intermediate data representation. We have each transaction, but we need to aggrergate the fees over time. Let's do the following: - create a new table called `fees` and subset `yearn` to only the columns we need - compute a new column that represents cumulative fees up to that point in time ```r fees <- yearn[,.(timestamp, amount_usd, protocol)][order(-timestamp)] fees$timestamp <- mdy_hm(fees$timestamp) fees[,date:=date(timestamp)] fees[, amount_day := sum(amount_usd), by=.(protocol, date)] daily_fees <- unique(fees[,.(date, amount_day, protocol)]) daily_fees <- daily_fees[order(date)] daily_fees[,cum_amount:=cumsum(amount_day), by=protocol] daily_fees <- daily_fees[order(-date)] ``` --- ## Plot the fees ```r ggplot(daily_fees, aes(date, cum_amount, colour=protocol)) + geom_line() + ggtitle("Protocol Fees") ``` <img src="yearn_files/figure-html/unnamed-chunk-4-1.png" style="display: block; margin: auto;" /> --- ## `fee_dest` Analysis We want to visualize the `rewards` vs `strategist` fee destinations over time. Yearn is decentralized and community-run. This means anyone can develop a strategy and deploy it on the Yearn protocol for anyone to use. If the strategy is successful, more people will want to participate in it. The yield earned from the strategy gets split between the strategist (person/group who created the investment strategy) and the participants, which gets distributed proportional to their share of the pool from the rewards allocation. So that's what we're interested in seeing -- how much money goes to the strategists versus gets paid out to the participants in rewards. First we need to create a data.table that tells us how much of the daily fees go to the rewards and strategist. ```r fee_dest <- yearn[,.(timestamp, amount_usd, fee_dest)][order(-timestamp)] fee_dest$timestamp <- mdy_hm(fee_dest$timestamp) fee_dest[,date:=date(timestamp)] fee_dest[, amount_day := sum(amount_usd), by=.(fee_dest, date)] daily_fee_dest <- unique(fee_dest[,.(date, amount_day, fee_dest)]) daily_fee_dest <- daily_fee_dest[order(date)] daily_fee_dest[,cum_amount:=cumsum(amount_day), by=fee_dest] daily_fee_dest <- daily_fee_dest[order(-date)] ``` --- ## Plot the fee destinations ```r ggplot(daily_fee_dest, aes(date, cum_amount, colour=fee_dest)) + geom_line() + ggtitle("Protocol Fee Destinations") ``` <img src="yearn_files/figure-html/unnamed-chunk-6-1.png" style="display: block; margin: auto;" /> --- ## `fee_type` Analysis We want to visualize the fee types over time. Once you deposit money into one of the Yearn products, you will begin earning yield. After some time, that yield will accumulate and you can do 2 things with it -- reinvest it, or withdraw it. Either way, money moves from the protocol so Yearn will collect fees once action is taken upon the yield. We just want to see where most of the fees come from. ```r fee_type <- yearn[,.(timestamp, amount_usd, fee_type)][order(-timestamp)] fee_type$timestamp <- mdy_hm(fee_type$timestamp) fee_type[,date:=date(timestamp)] fee_type[, amount_day := sum(amount_usd), by=.(fee_type, date)] daily_fee_type <- unique(fee_type[,.(date, amount_day, fee_type)]) daily_fee_type <- daily_fee_type[order(date)] daily_fee_type[,cum_amount:=cumsum(amount_day), by=fee_type] daily_fee_type <- daily_fee_type[order(-date)] ``` --- ## Plot `fee_type` Analysis Most of their fees come from the "harvest" fee type. This means people are re-investing their yield back into the platform to increase their yield even more, reinforcing the trust and satisfaction people have in the platform. ```r ggplot(daily_fee_type, aes(date, cum_amount, colour=fee_type)) + geom_line() + ggtitle("Protocol Fee Types") ``` <img src="yearn_files/figure-html/unnamed-chunk-8-1.png" style="display: block; margin: auto;" /> --- ## Daily Protocol Fees How much does the protocol make on a daily basis? ```r ggplot(daily_fees, aes(x=date, y=amount_day, color=protocol)) + geom_line() ``` <img src="yearn_files/figure-html/unnamed-chunk-9-1.png" style="display: block; margin: auto;" /> This is choppy. Let's smooth it out a bit by using a rolling average. --- Compute a rolling average. ```r daily_fees <- daily_fees[order(date)] daily_fees[, amount_rolling_avg:=Reduce(`+`, shift(amount_day + 0, 0:6, type='lag')), by=.(protocol)] daily_fees$amount_rolling_avg <- daily_fees$amount_rolling_avg/7 daily_fees[is.na(amount_rolling_avg), amount_rolling_avg:=0] ``` --- ## Plot weekly rolling average across protocols ```r ggplot(daily_fees, aes(x=date, y=amount_rolling_avg, color=protocol)) + geom_line() ``` <img src="yearn_files/figure-html/unnamed-chunk-11-1.png" style="display: block; margin: auto;" /> --- ## Plot by Protocol, Fee Destination If we want to break things out even further, we can combine the grouping to include both the protocol version and the fee destination. ```r fee_dest_pro <- yearn[,.(timestamp, amount_usd, protocol, fee_dest)][order(-timestamp)] fee_dest_pro$timestamp <- mdy_hm(fee_dest_pro$timestamp) fee_dest_pro[,date:=date(timestamp)] fee_dest_pro[, amount_day := sum(amount_usd), by=.(protocol, fee_dest, date)] daily_fee_dest_pro <- unique(fee_dest_pro[,.(date, amount_day, protocol, fee_dest)]) daily_fee_dest_pro <- daily_fee_dest_pro[order(date)] daily_fee_dest_pro[,cum_amount:=cumsum(amount_day), by=.(protocol, fee_dest)] daily_fee_dest_pro <- daily_fee_dest_pro[order(-date)] daily_fee_dest_pro$grp <- paste(daily_fee_dest_pro$protocol, daily_fee_dest_pro$fee_dest) ``` --- ## Plot by Protocol, Fee Destination ```r ggplot(daily_fee_dest_pro, aes(x=date, y=cum_amount, color=grp)) + geom_line() ``` <img src="yearn_files/figure-html/unnamed-chunk-13-1.png" style="display: block; margin: auto;" /> --- # Cont. ```r ggplot(daily_fee_dest_pro, aes(x=date, y=amount_day, color=grp)) + geom_line() ``` <img src="yearn_files/figure-html/unnamed-chunk-14-1.png" style="display: block; margin: auto;" /> --- ## Fee Table per Month, Year ```r fees[,month:=month(timestamp)] fees[,year:=year(timestamp)] fees[, amount_month := sum(amount_usd), by=.(year,month)] fees$my <- paste(fees$month, fees$year, sep="-") monthly_fees <- unique(fees[,.(amount_month, my)]) monthly_fees[order(my)] ``` ``` ## amount_month my ## 1: 812805.6 1-2021 ## 2: 1095888.2 10-2020 ## 3: 290858.3 11-2020 ## 4: 340549.6 12-2020 ## 5: 1460617.4 2-2021 ## 6: 4672856.0 3-2021 ## 7: 7584701.2 4-2021 ## 8: 10164772.2 5-2021 ## 9: 2485961.5 6-2021 ## 10: 843832.1 8-2020 ## 11: 2072363.3 9-2020 ``` ---