@ensuro/core 2.0.0-beta10 → 2.0.0-beta11

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 (49) hide show
  1. package/README.md +13 -0
  2. package/build/contracts/AccessManager.sol/AccessManager.json +7 -2
  3. package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +21 -2
  4. package/build/contracts/EToken.sol/EToken.json +21 -2
  5. package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +21 -2
  6. package/build/contracts/LiquidityThresholdAssetManager.sol/LiquidityThresholdAssetManager.json +19 -0
  7. package/build/contracts/Policy.sol/Policy.json +2 -2
  8. package/build/contracts/PolicyPool.sol/PolicyPool.json +2 -2
  9. package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +19 -0
  10. package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +21 -2
  11. package/build/contracts/Reserve.sol/Reserve.json +19 -0
  12. package/build/contracts/RiskModule.sol/RiskModule.json +19 -0
  13. package/build/contracts/SignedQuoteRiskModule.sol/SignedQuoteRiskModule.json +21 -2
  14. package/build/contracts/TimeScaled.sol/TimeScaled.json +2 -2
  15. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +21 -2
  16. package/build/contracts/dependencies/WadRayMath.sol/WadRayMath.json +2 -2
  17. package/build/contracts/interfaces/IAssetManager.sol/IAssetManager.json +19 -0
  18. package/build/contracts/interfaces/IPolicyPoolComponent.sol/IPolicyPoolComponent.json +19 -0
  19. package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +2 -2
  20. package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +2 -2
  21. package/build/contracts/mocks/InterfaceIdCalculator.sol/InterfaceIdCalculator.json +180 -0
  22. package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +2 -2
  23. package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +21 -2
  24. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +2 -2
  25. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +2 -2
  26. package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +21 -2
  27. package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +2 -2
  28. package/build/contracts/mocks/TestNFT.sol/TestNFT.json +2 -2
  29. package/contracts/AccessManager.sol +30 -1
  30. package/contracts/ERC4626AssetManager.sol +3 -0
  31. package/contracts/EToken.sol +89 -19
  32. package/contracts/LPManualWhitelist.sol +18 -2
  33. package/contracts/LiquidityThresholdAssetManager.sol +17 -2
  34. package/contracts/Policy.sol +4 -2
  35. package/contracts/PolicyPool.sol +58 -11
  36. package/contracts/PolicyPoolComponent.sol +25 -3
  37. package/contracts/PremiumsAccount.sol +55 -23
  38. package/contracts/Reserve.sol +19 -3
  39. package/contracts/RiskModule.sol +37 -13
  40. package/contracts/SignedQuoteRiskModule.sol +7 -0
  41. package/contracts/TrustfulRiskModule.sol +7 -0
  42. package/contracts/interfaces/IAssetManager.sol +8 -3
  43. package/contracts/interfaces/IPolicyPool.sol +1 -1
  44. package/contracts/interfaces/IPolicyPoolComponent.sol +2 -1
  45. package/contracts/mocks/InterfaceIdCalculator.sol +32 -0
  46. package/contracts/mocks/PolicyPoolComponentMock.sol +10 -0
  47. package/js/deploy.js +704 -0
  48. package/js/test-utils.js +139 -37
  49. package/package.json +1 -1
package/js/test-utils.js CHANGED
@@ -2,6 +2,8 @@ const { expect } = require("chai");
2
2
  const hre = require("hardhat");
3
3
  const { BigNumber } = require("ethers");
4
4
  const { LogDescription } = require("ethers/lib/utils");
5
+ const { findAll } = require("solidity-ast/utils");
6
+
5
7
  exports.WEEK = 3600 * 24 * 7;
6
8
  exports.DAY = 3600 * 24;
7
9
 
@@ -42,7 +44,7 @@ exports.now = function () {
42
44
  return Math.floor(new Date().getTime() / 1000);
43
45
  };
44
46
 
