back

ICO audit in 3 days – is it possible? Let’s find out!

18.3.2019

A few weeks ago we’ve been contacted by a company which planned to conduct an ICO and asked to perform an audit of their code. The idea around the coin sounded really ingenious – the token was supposed to be a utility token which would connect all participants of the global logistics ecosystem. It included carriers, suppliers, insurers and all other stakeholders that may be interested in being present on the market.

ICO audit in 3 days sounds impossible but is it really?

The thing is that the development of the code got delayed a little bit and the whole team had only 3 days to conduct the check. Other auditing companies would surely let our friends down but not Blockhunters! We were happy to rise to the challenge and do our best to meet the deadline. Let’s see how we managed to do this crazy task!

Warning: in no way should this article encourage you to plan such little time for conducting an audit for your ICO – especially if you need the whole platform audited, not only the ERC20 / ERC721 mechanism. Please act responsibly and contact Blockhunters or any other auditing companies about possible project scope and time required to get things done properly 🙂

1. Plan your work on the ICO audit

As obvious as it may sound, planning is often underrated by small programming teams when it comes to development work of short timespan. One of the reasons is that most of them work in agile framework, which operates on weekly / 2-weeks sprints so doing a 3-day work just doesn’t even count into the framework. Wrong! If you’re supposed to check the security of your smart contract that will hold thousands or even millions of dollars in the future then you really need to nail down that Gantt chart.

Our client’s project consisted of 5 Ethereum smart contracts:

  • main contract which was a regular ERC20 contract responsible for the token’s operation, using a SafeMath library from OpenZeppelin (really good practice!),
  • 4 lockup contracts for different stakeholders which were responsible for locking mechanism that would only allow the stakeholders access their tokens after a specific period of time. Fortunately all 4 files were based on exactly the same code so our work was to check each chunk of it really (I mean, REALLY) exhaustively.

Our plan was to check all vulnerabilities known from Ethereum network, then each of the methods separately together with all state and local variables. We were only supposed to audit the ICO mechanism, not the platform itself – which surely wouldn’t be possible in such short time.

We’ve divided our work into 4 simple stages:

1. Preparation and listing of smart contract methods and variables for our final report. (around 6 hours)
2. Checking vulnerabilities known from other Eth projects. (another 6 hours)
3. Verifying each method and state / local variable. (10 hours at least)
4. Final checks and some brainstorming on how to break the smart contracts even further.

Overall we’ve managed to conduct the ICO audit in a little bit more than 24 working hours (3 x 8 hours a day) having 3 team-members focused fully on that project.

2. Check vulnerabilities known from Ethereum ecosystem

All the following vulnerabilities have been known in Ethereum world for ages (block-wise 🙂 ) but you always should assume that they were not and check them again:

  • Reentrancy attack
  • Race conditions
  • Integer over / underflow
  • Timestamp
  • Library dependencies
  • Front-running attack
  • Insufficient gas griefing

So, the good thing is that our client had a really good developer (cheers man, nice clean code!) and he decided to use SafeMath library from OpenZeppelin which helped a lot! There was no way for integer over / underflows or library dependencies errors to happen in that case. Conclusion? Use SafeMath for your own safety 🙂

Moreover, the token mechanism was purely based on ERC20 standard, which also helps in conducting the check. Most developers are accustomed to ERC20 / ERC721 frameworks so if the ICO’s based on that then you can expect the workload to be significantly lower. Of course this only concerns the token economy methods, not the platform or business model itself – these require far more work and doing some business assessment. You can read about that in our other article about doing an ICO review.

3. Check all the methods. And variables.

The second part of the ICO audit included checking all the methods in main smart contract (roughly 40 of them) and in lockup contracts (around 20) together with all the variables (this one was important, as we learned afterwards).

Checking a method includes deploying the contract on the TestNet and fiddling a little bit with it – the more arguments it can receive, the more time you need to spend on that one. Things get really complicated when you have a lot of them (and especially when these are arrays) and the method itself calls other numerous methods with other numerous variables. The number of combinations where things can go wrong grows exponentially 🙂 That’s where our inhouse automatic tools prove really useful and save a lot of handwork.

Happily for us the code was clean and nice so what we did was test each method with different inputs – highest, lowest possible, etc. and then check its output. What we’ve learned was that one of the most important functions of lockup mechanism didn’t work as intended. In the code there were two TokenTimelock contract instances, both with the same variable. One of these instances set up its variable value while the other one was passing its own variable of the same name to another method. Unfortunately, the second instance, having its own variable with the same name had it uninitialized (it only had value in the first instance) which ended up in always passing a 0x0 address to the method.

This mechanism is commonly known as variable shadowing and can sometimes be tricky to spot – even if you write a nice and clean code. In this case it didn’t let the tokens to be transferred after the lockup period. Once the smart contract was published this way, the tokens would be held there forever with their future owners having no possibility to receive them whatsoever. That would be a really ugly surprise for the team and other stakeholders!

If you need any help with nasty code – contact us! Blockhunters are always willing to help in the wild wild west of blockchain 🙂