The fact that there are billions of dollars riding on smart contracts worldwide, it becomes pertinent to ensure that smart contracts are hack-proof and your funds are secure. As a wise man once said, “Wise people learn from their mistakes, wiser people learn from the mistakes of others”, we put out the harsh lessons we have learned throughout our journey in smart contract auditing space so that you don’t end up on the dark side of the deal.
Through this podcast, Ish and Nitika address the three major vulnerabilities in smart contracts that have led to the loss of funds. We have learnt about these vulnerabilities in great detail owing to our years of battle-hardened experience in crafting our skills as auditors. By the end of this, we hope you can also understand what are the major areas of concerns in a smart contract and what areas contribute the most to the fund loss.
Watch the full video here:
The written transcription of the video is below:
Ish Goel: Hey guys, my name is Ish Goel and I’m the CEO of Somish Blockchain Labs. This is our second episode of the smart contract auditing podcast, and in this video, we are going to talk about some serious stuff. So we are going to talk about the three errors or bugs that you can find commonly in smart contracts and the fact that they can also lead into fund loss. This is something which we’ve seen in high profile projects in the past, and we’re going to talk about all three of them today. So by the end of the podcast, we’ll understand how to avoid fund loss and what are the areas where fund loss can happen. So let’s get started. Cool, so Nitika, the first topic that we’re going to discuss today is that of reentrancy attacks. So can you help us understand what are reentrancy attacks in smart contracts, and what are the problems that arise because of reentrancy attacks?
Nitika Goel: Reentrancy attack, It occurs when a function, makes an external call to another untrusted contract before it resolves the effects that should have been resolved. So for example, I’ll give you a very straight example. So there is a contract and say people are pooling in funds into this contract and after 30 days you can just withdraw your funds with some interest. So suppose this is a very simple functionality. So you’ll have a function where you come and you claim your investments plus your interest after 30 days. A standard function would look like. I would check that, have 30 days passed that would pass and then I would transfer the funds to you. And I would just mention like this person has claimed, so something like this is a very simple example that I’m taking.
Now. What would happen is, that if this person to whom I need to transfer the funds is a contract. It’s an untrusted contract of course, and this contract calls back my function through which I was trying to claim the rewards. So what happens is this contract triggers the function to claim his rewards.
It passes the check. Yes, 30 days have passed. It transfers the money to this contract. This contract calls back the first function again. Now, I have not marked this claimed true as of now. So for me, the funds have not yet been withdrawn. So what happens is I transfer the funds again, and this is like a loop which keeps on happening and happening and happening. So, this is quite dangerous because this can actually drain out the entire funds of your contract.
Ish Goel: So it can allow an external party to enter your contract, and eventually drain the funds from that contract. This is a serious vulnerability.
Nitika Goel: This is quite a serious vulnerability. Now, typically there are two types of reentrancy attacks. So, one would be a single function and one would be a cross-function. So what the example that I just gave was a single function wherein, the external contract was calling the same function through which the funds were being transferred to that contract. They can be a complex scenario where I have put a reentrancy guard on this function, which was initiating the transaction. But the external contract is calling some other function of my contract, which is using the same state that was being used by this function. So for example, there is another function which also has some method to transfer funds again, and because I have not marked claimed as true. Instead of this function, passing on the funds the second function is able to pass on the funds. So, this is very tricky because it’s very difficult to find out. That’s where I think most of the contracts fail because, nowadays we know that we have to put reentrancy guards, but cross functions may skip our mind.
Ish Goel: Easily skipped. Yeah. Fair enough. So the bigger issue that we’re talking about, if I talk from a non-technical standpoint, is that if you have a reentrancy bug in your smart contract, so the attack surface is high in terms of fund loss, so people can simply call functions of your contracts and they can re-enter the same piece of code and eventually drain the funds.
Okay. So the second one that we are going to talk about again from fund loss perspective, is that of signature replay attacks. So can you help us understand what our signature replay attacks?
Nitika Goel: Yeah. So, there are use cases where, instead of a person directly initiating a transaction allows another person to initiate transaction on his behalf.
Ish Goel: Okay.
Nitika Goel: There are some cases where this is required as a part of the business process. So in this case, what happens is I sign my transaction via my private key and this generates a VRS signature that we call it in technical language. And then what happens when I send the data along with my signature, the contract generally tries to recover the public key of the person who was trying to make the initial transaction. So basically it would check the data and the signature and match that, yes, this transaction should have come by the person who signed it.
Ish Goel: Okay
Nitika Goel: So this is the general flow. Now what happens is the message which is being signed, if this message is not unique, it can be replayed.
So for example, I said that please transfer 10 Ether on my behalf. I signed that once. And if this does not have something unique in it, what can happen is somebody else can replay this again and again and again, and that would just transfer my funds again and again and again.
Ish Goel: But can you help us understand why would, how can somebody sign a transaction without having private key of the specific address?
Nitika Goel: So, like I mentioned, I have signed it once, so I have generated a VRS for that data. So they copied the same data, they replay the same data and the VRS. So because there is no check that this data is being replayed, the signature gets replayed. Also, this is like something which happens on the mainnet.
There are times when what happens is that I have tried and tested my application on a testnet and what I tried and tested on testnet is being replayed on mainnet. So this is all the more dangerous.
Ish Goel: I see, again results in fund loss.
Nitika Goel: Yes.
Ish Goel: Cool, so anything else you want to talk about from our signature replay perspective, or do we move on to the next one?
Nitika Goel: It’s just there are several solutions for this, nonce being one of the solutions, and there are several other ways to handle it. It’s just that there has to be something unique about your data and you have to mark your data as complete, so this has been analyzed.
Ish Goel: Okay. So, the last bug that we’re going to discuss today is that of Front Running, I’ve heard this term many times in this space. So if you could throw some light on what Front Running means and again, is this something which could lead into fund loss from a contract?
Nitika Goel: So, if I described Front Running. So basically what happens, in Ethereum, let’s take an example. So people, posting various transactions, they’re all posted to the Mempool and what is the transaction? When did you post it? That’s not important. What is important is the gas price for the miners. So you pay a higher gas price, your transaction gets picked up before the second person, right? So now what can happen is like, there are so many DeFi applications, where we have formula based calculations where suppose, you know, there’s a bonding curve, and if I pay in say ‘X’ amount of ether, I’m expected to get ‘Y’ amount of tokens. But this is based on a formula. So suppose the formula is based on the total supply of tokens.
Ish Goel: Okay.
Nitika Goel: Now, I was expecting, say a hundred tokens. What happens is that somebody initiates a transaction, he front runs the transaction before my transaction gets picked up and he changes the total supply. This results in the token supply being different from what I had expected. So what now happens is that I should have got a hundred tokens. I do not get those hundred tokens, I get something very different from my expectation so you got front runned by someone else.
So, these are some are financial applications where this can hit really hard when this is coupled with owner privileges, this becomes even more difficult. So for example, I was expecting that the fees that the application was charging was, say 1%, somebody has access to the owner keys. It might not be on intention, but somebody has access to the keys of the owner. And he changes that to suppose 99%. Now, I had in mind that I would get a hundred tokens. Now what would actually happen is that the 99% would go as fees to the owner’s key. And what I would actually get is just 1%.
Ish Goel: But this is the control which the owner can exercise.
Nitika Goel: Precisely, so there are times when the owner has the privilege on the config parameters, which are changing the price. There are also times when it is something which is like, automatically calculated, for example, total supply.
This is not in the hands of …
Ish Goel: But how is front running different from ownership control. Can you throw some light on that?
Nitika Goel: See, when I talk about ownership control, it is the right that the owner key has access to change or call some transactions, which changes the state of the system or it manipulates the flow of the system. But in this case, despite not having the private key, somebody else could also come and manipulate. For example, this is very common on platforms like Uniswap. So that is why today they have a concept of slippage. So where if suppose the customer says that at the max, I expect a 1% slippage. That means whatever price I have seen at max 1% below that, otherwise, please do not complete my transaction. So the transaction reverts in this case. Now imagine the slippage was not there and somebody comes and he manipulates the price. Anybody could do that. It’s not the owner of Uniswap who’s doing this. Anybody can play because it’s an automated formula which has been being manipulated. So in this case, it’s not the owner who’s changing it. There are times when the owner has special privileges and he is the one who can change the config parameters and there are times when it’s opened to the market.
Ish Goel: Cool, that was a very technical discussion, but thanks a lot for that Nitika. I think, it’s been, a wonderful episode today.
So guys, see the idea is that if you are building a smart contract application there are, certain caveats where people generally fall prey to. And these caveats can eventually result in a fund loss. Now, that’s the last thing you want when you’re building an alternative to financial products, which are in the CeFi market. If you’re in the DeFi market, the last thing that you want is that your protocol or product results in a fund loss. So I guess, we’ll continue to discuss these in the next episodes and, you know, also talk about other caveats. There’s a huge list which people generally fall prey to. But, for a beginning, it’s been amazing. So Nitika, thank you so much for this very informative session.
Guys, this is us, Ish Goel and Nitika, signing off for this episode.
Guys, don’t forget to subscribe to our podcast if you are in the space. If you’re excited about DeFi, writing smart contracts, this is the podcast for you.
You will be listening to a lot of cool stuff around how to write good contracts, make sure that they are bug-free and stay tuned for more episodes.
Nitika Goel: Thank you.