@ensuro/core 2.2.0 → 2.3.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/build/contracts/AccessManager.sol/AccessManager.json +2 -2
- package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +2 -2
- package/build/contracts/EToken.sol/EToken.json +2 -2
- package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +2 -2
- package/build/contracts/Policy.sol/Policy.json +2 -2
- package/build/contracts/PolicyPool.sol/PolicyPool.json +2 -2
- package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +2 -2
- package/build/contracts/SignedQuoteRiskModule.sol/SignedQuoteRiskModule.json +2 -2
- package/build/contracts/TieredSignedQuoteRiskModule.sol/TieredSignedQuoteRiskModule.json +1316 -0
- package/build/contracts/TimeScaled.sol/TimeScaled.json +2 -2
- package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +2 -2
- package/build/contracts/migration/LPManualWhitelistV20Upgraded.sol/LPManualWhitelistV20Upgraded.json +2 -2
- package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +6 -6
- package/build/contracts/mocks/InterfaceIdCalculator.sol/InterfaceIdCalculator.json +2 -2
- package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +2 -2
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +2 -2
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +2 -2
- package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +2 -2
- package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +2 -2
- package/build/contracts/mocks/TestNFT.sol/TestNFT.json +2 -2
- package/contracts/PolicyPool.sol +3 -2
- package/contracts/RiskModule.sol +5 -38
- package/contracts/SignedQuoteRiskModule.sol +3 -3
- package/contracts/TieredSignedQuoteRiskModule.sol +165 -0
- package/contracts/TrustfulRiskModule.sol +7 -2
- package/js/deploy.js +52 -67
- package/js/test-utils.js +41 -29
- package/package.json +1 -1
package/contracts/RiskModule.sol
CHANGED
|
@@ -26,8 +26,8 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
|
|
|
26
26
|
|
|
27
27
|
uint256 internal constant FOUR_DECIMAL_TO_WAD = 1e14;
|
|
28
28
|
uint16 internal constant HUNDRED_PERCENT = 1e4;
|
|
29
|
-
uint16 internal constant MIN_MOC = 5e3;
|
|
30
|
-
uint16 internal constant MAX_MOC = 4e4;
|
|
29
|
+
uint16 internal constant MIN_MOC = 5e3; // 50%
|
|
30
|
+
uint16 internal constant MAX_MOC = 4e4; // 400%
|
|
31
31
|
|
|
32
32
|
// For parameters that can be changed by the risk module provider
|
|
33
33
|
bytes32 public constant RM_PROVIDER_ROLE = keccak256("RM_PROVIDER_ROLE");
|
|
@@ -339,7 +339,8 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
|
|
|
339
339
|
}
|
|
340
340
|
|
|
341
341
|
/**
|
|
342
|
-
* @dev Called from child contracts to create policies (after they validated the pricing)
|
|
342
|
+
* @dev Called from child contracts to create policies (after they validated the pricing).
|
|
343
|
+
* whenNotPaused validation must be done in the external method.
|
|
343
344
|
*
|
|
344
345
|
* @param payout The exposure (maximum payout) of the policy
|
|
345
346
|
* @param premium The premium that will be paid by the policyHolder
|
|
@@ -357,7 +358,7 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
|
|
|
357
358
|
address payer,
|
|
358
359
|
address onBehalfOf,
|
|
359
360
|
uint96 internalId
|
|
360
|
-
) internal
|
|
361
|
+
) internal virtual returns (Policy.PolicyData memory) {
|
|
361
362
|
return
|
|
362
363
|
_newPolicyWithParams(
|
|
363
364
|
payout,
|
|
@@ -371,40 +372,6 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
|
|
|
371
372
|
);
|
|
372
373
|
}
|
|
373
374
|
|
|
374
|
-
/**
|
|
375
|
-
* @dev Called from child contracts to create policies (after they validated the pricing), receives custom params
|
|
376
|
-
*
|
|
377
|
-
* @param payout The exposure (maximum payout) of the policy
|
|
378
|
-
* @param premium The premium that will be paid by the policyHolder
|
|
379
|
-
* @param lossProb The probability of having to pay the maximum payout (wad)
|
|
380
|
-
* @param payer The account that pays for the premium
|
|
381
|
-
* @param expiration The expiration of the policy (timestamp)
|
|
382
|
-
* @param onBehalfOf The policy holder
|
|
383
|
-
* @param internalId An id that's unique within this module and it will be used to identify the policy
|
|
384
|
-
*/
|
|
385
|
-
function _newPolicyCustomParams(
|
|
386
|
-
uint256 payout,
|
|
387
|
-
uint256 premium,
|
|
388
|
-
uint256 lossProb,
|
|
389
|
-
uint40 expiration,
|
|
390
|
-
address payer,
|
|
391
|
-
address onBehalfOf,
|
|
392
|
-
uint96 internalId,
|
|
393
|
-
Params memory params_
|
|
394
|
-
) internal whenNotPaused returns (Policy.PolicyData memory) {
|
|
395
|
-
return
|
|
396
|
-
_newPolicyWithParams(
|
|
397
|
-
payout,
|
|
398
|
-
premium,
|
|
399
|
-
lossProb,
|
|
400
|
-
expiration,
|
|
401
|
-
payer,
|
|
402
|
-
onBehalfOf,
|
|
403
|
-
internalId,
|
|
404
|
-
params_
|
|
405
|
-
);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
375
|
/**
|
|
409
376
|
* @dev Internal method without whenNotPaused, MUST be called from other function that has this modifier
|
|
410
377
|
*/
|
|
@@ -159,7 +159,7 @@ contract SignedQuoteRiskModule is RiskModule {
|
|
|
159
159
|
bytes32 quoteSignatureR,
|
|
160
160
|
bytes32 quoteSignatureVS,
|
|
161
161
|
uint40 quoteValidUntil
|
|
162
|
-
) external returns (Policy.PolicyData memory createdPolicy) {
|
|
162
|
+
) external whenNotPaused returns (Policy.PolicyData memory createdPolicy) {
|
|
163
163
|
return
|
|
164
164
|
_newPolicySigned(
|
|
165
165
|
payout,
|
|
@@ -207,7 +207,7 @@ contract SignedQuoteRiskModule is RiskModule {
|
|
|
207
207
|
bytes32 quoteSignatureR,
|
|
208
208
|
bytes32 quoteSignatureVS,
|
|
209
209
|
uint40 quoteValidUntil
|
|
210
|
-
) external returns (uint256) {
|
|
210
|
+
) external whenNotPaused returns (uint256) {
|
|
211
211
|
return
|
|
212
212
|
_newPolicySigned(
|
|
213
213
|
payout,
|
|
@@ -255,7 +255,7 @@ contract SignedQuoteRiskModule is RiskModule {
|
|
|
255
255
|
bytes32 quoteSignatureR,
|
|
256
256
|
bytes32 quoteSignatureVS,
|
|
257
257
|
uint40 quoteValidUntil
|
|
258
|
-
) external returns (uint256) {
|
|
258
|
+
) external whenNotPaused returns (uint256) {
|
|
259
259
|
require(
|
|
260
260
|
onBehalfOf == _msgSender() || currency().allowance(onBehalfOf, _msgSender()) > 0,
|
|
261
261
|
"Sender is not authorized to create policies onBehalfOf"
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
pragma solidity ^0.8.0;
|
|
3
|
+
|
|
4
|
+
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
|
|
5
|
+
import {IPolicyPool} from "./interfaces/IPolicyPool.sol";
|
|
6
|
+
import {IPremiumsAccount} from "./interfaces/IPremiumsAccount.sol";
|
|
7
|
+
import {SignedQuoteRiskModule} from "./SignedQuoteRiskModule.sol";
|
|
8
|
+
import {Policy} from "./Policy.sol";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @title Tiered SignedQuote Risk Module
|
|
12
|
+
* @dev Risk Module that for policy creation verifies the different components of the price have been signed by a
|
|
13
|
+
* trusted account (PRICER_ROLE). For the resolution (resolvePolicy), it has to be called by an authorized user.
|
|
14
|
+
*
|
|
15
|
+
* It allows different collaterallization levels for different policy types, by defining tiers or buckets of loss
|
|
16
|
+
* probability.
|
|
17
|
+
*
|
|
18
|
+
* Each bucket's loss probability represents the upper bound of the bucket (inclusive). The global parameters of
|
|
19
|
+
* the contract represent the 100% bucket.
|
|
20
|
+
*
|
|
21
|
+
* @custom:security-contact security@ensuro.co
|
|
22
|
+
* @author Ensuro
|
|
23
|
+
*/
|
|
24
|
+
contract TieredSignedQuoteRiskModule is SignedQuoteRiskModule {
|
|
25
|
+
using SafeCast for uint256;
|
|
26
|
+
|
|
27
|
+
uint8 public constant MAX_BUCKETS = 4;
|
|
28
|
+
|
|
29
|
+
struct PackedBuckets {
|
|
30
|
+
uint64[MAX_BUCKETS] lossProbs;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
PackedBuckets internal _buckets;
|
|
34
|
+
PackedParams[MAX_BUCKETS] internal _bucketParams;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @dev Emitted when a new risk bucket is created.
|
|
38
|
+
* @param lossProb The loss probability of the new bucket.
|
|
39
|
+
* @param params The packed parameters of the new bucket.
|
|
40
|
+
*/
|
|
41
|
+
event NewBucket(uint256 lossProb, Params params);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @dev Emitted when the risks buckets are reset and only the default one remains
|
|
45
|
+
*/
|
|
46
|
+
event BucketsReset();
|
|
47
|
+
|
|
48
|
+
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
49
|
+
constructor(
|
|
50
|
+
IPolicyPool policyPool_,
|
|
51
|
+
IPremiumsAccount premiumsAccount_,
|
|
52
|
+
bool creationIsOpen_
|
|
53
|
+
) SignedQuoteRiskModule(policyPool_, premiumsAccount_, creationIsOpen_) {} // solhint-disable-line no-empty-blocks
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @dev Adds a new risk bucket with the given loss probability and parameters after the last one.
|
|
57
|
+
*
|
|
58
|
+
* Requirements:
|
|
59
|
+
*
|
|
60
|
+
* - The caller must have the LEVEL1_ROLE or LEVEL2_ROLE
|
|
61
|
+
*
|
|
62
|
+
* @param lossProb The loss probability of the new bucket.
|
|
63
|
+
* @param params_ The parameters of the new bucket.
|
|
64
|
+
*/
|
|
65
|
+
function pushBucket(uint256 lossProb, Params calldata params_)
|
|
66
|
+
external
|
|
67
|
+
onlyGlobalOrComponentRole2(LEVEL1_ROLE, LEVEL2_ROLE)
|
|
68
|
+
{
|
|
69
|
+
uint256 newBucket = 0;
|
|
70
|
+
if (_buckets.lossProbs[0] != 0) {
|
|
71
|
+
for (
|
|
72
|
+
newBucket = 1;
|
|
73
|
+
newBucket < MAX_BUCKETS && _buckets.lossProbs[newBucket] != 0;
|
|
74
|
+
newBucket++
|
|
75
|
+
) {} // solhint-disable-line no-empty-blocks
|
|
76
|
+
require(newBucket < MAX_BUCKETS, "No more than 4 buckets accepted");
|
|
77
|
+
require(
|
|
78
|
+
lossProb > uint256(_buckets.lossProbs[newBucket - 1]),
|
|
79
|
+
"lossProb <= last lossProb - reset instead"
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
_buckets.lossProbs[newBucket] = lossProb.toUint64();
|
|
83
|
+
_bucketParams[newBucket] = PackedParams({
|
|
84
|
+
moc: _wadTo4(params_.moc),
|
|
85
|
+
jrCollRatio: _wadTo4(params_.jrCollRatio),
|
|
86
|
+
collRatio: _wadTo4(params_.collRatio),
|
|
87
|
+
ensuroPpFee: _wadTo4(params_.ensuroPpFee),
|
|
88
|
+
ensuroCocFee: _wadTo4(params_.ensuroCocFee),
|
|
89
|
+
jrRoc: _wadTo4(params_.jrRoc),
|
|
90
|
+
srRoc: _wadTo4(params_.srRoc),
|
|
91
|
+
maxPayoutPerPolicy: type(uint32).max, // unused, but needs to be > 0
|
|
92
|
+
exposureLimit: type(uint32).max, //unused, but needs to be > 0
|
|
93
|
+
maxDuration: type(uint16).max //unused
|
|
94
|
+
});
|
|
95
|
+
if (newBucket < MAX_BUCKETS - 1) {
|
|
96
|
+
_buckets.lossProbs[newBucket + 1] = 0;
|
|
97
|
+
}
|
|
98
|
+
_validatePackedParams(_bucketParams[newBucket]);
|
|
99
|
+
emit NewBucket(lossProb, params_);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function resetBuckets() external onlyGlobalOrComponentRole2(LEVEL1_ROLE, LEVEL2_ROLE) {
|
|
103
|
+
_buckets.lossProbs[0] = 0;
|
|
104
|
+
emit BucketsReset();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @dev returns the risk bucket parameters for the given loss probability
|
|
109
|
+
*/
|
|
110
|
+
function bucketParams(uint256 lossProb) public view returns (Params memory) {
|
|
111
|
+
for (uint256 i = 0; i < MAX_BUCKETS && _buckets.lossProbs[i] != 0; i++) {
|
|
112
|
+
if (lossProb <= _buckets.lossProbs[i]) {
|
|
113
|
+
return _unpackParams(_bucketParams[i]);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return this.params();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function _newPolicy(
|
|
120
|
+
uint256 payout,
|
|
121
|
+
uint256 premium,
|
|
122
|
+
uint256 lossProb,
|
|
123
|
+
uint40 expiration,
|
|
124
|
+
address payer,
|
|
125
|
+
address onBehalfOf,
|
|
126
|
+
uint96 internalId
|
|
127
|
+
) internal override whenNotPaused returns (Policy.PolicyData memory) {
|
|
128
|
+
return
|
|
129
|
+
_newPolicyWithParams(
|
|
130
|
+
payout,
|
|
131
|
+
premium,
|
|
132
|
+
lossProb,
|
|
133
|
+
expiration,
|
|
134
|
+
payer,
|
|
135
|
+
onBehalfOf,
|
|
136
|
+
internalId,
|
|
137
|
+
bucketParams(lossProb)
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function getMinimumPremium(
|
|
142
|
+
uint256 payout,
|
|
143
|
+
uint256 lossProb,
|
|
144
|
+
uint40 expiration
|
|
145
|
+
) public view virtual override returns (uint256) {
|
|
146
|
+
return _getMinimumPremium(payout, lossProb, expiration, bucketParams(lossProb));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @dev returns the current risk bucket limits
|
|
151
|
+
*/
|
|
152
|
+
function buckets() external view returns (uint256[MAX_BUCKETS] memory result) {
|
|
153
|
+
for (uint256 i = 0; i < MAX_BUCKETS && _buckets.lossProbs[i] > 0; i++) {
|
|
154
|
+
result[i] = _buckets.lossProbs[i];
|
|
155
|
+
}
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @dev This empty reserved space is put in place to allow future versions to add new
|
|
161
|
+
* variables without shifting down storage in the inheritance chain.
|
|
162
|
+
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
|
|
163
|
+
*/
|
|
164
|
+
uint256[45] private __gap;
|
|
165
|
+
}
|
|
@@ -78,7 +78,7 @@ contract TrustfulRiskModule is RiskModule {
|
|
|
78
78
|
uint40 expiration,
|
|
79
79
|
address onBehalfOf,
|
|
80
80
|
uint96 internalId
|
|
81
|
-
) external onlyComponentRole(PRICER_ROLE) returns (uint256) {
|
|
81
|
+
) external whenNotPaused onlyComponentRole(PRICER_ROLE) returns (uint256) {
|
|
82
82
|
return
|
|
83
83
|
_newPolicy(
|
|
84
84
|
payout,
|
|
@@ -115,7 +115,12 @@ contract TrustfulRiskModule is RiskModule {
|
|
|
115
115
|
uint40 expiration,
|
|
116
116
|
address onBehalfOf,
|
|
117
117
|
uint96 internalId
|
|
118
|
-
)
|
|
118
|
+
)
|
|
119
|
+
external
|
|
120
|
+
whenNotPaused
|
|
121
|
+
onlyComponentRole(PRICER_ROLE)
|
|
122
|
+
returns (Policy.PolicyData memory createdPolicy)
|
|
123
|
+
{
|
|
119
124
|
return
|
|
120
125
|
_newPolicy(
|
|
121
126
|
payout,
|
package/js/deploy.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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
|
-
|
|
4
|
+
const { request } = require("undici");
|
|
5
5
|
const ethers = require("ethers");
|
|
6
6
|
|
|
7
7
|
const _BN = ethers.BigNumber.from;
|
|
@@ -14,6 +14,10 @@ const WhitelistStatus = {
|
|
|
14
14
|
blacklisted: 2,
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
const reservesOpts = {
|
|
18
|
+
unsafeAllow: ["delegatecall"],
|
|
19
|
+
};
|
|
20
|
+
|
|
17
21
|
/**
|
|
18
22
|
* Creates a fixed-point conversion function for the desired number of decimals
|
|
19
23
|
* @param decimals The number of decimals. Must be >= 6.
|
|
@@ -115,10 +119,28 @@ async function verifyContract(hre, contract, isProxy, constructorArguments) {
|
|
|
115
119
|
constructorArguments: constructorArguments,
|
|
116
120
|
});
|
|
117
121
|
if (isProxy) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
);
|
|
122
|
+
// the following should work but it fails with the current @openzeppelin/hardhat-upgrades version (1.20.0)
|
|
123
|
+
// await hre.run("verify:verify", {
|
|
124
|
+
// address: contract.address,
|
|
125
|
+
// });
|
|
126
|
+
|
|
127
|
+
// so we use the following workaround
|
|
128
|
+
const endpoints = await hre.run("verify:get-etherscan-endpoint");
|
|
129
|
+
const params = new URLSearchParams({
|
|
130
|
+
module: "contract",
|
|
131
|
+
action: "verifyproxycontract",
|
|
132
|
+
apiKey: hre.config.etherscan.apiKey,
|
|
133
|
+
address: contract.address,
|
|
134
|
+
});
|
|
135
|
+
const response = await request(endpoints.urls.apiURL, {
|
|
136
|
+
method: "POST",
|
|
137
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
138
|
+
body: params.toString(),
|
|
139
|
+
});
|
|
140
|
+
if (response.statusCode != 200)
|
|
141
|
+
throw new Error(`Etherscan replied with ${response.statusCode}: ${await response.body.text()}`);
|
|
142
|
+
const body = await response.body.json();
|
|
143
|
+
if (body.status != 1) throw new Error(`Etherscan replied with ${body}`);
|
|
122
144
|
}
|
|
123
145
|
} catch (error) {
|
|
124
146
|
console.log("Error verifying contract", error);
|
|
@@ -141,7 +163,7 @@ async function deployContract({ saveAddr, verify, contractClass, constructorArgs
|
|
|
141
163
|
}
|
|
142
164
|
|
|
143
165
|
async function deployProxyContract(
|
|
144
|
-
{ saveAddr, verify, contractClass, constructorArgs, initializeArgs, initializer },
|
|
166
|
+
{ saveAddr, verify, contractClass, constructorArgs, initializeArgs, initializer, deployProxyArgs },
|
|
145
167
|
hre
|
|
146
168
|
) {
|
|
147
169
|
const ContractFactory = await hre.ethers.getContractFactory(contractClass);
|
|
@@ -149,7 +171,7 @@ async function deployProxyContract(
|
|
|
149
171
|
constructorArgs: constructorArgs,
|
|
150
172
|
kind: "uups",
|
|
151
173
|
initializer: initializer,
|
|
152
|
-
|
|
174
|
+
...deployProxyArgs,
|
|
153
175
|
});
|
|
154
176
|
if (verify) {
|
|
155
177
|
// From https://ethereum.stackexchange.com/a/119622/79726
|
|
@@ -266,6 +288,7 @@ async function deployEToken(
|
|
|
266
288
|
contractClass: "EToken",
|
|
267
289
|
constructorArgs: [poolAddress],
|
|
268
290
|
initializeArgs: [etkName, etkSymbol, _W(maxUtilizationRate), _W(poolLoanInterestRate)],
|
|
291
|
+
deployProxyArgs: reservesOpts,
|
|
269
292
|
...opts,
|
|
270
293
|
},
|
|
271
294
|
hre
|
|
@@ -284,6 +307,7 @@ async function deployPremiumsAccount({ poolAddress, juniorEtk, seniorEtk, runAs,
|
|
|
284
307
|
contractClass: "PremiumsAccount",
|
|
285
308
|
constructorArgs: [poolAddress, juniorEtk, seniorEtk],
|
|
286
309
|
initializeArgs: [],
|
|
310
|
+
deployProxyArgs: reservesOpts,
|
|
287
311
|
...opts,
|
|
288
312
|
},
|
|
289
313
|
hre
|
|
@@ -342,26 +366,26 @@ async function deployRiskModule(
|
|
|
342
366
|
);
|
|
343
367
|
const rm = runAs === undefined ? contract : contract.connect(runAs);
|
|
344
368
|
|
|
345
|
-
if (moc != 1.0) {
|
|
346
|
-
moc = _W(moc);
|
|
347
|
-
await rm.setParam(0, moc);
|
|
348
|
-
}
|
|
349
|
-
if (jrCollRatio != 0.0) {
|
|
350
|
-
jrCollRatio = _W(jrCollRatio);
|
|
351
|
-
await rm.setParam(1, jrCollRatio);
|
|
352
|
-
}
|
|
353
|
-
if (jrRoc != 0.0) {
|
|
354
|
-
jrRoc = _W(jrRoc);
|
|
355
|
-
await rm.setParam(5, jrRoc);
|
|
356
|
-
}
|
|
357
|
-
if (ensuroCocFee != 0) {
|
|
358
|
-
ensuroCocFee = _W(ensuroCocFee);
|
|
359
|
-
await rm.setParam(4, ensuroCocFee);
|
|
360
|
-
}
|
|
361
|
-
if (maxDuration != 24 * 365) {
|
|
362
|
-
await rm.setParam(9, maxDuration);
|
|
363
|
-
}
|
|
364
369
|
if (opts.addComponent) {
|
|
370
|
+
if (moc != 1.0) {
|
|
371
|
+
moc = _W(moc);
|
|
372
|
+
await rm.setParam(0, moc);
|
|
373
|
+
}
|
|
374
|
+
if (jrCollRatio != 0.0) {
|
|
375
|
+
jrCollRatio = _W(jrCollRatio);
|
|
376
|
+
await rm.setParam(1, jrCollRatio);
|
|
377
|
+
}
|
|
378
|
+
if (jrRoc != 0.0) {
|
|
379
|
+
jrRoc = _W(jrRoc);
|
|
380
|
+
await rm.setParam(5, jrRoc);
|
|
381
|
+
}
|
|
382
|
+
if (ensuroCocFee != 0) {
|
|
383
|
+
ensuroCocFee = _W(ensuroCocFee);
|
|
384
|
+
await rm.setParam(4, ensuroCocFee);
|
|
385
|
+
}
|
|
386
|
+
if (maxDuration != 24 * 365) {
|
|
387
|
+
await rm.setParam(9, maxDuration);
|
|
388
|
+
}
|
|
365
389
|
let policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
|
|
366
390
|
if (runAs) policyPool = policyPool.connect(runAs);
|
|
367
391
|
await policyPool.addComponent(contract.address, 2);
|
|
@@ -369,21 +393,6 @@ async function deployRiskModule(
|
|
|
369
393
|
return contract.address;
|
|
370
394
|
}
|
|
371
395
|
|
|
372
|
-
async function deployFlightDelayRM(opts, hre) {
|
|
373
|
-
opts.extraArgs = [opts.linkToken, [opts.oracle, opts.delayTime, _W(opts.oracleFee), opts.dataJobId, opts.sleepJobId]];
|
|
374
|
-
return deployRiskModule(opts, hre);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
async function deployPriceRM(opts, hre) {
|
|
378
|
-
opts.extraConstructorArgs = [opts.assetOracle, opts.referenceOracle, _W(opts.slotSize)];
|
|
379
|
-
opts.extraArgs = [opts.oracleTolerance];
|
|
380
|
-
const rm = await deployRiskModule(opts, hre);
|
|
381
|
-
if (opts.minDuration != 3600) {
|
|
382
|
-
// TODO: we will need ORACLE_ADMIN_ROLE
|
|
383
|
-
await rm.setMinDuration(opts.minDuration);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
396
|
async function deploySignedQuoteRM(opts, hre) {
|
|
388
397
|
opts.extraConstructorArgs = [opts.creationIsOpen];
|
|
389
398
|
return deployRiskModule(opts, hre);
|
|
@@ -679,32 +688,6 @@ function add_task() {
|
|
|
679
688
|
.addParam("wallet", "RM address", types.address)
|
|
680
689
|
.setAction(deploySignedQuoteRM);
|
|
681
690
|
|
|
682
|
-
task("deploy:priceRiskModule", "Deploys and injects a Price RiskModule")
|
|
683
|
-
.addOptionalParam("verify", "Verify contract in Etherscan", false, types.boolean)
|
|
684
|
-
.addOptionalParam("saveAddr", "Save created contract address", "RM", types.str)
|
|
685
|
-
.addOptionalParam("addComponent", "Adds the new component to the pool", true, types.boolean)
|
|
686
|
-
.addParam("poolAddress", "PolicyPool Address", types.address)
|
|
687
|
-
.addParam("paAddress", "PremiumsAccount Address", types.address)
|
|
688
|
-
.addOptionalParam("rmClass", "RiskModule contract", "PriceRiskModule", types.str)
|
|
689
|
-
.addOptionalParam("rmName", "Name of the RM", "Price Risk Module", types.str)
|
|
690
|
-
.addOptionalParam("collRatio", "Collateralization ratio", 1.0, types.float)
|
|
691
|
-
.addOptionalParam("jrCollRatio", "Junior Collateralization ratio", 0.0, types.float)
|
|
692
|
-
.addOptionalParam("ensuroPpFee", "Ensuro Pure Premium Fee", 0.02, types.float)
|
|
693
|
-
.addOptionalParam("ensuroCocFee", "Ensuro Coc Fee", 0.1, types.float)
|
|
694
|
-
.addOptionalParam("roc", "Interest rate paid to Senior LPs for solvency capital", 0.05, types.float)
|
|
695
|
-
.addOptionalParam("jrRoc", "Interest rate paid to Junior LPs for solvency capital", 0.0, types.float)
|
|
696
|
-
.addOptionalParam("maxPayoutPerPolicy", "Max Payout Per policy", 10000, types.float)
|
|
697
|
-
.addOptionalParam("exposureLimit", "Exposure (sum of payouts) limit for the RM", 1e6, types.float)
|
|
698
|
-
.addOptionalParam("maxDuration", "Maximum policy duration in hours", 24 * 365, types.int)
|
|
699
|
-
.addOptionalParam("moc", "Margin of Conservativism", 1.0, types.float)
|
|
700
|
-
.addParam("wallet", "RM address", types.address)
|
|
701
|
-
.addParam("assetOracle", "Insured asset oracle address", types.address)
|
|
702
|
-
.addOptionalParam("referenceOracle", "Reference currency address", ethers.constants.AddressZero, types.address)
|
|
703
|
-
.addOptionalParam("slotSize", "Slot size", 0.01, types.float)
|
|
704
|
-
.addOptionalParam("oracleTolerance", "Oracle age tolerance", 1800, types.int)
|
|
705
|
-
.addOptionalParam("minDuration", "Minimum time that must elapse before a policy can be triggered", 3600, types.int)
|
|
706
|
-
.setAction(deployPriceRM);
|
|
707
|
-
|
|
708
691
|
task("ens:setAssetManager", "Sets an asset manager to a reserve")
|
|
709
692
|
.addParam("reserve", "Reserve Address", types.address)
|
|
710
693
|
.addParam("amAddress", "Address of Asset Manager (reuse one already deployed)", types.address)
|
|
@@ -813,5 +796,7 @@ module.exports = {
|
|
|
813
796
|
deployWhitelist,
|
|
814
797
|
WhitelistStatus,
|
|
815
798
|
txOverrides,
|
|
799
|
+
amountFunction,
|
|
800
|
+
_W,
|
|
816
801
|
_A,
|
|
817
802
|
};
|
package/js/test-utils.js
CHANGED
|
@@ -41,6 +41,19 @@ async function check_balances(currency, users, amounts) {
|
|
|
41
41
|
);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
const RiskModuleParameter = {
|
|
45
|
+
moc: 0,
|
|
46
|
+
jrCollRatio: 1,
|
|
47
|
+
collRatio: 2,
|
|
48
|
+
ensuroPpFee: 3,
|
|
49
|
+
ensuroCocFee: 4,
|
|
50
|
+
jrRoc: 5,
|
|
51
|
+
srRoc: 6,
|
|
52
|
+
maxPayoutPerPolicy: 7,
|
|
53
|
+
exposureLimit: 8,
|
|
54
|
+
maxDuration: 9,
|
|
55
|
+
};
|
|
56
|
+
|
|
44
57
|
const createRiskModule = async function (
|
|
45
58
|
pool,
|
|
46
59
|
premiumsAccount,
|
|
@@ -75,7 +88,6 @@ const createRiskModule = async function (
|
|
|
75
88
|
],
|
|
76
89
|
{
|
|
77
90
|
kind: "uups",
|
|
78
|
-
unsafeAllow: ["delegatecall"],
|
|
79
91
|
constructorArgs: [pool.address, premiumsAccount.address, ...extraConstructorArgs],
|
|
80
92
|
}
|
|
81
93
|
);
|
|
@@ -84,7 +96,7 @@ const createRiskModule = async function (
|
|
|
84
96
|
|
|
85
97
|
if (moc !== undefined && moc != 1.0) {
|
|
86
98
|
moc = _W(moc);
|
|
87
|
-
await rm.setParam(
|
|
99
|
+
await rm.setParam(RiskModuleParameter.moc, moc);
|
|
88
100
|
}
|
|
89
101
|
return rm;
|
|
90
102
|
};
|
|
@@ -141,7 +153,7 @@ const createEToken = async function (
|
|
|
141
153
|
],
|
|
142
154
|
{
|
|
143
155
|
kind: "uups",
|
|
144
|
-
unsafeAllow: ["delegatecall"],
|
|
156
|
+
unsafeAllow: ["delegatecall"], // This holds, because EToken is a reserve and uses delegatecall
|
|
145
157
|
constructorArgs: [pool.address, ...extraConstructorArgs],
|
|
146
158
|
}
|
|
147
159
|
);
|
|
@@ -236,7 +248,6 @@ async function deployPool(hre, options) {
|
|
|
236
248
|
{
|
|
237
249
|
constructorArgs: [accessManager.address, options.currency],
|
|
238
250
|
kind: "uups",
|
|
239
|
-
unsafeAllow: ["delegatecall"],
|
|
240
251
|
}
|
|
241
252
|
);
|
|
242
253
|
|
|
@@ -264,7 +275,7 @@ async function deployPremiumsAccount(hre, pool, options, addToPool = true) {
|
|
|
264
275
|
options.srEtkAddr || hre.ethers.constants.AddressZero,
|
|
265
276
|
],
|
|
266
277
|
kind: "uups",
|
|
267
|
-
unsafeAllow: ["delegatecall"],
|
|
278
|
+
unsafeAllow: ["delegatecall"], // This holds, because EToken is a reserve and uses delegatecall
|
|
268
279
|
});
|
|
269
280
|
|
|
270
281
|
await premiumsAccount.deployed();
|
|
@@ -424,34 +435,35 @@ async function makeSignedQuote(signer, policyParams) {
|
|
|
424
435
|
if (process.env.ENABLE_HH_WARNINGS !== "yes") hre.upgrades.silenceWarnings();
|
|
425
436
|
|
|
426
437
|
module.exports = {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
grantRole,
|
|
436
|
-
grantComponentRole,
|
|
437
|
-
initCurrency,
|
|
438
|
+
_BN,
|
|
439
|
+
_E,
|
|
440
|
+
_R,
|
|
441
|
+
_W,
|
|
442
|
+
accessControlMessage,
|
|
443
|
+
addEToken,
|
|
444
|
+
addRiskModule,
|
|
445
|
+
amountFunction,
|
|
438
446
|
approve_multiple,
|
|
439
447
|
check_balances,
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
getTransactionEvent,
|
|
448
|
+
createEToken,
|
|
449
|
+
createRiskModule,
|
|
450
|
+
DAY,
|
|
444
451
|
deployPool,
|
|
445
452
|
deployPremiumsAccount,
|
|
446
|
-
|
|
447
|
-
_BN,
|
|
448
|
-
WAD,
|
|
449
|
-
RAY,
|
|
450
|
-
amountFunction,
|
|
451
|
-
_W,
|
|
452
|
-
_R,
|
|
453
|
+
expected_change,
|
|
453
454
|
getComponentRole,
|
|
454
|
-
|
|
455
|
-
|
|
455
|
+
getRole,
|
|
456
|
+
getStorageLayout,
|
|
457
|
+
getTransactionEvent,
|
|
458
|
+
grantComponentRole,
|
|
459
|
+
grantRole,
|
|
460
|
+
initCurrency,
|
|
456
461
|
makePolicy,
|
|
462
|
+
makePolicyId,
|
|
463
|
+
makeQuoteMessage,
|
|
464
|
+
makeSignedQuote,
|
|
465
|
+
RAY,
|
|
466
|
+
RiskModuleParameter,
|
|
467
|
+
WAD,
|
|
468
|
+
WEEK,
|
|
457
469
|
};
|