Going to deploy a smart contract? Wait, You need to see this.

Prashant Prabhakar Singh
Sofocle Technologies
3 min readNov 17, 2017

So you have written a Smart Contract and ready to deploy it. Kudos. But before going live just make sure you have not made any of the given mistakes.

The motive of this article came from a friend who has lost some 5000 ethers due to poor design of smart contract.

Note: The points I am going to discuss came from my own or other’s experience.

Let’s just directly jump to the bullet points.

# Implement a fallback function.

If you don’t want your smart contract to receive ethers, implement a fallback function. This will prevent the accidental sending of ethers to your contract.

You need to understand that if you have not written a method to transfer ethers/tokens from contract to an external address, then the ethers/tokens send to that smart contract will result into permanent loss of ethers/tokens.

Just write this simple piece of code and you will be saved from a blunder that may let you lose millions.

/* This unnamed function is called whenever someone tries to send ether to it */
function () {
revert(); // Prevents accidental sending of ether
}

# Check for overflow and underflow

Checking for overflow is one of the most important concepts that newbies in solidity miss if they don’t read the documentation.

You must always check for overflows while performing arithmetic operations. Have a look at fantastic library implemented by zeppelin: SafeMath.sol.

Let’s understand first What is overflow?

Overflow and underflow are quite common in other languages as well. The datatypes used in solidity have some range (lower limit- upper limit). Any value that surpasses upper-limit gets rolled over. Underflow is just opposite of overflow.

Didn’t get it yet? Let’s understand through some code.

pragma solidity ^0.4.16;contract TestOverflow{
address public owner;
mapping (address => uint8) balanceOf;

function TestOverflow(){
owner = msg.sender;
balanceOf[msg.sender] = 255;
}

function getBalanceOf(address _addr) constant returns(uint){
return balanceOf[_addr];
}

function mintToken(address _target, uint8 mintedAmount){
balanceOf[_target] += mintedAmount;
}
}

In solidity, the limit of uint8 is 0–255. As you can see we already assigned an upper limit to the balance of owner. Now if try to mintToken to owner’s account, the value will overflow. For eg, if you call mintToken function with _target = owner and _value = 2, the balance of the owner will be 1 and not 257 as you might be expecting. This is due to the overflow of value. (255+1 = 0, 255+2 =1, with uint8 datatype). I hope now this is making sense, right?

The problem is not with addition but also with other arithmetic calculations as well. Now how to avoid overflow?

I strongly recommend using SafeMath.sol. But if you don’t want to use this directly, you can have a look at their code and implement it in your smart contract as per your need.

For the above case that I mentioned, you just need to add a single line in mintToken function to check for overflows.

function mintToken(address _target, uint8 mintedAmount){
// check for overflow
require (balanceOf[_target] + mintedAmount > balanceOf[_target]);
balanceOf[_target] += mintedAmount;
}

# State constant variables are initialized every time.

This goes as documented. The compiler doesn’t reserve any storage for the constant variables but replaces every occurrence of the variable by the constant value.

State variables can be declared as constant […] This has the effect that the compiler does not reserve a storage slot for these variables and every occurrence is replaced by their constant value.

Let’s see some code in practice:

pragma solidity ^0.4.16;contract TestConstantVar{
uint constant var1=now;
uint var2=now;
function checkConstant() returns(uint,uint){
return (var1,var2);
}
}

In this case, var2 will always return the time when the smart contract was deployed, but var1 returns the time when the function is called. This is because once the smart contract is created the timestamp was saved in var2 but no memory was reserved for var1. When you call checkConstant() function, var2 is returned as it was stored but var1 is replaced by now and thus returns the timestamp of when this return statement was executed.

That’s all I have in mind now. I will keep on updating this story whenever I’ll come across such cases which one might miss but which shouldn’t be missed.

--

--

Prashant Prabhakar Singh
Sofocle Technologies

Team lead at @SofocleTechnologies (www.sofocle.com) #Ethereum Developer #Blockchain Enthusiast