SIP-198: Update To Atomic Exchange Function

Author
StatusImplemented
TypeGovernance
NetworkEthereum
ImplementorMEB (@barrasso)
ReleaseMirach
ProposalLoading status...
Created2022-01-01

Simple Summary

Update the atomic exchange functionality, laid out in SIP-120, to include the following changes:

  • Allow trading at the pure the chainlink price for certain synths.
  • Remove the restriction on the Source or Destination Currencies being sUSD.

Abstract

The SIP proposes to incorporate into the atomic exchanges the ablity to configure a pure chainlink price feed for certain synths. Furthermore, the SIP proposes to remove the restriction on the source or destination currencies being sUSD.

Motivation

Currently in order to add a synth into Atomic Exchanges, we need the following:

  • The synth that can be traded
  • The equivalent uni-v3 token
  • The atomic price buffer
  • The atomic exchange fee

However, it is impossible to configure some forex stable synths due to the lack of an equivalent dex token that has deep persistent liquidity. One example is the recent EUR addition where we configured sEUR to take on the EURT token price. But TVL had dried up on the EURT/USDC pair, and liquidity flowed towards the EURT/USDT pool. This resulted in atomic prices being quoted at uncompetitive prices with respect to the fill that can be obtained elsewhere. An analysis run on both EUR and GBP, whereby we looked at the price differential between the pure chainlink price against the prices seen on centralized exchanges reveals that a fee of 20 bp would more than sufficient to cover the latency gap related to pushing prices on ETH by an oracle. In fact, chainlink push threshold on all forex synths is around 15 bp, which allows us to provide really competitive pricing without incurring the risk of oracle front-running.

Regarding the use case, synth stables on ETH have gained significant market share, due to the integration with FixedForex project and demand for these synths on curve for farming purposes. At the time of writing, the synth-forex market cap is around $220m and distributed as follows:

  • sEUR $108m
  • sJPY $21m
  • sAUD $18m
  • sGBP $29m
  • sCHF $27m
  • sKRW $19m

Hence, we should expect some volume with atomic forex trading across different curve pools, for curve farming, as well as different integration with other partners.

The restriction on the source currency or destination currency being in sUSD was incorporated in SIP-120 as a safety precaution. However, this can be relaxed as to accomodate for crypto to FX trades without exposing minters to additional risk.

Specification

Overview

The implementation includes the following major sections:

  • Tagging assets to trade at pure chainlink price
  • The computation methodology of the price of assets that trade atomicaly
  • The fill amount of a trade that trades atomically

Rationale

With SIP-120 any asset can be configured to trade atomically, however, the the downside is that it requires that a uniswap v3 pool be available with enough liquidity to make arbitrages on the uniswap pools align with real world prices. The lack of liquidity on those forex pools, resulted in prices drifting away on the EUR pools from prices on exchanges by hundreds of basis points. Furthermore, the lack of relevant uniswap liquidity pool for exotic forex assets makes this solution untenable. The alternative specified in this sip, is to tag assets to trade at the pure chainlink price and allow for these assets to utilize the chainlink price for the fill. Although this does expose the staking pool to the risk of latency arbitrage, since the oracle used might drift away with from real world prices for a short period of time, that said, raising fees to a certain level (since stables drift by only a few bp at a given time) and incorporating off chain circuit breakers SIP-231 allows us to cover both the tail and non-tail latency risks.

Technical Specification

  • setPureChainlinkPriceForAtomicSwapsEnabled is a method in SystemSettings that allows assets to be tagged to trade at the pure chainlink price.
  • getPureChainlinkPriceForAtomicSwapsEnabled is an internal function in MixinSystemSettings that returns True if an asset has been tagged to trade at purely the chainlink price and False otherwise

Atomic Price Computation Methodology

Context on Pricing and Naming Conventions

The price of an exchange when a trade materializes from a source (SRC) currency to a destination (DEST) currency can be broken down into two price components:

  • The price of the source currency in dollar terms is denoted SRC/USD, for example BTC/USD is at 38k$ per bitcoin.
  • the price of the destination in dollar terms, denoted DEST/USD
  • A trader, trades an amount of SRC currency, called SRC_Amount and he receives DEST_Amount.
  • SRC/DEST is the trade price, being the amount of destination currency received per source currency. It is obtained by dividing SRC/USD by DEST/USD. For example trading 1 bitcoin into eur, with destination EUR/USD 1.05$ and source BTC/USD at 38k$. Applying the previous formula will lead to 38k/1.05 , resulting in 36,190 EUR received, assuming 0 fees.
  • The computation of DEST_Amount is given by SRC_Amount * SRC/DEST * (1- fee).
  • In the case where SRC or DEST is the US Dollar, the same logic still applies, where one of the components is USD/USD or 1. An example of this is a trade of 1 USD into BTC, in such a situation the trade price SRC/DEST is obtained by dividing USD/USD 1 by BTC/USD (38k$) which leads to 0.0000263 btc received.
Computation Methodology in Atomic Pricing

