2020-05-29 16:45:37 +00:00
|
|
|
// SPDX-License-Identifier: agpl-3.0
|
2020-11-20 10:45:20 +00:00
|
|
|
pragma solidity 0.6.12;
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-09-04 10:48:29 +00:00
|
|
|
import {Errors} from '../helpers/Errors.sol';
|
2020-05-29 16:45:37 +00:00
|
|
|
|
|
|
|
/**
|
2020-07-13 08:54:08 +00:00
|
|
|
* @title WadRayMath library
|
|
|
|
* @author Aave
|
|
|
|
* @dev Provides mul and div function for wads (decimal numbers with 18 digits precision) and rays (decimals with 27 digits)
|
|
|
|
**/
|
2020-05-29 16:45:37 +00:00
|
|
|
|
|
|
|
library WadRayMath {
|
2020-07-13 08:54:08 +00:00
|
|
|
uint256 internal constant WAD = 1e18;
|
|
|
|
uint256 internal constant halfWAD = WAD / 2;
|
|
|
|
|
|
|
|
uint256 internal constant RAY = 1e27;
|
|
|
|
uint256 internal constant halfRAY = RAY / 2;
|
|
|
|
|
|
|
|
uint256 internal constant WAD_RAY_RATIO = 1e9;
|
|
|
|
|
|
|
|
/**
|
2020-11-25 17:33:49 +00:00
|
|
|
* @return One ray, 1e27
|
2020-07-13 08:54:08 +00:00
|
|
|
**/
|
|
|
|
function ray() internal pure returns (uint256) {
|
|
|
|
return RAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-25 17:33:49 +00:00
|
|
|
* @return One wad, 1e18
|
2020-07-13 08:54:08 +00:00
|
|
|
**/
|
|
|
|
|
|
|
|
function wad() internal pure returns (uint256) {
|
|
|
|
return WAD;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-25 17:33:49 +00:00
|
|
|
* @return Half ray, 1e27/2
|
2020-07-13 08:54:08 +00:00
|
|
|
**/
|
|
|
|
function halfRay() internal pure returns (uint256) {
|
|
|
|
return halfRAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-25 17:33:49 +00:00
|
|
|
* @return Half ray, 1e18/2
|
2020-07-13 08:54:08 +00:00
|
|
|
**/
|
|
|
|
function halfWad() internal pure returns (uint256) {
|
|
|
|
return halfWAD;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-25 17:33:49 +00:00
|
|
|
* @dev Multiplies two wad, rounding half up to the nearest wad
|
|
|
|
* @param a Wad
|
|
|
|
* @param b Wad
|
|
|
|
* @return The result of a*b, in wad
|
2020-07-13 08:54:08 +00:00
|
|
|
**/
|
|
|
|
function wadMul(uint256 a, uint256 b) internal pure returns (uint256) {
|
2020-10-28 10:47:01 +00:00
|
|
|
if (a == 0 || b == 0) {
|
2020-08-22 10:04:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2020-09-09 19:26:52 +00:00
|
|
|
|
2020-10-30 12:40:06 +00:00
|
|
|
require(a <= (type(uint256).max - halfWAD) / b, Errors.MATH_MULTIPLICATION_OVERFLOW);
|
2020-09-09 19:26:52 +00:00
|
|
|
|
2020-10-28 10:47:01 +00:00
|
|
|
return (a * b + halfWAD) / WAD;
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-25 17:33:49 +00:00
|
|
|
* @dev Divides two wad, rounding half up to the nearest wad
|
|
|
|
* @param a Wad
|
|
|
|
* @param b Wad
|
|
|
|
* @return The result of a/b, in wad
|
2020-07-13 08:54:08 +00:00
|
|
|
**/
|
|
|
|
function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) {
|
2020-10-14 09:03:32 +00:00
|
|
|
require(b != 0, Errors.MATH_DIVISION_BY_ZERO);
|
2020-07-13 08:54:08 +00:00
|
|
|
uint256 halfB = b / 2;
|
|
|
|
|
2020-10-30 12:40:06 +00:00
|
|
|
require(a <= (type(uint256).max - halfB) / WAD, Errors.MATH_MULTIPLICATION_OVERFLOW);
|
2020-08-22 10:04:34 +00:00
|
|
|
|
2020-10-28 10:47:01 +00:00
|
|
|
return (a * WAD + halfB) / b;
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-25 17:33:49 +00:00
|
|
|
* @dev Multiplies two ray, rounding half up to the nearest ray
|
|
|
|
* @param a Ray
|
|
|
|
* @param b Ray
|
|
|
|
* @return The result of a*b, in ray
|
2020-07-13 08:54:08 +00:00
|
|
|
**/
|
|
|
|
function rayMul(uint256 a, uint256 b) internal pure returns (uint256) {
|
2020-10-28 10:47:01 +00:00
|
|
|
if (a == 0 || b == 0) {
|
2020-08-22 10:04:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2020-09-09 19:26:52 +00:00
|
|
|
|
2020-10-30 12:40:06 +00:00
|
|
|
require(a <= (type(uint256).max - halfRAY) / b, Errors.MATH_MULTIPLICATION_OVERFLOW);
|
2020-09-09 19:26:52 +00:00
|
|
|
|
2020-10-28 10:47:01 +00:00
|
|
|
return (a * b + halfRAY) / RAY;
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-25 17:33:49 +00:00
|
|
|
* @dev Divides two ray, rounding half up to the nearest ray
|
|
|
|
* @param a Ray
|
|
|
|
* @param b Ray
|
|
|
|
* @return The result of a/b, in ray
|
2020-07-13 08:54:08 +00:00
|
|
|
**/
|
|
|
|
function rayDiv(uint256 a, uint256 b) internal pure returns (uint256) {
|
2020-10-14 09:03:32 +00:00
|
|
|
require(b != 0, Errors.MATH_DIVISION_BY_ZERO);
|
2020-07-13 08:54:08 +00:00
|
|
|
uint256 halfB = b / 2;
|
|
|
|
|
2020-10-30 12:40:06 +00:00
|
|
|
require(a <= (type(uint256).max - halfB) / RAY, Errors.MATH_MULTIPLICATION_OVERFLOW);
|
2020-08-22 10:04:34 +00:00
|
|
|
|
2020-10-28 10:47:01 +00:00
|
|
|
return (a * RAY + halfB) / b;
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-25 17:33:49 +00:00
|
|
|
* @dev Casts ray down to wad
|
|
|
|
* @param a Ray
|
2020-07-13 08:54:08 +00:00
|
|
|
* @return a casted to wad, rounded half up to the nearest wad
|
|
|
|
**/
|
|
|
|
function rayToWad(uint256 a) internal pure returns (uint256) {
|
|
|
|
uint256 halfRatio = WAD_RAY_RATIO / 2;
|
2020-09-09 19:26:52 +00:00
|
|
|
uint256 result = halfRatio + a;
|
2020-10-14 09:03:32 +00:00
|
|
|
require(result >= halfRatio, Errors.MATH_ADDITION_OVERFLOW);
|
2020-07-13 08:54:08 +00:00
|
|
|
|
2020-09-09 19:26:52 +00:00
|
|
|
return result / WAD_RAY_RATIO;
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-25 17:33:49 +00:00
|
|
|
* @dev Converts wad up to ray
|
|
|
|
* @param a Wad
|
2020-07-13 08:54:08 +00:00
|
|
|
* @return a converted in ray
|
|
|
|
**/
|
|
|
|
function wadToRay(uint256 a) internal pure returns (uint256) {
|
2020-09-09 19:26:52 +00:00
|
|
|
uint256 result = a * WAD_RAY_RATIO;
|
2020-10-14 09:03:32 +00:00
|
|
|
require(result / WAD_RAY_RATIO == a, Errors.MATH_MULTIPLICATION_OVERFLOW);
|
2020-08-22 10:04:34 +00:00
|
|
|
return result;
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
}
|