SIP-303: Markets (V3)

Author
StatusDraft
TypeGovernance
NetworkEthereum & Optimism
ImplementorDaniel Beal (@dbeal-eth), Leonardo Massazza (@leomassazza), Alejandro Santander (@ajsantander)
ReleaseTBD
Created2022-05-03

Simple Summary

This SIP proposes the creation of markets in Version 3 of the Synthetix protocol. Markets are expected to accept snxUSD, generate derivatives, rely on liquidity provided by pools to back any debt they have issued, and return snxUSD to the pools backing it as an incentive.

Abstract

Markets are a generic abstraction that allow products (such as spot markets and futures markets) to be built on the protocol. Market contracts interact with the market manager to mint snxUSD, burn snxUSD, and coordinate liquidity from pools. Markets can be designed and deployed by anyone.

Motivation

By creating a generic market interface, we are able to cleanly separate concerns in the codebase and allow for greater composability with the protocol. Though we anticipate starting with implementations of futures and spot market contracts, it should be possible to design new types of markets backed by the protocol as well.

Specification

Overview

Markets interact with the market manager to read the amount of liquidity available to them and report the balance (net debt or credit) they’ve generated. The market manager tracks the share of the balance apportioned to each of the pools that are providing liquidity to a given market.

Rationale

By facilitating all of the logic pertaining to minting and burning snxUSD within the market manager, we’re able to allow the permissionless creation of markets in the protocol. The intention of this design is ensure that only the pools which back a given market are exposed to risk generated from this market, while keeping snxUSD fungible and shielded from this risk.

In the worst case scenario, a malicious actor could generate a market, persuade pools to provide it with liquidity, and then set the balance value to a large negative number (suggesting large debt inflation). This would subject the pools involved to liquidation, but no other risk should be assumed by the protocol.

Technical Specification

The market manager will implement something similar to the following interface:

interface IMarketManager {
	function registerMarket(address market) returns (uint);
	function liquidity(uint marketId) returns (uint);
  function marketUsdDebt(uint marketId) returns (int);
	function marketTotalDebt(uint marketId) returns (int);
	function deposit(uint marketId, uint amount);
	function withdraw(uint marketId, uint amount, address recipient);
}

Markets can be registered with the market manager using the registerMarket() function. This validates the presence of a debt() function in the specified contract and stores the market’s address. This function may also emit an event (for protocol analytics) or include various restrictions around market creation.

A market’s total debt has two components: snxUSD debt and reported debt. The snxUSD debt is increased when the market withdraws snxUSD and decreased when it deposits snxUSD. It may also report additional debt (with a reportedDebt function) which is typically incurred from price fluctations among the synthetic assets it backs. Each vault is responsible for a share of a market's total debt proportional to the amount of collateral it has delegated. A market cannot withdraw snxUSD if its debt exceeds a maximum calculated from a weighted average of the maximum debt share values among its backing pools.

The only function that a market must implement is reportedDebt().

interface IMarket {
	function reportedDebt(uint marketId) view returns uint;
}

As an example, a basic synth spot market for sBTC could be implemented as follows:

  • An ERC-20 contract would be deployed, with a mint and burn function only callable by the market contract and a symbol() function that returns sBTC.
  • The sBTC market contract would be deployed with the following functionality:
    • reportedDebt()
      • Returns the total supply of the sBTC token multiplied by the current price of BTC.
    • buy(uint amount)
      • Transfers the specified amount of snxUSD from msg.sender to the market manager with the deposit() function.
      • Determines the exchange rate based on a price oracle and applies any fees.
      • Mints the appropriate amount of sBTC to msg.sender.
    • sell(uint amount)
      • Burns the specified amount of sBTC from msg.sender.
      • Determines the exchange rate based on a price oracle and applies any fees.
      • Transfers the appropriate amount of snxUSD from the market manager the withdraw() function to msg.sender.

Note that if fees are simply deducted during exchange, they are effectively distributed among vaults pro-rata based on the amount of liquidity they’re providing. This would be similar to stakers having their snxUSD fees instantaneously burned in the current version of the protocol. Stakers could then mint snxUSD to retrieve them.

Test Cases

Relevant tests will be developed during implementation.

Configurable Values (Via SCCP)

  • Approved Markets (address[]) - This is a list of market contract addresses owned (or otherwise approved) by the Spartan Council and will be listed in the official UI.

Copyright and related rights waived via CC0.