@ensuro/core 2.5.0 → 2.6.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/test-utils.js CHANGED
@@ -1,12 +1,8 @@
1
- const { expect } = require("chai");
2
1
  const hre = require("hardhat");
3
- const { BigNumber } = require("ethers");
4
- const { LogDescription } = require("ethers/lib/utils");
5
- const { findAll } = require("solidity-ast/utils");
6
- const helpers = require("@nomicfoundation/hardhat-network-helpers");
2
+ const { _W, grantRole, getTransactionEvent } = require("../js/utils");
3
+ const { RiskModuleParameter } = require("../js/enums");
7
4
 
8
- WEEK = 3600 * 24 * 7;
9
- DAY = 3600 * 24;
5
+ const { AddressZero } = hre.ethers.constants;
10
6
 
11
7
  async function initCurrency(options, initial_targets, initial_balances) {
12
8
  const Currency = await hre.ethers.getContractFactory("TestCurrency");
@@ -25,36 +21,7 @@ async function initCurrency(options, initial_targets, initial_balances) {
25
21
  return currency;
26
22
  }
27
23
 
28
- async function approve_multiple(currency, spender, sources, amounts) {
29
- return Promise.all(
30
- sources.map(async function (source, index) {
31
- await currency.connect(source).approve(spender.address, amounts[index]);
32
- })
33
- );
34
- }
35
-
36
- async function check_balances(currency, users, amounts) {
37
- return Promise.all(
38
- users.map(async function (user, index) {
39
- expect(await currency.balanceOf(user.address)).to.equal(amounts[index]);
40
- })
41
- );
42
- }
43
-
44
- const RiskModuleParameter = {
45
- moc: 0,
46
- jrCollRatio: 1,
47
- collRatio: 2,
48
- ensuroPpFee: 3,
49
- ensuroCocFee: 4,
50
- jrRoc: 5,
51
- srRoc: 6,
52
- maxPayoutPerPolicy: 7,
53
- exposureLimit: 8,
54
- maxDuration: 9,
55
- };
56
-
57
- const createRiskModule = async function (
24
+ async function createRiskModule(
58
25
  pool,
59
26
  premiumsAccount,
60
27
  contractFactory,
@@ -99,7 +66,7 @@ const createRiskModule = async function (
99
66
  await rm.setParam(RiskModuleParameter.moc, moc);
100
67
  }
101
68
  return rm;
102
- };
69
+ }
103
70
 
104
71
  async function addRiskModule(
105
72
  pool,
@@ -135,7 +102,7 @@ async function addRiskModule(
135
102
  return rm;
136
103
  }
137
104
 
138
- const createEToken = async function (
105
+ async function createEToken(
139
106
  pool,
140
107
  { etkName, etkSymbol, maxUtilizationRate, poolLoanInterestRate, extraArgs, extraConstructorArgs }
141
108
  ) {
@@ -160,9 +127,9 @@ const createEToken = async function (
160
127
 
161
128
  await etk.deployed();
162
129
  return etk;
163
- };
130
+ }
164
131
 
165
- addEToken = async function addEToken(
132
+ async function addEToken(
166
133
  pool,
167
134
  { etkName, etkSymbol, maxUtilizationRate, poolLoanInterestRate, extraArgs, extraConstructorArgs }
168
135
  ) {
@@ -176,42 +143,12 @@ addEToken = async function addEToken(
176
143
  });
177
144
  await pool.addComponent(etk.address, 1);
178
145
  return etk;
179
- };
180
-
181
- async function expected_change(protocol_attribute, initial, change) {
182
- change = BigNumber.from(change);
183
- let actual_value = await protocol_attribute();
184
- expect(actual_value.sub(initial)).to.equal(change);
185
- return actual_value;
186
146
  }
187
147
 
188
- /**
189
- * Finds an event in the receipt
190
- * @param {Interface} interface The interface of the contract that contains the requested event
191
- * @param {TransactionReceipt} receipt Transaction receipt containing the events in the logs
192
- * @param {String} eventName The name of the event we are interested in
193
- * @returns {LogDescription}
194
- */
195
- const getTransactionEvent = function (interface, receipt, eventName) {
196
- // for each log in the transaction receipt
197
- for (const log of receipt.logs) {
198
- let parsedLog;
199
- try {
200
- parsedLog = interface.parseLog(log);
201
- } catch (error) {
202
- continue;
203
- }
204
- if (parsedLog.name == eventName) {
205
- return parsedLog;
206
- }
207
- }
208
- return null; // not found
209
- };
210
-
211
148
  const randomAddress = "0x89cDb70Fee571251a66E34caa1673cE40f7549Dc";
212
149
 
213
150
  /**
214
- * Deploys de PolicyPool contract and AccessManager
151
+ * Deploys the PolicyPool contract and AccessManager
215
152
  *
216
153
  * By default deployes de PolicyPool and AccessManager and grants LEVEL 1, 2, 3 permissions
217
154
  *
@@ -224,7 +161,7 @@ const randomAddress = "0x89cDb70Fee571251a66E34caa1673cE40f7549Dc";
224
161
  * - .grantRoles: default []. List of additional roles to grant
225
162
  * - .dontGrantL123Roles: if specified, doesn't grants LEVEL1, 2 and 3 roles.
226
163
  */
227
- async function deployPool(hre, options) {
164
+ async function deployPool(options) {
228
165
  const PolicyPool = await hre.ethers.getContractFactory("PolicyPool");
229
166
  const AccessManager = await hre.ethers.getContractFactory("AccessManager");
230
167
 
@@ -266,14 +203,10 @@ async function deployPool(hre, options) {
266
203
  return policyPool;
267
204
  }
268
205
 
269
- async function deployPremiumsAccount(hre, pool, options, addToPool = true) {
206
+ async function deployPremiumsAccount(pool, options, addToPool = true) {
270
207
  const PremiumsAccount = await hre.ethers.getContractFactory("PremiumsAccount");
271
208
  const premiumsAccount = await hre.upgrades.deployProxy(PremiumsAccount, [], {
272
- constructorArgs: [
273
- pool.address,
274
- options.jrEtkAddr || hre.ethers.constants.AddressZero,
275
- options.srEtkAddr || hre.ethers.constants.AddressZero,
276
- ],
209
+ constructorArgs: [pool.address, options.jrEtkAddr || AddressZero, options.srEtkAddr || AddressZero],
277
210
  kind: "uups",
278
211
  unsafeAllow: ["delegatecall"], // This holds, because EToken is a reserve and uses delegatecall
279
212
  });
@@ -285,112 +218,6 @@ async function deployPremiumsAccount(hre, pool, options, addToPool = true) {
285
218
  return premiumsAccount;
286
219
  }
287
220
 
288
- async function _getDefaultSigner(hre) {
289
- const signers = await hre.ethers.getSigners();
290
- return signers[0];
291
- }
292
-
293
- async function grantRole(hre, contract, role, user) {
294
- let userAddress;
295
- if (user === undefined) {
296
- user = await _getDefaultSigner(hre);
297
- userAddress = user.address;
298
- } else {
299
- userAddress = user;
300
- }
301
- if (!(await contract.hasRole(getRole(role), userAddress))) {
302
- await contract.grantRole(getRole(role), userAddress);
303
- }
304
- }
305
-
306
- async function grantComponentRole(hre, accessManager, component, role, user) {
307
- let userAddress;
308
- if (user === undefined) {
309
- user = await _getDefaultSigner(hre);
310
- userAddress = user.address;
311
- } else {
312
- userAddress = user.address === undefined ? user : user.address;
313
- }
314
- const componentRole = getComponentRole(component.address, getRole(role));
315
- if (!(await accessManager.hasRole(componentRole, userAddress))) {
316
- await accessManager.grantComponentRole(component.address, getRole(role), userAddress);
317
- }
318
- }
319
-
320
- const _E = hre.ethers.utils.parseEther;
321
-
322
- const _BN = hre.ethers.BigNumber.from;
323
-
324
- const WAD = _BN(10).pow(18); // 1e18
325
-
326
- const RAY = _BN(10).pow(27); // 1e27
327
-
328
- /**
329
- * Creates a fixed-point conversion function for the desired number of decimals
330
- * @param decimals The number of decimals. Must be >= 6.
331
- * @returns The amount function created. The function can receive strings (recommended),
332
- * floats/doubles (not recommended) and integers.
333
- *
334
- * Floats will be rounded to 6 decimal before scaling.
335
- */
336
- function amountFunction(decimals) {
337
- return function (value) {
338
- if (value === undefined) return undefined;
339
-
340
- if (typeof value === "string" || value instanceof String) {
341
- return hre.ethers.utils.parseUnits(value, decimals);
342
- }
343
-
344
- if (!Number.isInteger(value)) {
345
- return _BN(Math.round(value * 1e6)).mul(_BN(Math.pow(10, decimals - 6)));
346
- }
347
-
348
- return _BN(value).mul(_BN(10).pow(decimals));
349
- };
350
- }
351
-
352
- const _W = amountFunction(18);
353
-
354
- const _R = amountFunction(27);
355
-
356
- /**
357
- * Builds the component role identifier
358
- *
359
- * Mimics the behaviour of the PolicyPoolConfig.getComponentRole method
360
- *
361
- * Component roles are roles created doing XOR between the component
362
- * address and the original role.
363
- *
364
- * Example:
365
- * getComponentRole("0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", "ORACLE_ADMIN_ROLE")
366
- * // "0x05e01b185238b49f750d03d945e38a7f6c3be8b54de0ee42d481eb7814f0d3a8"
367
- */
368
- function getComponentRole(componentAddress, role) {
369
- if (!role.startsWith("0x")) role = getRole(role);
370
-
371
- // 32 byte array
372
- const bytesRole = hre.ethers.utils.arrayify(role);
373
-
374
- // 20 byte array
375
- const bytesAddress = hre.ethers.utils.arrayify(componentAddress);
376
-
377
- // xor each byte, padding bytesAddress with zeros at the end
378
- return hre.ethers.utils.hexlify(bytesRole.map((elem, idx) => elem ^ (bytesAddress[idx] || 0)));
379
- }
380
-
381
- /*
382
- Builds AccessControl error message for comparison in tests
383
- */
384
- function accessControlMessage(address, component, role) {
385
- const roleHash = component !== null ? getComponentRole(component, role) : getRole(role);
386
-
387
- return `AccessControl: account ${address.toLowerCase()} is missing role ${roleHash}`;
388
- }
389
-
390
- function makePolicyId(rm, internalId) {
391
- return hre.ethers.BigNumber.from(rm.address).shl(96).add(internalId);
392
- }
393
-
394
221
  async function makePolicy(pool, rm, cust, payout, premium, lossProb, expiration, internalId, method = "newPolicy") {
395
222
  let tx = await rm.connect(cust)[method](payout, premium, lossProb, expiration, cust.address, internalId);
396
223
  let receipt = await tx.wait();
@@ -399,71 +226,15 @@ async function makePolicy(pool, rm, cust, payout, premium, lossProb, expiration,
399
226
  return newPolicyEvt;
400
227
  }
401
228
 
402
- function getRole(role) {
403
- return role === "DEFAULT_ADMIN_ROLE"
404
- ? "0x0000000000000000000000000000000000000000000000000000000000000000"
405
- : hre.ethers.utils.keccak256(hre.ethers.utils.toUtf8Bytes(role));
406
- }
407
-
408
- async function getStorageLayout(contractSrc, contractName) {
409
- const buildInfo = await hre.artifacts.getBuildInfo(`${contractSrc}:${contractName}`);
410
- if (buildInfo === undefined) throw new Error(`Contract ${contractSrc}:${contractName} not in artifacts`);
411
-
412
- const solcOutput = buildInfo.output;
413
-
414
- const storageLayouts = {};
415
-
416
- for (const def of findAll("ContractDefinition", solcOutput.sources[contractSrc].ast)) {
417
- storageLayouts[def.name] = solcOutput.contracts[contractSrc][def.name].storageLayout;
418
- }
419
-
420
- return storageLayouts[contractName];
421
- }
422
-
423
- function makeQuoteMessage({ rmAddress, payout, premium, lossProb, expiration, policyData, validUntil }) {
424
- return ethers.utils.solidityPack(
425
- ["address", "uint256", "uint256", "uint256", "uint40", "bytes32", "uint40"],
426
- [rmAddress, payout, premium, lossProb, expiration, policyData, validUntil]
427
- );
428
- }
429
-
430
- async function makeSignedQuote(signer, policyParams) {
431
- const quoteMessage = makeQuoteMessage(policyParams);
432
- return ethers.utils.splitSignature(await signer.signMessage(ethers.utils.arrayify(quoteMessage)));
433
- }
434
-
435
229
  if (process.env.ENABLE_HH_WARNINGS !== "yes") hre.upgrades.silenceWarnings();
436
230
 
437
231
  module.exports = {
438
- _BN,
439
- _E,
440
- _R,
441
- _W,
442
- accessControlMessage,
443
232
  addEToken,
444
233
  addRiskModule,
445
- amountFunction,
446
- approve_multiple,
447
- check_balances,
448
234
  createEToken,
449
235
  createRiskModule,
450
- DAY,
451
236
  deployPool,
452
237
  deployPremiumsAccount,
453
- expected_change,
454
- getComponentRole,
455
- getRole,
456
- getStorageLayout,
457
- getTransactionEvent,
458
- grantComponentRole,
459
- grantRole,
460
238
  initCurrency,
461
239
  makePolicy,
462
- makePolicyId,
463
- makeQuoteMessage,
464
- makeSignedQuote,
465
- RAY,
466
- RiskModuleParameter,
467
- WAD,
468
- WEEK,
469
240
  };
package/js/utils.js ADDED
@@ -0,0 +1,264 @@
1
+ const { findAll } = require("solidity-ast/utils");
2
+ const ethers = require("ethers");
3
+ const helpers = require("@nomicfoundation/hardhat-network-helpers");
4
+
5
+ const _E = ethers.utils.parseEther;
6
+ const _BN = ethers.BigNumber.from;
7
+ const WAD = _BN(10).pow(18); // 1e18
8
+ const RAY = _BN(10).pow(27); // 1e27
9
+
10
+ async function getStorageLayout(hre, contractSrc, contractName) {
11
+ const buildInfo = await hre.artifacts.getBuildInfo(`${contractSrc}:${contractName}`);
12
+ if (buildInfo === undefined) throw new Error(`Contract ${contractSrc}:${contractName} not in artifacts`);
13
+
14
+ const solcOutput = buildInfo.output;
15
+
16
+ const storageLayouts = {};
17
+
18
+ for (const def of findAll("ContractDefinition", solcOutput.sources[contractSrc].ast)) {
19
+ storageLayouts[def.name] = solcOutput.contracts[contractSrc][def.name].storageLayout;
20
+ }
21
+
22
+ return storageLayouts[contractName];
23
+ }
24
+
25
+ /**
26
+ * Creates a fixed-point conversion function for the desired number of decimals
27
+ * @param decimals The number of decimals. Must be >= 6.
28
+ * @returns The amount function created. The function can receive strings (recommended),
29
+ * floats/doubles (not recommended) and integers.
30
+ *
31
+ * Floats will be rounded to 6 decimal before scaling.
32
+ */
33
+ function amountFunction(decimals) {
34
+ return function (value) {
35
+ if (value === undefined) return undefined;
36
+
37
+ if (typeof value === "string" || value instanceof String) {
38
+ return ethers.utils.parseUnits(value, decimals);
39
+ }
40
+
41
+ if (!Number.isInteger(value)) {
42
+ return _BN(Math.round(value * 1e6)).mul(_BN(Math.pow(10, decimals - 6)));
43
+ }
44
+
45
+ return _BN(value).mul(_BN(10).pow(decimals));
46
+ };
47
+ }
48
+
49
+ /** Wad function */
50
+ const _W = amountFunction(18);
51
+
52
+ /** Ray function */
53
+ const _R = amountFunction(27);
54
+
55
+ /**
56
+ * Returns a role identifier by computing the keccak of the role name.
57
+ */
58
+ function getRole(role) {
59
+ if (role.startsWith("0x")) return role;
60
+ return role === "DEFAULT_ADMIN_ROLE"
61
+ ? ethers.constants.HashZero
62
+ : ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
63
+ }
64
+
65
+ /**
66
+ * Builds the component role identifier
67
+ *
68
+ * Mimics the behaviour of the AccessManager.getComponentRole method
69
+ *
70
+ * Component roles are roles created doing XOR between the component
71
+ * address and the original role.
72
+ *
73
+ * Example:
74
+ * getComponentRole("0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", "ORACLE_ADMIN_ROLE")
75
+ * // "0x05e01b185238b49f750d03d945e38a7f6c3be8b54de0ee42d481eb7814f0d3a8"
76
+ */
77
+ function getComponentRole(componentAddress, role) {
78
+ if (!role.startsWith("0x")) role = getRole(role);
79
+
80
+ // 32 byte array
81
+ const bytesRole = ethers.utils.arrayify(role);
82
+
83
+ // 20 byte array
84
+ const bytesAddress = ethers.utils.arrayify(componentAddress);
85
+
86
+ // xor each byte, padding bytesAddress with zeros at the end
87
+ // eslint-disable-next-line no-bitwise
88
+ return ethers.utils.hexlify(bytesRole.map((elem, idx) => elem ^ (bytesAddress[idx] || 0)));
89
+ }
90
+
91
+ async function getDefaultSigner(hre) {
92
+ const signers = await hre.ethers.getSigners();
93
+ return signers[0];
94
+ }
95
+
96
+ /**
97
+ * Grant a component role to a user.
98
+ */
99
+ // eslint-disable-next-line no-empty-function
100
+ async function grantComponentRole(hre, contract, component, role, user, txOverrides = {}, log = () => {}) {
101
+ let userAddress;
102
+ if (user === undefined) {
103
+ user = await getDefaultSigner(hre);
104
+ userAddress = user.address;
105
+ } else {
106
+ userAddress = user.address === undefined ? user : user.address;
107
+ }
108
+ const roleHex = getRole(role);
109
+ const componentAddress = component.address || component;
110
+ const componentRole = await contract.getComponentRole(componentAddress, roleHex);
111
+ if (!(await contract.hasRole(componentRole, userAddress))) {
112
+ await contract.grantComponentRole(componentAddress, roleHex, userAddress, txOverrides);
113
+ log(`Role ${role} (${roleHex}) Component ${componentAddress} granted to ${userAddress}`);
114
+ } else {
115
+ log(`Role ${role} (${roleHex}) Component ${componentAddress} already granted to ${userAddress}`);
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Grant a role to a user
121
+ */
122
+ // eslint-disable-next-line no-empty-function
123
+ async function grantRole(hre, contract, role, user, txOverrides = {}, log = () => {}) {
124
+ let userAddress;
125
+ if (user === undefined) {
126
+ user = await getDefaultSigner(hre);
127
+ userAddress = user.address;
128
+ } else {
129
+ userAddress = user.address === undefined ? user : user.address;
130
+ }
131
+ const roleHex = getRole(role);
132
+ if (!(await contract.hasRole(roleHex, userAddress))) {
133
+ await contract.grantRole(roleHex, userAddress, txOverrides);
134
+ log(`Role ${role} (${roleHex}) granted to ${userAddress}`);
135
+ } else {
136
+ log(`Role ${role} (${roleHex}) already granted to ${userAddress}`);
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Finds an event in the receipt
142
+ * @param {Interface} interface The interface of the contract that contains the requested event
143
+ * @param {TransactionReceipt} receipt Transaction receipt containing the events in the logs
144
+ * @param {String} eventName The name of the event we are interested in
145
+ * @returns {LogDescription}
146
+ */
147
+ function getTransactionEvent(interface, receipt, eventName) {
148
+ // for each log in the transaction receipt
149
+ for (const log of receipt.logs) {
150
+ let parsedLog;
151
+ try {
152
+ parsedLog = interface.parseLog(log);
153
+ } catch (error) {
154
+ continue;
155
+ }
156
+ if (parsedLog.name == eventName) {
157
+ return parsedLog;
158
+ }
159
+ }
160
+ return null; // not found
161
+ }
162
+
163
+ /**
164
+ * Builds AccessControl error message for comparison in tests
165
+ */
166
+ function accessControlMessage(address, component, role) {
167
+ const roleHash = component !== null ? getComponentRole(component, role) : getRole(role);
168
+
169
+ return `AccessControl: account ${address.toLowerCase()} is missing role ${roleHash}`;
170
+ }
171
+
172
+ /**
173
+ * Create a policy id by combining the riskmodule address and the internal id.
174
+ *
175
+ * Mimics the PolicyPool.newPolicy method of building the policy id.
176
+ */
177
+ function makePolicyId(rmAddress, internalId) {
178
+ return _BN(rmAddress).shl(96).add(internalId);
179
+ }
180
+
181
+ /**
182
+ * Create a packed quote message for later signing or hashing.
183
+ *
184
+ * Mimics the behaviour of the SignedQuoteRiskModule._newSignedPolicy method.
185
+ */
186
+ function makeQuoteMessage({ rmAddress, payout, premium, lossProb, expiration, policyData, validUntil }) {
187
+ return ethers.utils.solidityPack(
188
+ ["address", "uint256", "uint256", "uint256", "uint40", "bytes32", "uint40"],
189
+ [rmAddress, payout, premium, lossProb, expiration, policyData, validUntil]
190
+ );
191
+ }
192
+
193
+ /**
194
+ * Create a packed quote message for later signing or hashing.
195
+ *
196
+ * Mimics the behaviour of the SignedBucketRiskModule._newSignedPolicy method.
197
+ */
198
+ function makeBucketQuoteMessage({
199
+ rmAddress,
200
+ payout,
201
+ premium,
202
+ lossProb,
203
+ expiration,
204
+ policyData,
205
+ bucketId,
206
+ validUntil,
207
+ }) {
208
+ return ethers.utils.solidityPack(
209
+ ["address", "uint256", "uint256", "uint256", "uint40", "bytes32", "uint256", "uint40"],
210
+ [rmAddress, payout, premium, lossProb, expiration, policyData, bucketId, validUntil]
211
+ );
212
+ }
213
+
214
+ /**
215
+ * Creates and signs a quote message from its policy parameters.
216
+ *
217
+ * Mimics the behaviour of policy-quote-api.
218
+ */
219
+ async function makeSignedQuote(signer, policyParams, makeQuoteMessageFn = makeQuoteMessage) {
220
+ const quoteMessage = makeQuoteMessageFn(policyParams);
221
+ return ethers.utils.splitSignature(await signer.signMessage(ethers.utils.arrayify(quoteMessage)));
222
+ }
223
+
224
+ /**
225
+ * Build a default policy parameters object.
226
+ */
227
+ async function defaultPolicyParams(
228
+ { rmAddress, payout, premium, lossProb, expiration, policyData, validUntil },
229
+ _A = amountFunction(6)
230
+ ) {
231
+ const now = await helpers.time.latest();
232
+ return {
233
+ rmAddress,
234
+ payout: payout || _A(1000),
235
+ premium: premium || ethers.constants.MaxUint256,
236
+ lossProb: lossProb || _W(0.1),
237
+ expiration: expiration || now + 3600 * 24 * 30,
238
+ policyData: policyData || ethers.utils.hexlify(ethers.utils.randomBytes(32)),
239
+ validUntil: validUntil || now + 3600 * 24 * 30,
240
+ };
241
+ }
242
+
243
+ module.exports = {
244
+ _BN,
245
+ _E,
246
+ _R,
247
+ _W,
248
+ accessControlMessage,
249
+ amountFunction,
250
+ defaultPolicyParams,
251
+ getComponentRole,
252
+ getDefaultSigner,
253
+ getRole,
254
+ getStorageLayout,
255
+ getTransactionEvent,
256
+ grantComponentRole,
257
+ grantRole,
258
+ makeBucketQuoteMessage,
259
+ makePolicyId,
260
+ makeQuoteMessage,
261
+ makeSignedQuote,
262
+ RAY,
263
+ WAD,
264
+ };
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.5.0",
4
+ "version": "2.6.0",
5
5
  "files": [
6
6
  "**/*.sol",
7
7
  "/build/contracts/*.json",
@@ -1,7 +1,5 @@
1
1
  const hre = require("hardhat");
2
- const { artifacts } = require("hardhat");
3
- const { findAll } = require("solidity-ast/utils");
4
- const { getStorageLayout } = require("../test/test-utils");
2
+ const { getStorageLayout } = require("../js/utils");
5
3
 
6
4
  /**
7
5
  * Script to print a contracts storage layout as a table.
@@ -9,11 +7,9 @@ const { getStorageLayout } = require("../test/test-utils");
9
7
  * Example usage: node scripts/storageLayout.js EToken
10
8
  */
11
9
 
12
- //
13
-
14
10
  async function main(contractSrc, contractName) {
15
11
  await hre.run("compile");
16
- const layout = await getStorageLayout(contractSrc, contractName);
12
+ const layout = await getStorageLayout(hre, contractSrc, contractName);
17
13
 
18
14
  const summary = layout.storage.map((item) => ({
19
15
  slot: parseInt(item.slot),
@@ -29,5 +25,6 @@ const [contractSrc, contractName] = [`contracts/${process.argv[2]}.sol`, process
29
25
 
30
26
  console.log(`Storage layout for ${contractSrc}:${contractName}`);
31
27
  main(contractSrc, contractName).then(() => {
28
+ // eslint-disable-next-line no-process-exit
32
29
  process.exit(0);
33
30
  });