SIP-165: Debt Pool Synthesis

Author
StatusImplemented
TypeGovernance
NetworkEthereum & Optimism
Implementordb (@dbeal-eth)
ReleaseDiphda
ProposalLoading status...
Created2021-12-16

Simple Summary

This SIP seeks to merge the debt pools across all chains on which Synthetix is deployed, tracking the total synth debt with a common oracle.

Abstract

Currently, each chain that Synthetix is deployed on has its own isolated debt pool. In order to seamlessly provide liquidity across chains and allow synths to be transferred between them, we must ensure that debt is tracked properly cross-chain.

We are able to do this by relying on an oracle which reports the value of the debt backed by the debt pool and the amount of debt shares issued across all chains. This also renders the debt cache obsolete, reducing the complexity of the codebase.

Motivation

Merging the debt pools is necessary to provide maximum liquidity across the protocol and allow synths to be transferred between multiple chains efficiently via cross-chain messaging, rather than relying on automated market makers (which are limited by the depth of their liquidity pools and subject to slippage).

Specification

Overview

The Chainlink oracles must monitor the debt composition across all chains and push relevant values to all of those chains.

The issuer should rely on the global values provided by this oracle—rather than chain-specific values—for the total debt shares (which is replacing the debt ledger system) and value of the total debt backed by the debt pool. Consequently, the debt cache is no longer needed to track the value of the total debt and so the debt pool oracles that would replace the debt cache (specified in SIP-156) does not need to be implemented.

Rationale

Although it would be possible to transmit debt updates between chains directly, relying on an oracle allows for a substantially more elegant implementation. Further, with debt shares, it is straightforward to track debt responsibility across an arbitrary number of chains.

Technical Specification

Implementation of this SIP involves a new Chainlink oracle and assorted updates to the protocol.

Debt Synthesis Oracles

This SIP relies on an oracle that provides the ratio between the total issued synths and the total debt shares across all chains and then updates these values across all chains. It is important that one oracle reports the ratio, rather than the individual values seperately, to minimize front-running opportunities. Review the Test Cases for more considerations regarding front-running.

This JavaScript code demonstrates the value that the oracle should update on each chain:

const { BigNumber } = require('ethers')
const { synthetix } = require('@synthetixio/contracts-interface')

async function debtSynthesisOracle() {
  const NETWORK_IDS = [1, 10]

  let totalDebtIssued = BigNumber.from(0)
  let totalDebtShares = BigNumber.from(0)

  for (networkId of NETWORK_IDS) {
    const snxjs = synthetix({ networkId })

    totalDebtIssued = totalDebtIssued.add(
      await snxjs.contracts.DebtCache.currentDebt(),
    )
    totalDebtShares = totalDebtShares.add(
      await snxjs.contracts.SynthetixDebtShare.totalSupply(),
    )
  }

  return totalDebtIssued.mul(BigNumber.from(10).pow(27)).div(totalDebtShares)
}

Another oracle should be deployed to report the total debt issued across all chains. We can also use this derive the total debt shares by relying on the ratio value reported by the oracle specified above.

const { BigNumber } = require('ethers')
const { synthetix } = require('@synthetixio/contracts-interface')

async function debtSynthesisOracle() {
  const NETWORK_IDS = [1, 10]

  let totalDebtIssued = BigNumber.from(0)

  for (networkId of NETWORK_IDS) {
    const snxjs = synthetix({ networkId })

    totalDebtIssued = totalDebtIssued.add(
      await snxjs.contracts.DebtCache.currentDebt(),
    )
  }

  return totalDebtIssued
}

A previous iteration of this SIP involved a single oracle which packed totalDebtIssued and totalDebtShares into the upper and lower bits of a uint256. The proposal has been updated due the Chainlink oracle infrastructure rounding the resulting value in some cases.

Protocol Updates

  • Debt Cache Deprecation: The debt cache will no longer be used going forward. The related keeper no longer needs to be maintained. The contract can be left in place, at minimum, to provide access to the currentDebt function for the oracle.

  • Synth Issuance: The issuer will now rely on the totalDebtIssued and totalDebtShares reported from the oracles rather than the equivalent values provided by the debt ledger and the debt cache.

  • SNX Rewards: SNX rewards will be provided to users proportionally on the networks that they are using to stake. This means that, in a given fee period, a staker will receive the same SNX rewards regardless how their staked funds are distributed across chains (as the percentage of debt shares that they own is agnostic to this distribution).

  • sUSD Rewards: sUSD rewards will be provided to users on the networks on which the exchange fees were generated. This means that, in a given fee period, a staker will receive more sUSD rewards if they are staked on a chain which has more exchange activity. This is the most elegant solution from an implementation standpoint (as we don't need to communicate exchange fee volumes cross-chain) and incentivizes users to provide liquidity to the more active chain.

  • Fee Pool Closure: The fee pool will need to be updated via cross-chain communication. Initially, L1 can use the Optimism Messenger to trigger the closure of the fee period on L2. Ultimately, this can use a cross-chain broadcaster to support additional chains.

  • Loans: The interest rates charged on loans are determined by examining an aggregate skew in the system. This may be difficult to compute accurately across two chains. It should be verified that the behavior of the loans contracts only examine the skew on their own chain, not involving the full cross-chain debt, if it isn’t feasible to properly account for it.

Also note that is possible for the totalDebtIssued to become negative if the value of synths backed by SNX tokens is less than the amount backed by wrappers and shorts. This risk already exists and is mitigated by the growth of incentives for individual SNX stakers as the debt pool becomes smaller.

Test Cases

Review two test cases here pertaining to oracle latency.

Automated tests pertaining to issuance and cross-chain communication for fee period closure are under development.

Configurable Values (Via SCCP)

N/A