Member-only story
5 Solidity Code Smells That Every Blockchain Developer Should Know
5 Mental Models for Smart Contract Exploit Detection
Recently I’ve been studying to become a Solidity auditor. My primary reason for doing this is I don’t believe there will be fewer smart contract bugs in the future, and therefore this skill will be in high demand for as long as Solidity is the primary language of smart contract development.
While studying for some upcoming interviews, I’ve gone through a number of different security tutorials, challenges, and post-mortems. After all of this studying I thought it would be beneficial to recap what I’ve learned.
This post is primarily for my own benefit to recap what I’ve learned in the last few weeks, but, since I’m doing it anyway I will also post it in case anyone else finds value in it.
5 Code Smells
In general I’ve found there to be 5 classes of Solidity exploits. Each exploit has a certain “code smell” associated with it. If you can detect the code smell, usually you’re more than halfway to the exploit, as it’s a case of figuring out what variation of a well-known exploit the code smell is suggesting and implementing it.
There are already countless posts about the most common Solidity exploits, so why write another? Well, typically these posts are written for Solidity developers, and not auditors. For this reason, they start with the exploits and work back to the code examples. In this post, I would like to do the opposite and start with the code smell first, because as an auditor, you’re looking at code that has already written, rather than writing the code yourself.
Dynamic Arrays
The first code smell is the use of dynamic arrays. The exploit associated with dynamic arrays is well-documented and well-known. This is the Solidity analog to the old C buffer overflow exploits. If a dynamic array is used in a smart contract, you can underflow it and get arbitrary access to all of the storage variables of a smart contract. This allows you to change balances, take ownership of a contract, or anything else related to contract variables. Note, this can also be used to allow an attacker access to related or dependent smart contract storage depending on how those related contracts are imported or called.