Created
August 14, 2020 21:55
-
-
Save PaulRBerg/4d7cb0873ed99dcd34df50fffb54dbb2 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.6.10+commit.00c0fcaf.js&optimize=true&gist=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* SPDX-License-Identifier: LGPL-3.0-or-later */ | |
pragma solidity ^0.6.10; | |
/** | |
* @title CarefulMath | |
* @author Compound | |
* @notice Exponential module for storing fixed-precision decimals. | |
* @dev Derived from OpenZeppelin's SafeMath library | |
*/ | |
abstract contract CarefulMath { | |
/** | |
* @notice Possible error codes that can be returned. | |
*/ | |
enum MathError { NO_ERROR, DIVISION_BY_ZERO, INTEGER_OVERFLOW, INTEGER_UNDERFLOW, MODULO_BY_ZERO } | |
/** | |
* @notice Adds two numbers, returns an error on overflow. | |
*/ | |
function addUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) { | |
uint256 c = a + b; | |
if (c >= a) { | |
return (MathError.NO_ERROR, c); | |
} else { | |
return (MathError.INTEGER_OVERFLOW, 0); | |
} | |
} | |
/** | |
* @notice Add `a` and `b` and then subtract `c`. | |
*/ | |
function addThenSubUInt( | |
uint256 a, | |
uint256 b, | |
uint256 c | |
) internal pure returns (MathError, uint256) { | |
(MathError err0, uint256 sum) = addUInt(a, b); | |
if (err0 != MathError.NO_ERROR) { | |
return (err0, 0); | |
} | |
return subUInt(sum, c); | |
} | |
/** | |
* @notice Integer division of two numbers, truncating the quotient. | |
*/ | |
function divUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) { | |
if (b == 0) { | |
return (MathError.DIVISION_BY_ZERO, 0); | |
} | |
return (MathError.NO_ERROR, a / b); | |
} | |
/** | |
* @notice Returns the remainder of dividing two numbers. | |
* @dev Reverts with custom message when dividing by zero. | |
* | |
* Counterpart to Solidity's `%` operator. This function uses a `revert` | |
* opcode (which leaves remaining gas untouched) while Solidity uses an | |
* invalid opcode to revert (consuming all remaining gas). | |
*/ | |
function modUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) { | |
if (b == 0) { | |
return (MathError.MODULO_BY_ZERO, 0); | |
} | |
return (MathError.NO_ERROR, a % b); | |
} | |
/** | |
* @notice Multiplies two numbers, returns an error on overflow. | |
*/ | |
function mulUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) { | |
if (a == 0) { | |
return (MathError.NO_ERROR, 0); | |
} | |
uint256 c = a * b; | |
if (c / a != b) { | |
return (MathError.INTEGER_OVERFLOW, 0); | |
} else { | |
return (MathError.NO_ERROR, c); | |
} | |
} | |
/** | |
* @notice Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend). | |
*/ | |
function subUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) { | |
if (b <= a) { | |
return (MathError.NO_ERROR, a - b); | |
} else { | |
return (MathError.INTEGER_UNDERFLOW, 0); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* SPDX-License-Identifier: LGPL-3.0-or-later */ | |
pragma solidity ^0.6.10; | |
import "./CarefulMath.sol"; | |
contract CarefulMathShowcase is CarefulMath { | |
function doMath(uint256 a, uint256 b) external pure returns (uint256) { | |
MathError mathErr; | |
uint256 result; | |
(mathErr, result) = addUInt(a, b); | |
require(mathErr == MathError.NO_ERROR, "BESPOKE_MATH_ERROR"); | |
return result; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* SPDX-License-Identifier: LGPL-3.0-or-later */ | |
pragma solidity ^0.6.10; | |
/** | |
* @title Erc20 | |
* @author OpenZeppelin | |
* @notice Wrappers over Solidity's arithmetic operations with added overflow | |
* checks. | |
* | |
* Arithmetic operations in Solidity wrap on overflow. This can easily result | |
* in bugs, because programmers usually assume that an overflow raises an | |
* error, which is the standard behavior in high level programming languages. | |
* `SafeMath` restores this intuition by reverting the transaction when an | |
* operation overflows. | |
* | |
* Using this library instead of the unchecked operations eliminates an entire | |
* class of bugs, so it's recommended to use it always. | |
*/ | |
library SafeMath { | |
/** | |
* @dev Returns the addition of two unsigned integers, reverting on | |
* overflow. | |
* | |
* Counterpart to Solidity's `+` operator. | |
* | |
* Requirements: | |
* - Addition cannot overflow. | |
*/ | |
function add(uint256 a, uint256 b) internal pure returns (uint256) { | |
uint256 c = a + b; | |
require(c >= a, "SafeMath: addition overflow"); | |
return c; | |
} | |
/** | |
* @dev Returns the subtraction of two unsigned integers, reverting on | |
* overflow (when the result is negative). | |
* | |
* Counterpart to Solidity's `-` operator. | |
* | |
* Requirements: | |
* - Subtraction cannot overflow. | |
*/ | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
return sub(a, b, "SafeMath: subtraction overflow"); | |
} | |
/** | |
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on | |
* overflow (when the result is negative). | |
* | |
* Counterpart to Solidity's `-` operator. | |
* | |
* Requirements: | |
* - Subtraction cannot overflow. | |
*/ | |
function sub( | |
uint256 a, | |
uint256 b, | |
string memory errorMessage | |
) internal pure returns (uint256) { | |
require(b <= a, errorMessage); | |
uint256 c = a - b; | |
return c; | |
} | |
/** | |
* @dev Returns the multiplication of two unsigned integers, reverting on | |
* overflow. | |
* | |
* Counterpart to Solidity's `*` operator. | |
* | |
* Requirements: | |
* - Multiplication cannot 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-contracts/pull/522 | |
if (a == 0) { | |
return 0; | |
} | |
uint256 c = a * b; | |
require(c / a == b, "SafeMath: multiplication overflow"); | |
return c; | |
} | |
/** | |
* @dev Returns the integer division of two unsigned integers. Reverts on | |
* division by zero. The result is rounded towards zero. | |
* | |
* Counterpart to Solidity's `/` operator. Note: this function uses a | |
* `revert` opcode (which leaves remaining gas untouched) while Solidity | |
* uses an invalid opcode to revert (consuming all remaining gas). | |
* | |
* Requirements: | |
* - The divisor cannot be zero. | |
*/ | |
function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
return div(a, b, "SafeMath: division by zero"); | |
} | |
/** | |
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on | |
* division by zero. The result is rounded towards zero. | |
* | |
* Counterpart to Solidity's `/` operator. Note: this function uses a | |
* `revert` opcode (which leaves remaining gas untouched) while Solidity | |
* uses an invalid opcode to revert (consuming all remaining gas). | |
* | |
* Requirements: | |
* - The divisor cannot be zero. | |
*/ | |
function div( | |
uint256 a, | |
uint256 b, | |
string memory errorMessage | |
) internal pure returns (uint256) { | |
// Solidity only automatically asserts when dividing by 0 | |
require(b > 0, errorMessage); | |
uint256 c = a / b; | |
// assert(a == b * c + a % b); // There is no case in which this doesn't hold | |
return c; | |
} | |
/** | |
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), | |
* Reverts when dividing by zero. | |
* | |
* Counterpart to Solidity's `%` operator. This function uses a `revert` | |
* opcode (which leaves remaining gas untouched) while Solidity uses an | |
* invalid opcode to revert (consuming all remaining gas). | |
* | |
* Requirements: | |
* - The divisor cannot be zero. | |
*/ | |
function mod(uint256 a, uint256 b) internal pure returns (uint256) { | |
return mod(a, b, "SafeMath: modulo by zero"); | |
} | |
/** | |
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), | |
* Reverts with custom message when dividing by zero. | |
* | |
* Counterpart to Solidity's `%` operator. This function uses a `revert` | |
* opcode (which leaves remaining gas untouched) while Solidity uses an | |
* invalid opcode to revert (consuming all remaining gas). | |
* | |
* Requirements: | |
* - The divisor cannot be zero. | |
*/ | |
function mod( | |
uint256 a, | |
uint256 b, | |
string memory errorMessage | |
) internal pure returns (uint256) { | |
require(b != 0, errorMessage); | |
return a % b; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* SPDX-License-Identifier: LGPL-3.0-or-later */ | |
pragma solidity ^0.6.10; | |
import "./SafeMath.sol"; | |
contract SafeMathShowcase { | |
using SafeMath for uint256; | |
function doMath(uint256 a, uint256 b) external pure returns (uint256) { | |
uint256 result = a.add(b); | |
return result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment