Bitcoin Reserve Pool
Executive Summary
Community proposal regarding how LFG may deploy its Bitcoin reserve to defend the UST peg
- Proposing a pool that facilitates rapid BTC liquidity to support UST during downwards peg deviations, and relies on traders to replenish the reserves outside of crises.
- The pool’s mechanics resembles the LUNA <> UST on-chain mechanism, but with two key differences:
- First, the pool holds a different asset (wrapped BTC), and so likely needs to use a distinct architecture (e.g. a smart contract capable of interfacing with CW20 wrapped assets).
- Second, the pool should use different parameters for exit and entry liquidity, rather than netting flows.
- We propose several sets of parameters to facilitate liquidity and defend against oracle attacks.
Reserve Model
The illustration below describes the minimum viable product for the BTC reserve pool. The reserve’s primary goal is to deploy liquidity during a crisis. The reserve’s secondary goals are to remain simple, such that it can be operationalized quickly and that additional features can be added in the future.
- LFG places its BTC in a reserve pool that retail traders can access at some discount, e.g. retail participants provide 1 UST in exchange for $0.98 in BTC initially.
- This mechanism provides a strong backstop for UST during a crisis.
- While tiered across multiple levels, the exit liquidity should be stiff at the initial discount, to facilitate robust outflows of BTC during a crisis.
- Once the crisis passes, external traders can purchase UST with BTC, e.g. deposit ~$1.00 in BTC in exchange for 1 UST.
- This drains the pool of accumulated UST after a crisis passes.
- This trade should be lucrative when UST faces upwards pressure or trades at a premium in a post-crisis state.
- As context, the size of the reserve pool will be around $2.5 billion in BTC at launch.
- Critically, this model assumes robust private markets for UST. It assumes the liquidity provided by the BTC reserve will be expressed onto the decentralized and centralized exchanges, like Astroport and Binance respectively, where most of UST’s trading volume occurs.
Reserve Mechanics
The virtual AMM for the LUNA <> UST on-chain swap mechanism would effectively be forked and utilized for the BTC reserve with three critical differences. (Note that the AMM is virtual because liquidity is centered around an oracle price, rather than the amounts of BTC and UST in the reserve.)
-
First, this mechanism design results in the delivery/holding of a pre-existing asset (wrapped BTC), whereas the LUNA <> UST one mints and burns new assets into and out of existence. This proposal assumes BTC is ported to the Terra ecosystem via a protocol such as Wormhole.
-
Second, this mechanism should set parameters that reflect its purpose — to distribute liquidity in an emergency — better.
-
Third, this mechanism should offer different parameterizations depending on whether traders are extracting BTC or UST from the reserve, i.e. asymmetry in the parameterization.
Reserve Parameters: Background
We discuss the reserve parameters for the virtual AMM at a high level. There are three key parameters:
-
BasePool
determines the size of the ‘virtual’ constant product pool and thus parameterizes the slippage that a given trade might incur, where slippage is approximately the trade’s size divided by theBasePool
parameter.- For instance, if we set
BasePool
to be $100MM, a $1M UST redemption would suffer an extra 100bps slippage (subject to theMinSpread
parameter). - A larger
BasePool
allows greater liquidity facilitation, but also risks allowing an attacker behind a stale or manipulated oracle to withdraw more funds at once.
- For instance, if we set
-
PoolRecoveryPeriod
determines the pace at which theBasePool
is replenished toward the initial value. A shorter recovery period thus facilitates better liquidity.- The same tradeoff emerges: shorter recoveries allow greater liquidity facilitation but face elevated risk of attacks.
-
MinSpread
is the smallest slippage that a swap will incur, which is needed to defend against stale oracles. Trades will be done at the greater of the estimated slippage and theMinSpread
parameter.- Again, the same tradeoff emerges: a lower spread allows liquidity to flow more easily, but also faces elevated attack risk.
Observations from the LUNA <> UST on-chain swap setting suggest a relatively smaller BasePool
and shorter PoolRecoveryPeriod
has been found to be the optimal mix. Empirically, this provides liquidity in small and continued bursts, while reducing the risks around an oracle attack.
For reference, the parameter structure looks like the following. For the on-chain UST <> LUNA mechanism, it is denominated in microSDR; but it should be denominated in UST for this mechanism.
type Params struct {
PoolRecoveryPeriod int64 `json:"pool_recovery_period" yaml:"pool_recovery_period"`
BasePool sdk.Dec `json:"base_pool" yaml:"base_pool"`
MinSpread sdk.Dec `json:"min_spread" yaml:"min_spread"`
}
PoolTerra=BasePool+TerraDelta
PoolLuna=(BasePool)**2/PoolTerra
Reserve Parameters: Asymmetry
The reserve fund is designed to provide deep liquidity at a discount when the UST peg is under pressure, and not to provide liquidity for the ordinary expansion and contraction of UST as the LUNA <> UST on-chain mechanism does. The reserve fund should also replenish itself with BTC after a crisis, but it does not need to do so with the same urgency.
As such, we recommend asymmetric parameters for the virtual AMM, which effectively splits the two sides of the pool (UST → BTC and BTC → UST) into independent pricing functions.
- This means that the internal state variable “TerraDelta” gets split into TerraDelta_EntryFlow and TerraDelta_ExitFlow, and are tracked and decayed separately.
- This splitting offers a further defense against oracle attacks. In the status quo, a single “TerraDelta” nets inflows and outflows, and an attacker can buy and sell to keep spreads narrow. By not offsetting inflows and outflows, the reserve prevents an attack from buying and selling without facing wide spreads.
See the illustration below as an example of potential parameters.
type Params struct {
PoolRecoveryPeriod_EntryFlow int64 `json:"pool_recovery_period_entryflow" yaml:"pool_recovery_period_entryflow"`
PoolRecoveryPeriod_ExitFlow int64 `json:"pool_recovery_period_exitflow" yaml:"pool_recovery_period_exitflow"`
BasePool_EntryFlow ust.Dec `json:"base_pool_entryflow" yaml:"base_pool_entryflow"`
BasePool_ExitFlow ust.Dec `json:"base_pool_exitflow" yaml:"base_pool_exitflow"`
MinSpread_EntryFlow ust.Dec `json:"min_spread_entryflow" yaml:"min_spread_entryflow"`
MinSpread_ExitFlow ust.Dec `json:"min_spread_exitflow" yaml:"min_spread_exitflow"`
}
PoolTerra_EntryFlow=BasePool_EntryFlow+TerraDelta_EntryFlow
PoolLuna_EntryFlow=(BasePool_EntryFlow)**2/PoolTerra_EntryFlow
PoolTerra_ExitFlow=BasePool_ExitFlow+TerraDelta_ExitFlow
PoolLuna_ExitFlow=(BasePool_ExitFlow)**2/PoolTerra_ExitFlow
//Hypothetical arrangement of initial parameters (entry flow, BTC for UST)
PoolRecoveryPeriod_EntryFlow // 10 minutes
BasePool_EntryFlow // $500 million
MinSpread_EntryFlow // 10 bps
//Hypothetical arrangement of initial parameters (exit flow, UST for BTC)
PoolRecoveryPeriod_ExitFlow // 1 minute
BasePool_ExitFlow // $500 million
MinSpread_ExitFlow // 200 bps
Reserve Parameters: Empirical Assessment
In this section, we offer guidance on what the actual parameter settings should be.
Exit Flow Parameters: this should be based on a desired activation level for the fund (e.g. $0.98) and the desired speed of deploying all capital. The table below shows how much liquidity is available instantly and per hour at a variety of slippage rates. All of these parameters are within reasonable ranges to defend against oracle attacks, as discussed in the appendix.
Parameters (Exit Flow) | Instant Liquidity | Per-Hour Liquidity | ||||||
---|---|---|---|---|---|---|---|---|
Base Pool | Recovery Period (minutes) | Minimum Spread (bps) | 200 bps | 300 bps | 400 bps | 200 bps | 300 bps | 400 bps |
$100MM | 1 | 200 | $2MM | $3MM | $4MM | $60MM | $90MM | $120MM |
$100MM | 1 | 300 | $0 | $3MM | $4MM | $0 | $90MM | $120MM |
$500MM | 1 | 200 | $10MM | $15MM | $20MM | $300MM | $450MM | $600MM |
$500MM | 1 | 300 | $0 | $15MM | $20MM | $0 | $450MM | $600MM |
$500MM | 5 | 200 | $10MM | $15MM | $20MM | $60MM | $90MM | $120MM |
$500MM | 5 | 300 | $0 | $15MM | $20MM | $0 | $90MM | $120MM |
$1,000MM | 0.5 | 200 | $20MM | $30MM | $40MM | $1,200MM | $1,800MM | $2,400MM |
$1,000MM | 0.5 | 300 | $0 | $30MM | $40MM | $0 | $1,800MM | $2,400MM |
$500MM | 0.1 | 200 | $10MM | $15MM | $20MM | $3,000MM | $4,500MM | $6,000MM |
$500MM | 0.1 | 300 | $0 | $15MM | $20MM | $0 | $4,500MM | $6,000MM |
In this table, we examine minimum spreads (i.e. activation levels) of 200 - 300 basis points, i.e. UST being redeemed for $0.97 - $0.98 in BTC. This is based on an empirical calibration, to prevent the fund for being utilized for ordinary movements in the price of UST in favor of extraordinary movements only. In particular, using hourly data in the past ninety days (as of 3/21/22), the 0.1% percentile of UST’s price was just above $0.98. Moreover, using daily data since UST’s inception, the 1% percentile of UST’s price was just above $0.98, with almost all exceptions coming from the large and sustained deviation in May 2021. Thus, 200 basis points seems like an appropriate threshold to be utilized in emergencies but not otherwise.
Entry Flow Parameters: this should be based on the desire to replenish BTC in the reserve after a crisis has passed and the UST peg has been restored. However, it may be desirable to provide liquidity at shallower depths, and replenish the reserve over a longer period of time. This is because the reserve should have a substantially smaller MinSpread
parameter, making it more vulnerable to oracle attacks — and so a longer PoolRecoveryPeriod
is appropriate.
Parameters (Entry Flow) | Instant Liquidity | Per-Day Liquidity | ||||||
---|---|---|---|---|---|---|---|---|
Base Pool | Recovery Period (minutes) | Minimum Spread (bps) | 5 bps | 10 bps | 50 bps | 5 bps | 10 bps | 50 bps |
$100MM | 1 | 5 | $50K | $100K | $500K | $36MM | $72MM | $360MM |
$100MM | 1 | 10 | $0 | $100K | $500K | $0 | $72MM | $360MM |
$500MM | 1 | 5 | $250K | $500K | $2.5MM | $180MM | $360MM | $1,800MM |
$500MM | 1 | 10 | $0 | $500K | $2.5MM | $0 | $360MM | $1,800MM |
$500MM | 5 | 5 | $250K | $500K | $2.5MM | $36MM | $72MM | $360MM |
$500MM | 5 | 10 | $0 | $500K | $2.5MM | $0 | $72MM | $360MM |
$1,000MM | 5 | 5 | $500K | $1MM | $5MM | $72MM | $144MM | $720MM |
$1,000MM | 5 | 10 | $0 | $1MM | $5MM | $0 | $144MM | $720MM |
$500MM | 10 | 5 | $250K | $500K | $2.5MM | $18MM | $36MM | $180MM |
$500MM | 10 | 10 | $0 | $500K | $2.5MM | $0 | $36MM | $180MM |
Oracle Attacks
The section contains the analysis needed to set attack-resistant parameters. It covers two types of oracle attacks: stale oracles, and manipulated oracles.
First, consider stale oracles. We present the plot of the 99.5 percentile of BTCUSD price movements (from the last six months), in absolute value, as a function of timescale. Stale oracle prices of up to five (5) Terra blocks expose the reserve to ~25 bps of price movement in the tails. As such, the MinSpread
parameter needs to be large compared to this, in order to protect trading against stale oracle prices being used to drain the pool over time.
Second, consider manipulated oracles. Here, we need to ensure that the BTC liquidity available from the reserve is small compared to that available in the centralized exchanges for BTCUSD. This protects against an attacker manipulating the real BTC price and then trading against this manipulated price. Below is a consolidated liquidity plot for all the major centralized exchanges, showing the slippage in bps that a market order of various USD notional sizes would suffer. Reassuringly, the BTCUSD market is very liquid — and so, as long as the reserve pool suffers more than ~20bps in slippage on a $10MM trade, there is negligible risk of an oracle being manipulated.
However, regardless of proposed mechanisms above to counter issues relating to oracles, we recommend the implementation of daily BTC redemption caps. This outflow restriction protects the reserve in the worst scenario, such that not all BTC could be drained in one or a series of days due an oracle bug. We suggest somewhere between 10-30% of the total reserve size as an initial redemption cap and are seeking community input for guidance.
We look forward to engaging with the community on this proposal.