ADD: RUNEPool

Context

TVL is monetised by TC in the way of swaps. The more TVL, the more it can monetise. Thus liquidity-provision should be nailed.

But Dual-LP UX is poor. The addressable market of those understanding the risks, tolerating the exposure to RUNE and willing to participant is extremely small compared to the size of the market of liquid crypto assets. Other protocols are being launched which have much more palatable LP assets (USDC base pair on Chainflip etc) that have a bigger market. TC should not be dethroned on TVL, it should work every day to command more crypto assets than any other protocol or platform (eg, coinbase with 1m+ BTC).

Savers (deposit L1, earn L1) have unveiled a blissful UX. No Saver on TC has a bad experience. Savers are the key to driving up liquidity. BUT, somebody needs to underwrite Savers. Today this is provided by Dual-LP and PoL. An upcoming change will make PoL match 1:1 to Savers, which will see PoL deploy faster. Another change in late 2023 makes PoL stay in for much longer; this should start making PoL profitable, since Yield is accumulative, Impermanent Loss (IL) is not. Thus on a long enough time frame, a PoL will always beat IL.

Additionally, since RUNEPool is working all pools simultaneously, the IL and Yield is much easier to reason about - simply track RUNE vs THE WORLD in a single pool, where aggregate IL will ALWAYS be less than Isolated IL; and the long-term yield is just the Liquidity APY. This means RUNE is less volatile and "pain" from RUNE volatility (IL) is socialised across all participants - there is no longer the small few experiencing peak pain and becoming the noisey minority.

However, PoL is finite, and the protocol holds risk in underwriting Savers. Thus all RUNE holders are actually underwriting Savers. An effort should be made to share risk with a specific cohort of people chasing extra yield.

Hence RUNEPool.

Desired

Allow RUNE holders to "pool" in RUNEPool. They earn RUNE on RUNE yield, which is the performance of PoL in all pools. They don't choose a pool, they all share in all.

RESERVE-owned PoL RUNE fluidly exits when a Pooler enters and vice-versa. Thus RUNEPool members take priority over RESERVE. PoL just ensures the liquidity required to match Savers is met. RUNEPool Units RPU track ownership.

When a Pooler leaves (redeems their units), total PoL size (in RUNE) is assessed and the holder's share is given to them. It may be more or less than what they contributed.

Characteristics

