@ensuro/core 2.0.0-beta2 → 2.0.0-beta5
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 +2 -1
- 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 +177 -119
- 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,40 @@ 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
|
|
178
|
+
// Deploy AccessManager
|
|
179
|
+
const accessManager = await hre.upgrades.deployProxy(AccessManager, [
|
|
160
180
|
options.policyPoolDetAddress || ethers.constants.AddressZero,
|
|
161
|
-
options.treasuryAddress || ethers.constants.AddressZero
|
|
162
181
|
], {kind: 'uups'});
|
|
163
182
|
|
|
164
|
-
await
|
|
183
|
+
await accessManager.deployed();
|
|
165
184
|
|
|
166
|
-
const policyPool = await hre.upgrades.deployProxy(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
185
|
+
const policyPool = await hre.upgrades.deployProxy(
|
|
186
|
+
PolicyPool,
|
|
187
|
+
[options.treasuryAddress || ethers.constants.AddressZero],
|
|
188
|
+
{
|
|
189
|
+
constructorArgs: [accessManager.address, policyNFT.address, options.currency],
|
|
190
|
+
kind: 'uups',
|
|
191
|
+
unsafeAllow: ["delegatecall"],
|
|
192
|
+
}
|
|
193
|
+
);
|
|
171
194
|
|
|
172
195
|
await policyPool.deployed();
|
|
173
196
|
|
|
174
197
|
for (const role of (options.grantRoles || [])) {
|
|
175
|
-
await grantRole(hre,
|
|
198
|
+
await grantRole(hre, accessManager, role);
|
|
176
199
|
}
|
|
177
200
|
|
|
178
|
-
await grantRole(hre,
|
|
179
|
-
await grantRole(hre,
|
|
180
|
-
await grantRole(hre,
|
|
201
|
+
await grantRole(hre, accessManager, "LEVEL1_ROLE");
|
|
202
|
+
await grantRole(hre, accessManager, "LEVEL2_ROLE");
|
|
203
|
+
await grantRole(hre, accessManager, "LEVEL3_ROLE");
|
|
181
204
|
return policyPool;
|
|
182
|
-
}
|
|
205
|
+
};
|
|
183
206
|
|
|
184
207
|
exports.deployPremiumsAccount = async function (hre, pool, options) {
|
|
185
208
|
const PremiumsAccount = await ethers.getContractFactory("PremiumsAccount");
|
|
@@ -189,14 +212,14 @@ exports.deployPremiumsAccount = async function (hre, pool, options) {
|
|
|
189
212
|
options.jrEtkAddr || ethers.constants.AddressZero,
|
|
190
213
|
options.srEtkAddr || ethers.constants.AddressZero,
|
|
191
214
|
],
|
|
192
|
-
kind:
|
|
215
|
+
kind: "uups",
|
|
193
216
|
unsafeAllow: ["delegatecall"],
|
|
194
217
|
});
|
|
195
218
|
|
|
196
219
|
await premiumsAccount.deployed();
|
|
197
220
|
await pool.addPremiumsAccount(premiumsAccount.address);
|
|
198
221
|
return premiumsAccount;
|
|
199
|
-
}
|
|
222
|
+
};
|
|
200
223
|
|
|
201
224
|
async function _getDefaultSigner(hre) {
|
|
202
225
|
const signers = await hre.ethers.getSigners();
|
|
@@ -212,7 +235,7 @@ async function grantRole(hre, contract, role, user) {
|
|
|
212
235
|
userAddress = user;
|
|
213
236
|
}
|
|
214
237
|
const roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
|
|
215
|
-
if (!await contract.hasRole(roleHex, userAddress)) {
|
|
238
|
+
if (!(await contract.hasRole(roleHex, userAddress))) {
|
|
216
239
|
await contract.grantRole(roleHex, userAddress);
|
|
217
240
|
}
|
|
218
241
|
}
|
|
@@ -229,7 +252,7 @@ async function grantComponentRole(hre, contract, component, role, user) {
|
|
|
229
252
|
}
|
|
230
253
|
const roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
|
|
231
254
|
const componentRole = await contract.getComponentRole(component.address, roleHex);
|
|
232
|
-
if (!await contract.hasRole(componentRole, userAddress)) {
|
|
255
|
+
if (!(await contract.hasRole(componentRole, userAddress))) {
|
|
233
256
|
await contract.grantComponentRole(component.address, roleHex, userAddress);
|
|
234
257
|
}
|
|
235
258
|
}
|
|
@@ -239,40 +262,75 @@ exports.grantComponentRole = grantComponentRole;
|
|
|
239
262
|
exports._E = ethers.utils.parseEther;
|
|
240
263
|
|
|
241
264
|
const _BN = ethers.BigNumber.from;
|
|
242
|
-
const WAD = _BN(1e10).mul(_BN(1e8));
|
|
243
|
-
const RAY = WAD.mul(_BN(1e9));
|
|
265
|
+
const WAD = _BN(1e10).mul(_BN(1e8)); // 1e10*1e8=1e18
|
|
266
|
+
const RAY = WAD.mul(_BN(1e9)); // 1e18*1e9=1e27
|
|
244
267
|
|
|
245
268
|
exports._BN = _BN;
|
|
246
269
|
|
|
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));
|
|
270
|
+
const _W = function (value) {
|
|
271
|
+
if (value === undefined) return undefined;
|
|
272
|
+
if (!Number.isInteger(value)) return _BN(Math.round(value * 1e9)).mul(_BN(1e9));
|
|
252
273
|
return _BN(value).mul(WAD);
|
|
253
|
-
}
|
|
274
|
+
};
|
|
254
275
|
|
|
255
276
|
exports._W = _W;
|
|
256
277
|
|
|
257
|
-
const _R = function(value) {
|
|
258
|
-
if (value === undefined)
|
|
259
|
-
|
|
260
|
-
if (!Number.isInteger(value))
|
|
261
|
-
return _BN(Math.round(value * 1e9)).mul(WAD);
|
|
278
|
+
const _R = function (value) {
|
|
279
|
+
if (value === undefined) return undefined;
|
|
280
|
+
if (!Number.isInteger(value)) return _BN(Math.round(value * 1e9)).mul(WAD);
|
|
262
281
|
return _BN(value).mul(RAY);
|
|
263
|
-
}
|
|
282
|
+
};
|
|
264
283
|
|
|
265
284
|
exports._R = _R;
|
|
266
285
|
|
|
267
286
|
exports.amountFunction = function (decimals) {
|
|
268
287
|
// Decimals must be at least 6
|
|
269
288
|
return function (value) {
|
|
270
|
-
if (value === undefined)
|
|
271
|
-
|
|
272
|
-
if (typeof value === 'string' || value instanceof String) {
|
|
289
|
+
if (value === undefined) return undefined;
|
|
290
|
+
if (typeof value === "string" || value instanceof String) {
|
|
273
291
|
return _BN(value).mul(_BN(Math.pow(10, decimals)));
|
|
274
292
|
} else {
|
|
275
293
|
return _BN(Math.round(value * 1e6)).mul(_BN(Math.pow(10, decimals - 6)));
|
|
276
294
|
}
|
|
277
|
-
}
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
/*
|
|
299
|
+
Builds the component role identifier
|
|
300
|
+
|
|
301
|
+
Mimics the behaviour of the PolicyPoolConfig.getComponentRole method
|
|
302
|
+
|
|
303
|
+
Component roles are roles created doing XOR between the component
|
|
304
|
+
address and the original role.
|
|
305
|
+
|
|
306
|
+
Example:
|
|
307
|
+
getComponentRole("0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", "ORACLE_ADMIN_ROLE")
|
|
308
|
+
// "0x05e01b185238b49f750d03d945e38a7f6c3be8b54de0ee42d481eb7814f0d3a8"
|
|
309
|
+
*/
|
|
310
|
+
function getComponentRole(componentAddress, roleName) {
|
|
311
|
+
// 32 byte array
|
|
312
|
+
const bytesRole = ethers.utils.arrayify(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(roleName)));
|
|
313
|
+
|
|
314
|
+
// 20 byte array
|
|
315
|
+
const bytesAddress = ethers.utils.arrayify(componentAddress);
|
|
316
|
+
|
|
317
|
+
// xor each byte, padding bytesAddress with zeros at the end
|
|
318
|
+
return ethers.utils.hexlify(bytesRole.map((elem, idx) => elem ^ (bytesAddress[idx] || 0)));
|
|
278
319
|
}
|
|
320
|
+
|
|
321
|
+
exports.getComponentRole = getComponentRole;
|
|
322
|
+
|
|
323
|
+
/*
|
|
324
|
+
Builds AccessControl error message for comparison in tests
|
|
325
|
+
*/
|
|
326
|
+
function accessControlMessage(address, component, role) {
|
|
327
|
+
return `AccessControl: account ${address.toLowerCase()} is missing role ${getComponentRole(component, role)}`;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
exports.accessControlMessage = accessControlMessage;
|
|
331
|
+
|
|
332
|
+
function makePolicyId(rm, internalId) {
|
|
333
|
+
return ethers.BigNumber.from(rm.address).shl(96).add(internalId);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
exports.makePolicyId = makePolicyId;
|