@ensuro/core 1.2.7 → 2.0.0-beta3
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 +50 -17
- package/build/contracts/EToken.sol/EToken.json +144 -173
- package/build/contracts/FlightDelayRiskModule.sol/FlightDelayRiskModule.json +101 -323
- package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +15 -2
- package/build/contracts/Policy.sol/Policy.json +2 -2
- package/build/contracts/PolicyNFT.sol/PolicyNFT.json +16 -3
- package/build/contracts/PolicyPool.sol/PolicyPool.json +105 -351
- package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +13 -0
- package/build/contracts/PolicyPoolConfig.sol/PolicyPoolConfig.json +77 -98
- package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +761 -0
- package/build/contracts/{BaseAssetManager.sol/BaseAssetManager.json → Reserve.sol/Reserve.json} +15 -202
- package/build/contracts/RiskModule.sol/RiskModule.json +83 -310
- package/build/contracts/TimeScaled.sol/TimeScaled.json +24 -0
- package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +131 -333
- package/build/contracts/dependencies/ChainlinkClientUpgradeable.sol/ChainlinkClientUpgradeable.json +15 -2
- package/build/contracts/dependencies/ERC1967Proxy.sol/ERC1967Proxy.json +64 -0
- package/build/{interfaces/IExchange.sol/IExchange.json → contracts/dependencies/IERC20Metadata.sol/IERC20Metadata.json} +83 -79
- package/build/{interfaces → contracts/interfaces}/IEToken.sol/IEToken.json +32 -97
- package/build/{interfaces → contracts/interfaces}/ILPWhitelist.sol/ILPWhitelist.json +1 -1
- package/build/{interfaces → contracts/interfaces}/IPolicyHolder.sol/IPolicyHolder.json +1 -1
- package/build/{interfaces → contracts/interfaces}/IPolicyNFT.sol/IPolicyNFT.json +1 -1
- package/build/{interfaces → contracts/interfaces}/IPolicyPool.sol/IPolicyPool.json +121 -108
- package/build/{interfaces → contracts/interfaces}/IPolicyPoolComponent.sol/IPolicyPoolComponent.json +1 -1
- package/build/{interfaces → contracts/interfaces}/IPolicyPoolConfig.sol/IPolicyPoolConfig.json +20 -49
- package/build/contracts/interfaces/IPremiumsAccount.sol/IPremiumsAccount.json +302 -0
- package/build/{interfaces → contracts/interfaces}/IRiskModule.sol/IRiskModule.json +58 -34
- package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +43 -0
- package/build/{interfaces/IInsolvencyHook.sol/IInsolvencyHook.json → contracts/mocks/IMintableERC20.sol/IMintableERC20.json} +13 -8
- package/build/contracts/mocks/LinkTokenMock.sol/LinkTokenMock.json +370 -0
- package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +202 -0
- package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +35 -0
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +603 -0
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +92 -0
- package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +343 -0
- package/build/contracts/mocks/TestNFT.sol/TestNFT.json +388 -0
- package/build/contracts/upgraded/PolicyNFTv1.sol/PolicyNFTv1.json +16 -3
- package/build/contracts/upgraded/PolicyNFTv1.sol/PolicyNFTv1_Upgrade.json +16 -3
- package/contracts/EToken.sol +210 -267
- package/contracts/FlightDelayRiskModule.sol +30 -21
- package/contracts/LPManualWhitelist.sol +4 -4
- package/contracts/Policy.sol +48 -44
- package/contracts/PolicyNFT.sol +2 -2
- package/contracts/PolicyPool.sol +114 -467
- package/contracts/PolicyPoolComponent.sol +8 -3
- package/contracts/PolicyPoolConfig.sol +29 -91
- package/contracts/PremiumsAccount.sol +274 -0
- package/contracts/Reserve.sol +34 -0
- package/contracts/RiskModule.sol +216 -164
- package/contracts/TimeScaled.sol +134 -0
- package/contracts/TrustfulRiskModule.sol +23 -21
- package/contracts/dependencies/ERC1967Proxy.sol +19 -0
- package/contracts/dependencies/IERC20Metadata.sol +19 -0
- package/contracts/interfaces/IEToken.sol +172 -0
- package/{interfaces → contracts/interfaces}/ILPWhitelist.sol +0 -0
- package/{interfaces → contracts/interfaces}/IPolicyHolder.sol +0 -0
- package/{interfaces → contracts/interfaces}/IPolicyNFT.sol +0 -0
- package/contracts/interfaces/IPolicyPool.sol +138 -0
- package/{interfaces → contracts/interfaces}/IPolicyPoolComponent.sol +0 -0
- package/{interfaces → contracts/interfaces}/IPolicyPoolConfig.sol +29 -22
- package/contracts/interfaces/IPremiumsAccount.sol +71 -0
- package/contracts/interfaces/IRiskModule.sol +60 -0
- package/contracts/mocks/ForwardProxy.sol +66 -0
- package/contracts/mocks/IMintableERC20.sol +13 -0
- package/contracts/mocks/LinkTokenMock.sol +30 -0
- package/contracts/mocks/PolicyHolderMock.sol +68 -0
- package/contracts/mocks/PolicyPoolComponentMock.sol +17 -0
- package/contracts/mocks/PolicyPoolMock.sol +122 -0
- package/contracts/mocks/TestCurrency.sol +35 -0
- package/contracts/mocks/TestNFT.sol +23 -0
- package/contracts/upgraded/PolicyNFTv1.sol +1 -1
- package/js/test-utils.js +278 -0
- package/package.json +2 -2
- package/build/contracts/AaveAssetManager.sol/AaveAssetManager.json +0 -742
- package/build/contracts/DataTypes.sol/DataTypes.json +0 -10
- package/build/contracts/Exchange.sol/Exchange.json +0 -591
- package/build/contracts/extras/IPriceRiskModule.sol/IPriceRiskModule.json +0 -253
- package/build/contracts/extras/PriceRiskModule.sol/PriceRiskModule.json +0 -1055
- package/build/interfaces/IAssetManager.sol/IAssetManager.json +0 -31
- package/build/interfaces/IExchange.sol/IPriceOracle.json +0 -30
- package/contracts/AaveAssetManager.sol +0 -298
- package/contracts/BaseAssetManager.sol +0 -301
- package/contracts/DataTypes.sol +0 -287
- package/contracts/Exchange.sol +0 -189
- package/contracts/extras/IPriceRiskModule.sol +0 -41
- package/contracts/extras/PriceRiskModule.sol +0 -243
- package/interfaces/IAssetManager.sol +0 -23
- package/interfaces/IEToken.sol +0 -48
- package/interfaces/IExchange.sol +0 -59
- package/interfaces/IInsolvencyHook.sol +0 -27
- package/interfaces/IPolicyPool.sol +0 -44
- package/interfaces/IRiskModule.sol +0 -29
package/contracts/PolicyPool.sol
CHANGED
|
@@ -5,21 +5,18 @@ import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IER
|
|
|
5
5
|
import {AddressUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
|
|
6
6
|
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
7
7
|
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
8
|
-
import {IPolicyPoolConfig} from "
|
|
8
|
+
import {IPolicyPoolConfig} from "./interfaces/IPolicyPoolConfig.sol";
|
|
9
9
|
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
|
|
10
10
|
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {IPolicyPoolComponent} from "
|
|
15
|
-
import {IEToken} from "
|
|
16
|
-
import {IPolicyNFT} from "
|
|
17
|
-
import {IPolicyHolder} from "
|
|
18
|
-
import {IAssetManager} from "../interfaces/IAssetManager.sol";
|
|
11
|
+
import {IPremiumsAccount} from "./interfaces/IPremiumsAccount.sol";
|
|
12
|
+
import {IPolicyPool} from "./interfaces/IPolicyPool.sol";
|
|
13
|
+
import {IRiskModule} from "./interfaces/IRiskModule.sol";
|
|
14
|
+
import {IPolicyPoolComponent} from "./interfaces/IPolicyPoolComponent.sol";
|
|
15
|
+
import {IEToken} from "./interfaces/IEToken.sol";
|
|
16
|
+
import {IPolicyNFT} from "./interfaces/IPolicyNFT.sol";
|
|
17
|
+
import {IPolicyHolder} from "./interfaces/IPolicyHolder.sol";
|
|
19
18
|
import {Policy} from "./Policy.sol";
|
|
20
19
|
import {WadRayMath} from "./WadRayMath.sol";
|
|
21
|
-
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
|
|
22
|
-
import {DataTypes} from "./DataTypes.sol";
|
|
23
20
|
|
|
24
21
|
/**
|
|
25
22
|
* @title Ensuro PolicyPool contract
|
|
@@ -32,29 +29,17 @@ import {DataTypes} from "./DataTypes.sol";
|
|
|
32
29
|
* @custom:security-contact security@ensuro.co
|
|
33
30
|
* @author Ensuro
|
|
34
31
|
*/
|
|
35
|
-
// #invariant_disabled {:msg "Borrow up to activePurePremiums"} _borrowedActivePP <= _activePurePremiums;
|
|
36
|
-
// #invariant_disabled {:msg "Can't borrow if not exhausted before won"} (_borrowedActivePP > 0) ==> _wonPurePremiums == 0;
|
|
37
32
|
contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
38
33
|
using EnumerableSet for EnumerableSet.AddressSet;
|
|
39
34
|
using WadRayMath for uint256;
|
|
40
35
|
using Policy for Policy.PolicyData;
|
|
41
|
-
using DataTypes for DataTypes.ETokenToWadMap;
|
|
42
|
-
using DataTypes for DataTypes.ETokenStatusMap;
|
|
43
36
|
using SafeERC20 for IERC20Metadata;
|
|
44
37
|
|
|
45
|
-
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
|
|
46
|
-
// solhint-disable-next-line var-name-mixedcase
|
|
47
|
-
uint256 public immutable NEGLIGIBLE_AMOUNT; // init as 10**(decimals-3) == 0.001 USD
|
|
48
|
-
|
|
49
|
-
bytes32 public constant WITHDRAW_WON_PREMIUMS_ROLE = keccak256("WITHDRAW_WON_PREMIUMS_ROLE");
|
|
50
|
-
|
|
51
38
|
bytes32 public constant GUARDIAN_ROLE = keccak256("GUARDIAN_ROLE");
|
|
52
39
|
bytes32 public constant LEVEL1_ROLE = keccak256("LEVEL1_ROLE");
|
|
53
40
|
bytes32 public constant LEVEL2_ROLE = keccak256("LEVEL2_ROLE");
|
|
54
41
|
bytes32 public constant LEVEL3_ROLE = keccak256("LEVEL3_ROLE");
|
|
55
42
|
|
|
56
|
-
uint256 public constant MAX_ETOKENS = 10;
|
|
57
|
-
|
|
58
43
|
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
|
|
59
44
|
IPolicyPoolConfig internal immutable _config;
|
|
60
45
|
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
|
|
@@ -62,34 +47,49 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
|
62
47
|
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
|
|
63
48
|
IPolicyNFT internal immutable _policyNFT;
|
|
64
49
|
|
|
65
|
-
|
|
50
|
+
enum ETokenStatus {
|
|
51
|
+
inactive, // doesn't exists - All operations rejected
|
|
52
|
+
active, // deposit / withdraw / lockScr / unlockScr OK
|
|
53
|
+
deprecated, // withdraw OK, unlockScr OK, deposit rejected, no new policies
|
|
54
|
+
suspended // all operations temporarily rejected
|
|
55
|
+
}
|
|
66
56
|
|
|
67
|
-
|
|
68
|
-
|
|
57
|
+
/**
|
|
58
|
+
* @dev Mapping of installed eTokens (see {EToken}) in the PolicyPool. For each one it keep an state
|
|
59
|
+
* {ETokenStatus}.
|
|
60
|
+
*/
|
|
61
|
+
mapping(IEToken => ETokenStatus) private _eTokens;
|
|
69
62
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
/**
|
|
64
|
+
* @dev Mapping that stores the active policies (the policyId is the key). It just saves the hash of the policies,
|
|
65
|
+
* the full {Policy-PolicyData} struct has to be sent for each operation (hash is used to verify).
|
|
66
|
+
*/
|
|
67
|
+
mapping(uint256 => bytes32) internal _policies;
|
|
73
68
|
|
|
69
|
+
/**
|
|
70
|
+
* @dev Event emitted every time a new policy is added to the pool. Contains all the data about the policy that is
|
|
71
|
+
* later required for doing operations with the policy like resolution or expiration.
|
|
72
|
+
*/
|
|
74
73
|
event NewPolicy(IRiskModule indexed riskModule, Policy.PolicyData policy);
|
|
75
|
-
event PolicyRebalanced(IRiskModule indexed riskModule, uint256 indexed policyId);
|
|
76
|
-
event PolicyResolved(IRiskModule indexed riskModule, uint256 indexed policyId, uint256 payout);
|
|
77
74
|
|
|
78
|
-
|
|
75
|
+
/**
|
|
76
|
+
* @dev Event emitted every time a policy is removed from the pool. If the policy expired, the `payout` is 0,
|
|
77
|
+
* otherwise is the amount transferred to the policyholder.
|
|
78
|
+
*/
|
|
79
|
+
event PolicyResolved(IRiskModule indexed riskModule, uint256 indexed policyId, uint256 payout);
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
*
|
|
82
|
-
* And can come out (withdrawed to treasury) with withdrawWonPremiums
|
|
81
|
+
/**
|
|
82
|
+
* @dev Event emitted when a new eToken is added to the pool or the status changes. See {ETokenStatus}.
|
|
83
83
|
*/
|
|
84
|
-
event
|
|
84
|
+
event ETokenStatusChanged(IEToken indexed eToken, ETokenStatus newStatus);
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
/**
|
|
87
|
+
* @dev Event emitted when a new PremiumsAccount is added to the pool or the status changes. TODO
|
|
88
|
+
*/
|
|
89
|
+
event PremiumsAccountStatusChanged(
|
|
90
|
+
IPremiumsAccount indexed premiumsAccount,
|
|
91
|
+
ETokenStatus newStatus
|
|
92
|
+
);
|
|
93
93
|
|
|
94
94
|
modifier onlyRole(bytes32 role) {
|
|
95
95
|
_config.checkRole(role, msg.sender);
|
|
@@ -110,7 +110,6 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
|
110
110
|
_config = config_;
|
|
111
111
|
_policyNFT = policyNFT_;
|
|
112
112
|
_currency = currency_;
|
|
113
|
-
NEGLIGIBLE_AMOUNT = 10**(currency_.decimals() - 3);
|
|
114
113
|
}
|
|
115
114
|
|
|
116
115
|
function initialize() public initializer {
|
|
@@ -122,16 +121,7 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
|
122
121
|
// solhint-disable-next-line func-name-mixedcase
|
|
123
122
|
function __PolicyPool_init_unchained() internal initializer {
|
|
124
123
|
_config.connect();
|
|
125
|
-
require(
|
|
126
|
-
_config.assetManager() == IAssetManager(address(0)),
|
|
127
|
-
"AssetManager can't be set before PolicyPool initialization"
|
|
128
|
-
);
|
|
129
124
|
_policyNFT.connect();
|
|
130
|
-
/*
|
|
131
|
-
_activePurePremiums = 0;
|
|
132
|
-
_borrowedActivePP = 0;
|
|
133
|
-
_wonPurePremiums = 0;
|
|
134
|
-
*/
|
|
135
125
|
}
|
|
136
126
|
|
|
137
127
|
// solhint-disable-next-line no-empty-blocks
|
|
@@ -157,77 +147,69 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
|
157
147
|
return address(_policyNFT);
|
|
158
148
|
}
|
|
159
149
|
|
|
160
|
-
function purePremiums() public view returns (uint256) {
|
|
161
|
-
return _activePurePremiums + _wonPurePremiums - _borrowedActivePP;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function activePurePremiums() external view returns (uint256) {
|
|
165
|
-
return _activePurePremiums;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function wonPurePremiums() external view returns (uint256) {
|
|
169
|
-
return _wonPurePremiums;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function borrowedActivePP() external view returns (uint256) {
|
|
173
|
-
return _borrowedActivePP;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// #if_succeeds_disabled {:msg "eToken added as active"} _eTokens.get(eToken) == DataTypes.ETokenStatus.active;
|
|
177
150
|
function addEToken(IEToken eToken) external onlyRole(LEVEL1_ROLE) {
|
|
178
|
-
|
|
179
|
-
require(
|
|
151
|
+
ETokenStatus status = _eTokens[eToken];
|
|
152
|
+
require(status == ETokenStatus.inactive, "eToken already in the pool");
|
|
180
153
|
require(address(eToken) != address(0), "eToken can't be zero");
|
|
181
154
|
require(
|
|
182
155
|
IPolicyPoolComponent(address(eToken)).policyPool() == this,
|
|
183
156
|
"EToken not linked to this pool"
|
|
184
157
|
);
|
|
185
158
|
|
|
186
|
-
_eTokens
|
|
187
|
-
emit ETokenStatusChanged(eToken,
|
|
159
|
+
_eTokens[eToken] = ETokenStatus.active;
|
|
160
|
+
emit ETokenStatusChanged(eToken, ETokenStatus.active);
|
|
188
161
|
}
|
|
189
162
|
|
|
190
163
|
function removeEToken(IEToken eToken) external onlyRole(LEVEL3_ROLE) {
|
|
191
|
-
|
|
164
|
+
ETokenStatus status = _eTokens[eToken];
|
|
165
|
+
require(status == ETokenStatus.deprecated, "EToken not deprecated");
|
|
192
166
|
require(eToken.totalSupply() == 0, "EToken has liquidity, can't be removed");
|
|
193
|
-
|
|
167
|
+
delete _eTokens[eToken];
|
|
168
|
+
emit ETokenStatusChanged(eToken, ETokenStatus.inactive);
|
|
194
169
|
}
|
|
195
170
|
|
|
196
|
-
function changeETokenStatus(IEToken eToken,
|
|
171
|
+
function changeETokenStatus(IEToken eToken, ETokenStatus newStatus)
|
|
197
172
|
external
|
|
198
173
|
onlyRole2(GUARDIAN_ROLE, LEVEL1_ROLE)
|
|
199
174
|
{
|
|
200
|
-
|
|
175
|
+
ETokenStatus status = _eTokens[eToken];
|
|
176
|
+
require(status != ETokenStatus.inactive, "EToken not found");
|
|
201
177
|
require(
|
|
202
|
-
newStatus !=
|
|
178
|
+
newStatus != ETokenStatus.suspended || _config.hasRole(GUARDIAN_ROLE, msg.sender),
|
|
203
179
|
"Only GUARDIAN can suspend eTokens"
|
|
204
180
|
);
|
|
205
|
-
_eTokens
|
|
181
|
+
_eTokens[eToken] = newStatus;
|
|
206
182
|
emit ETokenStatusChanged(eToken, newStatus);
|
|
207
183
|
}
|
|
208
184
|
|
|
209
|
-
function getETokenStatus(IEToken eToken) external view returns (
|
|
210
|
-
return _eTokens
|
|
185
|
+
function getETokenStatus(IEToken eToken) external view returns (ETokenStatus) {
|
|
186
|
+
return _eTokens[eToken];
|
|
211
187
|
}
|
|
212
188
|
|
|
213
|
-
function
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
189
|
+
function addPremiumsAccount(IPremiumsAccount pa) external onlyRole(LEVEL1_ROLE) {
|
|
190
|
+
// TODO: limit in # of PremiumsAccount?
|
|
191
|
+
// TODO: keep PremiumsAccount status?
|
|
192
|
+
require(address(pa) != address(0), "PremiumsAccount can't be zero");
|
|
193
|
+
require(
|
|
194
|
+
IPolicyPoolComponent(address(pa)).policyPool() == this,
|
|
195
|
+
"PremiumsAccount not linked to this pool"
|
|
196
|
+
);
|
|
197
|
+
IEToken etk = pa.juniorEtk();
|
|
198
|
+
if (address(etk) != address(0)) {
|
|
199
|
+
etk.addBorrower(address(pa));
|
|
218
200
|
}
|
|
219
|
-
|
|
220
|
-
|
|
201
|
+
etk = pa.seniorEtk();
|
|
202
|
+
if (address(etk) != address(0)) {
|
|
203
|
+
etk.addBorrower(address(pa));
|
|
221
204
|
}
|
|
205
|
+
emit PremiumsAccountStatusChanged(pa, ETokenStatus.active);
|
|
206
|
+
// TODO: functions for deactivating premiumsAccount (and remove them as borrower)
|
|
222
207
|
}
|
|
223
208
|
|
|
224
|
-
/// #if_succeeds
|
|
225
|
-
/// {:msg "must take balance from sender"}
|
|
226
|
-
/// _currency.balanceOf(msg.sender) == old(_currency.balanceOf(msg.sender) - amount);
|
|
227
209
|
function deposit(IEToken eToken, uint256 amount) external override whenNotPaused {
|
|
228
|
-
|
|
229
|
-
require(
|
|
230
|
-
_currency.safeTransferFrom(msg.sender, address(
|
|
210
|
+
ETokenStatus etkStatus = _eTokens[eToken];
|
|
211
|
+
require(etkStatus == ETokenStatus.active, "eToken is not active");
|
|
212
|
+
_currency.safeTransferFrom(msg.sender, address(eToken), amount);
|
|
231
213
|
eToken.deposit(msg.sender, amount);
|
|
232
214
|
}
|
|
233
215
|
|
|
@@ -237,19 +219,13 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
|
237
219
|
whenNotPaused
|
|
238
220
|
returns (uint256)
|
|
239
221
|
{
|
|
240
|
-
|
|
222
|
+
ETokenStatus etkStatus = _eTokens[eToken];
|
|
241
223
|
require(
|
|
242
|
-
|
|
243
|
-
(
|
|
244
|
-
(etkStatus == DataTypes.ETokenStatus.active ||
|
|
245
|
-
etkStatus == DataTypes.ETokenStatus.deprecated)
|
|
246
|
-
),
|
|
224
|
+
etkStatus == ETokenStatus.active || etkStatus == ETokenStatus.deprecated,
|
|
247
225
|
"eToken not found or withdraws not allowed"
|
|
248
226
|
);
|
|
249
227
|
address provider = msg.sender;
|
|
250
|
-
|
|
251
|
-
if (withdrawed > 0) _transferTo(provider, withdrawed);
|
|
252
|
-
return withdrawed;
|
|
228
|
+
return eToken.withdraw(provider, amount);
|
|
253
229
|
}
|
|
254
230
|
|
|
255
231
|
function newPolicy(
|
|
@@ -262,148 +238,34 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
|
262
238
|
_config.checkAcceptsNewPolicy(rm);
|
|
263
239
|
policy.id = (uint256(uint160(address(rm))) << 96) + internalId;
|
|
264
240
|
_policies[policy.id] = policy.hash();
|
|
265
|
-
|
|
266
|
-
|
|
241
|
+
IPremiumsAccount pa = rm.premiumsAccount();
|
|
242
|
+
pa.policyCreated(policy);
|
|
267
243
|
_policyNFT.safeMint(customer, policy.id);
|
|
268
|
-
_currency.safeTransferFrom(customer, address(this), policy.purePremium + policy.premiumForLps);
|
|
269
|
-
_currency.safeTransferFrom(customer, _config.treasury(), policy.premiumForEnsuro);
|
|
270
|
-
if (policy.premiumForRm > 0 && customer != rm.wallet())
|
|
271
|
-
_currency.safeTransferFrom(customer, rm.wallet(), policy.premiumForRm);
|
|
272
|
-
emit NewPolicy(rm, policy);
|
|
273
|
-
return policy.id;
|
|
274
|
-
}
|
|
275
244
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
uint256 etkOcean = etk.oceanForNewScr();
|
|
287
|
-
if (etkOcean == 0) continue;
|
|
288
|
-
ocean += etkOcean;
|
|
289
|
-
policyFunds.set(etk, etkOcean);
|
|
290
|
-
}
|
|
291
|
-
_distributeScr(policy.scr, policy.interestRate(), ocean, policyFunds);
|
|
292
|
-
}
|
|
245
|
+
// Distribute the premium
|
|
246
|
+
_currency.safeTransferFrom(customer, address(pa), policy.purePremium);
|
|
247
|
+
if (policy.srCoc > 0)
|
|
248
|
+
_currency.safeTransferFrom(customer, address(pa.seniorEtk()), policy.srCoc);
|
|
249
|
+
if (policy.jrCoc > 0)
|
|
250
|
+
_currency.safeTransferFrom(customer, address(pa.juniorEtk()), policy.jrCoc);
|
|
251
|
+
_currency.safeTransferFrom(customer, _config.treasury(), policy.ensuroCommission);
|
|
252
|
+
if (policy.partnerCommission > 0 && customer != rm.wallet())
|
|
253
|
+
_currency.safeTransferFrom(customer, rm.wallet(), policy.partnerCommission);
|
|
254
|
+
// TODO: this code does up to 5 ERC20 transfers. How we can avoid this? Delayed transfers?
|
|
293
255
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
* @param scr SCR to distribute
|
|
297
|
-
* @param ocean Total ocean available in the ETokens for this SCR
|
|
298
|
-
* @param policyFunds Input: loaded with ocean available for this SCR (sum=ocean)
|
|
299
|
-
Ouput: loaded with locked SRC (sum=scr)
|
|
300
|
-
*/
|
|
301
|
-
function _distributeScr(
|
|
302
|
-
uint256 scr,
|
|
303
|
-
uint256 interestRate,
|
|
304
|
-
uint256 ocean,
|
|
305
|
-
DataTypes.ETokenToWadMap storage policyFunds
|
|
306
|
-
) internal {
|
|
307
|
-
require(ocean >= scr, "Not enought ocean to cover the policy");
|
|
308
|
-
uint256 scrNotLocked = scr;
|
|
309
|
-
|
|
310
|
-
for (uint256 i = 0; i < policyFunds.length(); i++) {
|
|
311
|
-
uint256 etkScr;
|
|
312
|
-
(IEToken etk, uint256 etkOcean) = policyFunds.at(i);
|
|
313
|
-
if (i < policyFunds.length() - 1) etkScr = scr.wadMul(etkOcean).wadDiv(ocean);
|
|
314
|
-
else etkScr = scrNotLocked;
|
|
315
|
-
etk.lockScr(interestRate, etkScr);
|
|
316
|
-
policyFunds.set(etk, etkScr);
|
|
317
|
-
scrNotLocked -= etkScr;
|
|
318
|
-
}
|
|
256
|
+
emit NewPolicy(rm, policy);
|
|
257
|
+
return policy.id;
|
|
319
258
|
}
|
|
320
259
|
|
|
321
260
|
function _balance() internal view returns (uint256) {
|
|
322
261
|
return _currency.balanceOf(address(this));
|
|
323
262
|
}
|
|
324
263
|
|
|
325
|
-
function _transferTo(address destination, uint256 amount) internal {
|
|
326
|
-
if (amount == 0) return;
|
|
327
|
-
if (_config.assetManager() != IAssetManager(address(0)) && _balance() < amount) {
|
|
328
|
-
_config.assetManager().refillWallet(amount);
|
|
329
|
-
}
|
|
330
|
-
// Calculate again the balance and check if enought, if not call unsolvency_hook
|
|
331
|
-
if (_config.insolvencyHook() != IInsolvencyHook(address(0)) && _balance() < amount) {
|
|
332
|
-
_config.insolvencyHook().outOfCash(amount - _balance());
|
|
333
|
-
}
|
|
334
|
-
_currency.safeTransfer(destination, amount);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
function _payFromPool(uint256 toPay) internal returns (uint256) {
|
|
338
|
-
// 1. take from won_pure_premiums
|
|
339
|
-
if (toPay <= _wonPurePremiums) {
|
|
340
|
-
_wonPurePremiums -= toPay;
|
|
341
|
-
return 0;
|
|
342
|
-
}
|
|
343
|
-
if (_wonPurePremiums > 0) {
|
|
344
|
-
toPay -= _wonPurePremiums;
|
|
345
|
-
_wonPurePremiums = 0;
|
|
346
|
-
}
|
|
347
|
-
// 2. borrow from active pure premiums
|
|
348
|
-
if (_activePurePremiums > _borrowedActivePP) {
|
|
349
|
-
if (toPay <= (_activePurePremiums - _borrowedActivePP)) {
|
|
350
|
-
_borrowedActivePP += toPay;
|
|
351
|
-
return 0;
|
|
352
|
-
} else {
|
|
353
|
-
toPay -= _activePurePremiums - _borrowedActivePP;
|
|
354
|
-
_borrowedActivePP = _activePurePremiums;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
return toPay;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function _storePurePremiumWon(uint256 purePremiumWon) internal {
|
|
361
|
-
if (purePremiumWon == 0) return;
|
|
362
|
-
if (_borrowedActivePP >= purePremiumWon) {
|
|
363
|
-
_borrowedActivePP -= purePremiumWon;
|
|
364
|
-
} else {
|
|
365
|
-
if (_borrowedActivePP > 0) {
|
|
366
|
-
purePremiumWon -= _borrowedActivePP;
|
|
367
|
-
_borrowedActivePP = 0;
|
|
368
|
-
}
|
|
369
|
-
_wonPurePremiums += purePremiumWon;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
function _processResolution(
|
|
374
|
-
Policy.PolicyData memory policy,
|
|
375
|
-
bool customerWon,
|
|
376
|
-
uint256 payout
|
|
377
|
-
) internal returns (uint256, uint256) {
|
|
378
|
-
uint256 borrowFromScr; // = 0
|
|
379
|
-
uint256 purePremiumWon; // = 0
|
|
380
|
-
uint256 aux;
|
|
381
|
-
|
|
382
|
-
if (customerWon) {
|
|
383
|
-
_transferTo(_policyNFT.ownerOf(policy.id), payout);
|
|
384
|
-
if (policy.purePremium > payout) {
|
|
385
|
-
purePremiumWon = policy.purePremium - payout;
|
|
386
|
-
} else {
|
|
387
|
-
borrowFromScr = _payFromPool(payout - policy.purePremium);
|
|
388
|
-
}
|
|
389
|
-
} else {
|
|
390
|
-
// Pay RM and Ensuro
|
|
391
|
-
purePremiumWon = policy.purePremium;
|
|
392
|
-
// cover first _borrowedActivePP
|
|
393
|
-
if (_borrowedActivePP > _activePurePremiums) {
|
|
394
|
-
aux = Math.min(_borrowedActivePP - _activePurePremiums, purePremiumWon);
|
|
395
|
-
_borrowedActivePP -= aux;
|
|
396
|
-
purePremiumWon -= aux;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
return (borrowFromScr, purePremiumWon);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
264
|
function _validatePolicy(Policy.PolicyData memory policy) internal view {
|
|
403
265
|
require(policy.id != 0 && policy.hash() == _policies[policy.id], "Policy not found");
|
|
404
266
|
}
|
|
405
267
|
|
|
406
|
-
function expirePolicy(Policy.PolicyData calldata policy) external whenNotPaused {
|
|
268
|
+
function expirePolicy(Policy.PolicyData calldata policy) external override whenNotPaused {
|
|
407
269
|
require(policy.expiration <= block.timestamp, "Policy not expired yet");
|
|
408
270
|
return _resolvePolicy(policy, 0, true);
|
|
409
271
|
}
|
|
@@ -424,6 +286,14 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
|
424
286
|
return _resolvePolicy(policy, customerWon ? policy.payout : 0, false);
|
|
425
287
|
}
|
|
426
288
|
|
|
289
|
+
/**
|
|
290
|
+
* @dev Internal function that handles the different alternative resolutions for a policy, with or without payout and
|
|
291
|
+
* expiration.
|
|
292
|
+
*
|
|
293
|
+
* @param policy A policy created with {Policy-initialize}
|
|
294
|
+
* @param payout The amount to paid to the policyholder
|
|
295
|
+
* @param expired True for expiration resolution (`payout` must be 0)
|
|
296
|
+
*/
|
|
427
297
|
function _resolvePolicy(
|
|
428
298
|
Policy.PolicyData memory policy,
|
|
429
299
|
uint256 payout,
|
|
@@ -438,33 +308,17 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
|
438
308
|
|
|
439
309
|
bool customerWon = payout > 0;
|
|
440
310
|
|
|
441
|
-
_activePurePremiums -= policy.purePremium;
|
|
442
|
-
|
|
443
|
-
(uint256 borrowFromScr, uint256 purePremiumWon) = _processResolution(
|
|
444
|
-
policy,
|
|
445
|
-
customerWon,
|
|
446
|
-
payout
|
|
447
|
-
);
|
|
448
|
-
|
|
449
311
|
if (customerWon) {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
if (borrowFromScrLeft > NEGLIGIBLE_AMOUNT)
|
|
453
|
-
borrowFromScrLeft = _takeLoanFromAnyEtk(borrowFromScrLeft);
|
|
454
|
-
require(
|
|
455
|
-
borrowFromScrLeft <= NEGLIGIBLE_AMOUNT,
|
|
456
|
-
"Don't know where to take the rest of the money"
|
|
457
|
-
);
|
|
312
|
+
address policyOwner = _policyNFT.ownerOf(policy.id);
|
|
313
|
+
rm.premiumsAccount().policyResolvedWithPayout(policyOwner, policy, payout);
|
|
458
314
|
} else {
|
|
459
|
-
|
|
315
|
+
rm.premiumsAccount().policyExpired(policy);
|
|
460
316
|
}
|
|
461
317
|
|
|
462
|
-
|
|
463
|
-
rm.releaseScr(policy.scr);
|
|
318
|
+
rm.releaseExposure(policy.payout);
|
|
464
319
|
|
|
465
320
|
emit PolicyResolved(policy.riskModule, policy.id, payout);
|
|
466
321
|
delete _policies[policy.id];
|
|
467
|
-
delete _policiesFunds[policy.id];
|
|
468
322
|
if (payout > 0) {
|
|
469
323
|
_notifyPayout(policy.id, payout);
|
|
470
324
|
} else {
|
|
@@ -472,6 +326,10 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
|
472
326
|
}
|
|
473
327
|
}
|
|
474
328
|
|
|
329
|
+
/**
|
|
330
|
+
* @dev Notifies the payout with a callback if the policyholder is a contract. Only reverts if the policyholder
|
|
331
|
+
* contract explicitly reverts. Doesn't reverts is the callback is not implemented.
|
|
332
|
+
*/
|
|
475
333
|
function _notifyPayout(uint256 policyId, uint256 payout) internal {
|
|
476
334
|
address customer = _policyNFT.ownerOf(policyId);
|
|
477
335
|
if (!AddressUpgradeable.isContract(customer)) return;
|
|
@@ -494,6 +352,9 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
|
494
352
|
}
|
|
495
353
|
}
|
|
496
354
|
|
|
355
|
+
/**
|
|
356
|
+
* @dev Notifies the expiration with a callback if the policyholder is a contract. Never reverts.
|
|
357
|
+
*/
|
|
497
358
|
function _notifyExpiration(uint256 policyId) internal {
|
|
498
359
|
address customer = _policyNFT.ownerOf(policyId);
|
|
499
360
|
if (!AddressUpgradeable.isContract(customer)) return;
|
|
@@ -505,218 +366,4 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable {
|
|
|
505
366
|
return;
|
|
506
367
|
}
|
|
507
368
|
}
|
|
508
|
-
|
|
509
|
-
function _interestAdjustment(Policy.PolicyData memory policy)
|
|
510
|
-
internal
|
|
511
|
-
view
|
|
512
|
-
returns (bool, uint256)
|
|
513
|
-
{
|
|
514
|
-
// Calculate interest accrual adjustment
|
|
515
|
-
uint256 aux = policy.accruedInterest();
|
|
516
|
-
if (policy.premiumForLps >= aux) return (true, policy.premiumForLps - aux);
|
|
517
|
-
else return (false, aux - policy.premiumForLps);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
function _updatePolicyFundsCustWon(Policy.PolicyData memory policy, uint256 borrowFromScr)
|
|
521
|
-
internal
|
|
522
|
-
returns (uint256)
|
|
523
|
-
{
|
|
524
|
-
uint256 borrowFromScrLeft = 0;
|
|
525
|
-
uint256 interestRate = policy.interestRate();
|
|
526
|
-
(bool positive, uint256 adjustment) = _interestAdjustment(policy);
|
|
527
|
-
|
|
528
|
-
// Iterate policyFunds - unlockScr / adjust / take loan
|
|
529
|
-
DataTypes.ETokenToWadMap storage policyFunds = _policiesFunds[policy.id];
|
|
530
|
-
for (uint256 i = 0; i < policyFunds.length(); i++) {
|
|
531
|
-
(IEToken etk, uint256 etkScr) = policyFunds.at(i);
|
|
532
|
-
etk.unlockScr(interestRate, etkScr);
|
|
533
|
-
etkScr = etkScr.wadDiv(policy.scr);
|
|
534
|
-
// etkScr now represents the share of SCR that's covered by this etk (variable reuse)
|
|
535
|
-
etk.discreteEarning(adjustment.wadMul(etkScr), positive);
|
|
536
|
-
if (borrowFromScr > 0) {
|
|
537
|
-
uint256 aux;
|
|
538
|
-
aux = borrowFromScr.wadMul(etkScr);
|
|
539
|
-
borrowFromScrLeft += aux - etk.lendToPool(aux, true);
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
return borrowFromScrLeft;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
// Almost duplicated code from _updatePolicyFundsCustWon but separated to avoid stack depth error
|
|
546
|
-
function _updatePolicyFundsCustLost(Policy.PolicyData memory policy, uint256 purePremiumWon)
|
|
547
|
-
internal
|
|
548
|
-
returns (uint256)
|
|
549
|
-
{
|
|
550
|
-
uint256 interestRate = policy.interestRate();
|
|
551
|
-
(bool positive, uint256 adjustment) = _interestAdjustment(policy);
|
|
552
|
-
|
|
553
|
-
// Iterate policyFunds - unlockScr / adjust / repay loan
|
|
554
|
-
DataTypes.ETokenToWadMap storage policyFunds = _policiesFunds[policy.id];
|
|
555
|
-
for (uint256 i = 0; i < policyFunds.length(); i++) {
|
|
556
|
-
(IEToken etk, uint256 etkScr) = policyFunds.at(i);
|
|
557
|
-
etk.unlockScr(interestRate, etkScr);
|
|
558
|
-
etkScr = etkScr.wadDiv(policy.scr);
|
|
559
|
-
// etkScr now represents the share of SCR that's covered by this etk (variable reuse)
|
|
560
|
-
etk.discreteEarning(adjustment.wadMul(etkScr), positive);
|
|
561
|
-
if (purePremiumWon > 0 && etk.getPoolLoan() > 0) {
|
|
562
|
-
uint256 aux;
|
|
563
|
-
// if debt with token, repay from purePremium
|
|
564
|
-
aux = policy.purePremium.wadMul(etkScr);
|
|
565
|
-
aux = Math.min(purePremiumWon, Math.min(etk.getPoolLoan(), aux));
|
|
566
|
-
etk.repayPoolLoan(aux);
|
|
567
|
-
purePremiumWon -= aux;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
return purePremiumWon;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
/*
|
|
574
|
-
* Called when the payout to be taken from policyFunds wasn't enought.
|
|
575
|
-
* Then I take loan from the others tokens
|
|
576
|
-
*/
|
|
577
|
-
function _takeLoanFromAnyEtk(uint256 loanLeft) internal returns (uint256) {
|
|
578
|
-
for (uint256 i = 0; i < _eTokens.length(); i++) {
|
|
579
|
-
(IEToken etk, DataTypes.ETokenStatus etkStatus) = _eTokens.at(i);
|
|
580
|
-
if (etkStatus != DataTypes.ETokenStatus.active) continue;
|
|
581
|
-
loanLeft -= etk.lendToPool(loanLeft, false);
|
|
582
|
-
if (loanLeft <= NEGLIGIBLE_AMOUNT) break;
|
|
583
|
-
}
|
|
584
|
-
return loanLeft;
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
/**
|
|
588
|
-
*
|
|
589
|
-
* Repays a loan taken with the eToken with the money in the premium pool.
|
|
590
|
-
* The repayment should happen without calling this method when customer losses and eToken is one of the
|
|
591
|
-
* policyFunds. But sometimes we need to take loans from tokens not linked to the policy.
|
|
592
|
-
*
|
|
593
|
-
* returns The amount repaid
|
|
594
|
-
*
|
|
595
|
-
* Requirements:
|
|
596
|
-
*
|
|
597
|
-
* - `eToken` must be `active` or `deprecated`
|
|
598
|
-
*/
|
|
599
|
-
function repayETokenLoan(IEToken eToken) external whenNotPaused returns (uint256) {
|
|
600
|
-
(bool found, DataTypes.ETokenStatus etkStatus) = _eTokens.tryGet(eToken);
|
|
601
|
-
require(
|
|
602
|
-
found &&
|
|
603
|
-
(etkStatus == DataTypes.ETokenStatus.active ||
|
|
604
|
-
etkStatus == DataTypes.ETokenStatus.deprecated),
|
|
605
|
-
"eToken is not active"
|
|
606
|
-
);
|
|
607
|
-
uint256 poolLoan = eToken.getPoolLoan();
|
|
608
|
-
uint256 toPayLater = _payFromPool(poolLoan);
|
|
609
|
-
eToken.repayPoolLoan(poolLoan - toPayLater);
|
|
610
|
-
return poolLoan - toPayLater;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
/**
|
|
614
|
-
*
|
|
615
|
-
* Endpoint to receive "free money" and inject that money into the premium pool.
|
|
616
|
-
*
|
|
617
|
-
* Can be used for example if the PolicyPool subscribes an excess loss policy with other company.
|
|
618
|
-
*
|
|
619
|
-
*/
|
|
620
|
-
function receiveGrant(uint256 amount) external override {
|
|
621
|
-
_currency.safeTransferFrom(msg.sender, address(this), amount);
|
|
622
|
-
_storePurePremiumWon(amount);
|
|
623
|
-
emit WonPremiumsInOut(true, amount);
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
/**
|
|
627
|
-
*
|
|
628
|
-
* Withdraws excess premiums to PolicyPool's treasury.
|
|
629
|
-
* This might be needed in some cases for example if we are deprecating the protocol or the excess premiums
|
|
630
|
-
* are needed to compensate something. Shouldn't be used. Can be disabled revoking role WITHDRAW_WON_PREMIUMS_ROLE
|
|
631
|
-
*
|
|
632
|
-
* returns The amount withdrawed
|
|
633
|
-
*
|
|
634
|
-
* Requirements:
|
|
635
|
-
*
|
|
636
|
-
* - onlyRole(WITHDRAW_WON_PREMIUMS_ROLE)
|
|
637
|
-
* - _wonPurePremiums > 0
|
|
638
|
-
*/
|
|
639
|
-
function withdrawWonPremiums(uint256 amount)
|
|
640
|
-
external
|
|
641
|
-
onlyRole(WITHDRAW_WON_PREMIUMS_ROLE)
|
|
642
|
-
returns (uint256)
|
|
643
|
-
{
|
|
644
|
-
if (amount > _wonPurePremiums) amount = _wonPurePremiums;
|
|
645
|
-
require(amount > 0, "No premiums to withdraw");
|
|
646
|
-
_wonPurePremiums -= amount;
|
|
647
|
-
_transferTo(_config.treasury(), amount);
|
|
648
|
-
emit WonPremiumsInOut(false, amount);
|
|
649
|
-
return amount;
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
function getInvestable() external view override returns (uint256) {
|
|
653
|
-
uint256 borrowedFromEtk = 0;
|
|
654
|
-
for (uint256 i = 0; i < _eTokens.length(); i++) {
|
|
655
|
-
(
|
|
656
|
-
IEToken etk, /* DataTypes.ETokenStatus etkStatus */
|
|
657
|
-
|
|
658
|
-
) = _eTokens.at(i);
|
|
659
|
-
// TODO: define if not active are investable or not
|
|
660
|
-
borrowedFromEtk += etk.getPoolLoan();
|
|
661
|
-
}
|
|
662
|
-
uint256 premiums = purePremiums();
|
|
663
|
-
if (premiums > borrowedFromEtk) return premiums - borrowedFromEtk;
|
|
664
|
-
else return 0;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
function totalETokenSupply() public view override returns (uint256) {
|
|
668
|
-
uint256 ret = 0;
|
|
669
|
-
for (uint256 i = 0; i < _eTokens.length(); i++) {
|
|
670
|
-
(
|
|
671
|
-
IEToken etk, /* DataTypes.ETokenStatus etkStatus */
|
|
672
|
-
|
|
673
|
-
) = _eTokens.at(i);
|
|
674
|
-
// TODO: define if not active are investable or not
|
|
675
|
-
ret += etk.totalSupply();
|
|
676
|
-
}
|
|
677
|
-
return ret;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
function assetEarnings(uint256 amount, bool positive)
|
|
681
|
-
external
|
|
682
|
-
override
|
|
683
|
-
onlyAssetManager
|
|
684
|
-
whenNotPaused
|
|
685
|
-
{
|
|
686
|
-
if (positive) {
|
|
687
|
-
// earnings
|
|
688
|
-
_storePurePremiumWon(amount);
|
|
689
|
-
} else {
|
|
690
|
-
// losses
|
|
691
|
-
_payFromPool(amount); // return value should be 0 if not, losses are more than capital available
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
function getPolicyFundCount(uint256 policyId) external view returns (uint256) {
|
|
696
|
-
return _policiesFunds[policyId].length();
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
function getPolicyFundAt(uint256 policyId, uint256 index)
|
|
700
|
-
external
|
|
701
|
-
view
|
|
702
|
-
returns (IEToken, uint256)
|
|
703
|
-
{
|
|
704
|
-
return _policiesFunds[policyId].at(index);
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
function getPolicyFund(uint256 policyId, IEToken etoken) external view returns (uint256) {
|
|
708
|
-
(bool success, uint256 amount) = _policiesFunds[policyId].tryGet(etoken);
|
|
709
|
-
if (success) return amount;
|
|
710
|
-
else return 0;
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
function getETokenCount() external view override returns (uint256) {
|
|
714
|
-
return _eTokens.length();
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
function getETokenAt(uint256 index) external view override returns (IEToken) {
|
|
718
|
-
(IEToken etk, DataTypes.ETokenStatus etkStatus) = _eTokens.at(index);
|
|
719
|
-
if (etkStatus != DataTypes.ETokenStatus.inactive) return etk;
|
|
720
|
-
else return IEToken(address(0));
|
|
721
|
-
}
|
|
722
369
|
}
|