@ensuro/core 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +93 -0
  2. package/build/contracts/AaveAssetManager.sol/AaveAssetManager.json +772 -0
  3. package/build/contracts/BaseAssetManager.sol/BaseAssetManager.json +494 -0
  4. package/build/contracts/DataTypes.sol/DataTypes.json +10 -0
  5. package/build/contracts/EToken.sol/EToken.json +1148 -0
  6. package/build/contracts/FlightDelayRiskModule.sol/FlightDelayRiskModule.json +1093 -0
  7. package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +412 -0
  8. package/build/contracts/Policy.sol/Policy.json +10 -0
  9. package/build/contracts/PolicyNFT.sol/PolicyNFT.json +570 -0
  10. package/build/contracts/PolicyPool.sol/PolicyPool.json +1257 -0
  11. package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +281 -0
  12. package/build/contracts/PolicyPoolConfig.sol/PolicyPoolConfig.json +660 -0
  13. package/build/contracts/RiskModule.sol/RiskModule.json +748 -0
  14. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +1032 -0
  15. package/build/contracts/WadRayMath.sol/WadRayMath.json +10 -0
  16. package/build/contracts/dependencies/ChainlinkClientUpgradeable.sol/ChainlinkClientUpgradeable.json +50 -0
  17. package/build/contracts/upgraded/IPolicyNFTv1.sol/IPolicyNFTv1.json +322 -0
  18. package/build/contracts/upgraded/PolicyNFTv1.sol/PolicyNFTv1.json +571 -0
  19. package/build/contracts/upgraded/PolicyNFTv1.sol/PolicyNFTv1_Upgrade.json +602 -0
  20. package/build/interfaces/IAssetManager.sol/IAssetManager.json +31 -0
  21. package/build/interfaces/IEToken.sol/IEToken.json +491 -0
  22. package/build/interfaces/IInsolvencyHook.sol/IInsolvencyHook.json +42 -0
  23. package/build/interfaces/ILPWhitelist.sol/ILPWhitelist.json +74 -0
  24. package/build/interfaces/IPolicyNFT.sol/IPolicyNFT.json +321 -0
  25. package/build/interfaces/IPolicyPool.sol/IPolicyPool.json +445 -0
  26. package/build/interfaces/IPolicyPoolComponent.sol/IPolicyPoolComponent.json +24 -0
  27. package/build/interfaces/IPolicyPoolConfig.sol/IPolicyPoolConfig.json +328 -0
  28. package/build/interfaces/IRiskModule.sol/IRiskModule.json +141 -0
  29. package/contracts/AaveAssetManager.sol +326 -0
  30. package/contracts/BaseAssetManager.sol +283 -0
  31. package/contracts/DataTypes.sol +287 -0
  32. package/contracts/EToken.sol +773 -0
  33. package/contracts/FlightDelayRiskModule.sol +208 -0
  34. package/contracts/LPManualWhitelist.sol +57 -0
  35. package/contracts/Policy.sol +104 -0
  36. package/contracts/PolicyNFT.sol +96 -0
  37. package/contracts/PolicyPool.sol +716 -0
  38. package/contracts/PolicyPoolComponent.sol +164 -0
  39. package/contracts/PolicyPoolConfig.sol +231 -0
  40. package/contracts/RiskModule.sol +323 -0
  41. package/contracts/TrustfulRiskModule.sol +81 -0
  42. package/contracts/WadRayMath.sol +135 -0
  43. package/contracts/dependencies/ChainlinkClientUpgradeable.sol +371 -0
  44. package/contracts/upgraded/IPolicyNFTv1.sol +15 -0
  45. package/contracts/upgraded/PolicyNFTv1.sol +126 -0
  46. package/interfaces/IAssetManager.sol +23 -0
  47. package/interfaces/IEToken.sol +44 -0
  48. package/interfaces/IInsolvencyHook.sol +27 -0
  49. package/interfaces/ILPWhitelist.sol +23 -0
  50. package/interfaces/IPolicyNFT.sol +15 -0
  51. package/interfaces/IPolicyPool.sol +44 -0
  52. package/interfaces/IPolicyPoolComponent.sol +13 -0
  53. package/interfaces/IPolicyPoolConfig.sol +81 -0
  54. package/interfaces/IRiskModule.sol +29 -0
  55. package/package.json +30 -0