45
- exports.addRiskModule = async function (
47
+ const createRiskModule = async function (
46
48
  pool,
47
49
  premiumsAccount,
48
50
  contractFactory,
@@ -68,7 +70,7 @@ exports.addRiskModule = async function (
68
70
  rmName || "RiskModule",
69
71
  _W(scrPercentage) || _W(1),
70
72
  _W(ensuroFee) || _W(0),
71
- _W(scrInterestRate) || _W(0.1),
73
+ _W(scrInterestRate) || _W("0.1"),
72
74
  _A(maxScrPerPolicy) || _A(1000),
73
75
  _A(scrLimit) || _A(1000000),
74
76
  wallet || "0xdD2FD4581271e230360230F9337D5c0430Bf44C0", // Random address
@@ -87,11 +89,46 @@ exports.addRiskModule = async function (
87
89
  moc = _W(moc);
88
90
  await rm.setParam(0, moc);
89
91
  }
92
+ return rm;
93
+ };
94
+
95
+ exports.createRiskModule = createRiskModule;
96
+
97
+ exports.addRiskModule = async function (
98
+ pool,
99
+ premiumsAccount,
100
+ contractFactory,
101
+ {
102
+ rmName,
103
+ scrPercentage,
104
+ scrInterestRate,
105
+ ensuroFee,
106
+ maxScrPerPolicy,
107
+ scrLimit,
108
+ moc,
109
+ wallet,
110
+ extraArgs,
111
+ extraConstructorArgs,
112
+ }
113
+ ) {
114
+ const rm = await createRiskModule(pool, premiumsAccount, contractFactory, {
115
+ rmName,
116
+ scrPercentage,
117
+ scrInterestRate,
118
+ ensuroFee,
119
+ maxScrPerPolicy,
120
+ scrLimit,
121
+ moc,
122
+ wallet,
123
+ extraArgs,
124
+ extraConstructorArgs,
125
+ });
126
+
90
127
  await pool.addComponent(rm.address, 2);
91
128
  return rm;
92
129
  };
93
130
 
94
- exports.addEToken = async function (
131
+ const createEToken = async function (
95
132
  pool,
96
133
  { etkName, etkSymbol, maxUtilizationRate, poolLoanInterestRate, extraArgs, extraConstructorArgs }
97
134
  ) {
@@ -101,8 +138,8 @@ exports.addEToken = async function (
101
138
  const etk = await hre.upgrades.deployProxy(
102
139
  EToken,
103
140
  [
104
- etkName || "EToken",
105
- etkSymbol || "eUSD1YEAR",
141
+ etkName === undefined ? "EToken" : etkName,
142
+ etkSymbol === undefined ? "eUSD1YEAR" : etkSymbol,
106
143
  _W(maxUtilizationRate) || _W(1),
107
144
  _W(poolLoanInterestRate) || _W("0.05"),
108
145
  ...extraArgs,
@@ -115,6 +152,23 @@ exports.addEToken = async function (
115
152
  );
116
153
 
117
154
  await etk.deployed();
155
+ return etk;
156
+ };
157
+
158
+ exports.createEToken = createEToken;
159
+
160
+ exports.addEToken = async function (
161
+ pool,
162
+ { etkName, etkSymbol, maxUtilizationRate, poolLoanInterestRate, extraArgs, extraConstructorArgs }
163
+ ) {
164
+ const etk = await createEToken(pool, {
165
+ etkName,
166
+ etkSymbol,
167
+ maxUtilizationRate,
168
+ poolLoanInterestRate,
169
+ extraArgs,
170
+ extraConstructorArgs,
171
+ });
118
172
  await pool.addComponent(etk.address, 1);
119
173
  return etk;
120
174
  };
@@ -161,21 +215,42 @@ const getTransactionEvent = function (interface, receipt, eventName) {
161
215
 
162
216
  exports.getTransactionEvent = getTransactionEvent;
163
217
 
218
+ const randomAddress = "0x89cDb70Fee571251a66E34caa1673cE40f7549Dc";
219
+
220
+ /**
221
+ * Deploys de PolicyPool contract and AccessManager
222
+ *
223
+ * By default deployes de PolicyPool and AccessManager and grants LEVEL 1, 2, 3 permissions
224
+ *
225
+ * options:
226
+ * - .currency: mandatory, the address of the currency used in the PolicyPool
227
+ * - .access: if specified, doesn't create an AccessManager, uses this address.toLowerCase
228
+ * - .nftName: default "Policy NFT"
229
+ * - .nftSymbol: default "EPOL"
230
+ * - .treasuryAddress: default randomAddress
231
+ * - .grantRoles: default []. List of additional roles to grant
232
+ * - .dontGrantL123Roles: if specified, doesn't grants LEVEL1, 2 and 3 roles.
233
+ */
164
234
  exports.deployPool = async function (hre, options) {
165
235
  const PolicyPool = await hre.ethers.getContractFactory("PolicyPool");
166
236
  const AccessManager = await hre.ethers.getContractFactory("AccessManager");
167
237
 
168
- // Deploy AccessManager
169
- const accessManager = await hre.upgrades.deployProxy(AccessManager, [], { kind: "uups" });
238
+ let accessManager;
170
239
 
171
- await accessManager.deployed();
240
+ if (options.access === undefined) {
241
+ // Deploy AccessManager
242
+ accessManager = await hre.upgrades.deployProxy(AccessManager, [], { kind: "uups" });
243
+ await accessManager.deployed();
244
+ } else {
245
+ accessManager = await hre.ethers.getContractAt("AccessManager", options.access);
246
+ }
172
247
 
173
248
  const policyPool = await hre.upgrades.deployProxy(
174
249
  PolicyPool,
175
250
  [
176
- options.nftName || "Policy NFT",
177
- options.nftSymbol || "EPOL",
178
- options.treasuryAddress || hre.ethers.constants.AddressZero,
251
+ options.nftName === undefined ? "Policy NFT" : options.nftName,
252
+ options.nftSymbol === undefined ? "EPOL" : options.nftSymbol,
253
+ options.treasuryAddress || randomAddress,
179
254
  ],
180
255
  {
181
256
  constructorArgs: [accessManager.address, options.currency],
@@ -190,9 +265,12 @@ exports.deployPool = async function (hre, options) {
190
265
  await grantRole(hre, accessManager, role);
191
266
  }
192
267
 
193
- await grantRole(hre, accessManager, "LEVEL1_ROLE");
194
- await grantRole(hre, accessManager, "LEVEL2_ROLE");
195
- await grantRole(hre, accessManager, "LEVEL3_ROLE");
268
+ if (options.dontGrantL123Roles === undefined) {
269
+ await grantRole(hre, accessManager, "LEVEL1_ROLE");
270
+ await grantRole(hre, accessManager, "LEVEL2_ROLE");
271
+ await grantRole(hre, accessManager, "LEVEL3_ROLE");
272
+ }
273
+
196
274
  return policyPool;
197
275
  };
198
276
 
@@ -251,41 +329,48 @@ async function grantComponentRole(hre, accessManager, component, role, user) {
251
329
 
252
330
  exports.grantComponentRole = grantComponentRole;
253
331
 
254
- exports._E = hre.ethers.utils.parseEther;
332
+ const _E = hre.ethers.utils.parseEther;
333
+ exports._E = _E;
255
334
 
256
335
  const _BN = hre.ethers.BigNumber.from;
257
- const WAD = _BN(1e10).mul(_BN(1e8)); // 1e10*1e8=1e18
258
- const RAY = WAD.mul(_BN(1e9)); // 1e18*1e9=1e27
259
-
260
336
  exports._BN = _BN;
261
337
 
262
- const _W = function (value) {
263
- if (value === undefined) return undefined;
264
- if (!Number.isInteger(value)) return _BN(Math.round(value * 1e9)).mul(_BN(1e9));
265
- return _BN(value).mul(WAD);
266
- };
267
-
268
- exports._W = _W;
338
+ const WAD = _BN(10).pow(18); // 1e18
339
+ exports.WAD = WAD;
269
340
 
270
- const _R = function (value) {
271
- if (value === undefined) return undefined;
272
- if (!Number.isInteger(value)) return _BN(Math.round(value * 1e9)).mul(WAD);
273
- return _BN(value).mul(RAY);
274
- };
275
-
276
- exports._R = _R;
341
+ const RAY = _BN(10).pow(27); // 1e27
342
+ exports.RAY = RAY;
277
343
 
278
- exports.amountFunction = function (decimals) {
279
- // Decimals must be at least 6
344
+ /**
345
+ * Creates a fixed-point conversion function for the desired number of decimals
346
+ * @param decimals The number of decimals. Must be >= 6.
347
+ * @returns The amount function created. The function can receive strings (recommended),
348
+ * floats/doubles (not recommended) and integers.
349
+ *
350
+ * Floats will be rounded to 6 decimal before scaling.
351
+ */
352
+ function amountFunction(decimals) {
280
353
  return function (value) {
281
354
  if (value === undefined) return undefined;
355
+
282
356
  if (typeof value === "string" || value instanceof String) {
283
- return _BN(value).mul(_BN(Math.pow(10, decimals)));
284
- } else {
357
+ return hre.ethers.utils.parseUnits(value, decimals);
358
+ }
359
+
360
+ if (!Number.isInteger(value)) {
285
361
  return _BN(Math.round(value * 1e6)).mul(_BN(Math.pow(10, decimals - 6)));
286
362
  }
363
+
364
+ return _BN(value).mul(_BN(10).pow(decimals));
287
365
  };
288
- };
366
+ }
367
+ exports.amountFunction = amountFunction;
368
+
369
+ const _W = amountFunction(18);
370
+ exports._W = _W;
371
+
372
+ const _R = amountFunction(27);
373
+ exports._R = _R;
289
374
 
290
375
  /**
291
376
  * Builds the component role identifier
@@ -353,4 +438,21 @@ function getRole(role) {
353
438
 
354
439
  exports.getRole = getRole;
355
440
 
441
+ async function getStorageLayout(contractSrc, contractName) {
442
+ const buildInfo = await hre.artifacts.getBuildInfo(`${contractSrc}:${contractName}`);
443
+ if (buildInfo === undefined) throw new Error(`Contract ${contractSrc}:${contractName} not in artifacts`);
444
+
445
+ const solcOutput = buildInfo.output;
446
+
447
+ const storageLayouts = {};
448
+
449
+ for (const def of findAll("ContractDefinition", solcOutput.sources[contractSrc].ast)) {
450
+ storageLayouts[def.name] = solcOutput.contracts[contractSrc][def.name].storageLayout;
451
+ }
452
+
453
+ return storageLayouts[contractName];
454
+ }
455
+
456
+ exports.getStorageLayout = getStorageLayout;
457
+
356
458
  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": "2.0.0-beta10",
4
+ "version": "2.0.0-beta11",
5
5
  "files": [
6
6
  "**/*.sol",
7
7
  "/build/contracts/*.json",