85 lines
2.1 KiB
Solidity
85 lines
2.1 KiB
Solidity
|
pragma solidity >=0.5.17;
|
||
|
|
||
|
/**
|
||
|
* @title Careful Math
|
||
|
* @author Compound
|
||
|
* @notice Derived from OpenZeppelin's SafeMath library
|
||
|
* https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol
|
||
|
*/
|
||
|
contract CarefulMath {
|
||
|
/**
|
||
|
* @dev Possible error codes that we can return
|
||
|
*/
|
||
|
enum MathError {
|
||
|
NO_ERROR,
|
||
|
DIVISION_BY_ZERO,
|
||
|
INTEGER_OVERFLOW,
|
||
|
INTEGER_UNDERFLOW
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev Multiplies two numbers, returns an error on overflow.
|
||
|
*/
|
||
|
function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {
|
||
|
if (a == 0) {
|
||
|
return (MathError.NO_ERROR, 0);
|
||
|
}
|
||
|
|
||
|
uint c = a * b;
|
||
|
|
||
|
if (c / a != b) {
|
||
|
return (MathError.INTEGER_OVERFLOW, 0);
|
||
|
} else {
|
||
|
return (MathError.NO_ERROR, c);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev Integer division of two numbers, truncating the quotient.
|
||
|
*/
|
||
|
function divUInt(uint a, uint b) internal pure returns (MathError, uint) {
|
||
|
if (b == 0) {
|
||
|
return (MathError.DIVISION_BY_ZERO, 0);
|
||
|
}
|
||
|
|
||
|
return (MathError.NO_ERROR, a / b);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).
|
||
|
*/
|
||
|
function subUInt(uint a, uint b) internal pure returns (MathError, uint) {
|
||
|
if (b <= a) {
|
||
|
return (MathError.NO_ERROR, a - b);
|
||
|
} else {
|
||
|
return (MathError.INTEGER_UNDERFLOW, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev Adds two numbers, returns an error on overflow.
|
||
|
*/
|
||
|
function addUInt(uint a, uint b) internal pure returns (MathError, uint) {
|
||
|
uint c = a + b;
|
||
|
|
||
|
if (c >= a) {
|
||
|
return (MathError.NO_ERROR, c);
|
||
|
} else {
|
||
|
return (MathError.INTEGER_OVERFLOW, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev add a and b and then subtract c
|
||
|
*/
|
||
|
function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {
|
||
|
(MathError err0, uint sum) = addUInt(a, b);
|
||
|
|
||
|
if (err0 != MathError.NO_ERROR) {
|
||
|
return (err0, 0);
|
||
|
}
|
||
|
|
||
|
return subUInt(sum, c);
|
||
|
}
|
||
|
}
|