SIP-148: Upgrade Liquidation Mechanism V2

Author
StatusApproved
TypeGovernance
NetworkEthereum
ImplementorMark Barrasso (@barrasso), Noah Litvin (@noahlitvin)
ReleaseTBD
ProposalLoading status...
Created2021-06-11

Simple Summary

This SIP proposes a modification to the existing liquidation mechanism defined in SIP-15, the purpose is to reduce the likelihood of cascading liquidations leading to a destabilization of the protocol.

Abstract

Liquidated SNX will be transferred to a pool and distributed proportionally to stakers, subject to a 12 month escrow. Users may liquidate themselves (whenever they are below the target c-ratio), flag others for liquidation (when that user falls below a configurable c-ratio), and liquidate others (if they have been flagged for a configurable amount of time). Users who flag and liquidate others will receive a configurable flat SNX reward. Users who are liquidated will incur a configurable percentage penalty.

Motivation

As we have seen with the liquidations on 10-11th of June 2021, there is a possibility for cascading liquidations to have substantial market impact. This happens when new accounts get flagged for liquidation, resulting in fear among token holders who take action by selling. This depression in price then causes more accounts to be flagged for liquidation and the cycle continues. This could result in a catastrophic failure of the system leading to large losses for synth holders.

Moreover, users are not effectively incentivized to restore their c-ratio in some cases, as they essentially hold a free put option, which could be very valuable in times of market stress.

Accounts with very large stakes may also believe that they are unable to sell their SNX without incurring more than 10% slippage, which may make liquidation preferable to restoring their c-ratio. Fear of large accounts being liquidated could also lead to substantial adverse market impact in the anticipation of the liquidation event.

The goal of this SIP is:

  1. To more heavily incentivize stakers to act in the best interests of the system during times of stress.
  2. To lower uncertainty about bad debt for synth holders and make it clear that SNX holders are the ultimate backstop for the system.
  3. To remove forced liquidations at inopportune times and encourage insolvent stakers to explore other options such as self-liquidating in order to avoid costly penalties.

This redesigned liquidation mechanism creates much better incentive alignment within the system by providing options for stakers to repair their c-ratio with a minimal penalty if they are unable or unwilling to buy synths on market to restore their c-ratio. It also ensures that, in extreme scenarios, liquidations happen in a orderly manner without creating a negative feedback loop on the price of SNX. It relaxes the current liquidation mechanism by relying more on self-liquidation for protecting system solvency. Fundamentally, it creates two layers of penalties that transfers ownership of the protocol from inefficient stakers to more efficient stakers. This, combined with the existing incentives to repair c-ratios, should result in a more responsive and stable network c-ratio.

Specification

Overview

A new contract will be deployed that will receive liquidated SNX. This SNX will be assigned to stakers based on their percentage of the total debt shares at the time of the liquidation.

Rationale

The initial version of this SIP proposed a three tiered system of liquidations with instant liquidation as the final backstop of the system. After several SIP presentations and discussions within the community, the consensus view is that instant liquidations still pose too large a risk to the network where adversarial actors could try to attack the system to trigger instant liquidations and share in the liquidation rewards. Instant liquidations were therefore removed from the current version of this SIP, but the liquidation penalities for both forced and self liquidations were increased substantially to ensure that solvent stakers are sufficiently rewarded if a significant percentage of the network elects to utilize self-liquidation.

The following implementation approach will allow us to make minimal modifications to existing contracts and rely on an adapted version of the staking rewards contract to manage distribution of the liquidated SNX to stakers.

Technical Specification

The BaseSynthetix contract will be updated such that the liquidateDelinquentAccount method will transfer the liquidated SNX to a new LiquidatorRewards contract. A new selfLiquidateAccount function will be added to the BaseSynthetix contract to handle the self-liquidation use case.

In the Issuer contract, the liquidateDelinquentAccount function will be modified to check whether the given account is able to be liquidated and then rely on debt shares to calculate the amount to liquidate. A similar selfLiquidateAccount function will be added for the self-liquidation use case.

The upgraded Liquidator contract will replace the existing Liquidations contract to implement a new function to handle the self-liquidation use case and rely on the configurable values specified in this SIP.

A new LiquidatorRewards contract will be deployed to track the rewards earned by stakers based on their percentage of the total debt shares at the time liquidations occur (to ensure that rewards are fairly distributed). This will be a modified version of the existing StakingRewards contract which will rely on debt shares (rather than the ERC-20 token staked in the contract) and claimed rewards will be transfered to a 12 month escrow (rather than being provided immediately).

BaseSynthetix Contract Interface Updates

The BaseSynthetix contract is used to liquidate a flagged account or self-liquidate.

pragma solidity >=0.4.24;

interface ISynthetix {
    // Liquidate account if c-ratio is below the SCCP specified value
    function liquidateDelinquentAccount(address account, uint susdAmount) external returns (bool);

    // Self liquidate account back to target c-ratio
    function selfLiquidateAccount(address account, uint susdAmount) external returns (bool);
}

Issuer Contract Interface Updates

The Issuer contract authorizes whether an account can be liquidated and calculates the amount to liquidate.

pragma solidity >=0.4.24;

interface IIssuer {
    // Restricted: used internally to Synthetix contracts

    // Liquidate a specified account if allowed
    function liquidateDelinquentAccount(
        address delinquentAccount,
        uint susdAmount,
        address liquidatorAccount
    ) external returns (uint totalRedeemed, uint amountToLiquidate);

    // Liquidate the calling account if allowed
    function selfLiquidateAccount(
        address account,
        uint susdAmount
    ) external returns (uint totalRedeemed, uint amountToLiquidate);
}

Liquidator Contract Interface Updates

The Liquidator contract is used to check which accounts can be liquidated and flag accounts for liquidation if eligible.

pragma solidity >=0.4.24;

interface ILiquidator {
    // Views
    function liquidationPenalty() external view returns (uint);

    function forcedLiquidationOpen(address account) external view returns (bool);

    function selfLiquidationOpen(address account) external view returns (bool);

    function calculateAmountToFixCollateral(uint debtBalance, uint collateral) external view returns (uint);

    // Mutative Functions
    function flagAccountForLiquidation(address account) external;

    // Restricted: used internally to Synthetix contracts
    function removeAccountInLiquidation(address account) external;

    function checkAndRemoveAccountInLiquidation(address account) external;
}

SystemSettings Contract Interface Updates

SystemSettings contract is used to track the parameters related to liquidations.

pragma solidity >=0.4.24;

interface ISystemSettings {
    // Views
    function liquidationPenalty() external view returns (uint);

    function selfLiquidationPenalty() external view returns (uint);

    function flagReward() external view returns (uint);

    function liquidationReward(uint reward) external;

    // Owner only
    function setLiquidationDelay(uint time) external;

    function setLiquidationRatio(uint liquidationRatio) external;

    function setLiquidationPenalty(uint penalty) external;

    function setSelfLiquidationPenalty(uint penalty) external;

    function setFlagReward(uint reward) external;

    function setLiquidationReward(uint reward) external;
}

Test Cases

TBD

Configurable Values (Via SCCP)

  • liquidationEscrowDuration: 1 year
  • liquidationDelay: 24 hours
  • liquidationRatio: 200%
  • liquidationPenalty: 30%
  • selfLiquidationPenalty: 20%
  • flagReward (L1): 10 SNX
  • flagReward (L2): 1 SNX
  • liquidateReward (L1): 20 SNX
  • liquidateReward (L2): 2 SNX

##Copyright

Copyright and related rights waived via CC0.