Synthetixio / synthetix

Synthetix Solidity smart contracts
https://synthetix.io/
MIT License
1.2k stars 594 forks source link

Decentralized oracles with Chainlink #293

Open jjgonecrypto opened 4 years ago

jjgonecrypto commented 4 years ago

Problem

The current Synthetix (SNX) oracle is a centralized point of failure. It runs constantly, reading in prices from a range of real-world pricing services and updates the ExchangeRates contract (currently at 0x99a46c4 at this time) with the latest prices for all of the assets underlying each of our synths (priced in USD).

The code for the SNX oracle is closed-source and centralized. It is closed in order to prevent bots from calculating differences in prices off-chain and profiting from delays in Ethereum transaction latency. It is centralized and managed by the Synthetix team, and while vigorously monitored and maintained, has significant centralization risk, with users forced to trust the team, their processes and integrity.

Proposal

To migrate to a decentralized oracle solution for all of our synths. The most robust solution available with the highest level of community engagement is the Chainlink ecosystem of pricing networks.

We propose to enter into agreement with Chainlink, upgrading our ExchangeRates contract to using their pricing networks gradually.

However, in order to prevent front-running of decentralized oracle prices, there is a strict dependency on Synthetix first refactoring the exchange() functionality to a new queuing mechanism (more details below).

Terminology

The Chainlink ecosystem uses certain language around oracles and pricing that makes sense to incorporate into the Synthetix nomenclature.

For example, here is a visualization of the ETHUSD aggregation network: https://eth-usd-aggregator.chain.link/

image

Implementation

To work with the Chainlink ecosystem, our ExchangeRates contract would need to be refactored.

Unlike our current oracle which pushes multiple prices updates simultaneously, Chainlink uses a one-price-per-contract approach for modularity and reuse purposes. We agree with this approach, though some light refactoring will be required so that our ExchangeRates contract knows where to find the price for each synth. It will need a mapping of synth keys to a Chainlink Aggregator for that pricing network (e.g. mapping(bytes32=>address)).

For inverted synths - such as iETH, iBTC et al - we propose reading the regular rate from the Aggregator and then inverting it in our ExchangeRates contract, as we do currently.

Cost Basis

Currently the Synthetix Foundation is paying both the API costs for real world pricing of assets and the gas costs of updating the ExchangeRates contract on-chain.

Moving towards decentralized oracles will offload these costs from Synthetix directly. Synthetix and Chainlink are working together to find a reasonable cost basis for ongoing upkeep of the various pricing networks for all synthetic assets used.

Considerations

Pricing networks

Since inception, Synthetix has been fairly flexible with trying out different synths. This will be marginally more difficult under a decentralized system as a price network needs to form and be available on mainnet for every new synth added to the ecosystem. This will mean more lead time for adding new synths to the system.

Index synths

