@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.
- package/README.md +31 -14
- package/build/contracts/AccessManager.sol/AccessManager.json +7 -2
- package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +28 -3
- package/build/contracts/EToken.sol/EToken.json +21 -15
- package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +21 -2
- package/build/contracts/LiquidityThresholdAssetManager.sol/LiquidityThresholdAssetManager.json +26 -1
- package/build/contracts/Policy.sol/Policy.json +2 -2
- package/build/contracts/PolicyPool.sol/PolicyPool.json +40 -2
- package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +19 -0
- package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +21 -15
- package/build/contracts/Reserve.sol/Reserve.json +19 -13
- package/build/contracts/RiskModule.sol/RiskModule.json +19 -0
- package/build/contracts/SignedQuoteRiskModule.sol/SignedQuoteRiskModule.json +1110 -0
- package/build/contracts/TimeScaled.sol/TimeScaled.json +3 -17
- package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +137 -2
- package/build/contracts/{WadRayMath.sol → dependencies/WadRayMath.sol}/WadRayMath.json +3 -3
- package/build/contracts/interfaces/IAssetManager.sol/IAssetManager.json +26 -1
- package/build/contracts/interfaces/IPolicyPool.sol/IPolicyPool.json +38 -0
- package/build/contracts/interfaces/IPolicyPoolComponent.sol/IPolicyPoolComponent.json +19 -0
- package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +2 -2
- package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +2 -2
- package/build/contracts/mocks/InterfaceIdCalculator.sol/InterfaceIdCalculator.json +180 -0
- package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +28 -2
- package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +21 -2
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +115 -2
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +2 -2
- package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +111 -2
- package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +2 -2
- package/build/contracts/mocks/TestNFT.sol/TestNFT.json +2 -2
- package/contracts/AccessManager.sol +31 -2
- package/contracts/ERC4626AssetManager.sol +8 -2
- package/contracts/EToken.sol +129 -60
- package/contracts/LPManualWhitelist.sol +18 -2
- package/contracts/LiquidityThresholdAssetManager.sol +28 -12
- package/contracts/Policy.sol +5 -3
- package/contracts/PolicyPool.sol +221 -29
- package/contracts/PolicyPoolComponent.sol +36 -25
- package/contracts/PremiumsAccount.sol +220 -32
- package/contracts/Reserve.sol +130 -19
- package/contracts/RiskModule.sol +53 -20
- package/contracts/SignedQuoteRiskModule.sol +310 -0
- package/contracts/TimeScaled.sol +19 -15
- package/contracts/TrustfulRiskModule.sol +107 -6
- package/contracts/dependencies/WadRayMath.sol +126 -0
- package/contracts/interfaces/IAccessManager.sol +68 -13
- package/contracts/interfaces/IAssetManager.sol +69 -2
- package/contracts/interfaces/IEToken.sol +4 -1
- package/contracts/interfaces/ILPWhitelist.sol +17 -0
- package/contracts/interfaces/IPolicyPool.sol +19 -1
- package/contracts/interfaces/IPolicyPoolComponent.sol +5 -1
- package/contracts/interfaces/IRiskModule.sol +67 -4
- package/contracts/mocks/InterfaceIdCalculator.sol +32 -0
- package/contracts/mocks/PolicyHolderMock.sol +21 -0
- package/contracts/mocks/PolicyPoolComponentMock.sol +10 -0
- package/contracts/mocks/PolicyPoolMock.sol +31 -0
- package/contracts/mocks/RiskModuleMock.sol +7 -1
- package/js/deploy.js +734 -0
- package/js/test-utils.js +184 -69
- package/package.json +4 -2
- package/scripts/change-pragma.sh +19 -0
- package/scripts/deploySmokeTest-fork.sh +53 -0
- package/scripts/deploySmokeTest.sh +51 -0
- package/scripts/storageLayout.js +33 -0
- package/scripts/utils.sh +65 -0
- 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
|
-
|
|
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
|
-
|
|
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
|
|
104
|
-
etkSymbol
|
|
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
|
-
|
|
168
|
-
const accessManager = await hre.upgrades.deployProxy(AccessManager, [], { kind: "uups" });
|
|
238
|
+
let accessManager;
|
|
169
239
|
|
|
170
|
-
|
|
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
|
|
176
|
-
options.nftSymbol
|
|
177
|
-
options.treasuryAddress ||
|
|
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
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
-
|
|
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
|
-
|
|
229
|
-
|
|
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
|
|
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,
|
|
326
|
+
await accessManager.grantComponentRole(component.address, getRole(role), userAddress);
|
|
248
327
|
}
|
|
249
328
|
}
|
|
250
329
|
|
|
251
330
|
exports.grantComponentRole = grantComponentRole;
|
|
252
331
|
|
|
253
|
-
|
|
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
|
|
262
|
-
|
|
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
|
-
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
|
283
|
-
}
|
|
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
|
-
|
|
364
|
+
return _BN(value).mul(_BN(10).pow(decimals));
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
exports.amountFunction = amountFunction;
|
|
291
368
|
|
|
292
|
-
|
|
369
|
+
const _W = amountFunction(18);
|
|
370
|
+
exports._W = _W;
|
|
293
371
|
|
|
294
|
-
|
|
295
|
-
|
|
372
|
+
const _R = amountFunction(27);
|
|
373
|
+
exports._R = _R;
|
|
296
374
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
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(
|
|
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
|
-
|
|
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": "
|
|
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
|
+
});
|
package/scripts/utils.sh
ADDED
|
@@ -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
|
+
}
|