Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signed SafeMath #1559

Merged
merged 10 commits into from
Dec 18, 2018
63 changes: 58 additions & 5 deletions contracts/math/SafeMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ pragma solidity ^0.4.24;
* @dev Math operations with safety checks that revert on error
*/
library SafeMath {
int256 constant private INT256_MIN = -2**255;
frangio marked this conversation as resolved.
Show resolved Hide resolved

/**
* @dev Multiplies two numbers, reverts on overflow.
* @dev Multiplies two unsigned integers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
Expand All @@ -23,7 +25,26 @@ library SafeMath {
}

/**
* @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
* @dev Multiplies two signed integers, reverts on overflow.
*/
function mul(int256 a, int256 b) internal pure returns (int256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}

require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below

int256 c = a * b;
require(c / a == b);

return c;
}

/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
Expand All @@ -35,7 +56,19 @@ library SafeMath {
}

/**
* @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
* @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
*/
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0); // Solidity only automatically asserts when dividing by 0
require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow

int256 c = a / b;

return c;
}

/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
Expand All @@ -45,7 +78,17 @@ library SafeMath {
}

/**
* @dev Adds two numbers, reverts on overflow.
* @dev Subtracts two signed integers, reverts on overflow.
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a));

return c;
}

/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
Expand All @@ -55,7 +98,17 @@ library SafeMath {
}

/**
* @dev Divides two numbers and returns the remainder (unsigned integer modulo),
* @dev Adds two signed integers, reverts on overflow.
*/
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a));

return c;
}

/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
Expand Down
28 changes: 23 additions & 5 deletions contracts/mocks/SafeMathMock.sol
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
pragma solidity ^0.4.24;


import "../math/SafeMath.sol";


contract SafeMathMock {
function mul(uint256 a, uint256 b) public pure returns (uint256) {
function mulUints(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMath.mul(a, b);
}

function div(uint256 a, uint256 b) public pure returns (uint256) {
function mulInts(int256 a, int256 b) public pure returns (int256) {
return SafeMath.mul(a, b);
}

function divUints(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMath.div(a, b);
}

function divInts(int256 a, int256 b) public pure returns (int256) {
return SafeMath.div(a, b);
}

function sub(uint256 a, uint256 b) public pure returns (uint256) {
function subUints(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMath.sub(a, b);
}

function subInts(int256 a, int256 b) public pure returns (int256) {
return SafeMath.sub(a, b);
}

function add(uint256 a, uint256 b) public pure returns (uint256) {
function addUints(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMath.add(a, b);
}

function addInts(int256 a, int256 b) public pure returns (int256) {
return SafeMath.add(a, b);
}

function mod(uint256 a, uint256 b) public pure returns (uint256) {
function modUints(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMath.mod(a, b);
}
}
2 changes: 2 additions & 0 deletions test/helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ const BigNumber = web3.BigNumber;
module.exports = {
ZERO_ADDRESS: '0x0000000000000000000000000000000000000000',
MAX_UINT256: new BigNumber(2).pow(256).minus(1),
MAX_INT256: new BigNumber(2).pow(255).minus(1),
MIN_INT256: new BigNumber(2).pow(255).times(-1),
};
Loading