The most famous attack in history: The Reentrancy Attack

Aitor Zaldua
Block Magnates
Published in
4 min readNov 8, 2022

--

Image from Vitalik Buterin Twitter account.

July 2016. General Vitalik Buterin cries in a corner of the office. Something horrible happens to his only son. Fighting against the invader, it is about to die in the battlefield. But Vitaly is not ready to say goodbye to him. He and Gavin Wood, or rather, Bruce Banner and Tony Stark, are not going the give up so easily. They have the ultimate solution, the end of an era, the Supernova.

And finally, Vitaly press the red button.

And the world was never be the same.

Ethereum split into 2 blockchains and, as already happened in the, #they-should-have-given-it-the-oscar, movie Twins (1998), the result was like having Danny De Vito and Arnold Schwarzenegger again. They called the old network Ethereum Classic, ETC, the Danny De Vito network, with the bug that triggered the cataclysm. And they called the new one Ethereum mainnet, mr. Universe, the flawless, the perfect son.

But, what happens that they were forced to do such a drastic decision?

The Attack

The thing is that now something very sadly famous has happened: The Reentrancy Attack. Months earlier, The DAO was launched as the first major organization in the Ethereum ecosystem. Quickly, the organization was able to raise about $150 million but, in less than 3 months, it was hacked and $60 million worth of ether was stolen, about 14% of all ETH at the time.

The decision was controversial but, in the end, Buterin and the team decided to execute a hard fork, i.e. restore a pre-attack backup and fix the code error. Thus, the funds were returned to DAO. But some people were not happy with the decision and, currently, they are still working with the original, called Ethereum classic.

So, what is a reentrancy attack? Let’s look at Ethernaut number 10 code , because, yes, this is another post in the Ethernaut series.

  • We have the donate( ) function, to donate ETH to the account of our choice.
  • We have the withdraw( ) function, the vulnerable one, to withdraw funds from our account.

The Vulnerability

The main problem is that the solidity code was built to service the request to send cryptocurrencies made by humans, people. They never expected the call from another contract. and that is a mistake.

Look at the picture

When the call comes from another contract, the fallback/receive function is activated and, if that function calls back the withdrawal, the victim contract never has a chance to update the customer’s balance, setting it to 0, so the hacker can withdraw funds until the victim contract is depleted.

The attack contract could be something like this:

The solution

The most common solution is very simple: Just altered the order of the instructions. Instead of CHECK → INTERACT → EFFECT just do CHECK → EFFECT → INTERACT

In addition, you can add Open Zeppelin’s ReentrancyGuard library to prevent re-entrancy. The new script looks like this:

Oh boy, there are a few modifications, indeed! Are you able to find the 6 differences?

It would probably be recommendable to also add the OZ´s Ownership library and, if we dig a little deeper, we can find another recommendation. But that’s enough for today, let’s continue! Reentrancy will never be a problem again.

Happy hacking and make the web a better place!

--

--

Security Researcher | Smart Contract Dev | Blockchain Instructor. Follow me on twitter: @azdraft_