For indexed synths - such as sCEX and the upcoming sDEFI which are a weighted basket of number of prices - we propose working with Chainlink nodes to do the weighted calculations off-chain and provide the pricing of our indexes on-chain directly. The alternative would be a pricing network for every price inside each index (if it didn't exist already), which would be too costly.

Concerns

Front-running

The current Synthetix system tackles front-running of SNX oracle updates by limiting how much Gwei an exchange can be performed with (see SIP-12). This works as the centralized SNX oracle can be guaranteed to ensure all oracle updates are performed with higher Gwei than the aforementioned limit.

With Chainlink's network of decentralized oracles, this cannot be guaranteed. However with a large number of oracles per price network, and the Aggregator taking the median of a minimum number of updates, front running a price network becomes marginally more complex.

Frequency of updates

The SNX oracle runs regularly and updates prices on-chain, ensuring that small price movements are tracked. If an on-chain price deviates by more than the current exchange fee (currently 0.5% but lowering back to 0.3% soon), we update it, preventing bots from taking advantage of the difference between on-chain and real-world pricing (what we refer to as "technical front-running"). Morever, the SNX oracle ensures that every price is updated at least once an hour - and if any price is more than 3 hours stale (configurable via ExchangeRates.rateStalePeriod), the system freezes.

Chainlink's pricing networks will target on a 1% price deviation and a heartbeat of approximately twice a day. While the slower heartbeat can be incorporated into our system, the larger price deviation would expose the system to an unacceptable amount of "technical front-running".

Dependencies

Thus, in order to migrate to the decentralized oracle system of Chainlink and not expose the system to front-running attacks mentioned above, a different mechanism of exchanging is required. What we propose is to overhaul the exchange() functionality inside Synthetix. Instead of exchanges happening immediately, they would be placed into a queue to be processed FIFO once prices for both the source and destination synths has been received. This introduces its own challenges (such as who pays the gas), but has the added benefit of supporting limit orders on-chain.

This queuing mechanism will be a prerequisite to migrating to a decentralized oracle service. Once applied, we can begin the transition to Chainlink's pricing networks, one synth at a time.

CryptoToit commented 4 years ago

Hey Justin, great write up!

Couple questions: 1- Which "Price Networks (PN)" are currently available from the ChainLink network? 2- Do you have an available list? 3- Does these cover our current list of Synths? 4- If not, what would it take to 'get' a new PN up and running? It seems that it would require at least 14 independent nodes contributing to a specific PN.

My concern wrt the questions above is that we end up with 70% of Synths reading price from the ChainLink network and still have to sit with a centralised Oracle for years. I'm thinking of when we start getting to synths like AAPL, MSFT, FB, GOOGL etc.

I do however agree and like the phased approach of migrating specific synths over one at a time.

Cheers

jjgonecrypto commented 4 years ago

Hey @cryptotoit,

  1. Right now only ETHUSD AFAIK, though other crypto markets are on the way
  2. No I don't, but perhaps @JohannEid can chime in?
  3. No they don't, but Chainlink are aware of SNX needs and are working towards them
  4. A PN needs enough oracles to be be "secure" - i.e. how many nodes does an attacker need to be compromised in order to significantly impact the price? If the minimum number of oracles is 7 then the answer is 4, if 5 then 3 (the majority). We're going to work with Chainlink and their nodes to decide on the right minimum of oracles needed per price together.

You're right to be concerned about a continued dependency on the centralized SNX oracle, yet both teams want to see the end of the SNX oracle sooner rather than later. We won't consider the SNX platform decentralized and derisked until all prices are sourced from decentralized on-chain oracles.

JohannEid commented 4 years ago

Hey @CryptoToit , @justinjmoses answered most of the points. Concerning the price feeds, we currently have ETH/USD on mainnet and will be putting new ones first on testnet then mainnet in the very near future. The process for Chainlnik to put new PN(price networks) on mainnet is extremely straightforward and we're confident that we'll be able to answer all of Synthetix's oracles needs in a timely manner.

You can keep yourself updated by following this page

As for the node operators who're responsible to provide data to these PNs, we already have more then 80+ listed here including 20 highly reliable blockchain infrastructure companies.

ghost commented 4 years ago

Decentralized Oracle make no sense if without data source diversity,20+ oracle nodes get data input from only limited data source. And especially important official data,such as stock price,game results,weather data, the data source is almost just one,and centralized oracle is more efficient than decentralized oracle( the all nodes get input from the same one source).

ChainLinkGod commented 4 years ago

@iblockchain I agree this is legitimate concern for oracle feeds, but Chainlink Oracle networks support both decentralization at both the oracle operator level and the data source level. For example the ETH/USD Heartbeat (https://eth-usd-aggregator-staging.chain.link) currently pulls the ETH price from BraveNewCoin, CoinMarketCap, CryptoCompare, Kaiko, and I think a few other sources as well. Each Oracle delivers their data from their respective source to Ethereum and the median is taken (or any other aggregation method) on-chain (eventually off-chain through Threshold Signatures).

JohannEid commented 4 years ago

@ChainLinkGod exactly the right answer. Just for your information, the nodes on ETH/USD network are also pulling data from Coinpaprika, Coingecko, CoinAPI and CoinCap, making it a total of 8 different data providers. We plan to bring the same focus on decentralization to Synthetix's price feeds.

Arthur0x commented 4 years ago

How often is the Chainlink oracle for ETHUSD updated at current implementation? My biggest concern is the frequency of updates. Even the current Synthetix oracle arguably doesn't update the price frequent enough especially when compare to an off-chain orderbook onchain settlement DEX protocol like 0x or Loopring.

In a day where market doesn't move much and the Chainlink oracle is only updated once every 30 mins, the user experience of Synthetix Exchange will be severely impacted especially when combined with our Exchange queuing proposal. A trade order might not be executed for a long time, this essentially make a market order on Synthetix impossible.

JohannEid commented 4 years ago

Hey @Arthur0x - thank you for your comment. We plan to update the price at every 1% deviation. The way it will work is by having an off-chain component called the "flux monitor" which will ping a price API every minute. If it ever sees a 1% difference in price between the on-chain price and the current API price, it will trigger an update of the reference contract.

RewKang commented 4 years ago

@JohannEid Who controls the flux monitor? Would it be considered a centralized source of risk?

JohannEid commented 4 years ago

Hey @RewKang , the intent is to have third party node operators all run their own flux monitor which will allow for a highly decentralized network without any central point of failure. For each node operators running, there will be another flux monitor up.

jjgonecrypto commented 4 years ago

Here is the proposal for phase one of the migration - commodity and forex synths: https://sips.synthetix.io/sips/sip-32

dongzhuoyao commented 3 years ago

Hey @Arthur0x - thank you for your comment. We plan to update the price at every 1% deviation. The way it will work is by having an off-chain component called the "flux monitor" which will ping a price API every minute. If it ever sees a 1% difference in price between the on-chain price and the current API price, it will trigger an update of the reference contract.

So you mean each minute, we will query the on-chain price, which will also introduce cost?