parent
15c35e6ecd
commit
43f71afcbc
@ -0,0 +1,68 @@ |
||||
// Copyright (c) 2016 Smart Contract Solutions, Inc. |
||||
|
||||
pragma solidity ^0.4.24; |
||||
|
||||
|
||||
/** |
||||
* @title SafeMath |
||||
* @dev Math operations with safety checks that revert on error |
||||
*/ |
||||
library SafeMath { |
||||
|
||||
/** |
||||
* @dev Multiplies two numbers, 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 |
||||
// benefit is lost if 'b' is also tested. |
||||
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 |
||||
if (_a == 0) { |
||||
return 0; |
||||
} |
||||
|
||||
uint256 c = _a * _b; |
||||
require(c / _a == _b); |
||||
|
||||
return c; |
||||
} |
||||
|
||||
/** |
||||
* @dev Integer division of two numbers truncating the quotient, reverts on division by zero. |
||||
*/ |
||||
function div(uint256 _a, uint256 _b) internal pure returns (uint256) { |
||||
require(_b > 0); // Solidity only automatically asserts when dividing by 0 |
||||
uint256 c = _a / _b; |
||||
// assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold |
||||
|
||||
return c; |
||||
} |
||||
|
||||
/** |
||||
* @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). |
||||
*/ |
||||
function sub(uint256 _a, uint256 _b) internal pure returns (uint256) { |
||||
require(_b <= _a); |
||||
uint256 c = _a - _b; |
||||
|
||||
return c; |
||||
} |
||||
|
||||
/** |
||||
* @dev Adds two numbers, reverts on overflow. |
||||
*/ |
||||
function add(uint256 _a, uint256 _b) internal pure returns (uint256) { |
||||
uint256 c = _a + _b; |
||||
require(c >= _a); |
||||
|
||||
return c; |
||||
} |
||||
|
||||
/** |
||||
* @dev Divides two numbers and returns the remainder (unsigned integer modulo), |
||||
* reverts when dividing by zero. |
||||
*/ |
||||
function mod(uint256 a, uint256 b) internal pure returns (uint256) { |
||||
require(b != 0); |
||||
return a % b; |
||||
} |
||||
} |
@ -0,0 +1,31 @@ |
||||
pragma solidity ^0.4.24; |
||||
import "./SafeMath.sol"; |
||||
|
||||
/* |
||||
Using a proxy contract here allows revert-causing functions that contain |
||||
require() to return false rather than halt execution |
||||
https://truffleframework.com/tutorials/testing-for-throws-in-solidity-tests |
||||
*/ |
||||
contract SafeMathProxy { |
||||
using SafeMath for uint; |
||||
|
||||
function divProxy(uint256 a, uint256 b) returns (uint256) { |
||||
return a.div(b); |
||||
} |
||||
|
||||
function mulProxy(uint256 a, uint256 b) returns (uint256) { |
||||
return a.mul(b); |
||||
} |
||||
|
||||
function subProxy(uint256 a, uint256 b) returns (uint256) { |
||||
return a.sub(b); |
||||
} |
||||
|
||||
function addProxy(uint256 a, uint256 b) returns (uint256) { |
||||
return a.add(b); |
||||
} |
||||
|
||||
function modProxy(uint256 a, uint256 b) returns (uint256) { |
||||
return a.mod(b); |
||||
} |
||||
} |
@ -0,0 +1,86 @@ |
||||
pragma solidity ^0.4.24; |
||||
import "./tests.sol"; |
||||
import "./SafeMath.sol"; |
||||
import "./SafeMathProxy.sol"; |
||||
|
||||
contract SafeMathTest { |
||||
SafeMathProxy safemathproxy; |
||||
|
||||
function beforeAll() { |
||||
safemathproxy = new SafeMathProxy(); |
||||
} |
||||
|
||||
function unsafeMultiplicationShouldOverflow() public constant returns (bool) { |
||||
uint256 a = 4; |
||||
uint256 b = 2 ** 256 - 1; |
||||
return Assert.equal( |
||||
a * b, |
||||
2 ** 256 - 4, |
||||
"unsafe multiplication did not overflow" |
||||
); |
||||
} |
||||
|
||||
function safeMultiplicationShouldRevert() public constant returns (bool) { |
||||
uint256 a = 4; |
||||
uint256 b = 2 ** 256 - 1; |
||||
return Assert.equal( |
||||
address(safemathproxy).call.gas(40000).value(0)("mulProxy",[a, b]), |
||||
false, |
||||
"safe multiplication did not revert" |
||||
); |
||||
} |
||||
|
||||
function safeDivisionByZeroShouldRevert() public constant returns (bool) { |
||||
uint256 a = 4; |
||||
uint256 b = 0; |
||||
return Assert.equal( |
||||
address(safemathproxy).call.gas(40000).value(0)("divProxy", [a, b]), |
||||
false, |
||||
"safe division did not revert" |
||||
); |
||||
} |
||||
|
||||
function unsafeSubtractShouldUnderflow() public constant returns (bool) { |
||||
uint256 a = 0; |
||||
uint256 b = a - 1; |
||||
return Assert.equal( |
||||
b, |
||||
2 ** 256 - 1, |
||||
"unsafe subtraction did not underflow" |
||||
); |
||||
} |
||||
|
||||
function safeSubtractShouldRevert() public constant returns (bool) { |
||||
return Assert.equal( |
||||
address(safemathproxy).call.gas(40000).value(0)("subProxy", [0, 1]), |
||||
false, |
||||
"safe subtract should revert" |
||||
); |
||||
} |
||||
|
||||
function unsafeAdditionShouldOverflow() public constant returns (bool) { |
||||
uint256 a = 1; |
||||
uint256 b = 2 ** 256 - 1; |
||||
return Assert.equal(a + b, 0, "unsafe addition did not overflow"); |
||||
} |
||||
|
||||
function safeAdditionShouldRevert() public constant returns (bool) { |
||||
uint256 a = 1; |
||||
uint256 b = 2 ** 256 - 1; |
||||
return Assert.equal( |
||||
address(safemathproxy).call.gas(40000).value(0)("addProxy", [a, b]), |
||||
false, |
||||
"safe addition should revert" |
||||
); |
||||
} |
||||
|
||||
function safeModulusShouldRevert() public constant returns (bool) { |
||||
uint256 a = 1; |
||||
uint256 b = 0; |
||||
return Assert.equal( |
||||
address(safemathproxy).call.gas(40000).value(0)("modProxy", [a, b]), |
||||
false, |
||||
"safe modulus did not revert" |
||||
); |
||||
} |
||||
} |
Loading…
Reference in new issue