@ensuro/core 2.0.0-beta8 → 2.0.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.
Files changed (65) hide show
  1. package/README.md +31 -14
  2. package/build/contracts/AccessManager.sol/AccessManager.json +7 -2
  3. package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +28 -3
  4. package/build/contracts/EToken.sol/EToken.json +21 -15
  5. package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +21 -2
  6. package/build/contracts/LiquidityThresholdAssetManager.sol/LiquidityThresholdAssetManager.json +26 -1
  7. package/build/contracts/Policy.sol/Policy.json +2 -2
  8. package/build/contracts/PolicyPool.sol/PolicyPool.json +40 -2
  9. package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +19 -0
  10. package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +21 -15
  11. package/build/contracts/Reserve.sol/Reserve.json +19 -13
  12. package/build/contracts/RiskModule.sol/RiskModule.json +19 -0
  13. package/build/contracts/SignedQuoteRiskModule.sol/SignedQuoteRiskModule.json +1110 -0
  14. package/build/contracts/TimeScaled.sol/TimeScaled.json +3 -17
  15. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +137 -2
  16. package/build/contracts/{WadRayMath.sol → dependencies/WadRayMath.sol}/WadRayMath.json +3 -3
  17. package/build/contracts/interfaces/IAssetManager.sol/IAssetManager.json +26 -1
  18. package/build/contracts/interfaces/IPolicyPool.sol/IPolicyPool.json +38 -0
  19. package/build/contracts/interfaces/IPolicyPoolComponent.sol/IPolicyPoolComponent.json +19 -0
  20. package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +2 -2
  21. package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +2 -2
  22. package/build/contracts/mocks/InterfaceIdCalculator.sol/InterfaceIdCalculator.json +180 -0
  23. package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +28 -2
  24. package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +21 -2
  25. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +115 -2
  26. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +2 -2
  27. package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +111 -2
  28. package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +2 -2
  29. package/build/contracts/mocks/TestNFT.sol/TestNFT.json +2 -2
  30. package/contracts/AccessManager.sol +31 -2
  31. package/contracts/ERC4626AssetManager.sol +8 -2
  32. package/contracts/EToken.sol +129 -60
  33. package/contracts/LPManualWhitelist.sol +18 -2
  34. package/contracts/LiquidityThresholdAssetManager.sol +28 -12
  35. package/contracts/Policy.sol +5 -3
  36. package/contracts/PolicyPool.sol +221 -29
  37. package/contracts/PolicyPoolComponent.sol +36 -25
  38. package/contracts/PremiumsAccount.sol +220 -32
  39. package/contracts/Reserve.sol +130 -19
  40. package/contracts/RiskModule.sol +53 -20
  41. package/contracts/SignedQuoteRiskModule.sol +310 -0
  42. package/contracts/TimeScaled.sol +19 -15
  43. package/contracts/TrustfulRiskModule.sol +107 -6
  44. package/contracts/dependencies/WadRayMath.sol +126 -0
  45. package/contracts/interfaces/IAccessManager.sol +68 -13
  46. package/contracts/interfaces/IAssetManager.sol +69 -2
  47. package/contracts/interfaces/IEToken.sol +4 -1
  48. package/contracts/interfaces/ILPWhitelist.sol +17 -0
  49. package/contracts/interfaces/IPolicyPool.sol +19 -1
  50. package/contracts/interfaces/IPolicyPoolComponent.sol +5 -1
  51. package/contracts/interfaces/IRiskModule.sol +67 -4
  52. package/contracts/mocks/InterfaceIdCalculator.sol +32 -0
  53. package/contracts/mocks/PolicyHolderMock.sol +21 -0
  54. package/contracts/mocks/PolicyPoolComponentMock.sol +10 -0
  55. package/contracts/mocks/PolicyPoolMock.sol +31 -0
  56. package/contracts/mocks/RiskModuleMock.sol +7 -1
  57. package/js/deploy.js +734 -0
  58. package/js/test-utils.js +184 -69
  59. package/package.json +4 -2
  60. package/scripts/change-pragma.sh +19 -0
  61. package/scripts/deploySmokeTest-fork.sh +53 -0
  62. package/scripts/deploySmokeTest.sh +51 -0
  63. package/scripts/storageLayout.js +33 -0
  64. package/scripts/utils.sh +65 -0
  65. package/contracts/WadRayMath.sol +0 -135
