@ensuro/core 2.6.2 → 2.8.0-beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -5
- package/contracts/AccessManager.sol +3 -13
- package/contracts/EToken.sol +29 -95
- package/contracts/LPManualWhitelist.sol +11 -26
- package/contracts/LiquidityThresholdAssetManager.sol +10 -21
- package/contracts/Policy.sol +6 -17
- package/contracts/PolicyPool.sol +39 -91
- package/contracts/PolicyPoolComponent.sol +9 -32
- package/contracts/PremiumsAccount.sol +16 -47
- package/contracts/Reserve.sol +10 -16
- package/contracts/RiskModule.sol +22 -80
- package/contracts/SignedBucketRiskModule.sol +18 -80
- package/contracts/SignedQuoteRiskModule.sol +13 -44
- package/contracts/TieredSignedQuoteRiskModule.sol +7 -13
- package/contracts/TimeScaled.sol +8 -39
- package/contracts/TrustfulRiskModule.sol +13 -48
- package/contracts/interfaces/IAccessManager.sol +2 -11
- package/contracts/interfaces/IEToken.sol +1 -5
- package/contracts/interfaces/ILPWhitelist.sol +2 -10
- package/contracts/interfaces/IPolicyHolder.sol +2 -11
- package/contracts/interfaces/IPremiumsAccount.sol +1 -5
- package/contracts/migration/LPManualWhitelistV20.sol +3 -15
- package/contracts/migration/LPManualWhitelistV20Upgraded.sol +1 -5
- package/contracts/mocks/FixedRateVault.sol +1 -6
- package/contracts/mocks/PolicyHolderMock.sol +73 -29
- package/contracts/mocks/PolicyPoolComponentMock.sol +1 -3
- package/contracts/mocks/PolicyPoolMock.sol +8 -28
- package/contracts/mocks/RiskModuleMock.sol +3 -16
- package/contracts/mocks/TestNFT.sol +1 -1
- package/js/constants.js +8 -2
- package/js/deploy.js +65 -62
- package/js/enums.js +26 -8
- package/js/test-utils.js +105 -23
- package/js/utils.js +78 -28
- package/package.json +1 -1
- package/scripts/utils.sh +23 -12
- package/build/contracts/AccessManager.sol/AccessManager.json +0 -618
- package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +0 -238
- package/build/contracts/EToken.sol/EToken.json +0 -1277
- package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +0 -647
- package/build/contracts/LiquidityThresholdAssetManager.sol/LiquidityThresholdAssetManager.json +0 -222
- package/build/contracts/Policy.sol/Policy.json +0 -10
- package/build/contracts/PolicyPool.sol/PolicyPool.json +0 -1416
- package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +0 -332
- package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +0 -970
- package/build/contracts/Reserve.sol/Reserve.json +0 -403
- package/build/contracts/RiskModule.sol/RiskModule.json +0 -559
- package/build/contracts/SignedBucketRiskModule.sol/SignedBucketRiskModule.json +0 -1262
- package/build/contracts/SignedQuoteRiskModule.sol/SignedQuoteRiskModule.json +0 -1110
- package/build/contracts/TieredSignedQuoteRiskModule.sol/TieredSignedQuoteRiskModule.json +0 -1316
- package/build/contracts/TimeScaled.sol/TimeScaled.json +0 -10
- package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +0 -984
- package/build/contracts/dependencies/ERC1967Proxy.sol/ERC1967Proxy.json +0 -64
- package/build/contracts/dependencies/IERC20Metadata.sol/IERC20Metadata.json +0 -233
- package/build/contracts/dependencies/WadRayMath.sol/WadRayMath.json +0 -10
- package/build/contracts/interfaces/IAccessManager.sol/IAccessManager.json +0 -343
- package/build/contracts/interfaces/IAssetManager.sol/IAssetManager.json +0 -128
- package/build/contracts/interfaces/IEToken.sol/IEToken.json +0 -460
- package/build/contracts/interfaces/ILPWhitelist.sol/ILPWhitelist.json +0 -103
- package/build/contracts/interfaces/IPolicyHolder.sol/IPolicyHolder.json +0 -108
- package/build/contracts/interfaces/IPolicyPool.sol/IPolicyPool.json +0 -501
- package/build/contracts/interfaces/IPolicyPoolComponent.sol/IPolicyPoolComponent.json +0 -43
- package/build/contracts/interfaces/IPremiumsAccount.sol/IPremiumsAccount.json +0 -315
- package/build/contracts/interfaces/IRiskModule.sol/IRiskModule.json +0 -165
- package/build/contracts/migration/LPManualWhitelistV20.sol/LPManualWhitelistV20.json +0 -481
- package/build/contracts/migration/LPManualWhitelistV20Upgraded.sol/LPManualWhitelistV20Upgraded.json +0 -492
- package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +0 -736
- package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +0 -43
- package/build/contracts/mocks/IMintableERC20.sol/IMintableERC20.json +0 -47
- package/build/contracts/mocks/InterfaceIdCalculator.sol/InterfaceIdCalculator.json +0 -180
- package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +0 -228
- package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +0 -54
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +0 -721
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +0 -92
- package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +0 -783
- package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +0 -343
- package/build/contracts/mocks/TestNFT.sol/TestNFT.json +0 -388
- package/contracts/dependencies/ERC1967Proxy.sol +0 -19
- package/contracts/dependencies/IERC20Metadata.sol +0 -19
package/js/deploy.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const upgrades_core = require("@openzeppelin/upgrades-core");
|
|
2
2
|
const helpers = require("@nomicfoundation/hardhat-network-helpers");
|
|
3
3
|
const fs = require("fs");
|
|
4
|
-
const { request } = require("undici");
|
|
5
4
|
const ethers = require("ethers");
|
|
6
5
|
const { task, types } = require("hardhat/config");
|
|
7
6
|
const { WhitelistStatus } = require("../js/enums");
|
|
@@ -78,53 +77,50 @@ async function logContractCreated(hre, contractName, address) {
|
|
|
78
77
|
async function verifyContract(hre, contract, isProxy, constructorArguments) {
|
|
79
78
|
if (isProxy === undefined) isProxy = false;
|
|
80
79
|
if (constructorArguments === undefined) constructorArguments = [];
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
const contractAddr = await ethers.resolveAddress(contract);
|
|
81
|
+
const address = isProxy
|
|
82
|
+
? await upgrades_core.getImplementationAddress(hre.network.provider, contractAddr)
|
|
83
|
+
: contractAddr;
|
|
83
84
|
try {
|
|
84
85
|
await hre.run("verify:verify", {
|
|
85
86
|
address: address,
|
|
86
87
|
constructorArguments: constructorArguments,
|
|
87
88
|
});
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.log("Error verifying contract implementation: ", error);
|
|
91
|
+
console.log("You can retry with:");
|
|
92
|
+
console.log(
|
|
93
|
+
` npx hardhat verify --network '${hre.network.name}' '${address}' ${constructorArguments
|
|
94
|
+
.map((a) => `'${a.toString()}'`)
|
|
95
|
+
.join(" ")}`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
88
99
|
if (isProxy) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// });
|
|
93
|
-
|
|
94
|
-
// so we use the following workaround
|
|
95
|
-
const endpoints = await hre.run("verify:get-etherscan-endpoint");
|
|
96
|
-
const params = new URLSearchParams({
|
|
97
|
-
module: "contract",
|
|
98
|
-
action: "verifyproxycontract",
|
|
99
|
-
apiKey: hre.config.etherscan.apiKey,
|
|
100
|
-
address: contract.address,
|
|
101
|
-
});
|
|
102
|
-
const response = await request(endpoints.urls.apiURL, {
|
|
103
|
-
method: "POST",
|
|
104
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
105
|
-
body: params.toString(),
|
|
100
|
+
await hre.run("verify:verify", {
|
|
101
|
+
address: contractAddr,
|
|
102
|
+
constructorArguments: constructorArguments,
|
|
106
103
|
});
|
|
107
|
-
if (response.statusCode != 200)
|
|
108
|
-
throw new Error(`Etherscan replied with ${response.statusCode}: ${await response.body.text()}`);
|
|
109
|
-
const body = await response.body.json();
|
|
110
|
-
if (body.status != 1) throw new Error(`Etherscan replied with ${body}`);
|
|
111
104
|
}
|
|
112
105
|
} catch (error) {
|
|
113
|
-
console.log("Error verifying contract", error);
|
|
106
|
+
console.log("Error verifying contract proxy: ", error);
|
|
107
|
+
const endpoints = await hre.run("verify:get-etherscan-endpoint");
|
|
108
|
+
console.log(`You should do it manually at ${endpoints.urls.browserURL}/proxyContractChecker?a=${contractAddr}`);
|
|
114
109
|
}
|
|
115
110
|
}
|
|
116
111
|
|
|
117
112
|
async function deployContract({ saveAddr, verify, contractClass, constructorArgs }, hre) {
|
|
118
113
|
const ContractFactory = await hre.ethers.getContractFactory(contractClass);
|
|
119
114
|
const contract = await ContractFactory.deploy(...constructorArgs, txOverrides());
|
|
115
|
+
const contractAddr = await ethers.resolveAddress(contract);
|
|
120
116
|
if (verify) {
|
|
121
117
|
// From https://ethereum.stackexchange.com/a/119622/79726
|
|
122
118
|
await contract.deployTransaction.wait(6);
|
|
123
119
|
} else {
|
|
124
|
-
await contract.
|
|
120
|
+
await contract.waitForDeployment();
|
|
125
121
|
}
|
|
126
|
-
await logContractCreated(hre, contractClass,
|
|
127
|
-
saveAddress(saveAddr,
|
|
122
|
+
await logContractCreated(hre, contractClass, contractAddr);
|
|
123
|
+
saveAddress(saveAddr, contractAddr);
|
|
128
124
|
if (verify) await verifyContract(hre, contract, false, constructorArgs);
|
|
129
125
|
return { ContractFactory, contract };
|
|
130
126
|
}
|
|
@@ -140,14 +136,15 @@ async function deployProxyContract(
|
|
|
140
136
|
initializer: initializer,
|
|
141
137
|
...deployProxyArgs,
|
|
142
138
|
});
|
|
139
|
+
const contractAddr = await ethers.resolveAddress(contract);
|
|
143
140
|
if (verify) {
|
|
144
141
|
// From https://ethereum.stackexchange.com/a/119622/79726
|
|
145
142
|
await contract.deployTransaction.wait(6);
|
|
146
143
|
} else {
|
|
147
|
-
await contract.
|
|
144
|
+
await contract.waitForDeployment();
|
|
148
145
|
}
|
|
149
|
-
await logContractCreated(hre, contractClass,
|
|
150
|
-
saveAddress(saveAddr,
|
|
146
|
+
await logContractCreated(hre, contractClass, contractAddr);
|
|
147
|
+
saveAddress(saveAddr, contractAddr);
|
|
151
148
|
if (verify) await verifyContract(hre, contract, true, constructorArgs);
|
|
152
149
|
return { ContractFactory, contract };
|
|
153
150
|
}
|
|
@@ -161,7 +158,7 @@ async function grantRoleTask({ contractAddress, role, account, component, impers
|
|
|
161
158
|
}
|
|
162
159
|
contract = contract.connect(signer);
|
|
163
160
|
}
|
|
164
|
-
if (component === ethers.
|
|
161
|
+
if (component === ethers.ZeroAddress) {
|
|
165
162
|
await grantRole(hre, contract, role, account, txOverrides(), console.log);
|
|
166
163
|
} else {
|
|
167
164
|
await grantComponentRole(hre, contract, component, role, account, txOverrides(), console.log);
|
|
@@ -178,11 +175,11 @@ async function deployTestCurrency({ currName, currSymbol, initialSupply, ...opts
|
|
|
178
175
|
},
|
|
179
176
|
hre
|
|
180
177
|
)
|
|
181
|
-
).contract
|
|
178
|
+
).contract;
|
|
182
179
|
}
|
|
183
180
|
|
|
184
181
|
async function deployAccessManager(opts, hre) {
|
|
185
|
-
return (await deployProxyContract({ contractClass: "AccessManager", ...opts }, hre)).contract
|
|
182
|
+
return (await deployProxyContract({ contractClass: "AccessManager", ...opts }, hre)).contract;
|
|
186
183
|
}
|
|
187
184
|
|
|
188
185
|
async function deployPolicyPool({ accessAddress, currencyAddress, nftName, nftSymbol, treasuryAddress, ...opts }, hre) {
|
|
@@ -196,7 +193,7 @@ async function deployPolicyPool({ accessAddress, currencyAddress, nftName, nftSy
|
|
|
196
193
|
},
|
|
197
194
|
hre
|
|
198
195
|
)
|
|
199
|
-
).contract
|
|
196
|
+
).contract;
|
|
200
197
|
}
|
|
201
198
|
|
|
202
199
|
async function deployEToken(
|
|
@@ -216,9 +213,9 @@ async function deployEToken(
|
|
|
216
213
|
if (opts.addComponent) {
|
|
217
214
|
let policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
|
|
218
215
|
if (runAs) policyPool = policyPool.connect(runAs);
|
|
219
|
-
await policyPool.addComponent(contract
|
|
216
|
+
await policyPool.addComponent(contract, 1);
|
|
220
217
|
}
|
|
221
|
-
return contract
|
|
218
|
+
return contract;
|
|
222
219
|
}
|
|
223
220
|
|
|
224
221
|
async function deployPremiumsAccount({ poolAddress, juniorEtk, seniorEtk, runAs, ...opts }, hre) {
|
|
@@ -235,9 +232,9 @@ async function deployPremiumsAccount({ poolAddress, juniorEtk, seniorEtk, runAs,
|
|
|
235
232
|
if (opts.addComponent) {
|
|
236
233
|
let policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
|
|
237
234
|
if (runAs) policyPool = policyPool.connect(runAs);
|
|
238
|
-
await policyPool.addComponent(contract
|
|
235
|
+
await policyPool.addComponent(contract, 3);
|
|
239
236
|
}
|
|
240
|
-
return contract
|
|
237
|
+
return contract;
|
|
241
238
|
}
|
|
242
239
|
|
|
243
240
|
async function deployRiskModule(
|
|
@@ -264,8 +261,11 @@ async function deployRiskModule(
|
|
|
264
261
|
},
|
|
265
262
|
hre
|
|
266
263
|
) {
|
|
267
|
-
extraArgs = extraArgs || [];
|
|
268
|
-
|
|
264
|
+
extraArgs = typeof extraArgs === "string" ? JSON.parse(extraArgs) : extraArgs || [];
|
|
265
|
+
|
|
266
|
+
extraConstructorArgs =
|
|
267
|
+
typeof extraConstructorArgs === "string" ? JSON.parse(extraConstructorArgs) : extraConstructorArgs || [];
|
|
268
|
+
|
|
269
269
|
const { contract } = await deployProxyContract(
|
|
270
270
|
{
|
|
271
271
|
contractClass: rmClass,
|
|
@@ -285,7 +285,6 @@ async function deployRiskModule(
|
|
|
285
285
|
hre
|
|
286
286
|
);
|
|
287
287
|
const rm = runAs === undefined ? contract : contract.connect(runAs);
|
|
288
|
-
|
|
289
288
|
if (opts.addComponent) {
|
|
290
289
|
if (moc != 1.0) {
|
|
291
290
|
moc = _W(moc);
|
|
@@ -308,9 +307,9 @@ async function deployRiskModule(
|
|
|
308
307
|
}
|
|
309
308
|
let policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
|
|
310
309
|
if (runAs) policyPool = policyPool.connect(runAs);
|
|
311
|
-
await policyPool.addComponent(contract
|
|
310
|
+
await policyPool.addComponent(contract, 2);
|
|
312
311
|
}
|
|
313
|
-
return contract
|
|
312
|
+
return contract;
|
|
314
313
|
}
|
|
315
314
|
|
|
316
315
|
async function deploySignedQuoteRM(opts, hre) {
|
|
@@ -323,9 +322,9 @@ async function setAssetManager({ reserve, amAddress, liquidityMin, liquidityMidd
|
|
|
323
322
|
const tx = await reserveContract.setAssetManager(amAddress, false);
|
|
324
323
|
console.log(`Asset Manager ${amAddress} set to reserve ${reserve}`);
|
|
325
324
|
if (liquidityMin !== undefined || liquidityMiddle !== undefined || liquidityMax !== undefined) {
|
|
326
|
-
liquidityMin = liquidityMin === undefined ? ethers.
|
|
327
|
-
liquidityMiddle = liquidityMiddle === undefined ? ethers.
|
|
328
|
-
liquidityMax = liquidityMax === undefined ? ethers.
|
|
325
|
+
liquidityMin = liquidityMin === undefined ? ethers.MaxUint256 : _A(liquidityMin);
|
|
326
|
+
liquidityMiddle = liquidityMiddle === undefined ? ethers.MaxUint256 : _A(liquidityMiddle);
|
|
327
|
+
liquidityMax = liquidityMax === undefined ? ethers.MaxUint256 : _A(liquidityMax);
|
|
329
328
|
const amContract = await hre.ethers.getContractAt(
|
|
330
329
|
"ERC4626AssetManager", // Not relevant if it's ERC4626AssetManager, only need setLiquidityThresholds
|
|
331
330
|
amAddress
|
|
@@ -350,7 +349,7 @@ async function deployERC4626AssetManager({ asset, vault, amClass, ...opts }, hre
|
|
|
350
349
|
},
|
|
351
350
|
hre
|
|
352
351
|
)
|
|
353
|
-
).contract
|
|
352
|
+
).contract;
|
|
354
353
|
}
|
|
355
354
|
|
|
356
355
|
async function deployAaveAssetManager({ asset, aave, amClass, ...opts }, hre) {
|
|
@@ -363,7 +362,7 @@ async function deployAaveAssetManager({ asset, aave, amClass, ...opts }, hre) {
|
|
|
363
362
|
},
|
|
364
363
|
hre
|
|
365
364
|
)
|
|
366
|
-
).contract
|
|
365
|
+
).contract;
|
|
367
366
|
}
|
|
368
367
|
|
|
369
368
|
async function deployWhitelist(
|
|
@@ -390,17 +389,17 @@ async function deployWhitelist(
|
|
|
390
389
|
);
|
|
391
390
|
if (eToken !== undefined) {
|
|
392
391
|
const etk = await hre.ethers.getContractAt("EToken", eToken);
|
|
393
|
-
await etk.setWhitelist(contract
|
|
392
|
+
await etk.setWhitelist(contract);
|
|
394
393
|
}
|
|
395
394
|
if (eToken2 !== undefined) {
|
|
396
395
|
const etk = await hre.ethers.getContractAt("EToken", eToken2);
|
|
397
|
-
await etk.setWhitelist(contract
|
|
396
|
+
await etk.setWhitelist(contract);
|
|
398
397
|
}
|
|
399
398
|
if (eToken3 !== undefined) {
|
|
400
399
|
const etk = await hre.ethers.getContractAt("EToken", eToken3);
|
|
401
|
-
await etk.setWhitelist(contract
|
|
400
|
+
await etk.setWhitelist(contract);
|
|
402
401
|
}
|
|
403
|
-
return contract
|
|
402
|
+
return contract;
|
|
404
403
|
}
|
|
405
404
|
|
|
406
405
|
async function trustfullPolicy({ rmAddress, payout, premium, lossProb, expiration, customer }, hre) {
|
|
@@ -413,7 +412,7 @@ async function trustfullPolicy({ rmAddress, payout, premium, lossProb, expiratio
|
|
|
413
412
|
customer = customer || (await getDefaultSigner(hre));
|
|
414
413
|
premium = _A(premium);
|
|
415
414
|
|
|
416
|
-
await currency.approve(policyPool
|
|
415
|
+
await currency.approve(policyPool, premium);
|
|
417
416
|
lossProb = _W(lossProb);
|
|
418
417
|
if (expiration === undefined) {
|
|
419
418
|
expiration = 3600;
|
|
@@ -457,7 +456,7 @@ async function flightDelayPolicy(
|
|
|
457
456
|
customer = customer || (await getDefaultSigner(hre));
|
|
458
457
|
premium = _A(premium);
|
|
459
458
|
|
|
460
|
-
await currency.approve(policyPool
|
|
459
|
+
await currency.approve(policyPool, premium);
|
|
461
460
|
lossProb = _W(lossProb);
|
|
462
461
|
payout = _A(payout);
|
|
463
462
|
|
|
@@ -484,7 +483,7 @@ async function listETokens({ poolAddress }, hre) {
|
|
|
484
483
|
for (let i = 0; i < etkCount; i++) {
|
|
485
484
|
const etk = await hre.ethers.getContractAt("EToken", await policyPool.getETokenAt(i));
|
|
486
485
|
const etkName = await etk.name();
|
|
487
|
-
console.log(`eToken at ${etk.
|
|
486
|
+
console.log(`eToken at ${etk.target}: ${etkName}`);
|
|
488
487
|
}
|
|
489
488
|
}
|
|
490
489
|
|
|
@@ -493,8 +492,8 @@ async function deposit({ etkAddress, amount }, hre) {
|
|
|
493
492
|
const policyPool = await hre.ethers.getContractAt("PolicyPool", await etk.policyPool());
|
|
494
493
|
const currency = await hre.ethers.getContractAt("IERC20Metadata", await policyPool.currency());
|
|
495
494
|
amount = _A(amount);
|
|
496
|
-
await currency.approve(policyPool
|
|
497
|
-
const tx = await policyPool.deposit(etk
|
|
495
|
+
await currency.approve(policyPool, amount);
|
|
496
|
+
const tx = await policyPool.deposit(etk, amount, { gasLimit: 999999 });
|
|
498
497
|
console.log(tx);
|
|
499
498
|
}
|
|
500
499
|
|
|
@@ -512,11 +511,13 @@ function add_task() {
|
|
|
512
511
|
.setAction(async function (taskArgs, hre) {
|
|
513
512
|
if (taskArgs.currencyAddress === undefined) {
|
|
514
513
|
taskArgs.saveAddr = "CURRENCY";
|
|
515
|
-
|
|
514
|
+
const currency = await deployTestCurrency(taskArgs, hre);
|
|
515
|
+
taskArgs.currencyAddress = await ethers.resolveAddress(currency);
|
|
516
516
|
}
|
|
517
517
|
if (taskArgs.accessAddress === undefined) {
|
|
518
518
|
taskArgs.saveAddr = "ACCESSMANAGER";
|
|
519
|
-
|
|
519
|
+
const access = await deployAccessManager(taskArgs, hre);
|
|
520
|
+
taskArgs.accessAddress = await ethers.resolveAddress(access);
|
|
520
521
|
}
|
|
521
522
|
taskArgs.saveAddr = "POOL";
|
|
522
523
|
await deployPolicyPool(taskArgs, hre);
|
|
@@ -540,7 +541,7 @@ function add_task() {
|
|
|
540
541
|
.addOptionalParam("saveAddr", "Save created contract address", "POOL", types.str)
|
|
541
542
|
.addOptionalParam("nftName", "Name of Policies NFT Token", "Ensuro Policies NFT", types.str)
|
|
542
543
|
.addOptionalParam("nftSymbol", "Symbol of Policies NFT Token", "EPOL", types.str)
|
|
543
|
-
.addOptionalParam("treasuryAddress", "Treasury Address", ethers.
|
|
544
|
+
.addOptionalParam("treasuryAddress", "Treasury Address", ethers.ZeroAddress, types.address)
|
|
544
545
|
.addParam("currencyAddress", "Currency Address", types.address)
|
|
545
546
|
.addParam("accessAddress", "AccessManager Address", types.address)
|
|
546
547
|
.setAction(deployPolicyPool);
|
|
@@ -583,6 +584,8 @@ function add_task() {
|
|
|
583
584
|
.addOptionalParam("exposureLimit", "Exposure (sum of payouts) limit for the RM", 1e6, types.float)
|
|
584
585
|
.addOptionalParam("maxDuration", "Maximum policy duration in hours", 24 * 365, types.int)
|
|
585
586
|
.addOptionalParam("moc", "Margin of Conservativism", 1.0, types.float)
|
|
587
|
+
.addOptionalParam("extraConstructorArgs", "Additional constructor args", undefined, types.str)
|
|
588
|
+
.addOptionalParam("extraArgs", "Additional initializer args", undefined, types.str)
|
|
586
589
|
.addParam("wallet", "RM address", types.address)
|
|
587
590
|
.setAction(deployRiskModule);
|
|
588
591
|
|
|
@@ -694,7 +697,7 @@ function add_task() {
|
|
|
694
697
|
.addOptionalParam(
|
|
695
698
|
"component",
|
|
696
699
|
"Address of the component if it's a component role",
|
|
697
|
-
ethers.
|
|
700
|
+
ethers.ZeroAddress,
|
|
698
701
|
types.address
|
|
699
702
|
)
|
|
700
703
|
.setAction(grantRoleTask);
|
package/js/enums.js
CHANGED
|
@@ -4,7 +4,29 @@ const WhitelistStatus = {
|
|
|
4
4
|
blacklisted: 2,
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
+
const ComponentKind = {
|
|
8
|
+
eToken: 1,
|
|
9
|
+
riskModule: 2,
|
|
10
|
+
premiumsAccount: 3,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const ComponentStatus = {
|
|
14
|
+
inactive: 0,
|
|
15
|
+
active: 1,
|
|
16
|
+
deprecated: 2,
|
|
17
|
+
suspended: 3,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const ETokenParameter = {
|
|
21
|
+
// From IEToken.Parameter
|
|
22
|
+
liquidityRequirement: 0,
|
|
23
|
+
minUtilizationRate: 1,
|
|
24
|
+
maxUtilizationRate: 2,
|
|
25
|
+
internalLoanInterestRate: 3,
|
|
26
|
+
};
|
|
27
|
+
|
|
7
28
|
const RiskModuleParameter = {
|
|
29
|
+
// From IRiskModule.Parameter
|
|
8
30
|
moc: 0,
|
|
9
31
|
jrCollRatio: 1,
|
|
10
32
|
collRatio: 2,
|
|
@@ -17,14 +39,10 @@ const RiskModuleParameter = {
|
|
|
17
39
|
maxDuration: 9,
|
|
18
40
|
};
|
|
19
41
|
|
|
20
|
-
const ComponentKind = {
|
|
21
|
-
eToken: 1,
|
|
22
|
-
riskModule: 2,
|
|
23
|
-
premiumsAccount: 3,
|
|
24
|
-
};
|
|
25
|
-
|
|
26
42
|
module.exports = {
|
|
27
|
-
WhitelistStatus,
|
|
28
|
-
RiskModuleParameter,
|
|
29
43
|
ComponentKind,
|
|
44
|
+
ComponentStatus,
|
|
45
|
+
ETokenParameter,
|
|
46
|
+
RiskModuleParameter,
|
|
47
|
+
WhitelistStatus,
|
|
30
48
|
};
|
package/js/test-utils.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const hre = require("hardhat");
|
|
2
2
|
const { _W, grantRole, getTransactionEvent } = require("../js/utils");
|
|
3
3
|
const { RiskModuleParameter } = require("../js/enums");
|
|
4
|
+
const helpers = require("@nomicfoundation/hardhat-network-helpers");
|
|
4
5
|
|
|
5
|
-
const {
|
|
6
|
+
const { ethers } = hre;
|
|
7
|
+
const { ZeroAddress } = ethers;
|
|
6
8
|
|
|
7
9
|
async function initCurrency(options, initial_targets, initial_balances) {
|
|
8
|
-
const Currency = await
|
|
10
|
+
const Currency = await ethers.getContractFactory(options.contractClass || "TestCurrency");
|
|
9
11
|
let currency = await Currency.deploy(
|
|
10
12
|
options.name || "Test Currency",
|
|
11
13
|
options.symbol || "TEST",
|
|
@@ -15,7 +17,27 @@ async function initCurrency(options, initial_targets, initial_balances) {
|
|
|
15
17
|
initial_targets = initial_targets || [];
|
|
16
18
|
await Promise.all(
|
|
17
19
|
initial_targets.map(async function (user, index) {
|
|
18
|
-
await currency.transfer(user
|
|
20
|
+
await currency.transfer(user, initial_balances[index]);
|
|
21
|
+
})
|
|
22
|
+
);
|
|
23
|
+
return currency;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
* @param currencyAddress The currency contract address, for example the USDC address
|
|
29
|
+
* @param currencyOrigin An account that holds at least sum(initialBalances) of currency tokens
|
|
30
|
+
* @param initialTargets Array of addresses that will receive the initial balances
|
|
31
|
+
* @param initialBalances Initial balances for each address
|
|
32
|
+
*/
|
|
33
|
+
async function initForkCurrency(currencyAddress, currencyOrigin, initialTargets, initialBalances) {
|
|
34
|
+
const currency = await ethers.getContractAt("IERC20", currencyAddress);
|
|
35
|
+
await helpers.impersonateAccount(currencyOrigin);
|
|
36
|
+
await helpers.setBalance(currencyOrigin, ethers.parseEther("100"));
|
|
37
|
+
const whale = await ethers.getSigner(currencyOrigin);
|
|
38
|
+
await Promise.all(
|
|
39
|
+
initialTargets.map(async function (user, index) {
|
|
40
|
+
await currency.connect(whale).transfer(user, initialBalances[index]);
|
|
19
41
|
})
|
|
20
42
|
);
|
|
21
43
|
return currency;
|
|
@@ -41,6 +63,11 @@ async function createRiskModule(
|
|
|
41
63
|
extraArgs = extraArgs || [];
|
|
42
64
|
extraConstructorArgs = extraConstructorArgs || [];
|
|
43
65
|
const _A = pool._A || _W;
|
|
66
|
+
maxPayoutPerPolicy = maxPayoutPerPolicy !== undefined ? _A(maxPayoutPerPolicy) : _A(1000);
|
|
67
|
+
exposureLimit = exposureLimit !== undefined ? _A(exposureLimit) : _A(1000000);
|
|
68
|
+
|
|
69
|
+
const poolAddr = await ethers.resolveAddress(pool);
|
|
70
|
+
const paAddr = await ethers.resolveAddress(premiumsAccount);
|
|
44
71
|
const rm = await hre.upgrades.deployProxy(
|
|
45
72
|
contractFactory,
|
|
46
73
|
[
|
|
@@ -48,18 +75,18 @@ async function createRiskModule(
|
|
|
48
75
|
_W(collRatio) || _W(1),
|
|
49
76
|
_W(ensuroPPFee) || _W(0),
|
|
50
77
|
_W(srRoc) || _W("0.1"),
|
|
51
|
-
|
|
52
|
-
|
|
78
|
+
maxPayoutPerPolicy,
|
|
79
|
+
exposureLimit,
|
|
53
80
|
wallet || "0xdD2FD4581271e230360230F9337D5c0430Bf44C0", // Random address
|
|
54
81
|
...extraArgs,
|
|
55
82
|
],
|
|
56
83
|
{
|
|
57
84
|
kind: "uups",
|
|
58
|
-
constructorArgs: [
|
|
85
|
+
constructorArgs: [poolAddr, paAddr, ...extraConstructorArgs],
|
|
59
86
|
}
|
|
60
87
|
);
|
|
61
88
|
|
|
62
|
-
await rm.
|
|
89
|
+
await rm.waitForDeployment();
|
|
63
90
|
|
|
64
91
|
if (moc !== undefined && moc != 1.0) {
|
|
65
92
|
moc = _W(moc);
|
|
@@ -98,7 +125,7 @@ async function addRiskModule(
|
|
|
98
125
|
extraConstructorArgs,
|
|
99
126
|
});
|
|
100
127
|
|
|
101
|
-
await pool.addComponent(rm
|
|
128
|
+
await pool.addComponent(rm, 2);
|
|
102
129
|
return rm;
|
|
103
130
|
}
|
|
104
131
|
|
|
@@ -106,9 +133,10 @@ async function createEToken(
|
|
|
106
133
|
pool,
|
|
107
134
|
{ etkName, etkSymbol, maxUtilizationRate, poolLoanInterestRate, extraArgs, extraConstructorArgs }
|
|
108
135
|
) {
|
|
109
|
-
const EToken = await
|
|
136
|
+
const EToken = await ethers.getContractFactory("EToken");
|
|
110
137
|
extraArgs = extraArgs || [];
|
|
111
138
|
extraConstructorArgs = extraConstructorArgs || [];
|
|
139
|
+
const poolAddr = await ethers.resolveAddress(pool);
|
|
112
140
|
const etk = await hre.upgrades.deployProxy(
|
|
113
141
|
EToken,
|
|
114
142
|
[
|
|
@@ -121,11 +149,11 @@ async function createEToken(
|
|
|
121
149
|
{
|
|
122
150
|
kind: "uups",
|
|
123
151
|
unsafeAllow: ["delegatecall"], // This holds, because EToken is a reserve and uses delegatecall
|
|
124
|
-
constructorArgs: [
|
|
152
|
+
constructorArgs: [poolAddr, ...extraConstructorArgs],
|
|
125
153
|
}
|
|
126
154
|
);
|
|
127
155
|
|
|
128
|
-
await etk.
|
|
156
|
+
await etk.waitForDeployment();
|
|
129
157
|
return etk;
|
|
130
158
|
}
|
|
131
159
|
|
|
@@ -141,7 +169,7 @@ async function addEToken(
|
|
|
141
169
|
extraArgs,
|
|
142
170
|
extraConstructorArgs,
|
|
143
171
|
});
|
|
144
|
-
await pool.addComponent(etk
|
|
172
|
+
await pool.addComponent(etk, 1);
|
|
145
173
|
return etk;
|
|
146
174
|
}
|
|
147
175
|
|
|
@@ -162,19 +190,21 @@ const randomAddress = "0x89cDb70Fee571251a66E34caa1673cE40f7549Dc";
|
|
|
162
190
|
* - .dontGrantL123Roles: if specified, doesn't grants LEVEL1, 2 and 3 roles.
|
|
163
191
|
*/
|
|
164
192
|
async function deployPool(options) {
|
|
165
|
-
const PolicyPool = await
|
|
166
|
-
const AccessManager = await
|
|
193
|
+
const PolicyPool = await ethers.getContractFactory("PolicyPool");
|
|
194
|
+
const AccessManager = await ethers.getContractFactory("AccessManager");
|
|
167
195
|
|
|
168
196
|
let accessManager;
|
|
169
197
|
|
|
170
198
|
if (options.access === undefined) {
|
|
171
199
|
// Deploy AccessManager
|
|
172
200
|
accessManager = await hre.upgrades.deployProxy(AccessManager, [], { kind: "uups" });
|
|
173
|
-
await accessManager.
|
|
201
|
+
await accessManager.waitForDeployment();
|
|
174
202
|
} else {
|
|
175
|
-
accessManager = await
|
|
203
|
+
accessManager = await ethers.getContractAt("AccessManager", options.access);
|
|
176
204
|
}
|
|
177
205
|
|
|
206
|
+
const currencyAddr = await ethers.resolveAddress(options.currency);
|
|
207
|
+
const amAddr = await ethers.resolveAddress(accessManager);
|
|
178
208
|
const policyPool = await hre.upgrades.deployProxy(
|
|
179
209
|
PolicyPool,
|
|
180
210
|
[
|
|
@@ -183,12 +213,12 @@ async function deployPool(options) {
|
|
|
183
213
|
options.treasuryAddress || randomAddress,
|
|
184
214
|
],
|
|
185
215
|
{
|
|
186
|
-
constructorArgs: [
|
|
216
|
+
constructorArgs: [amAddr, currencyAddr],
|
|
187
217
|
kind: "uups",
|
|
188
218
|
}
|
|
189
219
|
);
|
|
190
220
|
|
|
191
|
-
await policyPool.
|
|
221
|
+
await policyPool.waitForDeployment();
|
|
192
222
|
|
|
193
223
|
for (const role of options.grantRoles || []) {
|
|
194
224
|
await grantRole(hre, accessManager, role);
|
|
@@ -204,28 +234,76 @@ async function deployPool(options) {
|
|
|
204
234
|
}
|
|
205
235
|
|
|
206
236
|
async function deployPremiumsAccount(pool, options, addToPool = true) {
|
|
207
|
-
const PremiumsAccount = await
|
|
237
|
+
const PremiumsAccount = await ethers.getContractFactory("PremiumsAccount");
|
|
238
|
+
const poolAddr = await ethers.resolveAddress(pool);
|
|
239
|
+
const jrEtkAddr = options.jrEtk ? await ethers.resolveAddress(options.jrEtk) : ZeroAddress;
|
|
240
|
+
const srEtkAddr = options.srEtk ? await ethers.resolveAddress(options.srEtk) : ZeroAddress;
|
|
208
241
|
const premiumsAccount = await hre.upgrades.deployProxy(PremiumsAccount, [], {
|
|
209
|
-
constructorArgs: [
|
|
242
|
+
constructorArgs: [poolAddr, jrEtkAddr, srEtkAddr],
|
|
210
243
|
kind: "uups",
|
|
211
244
|
unsafeAllow: ["delegatecall"], // This holds, because EToken is a reserve and uses delegatecall
|
|
212
245
|
});
|
|
213
246
|
|
|
214
|
-
await premiumsAccount.
|
|
247
|
+
await premiumsAccount.waitForDeployment();
|
|
215
248
|
|
|
216
|
-
if (addToPool) await pool.addComponent(premiumsAccount
|
|
249
|
+
if (addToPool) await pool.addComponent(premiumsAccount, 3);
|
|
217
250
|
|
|
218
251
|
return premiumsAccount;
|
|
219
252
|
}
|
|
220
253
|
|
|
221
254
|
async function makePolicy(pool, rm, cust, payout, premium, lossProb, expiration, internalId, method = "newPolicy") {
|
|
222
|
-
let tx = await rm.connect(cust)[method](payout, premium, lossProb, expiration, cust
|
|
255
|
+
let tx = await rm.connect(cust)[method](payout, premium, lossProb, expiration, cust, internalId);
|
|
223
256
|
let receipt = await tx.wait();
|
|
224
257
|
const newPolicyEvt = getTransactionEvent(pool.interface, receipt, "NewPolicy");
|
|
225
258
|
|
|
226
259
|
return newPolicyEvt;
|
|
227
260
|
}
|
|
228
261
|
|
|
262
|
+
/**
|
|
263
|
+
* Resets hardhat network to fork on the specified block and url
|
|
264
|
+
*/
|
|
265
|
+
async function setupChain(block, alchemyUrlEnv = "ALCHEMY_URL") {
|
|
266
|
+
const alchemyUrl = process.env[alchemyUrlEnv];
|
|
267
|
+
if (alchemyUrl === undefined) throw new Error(`Define envvar ${alchemyUrlEnv} for this test`);
|
|
268
|
+
|
|
269
|
+
if (block === undefined) throw new Error("Block can't be undefined use null for the current block");
|
|
270
|
+
if (block === null) block = undefined;
|
|
271
|
+
return hre.network.provider.request({
|
|
272
|
+
method: "hardhat_reset",
|
|
273
|
+
params: [
|
|
274
|
+
{
|
|
275
|
+
forking: {
|
|
276
|
+
jsonRpcUrl: alchemyUrl,
|
|
277
|
+
blockNumber: block,
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
],
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const skipForkTests = process.env.SKIP_FORK_TESTS === "true";
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Chai test case wrapper for tests that require forking a live chain.
|
|
288
|
+
*
|
|
289
|
+
* It validates that the chain node URL is set, forks the chain at the specified block and adds the
|
|
290
|
+
* block number to the test name.
|
|
291
|
+
*/
|
|
292
|
+
const fork = {
|
|
293
|
+
it: (name, blockNumber, test, alchemyUrlEnv = "ALCHEMY_URL") => {
|
|
294
|
+
const fullName = `[FORK ${blockNumber}] ${name}`;
|
|
295
|
+
|
|
296
|
+
// eslint-disable-next-line func-style
|
|
297
|
+
const wrapped = async (...args) => {
|
|
298
|
+
await setupChain(blockNumber, alchemyUrlEnv);
|
|
299
|
+
|
|
300
|
+
return test(...args);
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
return (skipForkTests ? it.skip : it)(fullName, wrapped);
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
|
|
229
307
|
if (process.env.ENABLE_HH_WARNINGS !== "yes") hre.upgrades.silenceWarnings();
|
|
230
308
|
|
|
231
309
|
module.exports = {
|
|
@@ -235,6 +313,10 @@ module.exports = {
|
|
|
235
313
|
createRiskModule,
|
|
236
314
|
deployPool,
|
|
237
315
|
deployPremiumsAccount,
|
|
316
|
+
fork,
|
|
238
317
|
initCurrency,
|
|
318
|
+
initForkCurrency,
|
|
239
319
|
makePolicy,
|
|
320
|
+
setupChain,
|
|
321
|
+
skipForkTests,
|
|
240
322
|
};
|