@ensuro/core 2.0.0-beta9 → 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 (56) hide show
  1. package/README.md +14 -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 +21 -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 +1110 -0
  14. package/build/contracts/TimeScaled.sol/TimeScaled.json +2 -2
  15. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +137 -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/IPolicyPool.sol/IPolicyPool.json +19 -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 +2 -2
  24. package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +21 -2
  25. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +21 -2
  26. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +2 -2
  27. package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +21 -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 +30 -1
  31. package/contracts/ERC4626AssetManager.sol +3 -0
  32. package/contracts/EToken.sol +89 -19
  33. package/contracts/LPManualWhitelist.sol +18 -2
  34. package/contracts/LiquidityThresholdAssetManager.sol +17 -2
  35. package/contracts/Policy.sol +4 -2
  36. package/contracts/PolicyPool.sol +72 -13
  37. package/contracts/PolicyPoolComponent.sol +29 -3
  38. package/contracts/PremiumsAccount.sol +72 -24
  39. package/contracts/Reserve.sol +19 -3
  40. package/contracts/RiskModule.sol +46 -13
  41. package/contracts/SignedQuoteRiskModule.sol +310 -0
  42. package/contracts/TrustfulRiskModule.sol +104 -3
  43. package/contracts/interfaces/IAssetManager.sol +8 -3
  44. package/contracts/interfaces/IPolicyPool.sol +15 -4
  45. package/contracts/interfaces/IPolicyPoolComponent.sol +2 -1
  46. package/contracts/mocks/InterfaceIdCalculator.sol +32 -0
  47. package/contracts/mocks/PolicyPoolComponentMock.sol +10 -0
  48. package/contracts/mocks/PolicyPoolMock.sol +4 -0
  49. package/js/deploy.js +734 -0
  50. package/js/test-utils.js +139 -37
  51. package/package.json +4 -2
  52. package/scripts/change-pragma.sh +19 -0
  53. package/scripts/deploySmokeTest-fork.sh +53 -0
  54. package/scripts/deploySmokeTest.sh +51 -0
  55. package/scripts/storageLayout.js +33 -0
  56. package/scripts/utils.sh +65 -0
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,12 +1,14 @@
1
1
  {
2
2
  "name": "@ensuro/core",
3
3
  "description": "Ensuro - Decentralized insurance protocol",
4
- "version": "v2.0.0-beta9",
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
+ }