On April 25, 2018, OKEX, the third largest Hong Kong-based cryptocurrency exchange in the world was forced to suspend all ERC20 tokens after the developers discovered a bug called BatchOverFlow that made the tokens vulnerable. Malicious parties could generate a large number of tokens and deposit that into a regular address. This would make many of the tokens vulnerable to price manipulation. It is notable that this came at the heels of an exploit that caused users of MyEtherWaller, an ERC20 wallet resource, unwittingly interact with phishing websites which left their funds and information exposed. “While some sources erroneously attributed the attack to weaknesses within MyEtherWallet’s infrastructure, developers subsequently refuted the claims.”
This article will give you an idea about the common vulnerabilities a poorly coded smartcontract can have and the possible solutions to it.
Talk to our experts to make sure your smartcontract is secure.
This occurs when the nature of the system inhibits simultaneous operations when the operations should occur in a proper sequence. Smart contracts are executed only if certain conditions are met, there is a sequence to be followed. If external contracts are called in, it could inadvertently take over the control flow and make changes to the data. It was such a bug that caused the DAO’s collapse. There are different types of race conditions. Reentrancy race condition occurs when functions are called repeatedly before the first invocation of the function was finished. Cross function race conditions can occur when two different functions share the same state in a contract.
Solution: Race conditions can be avoided up to an extent by calling any external function only after the completion of the internal work execution. However, the best option is to avoid calling external functions if possible.
Before any transaction is added in a block by a miner, it is kept in the mempool for a short while. This makes it possible to tell what actions occur before its added to the block. But when it comes to decentralized markets, it goes a bit off; as the market order implemented is seen before the other transaction gets included in the block.
Solution: Securing the contract against this is tough as it boils down to the conditions in the contract itself. Possible options to prevent this vulnerability is to use batch auctions and to use a pre-commit scheme.
Contracts could have timestamp conditions to perform certain actions. The problem is when the miners manipulate them. The Blockchain accounts for the local system’s timestamp which causes a delay of seconds which is sufficient for hostile parties to launch an attack on the contract. This could affect the outcome of timestamp dependent contracts as the miner could then choose a different timestamp.
Solution: You could introduce schemes that require a time commitment. This was proposed by Dan Boneh and Moni Naor and it applies when two mutually distrusting parties wish to swap signatures on a contract. The solution involves a two-party protocol: both parties would invest comparable amounts of time to retrieve their signatures in case one or both decide to leave.
When a miner competes with a smartcontract participant to place their own information stored on the contract. When a participant places his bet, corresponding data is saved on the blockchain and any miner can access it to see the bet number simply by calling a public mapping. Since the condition of the called function isn’t updating until the end of mining, there is a risk of a reordering attack.
Solution: update the condition of the number of bets at the beginning of the distributePrizes() function to avoid this kind of unexpected behavior.
This kind of vulnerability is quite hard to happen. Anyhow, there is a possibility for it to happen. In this type of vulnerability, if the balance token reaches the maximum or minimum unit value, it will circle back to zero or the maximum set limit. If your token’s unit value is favorable for a user to reach the maximum limit of (2^256), then this vulnerability is a concern for you. But for most cases, it is not the case. Also, the ability of a user to update the unit value by calling a function makes the contract vulnerable to attack.
Solution: Implement the system in such a way that only an admin has permission to change the variable’s state. Moreover, the user should be able to increment by only 1 at a time adds extra security as it is not feasible to reach this limit.
This vulnerability of ERC20 tokens was discovered by Golem team. A hacker can create an ethereum wallet address with trailing zeros and buys token from a contract by removing the trailing zeros. If the contract doesn’t check the length of the address of the sender, Ethereum’s virtual machine will just add zeroes to the transaction until the address is complete. This results in returning 256000 tokens for each purchase of 1000 tokens.
Solution: Make sure to add conditions in contract to check the completeness of sender address.
An example would be an auction contract. When a refund is attempted to the previous high bidder and it fails, then it reverts. This opens up a vulnerability when malicious actors could place themselves as the highest bidder by ensuring that all refunds to their address fail and this would prevent anyone else from bidding. It could also be the case with crowdfunding contracts which requires it to iterate through an array to pay users. If one payment fails, then the entire payout would revert.
Solution: You could isolate each payment as one transaction instead of combining them all. This is known as a pull payment system where users can withdraw funds as opposed to pushing the funds to them.
A related problem as the previous point is if you are paying out to a lot of addresses at the same time, then you risk running out the block gas limit which is the maximum amount of computation that can be processed by a block. If that happens, it results in a failed transaction. An attacker could take advantage of this by adding a number of addresses that are due to very small payments. Thing is, the gas cost of these payments end up being more than the limit itself and that would block the refunds altogether.
Solution: Use Pull over push payment system. Isolate the external call into its own transaction which can be initiated by the recipient of the call.
The logic in the contract is designed to disallow payments to the contract unless it is forcibly done. There are quite a few methods to send Ether without activating the fall-back function. Thus, it is possible to make the balance of the contract greater than zero and possibly affect its function if is programmed with a condition which checks the balance in the contract.
Solution: The self-destruct contract method allows a user to target a beneficiary address to send any excess of ether received in a contract. It’s also possible to do this before executing the contract also by precomputing an address into which Ether could be sent.
While smart contract and Blockchain technology is considered very secure and highly immutable, events such as the one at OKEX can be sobering and give us pause. Exercising some caution would allow us to manage the risks associated with this technology and gain the most possible. Make sure your smartcontract is equipped to prevent the above-mentioned vulnerabilities.
We recommend Coin Factory by Accubits - the best ICO platform available in the market to securely conduct your token sales