package/js/test-utils.js CHANGED
@@ -1,11 +1,14 @@
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");
5
+ const { findAll } = require("solidity-ast/utils");
6
+
4
7
  exports.WEEK = 3600 * 24 * 7;
5
8
  exports.DAY = 3600 * 24;
6
9
 
7
10
  exports.initCurrency = async function (options, initial_targets, initial_balances) {
8
- const Currency = await ethers.getContractFactory("TestCurrency");
11
+ const Currency = await hre.ethers.getContractFactory("TestCurrency");
9
12
  let currency = await Currency.deploy(
10
13
  options.name || "Test Currency",
11
14
  options.symbol || "TEST",
@@ -41,7 +44,7 @@ exports.now = function () {
41
44
  return Math.floor(new Date().getTime() / 1000);
42
45
  };
43
46
 
44
- exports.addRiskModule = async function (
47
+ const createRiskModule = async function (
45
48
  pool,
46
49
  premiumsAccount,
47
50
  contractFactory,
@@ -67,7 +70,7 @@ exports.addRiskModule = async function (
67
70
  rmName || "RiskModule",
68
71
  _W(scrPercentage) || _W(1),
69
72
  _W(ensuroFee) || _W(0),
70
- _W(scrInterestRate) || _W(0.1),
73
+ _W(scrInterestRate) || _W("0.1"),
71
74
  _A(maxScrPerPolicy) || _A(1000),
72
75
  _A(scrLimit) || _A(1000000),
73
76
  wallet || "0xdD2FD4581271e230360230F9337D5c0430Bf44C0", // Random address
@@ -86,22 +89,57 @@ exports.addRiskModule = async function (
86
89
  moc = _W(moc);
87
90
  await rm.setParam(0, moc);
88
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
+
89
127
  await pool.addComponent(rm.address, 2);
90
128
  return rm;
91
129
  };
92
130
 
93
- exports.addEToken = async function (
131
+ const createEToken = async function (
94
132
  pool,
95
133
  { etkName, etkSymbol, maxUtilizationRate, poolLoanInterestRate, extraArgs, extraConstructorArgs }
96
134
  ) {
97
- const EToken = await ethers.getContractFactory("EToken");
135
+ const EToken = await hre.ethers.getContractFactory("EToken");
98
136
  extraArgs = extraArgs || [];
99
137
  extraConstructorArgs = extraConstructorArgs || [];
100
138
  const etk = await hre.upgrades.deployProxy(
101
139
  EToken,
102
140
  [
103
- etkName || "EToken",
104
- etkSymbol || "eUSD1YEAR",
141
+ etkName === undefined ? "EToken" : etkName,
142
+ etkSymbol === undefined ? "eUSD1YEAR" : etkSymbol,
105
143
  _W(maxUtilizationRate) || _W(1),
106
144
  _W(poolLoanInterestRate) || _W("0.05"),
107
145
  ...extraArgs,
@@ -114,6 +152,23 @@ exports.addEToken = async function (
114
152
  );
115
153
 
116
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
+ });
117
172
  await pool.addComponent(etk.address, 1);
118
173
  return etk;
119
174
  };
@@ -132,7 +187,7 @@ exports.impersonate = async function (address, setBalanceTo) {
132
187
  if (setBalanceTo !== undefined)
133
188
  await hre.network.provider.request({ method: "hardhat_setBalance", params: [address, setBalanceTo.toHexString()] });
134
189
 
135
- return await ethers.getSigner(address);
190
+ return await hre.ethers.getSigner(address);
136
191
  };
137
192
 
138
193
  /**
@@ -160,21 +215,42 @@ const getTransactionEvent = function (interface, receipt, eventName) {
160
215
 
161
216
  exports.getTransactionEvent = getTransactionEvent;
162
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
+ */
163
234
  exports.deployPool = async function (hre, options) {
164
- const PolicyPool = await ethers.getContractFactory("PolicyPool");
165
- const AccessManager = await ethers.getContractFactory("AccessManager");
235
+ const PolicyPool = await hre.ethers.getContractFactory("PolicyPool");
236
+ const AccessManager = await hre.ethers.getContractFactory("AccessManager");
166
237
 
167
- // Deploy AccessManager
168
- const accessManager = await hre.upgrades.deployProxy(AccessManager, [], { kind: "uups" });
238
+ let accessManager;
169
239
 
170
- 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
+ }
171
247
 
172
248
  const policyPool = await hre.upgrades.deployProxy(
173
249
  PolicyPool,
174
250
  [
175
- options.nftName || "Policy NFT",
176
- options.nftSymbol || "EPOL",
177
- options.treasuryAddress || ethers.constants.AddressZero,
251
+ options.nftName === undefined ? "Policy NFT" : options.nftName,
252
+ options.nftSymbol === undefined ? "EPOL" : options.nftSymbol,
253
+ options.treasuryAddress || randomAddress,
178
254
  ],
179
255
  {
180
256
  constructorArgs: [accessManager.address, options.currency],
@@ -189,26 +265,31 @@ exports.deployPool = async function (hre, options) {
189
265
  await grantRole(hre, accessManager, role);
190
266
  }
191
267
 
192
- await grantRole(hre, accessManager, "LEVEL1_ROLE");
193
- await grantRole(hre, accessManager, "LEVEL2_ROLE");
194
- 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
+
195
274
  return policyPool;
196
275
  };
197
276
 
198
- exports.deployPremiumsAccount = async function (hre, pool, options) {
199
- const PremiumsAccount = await ethers.getContractFactory("PremiumsAccount");
277
+ exports.deployPremiumsAccount = async function (hre, pool, options, addToPool = true) {
278
+ const PremiumsAccount = await hre.ethers.getContractFactory("PremiumsAccount");
200
279
  const premiumsAccount = await hre.upgrades.deployProxy(PremiumsAccount, [], {
201
280
  constructorArgs: [
202
281
  pool.address,
203
- options.jrEtkAddr || ethers.constants.AddressZero,
204
- options.srEtkAddr || ethers.constants.AddressZero,
282
+ options.jrEtkAddr || hre.ethers.constants.AddressZero,
283
+ options.srEtkAddr || hre.ethers.constants.AddressZero,
205
284
  ],
206
285
  kind: "uups",
207
286
  unsafeAllow: ["delegatecall"],
208
287
  });
209
288
 
210
289
  await premiumsAccount.deployed();
211
- await pool.addComponent(premiumsAccount.address, 3);
290
+
291
+ if (addToPool) await pool.addComponent(premiumsAccount.address, 3);
292
+
212
293
  return premiumsAccount;
213
294
  };
214
295
 
@@ -225,9 +306,8 @@ async function grantRole(hre, contract, role, user) {
225
306
  } else {
226
307
  userAddress = user;
227
308
  }
228
- const roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
229
- if (!(await contract.hasRole(roleHex, userAddress))) {
230
- await contract.grantRole(roleHex, userAddress);
309
+ if (!(await contract.hasRole(getRole(role), userAddress))) {
310
+ await contract.grantRole(getRole(role), userAddress);
231
311
  }
232
312
  }
233
313
 
@@ -241,72 +321,78 @@ async function grantComponentRole(hre, accessManager, component, role, user) {
241
321
  } else {
242
322
  userAddress = user.address === undefined ? user : user.address;
243
323
  }
244
- const roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
245
- const componentRole = await accessManager.getComponentRole(component.address, roleHex);
324
+ const componentRole = getComponentRole(component.address, getRole(role));
246
325
  if (!(await accessManager.hasRole(componentRole, userAddress))) {
247
- await accessManager.grantComponentRole(component.address, roleHex, userAddress);
326
+ await accessManager.grantComponentRole(component.address, getRole(role), userAddress);
248
327
  }
249
328
  }
250
329
 
251
330
  exports.grantComponentRole = grantComponentRole;
252
331
 
253
- exports._E = ethers.utils.parseEther;
254
-
255
- const _BN = ethers.BigNumber.from;
256
- const WAD = _BN(1e10).mul(_BN(1e8)); // 1e10*1e8=1e18
257
- const RAY = WAD.mul(_BN(1e9)); // 1e18*1e9=1e27
332
+ const _E = hre.ethers.utils.parseEther;
333
+ exports._E = _E;
258
334
 
335
+ const _BN = hre.ethers.BigNumber.from;
259
336
  exports._BN = _BN;
260
337
 
261
- const _W = function (value) {
262
- if (value === undefined) return undefined;
263
- if (!Number.isInteger(value)) return _BN(Math.round(value * 1e9)).mul(_BN(1e9));
264
- return _BN(value).mul(WAD);
265
- };
338
+ const WAD = _BN(10).pow(18); // 1e18
339
+ exports.WAD = WAD;
266
340
 
267
- exports._W = _W;
268
-
269
- const _R = function (value) {
270
- if (value === undefined) return undefined;
271
- if (!Number.isInteger(value)) return _BN(Math.round(value * 1e9)).mul(WAD);
272
- return _BN(value).mul(RAY);
273
- };
341
+ const RAY = _BN(10).pow(27); // 1e27
342
+ exports.RAY = RAY;
274
343
 
275
- exports._R = _R;
276
-
277
- exports.amountFunction = function (decimals) {
278
- // 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) {
279
353
  return function (value) {
280
354
  if (value === undefined) return undefined;
355
+
281
356
  if (typeof value === "string" || value instanceof String) {
282
- return _BN(value).mul(_BN(Math.pow(10, decimals)));
283
- } else {
357
+ return hre.ethers.utils.parseUnits(value, decimals);
358
+ }
359
+
360
+ if (!Number.isInteger(value)) {
284
361
  return _BN(Math.round(value * 1e6)).mul(_BN(Math.pow(10, decimals - 6)));
285
362
  }
286
- };
287
- };
288
363
 
289
- /*
290
- Builds the component role identifier
364
+ return _BN(value).mul(_BN(10).pow(decimals));
365
+ };
366
+ }
367
+ exports.amountFunction = amountFunction;
291
368
 
292
- Mimics the behaviour of the PolicyPoolConfig.getComponentRole method
369
+ const _W = amountFunction(18);
370
+ exports._W = _W;
293
371
 
294
- Component roles are roles created doing XOR between the component
295
- address and the original role.
372
+ const _R = amountFunction(27);
373
+ exports._R = _R;
296
374
 
297
- Example:
298
- getComponentRole("0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", "ORACLE_ADMIN_ROLE")
299
- // "0x05e01b185238b49f750d03d945e38a7f6c3be8b54de0ee42d481eb7814f0d3a8"
300
- */
375
+ /**
376
+ * Builds the component role identifier
377
+ *
378
+ * Mimics the behaviour of the PolicyPoolConfig.getComponentRole method
379
+ *
380
+ * Component roles are roles created doing XOR between the component
381
+ * address and the original role.
382
+ *
383
+ * Example:
384
+ * getComponentRole("0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", "ORACLE_ADMIN_ROLE")
385
+ * // "0x05e01b185238b49f750d03d945e38a7f6c3be8b54de0ee42d481eb7814f0d3a8"
386
+ */
301
387
  function getComponentRole(componentAddress, roleName) {
302
388
  // 32 byte array
303
- const bytesRole = ethers.utils.arrayify(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(roleName)));
389
+ const bytesRole = hre.ethers.utils.arrayify(getRole(roleName));
304
390
 
305
391
  // 20 byte array
306
- const bytesAddress = ethers.utils.arrayify(componentAddress);
392
+ const bytesAddress = hre.ethers.utils.arrayify(componentAddress);
307
393
 
308
394
  // xor each byte, padding bytesAddress with zeros at the end
309
- return ethers.utils.hexlify(bytesRole.map((elem, idx) => elem ^ (bytesAddress[idx] || 0)));
395
+ return hre.ethers.utils.hexlify(bytesRole.map((elem, idx) => elem ^ (bytesAddress[idx] || 0)));
310
396
  }
311
397
 
312
398
  exports.getComponentRole = getComponentRole;
@@ -315,13 +401,15 @@ exports.getComponentRole = getComponentRole;
315
401
  Builds AccessControl error message for comparison in tests
316
402
  */
317
403
  function accessControlMessage(address, component, role) {
318
- return `AccessControl: account ${address.toLowerCase()} is missing role ${getComponentRole(component, role)}`;
404
+ const roleHash = component !== null ? getComponentRole(component, role) : getRole(role);
405
+
406
+ return `AccessControl: account ${address.toLowerCase()} is missing role ${roleHash}`;
319
407
  }
320
408
 
321
409
  exports.accessControlMessage = accessControlMessage;
322
410
 
323
411
  function makePolicyId(rm, internalId) {
324
- return ethers.BigNumber.from(rm.address).shl(96).add(internalId);
412
+ return hre.ethers.BigNumber.from(rm.address).shl(96).add(internalId);
325
413
  }
326
414
 
327
415
  exports.makePolicyId = makePolicyId;
@@ -341,3 +429,30 @@ async function blockchainNow(owner) {
341
429
  }
342
430
 
343
431
  exports.blockchainNow = blockchainNow;
432
+
433
+ function getRole(role) {
434
+ return role === "DEFAULT_ADMIN_ROLE"
435
+ ? "0x0000000000000000000000000000000000000000000000000000000000000000"
436
+ : hre.ethers.utils.keccak256(hre.ethers.utils.toUtf8Bytes(role));
437
+ }
438
+
439
+ exports.getRole = getRole;
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
+
458
+ if (process.env.ENABLE_HH_WARNINGS !== "yes") hre.upgrades.silenceWarnings();
package/package.json CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "@ensuro/core",
3
3
  "description": "Ensuro - Decentralized insurance protocol",
4
- "version": "v2.0.0-beta8",
4
+ "version": "2.0.0",
5
5
  "files": [
6
6
  "**/*.sol",
7
7
  "/build/contracts/*.json",
8
8
  "/build/interfaces/*.json",
9
- "/js/*.js"
9
+ "/js/*.js",
10
+ "/scripts/*.sh",
11
+ "/scripts/*.js"
10
12
  ],
11
13
  "repository": {
12
14
  "type": "git",
@@ -0,0 +1,19 @@
1
+ #!/bin/bash
2
+
3
+ if [ $# -ne 2 ]; then
4
+ echo "Usage $0 <contracts-dir> <new-pragma>"
5
+ exit 1
6
+ fi
7
+
8
+ CONTRACTS_DIR=$1
9
+ NEW_PRAGMA=$2
10
+
11
+ MD5S=`mktemp`
12
+
13
+ md5sum `find $CONTRACTS_DIR -name "*.sol"` > $MD5S
14
+
15
+ for SOLFILE in `find $CONTRACTS_DIR -name "*.sol"`; do
16
+ sed -i -r "s/^pragma solidity [0-9^~.]+;/pragma solidity $NEW_PRAGMA;/g" $SOLFILE
17
+ done
18
+
19
+ md5sum --check $MD5S | sed 's/: OK/: UNCHANGED/g' | sed 's/: FAILED/: MODIFIED/g' | grep -v "md5sum: "
@@ -0,0 +1,53 @@
1
+ #!/bin/bash
2
+
3
+ source `dirname $0`/utils.sh
4
+
5
+ export DEPLOY_AMOUNT_DECIMALS=6
6
+
7
+ resetAddresses
8
+
9
+ if [ -z $ALCHEMY_URL ]; then
10
+ echo "Must set environment variable $ALCHEMY_URL"
11
+ exit 1
12
+ fi
13
+
14
+ startHHNode --fork $ALCHEMY_URL
15
+
16
+ USDC=0x2791bca1f2de4661ed88a30c99a7a9449aa84174
17
+ AAVE_ADDR_PROV=0xd05e3E715d945B59290df0ae8eF85c1BdB684744 # Polygon Aave
18
+ SWAP_ROUTER=0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506 # Polygon SushiSwap
19
+ PRICE_ORACLE=0x0229f777b0fab107f9591a41d5f02e4e98db6f2d # Polygon Price Oracle of AAVE
20
+ ENSURO_TREASURY=0xFDa400f51aD6490542Bc6336Ea14b2D8bf7b0c34
21
+
22
+ npx hardhat --network $NETWORK deploy $VERIFY --currency-address $USDC \
23
+ --treasury-address $ENSURO_TREASURY || die "Error deploying pool"
24
+
25
+ POOL=`readAddress POOL`
26
+ ACCESSMANAGER=`readAddress ACCESSMANAGER`
27
+ echo "PolicyPool = $POOL / AccessManager = $ACCESSMANAGER"
28
+
29
+ for ROLE in LEVEL1 LEVEL2 LEVEL3; do
30
+ npx hardhat --network $NETWORK ens:grantRole --contract-address $ACCESSMANAGER \
31
+ --role ${ROLE}_ROLE || die "Error granting ${ROLE}_ROLE"
32
+ done
33
+
34
+ npx hardhat --network $NETWORK deploy:eToken \
35
+ --etk-name "Junior ETK" --etk-symbol "eUSDJr" --save-addr JRETK \
36
+ --pool-address $POOL $VERIFY || die "Error deploying eToken"
37
+
38
+ npx hardhat --network $NETWORK deploy:eToken \
39
+ --etk-name "Senior ETK" --etk-symbol "eUSDSr" --save-addr SRETK \
40
+ --pool-address $POOL $VERIFY || die "Error deploying eToken"
41
+
42
+ JRETK=`readAddress JRETK`
43
+ SRETK=`readAddress SRETK`
44
+
45
+ npx hardhat --network $NETWORK deploy:premiumsAccount $VERIFY \
46
+ --junior-etk $JRETK --senior-etk $SRETK \
47
+ --pool-address $POOL || die "Error deploying PremiumsAccount"
48
+
49
+ PREMIUMS_ACCOUNT=`readAddress PA`
50
+
51
+ echo "PremiumsAccount = $PREMIUMS_ACCOUNT"
52
+
53
+ killPID $HHNODE_PID
@@ -0,0 +1,51 @@
1
+ #!/bin/bash
2
+
3
+ source `dirname $0`/utils.sh
4
+
5
+ export DEPLOY_AMOUNT_DECIMALS=6
6
+
7
+ resetAddresses
8
+
9
+ startHHNode
10
+
11
+ ENSURO_TREASURY=0xFDa400f51aD6490542Bc6336Ea14b2D8bf7b0c34
12
+
13
+ npx hardhat --network $NETWORK deploy $VERIFY \
14
+ --treasury-address $ENSURO_TREASURY || die "Error deploying pool"
15
+
16
+ POOL=`readAddress POOL`
17
+ ACCESSMANAGER=`readAddress ACCESSMANAGER`
18
+ echo "PolicyPool = $POOL / AccessManager = $ACCESSMANAGER"
19
+
20
+ for ROLE in LEVEL1 LEVEL2 LEVEL3; do
21
+ npx hardhat --network $NETWORK ens:grantRole --contract-address $ACCESSMANAGER \
22
+ --role ${ROLE}_ROLE || die "Error granting ${ROLE}_ROLE"
23
+ done
24
+
25
+ npx hardhat --network $NETWORK deploy:eToken \
26
+ --etk-name "Junior ETK" --etk-symbol "eUSDJr" --save-addr JRETK \
27
+ --pool-address $POOL $VERIFY || die "Error deploying eToken"
28
+
29
+ npx hardhat --network $NETWORK deploy:eToken \
30
+ --etk-name "Senior ETK" --etk-symbol "eUSDSr" --save-addr SRETK \
31
+ --pool-address $POOL $VERIFY || die "Error deploying eToken"
32
+
33
+ JRETK=`readAddress JRETK`
34
+ SRETK=`readAddress SRETK`
35
+
36
+ npx hardhat --network $NETWORK deploy:premiumsAccount $VERIFY --pool-address $POOL \
37
+ --junior-etk $JRETK --senior-etk $SRETK || die "Error deploying Premiums Account"
38
+
39
+ PREMIUMS_ACCOUNT=`readAddress PA`
40
+
41
+ echo "PremiumsAccount = $PREMIUMS_ACCOUNT"
42
+
43
+ npx hardhat --network $NETWORK deploy:riskModule $VERIFY --pool-address $POOL \
44
+ --pa-address $PREMIUMS_ACCOUNT \
45
+ --wallet 0x951B9B8a7b0e3701E757c015F43df9F2F867B824 || die "Error deploying riskModule"
46
+
47
+ # Whitelist
48
+ npx hardhat --network $NETWORK deploy:whitelist $VERIFY \
49
+ --pool-address $POOL --e-token $SRETK || die "Error deploying Whitelist"
50
+
51
+ killPID $HHNODE_PID
@@ -0,0 +1,33 @@
1
+ const hre = require("hardhat");
2
+ const { artifacts } = require("hardhat");
3
+ const { findAll } = require("solidity-ast/utils");
4
+ const { getStorageLayout } = require("../test/test-utils");
5
+
6
+ /**
7
+ * Script to print a contracts storage layout as a table.
8
+ *
9
+ * Example usage: node scripts/storageLayout.js EToken
10
+ */
11
+
12
+ //
13
+
14
+ async function main(contractSrc, contractName) {
15
+ await hre.run("compile");
16
+ const layout = await getStorageLayout(contractSrc, contractName);
17
+
18
+ const summary = layout.storage.map((item) => ({
19
+ slot: parseInt(item.slot),
20
+ label: item.label,
21
+ type: item.type,
22
+ numberOfBytes: parseInt(layout.types[item.type].numberOfBytes),
23
+ endSlot: parseInt(item.slot) + Math.floor(parseInt(layout.types[item.type].numberOfBytes) / 32),
24
+ }));
25
+ console.table(summary);
26
+ }
27
+
28
+ const [contractSrc, contractName] = [`contracts/${process.argv[2]}.sol`, process.argv[2]];
29
+
30
+ console.log(`Storage layout for ${contractSrc}:${contractName}`);
31
+ main(contractSrc, contractName).then(() => {
32
+ process.exit(0);
33
+ });
@@ -0,0 +1,65 @@
1
+ die() {
2
+ printf "ERROR: %s\n" "$*"
3
+ exit 1
4
+ }
5
+
6
+ dieOnError() {
7
+ if [ $? -ne 0 ]; then
8
+ die $1
9
+ fi
10
+ }
11
+
12
+ export DEPLOY_AMOUNT_DECIMALS=6
13
+
14
+ NETWORK=${NETWORK:-localhost}
15
+
16
+ startHHNode() {
17
+ if [ $NETWORK == "localhost" ]; then
18
+ HHNODE_RUNNING=`ps aux | grep "/.bin/hardhat node" | grep -v grep | cut -c10-15`
19
+ if [ -z $HHNODE_RUNNING ]; then
20
+ START_HHNODE=1
21
+ fi
22
+ fi
23
+
24
+ if [ ! -z $START_HHNODE ]; then
25
+ echo "Starting hardhat node"
26
+ # npx hardhat node $* >/dev/null &
27
+ node_modules/.bin/hardhat node $* >/dev/null &
28
+
29
+ HHNODE_PID=$!
30
+ sleep 5
31
+ kill -0 $HHNODE_PID || die "Error launching hardhat node localhost"
32
+ fi
33
+ }
34
+
35
+ readAddress() {
36
+ if [ -z $ADDRESSES_FILENAME ]; then
37
+ export ADDRESSES_FILENAME=".addresses-$NETWORK.json"
38
+ fi
39
+ python -c "import json; print(json.load(open('$ADDRESSES_FILENAME'))['$1'])"
40
+ exit $?
41
+ }
42
+
43
+ resetAddresses() {
44
+ if [ -z $ADDRESSES_FILENAME ]; then
45
+ export ADDRESSES_FILENAME=".addresses-$NETWORK.json"
46
+ fi
47
+ python -c "open('$ADDRESSES_FILENAME', 'wt').write('{}')"
48
+ }
49
+
50
+ readPK() {
51
+ if [ $NETWORK != "localhost" ]; then
52
+ PK_VAR=${NETWORK^^}_ACCOUNTPK_1
53
+
54
+ if [ -z ${!PK_VAR} ]; then
55
+ read -p "Please enter the PK for the account: " -s $PK_VAR
56
+ export $PK_VAR
57
+ fi
58
+ fi
59
+ }
60
+
61
+ killPID() {
62
+ if [ ! -z $1 ]; then
63
+ kill $1
64
+ fi
65
+ }