FEATURE: Synthetic Assets
Overview
THORChain synthetic assets are primitives for both higher-order financial features, as well as fully-secured, fully-backed synthetic assets that can be sent anywhere in the Cosmos IBC ecosystem and they will always retain the guarantee they can be redeemed for the underlying.
THORChain synths are unique in that they are 50% backed by their own asset, with the other 50% backing being provided by RUNE. This is achieved by using pool ownership to collaterise the synth, which ensure always-on liquidity and pricing.
Implementation
Mint
- User mints Synth by adding RUNE to the pool (or swapping from an asset into RUNE, then adding that).
- synthUnits are issued to cover the new liquidity, but held by the protocol (not owned by anyone).
P = poolUnits
A = assetDepth, R = runeDepth, r = runeAmount
pool.runeDepth += r
synthAmount = (r * R * A)/(r + R)^2
synthSupply += synthAmount
transfer(recipient, synth, synthAmount)
SynthUnits are computationally derived at any point, this ensures there is only enough at any time to represent the outstanding supply.
S = totalSynths
A = assetDepth
R = runeDepth
runeValueOfSynths = S*(R/A)
runeCollateralOfSynth = runeValueOfSynths/2 = ((S*R)/A)/2 = (S*R)/(2*A)
PoolUnits are therefore the sum of liquidityUnits + synthUnits.
Redeem
User redeems synth by getting it swapped out to RUNE:
- Burn the synth
- Delete a pro-rata share of the liquidity units held for synths.
- Swap to RUNE and remove from the pool
s = synthToRedeem, T = totalSynthSupply
S = synthUnits
A = assetDepth, R = runeDepth
poolUnits -= GetShare(s, T, S)
synthSupply -= s
runeAmount = (s * A * R)/(s + A)^2
pool.runeDepth -= runeAmount
transfer(recipient, rune, runeAmount)
Synth Swaps
Synth Swaps can be done as follows:
- Layer1 to Synth: L1 in, RUNE moved over to the pool, synth MINTED
- Synth to Layer1: Synth REDEEMED, RUNE moved to next pool, Layer1 swapped out
- Synth to Synth: Synth REDEEMED, RUNE moved over to the pool, synth MINTED
To specify the destination asset is synth, simply provide a THOR address. If it is Layer1, then provide a layer1 address.
Minting from own pool
If a user wishes to mint from the same Layer1 asset, the process is simply a Layer1 swap to Synth, but the RUNE is not moved anywhere. EG:
pool.assetDepth += assetAmount
intermediaryRuneAmount = (a * A * R)/(a + A)^2
P = poolUnits
A = assetDepth, R = runeDepth, r = intermediaryRuneAmount
synthUnits += (P r)/(2 R) * (1 - (r/(r + R)))
synthAmount = (r * R * A)/(r + R)^2
synthSupply += synthAmount
transfer(recipient, synth, synthAmount)
Staged Pools
If an active pool which minted synths become staged, then swaps are disabled. However synth holders can always redeem for RUNE, or the underlying asset, by specifying that on the way out.
Economic Reasoning
Synths are backed by the collateral of the pool, 50% in RUNE, 50% in ASSET. Synth holders do not experience any gain or any loss caused by price changes when minting / redeeming a synth. They do however, pay a slip-based fee on entry or exit.
The dynamic synth unit accounting is to ensure that gain or loss caused by price divergence in the synths is quickly realised to LPs. Although since LPs have IL Protection, as long as they stay for longer than 100 days, the Protocol Reserve is taking on the price risk.