Transcript for:
Understanding Re-entrancy Attacks in Smart Contracts

Hello guys, it's Jonny time. Now you probably know me of the one who educates you about DeFi and crypto and blockchain And today I'm excited to educate you about something new Smart contract hacking and security and today we're gonna learn everything about re-entracy attack One of the most destructive attacks on crypto and DeFi with millions of dollars lost It all started in the DAO in 2017 when 150 million dollars were lost but it's also actively exploited attack these days that many defy protocols suffer from if it's the raric capital on april 2022 where 80 million dollars were stolen or rivest finance on march 22 when 11 million dollars were stolen so today you're gonna learn everything about free agency attacks how it works what you can do with it now i hope that you're gonna use it for good purposes. This video is for educational purposes only, and I hope you're gonna take this knowledge in order to become a white hat hacker that help projects to protect their smart contracts rather than the ones who hack them and steal innocent people money. We will also, in this tutorial, simulate this attack ourself and execute it with heart and solidity so you can learn the best, the practical way How to exploit this kind of attack yourself and eventually we will finish up by learning how to secure our smart contracts and write secure code that is immune to re-entry setbacks.

So I'm super excited and without further ado let's get started. Alright, so what is re-entracy attack? So exactly like the name says, re-entracy means re-enter.

It's a vulnerability and solidity and smart contracts that lets you, an attacker, re-enter the same function before it finished its execution. And the best way to understand it is by example. That's why I created this drawing here for you.

So imagine you have a smart contract that represents a bank. It lets users deposit and withdraw Ether from the smart contract and of course it's gonna save their balances in a storage variable in a mapping that maps between addresses to integers. So if Bob deposited 3 Ether the smart contract will know that now Bob has 3 Ether and later on when Bob comes and tries to withdraw the Ether the smart contract will send him the Ether back.

How the smart contact send him the Ether back? is basically sending the ether first, and then he updates the balance of Bob, the message sender, to zero. So Bob can send multiple times one ether, plus two, plus four, and then later on come and try to withdraw all so the smart contract know that during this time, Bob deposited in total seven ether.

So it's gonna send him the seven ether and change the balance of Bob from seven to zero. Quite simple, right? But something is wrong with this withdrawal function. Now try to pause the video, take a look at the function and let me know in the comments below if you spotted what's wrong.

Alright, so the withdrawal function, the first thing that it does, it sends the Ether to the user. That's where the problem relies. The smart contract, the bank, it thinks that Bob is a normal account.

But what if Bob is not a normal Ethereum account but a smart contract itself, right? Because smart contract can also be a user that deposit it to the bank and then wants to withdraw it. And in smart contracts, there is something called fallback function.

This function will be executed when the smart contract receives Ether automatically. And now you can connect the docks and understand that when the smart contract, the malicious smart contract, we can deploy a malicious smart contract that deposit let's say one if and then calls the withdraw function from the bank with one if but when this line of code will be executed when the bank will send the one eighth to the smart contract it will trigger here in the malicious contract a fallback function okay so this fallback function we can then use it in order to call again the withdraw function and guess what happens Now the banks, it doesn't know that it already sent us the ETH because it didn't update yet the balance, our balance, because it sent the ETH first. So it's basically endless loop that let us, the attackers, to drain the ETH from the Etherbank smart contract.

So the withdrawal function will be called, then he will send us the ETH. That will trigger our malicious fallback function that will call again the withdrawal now He still thinks that we have one ether or seven ether or whatever and he sends it again And then again fallback and then again reenter until the balance of the ether bank is zero and then okay You can update the balance to zero but instead of withdrawing one if we withdrawn I don't know maybe hundred it maybe thousands of it depends how much it exist in the smart contract. So now that we understand the concept of re-entracy attack, it's time to some in practice to make our hands dirty and read some Solidity code. So here is the implementation of the Etherbank. It's an updated Solidity version Etherbank.

Here you can see the mapping of the balances that stores the mapping between address to its balance. This is the deposit it functions very straightforward. It's a payable function that receives a message value which is if and store it in the balance storage variable.

Now this is a problematic withdraw function. As you can see it's a public function that any user can come and claim back and withdraw its balance. Now here we have a variable that represents the balance of the user and then we send the if okay we verify that the send was successful, that the transfer was successful, and then we update the balance.

