@ensuro/core 2.0.0-beta3 → 2.0.0-beta6
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 +487 -0
- package/build/contracts/EToken.sol/EToken.json +4 -4
- package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +4 -4
- package/build/contracts/PolicyNFT.sol/PolicyNFT.json +2 -2
- package/build/contracts/PolicyPool.sol/PolicyPool.json +148 -15
- package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +2 -2
- package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +4 -4
- package/build/contracts/Reserve.sol/Reserve.json +2 -2
- package/build/contracts/RiskModule.sol/RiskModule.json +2 -2
- package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +4 -4
- package/build/contracts/interfaces/{IPolicyPoolConfig.sol/IPolicyPoolConfig.json → IAccessManager.sol/IAccessManager.json} +2 -67
- package/build/contracts/interfaces/IPolicyPool.sol/IPolicyPool.json +15 -2
- package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +2 -2
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +19 -6
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +6 -6
- package/contracts/AccessManager.sol +72 -0
- package/contracts/EToken.sol +6 -13
- package/contracts/PolicyNFT.sol +3 -3
- package/contracts/PolicyPool.sol +108 -43
- package/contracts/PolicyPoolComponent.sol +11 -11
- package/contracts/PremiumsAccount.sol +1 -1
- package/contracts/RiskModule.sol +4 -8
- package/contracts/interfaces/{IPolicyPoolConfig.sol → IAccessManager.sol} +2 -21
- package/contracts/interfaces/IPolicyPool.sol +10 -5
- package/contracts/mocks/PolicyPoolMock.sol +15 -13
- package/js/test-utils.js +178 -122
- package/package.json +1 -1
- package/build/contracts/FlightDelayRiskModule.sol/FlightDelayRiskModule.json +0 -890
- package/build/contracts/PolicyPoolConfig.sol/PolicyPoolConfig.json +0 -665
- package/build/contracts/dependencies/ChainlinkClientUpgradeable.sol/ChainlinkClientUpgradeable.json +0 -63
- package/build/contracts/mocks/LinkTokenMock.sol/LinkTokenMock.json +0 -370
- package/build/contracts/upgraded/IPolicyNFTv1.sol/IPolicyNFTv1.json +0 -322
- package/build/contracts/upgraded/PolicyNFTv1.sol/PolicyNFTv1.json +0 -584
- package/build/contracts/upgraded/PolicyNFTv1.sol/PolicyNFTv1_Upgrade.json +0 -615
- package/contracts/FlightDelayRiskModule.sol +0 -217
- package/contracts/PolicyPoolConfig.sol +0 -185
- package/contracts/dependencies/ChainlinkClientUpgradeable.sol +0 -371
- package/contracts/mocks/LinkTokenMock.sol +0 -30
- package/contracts/upgraded/IPolicyNFTv1.sol +0 -15
- package/contracts/upgraded/PolicyNFTv1.sol +0 -126
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
pragma solidity ^0.8.0;
|
|
3
3
|
|
|
4
4
|
import {IAccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
|
|
5
|
-
import {ILPWhitelist} from "./ILPWhitelist.sol";
|
|
6
|
-
import {IRiskModule} from "./IRiskModule.sol";
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
|
-
* @title
|
|
7
|
+
* @title IAccessManager - Interface for the contract that handles roles for the PolicyPool and components
|
|
10
8
|
* @dev Interface for the contract that handles roles for the PolicyPool and components
|
|
11
9
|
* @author Ensuro
|
|
12
10
|
*/
|
|
13
|
-
interface
|
|
11
|
+
interface IAccessManager is IAccessControlUpgradeable {
|
|
14
12
|
enum GovernanceActions {
|
|
15
13
|
none,
|
|
16
14
|
setTreasury, // Changes PolicyPool treasury address
|
|
@@ -61,15 +59,6 @@ interface IPolicyPoolConfig is IAccessControlUpgradeable {
|
|
|
61
59
|
last
|
|
62
60
|
}
|
|
63
61
|
|
|
64
|
-
enum RiskModuleStatus {
|
|
65
|
-
inactive, // newPolicy and resolvePolicy rejected
|
|
66
|
-
active, // newPolicy and resolvePolicy accepted
|
|
67
|
-
deprecated, // newPolicy rejected, resolvePolicy accepted
|
|
68
|
-
suspended // newPolicy and resolvePolicy rejected (temporarily)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
event RiskModuleStatusChanged(IRiskModule indexed riskModule, RiskModuleStatus newStatus);
|
|
72
|
-
|
|
73
62
|
function checkRole(bytes32 role, address account) external view;
|
|
74
63
|
|
|
75
64
|
function checkComponentRole(
|
|
@@ -83,12 +72,4 @@ interface IPolicyPoolConfig is IAccessControlUpgradeable {
|
|
|
83
72
|
bytes32 role2,
|
|
84
73
|
address account
|
|
85
74
|
) external view;
|
|
86
|
-
|
|
87
|
-
function connect() external;
|
|
88
|
-
|
|
89
|
-
function treasury() external view returns (address);
|
|
90
|
-
|
|
91
|
-
function checkAcceptsNewPolicy(IRiskModule riskModule) external view;
|
|
92
|
-
|
|
93
|
-
function checkAcceptsResolvePolicy(IRiskModule riskModule) external view;
|
|
94
75
|
}
|
|
@@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
|
|
|
4
4
|
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
|
|
5
5
|
import {Policy} from "../Policy.sol";
|
|
6
6
|
import {IEToken} from "./IEToken.sol";
|
|
7
|
-
import {
|
|
7
|
+
import {IAccessManager} from "./IAccessManager.sol";
|
|
8
8
|
|
|
9
9
|
interface IPolicyPool {
|
|
10
10
|
/**
|
|
@@ -14,11 +14,10 @@ interface IPolicyPool {
|
|
|
14
14
|
function currency() external view returns (IERC20Metadata);
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* @dev Reference to the {
|
|
18
|
-
*
|
|
19
|
-
* @return The address of the PolicyPoolConfig contract
|
|
17
|
+
* @dev Reference to the {AccessManager} contract, this contract manages the access controls.
|
|
18
|
+
* @return The address of the AccessManager contract
|
|
20
19
|
*/
|
|
21
|
-
function
|
|
20
|
+
function access() external view returns (IAccessManager);
|
|
22
21
|
|
|
23
22
|
/**
|
|
24
23
|
* @dev Reference to the {PolicyNFT} contract. This contract it's an ERC721 Token that handles the ownership of the
|
|
@@ -27,6 +26,12 @@ interface IPolicyPool {
|
|
|
27
26
|
*/
|
|
28
27
|
function policyNFT() external view returns (address);
|
|
29
28
|
|
|
29
|
+
/**
|
|
30
|
+
* @dev Address of the treasury, that receives protocol fees.
|
|
31
|
+
* @return The address of the treasury
|
|
32
|
+
*/
|
|
33
|
+
function treasury() external view returns (address);
|
|
34
|
+
|
|
30
35
|
/**
|
|
31
36
|
* @dev Creates a new Policy. Must be called from an active RiskModule
|
|
32
37
|
*
|
|
@@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
|
|
|
4
4
|
import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
|
|
5
5
|
import {IRiskModule} from "../interfaces/IRiskModule.sol";
|
|
6
6
|
import {IEToken} from "../interfaces/IEToken.sol";
|
|
7
|
-
import {
|
|
7
|
+
import {IAccessManager} from "../interfaces/IAccessManager.sol";
|
|
8
8
|
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
|
|
9
9
|
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
|
|
10
10
|
import {Policy} from "../Policy.sol";
|
|
@@ -17,7 +17,7 @@ contract PolicyPoolMock is IPolicyPool {
|
|
|
17
17
|
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
|
|
18
18
|
|
|
19
19
|
IERC20Metadata internal _currency;
|
|
20
|
-
|
|
20
|
+
IAccessManager internal _access;
|
|
21
21
|
|
|
22
22
|
mapping(uint256 => Policy.PolicyData) internal policies;
|
|
23
23
|
mapping(uint256 => bytes32) internal policyHashes;
|
|
@@ -25,24 +25,27 @@ contract PolicyPoolMock is IPolicyPool {
|
|
|
25
25
|
event NewPolicy(IRiskModule indexed riskModule, Policy.PolicyData policy);
|
|
26
26
|
event PolicyResolved(IRiskModule indexed riskModule, uint256 indexed policyId, uint256 payout);
|
|
27
27
|
|
|
28
|
-
constructor(IERC20Metadata currency_,
|
|
28
|
+
constructor(IERC20Metadata currency_, IAccessManager access_) {
|
|
29
29
|
_currency = currency_;
|
|
30
|
-
|
|
31
|
-
_config.connect();
|
|
30
|
+
_access = access_;
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
function currency() external view override returns (IERC20Metadata) {
|
|
35
34
|
return _currency;
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
function
|
|
39
|
-
return
|
|
37
|
+
function access() external view override returns (IAccessManager) {
|
|
38
|
+
return _access;
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
function policyNFT() external pure override returns (address) {
|
|
43
42
|
return address(0);
|
|
44
43
|
}
|
|
45
44
|
|
|
45
|
+
function treasury() external pure override returns (address) {
|
|
46
|
+
return address(0);
|
|
47
|
+
}
|
|
48
|
+
|
|
46
49
|
function newPolicy(
|
|
47
50
|
Policy.PolicyData memory policy,
|
|
48
51
|
address, /* customer */
|
|
@@ -100,23 +103,22 @@ contract PolicyPoolMockForward is ForwardProxy {
|
|
|
100
103
|
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
|
|
101
104
|
|
|
102
105
|
IERC20Metadata internal _currency;
|
|
103
|
-
|
|
106
|
+
IAccessManager internal _access;
|
|
104
107
|
|
|
105
108
|
constructor(
|
|
106
109
|
address forwardTo,
|
|
107
110
|
IERC20Metadata currency_,
|
|
108
|
-
|
|
111
|
+
IAccessManager access_
|
|
109
112
|
) ForwardProxy(forwardTo) {
|
|
110
113
|
_currency = currency_;
|
|
111
|
-
|
|
112
|
-
_config.connect();
|
|
114
|
+
_access = access_;
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
function currency() external view returns (IERC20Metadata) {
|
|
116
118
|
return _currency;
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
function
|
|
120
|
-
return
|
|
121
|
+
function access() external view returns (IAccessManager) {
|
|
122
|
+
return _access;
|
|
121
123
|
}
|
|
122
124
|
}
|
package/js/test-utils.js
CHANGED
|
@@ -1,61 +1,84 @@
|
|
|
1
1
|
const { expect } = require("chai");
|
|
2
2
|
const { BigNumber } = require("ethers");
|
|
3
|
-
const {LogDescription} = require("ethers/lib/utils");
|
|
3
|
+
const { LogDescription } = require("ethers/lib/utils");
|
|
4
4
|
exports.WEEK = 3600 * 24 * 7;
|
|
5
5
|
exports.DAY = 3600 * 24;
|
|
6
6
|
|
|
7
|
-
exports.initCurrency = async function(options, initial_targets, initial_balances) {
|
|
7
|
+
exports.initCurrency = async function (options, initial_targets, initial_balances) {
|
|
8
8
|
const Currency = await ethers.getContractFactory("TestCurrency");
|
|
9
9
|
let currency = await Currency.deploy(
|
|
10
10
|
options.name || "Test Currency",
|
|
11
11
|
options.symbol || "TEST",
|
|
12
12
|
options.initial_supply,
|
|
13
|
-
options.decimals || 18
|
|
13
|
+
options.decimals || 18
|
|
14
14
|
);
|
|
15
15
|
initial_targets = initial_targets || [];
|
|
16
|
-
await Promise.all(
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
await Promise.all(
|
|
17
|
+
initial_targets.map(async function (user, index) {
|
|
18
|
+
await currency.transfer(user.address, initial_balances[index]);
|
|
19
|
+
})
|
|
20
|
+
);
|
|
19
21
|
return currency;
|
|
20
|
-
}
|
|
22
|
+
};
|
|
21
23
|
|
|
22
|
-
exports.approve_multiple = async function(currency, spender, sources, amounts) {
|
|
23
|
-
return Promise.all(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
24
|
+
exports.approve_multiple = async function (currency, spender, sources, amounts) {
|
|
25
|
+
return Promise.all(
|
|
26
|
+
sources.map(async function (source, index) {
|
|
27
|
+
await currency.connect(source).approve(spender.address, amounts[index]);
|
|
28
|
+
})
|
|
29
|
+
);
|
|
30
|
+
};
|
|
27
31
|
|
|
28
|
-
exports.check_balances = async function(currency, users, amounts) {
|
|
29
|
-
return Promise.all(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
32
|
+
exports.check_balances = async function (currency, users, amounts) {
|
|
33
|
+
return Promise.all(
|
|
34
|
+
users.map(async function (user, index) {
|
|
35
|
+
expect(await currency.balanceOf(user.address)).to.equal(amounts[index]);
|
|
36
|
+
})
|
|
37
|
+
);
|
|
38
|
+
};
|
|
33
39
|
|
|
34
|
-
exports.now = function() {
|
|
40
|
+
exports.now = function () {
|
|
35
41
|
return Math.floor(new Date().getTime() / 1000);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
exports.addRiskModule = async function(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
exports.addRiskModule = async function (
|
|
45
|
+
pool,
|
|
46
|
+
premiumsAccount,
|
|
47
|
+
contractFactory,
|
|
48
|
+
{
|
|
49
|
+
rmName,
|
|
50
|
+
scrPercentage,
|
|
51
|
+
scrInterestRate,
|
|
52
|
+
ensuroFee,
|
|
53
|
+
maxScrPerPolicy,
|
|
54
|
+
scrLimit,
|
|
55
|
+
moc,
|
|
56
|
+
wallet,
|
|
57
|
+
extraArgs,
|
|
58
|
+
extraConstructorArgs,
|
|
59
|
+
}
|
|
60
|
+
) {
|
|
42
61
|
extraArgs = extraArgs || [];
|
|
43
62
|
extraConstructorArgs = extraConstructorArgs || [];
|
|
44
63
|
const _A = pool._A || _W;
|
|
45
|
-
const rm = await hre.upgrades.deployProxy(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
const rm = await hre.upgrades.deployProxy(
|
|
65
|
+
contractFactory,
|
|
66
|
+
[
|
|
67
|
+
rmName || "RiskModule",
|
|
68
|
+
_W(scrPercentage) || _W(1),
|
|
69
|
+
_W(ensuroFee) || _W(0),
|
|
70
|
+
_W(scrInterestRate) || _W(0.1),
|
|
71
|
+
_A(maxScrPerPolicy) || _A(1000),
|
|
72
|
+
_A(scrLimit) || _A(1000000),
|
|
73
|
+
wallet || "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", // Random address
|
|
74
|
+
...extraArgs,
|
|
75
|
+
],
|
|
76
|
+
{
|
|
77
|
+
kind: "uups",
|
|
78
|
+
unsafeAllow: ["delegatecall"],
|
|
79
|
+
constructorArgs: [pool.address, premiumsAccount.address, ...extraConstructorArgs],
|
|
80
|
+
}
|
|
81
|
+
);
|
|
59
82
|
|
|
60
83
|
await rm.deployed();
|
|
61
84
|
|
|
@@ -63,66 +86,63 @@ exports.addRiskModule = async function(pool, premiumsAccount, contractFactory, {
|
|
|
63
86
|
moc = _W(moc);
|
|
64
87
|
await rm.setParam(0, moc);
|
|
65
88
|
}
|
|
66
|
-
|
|
67
|
-
await policyPoolConfig.addRiskModule(rm.address);
|
|
89
|
+
await pool.addRiskModule(rm.address);
|
|
68
90
|
return rm;
|
|
69
|
-
}
|
|
91
|
+
};
|
|
70
92
|
|
|
71
|
-
exports.addEToken = async function(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
93
|
+
exports.addEToken = async function (
|
|
94
|
+
pool,
|
|
95
|
+
{ etkName, etkSymbol, maxUtilizationRate, poolLoanInterestRate, extraArgs, extraConstructorArgs }
|
|
96
|
+
) {
|
|
75
97
|
const EToken = await ethers.getContractFactory("EToken");
|
|
76
98
|
extraArgs = extraArgs || [];
|
|
77
99
|
extraConstructorArgs = extraConstructorArgs || [];
|
|
78
|
-
const etk = await hre.upgrades.deployProxy(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
100
|
+
const etk = await hre.upgrades.deployProxy(
|
|
101
|
+
EToken,
|
|
102
|
+
[
|
|
103
|
+
etkName || "EToken",
|
|
104
|
+
etkSymbol || "eUSD1YEAR",
|
|
105
|
+
_W(maxUtilizationRate) || _W(1),
|
|
106
|
+
_W(poolLoanInterestRate) || _W("0.05"),
|
|
107
|
+
...extraArgs,
|
|
108
|
+
],
|
|
109
|
+
{
|
|
110
|
+
kind: "uups",
|
|
111
|
+
unsafeAllow: ["delegatecall"],
|
|
112
|
+
constructorArgs: [pool.address, ...extraConstructorArgs],
|
|
113
|
+
}
|
|
114
|
+
);
|
|
89
115
|
|
|
90
116
|
await etk.deployed();
|
|
91
117
|
await pool.addEToken(etk.address);
|
|
92
118
|
return etk;
|
|
93
|
-
}
|
|
119
|
+
};
|
|
94
120
|
|
|
95
|
-
exports.expected_change = async function(protocol_attribute, initial, change) {
|
|
121
|
+
exports.expected_change = async function (protocol_attribute, initial, change) {
|
|
96
122
|
change = BigNumber.from(change);
|
|
97
123
|
let actual_value = await protocol_attribute();
|
|
98
124
|
expect(actual_value.sub(initial)).to.equal(change);
|
|
99
125
|
return actual_value;
|
|
100
|
-
}
|
|
126
|
+
};
|
|
101
127
|
|
|
102
|
-
exports.impersonate = async function(address, setBalanceTo) {
|
|
103
|
-
const ok = await hre.network.provider.request(
|
|
104
|
-
|
|
105
|
-
);
|
|
106
|
-
if (!ok)
|
|
107
|
-
throw "Error impersonatting " + address;
|
|
128
|
+
exports.impersonate = async function (address, setBalanceTo) {
|
|
129
|
+
const ok = await hre.network.provider.request({ method: "hardhat_impersonateAccount", params: [address] });
|
|
130
|
+
if (!ok) throw "Error impersonatting " + address;
|
|
108
131
|
|
|
109
132
|
if (setBalanceTo !== undefined)
|
|
110
|
-
await hre.network.provider.request(
|
|
111
|
-
{method: "hardhat_setBalance", params: [address, setBalanceTo.toHexString()]}
|
|
112
|
-
);
|
|
133
|
+
await hre.network.provider.request({ method: "hardhat_setBalance", params: [address, setBalanceTo.toHexString()] });
|
|
113
134
|
|
|
114
135
|
return await ethers.getSigner(address);
|
|
115
|
-
}
|
|
116
|
-
|
|
136
|
+
};
|
|
117
137
|
|
|
118
138
|
/**
|
|
119
|
-
* Finds an event in the receipt
|
|
120
|
-
* @param {Interface} interface The interface of the contract that contains the requested event
|
|
121
|
-
* @param {TransactionReceipt} receipt Transaction receipt containing the events in the logs
|
|
122
|
-
* @param {String} eventName The name of the event we are interested in
|
|
123
|
-
* @returns {LogDescription}
|
|
124
|
-
*/
|
|
125
|
-
exports.getTransactionEvent = function(interface, receipt, eventName) {
|
|
139
|
+
* Finds an event in the receipt
|
|
140
|
+
* @param {Interface} interface The interface of the contract that contains the requested event
|
|
141
|
+
* @param {TransactionReceipt} receipt Transaction receipt containing the events in the logs
|
|
142
|
+
* @param {String} eventName The name of the event we are interested in
|
|
143
|
+
* @returns {LogDescription}
|
|
144
|
+
*/
|
|
145
|
+
exports.getTransactionEvent = function (interface, receipt, eventName) {
|
|
126
146
|
// for each log in the transaction receipt
|
|
127
147
|
for (const log of receipt.events) {
|
|
128
148
|
let parsedLog;
|
|
@@ -135,12 +155,12 @@ exports.getTransactionEvent = function(interface, receipt, eventName) {
|
|
|
135
155
|
return parsedLog;
|
|
136
156
|
}
|
|
137
157
|
}
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
158
|
+
return null; // not found
|
|
159
|
+
};
|
|
140
160
|
|
|
141
|
-
exports.deployPool = async function(hre, options) {
|
|
161
|
+
exports.deployPool = async function (hre, options) {
|
|
142
162
|
const PolicyPool = await ethers.getContractFactory("PolicyPool");
|
|
143
|
-
const
|
|
163
|
+
const AccessManager = await ethers.getContractFactory("AccessManager");
|
|
144
164
|
const PolicyNFT = await ethers.getContractFactory("PolicyNFT");
|
|
145
165
|
|
|
146
166
|
// Deploy PolicyNFT
|
|
@@ -149,37 +169,38 @@ exports.deployPool = async function(hre, options) {
|
|
|
149
169
|
[
|
|
150
170
|
options.nftName || "Policy NFT",
|
|
151
171
|
options.nftSymbol || "EPOL",
|
|
152
|
-
options.policyPoolDetAddress || ethers.constants.AddressZero
|
|
172
|
+
options.policyPoolDetAddress || ethers.constants.AddressZero,
|
|
153
173
|
],
|
|
154
|
-
{kind:
|
|
174
|
+
{ kind: "uups" }
|
|
155
175
|
);
|
|
156
176
|
await policyNFT.deployed();
|
|
157
177
|
|
|
158
|
-
// Deploy
|
|
159
|
-
const
|
|
160
|
-
options.policyPoolDetAddress || ethers.constants.AddressZero,
|
|
161
|
-
options.treasuryAddress || ethers.constants.AddressZero
|
|
162
|
-
], {kind: 'uups'});
|
|
178
|
+
// Deploy AccessManager
|
|
179
|
+
const accessManager = await hre.upgrades.deployProxy(AccessManager, [], { kind: "uups" });
|
|
163
180
|
|
|
164
|
-
await
|
|
181
|
+
await accessManager.deployed();
|
|
165
182
|
|
|
166
|
-
const policyPool = await hre.upgrades.deployProxy(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
183
|
+
const policyPool = await hre.upgrades.deployProxy(
|
|
184
|
+
PolicyPool,
|
|
185
|
+
[options.treasuryAddress || ethers.constants.AddressZero],
|
|
186
|
+
{
|
|
187
|
+
constructorArgs: [accessManager.address, policyNFT.address, options.currency],
|
|
188
|
+
kind: "uups",
|
|
189
|
+
unsafeAllow: ["delegatecall"],
|
|
190
|
+
}
|
|
191
|
+
);
|
|
171
192
|
|
|
172
193
|
await policyPool.deployed();
|
|
173
194
|
|
|
174
|
-
for (const role of
|
|
175
|
-
await grantRole(hre,
|
|
195
|
+
for (const role of options.grantRoles || []) {
|
|
196
|
+
await grantRole(hre, accessManager, role);
|
|
176
197
|
}
|
|
177
198
|
|
|
178
|
-
await grantRole(hre,
|
|
179
|
-
await grantRole(hre,
|
|
180
|
-
await grantRole(hre,
|
|
199
|
+
await grantRole(hre, accessManager, "LEVEL1_ROLE");
|
|
200
|
+
await grantRole(hre, accessManager, "LEVEL2_ROLE");
|
|
201
|
+
await grantRole(hre, accessManager, "LEVEL3_ROLE");
|
|
181
202
|
return policyPool;
|
|
182
|
-
}
|
|
203
|
+
};
|
|
183
204
|
|
|
184
205
|
exports.deployPremiumsAccount = async function (hre, pool, options) {
|
|
185
206
|
const PremiumsAccount = await ethers.getContractFactory("PremiumsAccount");
|
|
@@ -189,14 +210,14 @@ exports.deployPremiumsAccount = async function (hre, pool, options) {
|
|
|
189
210
|
options.jrEtkAddr || ethers.constants.AddressZero,
|
|
190
211
|
options.srEtkAddr || ethers.constants.AddressZero,
|
|
191
212
|
],
|
|
192
|
-
kind:
|
|
213
|
+
kind: "uups",
|
|
193
214
|
unsafeAllow: ["delegatecall"],
|
|
194
215
|
});
|
|
195
216
|
|
|
196
217
|
await premiumsAccount.deployed();
|
|
197
218
|
await pool.addPremiumsAccount(premiumsAccount.address);
|
|
198
219
|
return premiumsAccount;
|
|
199
|
-
}
|
|
220
|
+
};
|
|
200
221
|
|
|
201
222
|
async function _getDefaultSigner(hre) {
|
|
202
223
|
const signers = await hre.ethers.getSigners();
|
|
@@ -212,7 +233,7 @@ async function grantRole(hre, contract, role, user) {
|
|
|
212
233
|
userAddress = user;
|
|
213
234
|
}
|
|
214
235
|
const roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
|
|
215
|
-
if (!await contract.hasRole(roleHex, userAddress)) {
|
|
236
|
+
if (!(await contract.hasRole(roleHex, userAddress))) {
|
|
216
237
|
await contract.grantRole(roleHex, userAddress);
|
|
217
238
|
}
|
|
218
239
|
}
|
|
@@ -229,7 +250,7 @@ async function grantComponentRole(hre, contract, component, role, user) {
|
|
|
229
250
|
}
|
|
230
251
|
const roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
|
|
231
252
|
const componentRole = await contract.getComponentRole(component.address, roleHex);
|
|
232
|
-
if (!await contract.hasRole(componentRole, userAddress)) {
|
|
253
|
+
if (!(await contract.hasRole(componentRole, userAddress))) {
|
|
233
254
|
await contract.grantComponentRole(component.address, roleHex, userAddress);
|
|
234
255
|
}
|
|
235
256
|
}
|
|
@@ -239,40 +260,75 @@ exports.grantComponentRole = grantComponentRole;
|
|
|
239
260
|
exports._E = ethers.utils.parseEther;
|
|
240
261
|
|
|
241
262
|
const _BN = ethers.BigNumber.from;
|
|
242
|
-
const WAD = _BN(1e10).mul(_BN(1e8));
|
|
243
|
-
const RAY = WAD.mul(_BN(1e9));
|
|
263
|
+
const WAD = _BN(1e10).mul(_BN(1e8)); // 1e10*1e8=1e18
|
|
264
|
+
const RAY = WAD.mul(_BN(1e9)); // 1e18*1e9=1e27
|
|
244
265
|
|
|
245
266
|
exports._BN = _BN;
|
|
246
267
|
|
|
247
|
-
const _W = function(value) {
|
|
248
|
-
if (value === undefined)
|
|
249
|
-
|
|
250
|
-
if (!Number.isInteger(value))
|
|
251
|
-
return _BN(Math.round(value * 1e9)).mul(_BN(1e9));
|
|
268
|
+
const _W = function (value) {
|
|
269
|
+
if (value === undefined) return undefined;
|
|
270
|
+
if (!Number.isInteger(value)) return _BN(Math.round(value * 1e9)).mul(_BN(1e9));
|
|
252
271
|
return _BN(value).mul(WAD);
|
|
253
|
-
}
|
|
272
|
+
};
|
|
254
273
|
|
|
255
274
|
exports._W = _W;
|
|
256
275
|
|
|
257
|
-
const _R = function(value) {
|
|
258
|
-
if (value === undefined)
|
|
259
|
-
|
|
260
|
-
if (!Number.isInteger(value))
|
|
261
|
-
return _BN(Math.round(value * 1e9)).mul(WAD);
|
|
276
|
+
const _R = function (value) {
|
|
277
|
+
if (value === undefined) return undefined;
|
|
278
|
+
if (!Number.isInteger(value)) return _BN(Math.round(value * 1e9)).mul(WAD);
|
|
262
279
|
return _BN(value).mul(RAY);
|
|
263
|
-
}
|
|
280
|
+
};
|
|
264
281
|
|
|
265
282
|
exports._R = _R;
|
|
266
283
|
|
|
267
284
|
exports.amountFunction = function (decimals) {
|
|
268
285
|
// Decimals must be at least 6
|
|
269
286
|
return function (value) {
|
|
270
|
-
if (value === undefined)
|
|
271
|
-
|
|
272
|
-
if (typeof value === 'string' || value instanceof String) {
|
|
287
|
+
if (value === undefined) return undefined;
|
|
288
|
+
if (typeof value === "string" || value instanceof String) {
|
|
273
289
|
return _BN(value).mul(_BN(Math.pow(10, decimals)));
|
|
274
290
|
} else {
|
|
275
291
|
return _BN(Math.round(value * 1e6)).mul(_BN(Math.pow(10, decimals - 6)));
|
|
276
292
|
}
|
|
277
|
-
}
|
|
293
|
+
};
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
/*
|
|
297
|
+
Builds the component role identifier
|
|
298
|
+
|
|
299
|
+
Mimics the behaviour of the PolicyPoolConfig.getComponentRole method
|
|
300
|
+
|
|
301
|
+
Component roles are roles created doing XOR between the component
|
|
302
|
+
address and the original role.
|
|
303
|
+
|
|
304
|
+
Example:
|
|
305
|
+
getComponentRole("0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", "ORACLE_ADMIN_ROLE")
|
|
306
|
+
// "0x05e01b185238b49f750d03d945e38a7f6c3be8b54de0ee42d481eb7814f0d3a8"
|
|
307
|
+
*/
|
|
308
|
+
function getComponentRole(componentAddress, roleName) {
|
|
309
|
+
// 32 byte array
|
|
310
|
+
const bytesRole = ethers.utils.arrayify(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(roleName)));
|
|
311
|
+
|
|
312
|
+
// 20 byte array
|
|
313
|
+
const bytesAddress = ethers.utils.arrayify(componentAddress);
|
|
314
|
+
|
|
315
|
+
// xor each byte, padding bytesAddress with zeros at the end
|
|
316
|
+
return ethers.utils.hexlify(bytesRole.map((elem, idx) => elem ^ (bytesAddress[idx] || 0)));
|
|
278
317
|
}
|
|
318
|
+
|
|
319
|
+
exports.getComponentRole = getComponentRole;
|
|
320
|
+
|
|
321
|
+
/*
|
|
322
|
+
Builds AccessControl error message for comparison in tests
|
|
323
|
+
*/
|
|
324
|
+
function accessControlMessage(address, component, role) {
|
|
325
|
+
return `AccessControl: account ${address.toLowerCase()} is missing role ${getComponentRole(component, role)}`;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
exports.accessControlMessage = accessControlMessage;
|
|
329
|
+
|
|
330
|
+
function makePolicyId(rm, internalId) {
|
|
331
|
+
return ethers.BigNumber.from(rm.address).shl(96).add(internalId);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
exports.makePolicyId = makePolicyId;
|