@ensuro/core 2.1.0-beta3 → 2.1.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.
package/js/deploy.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const upgrades_core = require("@openzeppelin/upgrades-core");
2
+ const helpers = require("@nomicfoundation/hardhat-network-helpers");
2
3
  const fs = require("fs");
3
4
 
4
5
  const ethers = require("ethers");
@@ -139,11 +140,15 @@ async function deployContract({ saveAddr, verify, contractClass, constructorArgs
139
140
  return { ContractFactory, contract };
140
141
  }
141
142
 
142
- async function deployProxyContract({ saveAddr, verify, contractClass, constructorArgs, initializeArgs }, hre) {
143
+ async function deployProxyContract(
144
+ { saveAddr, verify, contractClass, constructorArgs, initializeArgs, initializer },
145
+ hre
146
+ ) {
143
147
  const ContractFactory = await hre.ethers.getContractFactory(contractClass);
144
148
  const contract = await hre.upgrades.deployProxy(ContractFactory, initializeArgs || [], {
145
149
  constructorArgs: constructorArgs,
146
150
  kind: "uups",
151
+ initializer: initializer,
147
152
  unsafeAllow: ["delegatecall"],
148
153
  });
149
154
  if (verify) {
@@ -200,8 +205,15 @@ async function grantRole(hre, contract, role, user) {
200
205
  }
201
206
  }
202
207
 
203
- async function grantRoleTask({ contractAddress, role, account, component }, hre) {
204
- const contract = await hre.ethers.getContractAt("AccessManager", contractAddress);
208
+ async function grantRoleTask({ contractAddress, role, account, component, impersonate, impersonateBalance }, hre) {
209
+ let contract = await hre.ethers.getContractAt("AccessManager", contractAddress);
210
+ if (impersonate !== undefined) {
211
+ const signer = await hre.ethers.getImpersonatedSigner(impersonate);
212
+ if (impersonateBalance !== undefined) {
213
+ await helpers.setBalance(signer.address, hre.ethers.utils.parseEther(impersonateBalance));
214
+ }
215
+ contract = contract.connect(signer);
216
+ }
205
217
  if (component === ethers.constants.AddressZero) {
206
218
  await grantRole(hre, contract, role, account);
207
219
  } else {
@@ -246,7 +258,7 @@ async function deployPolicyPool({ accessAddress, currencyAddress, nftName, nftSy
246
258
  }
247
259
 
248
260
  async function deployEToken(
249
- { poolAddress, etkName, etkSymbol, maxUtilizationRate, poolLoanInterestRate, ...opts },
261
+ { poolAddress, etkName, etkSymbol, maxUtilizationRate, poolLoanInterestRate, runAs, ...opts },
250
262
  hre
251
263
  ) {
252
264
  const { contract } = await deployProxyContract(
@@ -258,12 +270,15 @@ async function deployEToken(
258
270
  },
259
271
  hre
260
272
  );
261
- const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
262
- if (opts.addComponent) await policyPool.addComponent(contract.address, 1);
273
+ if (opts.addComponent) {
274
+ let policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
275
+ if (runAs) policyPool = policyPool.connect(runAs);
276
+ await policyPool.addComponent(contract.address, 1);
277
+ }
263
278
  return contract.address;
264
279
  }
265
280
 
266
- async function deployPremiumsAccount({ poolAddress, juniorEtk, seniorEtk, ...opts }, hre) {
281
+ async function deployPremiumsAccount({ poolAddress, juniorEtk, seniorEtk, runAs, ...opts }, hre) {
267
282
  const { contract } = await deployProxyContract(
268
283
  {
269
284
  contractClass: "PremiumsAccount",
@@ -273,8 +288,11 @@ async function deployPremiumsAccount({ poolAddress, juniorEtk, seniorEtk, ...opt
273
288
  },
274
289
  hre
275
290
  );
276
- const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
277
- if (opts.addComponent) await policyPool.addComponent(contract.address, 3);
291
+ if (opts.addComponent) {
292
+ let policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
293
+ if (runAs) policyPool = policyPool.connect(runAs);
294
+ await policyPool.addComponent(contract.address, 3);
295
+ }
278
296
  return contract.address;
279
297
  }
280
298
 
@@ -297,6 +315,7 @@ async function deployRiskModule(
297
315
  wallet,
298
316
  extraArgs,
299
317
  extraConstructorArgs,
318
+ runAs,
300
319
  ...opts
301
320
  },
302
321
  hre
@@ -321,7 +340,7 @@ async function deployRiskModule(
321
340
  },
322
341
  hre
323
342
  );
324
- const rm = contract;
343
+ const rm = runAs === undefined ? contract : contract.connect(runAs);
325
344
 
326
345
  if (moc != 1.0) {
327
346
  moc = _W(moc);
@@ -342,8 +361,11 @@ async function deployRiskModule(
342
361
  if (maxDuration != 24 * 365) {
343
362
  await rm.setParam(9, maxDuration);
344
363
  }
345
- const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
346
- if (opts.addComponent) await policyPool.addComponent(contract.address, 2);
364
+ if (opts.addComponent) {
365
+ let policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
366
+ if (runAs) policyPool = policyPool.connect(runAs);
367
+ await policyPool.addComponent(contract.address, 2);
368
+ }
347
369
  return contract.address;
348
370
  }
349
371
 
@@ -416,7 +438,7 @@ async function deployAaveAssetManager({ asset, aave, amClass, ...opts }, hre) {
416
438
  }
417
439
 
418
440
  async function deployWhitelist(
419
- { wlClass, poolAddress, extraConstructorArgs, extraArgs, eToken, eToken2, eToken3, defaultStatus, ...opts },
441
+ { wlClass, poolAddress, extraConstructorArgs, extraArgs, eToken, eToken2, eToken3, defaultStatus, runAs, ...opts },
420
442
  hre
421
443
  ) {
422
444
  extraArgs = extraArgs || [];
@@ -432,6 +454,7 @@ async function deployWhitelist(
432
454
  contractClass: wlClass,
433
455
  constructorArgs: [poolAddress, ...extraConstructorArgs],
434
456
  initializeArgs: [...extraArgs],
457
+ initializer: opts.initializer,
435
458
  ...opts,
436
459
  },
437
460
  hre
@@ -762,6 +785,8 @@ function add_task() {
762
785
  task("ens:grantRole", "Grants a given role")
763
786
  .addParam("contractAddress", "Contract", undefined, types.address)
764
787
  .addParam("role", "Role", types.str)
788
+ .addOptionalParam("impersonate", "Impersonate account before granting", undefined, types.address)
789
+ .addOptionalParam("impersonateBalance", "Impersonate setBalance", undefined, types.str)
765
790
  .addOptionalParam("account", "Account", undefined, types.address)
766
791
  .addOptionalParam(
767
792
  "component",
@@ -780,9 +805,13 @@ module.exports = {
780
805
  deployProxyContract,
781
806
  grantRole,
782
807
  grantComponentRole,
808
+ deployEToken,
809
+ deployPremiumsAccount,
783
810
  deployRiskModule,
784
811
  deploySignedQuoteRM,
785
812
  setAssetManager,
786
813
  deployWhitelist,
787
814
  WhitelistStatus,
815
+ txOverrides,
816
+ _A,
788
817
  };
package/js/test-utils.js CHANGED
@@ -3,11 +3,12 @@ const hre = require("hardhat");
3
3
  const { BigNumber } = require("ethers");
4
4
  const { LogDescription } = require("ethers/lib/utils");
5
5
  const { findAll } = require("solidity-ast/utils");
6
+ const helpers = require("@nomicfoundation/hardhat-network-helpers");
6
7
 
7
- exports.WEEK = 3600 * 24 * 7;
8
- exports.DAY = 3600 * 24;
8
+ WEEK = 3600 * 24 * 7;
9
+ DAY = 3600 * 24;
9
10
 
10
- exports.initCurrency = async function (options, initial_targets, initial_balances) {
11
+ async function initCurrency(options, initial_targets, initial_balances) {
11
12
  const Currency = await hre.ethers.getContractFactory("TestCurrency");
12
13
  let currency = await Currency.deploy(
13
14
  options.name || "Test Currency",
@@ -22,27 +23,23 @@ exports.initCurrency = async function (options, initial_targets, initial_balance
22
23
  })
23
24
  );
24
25
  return currency;
25
- };
26
+ }
26
27
 
27
- exports.approve_multiple = async function (currency, spender, sources, amounts) {
28
+ async function approve_multiple(currency, spender, sources, amounts) {
28
29
  return Promise.all(
29
30
  sources.map(async function (source, index) {
30
31
  await currency.connect(source).approve(spender.address, amounts[index]);
31
32
  })
32
33
  );
33
- };
34
+ }
34
35
 
35
- exports.check_balances = async function (currency, users, amounts) {
36
+ async function check_balances(currency, users, amounts) {
36
37
  return Promise.all(
37
38
  users.map(async function (user, index) {
38
39
  expect(await currency.balanceOf(user.address)).to.equal(amounts[index]);
39
40
  })
40
41
  );
41
- };
42
-
43
- exports.now = function () {
44
- return Math.floor(new Date().getTime() / 1000);
45
- };
42
+ }
46
43
 
47
44
  const createRiskModule = async function (
48
45
  pool,
@@ -50,11 +47,11 @@ const createRiskModule = async function (
50
47
  contractFactory,
51
48
  {
52
49
  rmName,
53
- scrPercentage,
54
- scrInterestRate,
55
- ensuroFee,
56
- maxScrPerPolicy,
57
- scrLimit,
50
+ collRatio,
51
+ srRoc,
52
+ ensuroPPFee,
53
+ maxPayoutPerPolicy,
54
+ exposureLimit,
58
55
  moc,
59
56
  wallet,
60
57
  extraArgs,
@@ -68,11 +65,11 @@ const createRiskModule = async function (
68
65
  contractFactory,
69
66
  [
70
67
  rmName || "RiskModule",
71
- _W(scrPercentage) || _W(1),
72
- _W(ensuroFee) || _W(0),
73
- _W(scrInterestRate) || _W("0.1"),
74
- _A(maxScrPerPolicy) || _A(1000),
75
- _A(scrLimit) || _A(1000000),
68
+ _W(collRatio) || _W(1),
69
+ _W(ensuroPPFee) || _W(0),
70
+ _W(srRoc) || _W("0.1"),
71
+ _A(maxPayoutPerPolicy) || _A(1000),
72
+ _A(exposureLimit) || _A(1000000),
76
73
  wallet || "0xdD2FD4581271e230360230F9337D5c0430Bf44C0", // Random address
77
74
  ...extraArgs,
78
75
  ],
@@ -92,19 +89,17 @@ const createRiskModule = async function (
92
89
  return rm;
93
90
  };
94
91
 
95
- exports.createRiskModule = createRiskModule;
96
-
97
- exports.addRiskModule = async function (
92
+ async function addRiskModule(
98
93
  pool,
99
94
  premiumsAccount,
100
95
  contractFactory,
101
96
  {
102
97
  rmName,
103
- scrPercentage,
104
- scrInterestRate,
105
- ensuroFee,
106
- maxScrPerPolicy,
107
- scrLimit,
98
+ collRatio,
99
+ srRoc,
100
+ ensuroPPFee,
101
+ maxPayoutPerPolicy,
102
+ exposureLimit,
108
103
  moc,
109
104
  wallet,
110
105
  extraArgs,
@@ -113,11 +108,11 @@ exports.addRiskModule = async function (
113
108
  ) {
114
109
  const rm = await createRiskModule(pool, premiumsAccount, contractFactory, {
115
110
  rmName,
116
- scrPercentage,
117
- scrInterestRate,
118
- ensuroFee,
119
- maxScrPerPolicy,
120
- scrLimit,
111
+ collRatio,
112
+ srRoc,
113
+ ensuroPPFee,
114
+ maxPayoutPerPolicy,
115
+ exposureLimit,
121
116
  moc,
122
117
  wallet,
123
118
  extraArgs,
@@ -126,7 +121,7 @@ exports.addRiskModule = async function (
126
121
 
127
122
  await pool.addComponent(rm.address, 2);
128
123
  return rm;
129
- };
124
+ }
130
125
 
131
126
  const createEToken = async function (
132
127
  pool,
@@ -155,9 +150,7 @@ const createEToken = async function (
155
150
  return etk;
156
151
  };
157
152
 
158
- exports.createEToken = createEToken;
159
-
160
- exports.addEToken = async function (
153
+ addEToken = async function addEToken(
161
154
  pool,
162
155
  { etkName, etkSymbol, maxUtilizationRate, poolLoanInterestRate, extraArgs, extraConstructorArgs }
163
156
  ) {
@@ -173,22 +166,12 @@ exports.addEToken = async function (
173
166
  return etk;
174
167
  };
175
168
 
176
- exports.expected_change = async function (protocol_attribute, initial, change) {
169
+ async function expected_change(protocol_attribute, initial, change) {
177
170
  change = BigNumber.from(change);
178
171
  let actual_value = await protocol_attribute();
179
172
  expect(actual_value.sub(initial)).to.equal(change);
180
173
  return actual_value;
181
- };
182
-
183
- exports.impersonate = async function (address, setBalanceTo) {
184
- const ok = await hre.network.provider.request({ method: "hardhat_impersonateAccount", params: [address] });
185
- if (!ok) throw "Error impersonatting " + address;
186
-
187
- if (setBalanceTo !== undefined)
188
- await hre.network.provider.request({ method: "hardhat_setBalance", params: [address, setBalanceTo.toHexString()] });
189
-
190
- return await hre.ethers.getSigner(address);
191
- };
174
+ }
192
175
 
193
176
  /**
194
177
  * Finds an event in the receipt
@@ -199,7 +182,7 @@ exports.impersonate = async function (address, setBalanceTo) {
199
182
  */
200
183
  const getTransactionEvent = function (interface, receipt, eventName) {
201
184
  // for each log in the transaction receipt
202
- for (const log of receipt.events) {
185
+ for (const log of receipt.logs) {
203
186
  let parsedLog;
204
187
  try {
205
188
  parsedLog = interface.parseLog(log);
@@ -213,8 +196,6 @@ const getTransactionEvent = function (interface, receipt, eventName) {
213
196
  return null; // not found
214
197
  };
215
198
 
216
- exports.getTransactionEvent = getTransactionEvent;
217
-
218
199
  const randomAddress = "0x89cDb70Fee571251a66E34caa1673cE40f7549Dc";
219
200
 
220
201
  /**
@@ -231,7 +212,7 @@ const randomAddress = "0x89cDb70Fee571251a66E34caa1673cE40f7549Dc";
231
212
  * - .grantRoles: default []. List of additional roles to grant
232
213
  * - .dontGrantL123Roles: if specified, doesn't grants LEVEL1, 2 and 3 roles.
233
214
  */
234
- exports.deployPool = async function (hre, options) {
215
+ async function deployPool(hre, options) {
235
216
  const PolicyPool = await hre.ethers.getContractFactory("PolicyPool");
236
217
  const AccessManager = await hre.ethers.getContractFactory("AccessManager");
237
218
 
@@ -272,9 +253,9 @@ exports.deployPool = async function (hre, options) {
272
253
  }
273
254
 
274
255
  return policyPool;
275
- };
256
+ }
276
257
 
277
- exports.deployPremiumsAccount = async function (hre, pool, options, addToPool = true) {
258
+ async function deployPremiumsAccount(hre, pool, options, addToPool = true) {
278
259
  const PremiumsAccount = await hre.ethers.getContractFactory("PremiumsAccount");
279
260
  const premiumsAccount = await hre.upgrades.deployProxy(PremiumsAccount, [], {
280
261
  constructorArgs: [
@@ -291,7 +272,7 @@ exports.deployPremiumsAccount = async function (hre, pool, options, addToPool =
291
272
  if (addToPool) await pool.addComponent(premiumsAccount.address, 3);
292
273
 
293
274
  return premiumsAccount;
294
- };
275
+ }
295
276
 
296
277
  async function _getDefaultSigner(hre) {
297
278
  const signers = await hre.ethers.getSigners();
@@ -311,8 +292,6 @@ async function grantRole(hre, contract, role, user) {
311
292
  }
312
293
  }
313
294
 
314
- exports.grantRole = grantRole;
315
-
316
295
  async function grantComponentRole(hre, accessManager, component, role, user) {
317
296
  let userAddress;
318
297
  if (user === undefined) {
@@ -327,19 +306,13 @@ async function grantComponentRole(hre, accessManager, component, role, user) {
327
306
  }
328
307
  }
329
308
 
330
- exports.grantComponentRole = grantComponentRole;
331
-
332
309
  const _E = hre.ethers.utils.parseEther;
333
- exports._E = _E;
334
310
 
335
311
  const _BN = hre.ethers.BigNumber.from;
336
- exports._BN = _BN;
337
312
 
338
313
  const WAD = _BN(10).pow(18); // 1e18
339
- exports.WAD = WAD;
340
314
 
341
315
  const RAY = _BN(10).pow(27); // 1e27
342
- exports.RAY = RAY;
343
316
 
344
317
  /**
345
318
  * Creates a fixed-point conversion function for the desired number of decimals
@@ -364,13 +337,10 @@ function amountFunction(decimals) {
364
337
  return _BN(value).mul(_BN(10).pow(decimals));
365
338
  };
366
339
  }
367
- exports.amountFunction = amountFunction;
368
340
 
369
341
  const _W = amountFunction(18);
370
- exports._W = _W;
371
342
 
372
343
  const _R = amountFunction(27);
373
- exports._R = _R;
374
344
 
375
345
  /**
376
346
  * Builds the component role identifier
@@ -395,8 +365,6 @@ function getComponentRole(componentAddress, roleName) {
395
365
  return hre.ethers.utils.hexlify(bytesRole.map((elem, idx) => elem ^ (bytesAddress[idx] || 0)));
396
366
  }
397
367
 
398
- exports.getComponentRole = getComponentRole;
399
-
400
368
  /*
401
369
  Builds AccessControl error message for comparison in tests
402
370
  */
@@ -406,14 +374,10 @@ function accessControlMessage(address, component, role) {
406
374
  return `AccessControl: account ${address.toLowerCase()} is missing role ${roleHash}`;
407
375
  }
408
376
 
409
- exports.accessControlMessage = accessControlMessage;
410
-
411
377
  function makePolicyId(rm, internalId) {
412
378
  return hre.ethers.BigNumber.from(rm.address).shl(96).add(internalId);
413
379
  }
414
380
 
415
- exports.makePolicyId = makePolicyId;
416
-
417
381
  async function makePolicy(pool, rm, cust, payout, premium, lossProb, expiration, internalId, method = "newPolicy") {
418
382
  let tx = await rm.connect(cust)[method](payout, premium, lossProb, expiration, cust.address, internalId);
419
383
  let receipt = await tx.wait();
@@ -422,22 +386,12 @@ async function makePolicy(pool, rm, cust, payout, premium, lossProb, expiration,
422
386
  return newPolicyEvt;
423
387
  }
424
388
 
425
- exports.makePolicy = makePolicy;
426
-
427
- async function blockchainNow(owner) {
428
- return (await owner.provider.getBlock("latest")).timestamp;
429
- }
430
-
431
- exports.blockchainNow = blockchainNow;
432
-
433
389
  function getRole(role) {
434
390
  return role === "DEFAULT_ADMIN_ROLE"
435
391
  ? "0x0000000000000000000000000000000000000000000000000000000000000000"
436
392
  : hre.ethers.utils.keccak256(hre.ethers.utils.toUtf8Bytes(role));
437
393
  }
438
394
 
439
- exports.getRole = getRole;
440
-
441
395
  async function getStorageLayout(contractSrc, contractName) {
442
396
  const buildInfo = await hre.artifacts.getBuildInfo(`${contractSrc}:${contractName}`);
443
397
  if (buildInfo === undefined) throw new Error(`Contract ${contractSrc}:${contractName} not in artifacts`);
@@ -453,6 +407,49 @@ async function getStorageLayout(contractSrc, contractName) {
453
407
  return storageLayouts[contractName];
454
408
  }
455
409
 
456
- exports.getStorageLayout = getStorageLayout;
410
+ function makeQuoteMessage({ rmAddress, payout, premium, lossProb, expiration, policyData, validUntil }) {
411
+ return ethers.utils.solidityPack(
412
+ ["address", "uint256", "uint256", "uint256", "uint40", "bytes32", "uint40"],
413
+ [rmAddress, payout, premium, lossProb, expiration, policyData, validUntil]
414
+ );
415
+ }
416
+
417
+ async function makeSignedQuote(signer, policyParams) {
418
+ const quoteMessage = makeQuoteMessage(policyParams);
419
+ return ethers.utils.splitSignature(await signer.signMessage(ethers.utils.arrayify(quoteMessage)));
420
+ }
457
421
 
458
422
  if (process.env.ENABLE_HH_WARNINGS !== "yes") hre.upgrades.silenceWarnings();
423
+
424
+ module.exports = {
425
+ getStorageLayout,
426
+ makeQuoteMessage,
427
+ makeSignedQuote,
428
+ getRole,
429
+ WEEK,
430
+ DAY,
431
+ createRiskModule,
432
+ createEToken,
433
+ grantRole,
434
+ grantComponentRole,
435
+ initCurrency,
436
+ approve_multiple,
437
+ check_balances,
438
+ addRiskModule,
439
+ addEToken,
440
+ expected_change,
441
+ getTransactionEvent,
442
+ deployPool,
443
+ deployPremiumsAccount,
444
+ _E,
445
+ _BN,
446
+ WAD,
447
+ RAY,
448
+ amountFunction,
449
+ _W,
450
+ _R,
451
+ getComponentRole,
452
+ accessControlMessage,
453
+ makePolicyId,
454
+ makePolicy,
455
+ };
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.1.0-beta3",
4
+ "version": "2.1.0",
5
5
  "files": [
6
6
  "**/*.sol",
7
7
  "/build/contracts/*.json",