@ensuro/core 2.0.0 → 2.1.0-beta1

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.
@@ -37,4 +37,18 @@ interface ILPWhitelist {
37
37
  address providerTo,
38
38
  uint256 amount
39
39
  ) external view returns (bool);
40
+
41
+ /**
42
+ * @dev Indicates whether or not a liquidity provider can withdraw an eToken.
43
+ *
44
+ * @param etoken The eToken (see {EToken}) where the provider wants to withdraw money.
45
+ * @param provider The address of the liquidity provider (user) that wants to withdraw
46
+ * @param amount The amount of the withdrawal
47
+ * @return true if `provider` withdraw request is accepted, false if not
48
+ */
49
+ function acceptsWithdrawal(
50
+ IEToken etoken,
51
+ address provider,
52
+ uint256 amount
53
+ ) external view returns (bool);
40
54
  }
package/js/deploy.js CHANGED
@@ -7,14 +7,34 @@ const _BN = ethers.BigNumber.from;
7
7
  const WAD = _BN(1e10).mul(_BN(1e8)); // 1e10*1e8=1e18
8
8
  const RAY = WAD.mul(_BN(1e9)); // 1e18*1e9=1e27
9
9
 
10
- function _W(value) {
11
- if (!Number.isInteger(value)) return _BN(value * 1e10).mul(_BN(1e8));
12
- return _BN(value).mul(WAD);
13
- }
10
+ const WhitelistStatus = {
11
+ notdefined: 0,
12
+ whitelisted: 1,
13
+ blacklisted: 2,
14
+ };
15
+
16
+ /**
17
+ * Creates a fixed-point conversion function for the desired number of decimals
18
+ * @param decimals The number of decimals. Must be >= 6.
19
+ * @returns The amount function created. The function can receive strings (recommended),
20
+ * floats/doubles (not recommended) and integers.
21
+ *
22
+ * Floats will be rounded to 6 decimal before scaling.
23
+ */
24
+ function amountFunction(decimals) {
25
+ return function (value) {
26
+ if (value === undefined) return undefined;
27
+
28
+ if (typeof value === "string" || value instanceof String) {
29
+ return hre.ethers.utils.parseUnits(value, decimals);
30
+ }
14
31
 
15
- function _R(value) {
16
- if (!Number.isInteger(value)) return _BN(Math.round(value * 1e9)).mul(WAD);
17
- return _BN(value).mul(RAY);
32
+ if (!Number.isInteger(value)) {
33
+ return _BN(Math.round(value * 1e6)).mul(_BN(Math.pow(10, decimals - 6)));
34
+ }
35
+
36
+ return _BN(value).mul(_BN(10).pow(decimals));
37
+ };
18
38
  }
19
39
 
20
40
  function amountDecimals() {
@@ -23,13 +43,25 @@ function amountDecimals() {
23
43
  return decimals;
24
44
  }
25
45
 
26
- function _A(value) {
27
- // Decimals must be at least 6
28
- if (typeof value === "string" || value instanceof String) {
29
- return _BN(value).mul(_BN(Math.pow(10, amountDecimals())));
30
- } else {
31
- return _BN(Math.round(value * 1e6)).mul(_BN(Math.pow(10, amountDecimals() - 6)));
46
+ const GWei = amountFunction(9);
47
+ const _W = amountFunction(18);
48
+ const _R = amountFunction(27);
49
+ const _A = amountFunction(amountDecimals());
50
+
51
+ /**
52
+ * Transaction overrides using env variables because hardhat-ethers ignores hardhat config
53
+ * See: https://hardhat.org/hardhat-runner/plugins/nomiclabs-hardhat-ethers#gas-transaction-parameters-in--hardhat.config--are-not-used
54
+ */
55
+ function txOverrides() {
56
+ const ret = {};
57
+ if (process.env.OVERRIDE_GAS_PRICE !== undefined) {
58
+ ret.gasPrice = GWei(parseFloat(process.env.OVERRIDE_GAS_PRICE));
59
+ }
60
+
61
+ if (process.env.OVERRIDE_GAS_LIMIT !== undefined) {
62
+ ret.gasLimit = parseInt(process.env.OVERRIDE_GAS_LIMIT);
32
63
  }
64
+ return ret || undefined;
33
65
  }
34
66
 
35
67
  function saveAddress(name, address) {
@@ -94,7 +126,7 @@ async function verifyContract(hre, contract, isProxy, constructorArguments) {
94
126
 
95
127
  async function deployContract({ saveAddr, verify, contractClass, constructorArgs }, hre) {
96
128
  const ContractFactory = await hre.ethers.getContractFactory(contractClass);
97
- const contract = await ContractFactory.deploy(...constructorArgs);
129
+ const contract = await ContractFactory.deploy(...constructorArgs, txOverrides());
98
130
  if (verify) {
99
131
  // From https://ethereum.stackexchange.com/a/119622/79726
100
132
  await contract.deployTransaction.wait(6);
@@ -126,6 +158,12 @@ async function deployProxyContract({ saveAddr, verify, contractClass, constructo
126
158
  return { ContractFactory, contract };
127
159
  }
128
160
 
161
+ function parseRole(role) {
162
+ if (role.startsWith("0x")) return role;
163
+ if (role === "DEFAULT_ADMIN_ROLE") return ethers.constants.HashZero;
164
+ return ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
165
+ }
166
+
129
167
  async function grantComponentRole(hre, contract, component, role, user) {
130
168
  let userAddress;
131
169
  if (user === undefined) {
@@ -134,11 +172,11 @@ async function grantComponentRole(hre, contract, component, role, user) {
134
172
  } else {
135
173
  userAddress = user;
136
174
  }
137
- const roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
175
+ const roleHex = parseRole(role);
138
176
  const componentAddress = component.address || component;
139
177
  const componentRole = await contract.getComponentRole(componentAddress, roleHex);
140
178
  if (!(await contract.hasRole(componentRole, userAddress))) {
141
- await contract.grantComponentRole(componentAddress, roleHex, userAddress);
179
+ await contract.grantComponentRole(componentAddress, roleHex, userAddress, txOverrides());
142
180
  console.log(`Role ${role} (${roleHex}) Component ${componentAddress} granted to ${userAddress}`);
143
181
  } else {
144
182
  console.log(`Role ${role} (${roleHex}) Component ${componentAddress} already granted to ${userAddress}`);
@@ -153,9 +191,9 @@ async function grantRole(hre, contract, role, user) {
153
191
  } else {
154
192
  userAddress = user;
155
193
  }
156
- const roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
194
+ const roleHex = parseRole(role);
157
195
  if (!(await contract.hasRole(roleHex, userAddress))) {
158
- await contract.grantRole(roleHex, userAddress);
196
+ await contract.grantRole(roleHex, userAddress, txOverrides());
159
197
  console.log(`Role ${role} (${roleHex}) granted to ${userAddress}`);
160
198
  } else {
161
199
  console.log(`Role ${role} (${roleHex}) already granted to ${userAddress}`);
@@ -221,7 +259,7 @@ async function deployEToken(
221
259
  hre
222
260
  );
223
261
  const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
224
- await policyPool.addComponent(contract.address, 1);
262
+ if (opts.addComponent) await policyPool.addComponent(contract.address, 1);
225
263
  return contract.address;
226
264
  }
227
265
 
@@ -236,7 +274,7 @@ async function deployPremiumsAccount({ poolAddress, juniorEtk, seniorEtk, ...opt
236
274
  hre
237
275
  );
238
276
  const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
239
- await policyPool.addComponent(contract.address, 3);
277
+ if (opts.addComponent) await policyPool.addComponent(contract.address, 3);
240
278
  return contract.address;
241
279
  }
242
280
 
@@ -302,10 +340,10 @@ async function deployRiskModule(
302
340
  await rm.setParam(4, ensuroCocFee);
303
341
  }
304
342
  if (maxDuration != 24 * 365) {
305
- await rm.setParam(9, ensuroCocFee);
343
+ await rm.setParam(9, maxDuration);
306
344
  }
307
345
  const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
308
- await policyPool.addComponent(contract.address, 2);
346
+ if (opts.addComponent) await policyPool.addComponent(contract.address, 2);
309
347
  return contract.address;
310
348
  }
311
349
 
@@ -331,7 +369,7 @@ async function deploySignedQuoteRM(opts, hre) {
331
369
 
332
370
  async function setAssetManager({ reserve, amAddress, liquidityMin, liquidityMiddle, liquidityMax }, hre) {
333
371
  const reserveContract = await hre.ethers.getContractAt("Reserve", reserve);
334
- await reserveContract.setAssetManager(amAddress, false);
372
+ const tx = await reserveContract.setAssetManager(amAddress, false);
335
373
  console.log(`Asset Manager ${amAddress} set to reserve ${reserve}`);
336
374
  if (liquidityMin !== undefined || liquidityMiddle !== undefined || liquidityMax !== undefined) {
337
375
  liquidityMin = liquidityMin === undefined ? ethers.constants.MaxUint256 : _A(liquidityMin);
@@ -341,6 +379,9 @@ async function setAssetManager({ reserve, amAddress, liquidityMin, liquidityMidd
341
379
  "ERC4626AssetManager", // Not relevant if it's ERC4626AssetManager, only need setLiquidityThresholds
342
380
  amAddress
343
381
  );
382
+
383
+ // To make sure the setAssetManager was executed - wait 2 confirmations
384
+ await tx.wait(process.env.NETWORK !== "localhost" ? 2 : undefined);
344
385
  await reserveContract.forwardToAssetManager(
345
386
  amContract.interface.encodeFunctionData("setLiquidityThresholds", [liquidityMin, liquidityMiddle, liquidityMax])
346
387
  );
@@ -375,10 +416,16 @@ async function deployAaveAssetManager({ asset, aave, amClass, ...opts }, hre) {
375
416
  }
376
417
 
377
418
  async function deployWhitelist(
378
- { wlClass, poolAddress, extraConstructorArgs, extraArgs, eToken, eToken2, eToken3, ...opts },
419
+ { wlClass, poolAddress, extraConstructorArgs, extraArgs, eToken, eToken2, eToken3, defaultStatus, ...opts },
379
420
  hre
380
421
  ) {
381
422
  extraArgs = extraArgs || [];
423
+ if (defaultStatus !== "") {
424
+ defaultStatus = defaultStatus
425
+ .split("")
426
+ .map((WB) => (WB == "W" ? WhitelistStatus.whitelisted : WhitelistStatus.blacklisted));
427
+ extraArgs.splice(0, 0, defaultStatus);
428
+ }
382
429
  extraConstructorArgs = extraConstructorArgs || [];
383
430
  const { contract } = await deployProxyContract(
384
431
  {
@@ -549,6 +596,7 @@ function add_task() {
549
596
  task("deploy:eToken", "Deploy an EToken and adds it to the pool")
550
597
  .addOptionalParam("verify", "Verify contract in Etherscan", false, types.boolean)
551
598
  .addOptionalParam("saveAddr", "Save created contract address", "ETOKEN", types.str)
599
+ .addOptionalParam("addComponent", "Adds the new component to the pool", true, types.boolean)
552
600
  .addParam("poolAddress", "PolicyPool Address", types.address)
553
601
  .addParam("etkName", "Name of EToken", types.str)
554
602
  .addParam("etkSymbol", "Symbol of EToken", types.str)
@@ -559,6 +607,7 @@ function add_task() {
559
607
  task("deploy:premiumsAccount", "Deploy a premiums account")
560
608
  .addOptionalParam("verify", "Verify contract in Etherscan", false, types.boolean)
561
609
  .addOptionalParam("saveAddr", "Save created contract address", "PA", types.str)
610
+ .addOptionalParam("addComponent", "Adds the new component to the pool", true, types.boolean)
562
611
  .addParam("poolAddress", "PolicyPool Address", types.address)
563
612
  .addParam("juniorEtk", "Junior EToken Address", types.address)
564
613
  .addParam("seniorEtk", "Senior EToken Address", types.address)
@@ -567,6 +616,7 @@ function add_task() {
567
616
  task("deploy:riskModule", "Deploys a RiskModule and adds it to the pool")
568
617
  .addOptionalParam("verify", "Verify contract in Etherscan", false, types.boolean)
569
618
  .addOptionalParam("saveAddr", "Save created contract address", "RM", types.str)
619
+ .addOptionalParam("addComponent", "Adds the new component to the pool", true, types.boolean)
570
620
  .addParam("poolAddress", "PolicyPool Address", types.address)
571
621
  .addParam("paAddress", "PremiumsAccount Address", types.address)
572
622
  .addOptionalParam("rmClass", "RiskModule contract", "TrustfulRiskModule", types.str)
@@ -587,6 +637,7 @@ function add_task() {
587
637
  task("deploy:signedQuoteRiskModule", "Deploys a RiskModule and adds it to the pool")
588
638
  .addOptionalParam("verify", "Verify contract in Etherscan", false, types.boolean)
589
639
  .addOptionalParam("saveAddr", "Save created contract address", "RM", types.str)
640
+ .addOptionalParam("addComponent", "Adds the new component to the pool", true, types.boolean)
590
641
  .addParam("poolAddress", "PolicyPool Address", types.address)
591
642
  .addParam("paAddress", "PremiumsAccount Address", types.address)
592
643
  .addOptionalParam("rmClass", "RiskModule contract", "SignedQuoteRiskModule", types.str)
@@ -608,6 +659,7 @@ function add_task() {
608
659
  task("deploy:priceRiskModule", "Deploys and injects a Price RiskModule")
609
660
  .addOptionalParam("verify", "Verify contract in Etherscan", false, types.boolean)
610
661
  .addOptionalParam("saveAddr", "Save created contract address", "RM", types.str)
662
+ .addOptionalParam("addComponent", "Adds the new component to the pool", true, types.boolean)
611
663
  .addParam("poolAddress", "PolicyPool Address", types.address)
612
664
  .addParam("paAddress", "PremiumsAccount Address", types.address)
613
665
  .addOptionalParam("rmClass", "RiskModule contract", "PriceRiskModule", types.str)
@@ -661,6 +713,7 @@ function add_task() {
661
713
  .addOptionalParam("eToken", "Set the Whitelist to a given eToken", undefined, types.address)
662
714
  .addOptionalParam("eToken2", "Set the Whitelist to a given eToken", undefined, types.address)
663
715
  .addOptionalParam("eToken3", "Set the Whitelist to a given eToken", undefined, types.address)
716
+ .addOptionalParam("defaultStatus", "Default Status Ej: 'BWWB'", "BWWB", types.str)
664
717
  .addParam("poolAddress", "PolicyPool Address", types.address)
665
718
  .setAction(deployWhitelist);
666
719
 
@@ -731,4 +784,5 @@ module.exports = {
731
784
  deploySignedQuoteRM,
732
785
  setAssetManager,
733
786
  deployWhitelist,
787
+ WhitelistStatus,
734
788
  };
package/js/test-utils.js CHANGED
@@ -414,8 +414,8 @@ function makePolicyId(rm, internalId) {
414
414
 
415
415
  exports.makePolicyId = makePolicyId;
416
416
 
417
- async function makePolicy(pool, rm, cust, payout, premium, lossProb, expiration, internalId) {
418
- let tx = await rm.connect(cust).newPolicy(payout, premium, lossProb, expiration, cust.address, internalId);
417
+ async function makePolicy(pool, rm, cust, payout, premium, lossProb, expiration, internalId, method = "newPolicy") {
418
+ let tx = await rm.connect(cust)[method](payout, premium, lossProb, expiration, cust.address, internalId);
419
419
  let receipt = await tx.wait();
420
420
  const newPolicyEvt = getTransactionEvent(pool.interface, receipt, "NewPolicy");
421
421
 
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",
4
+ "version": "v2.1.0-beta1",
5
5
  "files": [
6
6
  "**/*.sol",
7
7
  "/build/contracts/*.json",