Now here relies the problem. We send the ETH first, and then we update the balance later. That's where the problem starts.

Now let's try to deploy the smart contracts in order to simulate it and create our own environment. Guys, I wanted to share with you something super exciting and new. I've created a complete practical smart contract hacking course. accumulating 12 years of my cybersecurity and blockchain experience.

Without exaggerating, this is your holy grail all-in-one course which will instantly help you kickstart your career in smart contract hacking and security, making you the most demanded professional with insanely high salaries. Get exposed to tons of knowledge by signing up in the description below. By the way guys, all the code that I'm gonna show you over here gonna be in GitHub, in my public GitHub So feel free to clone it, to play with it, to practice re-entracy attack.

The link will be in the description below Now I'm using hardhat in order to simulate a local blockchain It's basically gonna simulate like Ethereum But on my localhost running a local simulated blockchain and we can that way simulate all the attack and in order to start the local Blockchain, we're gonna write npx hardhat node And it will take several seconds and there you can see you have all the accounts of the local blockchain It's just a simulation, a demo. Now I created some scripts that will help you deploy the smart contracts and make some activity in the network of like simulating users that deposit money to the bank. So the first script will be deploy bank We're gonna execute it right now that will deploy the bank smart contract.

Let's run it. NPX hard-hat run scripts Deploy bank and network make sure you had a local host so it will deploy it locally to the node and As you can see the ether bank was deployed to this kind of address and if you go here to the node you see that The transaction was submitted and there was a contract deployment of ether bank very easy very Straightforward now the next trip you want to run is the use bank that basically gonna simulate some activity of the bank It's gonna deposit some eats from account zero you then it deposits 5 ETH from account 1, 12 from account 2, so the bank will be realistic and users will deposit some ETH to it. So we're gonna do the exact same thing, but this time just change the script from deploy bank to use bank.

Alright, and you can see the script will write depositing 3 ETH, depositing 5 ETH, etc. And it will show that now the bank has 20 ETH in the balance and this is the balance as storage variable. That's what the bank knows that account 0 has. 3, 1 has 5, 2 has 12 and 3 which is the attacker has 0. So in our simulation the account 3 will represent the attacker and as you can see in the initial state it has 0. You can anytime check out the status of the bank by running the script check, check bank.

Okay, and then you can see the balances again. Now it's time to write the smart contract that is going to exploit the bank. Alright, so before jumping into riding on let's try to plan our attack So we want to attack this ether bank dot solve smart contract and in order to do so we need to deploy our own Smart contract will call it attacker dot soul Attack bank dot sold doesn't really matter this month contract will have two main functions one will be X execute which will start execution of the attack what it's supposed to do it's supposed to deposit first one ETH to the bank so the bank will see that we have some balance and then right after it will call the withdraw function to ask to withdraw this one ETH now once the withdrawal function will be executed it will send a smart contract back the ETH that will trigger the fallback function that will call again the withdrawal and then trigger the fallback until we drain the smart contract completely even though we deposited one it will we will be able to drain it to all the 20 it deposited by other users and now let's get started with the code and this is the attackbank.sol file okay so it's a solidity smart contract we declare here the interface of the ether bank the original smart contract the deposit and the withdrawal function so the attack bank smart contract will be able to interact with the ether bank smart contract and here we create a new contract called ether bank we we set some variables the ether bank smart contracts that we're going to attack and the owner we want to know who is the owner who deployed this malicious smart contract so eventually once all the logic will be done all the execution will be done we can send all the stolen if to the owner to the attacker who deployed this smart contract Now this is the constructor. This is the function that will be executed when the smart contract will be deployed. When it will be deployed, we need to tell it only what is the address of the contract that we want to attack, in our case the Etherbank address.

And as you can see here, we are setting the owner, the attacker, the one who deployed the smart contract, he will be the owner. And we save the Etherbank smart contracts by the address that we got upon deployment. Now this is the execute or attack smart function that we planned before.

