DAO duh Cha-Ching
A group of Russian programmers decided to set up a new blockchain platform. The new platform would improve on Bitcoin by allowing arbitrary contracts to be specified, rather than just the simple transactions supported by Bitcoin. It would have its own cryptocurrency, which people would be able to purchase with real money.
The platform would be called ‘Ethereum’, the currency ‘ether’. Initial purchase of ether started in 2014, and by earlier this year more than a billion dollars of the virtual commodity had been sold.
An organization called ‘The DAO’ (standing for Decentralized Autonomous Organization) was founded using the Ethereum platform to codify its laws, and was crowdfunded with around $150m-worth of ether. They boldly declared that their code was law:
The DAO is self-governing and not influenced by outside forces: its software operates autonomously and its by-laws are immutably chiseled into the Ethereum blockchain.
No more tedious legal documents — just software code. If you want to find out what the organization will do regarding a proposed business transaction, you run the code — which was proudly declared to be immutable.
“The truth is not always beautiful, nor beautiful words the truth.” ― Lao Tzu
So, what does the code look like? Well, this is the part that will have experienced programmers and computer scientists screaming, guffawing, or staring at the screen with mouth agape:
The designers of Ethereum decided to support their arbitrary contracts by having a virtual machine which would execute the contract code on all the systems participating in the blockchain. They decided to make their contracts programmable using a Turing-complete imperative programming language based on JavaScript. They apparently didn’t bother to add atomic transaction primitives; that’s a Simple Matter of Programming, right?
The choice of Turing-complete imperative programming opened up the Ethereum system to all the classic pitfalls of imperative programming — including unintended recursive loops and race conditions. It wasn’t long before someone pointed out that you could use a recursive call to cause a race condition. The code to send money to someone had the feature that the receiver was an object, and so of course that object could execute code when it received the money. And if the code it executed was the same ‘send’ operation again, you had what came to be known as the Race to Empty attack in which the calling code would think it had executed the receiver method once, but it had actually executed multiple times.
“If you do not change direction, you may end up where you are heading.” ― Lao Tzu
The coders of DAO had apparently considered this possibility. A ‘transfer’ function intended to be called during a transaction was carefully written to reduce the balance, check there was enough money, log the result, and then return true or false to indicate whether the transaction should continue. Unfortunately, the function to log the result was also called ‘Transfer’, but with a capital ‘T’. It’s the capital-‘T’ function that is called in the “withdraw reward for user” function, so the balance isn’t reduced if the code recurses.
It’s possible that this error is the cause of the bug, making it a really expensive single-character typo. The calling code apparently doesn’t bother to check the return value from calling the transfer function, so it’s also entirely possible that the code author only intended to log the transaction and not bother with interim balance checks. Or, the true error could be somewhere else entirely — I’ve not read the entire codebase. The very fact that it’s questionable where exactly the fault lies, however, points at a fundamental problem with trying to encode the complexities of business law into JavaScript. I can hardly believe I just had to write that sentence.
“To know non-knowing is optimal. To imagine one knows is affliction of mind” ― Lao Tzu
Whatever the root cause of the vulnerability, an enterprising hacker wrote himself a recursive business transaction, and siphoned off ether coins worth around $50 million — or about $80 million if you count ether at the value it had before news of the attack got out.
What about fixing the bug, assuming it’s a bug? No such luck. The code has been declared immutable, remember, so any child DAO forked from the parent will have the same weakness.
“No DAO funds at risk following the Ethereum smart contract ‘recursive call’ bug discovery” — DAO developer
What makes this hack so amusing is the fact that the DAO had explicitly declared that their code was law. Sure, there’s a one-line comment in the code suggesting the code doesn’t match the intent of the author, but the behavior of the code was declared to be what counted, not any statements by individuals. The code handed $79 million to someone — and now the founders of the DAO are saying hang on a minute, we didn’t intend that to happen, can we have a do-over? Suddenly they want to make their immutable code mutable, fork it, and roll back the transactions. To do this, they need the support of the Ethereum community.
Of course, if this happens, it will completely destroy the entire point of the exercise. If ether currency can be moved around by fiat because a bunch of people don’t like a particular business transaction, it’s no different from any regular currency. Pretty soon a government will turn up and say “These transactions are funding terrorism, you’re going to reverse them”. Many in the Ethereum community are saying that The DAO and its backers should be left on the hook — that the market should take care of it. If a few people end up losing a ton of money, so be it.
“If you try to change it, you will ruin it. Try to hold it, and you will lose it.” ― Lao Tzu
If the hacker came forward and sued to keep his transferred funds, it could make for a fascinating high stakes legal case. If the legal contract says that the code is a smart contract which controls all terms and conditions and that intent is irrelevant, as it does, then is what the hacker did actually illegal? As Bloomberg puts it, smart contracts were dumb.
“New Beginnings are often disguised as painful endings.” ― Lao Tzu
Update 2016-06-19
It gets better! The alleged hacker is planning to bribe the largest ether miners so that they will refuse to participate in any upcoming fork to recover the withdrawn funds.