@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.
Files changed (50) hide show
  1. package/README.md +17 -14
  2. package/build/contracts/AccessManager.sol/AccessManager.json +2 -2
  3. package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +12 -12
  4. package/build/contracts/EToken.sol/EToken.json +2 -15
  5. package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +2 -2
  6. package/build/contracts/LiquidityThresholdAssetManager.sol/LiquidityThresholdAssetManager.json +10 -10
  7. package/build/contracts/Policy.sol/Policy.json +2 -2
  8. package/build/contracts/PolicyPool.sol/PolicyPool.json +21 -2
  9. package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +2 -15
  10. package/build/contracts/Reserve.sol/Reserve.json +0 -13
  11. package/build/contracts/TimeScaled.sol/TimeScaled.json +3 -17
  12. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +2 -2
  13. package/build/contracts/{WadRayMath.sol → dependencies/WadRayMath.sol}/WadRayMath.json +3 -3
  14. package/build/contracts/interfaces/IAssetManager.sol/IAssetManager.json +10 -10
  15. package/build/contracts/interfaces/IPolicyPool.sol/IPolicyPool.json +19 -0
  16. package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +2 -2
  17. package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +2 -2
  18. package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +28 -2
  19. package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +2 -2
  20. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +96 -2
  21. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +2 -2
  22. package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +92 -2
  23. package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +2 -2
  24. package/build/contracts/mocks/TestNFT.sol/TestNFT.json +2 -2
  25. package/contracts/AccessManager.sol +1 -1
  26. package/contracts/ERC4626AssetManager.sol +7 -5
  27. package/contracts/EToken.sol +43 -44
  28. package/contracts/LiquidityThresholdAssetManager.sol +12 -10
  29. package/contracts/Policy.sol +1 -1
  30. package/contracts/PolicyPool.sol +152 -19
  31. package/contracts/PolicyPoolComponent.sol +7 -22
  32. package/contracts/PremiumsAccount.sol +159 -19
  33. package/contracts/Reserve.sol +113 -18
  34. package/contracts/RiskModule.sol +8 -8
  35. package/contracts/TimeScaled.sol +19 -15
  36. package/contracts/TrustfulRiskModule.sol +3 -3
  37. package/contracts/dependencies/WadRayMath.sol +126 -0
  38. package/contracts/interfaces/IAccessManager.sol +68 -13
  39. package/contracts/interfaces/IAssetManager.sol +64 -2
  40. package/contracts/interfaces/IEToken.sol +4 -1
  41. package/contracts/interfaces/ILPWhitelist.sol +17 -0
  42. package/contracts/interfaces/IPolicyPool.sol +7 -0
  43. package/contracts/interfaces/IPolicyPoolComponent.sol +3 -0
  44. package/contracts/interfaces/IRiskModule.sol +67 -4
  45. package/contracts/mocks/PolicyHolderMock.sol +21 -0
  46. package/contracts/mocks/PolicyPoolMock.sol +27 -0
  47. package/contracts/mocks/RiskModuleMock.sol +7 -1
  48. package/js/test-utils.js +49 -36
  49. package/package.json +1 -1
  50. 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
- await pool.addComponent(premiumsAccount.address, 3);
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
- const roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
229
- if (!(await contract.hasRole(roleHex, userAddress))) {
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 roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
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, roleHex, userAddress);
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
- getComponentRole("0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", "ORACLE_ADMIN_ROLE")
299
- // "0x05e01b185238b49f750d03d945e38a7f6c3be8b54de0ee42d481eb7814f0d3a8"
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(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(roleName)));
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
- return `AccessControl: account ${address.toLowerCase()} is missing role ${getComponentRole(component, role)}`;
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ensuro/core",
3
3
  "description": "Ensuro - Decentralized insurance protocol",
4
- "version": "v2.0.0-beta7",
4
+ "version": "v2.0.0-beta9",
5
5
  "files": [
6
6
  "**/*.sol",
7
7
  "/build/contracts/*.json",
@@ -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
- }