[Ethereum] How does the SafeMath library of OpenZeppelin protect your code from integer overflow

openzeppelinsolidity

Sorry for the newb question. I am reading the SafeMath code and it seems that it just does some multiplications and calculations?

How do you use it to protect your code? Do you just import it?

Best Answer

How do you use it to protect your code?

Functions of SafeMath check logic conditions of math operations.

function sub(uint256 a, uint256 b...
   assert(b <= a); // otherwise, subtracting b when (b > a) will cause integer underflow

function add(uint256 a, uint256 b...
    uint256 c = a + b;
    assert(c >= a); // if the addition will cause overflow, the values will start from 0 and c will be less than a

Do you just import it?

Three steps are required to correctly implement SafeMath in your contract:

  1. Import the library at the top of your code.
  2. Declare that you wish to attach the library functions to the uint256 type:

    using SafeMath for uint256;

  3. Replace each of the standard arithmetic operators in your code with the equivalent call to a SafeMath function:

    • a + b becomes a.add(b)
    • a - b becomes a.sub(b)
    • a * b becomes a.mul(b)
    • a / b becomes a.div(b)

If you omit the last step, as seems to be quite common when people are first starting out with smart contracts, then your code receives no protection whatsoever from overflows/underflows. It is just the same as if you had not included SafeMath at all. This can be verified by testing the following code:

import "./SafeMath.sol";

contract TestSafeMath {
    using SafeMath for uint256;

    function unsafeSubtract() public pure returns (uint256) {
        uint256 a = 0;
        return a - 1;
    }

    function safeSubtract() public pure returns (uint256) {
        uint256 a = 0;
        return a.sub(1);
    }
}

Even though the library has been imported, and the using statement declared, calling the first function will still return the enormously large integer value 115792089237316195423570985008687907853269984665640564039457584007913129639935, or hex FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, whereas the second function will correctly throw an exception to prevent the underflow.

Related Topic