SIP-48: Allow Views to Return When Rates Are Stale

Author
Discussions-To<https://discordapp.com/invite/AEdUHzt>
StatusImplemented
Created2020-03-09

Simple Summary

Allow all views to return even when rates are stale.

Abstract

Change the current logic which errors out on when reading effective values when rates are stale to instead simply returning the value even if stale.

Motivation

Since Synthetix's v2.0.0 "Multicurrency" release, the effectiveValue of some amount from one synth into another has been a view function which throws when either the src or dest currency is stale. Synthetix.totalIssuedSynths() and Synthetix.transferableSynthetix are also views impacted by stale prices.

This original approach was designed to indicate to any users of the system that it was in an invalid state and not useable.

However, this feature breaks dApps and scripts as it's not intuitive that a readable view function would revert. Instead, for better compatiblity, I propose that we always return answers for views and simply put the onus on our mutible functions to do the checks.

This means dApp writers need to be checking for the flag: Synthetix.anySynthRateStale() to know if the system is unusable.

Specification

  • The following views will no longer error out
    • ExchangeRates.effectiveValue() and ExchangeRates.effectiveValueAtRound()
    • Synthetix.totalIssuedSynths(), Synthetix.totalIssuedSynthsExcludeEtherCollateral(), Synthetix.maxIssuableSynths()
  • Synthetix to be given a new function anySynthRateStale() indicating if any synth is stale.
  • For mutative issue and burn functions:
    • add a require that anySynthRateStale() must be false
    • and ensure the SNX rate is not stale
  • For an exchange(), add a require that src and dest are both not stale
  • For an SNX transfer() or transferFrom()
    • add a require that anySynthRateStale() must be false
    • and ensure the SNX rate is not stale ensure SNX rate not stale along with anySynthRateStale()

Rationale

The mutative functions above are to be explicitly given the checks that they rely on in the views they read.

Test Cases

  • Given any synth rate is stale or the rate of SNX is stale, when Synthetix issuance (issue(.*)Synths()) or burning (burnSynths(.*)()) is attempted, it reverts
  • Given any synth rate is stale or the rate of SNX is stale, when Synthetix transfer (transfer(.*)()) is attempted, it reverts
  • Given a synth rate is stale, when Synthetix exchange (exchange(.*)()) is attempted either from or to that synth, it reverts

Implementation

Synthetix PR #451

Copyright and related rights waived via CC0.