SIP-198, leads to combinations that involve the usage of chainlink in certain situations and the usage of uniswap in others or a combination of the two sources of prices.

  1. PureChainlink Vs Not Pure Chainlink:
  • When a pure chainlink price is assigned to a currency, the chainlink price is used.
  • Otherwise the worse price between chainlink and uniswap is used in the combination. Worse price, means the price that would result in the lowest DEST_Amount.
  1. Naming Convention:
  • When _Uni is denoted on a currency, it means the price is from the uniswap V3 based DexPriceAggregatorUniswapV3 contract
  • When _Chainlink is denoted on a currency, the chainlink price is used
  1. Below are the different scenarios that could arise for trading currencies that have or don't have the Pure Chainlink tag:
  • SRC and DEST are both set to trade at the PureChainlinkPrice, in such a case, both SRC/USD_Chainlink and DEST/USD_Chainlink are used to compute SRC/DEST by dividing SRC/USD_Chainlink by DEST/USD_Chainlink.
  • SRC is NOT set to PureChainlinkPrice and DEST is set to PureChainlinkPrice. Therefore, SRC/DEST is obtained by dividing min(SRC/USD_UNI,SRC/USD_Chainlink) by DEST/USD_Chainlink.
  • SRC is set to PureChainlinkPrice and DEST is NOT set to PureChainlinkPrice. Therefore, SRC/DEST is obtained by dividing SRC/USD_Chainlink by max(DEST/USD_Chainlink,DEST/USD_Uni).
  • Both SRC and DEST are NOT set to PureChainlinkPrice, in such a case, SRC/DEST is obtained by dividing min(SRC/USD_UNI,SRC/USD_Chainlink) by max(DEST/USD_Chainlink,DEST/USD_Uni) .

Slippage Protection

Because prices could move by the time a trade lands on chain, minReturnAmount is incorporated, whereby a trade that leads to an amount lower than minReturnAmount would revert.

AtomicPriceBuffer

The CL_BUFFER is the buffer to be applied against the current Chainlink price in the direction detrimental to the trade, specified in bps and per-synth. This parameter had always been set to zero, given that controlling fees in order to offset latency was easier to reason about. Therfore, this parameter will be dropped from with current implementation of atomic exchanges.

Test Cases

  • Given that a trader intends to trade 10 sBTC to sEUR, with fees set to 0 bp

    • Given that EUR/USD_Chainlink is at 1.1 while EUR/USD_Uni is at 1.2.
      • Given that BTC/USD_Uni is 37,000 BTC/USD_Chainlink is at 38,000.
        • Given that sEURand sBTC are NOT set to trade at the pure chainlink price
          • When the user attempts to trade, setting the minReturnAmount to 300,000
            • ✅ Then it succeeds and the following take place:
              • 308,333 sEUR is sent to the user, and 10 sBTC is burned
          • When the user attempts to trade, setting the minReturnAmount to 310,000
            • ❌ Then it reverts, due to the retun amount being too low
        • Given that sBTC and sEUR are both set to trade at the pure chainlink price
          • When the user attempts to trade, setting the minReturnAmount to 300,000
            • ✅ Then it succeeds and the following take place:
              • 345,455 sEUR is sent to the user, and 10 sBTC is burned
          • When the user attempts to trade, setting the minReturnAmount to 350,000
            • ❌ Then it reverts, due to the retun amount being too low
        • Given that sBTC is set to trade at the pure chainlink price and sEUR is NOT set to trade at the pure chainlink price
          • When the user attempts to trade, setting the minReturnAmount to 300,000
            • ✅ Then it succeeds and the following take place:
              • 316,667 sEUR is sent to the user, and 10 sBTC is burned
          • When the user attempts to trade, setting the minReturnAmount to 320,000
            • ❌ Then it reverts, due to the retun amount being too low
        • Given that sEUR is set to trade at the pure chainlink price and sBTC is NOT set to trade at the pure chainlink price
          • When the user attempts to trade, setting the minReturnAmount to 330,000
            • ✅ Then it succeeds and the following take place:
              • 336,364 sEUR is sent to the user, and 10 sBTC is burned
          • When the user attempts to trade, setting the minReturnAmount to 340,000
            • ❌ Then it reverts, due to the retun amount being too low
  • Given that a trader intends to trade 10 sBTC to sEUR, with fees set to 50 bp

    • Given that EUR/USD_Chainlink is at 1.1 while EUR/USD_Uni is at 1.2.
      • Given that BTC/USD_Uni is 37,000 BTC/USD_Chainlink is at 38,000.
        • Given that sEURand sBTC are NOT set to trade at the pure chainlink price
          • When the user attempts to trade, setting the minReturnAmount to 300,000
            • ✅ Then it succeeds and the following take place:
              • 306,791 sEUR is sent to the user, sUSD 1,696 is sent to the fee pool and 10 sBTC is burned
          • When the user attempts to trade, setting the minReturnAmount to 307,000
            • ❌ Then it reverts, due to the retun amount being too low

Configurable Values (Via SCCP)

Aside from the SCCP configurable variables specified in SIP-120, the Spartan Council can assign that an asset can be traded at the pure chainlink price via SIP with setPureChainlinkPriceForAtomicSwapsEnabled.

Copyright and related rights waived via CC0.