Decimal.sol
1 /* 2 Copyright 2019 dYdX Trading Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 pragma solidity >=0.6.0; 18 pragma experimental ABIEncoderV2; 19 20 import { SafeMath } from "./SafeMath.sol"; 21 22 /** 23 * @title Decimal 24 * @author dYdX 25 * 26 * Library that defines a fixed-point number with 18 decimal places. 27 */ 28 library Decimal { 29 using SafeMath for uint256; 30 31 // ============ Constants ============ 32 33 uint256 constant BASE = 10**18; 34 35 // ============ Structs ============ 36 37 38 struct D256 { 39 uint256 value; 40 } 41 42 // ============ Static Functions ============ 43 44 function zero() 45 internal 46 pure 47 returns (D256 memory) 48 { 49 return D256({ value: 0 }); 50 } 51 52 function one() 53 internal 54 pure 55 returns (D256 memory) 56 { 57 return D256({ value: BASE }); 58 } 59 60 function from( 61 uint256 a 62 ) 63 internal 64 pure 65 returns (D256 memory) 66 { 67 return D256({ value: a.mul(BASE) }); 68 } 69 70 function ratio( 71 uint256 a, 72 uint256 b 73 ) 74 internal 75 pure 76 returns (D256 memory) 77 { 78 return D256({ value: getPartial(a, BASE, b) }); 79 } 80 81 // ============ Self Functions ============ 82 83 function add( 84 D256 memory self, 85 uint256 b 86 ) 87 internal 88 pure 89 returns (D256 memory) 90 { 91 return D256({ value: self.value.add(b.mul(BASE)) }); 92 } 93 94 function sub( 95 D256 memory self, 96 uint256 b 97 ) 98 internal 99 pure 100 returns (D256 memory) 101 { 102 return D256({ value: self.value.sub(b.mul(BASE)) }); 103 } 104 105 function sub( 106 D256 memory self, 107 uint256 b, 108 string memory reason 109 ) 110 internal 111 pure 112 returns (D256 memory) 113 { 114 return D256({ value: self.value.sub(b.mul(BASE), reason) }); 115 } 116 117 function mul( 118 D256 memory self, 119 uint256 b 120 ) 121 internal 122 pure 123 returns (D256 memory) 124 { 125 return D256({ value: self.value.mul(b) }); 126 } 127 128 function div( 129 D256 memory self, 130 uint256 b 131 ) 132 internal 133 pure 134 returns (D256 memory) 135 { 136 return D256({ value: self.value.div(b) }); 137 } 138 139 function pow( 140 D256 memory self, 141 uint256 b 142 ) 143 internal 144 pure 145 returns (D256 memory) 146 { 147 if (b == 0) { 148 return from(1); 149 } 150 151 D256 memory temp = D256({ value: self.value }); 152 for (uint256 i = 1; i < b; i++) { 153 temp = mul(temp, self); 154 } 155 156 return temp; 157 } 158 159 function add( 160 D256 memory self, 161 D256 memory b 162 ) 163 internal 164 pure 165 returns (D256 memory) 166 { 167 return D256({ value: self.value.add(b.value) }); 168 } 169 170 function sub( 171 D256 memory self, 172 D256 memory b 173 ) 174 internal 175 pure 176 returns (D256 memory) 177 { 178 return D256({ value: self.value.sub(b.value) }); 179 } 180 181 function sub( 182 D256 memory self, 183 D256 memory b, 184 string memory reason 185 ) 186 internal 187 pure 188 returns (D256 memory) 189 { 190 return D256({ value: self.value.sub(b.value, reason) }); 191 } 192 193 function mul( 194 D256 memory self, 195 D256 memory b 196 ) 197 internal 198 pure 199 returns (D256 memory) 200 { 201 return D256({ value: getPartial(self.value, b.value, BASE) }); 202 } 203 204 function div( 205 D256 memory self, 206 D256 memory b 207 ) 208 internal 209 pure 210 returns (D256 memory) 211 { 212 return D256({ value: getPartial(self.value, BASE, b.value) }); 213 } 214 215 function equals(D256 memory self, D256 memory b) internal pure returns (bool) { 216 return self.value == b.value; 217 } 218 219 function greaterThan(D256 memory self, D256 memory b) internal pure returns (bool) { 220 return compareTo(self, b) == 2; 221 } 222 223 function lessThan(D256 memory self, D256 memory b) internal pure returns (bool) { 224 return compareTo(self, b) == 0; 225 } 226 227 function greaterThanOrEqualTo(D256 memory self, D256 memory b) internal pure returns (bool) { 228 return compareTo(self, b) > 0; 229 } 230 231 function lessThanOrEqualTo(D256 memory self, D256 memory b) internal pure returns (bool) { 232 return compareTo(self, b) < 2; 233 } 234 235 function isZero(D256 memory self) internal pure returns (bool) { 236 return self.value == 0; 237 } 238 239 function asUint256(D256 memory self) internal pure returns (uint256) { 240 return self.value.div(BASE); 241 } 242 243 // ============ Core Methods ============ 244 245 function getPartial( 246 uint256 target, 247 uint256 numerator, 248 uint256 denominator 249 ) 250 private 251 pure 252 returns (uint256) 253 { 254 return target.mul(numerator).div(denominator); 255 } 256 257 function compareTo( 258 D256 memory a, 259 D256 memory b 260 ) 261 private 262 pure 263 returns (uint256) 264 { 265 if (a.value == b.value) { 266 return 1; 267 } 268 return a.value > b.value ? 2 : 0; 269 } 270 }