RUNEPool fulfils the following:

  1. RUNE holders have an option to "pool RUNE" (note, principle is not protected, so it shouldn't be referred to as pure staking, since capital loss can occur).
  2. In a high-yield market, RUNEPool should perform really well (in a bear market, losses may occur, but since IL doesn't accumulate, Poolers should just stay in for a longer time).
  3. Protocol offloads risk to Poolers, de-risking the system
  4. Cognitive Burden is shed; liquidity is provided as single asset, with yield claimed as a single asset.
  5. Derisked, index-based product: Poolers don't select a single asset-pool, they co-invest in ALL pools together - they are pursuing the performance of the protocol itself (and playing the incentive pendulum).
  6. Demand Centre for RUNE - people will buy RUNE and pool in a high-performing market.

Implementation

Genesis and Refund RESERVE

Internally, PoL is the main dual-LP of a pool, but its RUNEPool ownership is tracked. There are two things to track

  1. RUNEPool Units - tracking the ownership of PoL, which is either RESERVE or Pooler
  2. RUNEPool Balance - how much RUNE is participating (both static-pending and dynamic-deployed)
  3. RUNEPool Balance Static - how much specifically is static (not yet deployed)
  4. PoL - this is the RUNE value of deployed RUNE, which is dynamic

Assessing PoL value (this is dynamic)

pol_value_in_rune = sum_of_all_pools(pol_liquidity_share * rune_depth) * 2 //sum across each pool
runepool_balance_static //all the RUNE pending to be deployed, should start 0
runepool_balance_total = pol_value_in_rune + runepool_balance_static //total Balance static+dynamic

Issue RPU at Genesis

rpu_reserve = runepool_balance_total //Issue RESERVE all the units, 1:1
rpu_pooler = 0 //none, no RPU yet issued to a pooler
rpu_total = rpu_reserve + rpu_pooler //genesis amount

As Poolers enter, issue them units, and track total Balance

new_rune_deposited_by_pooler // new RUNE deposited

runepool_balance_static += new_rune_deposited_by_pooler

rpu_pooler += ( new_rune_deposited_by_pooler / (runepool_balance_total + rune_deposited_by_holder) ) * rpu_total

Now decrement RPU for RESERVE and refund RESERVE:

rpu_reserve -= ( new_rune_deposited_by_pooler / (runepool_balance_total) ) * rpu_total
runepool_balance_static -= new_rune_deposited_by_pooler
reserve += new_rune_deposited_by_holder // Refund Protocol

At some point, the RESERVE will be fully ejected, but PoL balance has not changed:

rpu_reserve = 0 //All decremented
rpu_pooler = lots //rpu_pooler has it all
rpu_total = rpu_reserve + rpu_pooler //sum of both

Redeeming

A pooler wishes to leave. Firstly measure RUNEPool balance, and assess pooler's RPU against that:

rpu_pooler_remove //how much they are withdrawing, (eg all of it)
pol_value_in_rune_refreshed //re-assess PoL value
runepool_balance_total = pol_value_in_rune_refreshed + runepool_balance_static //total Balance static+dynamic

payout_pooler = (rpu_pooler_remove / rpu_total) * runepool_balance_total //How much to owe them

rpu_total -= rpu_pooler_remove
rpu_pooler -= rpu_pooler_remove


if(payout_pooler > runepool_balance_static){
 //Not enough static RUNE, backload the missing from RESERVE and issue units
 missing_rune = payout_pooler - runepool_balance_static
 reserve -= missing_rune
 runepool_balance_static += missing_rune
 rpu_reserve_new += ( missing_rune / (runepool_balance_total + missing_rune) ) * rpu_total
 rpu_reserve += rpu_reserve_new
 rpu_total += rpu_reserve_new
}
runepool_balance_static -= payout_pooler
balance_pooler += payout_pooler

And that's it. Ownership of PoL is fluidly swapped between RESERVE and Pooler without adding/removing liquidity.

Other consids

  • Dual-LP functions are maintained to allow the creator of a pool to start a pool, as well as for PoL to enter/exit. However it should not be presented by interfaces as a recommended way to provide liquidity. Instead users should be directed to deposit L1 in Savers or deposit RUNE in RUNEVault.

  • Once a Pool is created, Savers can enter, matched with PoL. This will scale a pool's liquidity from any size, since price of the pool does not change with depositing Savers.

  • Only long-term RUNEVault holders should be attracted, setting a min "holding" period of 90 days, perhaps even 12 months. This is because short-term positions may experience IL, instead of having enough time for yield.

Sunsetting

RUNEPool is the second part of TC's attempt at solving the UX of providing liquidity:

  1. L1 Savers: 1 click deposit for L1, easy to understand, principle-protected, yield lower than other options
  2. RUNEPool: 1 click deposit for RUNE, aggregated IL < isolated IL, yield chases Liquidity APY, higher yield from Synth utilisation

The UX of providing either side of the pool (L1 or RUNE) is now solely contained to that asset, and only 1 option is presented to the user.

But it may not work, so this plan discusses how it could be sunset if the TC community wishes to return to solely Dual-LP:

  1. Put Savers in Withdraw-only mode
  2. As Savers leave, PoL is ejected from dynamic to static balance (sits in the module)
  3. RUNEPoolers can claim back their RUNE.
  4. Everyone can re-enter back as DLP.

done

Edited Apr 26, 2024 by THORChain
Assignee Loading
Time tracking Loading