@ensuro/core 2.0.0-beta7 → 2.0.0-beta9
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.
- package/README.md +17 -14
- package/build/contracts/AccessManager.sol/AccessManager.json +2 -2
- package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +12 -12
- package/build/contracts/EToken.sol/EToken.json +2 -15
- package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +2 -2
- package/build/contracts/LiquidityThresholdAssetManager.sol/LiquidityThresholdAssetManager.json +10 -10
- package/build/contracts/Policy.sol/Policy.json +2 -2
- package/build/contracts/PolicyPool.sol/PolicyPool.json +21 -2
- package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +2 -15
- package/build/contracts/Reserve.sol/Reserve.json +0 -13
- package/build/contracts/TimeScaled.sol/TimeScaled.json +3 -17
- package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +2 -2
- package/build/contracts/{WadRayMath.sol → dependencies/WadRayMath.sol}/WadRayMath.json +3 -3
- package/build/contracts/interfaces/IAssetManager.sol/IAssetManager.json +10 -10
- package/build/contracts/interfaces/IPolicyPool.sol/IPolicyPool.json +19 -0
- package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +2 -2
- package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +2 -2
- package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +28 -2
- package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +2 -2
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +96 -2
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +2 -2
- package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +92 -2
- package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +2 -2
- package/build/contracts/mocks/TestNFT.sol/TestNFT.json +2 -2
- package/contracts/AccessManager.sol +1 -1
- package/contracts/ERC4626AssetManager.sol +7 -5
- package/contracts/EToken.sol +43 -44
- package/contracts/LiquidityThresholdAssetManager.sol +12 -10
- package/contracts/Policy.sol +1 -1
- package/contracts/PolicyPool.sol +152 -19
- package/contracts/PolicyPoolComponent.sol +7 -22
- package/contracts/PremiumsAccount.sol +159 -19
- package/contracts/Reserve.sol +113 -18
- package/contracts/RiskModule.sol +8 -8
- package/contracts/TimeScaled.sol +19 -15
- package/contracts/TrustfulRiskModule.sol +3 -3
- package/contracts/dependencies/WadRayMath.sol +126 -0
- package/contracts/interfaces/IAccessManager.sol +68 -13
- package/contracts/interfaces/IAssetManager.sol +64 -2
- package/contracts/interfaces/IEToken.sol +4 -1
- package/contracts/interfaces/ILPWhitelist.sol +17 -0
- package/contracts/interfaces/IPolicyPool.sol +7 -0
- package/contracts/interfaces/IPolicyPoolComponent.sol +3 -0
- package/contracts/interfaces/IRiskModule.sol +67 -4
- package/contracts/mocks/PolicyHolderMock.sol +21 -0
- package/contracts/mocks/PolicyPoolMock.sol +27 -0
- package/contracts/mocks/RiskModuleMock.sol +7 -1
- package/js/test-utils.js +49 -36
- package/package.json +1 -1
- package/contracts/WadRayMath.sol +0 -135
|
@@ -8,11 +8,13 @@ contract PolicyHolderMock is IPolicyHolder {
|
|
|
8
8
|
uint256 public policyId;
|
|
9
9
|
uint256 public payout;
|
|
10
10
|
bool public fail;
|
|
11
|
+
bool public notImplemented;
|
|
11
12
|
|
|
12
13
|
event NotificationReceived(uint256 kind, uint256 policyId, address operator, address from);
|
|
13
14
|
|
|
14
15
|
constructor(bool fail_) {
|
|
15
16
|
fail = fail_;
|
|
17
|
+
notImplemented = false;
|
|
16
18
|
payout = type(uint256).max;
|
|
17
19
|
}
|
|
18
20
|
|
|
@@ -20,12 +22,21 @@ contract PolicyHolderMock is IPolicyHolder {
|
|
|
20
22
|
fail = fail_;
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
function setNotImplemented(bool notImplemented_) external {
|
|
26
|
+
notImplemented = notImplemented_;
|
|
27
|
+
}
|
|
28
|
+
|
|
23
29
|
function onERC721Received(
|
|
24
30
|
address operator,
|
|
25
31
|
address from,
|
|
26
32
|
uint256 policyId_,
|
|
27
33
|
bytes calldata
|
|
28
34
|
) external override returns (bytes4) {
|
|
35
|
+
if (notImplemented)
|
|
36
|
+
// solhint-disable-next-line no-inline-assembly
|
|
37
|
+
assembly {
|
|
38
|
+
revert(0, 0)
|
|
39
|
+
}
|
|
29
40
|
if (fail) revert("onERC721Received: They told me I have to fail");
|
|
30
41
|
policyId = policyId_;
|
|
31
42
|
emit NotificationReceived(0, policyId_, operator, from);
|
|
@@ -37,6 +48,11 @@ contract PolicyHolderMock is IPolicyHolder {
|
|
|
37
48
|
address from,
|
|
38
49
|
uint256 policyId_
|
|
39
50
|
) external override returns (bytes4) {
|
|
51
|
+
if (notImplemented)
|
|
52
|
+
// solhint-disable-next-line no-inline-assembly
|
|
53
|
+
assembly {
|
|
54
|
+
revert(0, 0)
|
|
55
|
+
}
|
|
40
56
|
if (fail) revert("onPolicyExpired: They told me I have to fail");
|
|
41
57
|
policyId = policyId_;
|
|
42
58
|
payout = 0;
|
|
@@ -59,6 +75,11 @@ contract PolicyHolderMock is IPolicyHolder {
|
|
|
59
75
|
uint256 policyId_,
|
|
60
76
|
uint256 amount
|
|
61
77
|
) external override returns (bytes4) {
|
|
78
|
+
if (notImplemented)
|
|
79
|
+
// solhint-disable-next-line no-inline-assembly
|
|
80
|
+
assembly {
|
|
81
|
+
revert(0, 0)
|
|
82
|
+
}
|
|
62
83
|
if (fail) revert("onPayoutReceived: They told me I have to fail");
|
|
63
84
|
policyId = policyId_;
|
|
64
85
|
payout = amount;
|
|
@@ -81,6 +81,10 @@ contract PolicyPoolMock is IPolicyPool {
|
|
|
81
81
|
return _resolvePolicy(policy, customerWon ? policy.payout : 0);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
function isActive(uint256 policyId) external view override returns (bool) {
|
|
85
|
+
return policyHashes[policyId] != bytes32(0);
|
|
86
|
+
}
|
|
87
|
+
|
|
84
88
|
function deposit(IEToken, uint256) external pure override {
|
|
85
89
|
revert("Not Implemented deposit");
|
|
86
90
|
}
|
|
@@ -88,6 +92,29 @@ contract PolicyPoolMock is IPolicyPool {
|
|
|
88
92
|
function withdraw(IEToken, uint256) external pure override returns (uint256) {
|
|
89
93
|
revert("Not Implemented withdraw");
|
|
90
94
|
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @dev Simple passthrough method for testing Policy.initialize
|
|
98
|
+
*/
|
|
99
|
+
function initializeAndEmitPolicy(
|
|
100
|
+
IRiskModule riskModule,
|
|
101
|
+
IRiskModule.Params memory rmParams,
|
|
102
|
+
uint256 premium,
|
|
103
|
+
uint256 payout,
|
|
104
|
+
uint256 lossProb,
|
|
105
|
+
uint40 expiration
|
|
106
|
+
) external {
|
|
107
|
+
Policy.PolicyData memory policy = Policy.initialize(
|
|
108
|
+
riskModule,
|
|
109
|
+
rmParams,
|
|
110
|
+
premium,
|
|
111
|
+
payout,
|
|
112
|
+
lossProb,
|
|
113
|
+
expiration
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
emit NewPolicy(riskModule, policy);
|
|
117
|
+
}
|
|
91
118
|
}
|
|
92
119
|
|
|
93
120
|
/**
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
2
|
pragma solidity ^0.8.0;
|
|
4
3
|
|
|
5
4
|
import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
|
|
@@ -66,4 +65,11 @@ contract RiskModuleMock is RiskModule {
|
|
|
66
65
|
) external onlyComponentRole(PRICER_ROLE) returns (uint256) {
|
|
67
66
|
return _newPolicy(payout, premium, lossProb, expiration, payer, onBehalfOf, internalId).id;
|
|
68
67
|
}
|
|
68
|
+
|
|
69
|
+
function resolvePolicy(Policy.PolicyData calldata policy, uint256 payout)
|
|
70
|
+
external
|
|
71
|
+
onlyComponentRole(RESOLVER_ROLE)
|
|
72
|
+
{
|
|
73
|
+
_policyPool.resolvePolicy(policy, payout);
|
|
74
|
+
}
|
|
69
75
|
}
|
package/js/test-utils.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
const { expect } = require("chai");
|
|
2
|
+
const hre = require("hardhat");
|
|
2
3
|
const { BigNumber } = require("ethers");
|
|
3
4
|
const { LogDescription } = require("ethers/lib/utils");
|
|
4
5
|
exports.WEEK = 3600 * 24 * 7;
|
|
5
6
|
exports.DAY = 3600 * 24;
|
|
6
7
|
|
|
7
8
|
exports.initCurrency = async function (options, initial_targets, initial_balances) {
|
|
8
|
-
const Currency = await ethers.getContractFactory("TestCurrency");
|
|
9
|
+
const Currency = await hre.ethers.getContractFactory("TestCurrency");
|
|
9
10
|
let currency = await Currency.deploy(
|
|
10
11
|
options.name || "Test Currency",
|
|
11
12
|
options.symbol || "TEST",
|
|
@@ -94,7 +95,7 @@ exports.addEToken = async function (
|
|
|
94
95
|
pool,
|
|
95
96
|
{ etkName, etkSymbol, maxUtilizationRate, poolLoanInterestRate, extraArgs, extraConstructorArgs }
|
|
96
97
|
) {
|
|
97
|
-
const EToken = await ethers.getContractFactory("EToken");
|
|
98
|
+
const EToken = await hre.ethers.getContractFactory("EToken");
|
|
98
99
|
extraArgs = extraArgs || [];
|
|
99
100
|
extraConstructorArgs = extraConstructorArgs || [];
|
|
100
101
|
const etk = await hre.upgrades.deployProxy(
|
|
@@ -132,7 +133,7 @@ exports.impersonate = async function (address, setBalanceTo) {
|
|
|
132
133
|
if (setBalanceTo !== undefined)
|
|
133
134
|
await hre.network.provider.request({ method: "hardhat_setBalance", params: [address, setBalanceTo.toHexString()] });
|
|
134
135
|
|
|
135
|
-
return await ethers.getSigner(address);
|
|
136
|
+
return await hre.ethers.getSigner(address);
|
|
136
137
|
};
|
|
137
138
|
|
|
138
139
|
/**
|
|
@@ -161,8 +162,8 @@ const getTransactionEvent = function (interface, receipt, eventName) {
|
|
|
161
162
|
exports.getTransactionEvent = getTransactionEvent;
|
|
162
163
|
|
|
163
164
|
exports.deployPool = async function (hre, options) {
|
|
164
|
-
const PolicyPool = await ethers.getContractFactory("PolicyPool");
|
|
165
|
-
const AccessManager = await ethers.getContractFactory("AccessManager");
|
|
165
|
+
const PolicyPool = await hre.ethers.getContractFactory("PolicyPool");
|
|
166
|
+
const AccessManager = await hre.ethers.getContractFactory("AccessManager");
|
|
166
167
|
|
|
167
168
|
// Deploy AccessManager
|
|
168
169
|
const accessManager = await hre.upgrades.deployProxy(AccessManager, [], { kind: "uups" });
|
|
@@ -174,7 +175,7 @@ exports.deployPool = async function (hre, options) {
|
|
|
174
175
|
[
|
|
175
176
|
options.nftName || "Policy NFT",
|
|
176
177
|
options.nftSymbol || "EPOL",
|
|
177
|
-
options.treasuryAddress || ethers.constants.AddressZero,
|
|
178
|
+
options.treasuryAddress || hre.ethers.constants.AddressZero,
|
|
178
179
|
],
|
|
179
180
|
{
|
|
180
181
|
constructorArgs: [accessManager.address, options.currency],
|
|
@@ -195,20 +196,22 @@ exports.deployPool = async function (hre, options) {
|
|
|
195
196
|
return policyPool;
|
|
196
197
|
};
|
|
197
198
|
|
|
198
|
-
exports.deployPremiumsAccount = async function (hre, pool, options) {
|
|
199
|
-
const PremiumsAccount = await ethers.getContractFactory("PremiumsAccount");
|
|
199
|
+
exports.deployPremiumsAccount = async function (hre, pool, options, addToPool = true) {
|
|
200
|
+
const PremiumsAccount = await hre.ethers.getContractFactory("PremiumsAccount");
|
|
200
201
|
const premiumsAccount = await hre.upgrades.deployProxy(PremiumsAccount, [], {
|
|
201
202
|
constructorArgs: [
|
|
202
203
|
pool.address,
|
|
203
|
-
options.jrEtkAddr || ethers.constants.AddressZero,
|
|
204
|
-
options.srEtkAddr || ethers.constants.AddressZero,
|
|
204
|
+
options.jrEtkAddr || hre.ethers.constants.AddressZero,
|
|
205
|
+
options.srEtkAddr || hre.ethers.constants.AddressZero,
|
|
205
206
|
],
|
|
206
207
|
kind: "uups",
|
|
207
208
|
unsafeAllow: ["delegatecall"],
|
|
208
209
|
});
|
|
209
210
|
|
|
210
211
|
await premiumsAccount.deployed();
|
|
211
|
-
|
|
212
|
+
|
|
213
|
+
if (addToPool) await pool.addComponent(premiumsAccount.address, 3);
|
|
214
|
+
|
|
212
215
|
return premiumsAccount;
|
|
213
216
|
};
|
|
214
217
|
|
|
@@ -225,9 +228,8 @@ async function grantRole(hre, contract, role, user) {
|
|
|
225
228
|
} else {
|
|
226
229
|
userAddress = user;
|
|
227
230
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
await contract.grantRole(roleHex, userAddress);
|
|
231
|
+
if (!(await contract.hasRole(getRole(role), userAddress))) {
|
|
232
|
+
await contract.grantRole(getRole(role), userAddress);
|
|
231
233
|
}
|
|
232
234
|
}
|
|
233
235
|
|
|
@@ -241,18 +243,17 @@ async function grantComponentRole(hre, accessManager, component, role, user) {
|
|
|
241
243
|
} else {
|
|
242
244
|
userAddress = user.address === undefined ? user : user.address;
|
|
243
245
|
}
|
|
244
|
-
const
|
|
245
|
-
const componentRole = await accessManager.getComponentRole(component.address, roleHex);
|
|
246
|
+
const componentRole = getComponentRole(component.address, getRole(role));
|
|
246
247
|
if (!(await accessManager.hasRole(componentRole, userAddress))) {
|
|
247
|
-
await accessManager.grantComponentRole(component.address,
|
|
248
|
+
await accessManager.grantComponentRole(component.address, getRole(role), userAddress);
|
|
248
249
|
}
|
|
249
250
|
}
|
|
250
251
|
|
|
251
252
|
exports.grantComponentRole = grantComponentRole;
|
|
252
253
|
|
|
253
|
-
exports._E = ethers.utils.parseEther;
|
|
254
|
+
exports._E = hre.ethers.utils.parseEther;
|
|
254
255
|
|
|
255
|
-
const _BN = ethers.BigNumber.from;
|
|
256
|
+
const _BN = hre.ethers.BigNumber.from;
|
|
256
257
|
const WAD = _BN(1e10).mul(_BN(1e8)); // 1e10*1e8=1e18
|
|
257
258
|
const RAY = WAD.mul(_BN(1e9)); // 1e18*1e9=1e27
|
|
258
259
|
|
|
@@ -286,27 +287,27 @@ exports.amountFunction = function (decimals) {
|
|
|
286
287
|
};
|
|
287
288
|
};
|
|
288
289
|
|
|
289
|
-
|
|
290
|
-
Builds the component role identifier
|
|
291
|
-
|
|
292
|
-
Mimics the behaviour of the PolicyPoolConfig.getComponentRole method
|
|
293
|
-
|
|
294
|
-
Component roles are roles created doing XOR between the component
|
|
295
|
-
address and the original role.
|
|
296
|
-
|
|
297
|
-
Example:
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
*/
|
|
290
|
+
/**
|
|
291
|
+
* Builds the component role identifier
|
|
292
|
+
*
|
|
293
|
+
* Mimics the behaviour of the PolicyPoolConfig.getComponentRole method
|
|
294
|
+
*
|
|
295
|
+
* Component roles are roles created doing XOR between the component
|
|
296
|
+
* address and the original role.
|
|
297
|
+
*
|
|
298
|
+
* Example:
|
|
299
|
+
* getComponentRole("0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", "ORACLE_ADMIN_ROLE")
|
|
300
|
+
* // "0x05e01b185238b49f750d03d945e38a7f6c3be8b54de0ee42d481eb7814f0d3a8"
|
|
301
|
+
*/
|
|
301
302
|
function getComponentRole(componentAddress, roleName) {
|
|
302
303
|
// 32 byte array
|
|
303
|
-
const bytesRole = ethers.utils.arrayify(
|
|
304
|
+
const bytesRole = hre.ethers.utils.arrayify(getRole(roleName));
|
|
304
305
|
|
|
305
306
|
// 20 byte array
|
|
306
|
-
const bytesAddress = ethers.utils.arrayify(componentAddress);
|
|
307
|
+
const bytesAddress = hre.ethers.utils.arrayify(componentAddress);
|
|
307
308
|
|
|
308
309
|
// xor each byte, padding bytesAddress with zeros at the end
|
|
309
|
-
return ethers.utils.hexlify(bytesRole.map((elem, idx) => elem ^ (bytesAddress[idx] || 0)));
|
|
310
|
+
return hre.ethers.utils.hexlify(bytesRole.map((elem, idx) => elem ^ (bytesAddress[idx] || 0)));
|
|
310
311
|
}
|
|
311
312
|
|
|
312
313
|
exports.getComponentRole = getComponentRole;
|
|
@@ -315,13 +316,15 @@ exports.getComponentRole = getComponentRole;
|
|
|
315
316
|
Builds AccessControl error message for comparison in tests
|
|
316
317
|
*/
|
|
317
318
|
function accessControlMessage(address, component, role) {
|
|
318
|
-
|
|
319
|
+
const roleHash = component !== null ? getComponentRole(component, role) : getRole(role);
|
|
320
|
+
|
|
321
|
+
return `AccessControl: account ${address.toLowerCase()} is missing role ${roleHash}`;
|
|
319
322
|
}
|
|
320
323
|
|
|
321
324
|
exports.accessControlMessage = accessControlMessage;
|
|
322
325
|
|
|
323
326
|
function makePolicyId(rm, internalId) {
|
|
324
|
-
return ethers.BigNumber.from(rm.address).shl(96).add(internalId);
|
|
327
|
+
return hre.ethers.BigNumber.from(rm.address).shl(96).add(internalId);
|
|
325
328
|
}
|
|
326
329
|
|
|
327
330
|
exports.makePolicyId = makePolicyId;
|
|
@@ -341,3 +344,13 @@ async function blockchainNow(owner) {
|
|
|
341
344
|
}
|
|
342
345
|
|
|
343
346
|
exports.blockchainNow = blockchainNow;
|
|
347
|
+
|
|
348
|
+
function getRole(role) {
|
|
349
|
+
return role === "DEFAULT_ADMIN_ROLE"
|
|
350
|
+
? "0x0000000000000000000000000000000000000000000000000000000000000000"
|
|
351
|
+
: hre.ethers.utils.keccak256(hre.ethers.utils.toUtf8Bytes(role));
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
exports.getRole = getRole;
|
|
355
|
+
|
|
356
|
+
if (process.env.ENABLE_HH_WARNINGS !== "yes") hre.upgrades.silenceWarnings();
|
package/package.json
CHANGED
package/contracts/WadRayMath.sol
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
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
|
-
}
|