As you can see it's external payable and it's first gonna call the deposit ETH function. Okay with one ETH. So we're gonna send from this malicious smart contract one ETH to the bank smart contract. Of course that will have to send with a transaction one ETH or load it up with one ETH in advance. So it will have the ETH to send to the original bank smart contract.

And then right after, we'll call the withdraw if. So it will ask the bank to withdraw all the one if that we deposited one line before. Now, this is where the magic begins.

The receive smart contract, the receive function. This is the fallback function. That's how we write fallback functions in Solidity.

And here we check if the Ether bank balance is greater than one is. We're going to call the withdraw it function again. So the bank is calling the withdraw function.

and will trigger this kind of function and here we check did we already drain the bank or is there any ETH left? If there is any ETH left, we're gonna call the withdraw ETH again and withdraw another one ETH else, which means that we already got all the ETH from the bank smart contract we're gonna simply send all the ETH of this malicious contract to the owner which is the attacker who deployed the smart contract. So it's quite simple. around 40 lines of code and this is how we can create a re-entry attack super super simple feel free to clone the code on github i'll put a link in the description and now it's time to start and deploy and execute the attack so first we want to deploy the malicious smart contract so we're gonna run the script solution and deploy attack contract okay so we are deploying first our malicious smart contract to the local blockchain let's click enter and the malicious contract has been deployed to whatever and here we can verify the attack bank contract has been deployed. Now we want to run the script attack.

This script is simply gonna take the malicious smart contract that we just deployed and call the attack function that will execute all the logic that we just created in the smart contract let's do it so we'll run script attack on localhost and as you can see over here after the attack this is my balance before the attack around 10 000 eth bank balance before the attack 20th and executing the attack attack done my balance after the attack is 10 018 is so we were able to withdraw a lot of it from the bank and in order to verify that the attack was successful we can run the script check bank again and here we will see that the bank balance as have left only with one ether okay we went easy on him we left one ether for the bank so we were able to withdraw 19th even though we just deposited one thanks to re-entrancy attack. Now you might ask oh my god this is so simple didn't know that re-entrancy attack that millions of dollars were stolen just because of this kind of simple and stupid vulnerability. Yes you're right but now let's try to understand how we can write better smart contracts that will not be vulnerable to re-entrancy attacks and people will not hack them.

So The first important thing that you need to learn about a re-entry attack and in general about writing smart contracts is that always, but always update the state variables first, the storage variables of the smart contracts before sending ETH or calling a center functions in other smart contracts. So by simply replacing the lines of the update and the transfer, okay, in the contract, in the withdraw function. we would avoid this kind of re-entracy attack because we would first update the balance of the user to zero and only after we would send the if which will trigger the fallback function so this is first way to protect against re-entracy attacks another way is to create some kind of mutex that will lock the smart contract so we can create a variable a boolean variable that will be called locked it's an internal variable and we create a modifier that's called re-entracy guard so we will apply to this modifier before every function that might be vulnerable to re-entry attack and simply this modifier just check if this locked mutex is true or false so we're gonna change it to true once we enter to the function so we'll do something like locked equals true and then the next time when we get into the smart contract again okay which will be protected by the re-enter-stigard modifier, we will check again, this modifier will be executed and we will see that the locked is true, so it will revert the transaction because this require will be executed. So you have some kind of variable that knows all the time if someone is trying to re-enter to the same function over and over again. So this is the second way of protecting against re-entracy attack by using a re-entracy guard modifier.

Now, if you want it even more simpler, in a more simple way, you don't have to implement this kind of function yourself. You can just use OpenZepp link, re-entracy guard smart contract. This is basically a contract that you can inherit from, and automatically it will let you use this kind of non-re-entrant modifier, which does the exact same thing.

Exactly like re-entracy guard, just they implement it for you. So you can simply just import the re-entry guard smart contract by open zeppelin and then inherit from this smart contract in your smart contract and now this non-re-entrant modifier will be available and you can place it in every sensitive function that might be vulnerable to re-entry attack. Alright so this is the re-entry attack tutorial. I hope you guys enjoyed it and learned something new. If you did make sure to smash the like button and subscribe to the channel and And if you have any more ideas about other videos that you want me to create about DeFi, about crypto, about hacking, let me know in the comments below.

Thank you so much and I will see you in the next videos. Bye bye.