What to Expect when your Smart Contract is Audited:
The Auditor’s Story
Considering a Smart Contract Audit?As a smart contract auditor, I’m trying to make sure your contract is secure against Ethereum Virtual Machine (EVM) level attacks. Those are the kinds of attacks that leverage the nuances of the EVM’s logic in order to hack your smart contract. What I am not looking at is your business logic. That job falls to your test writers. I can do that, DApp developers are polymaths by definition, but that requires a lot more hours and should be scoped out separately.
Specifically, I’m targeting the list of known attacks published by Consensys and the Ethereum Foundation.
- Race Conditions (Reentrancy and Cross-function Race Conditions)
- Transaction-Ordering Dependence (TOD) / Front Running
- Timestamp Dependence
- Integer Overflow and Underflow (including Storage Manipulation)
- Denial of Service with Unexpected Revert
- Denial of Service with Block Gas Limit
- Forcibly Sending Ether to a Contract
(A full description of these attacks can be found at https://consensys.github.io/smart-contract-best-practices/known_attacks/ and the definitive lecture of 2018 on this subject by Bernhard Mueller can be found at https://youtu.be/iqf6epACgds)
Compile and expose contract API
Now the first thing I am going to do is test your smart contract, ideally, with the test scripts you have already written. If I don’t have access to those I’ll compile your contracts in either Truffle or Remix in order to make sure the contract compiles and exposes the functions that have been detailed in the contract specification.
Ensure dependencies are accessible
Once I know I’m working with a functioning smart contract, there are a few steps I need to take in order to make sure my auditing application will recognize every dependency that your contract imports. I need to go grab the code of any dependency that is already deployed and then link it locally. If the framework your code is working in has any issues with pathing, I’ll copy your dependencies into the same folder as your contract and redirect the import statements to this copy. And then I’ll need to do the same for every dependency that I copied, because they will often times also have dependencies that I need to expose locally.
Explore every possible interaction
At this time in the smart contract audit, I’ll spin up Docker and run a local instance of my auditing application and give it the command to run a whole bunch of simulated interactions with your contract using symbolic execution. What this does is explore every possible interaction an actor can perform with your contract using an abstraction of any given input. So instead of testing every possible value that can be passed to every function, which would take longer than the heat death of the universe, it passes a symbol that stands for every possible input. This frees up time for the software to test all possible recursion in your contract’s flow control. The standard depth of recursion that I test for is 8 levels of recursion, but if we will be conducting a formal audit, I’ll run much deeper in an attempt to falsify any mathematical proofs required by a formal audit.
Trivial and non-trivial vulnerabilities
Once the smart contract audit application has finished exploring all the possibilities it will return a report that I will then convert to an appropriate file format; usually markdown, but some projects require JSON reports in order to be parsed by 3rd party applications. This report will contain both trivial and non-trivial vulnerabilities. The trivial ones are technically vulnerabilities, but are generally not exploitable. For example, if your contract is built atop OpenZeppelin smart contracts they could theoretically have malicious business logic, but if we check and see that OpenZeppelin is an accepted standard and does not have any delegate calls that will alter the behavior of the source contracts, we know that we are safe.
Non-trivial vulnerabilities are usually exposed by your business logic. A common one I see is Integer Overflow arising from a for loop that works with arrays. In this case, the business logic may be sound in that controls are in place that no combinations of array lengths or iterations through the for loop will result in an array length exceeding 2**256. But I would advise the client to request or perform a formal audit on that particular function in order to mathematically prove that there is no intersection between control logic boundaries and statistical vulnerability frontiers… or at least that the probability of their intersecting within a given timeframe is within the client’s risk tolerance.
Formal Auditing Recommendation
Finally, I’ll write up my “Formal Auditing Recommendation” in which I identify those functions that expose non-trivial vulnerabilities and suggest that they either be formally audited or rewritten in order to preclude those vulnerabilities. Only the client and their development team can determine which option is most appropriate. As a general rule, though, you want your smart contract to require as few proofs as possible so it’s usually wise to go for the rewrite first and follow that with a second smart contract audit.
Auditing and testing are the pillars of good contract security. If you are handling money in your contracts you should definitely seek out those services from experts. And, if you are looking for some experts in blockchain solutions, you’re always welcome to reach out to my team at web3devs!
The terms “cryptocurrency”, “coin”, and “token” tend to be thrown around pretty interchangeably. In a lot of cases, a coin and a token don’t seem any different at all. If you log into your favorite cryptocurrency exchange, they will be all mixed together in a giant list and behave exactly the same. However, behind the scenes, they are operating very differently. If you are planning on creating your own cryptocurrency, it’s important to know the differences. Depending on your needs, coin or token creation can drastically change your project scope, the type of users your project appeals to, and especially the way it is used.
Keep in mind that there is no central body anywhere defining these terms, the definitions and distinctions tend to come from general community consensus, so all of these terms can be somewhat fluid, but based on web3devs’ interaction with various blockchain communities around the Internet, we’re pretty confident these terms represent the current consensus. Blockchain tech changes fast, though, so don’t hesitate to reach out and correct us if you’re reading this at a later date and things have changed.
The term “cryptocurrency” is a fairly broad term. Out of the three terms we’re defining here, this one is probably the most ambiguous. The traditional definition was that a cryptocurrency is a digital currency that utilizes blockchain technology, which in turn uses cryptography to verify transactions. In the past few years, though, we’ve seen really interesting projects like Iota, which doesn’t even use a blockchain! These days, people typically use the term “cryptocurrency” as any digital currency which uses cryptographic techniques of some kind in place of a centralized party to verify transactions.
Coins are a type of cryptocurrency. Once again, these definitions are somewhat vague and fluid, but generally, coins represent cryptocurrencies with their own blockchain and completely independent ledger of all the transactions since the creation of the coin. Bitcoin, Dogecoin, Litecoin, Dash, etc. are all coins since they exist independent of any other blockchain. Because of that, each coin will typically have its own suite of software like wallets and miners. If it’s not explicitly mentioned, a good way to tell if a project is a coin or token is to go to its website. If there’s a big “download wallets” button front-and-center, it’s probably a coin and not a token.
When people talk about tokens, they are usually referring to a currency that is built on top of an existing blockchain. More often than not, they are specifically referring to a smart contract that exists on the Ethereum network. Tokens like Golem and Augur do not have their own blockchain. They are simply a smart contract on the Ethereum network that maintains the tokens’ balances for users that already exist on the Ethereum network. These typically are built according to certain standards, most likely what’s referred to as the ERC20 token standard, but more and more are being built on the new ERC721 standard. These tokens will most likely not have their own wallets, since the Ethereum infrastructure supports all of this functionality out of the box for any tokens built with and Ethereum smart contract. Because tokens are smart contracts, they are generally used as a component of a decentralized application and have other aspects rather than simple financial transactions. If you go to a project’s website, and there’s very little being said about sending and receiving money, and a lot of copy dedicated to something non-financial, it’s most likely a token.
Fungible vs. Non-fungible
The main difference between the two most popular types of tokens (ERC20 and ERC721) is an issue of fungibility. Fungibility is the aspect of whether or not any given token is completely interchangeable with another. In the case of ERC20, individual tokens are all exactly the same. If you have one Ether and I have one Ether and we trade, absolutely nothing will change (technically, there will be a state change on the chain, but for all intents and purposes, everything will still look exactly the same). In fact, in ERC20 contracts, each person’s amount of currency is just tallied in a list. This is very different from the bitcoin protocol where transactions are tracked to specific coins.
In the ERC721 standard, tokens are not completely interchangeable. The famous example of a non-fungible token is Cryptokitties. Each cryptokittie is a single ERC721 token. The cryptokittie you have and the one I have are distinct and unique. If we switch, it’s not as simple as updating our totals on a balance sheet, we will have a completely different item.
Neither standard is necessarily better or worse than the other, they are simply different and work well for different types of use cases.
Creating your own cryptocurrency
If you’re looking to create your own cryptocurrency, it’s important to understand the tradeoffs of both coins and tokens. Creating a coin is a much more intensive project, but it is much more customizable since you’re not constrained by another project’s protocols. However, if you don’t need much customization, if you just need a cryptocurrency that can send and receive, a token is probably the way to go as the entire infrastructure to use that currency is already there.
web3devs provides a cryptocurrency creation service if you are ready to start on creating a coin today.
I have a confession to make. The conspiracy theorists are going to run wild with this one. The truth is my father worked in the banking industry (I promise I’m not some establishment plant sent to infiltrate the blockchain industry… isn’t that what an establishment plant would say though??). For most of my dad’s career he worked as an IT manager for some of the major banks around the world. It always seemed like a pretty sweet gig. Working on banker’s hours, he was home at 5:30 on the dot every single weekday. No late nights, no weekends…
Except for one week every year. The dreaded week that came each and every year where they would deploy all the code they’d been working on for an entire year all at once. Yes, that’s right, they would deploy everything from an entire year all at once. He’d be on-call 24 hours for days just in case something went wrong. It would always be a very stressful time. But you know what? It generally went pretty smoothly.
Now, don’t get me wrong, I’m not advocating for waterfall project management. I’m a firm believer in agile methodology. But I also think there are some important lessons we can learn from those days. The reason they deployed code so infrequently is that they had to make absolutely, 100% sure that everything worked. The startup philosophy of “move fast and break things” could not be their motto. Why?
Because their software was managing large amounts of other people’s money.
Sound familiar? They had zero room for error. And they would almost always accomplish that. How? Waterfall development emphasizes two very important things that the world of blockchain development seems to have completely forgotten about: DevOps and QA.
DevOps is the concept of managing the environment your code is running in and how you deliver that code to various environments — basically the “everything else” of writing software besides the code itself. This is a completely different skill set than computer programming. In a small startup team, many companies can get away with their lead developer handling many of these tasks, but you would never see that in mature companies — especially a mature company in the finance industry.
QA is the concept of testing that deployed code functionally and making absolutely, positively sure that everything is working as expected — in fact, during the QA process you generally want to try to break things just to see how your system will respond. If you go through the entire QA process and find nothing broken, you probably don’t know what you’re doing. This is also a highly specialized skill. You cannot expect someone who is a great computer programmer to necessarily just “fill in” on the QA side of things and expect that person to be good at it. In fact, I would argue that a programmer cannot test their own code adequately, no matter their skill level. No matter how hard they try to look at a product objectively, the person that actually built that product will subconsciously only be looking at the “happy path”. To find an error in a product you’ve created is emotionally painful. As humans, our brains jump through every hoop we can find to avoid pain. Even if that hoop is subconsciously not clicking on something we know may not completely work. You need QA people testing that aren’t afraid to hurt the developer’s feelings.
In the blockchain industry, we’ve all seen companies that have raised millions of dollars in a matter of hours. Some of them already have established teams of dozens of developers. But how often have you seen any of these teams with even one person dedicated to DevOps and even one person dedicated to QA? I’ll tell you how many times I’ve seen it: zero.
So, these blockchain companies don’t have experts on their teams in managing how their code gets to production environments; they don’t have experts on their teams to even set up those production environments; and they don’t have experts on their teams to thoroughly test these environments once they’re up and running. But what they are doing is…
Managing large amounts of other people’s money.
In the web development world, we’ve slowly but surely starting stealing some of the best parts of the waterfall methodology and integrating them into agile. The realization of the importance of DevOps and QA has exploded in the last ten years. However, all of these web developers jumping into blockchain seem to have completely forgotten all of that progress. And we’ve all seen the results. The Parity “hacks”(maybe links) were a great example. Neither of those were hacks. They were both poorly written code that a good QA person would definitely have found. Somebody from the general public then started poking around and doing something “they weren’t supposed to do.” Guess what? There will always be people doing random shit on your platform that you didn’t intend for them to do. That’s just the way the world is.
The way the industry is shaping up is to crowd source QA to the general public. This method can work for some dumb social media site or something like that. But that’s not what we’re doing in blockchain. The blockchain industry is a part of the finance industry and we need to realize there’s a reason fintech does things the way they do. Every single Dapp, every single project, every single contract is managing people’s hard-earned money. We need to mature as an industry and realize that’s the situation we’re in and stop shooting from the hip with our code deployments and testing. The methodology is out there. It works. It’s worked for decades. Commit to using it.
Oh, did I mention web3devs now offers DevOps and QA services? 🙂 Shoot us an email to discuss.
Truffle is a very new framework for building ÐApps and debugging can be a little more difficult than just googling StackOverflow. To save you hours of cursing and table flipping, here is a list of debugging techniques that you should always try first.
Web3devs’ own Aaron Anderson gives us some advice on debugging Truffle projects for DApps using Solidity on Ethereum: https://medium.com/@andersonmmi/basic-debugging-techniques-for-truffle-development-e98cd5e358dc
web3devs and Blockchain901 are teaming up to continue their free, open-to-the-public Ethereum programming series.
Over the next few months, we’re going to be holding several Hack Nights to help people put together their own dApps using a combination of Solidity smart contract programming and web development.
There’s no need to be a programmer to attend, we’re confident we can teach anyone to code!
Just bring your laptop and an appetite (there will be pizza).
Here’s the link to the Meetup event (please RSVP)
The official Hack Night description:
This Hack Night will be the kickoff for the next few months of project-based work where we learn together how to create a full product people can use, not just a smart contract or dApp. We need more than just developers to get these products done, so come on out no matter your skill set. If you’ve got an idea for a product, bring that too! We’ll pitch ideas and form teams for the months ahead.
CryptoNote is an open source project that gives developers a good starting point for building their own cryptocurrency.
It’s used in a lot of the biggest cryptocurrency projects today like Monero and AEON.
You may be familiar with the way cryptocurrencies like bitcoin are not fully anonymous, but what us in the biz call pseudo-anonymous. That means that if you have someone’s public address (the long string of characters you need to actually send them money) you can look up the history of every transaction that person has ever done with that address and the addresses that they’ve sent and received bitcoin to and from since it’s all recorded on an immutable blockchain.
Using a lot of pretty advanced math and cryptography, CryptoNote allows for fully anonymous transactions, meaning even if you have someone’s public address, you can’t see all of their previous transactions — even though it’s all still stored on an immutable blockchain.
It’s pretty crazy stuff, but it works and can be verified mathematically.
Anyway, web3 dev Brian noticed that some of their C++ code specific to the Mac OS platform was a little outdated and wasn’t compiling correctly on the latest version of Mac OS. He found two changes that seemed to do the trick and requested his updated code be merged in. Before long, the CryptoNote team approved his changes and merged them into their codebase.
You can see the merge here.
Before too long, those changes should be picked up by many of the popular privacy-based cryptocurrencies out there.
P.S. The last time Brian got some code approved for a major blockchain open source project was with the popular Ethereum framework Truffle, where he fixed a small grammar error in their documentation. With that tiny little contribution he walked around the office for months calling himself a “Truffle contributor”, so we’ll see how much this more substantial open source contribution goes to his head :/