Introducing Apollo: analyzing the usage of ERC4626 across chains

Jonas Bostoen
Chainbound
Published in
9 min readJun 15, 2022

Chainbound is a research & development organization focused on public blockchains. This is the first in a series of articles which we believe will shape Chainbound’s mission in the years to come — feedbacks are more than appreciated :)

Introduction

For aiding our research efforts, Chainbound has been working on a tool to make EVM data extraction as easy as possible. We called it Apollo.

With Apollo you can query, filter, transform and save EVM chaindata via a custom schema.

We believe that Apollo is the best solution in the market to easily scrape obscure, cross-chain EVM data. Other tools are too limiting in what they can do; they either run only on a couple chains, or rely on indexing, which is a process that takes time and is not feasible for just any protocol. Apollo instead interacts directly with the standardized JSON RPC API that any EVM node implementation should expose. This means that as long as you have a JSON RPC API for your chain, Apollo will be able to run there. The only other thing you need is an ABI.

We chose to open-source Apollo. By doing so, we hope to ease the community efforts to produce data-driven research on EVM data that can’t be found anywhere else.

Inspired by this tweet, we also decided to directly use it to analyze the usage of the new ERC4626 Tokenized Vault Standard across multiple chains, thereby showcasing its applications and usage.

What is ERC4626?

One of the most powerful mechanisms in DeFi is composability, but composability relies on the successful standardization of the different components. For example, the crypto community agreed on the ERC20 token standard, which set the stage for DEXes like Uniswap to become popular trading venues. ERC721 is another famous standard that enabled the NFT revolution.

For more structured tokens like yield-bearing tokenized vaults, the community still does not have a set standard, which is a serious limitation to money-market composability and yields. ERC4626 aims to solve this, by proposing a new token standard for yield-bearing tokenized vaults.

Just to give you some background, you’ve probably already interacted with a yield bearing token. If you’ve ever staked Sushi in return for xSushi, or deposited ETH on Aave and received aETH, you’ve used these products. They represent shares of an underlying token that generate interest over time. The problem is that when building applications that can integrate with these tokens, you have to build an integration for each separate implementation. This is complex, error-prone, and resource intensive, resulting in less applications actually doing it. Bad for composability.

ERC4626 aims to set a standard for these products called the Tokenized Vault Standard. If an application works with ERC4626, it works with any yield-bearing token that implements the standard. This will drastically lower the integration effort and will enable a renaissance in DeFi yields. It will, for example, provide lending platforms the ability to easily accept any ERC4626 token as collateral, which would be one example of composable yield.

Let’s take a look at some of the events and methods of the interface (incomplete), because these will be useful later.

Analysis

Since we believe ERC4626 will be a very important building block in future for DeFi protocols, we will focus this analysis around the current state of ERC4626 standard. Partly because we live in a multi-chain world, and partly because we want to highlight a competitive feature that Apollo has, we will be looking at 4 chains: Ethereum, Polygon, Arbitrum and Optimism.

Apollo workflow

This is the game plan: we are going to collect every ERC4626 Deposit event (see above) across the chains, from February 1 until June 14. The problem is that the Deposit event signature is not unique to the ERC4626 event, because it is derived from the event name and its types. Under the hood, what we're actually filtering for is an event topic, which in this case will be

keccak256("Deposit(address,address,uint256,uint256)") = 0xdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7

There are other Deposit events that have the same signature, so we need to find a way to filter out the right ones. With Apollo, we can call methods at the time an event occurs, and the method will be called on the contract that emitted the event. So to filter out the ERC4626 events, we can call the asset method, which is part of the interface. If this call succeeds, we can be relatively sure the contract is an ERC4626 implementation. If this call reverts, however, which means that the contract does not adhere to the standard, Apollo will just move on and save nothing.

We will also be collecting some of the ERC20 metadata (which the ERC4626 interface should implement), namely symbol and decimals .

Schema

This is the schema we’re going to run:

We first have to define our time range, which we can do with start_time and end_time. format_date(fmt, date) can be used to convert a datetime to a UNIX timestamp, according to a format. The now variable is provided by the DSL.

Next up, we’ll define a loop block. For every item in items, Apollo will create a separate query, with the item as a variable. The name of the query (erc4626_deposits), will be the name of our output file / output table. We want to filter every Deposit event, which we can do by declaring an event block with the Deposit label. In the event block, we specify the ABI file (which can be found in the Apollo config directory, see setting up docs), and the outputs we want to save for further processing. These have to match the ABI exactly.

After this, we want to gather some extra information by calling some methods on the contract of interest. We do that with method blocks, which have the method name as a label. Just like in event, we define our outputs. There are 2 blocks that we don't need here, which are transform and filter, but you can read more on them in the schema docs. In the save block, we define the final format of our output columns. The save block has access to any previously defined output parameters, as well as other event context variables like blocknumber, timestamp, contract_address, tx_hash, and chain, which we all want to save. There are some helper functions available as well, and we'll use parse_decimals(raw, decimals) to format our output.

Running

Before running, make sure that every chain has a corresponding JSON-RPC API field in your config.yml. We suggest using either your own nodes, or providers like Alchemy or Chainstack, because the default public endpoints will not do. Even when using a specialized provider, you can get rate limited. This is why we've also provided an option to rate limit Apollo itself. For this research, we used Alchemy APIs with the default value of 100:

