How to create an easily rebalanced index without impermanent loss while generating yield from the composite pool token.
The PowerPool team has been building indices on top of Balancer since October 2020. To date, we released five mainnet products, including AMM-based indices and a stable-yield structured investment product (Yearn Lazy Ape). All these products were launched on top of a Balancer V1 fork with innovative modifications from our side. These include the ability to use the pool’s liquidity for staking and meta-governance, a dynamic weights model, and rebind strategies.
The introduction of Balancer V2 changes the landscape and allows building more complex and efficient solutions thanks to custom AMM pools, asset managers, and gas optimizations.
However, Impermanent Loss (IL) is still a major problem for building indices (actively tradable basket of tokens) on top of Balancer.
Market volatility is good for traders and arbitrageurs but it is very unlikely to be profitable for LPs. The composition of the pool constantly changes through swaps, balancing the pool’s prices with the wider market price. Arbitrageurs extract some value from the pool while changing its composition. The more tokens there are in the pool, the bigger is the set of potential arbitrage opportunities.
Just imagine: a basket with 4 tokens has N(N-1) or 4*3 available trading pairs while a basket with 11 tokens has 11*10 = 110 trading pairs.
Changing pool composition through rebalancing leads to impermanent loss. IL is often called “selling winners buying losers” in our community, which is not surprising given what actually happens: arbitrageurs rebalancing the pools try to find the biggest arbitrage gap and maximize their profits. For this purpose, the “cheapest” token is swapped for the most “expensive” one (defined in terms of the difference in prices on the external market and inside this AMM pool).
A visualisation of impermanent loss
Let’s consider a hypothetical constant product ASSY pool (AAVE 30%; SNX 25%; SUSHI 15%; YFI 30%). We created a simple arbitrage agent on top of the Balancer V1 cadCAD model which uses external market prices for simulating pool behavior during the observation period 22 JAN — 8 FEB 2021, with 5 minute granularity of the external market price data. The arbitrage agent used external and internal market prices for calculating arbitrage gaps on 12 trading pairs, optimizing trade size for the most profitable opportunity, and finally making a trade that updated pool balances.
Market prices for ASSY underlying tokens are presented below:
For demonstration purposes, we added the AAVE/YFI price based on swap_exact_amount_in Balancer function in Fig. 1. AAVE significantly grew during the observation period (from $200 to $500) while YFI stayed relatively flat between $28k and $32k. This led to a significant drop of YFI price in terms of AAVE (The amount of AAVE one could buy with 1 YFI dropped from >150 to ~75).
The balances of AAVE and YFI in the pool during the observation period are presented below:
We can see that AAVE was constantly bought (removed) from the pool while YFI was sold (added) to the pool. Here is the behavior of each token balance and the final difference between the composition of the initial pool:
YFI balance increased the most while the AAVE balance decreased significantly. SUSHI, whose value also increased during the observation period, was partially removed from the pool while SNX was added. This experiment is a simple demonstration of the “selling winners buying losers problem”, and corresponds to the on-chain data in a real pool.
Due to impermanent loss, liquidity providers will receive less value when they exit the pool compared to an equivalent passive portfolio. It’s a general problem of AMMs that researchers and developers try to solve, or at least minimize, using different dynamic approaches (weights, fees, virtual balances, etc). However, reducing IL is not an easy task, especially when it comes down to multi-token pools. In recent months we actively researched different opportunities for building indices on top of Balancer and found a new approach. Our solution makes “index” baskets of tokens largely immune to IL with a simple rebalancing mechanism acting through swaps.
PowerPool’s “rebalancing window” approach
Due to problem of IL and the fact that fees and possible yield from the underlying tokens almost never offset IL given the average historical volatility, we came to the following conclusion:
A static basket of tokens (without swaps) will be generally more profitable for LPs than a tradable pool.
If the basket is static, any major growth in some token will be fully captured by the index price.
We started R&D devoted to a simple question — how can we launch a static basket of tokens on top of Balancer and at the same time ensure easy on-demand rebalancing. Easy rebalancing through swaps is one Balancer’s best features given PowerPool’s vision of offering actively managed index funds based on fundamental metrics of protocols.
The idea is simple:
Swaps are disabled in the pool most of the time, except for short periods of rebalancing in so-called “rebalancing windows.”
Thus, LPs don’t suffer any IL and receive all possible capital gains from the growth of the assets and their staking rewards (since PowerPool indices use underlying tokens for yield generation).
How does it work?
The pool operates on top of Balancer with disabled swaps and single-sided liquidity joins/exits. Users can add/remove liquidity via multi-asset deposit/withdrawal or the ZAP* option offered by PowerPool.
We have considerable experience in building ZAPs, delivering one of the most complex multi-layer ZAPs solutions for Yearn Lazy Ape.
The most interesting part of the idea is the mechanism of the “rebalancing window” operation. It utilizes our Power Agent system (a system that can automatically call contracts when some condition is met), and previously-developed weights changing mechanism. The rebalancing algorithm for such a pool is the following:
Pool evolution map
T0 -> T1 -> T2 -> T3(new T0) -> T4 (new T1) -> T5 (new T2)
T0 — pool creation. Initial pool composition is established, swaps are disabled. Weights determine the balance ratio for joins and exits (all joins and exits are multi-asset).
T1 — The new pool structure is set (% of capital allocation into each token). It can be set manually (using text DAO proposal) or algorithmically (using fundamental metrics of the protocols, collected on-chain)
- Before swaps are enabled, the pool’s controller contract receives information about the external prices of assets (from the price oracle), and uses that information to calculate a new set of weights to reflect the current composition of the pool.
- At the same time, target weights corresponding to the new pool structure are set up.
- Swaps are enabled, and pool weights gradually begin shifting towards the new target.
T1-T2 — Weights start shifting from their initial values to the new target. An arbitrage gap appears, and arbitrageurs start making trades to increase and decrease the balances of the various tokens according to their new weights.*
T2 — Weights reach the target.
T3 — Start of a new rebalancing window as the procedure repeats when necessary (T3 is “new” T1)
*A gradual weight shift ensures that the maximum possible value stays in the pool (as in the presence of competition, arbitrageurs must pay the entry/exit (swap) fee multiple times).
Such pools featuring the “rebalancing window” and using V2 asset managers have the following advantages:
- Users can allocate their capital to an index without risks of IL, capturing all price action of the underlying tokens.
- Additionally, LPs receive rewards generated by staking the composite tokens.
- The basket can be easily rebalanced on-demand by arbitrageurs. There remains a cost of rebalancing, but it is much smaller than in the naive approach.
- Such an approach allows building algorithmically updated pools (e.g. updating every N days based on a set of on-chain metrics).
We plan to first apply this approach to our brand new product, BSCDEFI, an index built on top of our Balancer V1 BSC fork. BSCDEFI It is already live with more than $2m TVL and disabled swaps. We expect to enable the “rebalancing window” functionality by the end of the month.
Recently we created a Python model that allows simulating the “rebalancing window” mechanism applied to any basket of tokens launched on top of Balancer. The scope of the research includes determining the optimal time for rebalancing, weights shifting rate, the impact of market volatility, cost of rebalancing, IL, and stress-tests for the mechanism in case of extreme volatility. The results with the technical specification will be published in the next article.