Ghostboard pixel

Migrating away from trust

Decentralizing our price oracle with Chainlink

Migrating away from trust

Decentralizing our price oracle with Chainlink

Update (November 11, 2019): some of the content in this article is no longer up-to-date. Please check the blog for more recent information.

Synthetix works by calculating the value in USD of SNX tokens locked as collateral to mint sUSD and other Synths.

Say Alistair has 20,000 SNX in his Ethereum wallet. If he wants to mint sUSD in Mintr our dApp for managing the minting on synthetic assets within the Synthetix platform, the smart contract needs to know the USD value of SNX tokens.

If each SNX token is worth 0.05 USD, then 20,000 SNX is worth 1,000 USD (20000 x 0.05), and can mint 200 sUSD because the contract limits the amount issued (the debt) that can be created to 20% of the collateral value. The minted stablecoin — the sUSD — is a debt to the system, and must be sent back by Alistair to the SNX contract to unlock his 20k SNX tokens (say, if he wants to transfer them elsewhere). Another way to look at it is that his collateral (SNX) to debt (sUSD) ratio is 5:1 (or 500% collateralized).

Once he has minted, what then? Well, the price of SNX will continue to fluctuate due to market forces. So, he is incentivized to keep his ratio at 5:1 through our new staking rewards and network fees. The more diligent he is at maintaining that ratio as SNX price fluctuates, the more additional SNX and fees he will receive as reward for providing stability to the system.

To make all this work, our contracts need to know the current exchange rate of SNX to USD whenever a user wants to mint (0.05 in our above example). Since our inception, we’ve had written and maintained a pricing oracle¹ that provides the price of ETH and SNX against USD. It’s a lightweight piece of heavily tested code we wrote and maintain. It’s job is to get the most fair and balanced price in real time, and is heavily monitored with numerous fallbacks.

[1] So called because it provides smart contracts with information from outside the blockchain.

As we’ve expanded, we added support for exchanging sUSD for other synthetic assets (synths we call them — hence our name!) on our new exchange platform. To support these new synths we need the prices of these underlying assets against the US dollar as well. Right now our list of synths includes around fifteen currencies (USD, AUD, GBP, EUR, JPY, CNY, etc), along with gold (XAU), silver (XAG) and bitcoin (BTC) — all updated regularly (don’t get me started on the gas costs!)

The oracle works fine except for one thing. We own it completely and it is closed source. It’s our code, and we manage its deployment. A dozen or so employees and engineers across the world are responsible for its accuracy and consistency. The entire Synthetix community has to trust us to maintain a fair and even price, and trust isn’t the mantra of the modern world. Verify is.


As part of our commitment to DeFi (decentralized finance), we’ve integrated with Chainlink on Kovan — an Ethereum testnet. Chainlink provides decentralized pricing services by negotiating with providers with access to various data feeds (for some amount of LINK, their utility token). Once a price is requested, Chainlink forwards the request to an allocated node which retrieves the price from its providers and returns the price to the smart contract.

Here is our existing ExchangeRates contract’s source. In it we keep a mapping of currencyKeys to rates, along with their last update times. We periodically invoke updateRates from our centralized oracle, with the rates we sourced ourselves via our oracle.

Check out the state of the contract by reading it on Etherscan, try invoking the rates with SNX or sAUD. Note the price obtained needs to be divided by 10¹⁸ to account for 18 decimal places. The timestamps are in seconds.

And here, is the source of an integration with Chainlink on the Kovan testnet. We support an additional function requestCryptoPrice that creates the Chainlink request (using a JobID created by a Chainlink node on Kovan that looks up prices on CoinMarketCap). When the price is obtained, the fulfill function is invoked with the price, eventually invoking our internalUpdateRates function, for all intents and purposes as though invoked by our centralized oracle.

An example of a user manually requesting for the price of DAI on Kovan Etherscan (transaction mining time removed from GIF for display purposes).

What’s next?

Chainlink’s release onto Ethereum mainnet is forthcoming, and we’re excited to start integrating it into our live system.

Once live on mainnet, we’ll redeploy ExchangeRates and update our Synthetix contract to include it. We’ll then slowly start to migrate to Chainlink for our crypto pricing (SNX, ETH and BTC) alongside our existing oracle, before adding support for currency, commodity and stock synths. Eventually, we’ll deactivate our centralized oracle, sending it off to a well deserved retirement.

Stay tuned.