@@ -0,0 +1,323 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {WadRayMath} from "./WadRayMath.sol";
5
+ import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
6
+ import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
7
+ import {PolicyPoolComponent} from "./PolicyPoolComponent.sol";
8
+ import {IRiskModule} from "../interfaces/IRiskModule.sol";
9
+ import {IPolicyPoolConfig} from "../interfaces/IPolicyPoolConfig.sol";
10
+ import {Policy} from "./Policy.sol";
11
+
12
+ /**
13
+ * @title Ensuro Risk Module base contract
14
+ * @dev Risk Module that keeps the configuration and is responsible for pricing and policy resolution
15
+ * @custom:security-contact security@ensuro.co
16
+ * @author Ensuro
17
+ */
18
+ abstract contract RiskModule is IRiskModule, AccessControlUpgradeable, PolicyPoolComponent {
19
+ using Policy for Policy.PolicyData;
20
+ using WadRayMath for uint256;
21
+
22
+ uint256 internal constant SECONDS_IN_YEAR_RAY = 31536000e27; /* 365 * 24 * 3600 * 10e27 */
23
+
24
+ // For parameters that can be changed by the risk module provider
25
+ bytes32 public constant RM_PROVIDER_ROLE = keccak256("RM_PROVIDER_ROLE");
26
+
27
+ string private _name;
28
+ uint256 internal _scrPercentage; // in ray - Solvency Capital Requirement percentage, to calculate
29
+ // capital requirement as % of (payout - premium)
30
+ uint256 internal _moc; // in ray - Margin Of Conservativism - factor that multiplies lossProb
31
+ // to calculate purePremium
32
+ uint256 internal _ensuroFee; // in ray - % of pure premium that will go for Ensuro treasury
33
+ uint256 internal _scrInterestRate; // in ray - % of interest to charge for the SCR
34
+ uint256 internal _maxScrPerPolicy; // in wad - Max SCR per policy
35
+ uint256 internal _scrLimit; // in wad - Max SCR to be allocated to this module
36
+ uint256 internal _totalScr; // in wad - Current SCR allocated to this module
37
+
38
+ address internal _wallet; // Address of the RiskModule provider
39
+
40
+ modifier validateParamsAfterChange() {
41
+ _;
42
+ _validateParameters();
43
+ }
44
+
45
+ /// @custom:oz-upgrades-unsafe-allow constructor
46
+ // solhint-disable-next-line no-empty-blocks
47
+ constructor(IPolicyPool policyPool_) PolicyPoolComponent(policyPool_) {}
48
+
49
+ /**
50
+ * @dev Initializes the RiskModule
51
+ * @param name_ Name of the Risk Module
52
+ * @param scrPercentage_ Solvency Capital Requirement percentage, to calculate
53
+ capital requirement as % of (payout - premium) (in ray)
54
+ * @param ensuroFee_ % of pure premium that will go for Ensuro treasury (in ray)
55
+ * @param scrInterestRate_ % of interest to charge for the SCR (in ray)
56
+ * @param maxScrPerPolicy_ Max SCR to be allocated to this module (in wad)
57
+ * @param scrLimit_ Max SCR to be allocated to this module (in wad)
58
+ * @param wallet_ Address of the RiskModule provider
59
+ */
60
+ // solhint-disable-next-line func-name-mixedcase
61
+ function __RiskModule_init(
62
+ string memory name_,
63
+ uint256 scrPercentage_,
64
+ uint256 ensuroFee_,
65
+ uint256 scrInterestRate_,
66
+ uint256 maxScrPerPolicy_,
67
+ uint256 scrLimit_,
68
+ address wallet_
69
+ ) internal initializer {
70
+ __AccessControl_init();
71
+ __PolicyPoolComponent_init();
72
+ __RiskModule_init_unchained(
73
+ name_,
74
+ scrPercentage_,
75
+ ensuroFee_,
76
+ scrInterestRate_,
77
+ maxScrPerPolicy_,
78
+ scrLimit_,
79
+ wallet_
80
+ );
81
+ }
82
+
83
+ // solhint-disable-next-line func-name-mixedcase
84
+ function __RiskModule_init_unchained(
85
+ string memory name_,
86
+ uint256 scrPercentage_,
87
+ uint256 ensuroFee_,
88
+ uint256 scrInterestRate_,
89
+ uint256 maxScrPerPolicy_,
90
+ uint256 scrLimit_,
91
+ address wallet_
92
+ ) internal initializer {
93
+ _name = name_;
94
+ _scrPercentage = scrPercentage_;
95
+ _moc = WadRayMath.RAY;
96
+ _ensuroFee = ensuroFee_;
97
+ _scrInterestRate = scrInterestRate_;
98
+ _maxScrPerPolicy = maxScrPerPolicy_;
99
+ _scrLimit = scrLimit_;
100
+ _totalScr = 0;
101
+ _wallet = wallet_;
102
+ _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
103
+ _validateParameters();
104
+ }
105
+
106
+ // runs validation on RiskModule parameters
107
+ function _validateParameters() internal view {
108
+ require(
109
+ _scrPercentage <= WadRayMath.RAY && _scrPercentage > 0,
110
+ "Validation: scrPercentage must be <=1"
111
+ );
112
+ require(
113
+ _moc <= (2 * WadRayMath.RAY) && _moc >= (WadRayMath.RAY / 2),
114
+ "Validation: moc must be [0.5, 2]"
115
+ );
116
+ require(_ensuroFee <= WadRayMath.RAY, "Validation: ensuroFee must be <= 1");
117
+ require(_scrInterestRate <= WadRayMath.RAY, "Validation: scrInterestRate must be <= 1 (100%)");
118
+ // _maxScrPerPolicy no limits
119
+ require(_scrLimit >= _totalScr, "Validation: scrLimit can't be less than actual totalScr");
120
+ require(_wallet != address(0), "Validation: Wallet can't be zero address");
121
+ }
122
+
123
+ function name() public view override returns (string memory) {
124
+ return _name;
125
+ }
126
+
127
+ function scrPercentage() public view override returns (uint256) {
128
+ return _scrPercentage;
129
+ }
130
+
131
+ function moc() public view override returns (uint256) {
132
+ return _moc;
133
+ }
134
+
135
+ function ensuroFee() public view override returns (uint256) {
136
+ return _ensuroFee;
137
+ }
138
+
139
+ function scrInterestRate() public view override returns (uint256) {
140
+ return _scrInterestRate;
141
+ }
142
+
143
+ function maxScrPerPolicy() public view override returns (uint256) {
144
+ return _maxScrPerPolicy;
145
+ }
146
+
147
+ function scrLimit() public view override returns (uint256) {
148
+ return _scrLimit;
149
+ }
150
+
151
+ function totalScr() public view override returns (uint256) {
152
+ return _totalScr;
153
+ }
154
+
155
+ function wallet() public view override returns (address) {
156
+ return _wallet;
157
+ }
158
+
159
+ function setScrPercentage(uint256 newScrPercentage)
160
+ external
161
+ onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE)
162
+ validateParamsAfterChange
163
+ {
164
+ bool tweak = !hasPoolRole(LEVEL2_ROLE);
165
+ require(
166
+ !tweak || _isTweakRay(_scrPercentage, newScrPercentage, 1e26),
167
+ "Tweak exceeded: scrPercentage tweaks only up to 10%"
168
+ );
169
+ _scrPercentage = newScrPercentage;
170
+ _parameterChanged(
171
+ IPolicyPoolConfig.GovernanceActions.setScrPercentage,
172
+ newScrPercentage,
173
+ tweak
174
+ );
175
+ }
176
+
177
+ function setMoc(uint256 newMoc)
178
+ external
179
+ onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE)
180
+ validateParamsAfterChange
181
+ {
182
+ bool tweak = !hasPoolRole(LEVEL2_ROLE);
183
+ require(!tweak || _isTweakRay(_moc, newMoc, 1e26), "Tweak exceeded: moc tweaks only up to 10%");
184
+ _moc = newMoc;
185
+ _parameterChanged(IPolicyPoolConfig.GovernanceActions.setMoc, newMoc, tweak);
186
+ }
187
+
188
+ function setScrInterestRate(uint256 newScrInterestRate)
189
+ external
190
+ onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE)
191
+ validateParamsAfterChange
192
+ {
193
+ bool tweak = !hasPoolRole(LEVEL2_ROLE);
194
+ require(
195
+ !tweak || _isTweakRay(_scrInterestRate, newScrInterestRate, 3e26),
196
+ "Tweak exceeded: scrInterestRate tweaks only up to 30%"
197
+ );
198
+ _scrInterestRate = newScrInterestRate;
199
+ _parameterChanged(
200
+ IPolicyPoolConfig.GovernanceActions.setScrInterestRate,
201
+ newScrInterestRate,
202
+ tweak
203
+ );
204
+ }
205
+
206
+ function setEnsuroFee(uint256 newEnsuroFee)
207
+ external
208
+ onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE)
209
+ validateParamsAfterChange
210
+ {
211
+ bool tweak = !hasPoolRole(LEVEL2_ROLE);
212
+ require(
213
+ !tweak || _isTweakRay(_ensuroFee, newEnsuroFee, 3e26),
214
+ "Tweak exceeded: ensuroFee tweaks only up to 30%"
215
+ );
216
+ _ensuroFee = newEnsuroFee;
217
+ _parameterChanged(IPolicyPoolConfig.GovernanceActions.setEnsuroFee, newEnsuroFee, tweak);
218
+ }
219
+
220
+ function setMaxScrPerPolicy(uint256 newMaxScrPerPolicy)
221
+ external
222
+ onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE)
223
+ validateParamsAfterChange
224
+ {
225
+ bool tweak = !hasPoolRole(LEVEL2_ROLE);
226
+ require(
227
+ !tweak || _isTweakWad(_maxScrPerPolicy, newMaxScrPerPolicy, 3e17),
228
+ "Tweak exceeded: maxScrPerPolicy tweaks only up to 30%"
229
+ );
230
+ _maxScrPerPolicy = newMaxScrPerPolicy;
231
+ _parameterChanged(
232
+ IPolicyPoolConfig.GovernanceActions.setMaxScrPerPolicy,
233
+ newMaxScrPerPolicy,
234
+ tweak
235
+ );
236
+ }
237
+
238
+ function setScrLimit(uint256 newScrLimit)
239
+ external
240
+ onlyPoolRole3(LEVEL1_ROLE, LEVEL2_ROLE, LEVEL3_ROLE)
241
+ validateParamsAfterChange
242
+ {
243
+ bool tweak = !hasPoolRole(LEVEL2_ROLE) && !hasPoolRole(LEVEL1_ROLE);
244
+ require(
245
+ !tweak || _isTweakWad(_scrLimit, newScrLimit, 1e17),
246
+ "Tweak exceeded: scrLimit tweaks only up to 10%"
247
+ );
248
+ require(
249
+ newScrLimit <= _scrLimit ||
250
+ hasPoolRole(LEVEL1_ROLE) ||
251
+ _policyPool.totalETokenSupply().wadMul(1e17) > newScrLimit,
252
+ "Tweak exceeded: Increase, >=10% of the total liquidity, requires LEVEL1_ROLE"
253
+ );
254
+ require(newScrLimit >= _totalScr, "Can't set SCR less than current SCR allocation");
255
+ _scrLimit = newScrLimit;
256
+ _parameterChanged(IPolicyPoolConfig.GovernanceActions.setScrLimit, newScrLimit, tweak);
257
+ }
258
+
259
+ function setWallet(address wallet_)
260
+ external
261
+ onlyRole(RM_PROVIDER_ROLE)
262
+ validateParamsAfterChange
263
+ {
264
+ _wallet = wallet_;
265
+ _parameterChanged(
266
+ IPolicyPoolConfig.GovernanceActions.setWallet,
267
+ uint256(uint160(wallet_)),
268
+ false
269
+ );
270
+ }
271
+
272
+ function getMinimumPremium(
273
+ uint256 payout,
274
+ uint256 lossProb,
275
+ uint40 expiration
276
+ ) external view returns (uint256) {
277
+ uint256 purePremium = payout.wadToRay().rayMul(lossProb.rayMul(moc())).rayToWad();
278
+ uint256 scr = payout.wadMul(scrPercentage().rayToWad()) - purePremium;
279
+ uint256 interestRate = (
280
+ (scrInterestRate() * (expiration - block.timestamp)).rayDiv(SECONDS_IN_YEAR_RAY)
281
+ ).rayToWad();
282
+ uint256 premiumForLps = scr.wadMul(interestRate);
283
+ uint256 premiumForEnsuro = (purePremium + premiumForLps).wadMul(ensuroFee().rayToWad());
284
+ return purePremium + premiumForEnsuro + premiumForLps;
285
+ }
286
+
287
+ function _newPolicy(
288
+ uint256 payout,
289
+ uint256 premium,
290
+ uint256 lossProb,
291
+ uint40 expiration,
292
+ address customer,
293
+ uint96 internalId
294
+ ) internal whenNotPaused returns (Policy.PolicyData memory) {
295
+ require(premium < payout, "Premium must be less than payout");
296
+ require(expiration > uint40(block.timestamp), "Expiration must be in the future");
297
+ require(customer != address(0), "Customer can't be zero address");
298
+ require(
299
+ _policyPool.currency().allowance(customer, address(_policyPool)) >= premium,
300
+ "You must allow ENSURO to transfer the premium"
301
+ );
302
+ Policy.PolicyData memory policy = Policy.initialize(
303
+ this,
304
+ premium,
305
+ payout,
306
+ lossProb,
307
+ expiration
308
+ );
309
+ require(policy.scr <= _maxScrPerPolicy, "RiskModule: SCR is more than maximum per policy");
310
+ _totalScr += policy.scr;
311
+ require(_totalScr <= _scrLimit, "RiskModule: SCR limit exceeded");
312
+ uint256 policyId = _policyPool.newPolicy(policy, customer, internalId);
313
+ policy.id = policyId;
314
+ return policy;
315
+ }
316
+
317
+ function releaseScr(uint256 scrAmount) external override onlyPolicyPool {
318
+ // In the Python protype this function is called `remove_policy` and receives
319
+ // all the policy. Since we just need the amount, for performance reasons
320
+ // we just send the amount and the method is called releaseScr
321
+ _totalScr -= scrAmount;
322
+ }
323
+ }
@@ -0,0 +1,81 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
5
+ import {RiskModule} from "./RiskModule.sol";
6
+ import {Policy} from "./Policy.sol";
7
+
8
+ /**
9
+ * @title Trustful Risk Module
10
+ * @dev Risk Module without any validation, just the newPolicy and resolvePolicy need to be called by
11
+ authorized users
12
+ * @custom:security-contact security@ensuro.co
13
+ * @author Ensuro
14
+ */
15
+
16
+ contract TrustfulRiskModule is RiskModule {
17
+ bytes32 public constant PRICER_ROLE = keccak256("PRICER_ROLE");
18
+ bytes32 public constant RESOLVER_ROLE = keccak256("RESOLVER_ROLE");
19
+
20
+ /// @custom:oz-upgrades-unsafe-allow constructor
21
+ // solhint-disable-next-line no-empty-blocks
22
+ constructor(IPolicyPool policyPool_) RiskModule(policyPool_) {}
23
+
24
+ /**
25
+ * @dev Initializes the RiskModule
26
+ * @param name_ Name of the Risk Module
27
+ * @param scrPercentage_ Solvency Capital Requirement percentage, to calculate
28
+ capital requirement as % of (payout - premium) (in ray)
29
+ * @param ensuroFee_ % of premium that will go for Ensuro treasury (in ray)
30
+ * @param scrInterestRate_ cost of capital (in ray)
31
+ * @param maxScrPerPolicy_ Max SCR to be allocated to this module (in wad)
32
+ * @param scrLimit_ Max SCR to be allocated to this module (in wad)
33
+ * @param wallet_ Address of the RiskModule provider
34
+ */
35
+ function initialize(
36
+ string memory name_,
37
+ uint256 scrPercentage_,
38
+ uint256 ensuroFee_,
39
+ uint256 scrInterestRate_,
40
+ uint256 maxScrPerPolicy_,
41
+ uint256 scrLimit_,
42
+ address wallet_
43
+ ) public initializer {
44
+ __RiskModule_init(
45
+ name_,
46
+ scrPercentage_,
47
+ ensuroFee_,
48
+ scrInterestRate_,
49
+ maxScrPerPolicy_,
50
+ scrLimit_,
51
+ wallet_
52
+ );
53
+ }
54
+
55
+ function newPolicy(
56
+ uint256 payout,
57
+ uint256 premium,
58
+ uint256 lossProb,
59
+ uint40 expiration,
60
+ address customer,
61
+ uint96 internalId
62
+ ) external onlyRole(PRICER_ROLE) returns (uint256) {
63
+ return _newPolicy(payout, premium, lossProb, expiration, customer, internalId).id;
64
+ }
65
+
66
+ function resolvePolicy(Policy.PolicyData calldata policy, uint256 payout)
67
+ external
68
+ onlyRole(RESOLVER_ROLE)
69
+ whenNotPaused
70
+ {
71
+ _policyPool.resolvePolicy(policy, payout);
72
+ }
73
+
74
+ function resolvePolicyFullPayout(Policy.PolicyData calldata policy, bool customerWon)
75
+ external
76
+ onlyRole(RESOLVER_ROLE)
77
+ whenNotPaused
78
+ {
79
+ _policyPool.resolvePolicyFullPayout(policy, customerWon);
80
+ }
81
+ }
@@ -0,0 +1,135 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ /**
5
+ * @title WadRayMath library
6
+ * @author Aave / Ensuro
7
+ * @dev Provides mul and div function for wads (decimal numbers with 18 digits precision) and rays
8
+ * (decimals with 27 digits)
9
+ * @custom:security-contact security@ensuro.co
10
+ **/
11
+
12
+ library WadRayMath {
13
+ uint256 internal constant WAD = 1e18;
14
+ uint256 internal constant HALF_WAD = WAD / 2;
15
+
16
+ uint256 internal constant RAY = 1e27;
17
+ uint256 internal constant HALF_RAY = RAY / 2;
18
+
19
+ uint256 internal constant WAD_RAY_RATIO = 1e9;
20
+
21
+ /**
22
+ * @return One ray, 1e27
23
+ **/
24
+ function ray() internal pure returns (uint256) {
25
+ return RAY;
26
+ }
27
+
28
+ /**
29
+ * @return One wad, 1e18
30
+ **/
31
+
32
+ function wad() internal pure returns (uint256) {
33
+ return WAD;
34
+ }
35
+
36
+ /**
37
+ * @return Half ray, 1e27/2
38
+ **/
39
+ function halfRay() internal pure returns (uint256) {
40
+ return HALF_RAY;
41
+ }
42
+
43
+ /**
44
+ * @return Half ray, 1e18/2
45
+ **/
46
+ function halfWad() internal pure returns (uint256) {
47
+ return HALF_WAD;
48
+ }
49
+
50
+ /**
51
+ * @dev Multiplies two wad, rounding half up to the nearest wad
52
+ * @param a Wad
53
+ * @param b Wad
54
+ * @return The result of a*b, in wad
55
+ **/
56
+ function wadMul(uint256 a, uint256 b) internal pure returns (uint256) {
57
+ if (a == 0 || b == 0) {
58
+ return 0;
59
+ }
60
+
61
+ require(a <= (type(uint256).max - HALF_WAD) / b, "wadMul: Math Multiplication Overflow");
62
+
63
+ return (a * b + HALF_WAD) / WAD;
64
+ }
65
+
66
+ /**
67
+ * @dev Divides two wad, rounding half up to the nearest wad
68
+ * @param a Wad
69
+ * @param b Wad
70
+ * @return The result of a/b, in wad
71
+ **/
72
+ function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) {
73
+ require(b != 0, "wadDiv: Division by zero");
74
+ uint256 halfB = b / 2;
75
+
76
+ require(a <= (type(uint256).max - halfB) / WAD, "wadDiv: Math Multiplication Overflow");
77
+
78
+ return (a * WAD + halfB) / b;
79
+ }
80
+
81
+ /**
82
+ * @dev Multiplies two ray, rounding half up to the nearest ray
83
+ * @param a Ray
84
+ * @param b Ray
85
+ * @return The result of a*b, in ray
86
+ **/
87
+ function rayMul(uint256 a, uint256 b) internal pure returns (uint256) {
88
+ if (a == 0 || b == 0) {
89
+ return 0;
90
+ }
91
+
92
+ require(a <= (type(uint256).max - HALF_RAY) / b, "rayMul: Math Multiplication Overflow");
93
+
94
+ return (a * b + HALF_RAY) / RAY;
95
+ }
96
+
97
+ /**
98
+ * @dev Divides two ray, rounding half up to the nearest ray
99
+ * @param a Ray
100
+ * @param b Ray
101
+ * @return The result of a/b, in ray
102
+ **/
103
+ function rayDiv(uint256 a, uint256 b) internal pure returns (uint256) {
104
+ require(b != 0, "rayDiv: Division by zero");
105
+ uint256 halfB = b / 2;
106
+
107
+ require(a <= (type(uint256).max - halfB) / RAY, "rayDiv: Math Multiplication Overflow");
108
+
109
+ return (a * RAY + halfB) / b;
110
+ }
111
+
112
+ /**
113
+ * @dev Casts ray down to wad
114
+ * @param a Ray
115
+ * @return a casted to wad, rounded half up to the nearest wad
116
+ **/
117
+ function rayToWad(uint256 a) internal pure returns (uint256) {
118
+ uint256 halfRatio = WAD_RAY_RATIO / 2;
119
+ uint256 result = halfRatio + a;
120
+ require(result >= halfRatio, "rayToWad: Math Addition Overflow");
121
+
122
+ return result / WAD_RAY_RATIO;
123
+ }
124
+
125
+ /**
126
+ * @dev Converts wad up to ray
127
+ * @param a Wad
128
+ * @return a converted in ray
129
+ **/
130
+ function wadToRay(uint256 a) internal pure returns (uint256) {
131
+ uint256 result = a * WAD_RAY_RATIO;
132
+ require(result / WAD_RAY_RATIO == a, "wadToRad: Math Multiplication Overflow");
133
+ return result;
134
+ }
135
+ }