district0x Token and Token Offering Audit
For the last couple of weeks, I’ve been reviewing district0x’s token offering smart contracts.
The last commit reviewed was: 650eec2851bb3b9fe20f2d66c9155476f788ee5a at https://github.com/district0x/district0x-network-token
I’ve been working closely with the district0x developers, they had the code in a good place when I started my audit, the code was of a high quality, complete, well commented, clean, and had very few issues to address. However, I advised them to make some changes to minimize any potential issues that could arise and aided in the final design changes to be made before freezing the code.
The main changes that occurred were:
- Simplification of the code.
- Implementing standard contracts that have already been well tested like the ConsenSys Multisig and the MiniMe Token.
- Added some safety mechanisms in order to extract unexpected tokens sent to the contracts.
At this point, I don’t see any issues that can affect the security of funds sent to these smart contracts.
It is worth mentioning that the ether sent to the contract will be forwarded to the district0x multisig to protect the ether at all times in a proven contract.
All transactions that move ether and tokens are logged in the blockchain, so in the worst case scenario (however unlikely), it will always be possible to reconstruct the correct token balances, it is not possible to do this with ether, and is one of the most important design conditions to be included in every token offering.
The core of the token contract is based on the MiniMe Token (an ERC20 clonable token). This token was developed by myself and has been successfully implemented in important projects like Status.im, Aragon, Swarm City and Giveth.io for months now.
This makes the probability of losing any ether even if there is an unseen issue in these contracts very low.
Most important facts that all contributors must know
- The collected ether will go to the district0x multisig `multisigWallet`controlled by a series of accounts that can move the ether wherever they desire. This is standard in all token offerings but it’s important to know who will control this multisig as there is trust involved.
- This contract has a maximum gasPrice of 50 Gwei, any transaction with a higher price WILL THROW and the entirety of any gas attached to this transaction will be sent to the miners.
- The tokens will be transferred to the contributors accounts AFTER the contribution period has finished. So don’t worry if you don’t see the tokens during the contribution period, it is expected.
- Transfers will be enabled by the owner of the contract. This implies that users must trust that the owner will do it.
Some notes for the more technically minded.
50 Gwei gasPrice MAX
The district0x team has decided to set a maximum limit of 50 Gwei for gas price of these transactions. This decision has already been used in other contracts like Bancor and Status.
This choice has advantages and disadvantages:
The biggest advantage is that during the contribution period the Ethereum community is still able to use the network to reveal ENS bids and do other time sensitive actions if they are willing to pay a higher gasPrice than 50 Gwei.
The biggest disadvantage is that whales with technical expertise (now that using a high gasPrice to get an advantage is no longer possible) are incentivized to split their contribution into many transactions to have a probabilistic advantage by flooding the transaction pool.
Considering this, and the experience of the Status.im contribution where I was the main author of the smart contracts, my recommendation would be to remove this limitation.
From my point of view, the vesting functionality should be implemented as a separate contract, as opposed to within the token contract. This functionality adds a lot of lines to the contract that very few people will use. So in the unlikely chance that there is an unseen vulnerability it would be better if it were separated from the critical token contract.
The benefit of keeping this functionality in the contract is that it’s much easier for the user to manage their vested tokens, because they are treated as normal tokens.
Limitations of this work
I didn’t audit the ConsenSys Multisig wallet.
I didn’t make any low level reviews of the assembly code generated by the solidity compiler.
I didn’t make any tests for this code. Just read the code and commented on all of the issues that I found.
I didn’t verify the deployment of the contract.
I just made an audit of the smart contracts. I’m not making any evaluation of the project or the people leading the project.
Smart contract security audits like this one, reduce the risks of the smart contracts issues, but they do not warranty bug-free code. I encourage the community, especially the district0x community that will be using these contracts, to continue to analyze them to inform themselves before interacting with these or any other smart contracts..