Practicing Safemath for Smart Contracts with Solidity and Openzeppelin

View of Navy Pier from the Distributed Confrence

At the beginning of my endevour to learn more about distributed ledger technologies I encountered Solidity but then tried to lookup other smart contract languages like Viper or LLL. I was dead wrong about this assertion because really the leader in the space is Solidity and that it is tightly coupled with Javascript. All EVM languages out there are either prototypes or abandoned prototypes . LLL would be useful as a compile target since it is very close to machine code (it actually reminds me of prescheme in this regard).

So this is my second real Solidity program that I made without using inherits. I was doing the following tutorial (which I recommend) from http://truffleframework.com/tutorials/debugger-variable-inspection . In this tutorial they go over the Fibonacci numbers. I thought that I would also try to take a crack at a similar program. After not figuring out how to write a factorial function in Solidity I decided to try to write a program that computes the Lucas numbers.

First off recall the Fibonacci numbers (1,1,2,3,5…). How this sequence is generated is that you add the last two numbers together and you get the next number. A distinction that you start off with the first two numbers both as 1. The Lucas numbers are an integer sequence similar to the Fibonacci numbers except the starting numbers are $L_1 = 2$ and L_2+1. This gives you the Lucas numbers which are (2,1,3,4,7…).

pragma solidity ^0.4.22;
contract Lucas {
uint[] lucseries;
  // n = how many in the series to return
function generateLuc(uint n) public {
    // set 1st and 2nd entries
lucseries.push(2);
lucseries.push(1);
    // generate subsequent entries
for (uint i=2; i < n ; i++) {
lucseries.push(lucseries[i-1] + lucseries[i-2]);
}
   }
}

This is really a toy implementation. If we want to practice safemath correctly we really need to analyze the program and apply it where needed. Now since we know that the Lucas series similar to the Fibonacci sequence which increases (except for the first number which we are disregarding) we will have to replace the addition in the smart contract into an add using Safemath. Below is the same program but using the safemath library.

pragma solidity ^0.4.22;
import "github.com/OpenZeppelin/zeppelin-solidity/contracts/math/SafeMath.sol";
contract Lucas {

using SafeMath for uint; //
uint[] lucseries;
// n = how many in the series to return
function generateLuc(uint n) public {
// set 1st and 2nd entries
lucseries.push(2);
lucseries.push(1);
// generate subsequent entries
for (uint i=2; i < n ; i++) {
lucseries.push(lucseries[i-1].add( lucseries[i-2]));
}
}
}

Now we get an exception when we want to compute a large list of Lucas numbers. Note, that I didn’t add using add for the subtractions here due to the fact that those would not trigger an underflow but due to the programs design we can trigger an overflow. A exercise for the reader would be to see what happens if you run the above program and see how it throws an exception? I know people actually hate exercises so what actually happens is that it doesn’t overflow. This actually caught me by surprise but it seems like in the Javascript Simulator it gives an error “invalid opcode”. So the program fails during the loop at the 111th iteration.

Computation of the Lucas Number in Solidity fails at the 111th iteration

To see what actually happens when safemath triggers an exception lets just add 2²⁵⁶-1 twice in a simple smart contract.

pragma solidity ^0.4.22;
import "github.com/OpenZeppelin/zeppelin-solidity/contracts/math/SafeMath.sol";
contract Exception {

using SafeMath for uint; //
uint two_to_the_256_power_minus_one = 115792089237316195423570985008687907853269984665640564039457584007913129639935; //2 to the 256 power minus 1
uint more = two_to_the_256_power_minus_one + two_to_the_256_power_minus_one;

}

And here we get the exception we were hoping for!

Practicing Safemath and getting the exception you desire.

We want this exception to trigger instead of integer underflow because that can cause real security flaws and cost you a great deal of money.

Note that I am using syntax that is only found in Remix. When using this in a smart contract that is not in remix you need to include the file by a relative include and it won’t accept a URL.

Anyways, I hope you found this blog post exceptional. Follow me if you want to see more! My upcoming blog posts will be centered around developing a prototype to an ICO so stay tuned!

If you want to donate ETH to me you can at the following address:

0x3DkrzVdJxAaNBmMNjidVR5roNJT9hkPLXN