@ensuro/core 2.0.0 → 2.1.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/build/contracts/EToken.sol/EToken.json +58 -2
- package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +193 -9
- package/build/contracts/interfaces/ILPWhitelist.sol/ILPWhitelist.json +29 -0
- package/build/contracts/mocks/InterfaceIdCalculator.sol/InterfaceIdCalculator.json +2 -2
- package/contracts/EToken.sol +40 -4
- package/contracts/LPManualWhitelist.sol +97 -11
- package/contracts/interfaces/ILPWhitelist.sol +14 -0
- package/js/deploy.js +78 -24
- package/js/test-utils.js +2 -2
- package/package.json +1 -1
|
@@ -37,4 +37,18 @@ interface ILPWhitelist {
|
|
|
37
37
|
address providerTo,
|
|
38
38
|
uint256 amount
|
|
39
39
|
) external view returns (bool);
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @dev Indicates whether or not a liquidity provider can withdraw an eToken.
|
|
43
|
+
*
|
|
44
|
+
* @param etoken The eToken (see {EToken}) where the provider wants to withdraw money.
|
|
45
|
+
* @param provider The address of the liquidity provider (user) that wants to withdraw
|
|
46
|
+
* @param amount The amount of the withdrawal
|
|
47
|
+
* @return true if `provider` withdraw request is accepted, false if not
|
|
48
|
+
*/
|
|
49
|
+
function acceptsWithdrawal(
|
|
50
|
+
IEToken etoken,
|
|
51
|
+
address provider,
|
|
52
|
+
uint256 amount
|
|
53
|
+
) external view returns (bool);
|
|
40
54
|
}
|
package/js/deploy.js
CHANGED
|
@@ -7,14 +7,34 @@ const _BN = ethers.BigNumber.from;
|
|
|
7
7
|
const WAD = _BN(1e10).mul(_BN(1e8)); // 1e10*1e8=1e18
|
|
8
8
|
const RAY = WAD.mul(_BN(1e9)); // 1e18*1e9=1e27
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
const WhitelistStatus = {
|
|
11
|
+
notdefined: 0,
|
|
12
|
+
whitelisted: 1,
|
|
13
|
+
blacklisted: 2,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Creates a fixed-point conversion function for the desired number of decimals
|
|
18
|
+
* @param decimals The number of decimals. Must be >= 6.
|
|
19
|
+
* @returns The amount function created. The function can receive strings (recommended),
|
|
20
|
+
* floats/doubles (not recommended) and integers.
|
|
21
|
+
*
|
|
22
|
+
* Floats will be rounded to 6 decimal before scaling.
|
|
23
|
+
*/
|
|
24
|
+
function amountFunction(decimals) {
|
|
25
|
+
return function (value) {
|
|
26
|
+
if (value === undefined) return undefined;
|
|
27
|
+
|
|
28
|
+
if (typeof value === "string" || value instanceof String) {
|
|
29
|
+
return hre.ethers.utils.parseUnits(value, decimals);
|
|
30
|
+
}
|
|
14
31
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
32
|
+
if (!Number.isInteger(value)) {
|
|
33
|
+
return _BN(Math.round(value * 1e6)).mul(_BN(Math.pow(10, decimals - 6)));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return _BN(value).mul(_BN(10).pow(decimals));
|
|
37
|
+
};
|
|
18
38
|
}
|
|
19
39
|
|
|
20
40
|
function amountDecimals() {
|
|
@@ -23,13 +43,25 @@ function amountDecimals() {
|
|
|
23
43
|
return decimals;
|
|
24
44
|
}
|
|
25
45
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
46
|
+
const GWei = amountFunction(9);
|
|
47
|
+
const _W = amountFunction(18);
|
|
48
|
+
const _R = amountFunction(27);
|
|
49
|
+
const _A = amountFunction(amountDecimals());
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Transaction overrides using env variables because hardhat-ethers ignores hardhat config
|
|
53
|
+
* See: https://hardhat.org/hardhat-runner/plugins/nomiclabs-hardhat-ethers#gas-transaction-parameters-in--hardhat.config--are-not-used
|
|
54
|
+
*/
|
|
55
|
+
function txOverrides() {
|
|
56
|
+
const ret = {};
|
|
57
|
+
if (process.env.OVERRIDE_GAS_PRICE !== undefined) {
|
|
58
|
+
ret.gasPrice = GWei(parseFloat(process.env.OVERRIDE_GAS_PRICE));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (process.env.OVERRIDE_GAS_LIMIT !== undefined) {
|
|
62
|
+
ret.gasLimit = parseInt(process.env.OVERRIDE_GAS_LIMIT);
|
|
32
63
|
}
|
|
64
|
+
return ret || undefined;
|
|
33
65
|
}
|
|
34
66
|
|
|
35
67
|
function saveAddress(name, address) {
|
|
@@ -94,7 +126,7 @@ async function verifyContract(hre, contract, isProxy, constructorArguments) {
|
|
|
94
126
|
|
|
95
127
|
async function deployContract({ saveAddr, verify, contractClass, constructorArgs }, hre) {
|
|
96
128
|
const ContractFactory = await hre.ethers.getContractFactory(contractClass);
|
|
97
|
-
const contract = await ContractFactory.deploy(...constructorArgs);
|
|
129
|
+
const contract = await ContractFactory.deploy(...constructorArgs, txOverrides());
|
|
98
130
|
if (verify) {
|
|
99
131
|
// From https://ethereum.stackexchange.com/a/119622/79726
|
|
100
132
|
await contract.deployTransaction.wait(6);
|
|
@@ -126,6 +158,12 @@ async function deployProxyContract({ saveAddr, verify, contractClass, constructo
|
|
|
126
158
|
return { ContractFactory, contract };
|
|
127
159
|
}
|
|
128
160
|
|
|
161
|
+
function parseRole(role) {
|
|
162
|
+
if (role.startsWith("0x")) return role;
|
|
163
|
+
if (role === "DEFAULT_ADMIN_ROLE") return ethers.constants.HashZero;
|
|
164
|
+
return ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
|
|
165
|
+
}
|
|
166
|
+
|
|
129
167
|
async function grantComponentRole(hre, contract, component, role, user) {
|
|
130
168
|
let userAddress;
|
|
131
169
|
if (user === undefined) {
|
|
@@ -134,11 +172,11 @@ async function grantComponentRole(hre, contract, component, role, user) {
|
|
|
134
172
|
} else {
|
|
135
173
|
userAddress = user;
|
|
136
174
|
}
|
|
137
|
-
const roleHex =
|
|
175
|
+
const roleHex = parseRole(role);
|
|
138
176
|
const componentAddress = component.address || component;
|
|
139
177
|
const componentRole = await contract.getComponentRole(componentAddress, roleHex);
|
|
140
178
|
if (!(await contract.hasRole(componentRole, userAddress))) {
|
|
141
|
-
await contract.grantComponentRole(componentAddress, roleHex, userAddress);
|
|
179
|
+
await contract.grantComponentRole(componentAddress, roleHex, userAddress, txOverrides());
|
|
142
180
|
console.log(`Role ${role} (${roleHex}) Component ${componentAddress} granted to ${userAddress}`);
|
|
143
181
|
} else {
|
|
144
182
|
console.log(`Role ${role} (${roleHex}) Component ${componentAddress} already granted to ${userAddress}`);
|
|
@@ -153,9 +191,9 @@ async function grantRole(hre, contract, role, user) {
|
|
|
153
191
|
} else {
|
|
154
192
|
userAddress = user;
|
|
155
193
|
}
|
|
156
|
-
const roleHex =
|
|
194
|
+
const roleHex = parseRole(role);
|
|
157
195
|
if (!(await contract.hasRole(roleHex, userAddress))) {
|
|
158
|
-
await contract.grantRole(roleHex, userAddress);
|
|
196
|
+
await contract.grantRole(roleHex, userAddress, txOverrides());
|
|
159
197
|
console.log(`Role ${role} (${roleHex}) granted to ${userAddress}`);
|
|
160
198
|
} else {
|
|
161
199
|
console.log(`Role ${role} (${roleHex}) already granted to ${userAddress}`);
|
|
@@ -221,7 +259,7 @@ async function deployEToken(
|
|
|
221
259
|
hre
|
|
222
260
|
);
|
|
223
261
|
const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
|
|
224
|
-
await policyPool.addComponent(contract.address, 1);
|
|
262
|
+
if (opts.addComponent) await policyPool.addComponent(contract.address, 1);
|
|
225
263
|
return contract.address;
|
|
226
264
|
}
|
|
227
265
|
|
|
@@ -236,7 +274,7 @@ async function deployPremiumsAccount({ poolAddress, juniorEtk, seniorEtk, ...opt
|
|
|
236
274
|
hre
|
|
237
275
|
);
|
|
238
276
|
const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
|
|
239
|
-
await policyPool.addComponent(contract.address, 3);
|
|
277
|
+
if (opts.addComponent) await policyPool.addComponent(contract.address, 3);
|
|
240
278
|
return contract.address;
|
|
241
279
|
}
|
|
242
280
|
|
|
@@ -302,10 +340,10 @@ async function deployRiskModule(
|
|
|
302
340
|
await rm.setParam(4, ensuroCocFee);
|
|
303
341
|
}
|
|
304
342
|
if (maxDuration != 24 * 365) {
|
|
305
|
-
await rm.setParam(9,
|
|
343
|
+
await rm.setParam(9, maxDuration);
|
|
306
344
|
}
|
|
307
345
|
const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
|
|
308
|
-
await policyPool.addComponent(contract.address, 2);
|
|
346
|
+
if (opts.addComponent) await policyPool.addComponent(contract.address, 2);
|
|
309
347
|
return contract.address;
|
|
310
348
|
}
|
|
311
349
|
|
|
@@ -331,7 +369,7 @@ async function deploySignedQuoteRM(opts, hre) {
|
|
|
331
369
|
|
|
332
370
|
async function setAssetManager({ reserve, amAddress, liquidityMin, liquidityMiddle, liquidityMax }, hre) {
|
|
333
371
|
const reserveContract = await hre.ethers.getContractAt("Reserve", reserve);
|
|
334
|
-
await reserveContract.setAssetManager(amAddress, false);
|
|
372
|
+
const tx = await reserveContract.setAssetManager(amAddress, false);
|
|
335
373
|
console.log(`Asset Manager ${amAddress} set to reserve ${reserve}`);
|
|
336
374
|
if (liquidityMin !== undefined || liquidityMiddle !== undefined || liquidityMax !== undefined) {
|
|
337
375
|
liquidityMin = liquidityMin === undefined ? ethers.constants.MaxUint256 : _A(liquidityMin);
|
|
@@ -341,6 +379,9 @@ async function setAssetManager({ reserve, amAddress, liquidityMin, liquidityMidd
|
|
|
341
379
|
"ERC4626AssetManager", // Not relevant if it's ERC4626AssetManager, only need setLiquidityThresholds
|
|
342
380
|
amAddress
|
|
343
381
|
);
|
|
382
|
+
|
|
383
|
+
// To make sure the setAssetManager was executed - wait 2 confirmations
|
|
384
|
+
await tx.wait(process.env.NETWORK !== "localhost" ? 2 : undefined);
|
|
344
385
|
await reserveContract.forwardToAssetManager(
|
|
345
386
|
amContract.interface.encodeFunctionData("setLiquidityThresholds", [liquidityMin, liquidityMiddle, liquidityMax])
|
|
346
387
|
);
|
|
@@ -375,10 +416,16 @@ async function deployAaveAssetManager({ asset, aave, amClass, ...opts }, hre) {
|
|
|
375
416
|
}
|
|
376
417
|
|
|
377
418
|
async function deployWhitelist(
|
|
378
|
-
{ wlClass, poolAddress, extraConstructorArgs, extraArgs, eToken, eToken2, eToken3, ...opts },
|
|
419
|
+
{ wlClass, poolAddress, extraConstructorArgs, extraArgs, eToken, eToken2, eToken3, defaultStatus, ...opts },
|
|
379
420
|
hre
|
|
380
421
|
) {
|
|
381
422
|
extraArgs = extraArgs || [];
|
|
423
|
+
if (defaultStatus !== "") {
|
|
424
|
+
defaultStatus = defaultStatus
|
|
425
|
+
.split("")
|
|
426
|
+
.map((WB) => (WB == "W" ? WhitelistStatus.whitelisted : WhitelistStatus.blacklisted));
|
|
427
|
+
extraArgs.splice(0, 0, defaultStatus);
|
|
428
|
+
}
|
|
382
429
|
extraConstructorArgs = extraConstructorArgs || [];
|
|
383
430
|
const { contract } = await deployProxyContract(
|
|
384
431
|
{
|
|
@@ -549,6 +596,7 @@ function add_task() {
|
|
|
549
596
|
task("deploy:eToken", "Deploy an EToken and adds it to the pool")
|
|
550
597
|
.addOptionalParam("verify", "Verify contract in Etherscan", false, types.boolean)
|
|
551
598
|
.addOptionalParam("saveAddr", "Save created contract address", "ETOKEN", types.str)
|
|
599
|
+
.addOptionalParam("addComponent", "Adds the new component to the pool", true, types.boolean)
|
|
552
600
|
.addParam("poolAddress", "PolicyPool Address", types.address)
|
|
553
601
|
.addParam("etkName", "Name of EToken", types.str)
|
|
554
602
|
.addParam("etkSymbol", "Symbol of EToken", types.str)
|
|
@@ -559,6 +607,7 @@ function add_task() {
|
|
|
559
607
|
task("deploy:premiumsAccount", "Deploy a premiums account")
|
|
560
608
|
.addOptionalParam("verify", "Verify contract in Etherscan", false, types.boolean)
|
|
561
609
|
.addOptionalParam("saveAddr", "Save created contract address", "PA", types.str)
|
|
610
|
+
.addOptionalParam("addComponent", "Adds the new component to the pool", true, types.boolean)
|
|
562
611
|
.addParam("poolAddress", "PolicyPool Address", types.address)
|
|
563
612
|
.addParam("juniorEtk", "Junior EToken Address", types.address)
|
|
564
613
|
.addParam("seniorEtk", "Senior EToken Address", types.address)
|
|
@@ -567,6 +616,7 @@ function add_task() {
|
|
|
567
616
|
task("deploy:riskModule", "Deploys a RiskModule and adds it to the pool")
|
|
568
617
|
.addOptionalParam("verify", "Verify contract in Etherscan", false, types.boolean)
|
|
569
618
|
.addOptionalParam("saveAddr", "Save created contract address", "RM", types.str)
|
|
619
|
+
.addOptionalParam("addComponent", "Adds the new component to the pool", true, types.boolean)
|
|
570
620
|
.addParam("poolAddress", "PolicyPool Address", types.address)
|
|
571
621
|
.addParam("paAddress", "PremiumsAccount Address", types.address)
|
|
572
622
|
.addOptionalParam("rmClass", "RiskModule contract", "TrustfulRiskModule", types.str)
|
|
@@ -587,6 +637,7 @@ function add_task() {
|
|
|
587
637
|
task("deploy:signedQuoteRiskModule", "Deploys a RiskModule and adds it to the pool")
|
|
588
638
|
.addOptionalParam("verify", "Verify contract in Etherscan", false, types.boolean)
|
|
589
639
|
.addOptionalParam("saveAddr", "Save created contract address", "RM", types.str)
|
|
640
|
+
.addOptionalParam("addComponent", "Adds the new component to the pool", true, types.boolean)
|
|
590
641
|
.addParam("poolAddress", "PolicyPool Address", types.address)
|
|
591
642
|
.addParam("paAddress", "PremiumsAccount Address", types.address)
|
|
592
643
|
.addOptionalParam("rmClass", "RiskModule contract", "SignedQuoteRiskModule", types.str)
|
|
@@ -608,6 +659,7 @@ function add_task() {
|
|
|
608
659
|
task("deploy:priceRiskModule", "Deploys and injects a Price RiskModule")
|
|
609
660
|
.addOptionalParam("verify", "Verify contract in Etherscan", false, types.boolean)
|
|
610
661
|
.addOptionalParam("saveAddr", "Save created contract address", "RM", types.str)
|
|
662
|
+
.addOptionalParam("addComponent", "Adds the new component to the pool", true, types.boolean)
|
|
611
663
|
.addParam("poolAddress", "PolicyPool Address", types.address)
|
|
612
664
|
.addParam("paAddress", "PremiumsAccount Address", types.address)
|
|
613
665
|
.addOptionalParam("rmClass", "RiskModule contract", "PriceRiskModule", types.str)
|
|
@@ -661,6 +713,7 @@ function add_task() {
|
|
|
661
713
|
.addOptionalParam("eToken", "Set the Whitelist to a given eToken", undefined, types.address)
|
|
662
714
|
.addOptionalParam("eToken2", "Set the Whitelist to a given eToken", undefined, types.address)
|
|
663
715
|
.addOptionalParam("eToken3", "Set the Whitelist to a given eToken", undefined, types.address)
|
|
716
|
+
.addOptionalParam("defaultStatus", "Default Status Ej: 'BWWB'", "BWWB", types.str)
|
|
664
717
|
.addParam("poolAddress", "PolicyPool Address", types.address)
|
|
665
718
|
.setAction(deployWhitelist);
|
|
666
719
|
|
|
@@ -731,4 +784,5 @@ module.exports = {
|
|
|
731
784
|
deploySignedQuoteRM,
|
|
732
785
|
setAssetManager,
|
|
733
786
|
deployWhitelist,
|
|
787
|
+
WhitelistStatus,
|
|
734
788
|
};
|
package/js/test-utils.js
CHANGED
|
@@ -414,8 +414,8 @@ function makePolicyId(rm, internalId) {
|
|
|
414
414
|
|
|
415
415
|
exports.makePolicyId = makePolicyId;
|
|
416
416
|
|
|
417
|
-
async function makePolicy(pool, rm, cust, payout, premium, lossProb, expiration, internalId) {
|
|
418
|
-
let tx = await rm.connect(cust)
|
|
417
|
+
async function makePolicy(pool, rm, cust, payout, premium, lossProb, expiration, internalId, method = "newPolicy") {
|
|
418
|
+
let tx = await rm.connect(cust)[method](payout, premium, lossProb, expiration, cust.address, internalId);
|
|
419
419
|
let receipt = await tx.wait();
|
|
420
420
|
const newPolicyEvt = getTransactionEvent(pool.interface, receipt, "NewPolicy");
|
|
421
421
|
|