apollo --stdout --csv --log-level 0 --rate-limit 100

We managed to not exceed our CU capacity, and not get any time-outs. It took around 5 minutes to collect this data. If you have your own node, you can crank this number up. When running this with our own Erigon node and a value of 500, we managed to collect everything in around 30 seconds.

Internally, Apollo uses primitive caching, and methods like symbol and decimals are cached for every contract, drastically reducing the amount of calls made to the API. At the end of execution, you will see some stats printed for each chain:

Results

Get the results (8328 lines): erc4626_deposits.csv

Daily Deposit events per chain

Daily deposits per chain. The first deposit was on February 14 2022.

As we can see here, ERC4626 adoption on Polygon has been the most successful, perhaps surprisingly. Since its inception, Polygon has had 4046 ERC4626 Deposit events. Ethereum comes in second with 3287 events, Optimism third with 939 events, and finally Arbitrum, with only 55 events. Because of the lack of data on Arbitrum, our analysis only covers the other 3 chains. Ethereum was by far the first with any Deposit events at all, and we'll come back to that later.

Zooming in to where things become interesting, we can see that usage really started picking up on May 4th.

Daily deposits per chain, starting may 1 2022

This is when both Thorswap Staking V2 on Ethereum and Aavegotchi wapGHST Staking on Polygon went live, and they both implemented the ERC4626 standard.

Protocols

Ethereum

Let’s start with Ethereum, since it had the first deployments. Focusing in on the daily Deposit events on Ethereum, we get the following chart:

Daily ERC4626 deposits on Ethereum

Looking at those first deposits and their symbols, we can figure out which protocols spearheaded ERC4626 adoption:

From this table, we can see that Convex Finance were the earliest adopters of ERC4626. They use it in some of their staking pools, specifically for staking Curve LP tokens. There are other tokens, like (re)TOKE (part of TOKEMAK) which only have 1 deposit over the course of their lifetime, so we're not going to mention those. If you're looking for that secret single deposit alpha, download the dataset above! Convex has currently deployed the most ERC4626 vaults.

Next up, we start to see some implementations from the original authors of ERC4626: Fei Protocol. Tokens like tsTribe and tsBAL are part of the Tribe Turbo deployments. They don't seem to be active, though.

WOUSD is part of a protocol called Origin Dollar, a yield bearing stablecoin. Finally we have vTHOR, which is part of Thorswap. On Ethereum, this is by far the most popular ERC4626 vault by number of deposits.

If we sort by the most active ERC4626 vaults, we get the following table:

Aside from Thorswap and Convex, two other very popular ERC4626 deployments are xMPL from Maple Finance and uCVX, a partnership between Pirex and Llama Airforce which allows you to deposit pxCVX, a vault for CVX. Composability in action!

Filtering out the vaults with less than 10 deposits we get the following pie chart, highlighting the dominance of vTHOR and xMPL:

Number of deposits by symbol on Ethereum

vTHOR currently manages about $12,7M USD of THOR deposits, and xMPL around $45M of MPL. So even though vTHOR has more deposits, xMPL manages a lot more assets.

Polygon

Polygon usage really only started after the deployment of wapGHST staking on May 4th. On May 26th, mStable upgraded their Save Contracts to implement ERC4626, and deposits stayed consistently high.

Daily ERC4626 deposits on Polygon

Zooming in on the most active vaults, mStable’s imUSD is at the top, followed by wapGHST:

imUSD currently manages around $6,5M mUSD, and wapGHST manages $1,7M worth of aPolGHST, which is the Aave token for Aavegotchi GHST.

We could not find any info on LOL, which is a vault for Aave Polygon USDC. eVault was interesting. Most of the Deposit events where from 0x2C882729f2710D0b8d23d98199ba9FdA1aF05109, which turned out to be a mocking contract with LINK as its underlying token. The real implementation was at 0xff07A39665740eB95E57ccDC3963B026741cC88E, which is a QiDAO vault for Quickswap WMATIC-QI LP tokens. The contract was only deployed 5 days ago at the time of writing (June 14, 2022).

Taking a look at the pie chart, it’s clear that imUSD and wapGHST are the only game in town so far.

Number of deposits by symbol on Polygon

Optimism

Daily ERC4626 deposits on Optimism

Optimism had 0 ERC4626 activity until May 24th, when Rubicon Finance upgraded their tokens to implement the standard. Aside from Rubicon (the bath tokens), there doesn't seem to be a lot of ERC4626 activity:

Rubicon Finance is clearly leading the way with ERC4626 adoption on Optimism:

Number of deposits per symbol

Conclusion

ERC4626 is definitely picking up some steam, but there aren’t many big protocols like Aave or Compound that upgraded their contracts yet, even though the whole DeFi ecosystem would clearly benefit from it. Kudos to all the protocols that did implement it!

If you want to analyze the data yourself, you can download it here: erc4626_deposits.csv. You can also try out Apollo at github.com/chainbound/apollo, make sure to read the documentation!

Caution

Apollo is still alpha software, and there will be bugs. If you find any, please open an issue on Github.

--

--