As many of you may have seen in the crypto news, Synthetix (a platform for derivatives) recently had an issue where their Oracle reported the wrong value and caused some serious losses (and conversely gains) for certain customers.
As an oracle provider, we’ve gotten quite a few questions on how we would ‘solve’ the issue. But to be honest, it wasn’t an ‘oracle’ problem per se, but more so a system design problem.
Bad data happens, this shit’s new, we get it. So to start off, I’m not saying Synthetix is awful or anything of the sort. In fact, I love that they actually launched a product and have managed to get some users. That right there deserves way more credit in this space, and I’m a huge fan of what they’re trying to build.
But that said, there’s all sorts of checks that should have been in place to handle this.
‘Oracle’ is sort of an all encompassing term, but it can really mean two different things. One, it can be a price feed or data piece in a smart contract, like the ETH/USD price. Furthermore,it can be a solution for getting data into your smart contracts. So in the first case, like how Synthetix uses the term, an oracle failing means your price feed has failed. The price feed could have been off-chain data, an Augur market settling, or even transaction price on a DEX, but it has to do with the validity of the data versus what it is supposed to be representing. In the second case, the data is actually some specific element off-chain. The network of miners, a group of known parties, or just one entity, is actually your ‘oracle’. What the off-chain data is or how you use it on-chain isn’t the ‘oracle’ in this second case.
For DeFi products, knowing the mechanics of your underlying settlement price is of utmost importance. If you are settling to the ETH/USD price, what does that mean? Is it the result of an auction, the EOD price on some exchange, or the average of several API calls to certain exchanges?
The problem in Synthetix case was that an exchange reported the wrong price for Korean Won at a rate of 1000X the current rate. They quickly identified the problem correctly as being that this API should have been detected as an outlier and thrown out but for some reason it wasn’t.
Solutions
First you need to identify what the settlement mechanism is. Are you settling to the price of ETH as reported by a network of people, the price of ETH at GDAX, the average price of ETH over the past day on GDAX, or the price of ETH as reported by the GDAX API? All of the above have different consequences and different problems with creating a decentralized oracle around it.
Next, you need to figure out how you’re going to get it into your smart contract. Are you using a centralized party like Oraclize(Provable),your own company, or are you relying on a decentralized network of validators/ reporters? Hopefully the latter, but either way you need to be ready for that piece to have issues as well.
Best Practices for Smart Contracts
As with anything, if something is fast and easy, you’re probably not going to get the same security guarantees as you would with a slow system with checks. Represented well by systems like Tellor, Augur, or even Maker, you need a fall back plan if things break (e.g.a dispute process to put it up to a vote) and then a fallback plan if that fails. The downfall of course is that to build in some more robustness, it will likely degrade the UX and slow things down. But if you want true decentralization, you need to take your time. Security costs something and trying to build a blazing fast derivatives product with even a centralized oracle is very hard.
Bad API calls, or even malicious API operators, happen. Let’s make some seriously smart smart contracts that have some features built in to handle this.