@ensuro/core 2.8.0 → 2.8.2
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 +618 -0
- package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +238 -0
- package/build/contracts/EToken.sol/EToken.json +1287 -0
- package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +657 -0
- package/build/contracts/LiquidityThresholdAssetManager.sol/LiquidityThresholdAssetManager.json +222 -0
- package/build/contracts/Policy.sol/Policy.json +10 -0
- package/build/contracts/PolicyPool.sol/PolicyPool.json +1775 -0
- package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +342 -0
- package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +1142 -0
- package/build/contracts/Reserve.sol/Reserve.json +413 -0
- package/build/contracts/RiskModule.sol/RiskModule.json +589 -0
- package/build/contracts/SignedBucketRiskModule.sol/SignedBucketRiskModule.json +1251 -0
- package/build/contracts/SignedQuoteRiskModule.sol/SignedQuoteRiskModule.json +1145 -0
- package/build/contracts/TimeScaled.sol/TimeScaled.json +10 -0
- package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +1143 -0
- package/build/contracts/dependencies/WadRayMath.sol/WadRayMath.json +10 -0
- package/build/contracts/interfaces/IAccessManager.sol/IAccessManager.json +343 -0
- package/build/contracts/interfaces/IAssetManager.sol/IAssetManager.json +128 -0
- package/build/contracts/interfaces/IEToken.sol/IEToken.json +460 -0
- package/build/contracts/interfaces/ILPWhitelist.sol/ILPWhitelist.json +103 -0
- package/build/contracts/interfaces/IPolicyHolder.sol/IPolicyHolder.json +108 -0
- package/build/contracts/interfaces/IPolicyHolderV2.sol/IPolicyHolderV2.json +142 -0
- package/build/contracts/interfaces/IPolicyPool.sol/IPolicyPool.json +820 -0
- package/build/contracts/interfaces/IPolicyPoolComponent.sol/IPolicyPoolComponent.json +43 -0
- package/build/contracts/interfaces/IPremiumsAccount.sol/IPremiumsAccount.json +477 -0
- package/build/contracts/interfaces/IRiskModule.sol/IRiskModule.json +165 -0
- package/build/contracts/migration/LPManualWhitelistV20.sol/LPManualWhitelistV20.json +491 -0
- package/build/contracts/migration/LPManualWhitelistV20Upgraded.sol/LPManualWhitelistV20Upgraded.json +502 -0
- package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +736 -0
- package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +43 -0
- package/build/contracts/mocks/IMintableERC20.sol/IMintableERC20.json +47 -0
- package/build/contracts/mocks/InterfaceIdCalculator.sol/InterfaceIdCalculator.json +193 -0
- package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +457 -0
- package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +54 -0
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +929 -0
- package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +92 -0
- package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +1316 -0
- package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +343 -0
- package/build/contracts/mocks/TestNFT.sol/TestNFT.json +388 -0
- package/contracts/Policy.sol +58 -21
- package/contracts/PolicyPool.sol +155 -37
- package/contracts/PolicyPoolComponent.sol +5 -2
- package/contracts/RiskModule.sol +27 -30
- package/contracts/SignedBucketRiskModule.sol +32 -95
- package/contracts/SignedQuoteRiskModule.sol +3 -1
- package/contracts/interfaces/IPolicyHolder.sol +2 -2
- package/contracts/interfaces/IPolicyHolderV2.sol +29 -0
- package/contracts/mocks/PolicyHolderMock.sol +71 -10
- package/js/deploy.js +6 -25
- package/js/utils.js +9 -4
- package/package.json +3 -5
- package/contracts/TieredSignedQuoteRiskModule.sol +0 -159
package/contracts/PolicyPool.sol
CHANGED
|
@@ -11,6 +11,7 @@ import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/U
|
|
|
11
11
|
|
|
12
12
|
import {IAccessManager} from "./interfaces/IAccessManager.sol";
|
|
13
13
|
import {IEToken} from "./interfaces/IEToken.sol";
|
|
14
|
+
import {IPolicyHolderV2} from "./interfaces/IPolicyHolderV2.sol";
|
|
14
15
|
import {IPolicyHolder} from "./interfaces/IPolicyHolder.sol";
|
|
15
16
|
import {IPolicyPool} from "./interfaces/IPolicyPool.sol";
|
|
16
17
|
import {IPolicyPoolComponent} from "./interfaces/IPolicyPoolComponent.sol";
|
|
@@ -43,6 +44,8 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
43
44
|
bytes32 public constant LEVEL2_ROLE = keccak256("LEVEL2_ROLE");
|
|
44
45
|
bytes32 public constant LEVEL3_ROLE = keccak256("LEVEL3_ROLE");
|
|
45
46
|
|
|
47
|
+
uint256 internal constant HOLDER_GAS_LIMIT = 150000;
|
|
48
|
+
|
|
46
49
|
/**
|
|
47
50
|
* @dev {AccessManager} that handles the access permissions for the PolicyPool and its components.
|
|
48
51
|
*/
|
|
@@ -125,6 +128,98 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
125
128
|
*/
|
|
126
129
|
string internal _nftBaseURI;
|
|
127
130
|
|
|
131
|
+
/**
|
|
132
|
+
* @dev Constructor error when address(0) is sent as `access()`
|
|
133
|
+
*/
|
|
134
|
+
error NoZeroAccess();
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @dev Constructor error when address(0) is sent as `currency()`
|
|
138
|
+
*/
|
|
139
|
+
error NoZeroCurrency();
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @dev Constructor error (or setTreasury) when address(0) is sent as `treasury()`
|
|
143
|
+
*/
|
|
144
|
+
error NoZeroTreasury();
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @dev Initialization error when empty name for the ERC721 is sent
|
|
148
|
+
*/
|
|
149
|
+
error NoEmptyName();
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @dev Initialization error when empty symbol for the ERC721 is sent
|
|
153
|
+
*/
|
|
154
|
+
error NoEmptySymbol();
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @dev Upgrade error when the new implementation contract tries to change the `access()`
|
|
158
|
+
*/
|
|
159
|
+
error UpgradeCannotChangeAccess();
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @dev Upgrade error when the new implementation contract tries to change the `currency()`
|
|
163
|
+
*/
|
|
164
|
+
error UpgradeCannotChangeCurrency();
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @dev Error when trying to add a component that was already added to the PolicyPool
|
|
168
|
+
*/
|
|
169
|
+
error ComponentAlreadyInThePool();
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @dev Error when trying to add a component that isn't linked to this pool (`.policyPool() != this`)
|
|
173
|
+
*/
|
|
174
|
+
error ComponentNotLinkedToThisPool();
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* @dev Error when a component is not of the right kind, it might happen if a component declared as
|
|
178
|
+
* ComponentKind.eToken doesn't support the IEToken interface (or similar) or when in a given operation
|
|
179
|
+
* we expect a component to be a risk module and the stored kind is different.
|
|
180
|
+
*/
|
|
181
|
+
error ComponentNotTheRightKind(IPolicyPoolComponent component, ComponentKind expectedKind);
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @dev Error when a component is expected to be deprecated for the operation (see `removeComponent`) and it isn't.
|
|
185
|
+
*/
|
|
186
|
+
error ComponentNotDeprecated();
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @dev Error when trying to remove a component that is still in use. The "in use" definition can change from one
|
|
190
|
+
* component to the other. For eToken in use means `totalSupply() != 0`. For PremiumsAccount means
|
|
191
|
+
* `purePremiums() != 0`. For RiskModule means `activeExposure() != 0`.
|
|
192
|
+
*/
|
|
193
|
+
error ComponentInUseCannotRemove(ComponentKind kind, uint256 amount);
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @dev Error when a component is not found in the pool (status = 0 = inactive)
|
|
197
|
+
*/
|
|
198
|
+
error ComponentNotFound();
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* @dev Error when a component is not found in the pool or is not active (status != active)
|
|
202
|
+
*/
|
|
203
|
+
error ComponentNotFoundOrNotActive();
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @dev Error when a component is not active or deprecated. Happens on some operations like eToken withdrawals or
|
|
207
|
+
* policy resolutions that accept the component might be active or deprecated and isn't on any of those states.
|
|
208
|
+
*/
|
|
209
|
+
error ComponentMustBeActiveOrDeprecated();
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* @dev Error when a method intented to be called by riskModule (and by policy's risk module) is called by someone
|
|
213
|
+
* else.
|
|
214
|
+
*/
|
|
215
|
+
error OnlyRiskModuleAllowed();
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* @dev Error raised when IPolicyHolder doesn't return the expected selector answer when notified of policy payout,
|
|
219
|
+
* reception or replacement.
|
|
220
|
+
*/
|
|
221
|
+
error InvalidNotificationResponse(bytes4 response);
|
|
222
|
+
|
|
128
223
|
/**
|
|
129
224
|
* @dev Event emitted when the treasury changes
|
|
130
225
|
*
|
|
@@ -142,6 +237,13 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
142
237
|
*/
|
|
143
238
|
event ComponentStatusChanged(IPolicyPoolComponent indexed component, ComponentKind kind, ComponentStatus newStatus);
|
|
144
239
|
|
|
240
|
+
/**
|
|
241
|
+
* @dev Event emitted when a IPolicyHolder reverts on the expiration notification. The operation doesn't reverts
|
|
242
|
+
*
|
|
243
|
+
* @param policyId The id of the policy being expired
|
|
244
|
+
* @param holder The address of the contract that owns the policy
|
|
245
|
+
*/
|
|
246
|
+
event ExpirationNotificationFailed(uint256 indexed policyId, IPolicyHolder holder);
|
|
145
247
|
/**
|
|
146
248
|
* @dev Modifier that checks the caller has a given role
|
|
147
249
|
*/
|
|
@@ -167,8 +269,8 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
167
269
|
*/
|
|
168
270
|
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
169
271
|
constructor(IAccessManager access_, IERC20Metadata currency_) {
|
|
170
|
-
|
|
171
|
-
|
|
272
|
+
if (address(access_) == address(0)) revert NoZeroAccess();
|
|
273
|
+
if (address(currency_) == address(0)) revert NoZeroCurrency();
|
|
172
274
|
_disableInitializers();
|
|
173
275
|
_access = access_;
|
|
174
276
|
_currency = currency_;
|
|
@@ -182,8 +284,8 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
182
284
|
* @param treasury_ The address of the treasury that will receive the protocol fees.
|
|
183
285
|
*/
|
|
184
286
|
function initialize(string memory name_, string memory symbol_, address treasury_) public initializer {
|
|
185
|
-
|
|
186
|
-
|
|
287
|
+
if (bytes(name_).length == 0) revert NoEmptyName();
|
|
288
|
+
if (bytes(symbol_).length == 0) revert NoEmptySymbol();
|
|
187
289
|
__UUPSUpgradeable_init();
|
|
188
290
|
__ERC721_init(name_, symbol_);
|
|
189
291
|
__Pausable_init();
|
|
@@ -204,8 +306,8 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
204
306
|
|
|
205
307
|
function _authorizeUpgrade(address newImpl) internal view override onlyRole2(GUARDIAN_ROLE, LEVEL1_ROLE) {
|
|
206
308
|
IPolicyPool newPool = IPolicyPool(newImpl);
|
|
207
|
-
|
|
208
|
-
|
|
309
|
+
if (newPool.access() != _access) revert UpgradeCannotChangeAccess();
|
|
310
|
+
if (newPool.currency() != _currency) revert UpgradeCannotChangeCurrency();
|
|
209
311
|
}
|
|
210
312
|
|
|
211
313
|
/**
|
|
@@ -238,7 +340,7 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
238
340
|
}
|
|
239
341
|
|
|
240
342
|
function _setTreasury(address treasury_) internal {
|
|
241
|
-
|
|
343
|
+
if (treasury_ == address(0)) revert NoZeroTreasury();
|
|
242
344
|
_treasury = treasury_;
|
|
243
345
|
emit ComponentChanged(IAccessManager.GovernanceActions.setTreasury, _treasury);
|
|
244
346
|
}
|
|
@@ -280,15 +382,14 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
280
382
|
*/
|
|
281
383
|
function addComponent(IPolicyPoolComponent component, ComponentKind kind) external onlyRole(LEVEL1_ROLE) {
|
|
282
384
|
Component storage comp = _components[component];
|
|
283
|
-
|
|
284
|
-
|
|
385
|
+
if (comp.status != ComponentStatus.inactive) revert ComponentAlreadyInThePool();
|
|
386
|
+
if (component.policyPool() != this) revert ComponentNotLinkedToThisPool();
|
|
285
387
|
|
|
286
|
-
|
|
287
|
-
(kind == ComponentKind.eToken && component.supportsInterface(type(IEToken).interfaceId)) ||
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
);
|
|
388
|
+
if (
|
|
389
|
+
(kind == ComponentKind.eToken && !component.supportsInterface(type(IEToken).interfaceId)) ||
|
|
390
|
+
(kind == ComponentKind.premiumsAccount && !component.supportsInterface(type(IPremiumsAccount).interfaceId)) ||
|
|
391
|
+
(kind == ComponentKind.riskModule && !component.supportsInterface(type(IRiskModule).interfaceId))
|
|
392
|
+
) revert ComponentNotTheRightKind(component, kind);
|
|
292
393
|
|
|
293
394
|
comp.status = ComponentStatus.active;
|
|
294
395
|
comp.kind = kind;
|
|
@@ -321,14 +422,16 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
321
422
|
*/
|
|
322
423
|
function removeComponent(IPolicyPoolComponent component) external onlyRole(LEVEL1_ROLE) {
|
|
323
424
|
Component storage comp = _components[component];
|
|
324
|
-
|
|
425
|
+
if (comp.status != ComponentStatus.deprecated) revert ComponentNotDeprecated();
|
|
325
426
|
if (comp.kind == ComponentKind.eToken) {
|
|
326
|
-
|
|
427
|
+
if (IEToken(address(component)).totalSupply() != 0)
|
|
428
|
+
revert ComponentInUseCannotRemove(comp.kind, IEToken(address(component)).totalSupply());
|
|
327
429
|
} else if (comp.kind == ComponentKind.riskModule) {
|
|
328
|
-
|
|
430
|
+
if (IRiskModule(address(component)).activeExposure() != 0)
|
|
431
|
+
revert ComponentInUseCannotRemove(comp.kind, IRiskModule(address(component)).activeExposure());
|
|
329
432
|
} else if (comp.kind == ComponentKind.premiumsAccount) {
|
|
330
433
|
IPremiumsAccount pa = IPremiumsAccount(address(component));
|
|
331
|
-
|
|
434
|
+
if (pa.purePremiums() != 0) revert ComponentInUseCannotRemove(comp.kind, pa.purePremiums());
|
|
332
435
|
IEToken etk = pa.juniorEtk();
|
|
333
436
|
if (address(etk) != address(0)) {
|
|
334
437
|
etk.removeBorrower(address(pa));
|
|
@@ -360,13 +463,13 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
360
463
|
ComponentStatus newStatus
|
|
361
464
|
) external onlyRole2(GUARDIAN_ROLE, LEVEL1_ROLE) {
|
|
362
465
|
Component storage comp = _components[component];
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
466
|
+
if (comp.status == ComponentStatus.inactive) revert ComponentNotFound();
|
|
467
|
+
if (newStatus == ComponentStatus.active || newStatus == ComponentStatus.deprecated) {
|
|
468
|
+
_access.checkRole(LEVEL1_ROLE, _msgSender());
|
|
469
|
+
} else {
|
|
470
|
+
// ComponentStatus.suspended requires GUARDIAN_ROLE
|
|
471
|
+
_access.checkRole(GUARDIAN_ROLE, _msgSender());
|
|
472
|
+
}
|
|
370
473
|
comp.status = newStatus;
|
|
371
474
|
emit ComponentStatusChanged(component, comp.kind, newStatus);
|
|
372
475
|
}
|
|
@@ -383,20 +486,18 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
383
486
|
|
|
384
487
|
function _componentStatus(address component, ComponentKind kind) internal view returns (ComponentStatus) {
|
|
385
488
|
Component storage comp = _components[IPolicyPoolComponent(component)];
|
|
386
|
-
|
|
489
|
+
if (comp.kind != kind) revert ComponentNotTheRightKind(IPolicyPoolComponent(component), kind);
|
|
387
490
|
return comp.status;
|
|
388
491
|
}
|
|
389
492
|
|
|
390
493
|
function _requireCompActive(address component, ComponentKind kind) internal view {
|
|
391
|
-
|
|
494
|
+
if (_componentStatus(component, kind) != ComponentStatus.active) revert ComponentNotFoundOrNotActive();
|
|
392
495
|
}
|
|
393
496
|
|
|
394
497
|
function _requireCompActiveOrDeprecated(address component, ComponentKind kind) internal view {
|
|
395
498
|
ComponentStatus status = _componentStatus(component, kind);
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
"Component must be active or deprecated"
|
|
399
|
-
);
|
|
499
|
+
if (status != ComponentStatus.active && status != ComponentStatus.deprecated)
|
|
500
|
+
revert ComponentMustBeActiveOrDeprecated();
|
|
400
501
|
}
|
|
401
502
|
|
|
402
503
|
function deposit(IEToken eToken, uint256 amount) external override whenNotPaused {
|
|
@@ -419,7 +520,7 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
419
520
|
) external override whenNotPaused returns (uint256) {
|
|
420
521
|
// Checks
|
|
421
522
|
IRiskModule rm = policy.riskModule;
|
|
422
|
-
|
|
523
|
+
if (address(rm) != _msgSender()) revert OnlyRiskModuleAllowed();
|
|
423
524
|
_requireCompActive(address(rm), ComponentKind.riskModule);
|
|
424
525
|
IPremiumsAccount pa = rm.premiumsAccount();
|
|
425
526
|
_requireCompActive(address(pa), ComponentKind.premiumsAccount);
|
|
@@ -459,7 +560,7 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
459
560
|
// Checks
|
|
460
561
|
_validatePolicy(oldPolicy);
|
|
461
562
|
IRiskModule rm = oldPolicy.riskModule;
|
|
462
|
-
|
|
563
|
+
if (address(rm) != _msgSender()) revert OnlyRiskModuleAllowed();
|
|
463
564
|
_requireCompActive(address(rm), ComponentKind.riskModule);
|
|
464
565
|
IPremiumsAccount pa = rm.premiumsAccount();
|
|
465
566
|
_requireCompActive(address(pa), ComponentKind.premiumsAccount);
|
|
@@ -509,6 +610,7 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
509
610
|
|
|
510
611
|
emit NewPolicy(rm, newPolicy_);
|
|
511
612
|
emit PolicyReplaced(rm, oldPolicy.id, newPolicy_.id);
|
|
613
|
+
_notifyReplacement(oldPolicy.id, newPolicy_.id);
|
|
512
614
|
return newPolicy_.id;
|
|
513
615
|
}
|
|
514
616
|
|
|
@@ -566,7 +668,7 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
566
668
|
// Checks
|
|
567
669
|
_validatePolicy(policy);
|
|
568
670
|
IRiskModule rm = policy.riskModule;
|
|
569
|
-
|
|
671
|
+
if (!expired && address(rm) != _msgSender()) revert OnlyRiskModuleAllowed();
|
|
570
672
|
require(payout == 0 || policy.expiration > block.timestamp, "Can't pay expired policy");
|
|
571
673
|
_requireCompActiveOrDeprecated(address(rm), ComponentKind.riskModule);
|
|
572
674
|
|
|
@@ -606,7 +708,7 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
606
708
|
if (!ERC165Checker.supportsInterface(customer, type(IPolicyHolder).interfaceId)) return;
|
|
607
709
|
|
|
608
710
|
bytes4 retval = IPolicyHolder(customer).onPayoutReceived(_msgSender(), address(this), policyId, payout);
|
|
609
|
-
|
|
711
|
+
if (retval != IPolicyHolder.onPayoutReceived.selector) revert InvalidNotificationResponse(retval);
|
|
610
712
|
}
|
|
611
713
|
|
|
612
714
|
/**
|
|
@@ -617,13 +719,29 @@ contract PolicyPool is IPolicyPool, PausableUpgradeable, UUPSUpgradeable, ERC721
|
|
|
617
719
|
if (!AddressUpgradeable.isContract(customer)) return;
|
|
618
720
|
if (!ERC165Checker.supportsInterface(customer, type(IPolicyHolder).interfaceId)) return;
|
|
619
721
|
|
|
620
|
-
try IPolicyHolder(customer).onPolicyExpired(_msgSender(), address(this), policyId) returns (
|
|
722
|
+
try IPolicyHolder(customer).onPolicyExpired{gas: HOLDER_GAS_LIMIT}(_msgSender(), address(this), policyId) returns (
|
|
723
|
+
bytes4
|
|
724
|
+
) {
|
|
621
725
|
return;
|
|
622
726
|
} catch {
|
|
727
|
+
emit ExpirationNotificationFailed(policyId, IPolicyHolder(customer));
|
|
623
728
|
return;
|
|
624
729
|
}
|
|
625
730
|
}
|
|
626
731
|
|
|
732
|
+
/**
|
|
733
|
+
* @dev Notifies the replacement with a callback if the policyholder is a contract. Never reverts.
|
|
734
|
+
*/
|
|
735
|
+
function _notifyReplacement(uint256 oldPolicyId, uint256 newPolicyId) internal {
|
|
736
|
+
address customer = ownerOf(oldPolicyId);
|
|
737
|
+
if (!AddressUpgradeable.isContract(customer)) return;
|
|
738
|
+
if (!ERC165Checker.supportsInterface(customer, type(IPolicyHolderV2).interfaceId)) return;
|
|
739
|
+
|
|
740
|
+
bytes4 retval = IPolicyHolderV2(customer).onPolicyReplaced(_msgSender(), address(this), oldPolicyId, newPolicyId);
|
|
741
|
+
// PolicyHolder can revert and cancel the policy replacement
|
|
742
|
+
if (retval != IPolicyHolderV2.onPolicyReplaced.selector) revert InvalidNotificationResponse(retval);
|
|
743
|
+
}
|
|
744
|
+
|
|
627
745
|
/**
|
|
628
746
|
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
|
|
629
747
|
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
|
|
@@ -42,6 +42,9 @@ abstract contract PolicyPoolComponent is UUPSUpgradeable, PausableUpgradeable, I
|
|
|
42
42
|
event GovernanceAction(IAccessManager.GovernanceActions indexed action, uint256 value);
|
|
43
43
|
event ComponentChanged(IAccessManager.GovernanceActions indexed action, address value);
|
|
44
44
|
|
|
45
|
+
error NoZeroPolicyPool();
|
|
46
|
+
error UpgradeCannotChangePolicyPool();
|
|
47
|
+
|
|
45
48
|
modifier onlyPolicyPool() {
|
|
46
49
|
require(_msgSender() == address(_policyPool), "The caller must be the PolicyPool");
|
|
47
50
|
_;
|
|
@@ -76,7 +79,7 @@ abstract contract PolicyPoolComponent is UUPSUpgradeable, PausableUpgradeable, I
|
|
|
76
79
|
|
|
77
80
|
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
78
81
|
constructor(IPolicyPool policyPool_) {
|
|
79
|
-
|
|
82
|
+
if (address(policyPool_) == address(0)) revert NoZeroPolicyPool();
|
|
80
83
|
_disableInitializers();
|
|
81
84
|
_policyPool = policyPool_;
|
|
82
85
|
}
|
|
@@ -94,7 +97,7 @@ abstract contract PolicyPoolComponent is UUPSUpgradeable, PausableUpgradeable, I
|
|
|
94
97
|
}
|
|
95
98
|
|
|
96
99
|
function _upgradeValidations(address newImpl) internal view virtual {
|
|
97
|
-
|
|
100
|
+
if (IPolicyPoolComponent(newImpl).policyPool() != _policyPool) revert UpgradeCannotChangePolicyPool();
|
|
98
101
|
}
|
|
99
102
|
|
|
100
103
|
/**
|
package/contracts/RiskModule.sol
CHANGED
|
@@ -56,12 +56,16 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
|
|
|
56
56
|
|
|
57
57
|
address internal _wallet; // Address of the RiskModule provider
|
|
58
58
|
|
|
59
|
+
error NoZeroWallet();
|
|
60
|
+
error ExposureLimitCannotBeLessThanActiveExposure();
|
|
61
|
+
error PremiumsAccountMustBePartOfThePool();
|
|
62
|
+
error UpgradeCannotChangePremiumsAccount();
|
|
63
|
+
|
|
59
64
|
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
60
65
|
constructor(IPolicyPool policyPool_, IPremiumsAccount premiumsAccount_) PolicyPoolComponent(policyPool_) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
);
|
|
66
|
+
if (PolicyPoolComponent(address(premiumsAccount_)).policyPool() != policyPool_) {
|
|
67
|
+
revert PremiumsAccountMustBePartOfThePool();
|
|
68
|
+
}
|
|
65
69
|
_premiumsAccount = premiumsAccount_;
|
|
66
70
|
}
|
|
67
71
|
|
|
@@ -120,7 +124,9 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
|
|
|
120
124
|
function _upgradeValidations(address newImpl) internal view virtual override {
|
|
121
125
|
super._upgradeValidations(newImpl);
|
|
122
126
|
IRiskModule newRM = IRiskModule(newImpl);
|
|
123
|
-
|
|
127
|
+
if (newRM.premiumsAccount() != _premiumsAccount) {
|
|
128
|
+
revert UpgradeCannotChangePremiumsAccount();
|
|
129
|
+
}
|
|
124
130
|
}
|
|
125
131
|
|
|
126
132
|
/**
|
|
@@ -133,8 +139,12 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
|
|
|
133
139
|
// runs validation on RiskModule parameters
|
|
134
140
|
function _validateParameters() internal view virtual override {
|
|
135
141
|
// _maxPayoutPerPolicy no limits
|
|
136
|
-
|
|
137
|
-
|
|
142
|
+
if (exposureLimit() < _activeExposure) {
|
|
143
|
+
revert ExposureLimitCannotBeLessThanActiveExposure();
|
|
144
|
+
}
|
|
145
|
+
if (_wallet == address(0)) {
|
|
146
|
+
revert NoZeroWallet();
|
|
147
|
+
}
|
|
138
148
|
_validatePackedParams(_params);
|
|
139
149
|
}
|
|
140
150
|
|
|
@@ -259,7 +269,9 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
|
|
|
259
269
|
}
|
|
260
270
|
|
|
261
271
|
function setWallet(address wallet_) external onlyComponentRole(RM_PROVIDER_ROLE) {
|
|
262
|
-
|
|
272
|
+
if (wallet_ == address(0)) {
|
|
273
|
+
revert NoZeroWallet();
|
|
274
|
+
}
|
|
263
275
|
_wallet = wallet_;
|
|
264
276
|
_parameterChanged(IAccessManager.GovernanceActions.setWallet, uint256(uint160(wallet_)), false);
|
|
265
277
|
}
|
|
@@ -269,32 +281,17 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
|
|
|
269
281
|
uint256 lossProb,
|
|
270
282
|
uint40 expiration
|
|
271
283
|
) public view virtual returns (uint256) {
|
|
272
|
-
return _getMinimumPremium(payout, lossProb, expiration, params());
|
|
284
|
+
return _getMinimumPremium(payout, lossProb, expiration, uint40(block.timestamp), params());
|
|
273
285
|
}
|
|
274
286
|
|
|
275
287
|
function _getMinimumPremium(
|
|
276
288
|
uint256 payout,
|
|
277
289
|
uint256 lossProb,
|
|
278
290
|
uint40 expiration,
|
|
291
|
+
uint40 start,
|
|
279
292
|
Params memory p
|
|
280
|
-
) internal
|
|
281
|
-
|
|
282
|
-
uint256 jrScr = payout.wadMul(p.jrCollRatio);
|
|
283
|
-
if (jrScr > purePremium) {
|
|
284
|
-
jrScr -= purePremium;
|
|
285
|
-
} else {
|
|
286
|
-
jrScr = 0;
|
|
287
|
-
}
|
|
288
|
-
uint256 srScr = payout.wadMul(p.collRatio);
|
|
289
|
-
if (srScr > (purePremium + jrScr)) {
|
|
290
|
-
srScr -= purePremium + jrScr;
|
|
291
|
-
} else {
|
|
292
|
-
srScr = 0;
|
|
293
|
-
}
|
|
294
|
-
uint256 jrCoc = jrScr.wadMul((p.jrRoc * (expiration - block.timestamp)).wadDiv(SECONDS_IN_YEAR_WAD));
|
|
295
|
-
uint256 srCoc = srScr.wadMul((p.srRoc * (expiration - block.timestamp)).wadDiv(SECONDS_IN_YEAR_WAD));
|
|
296
|
-
uint256 ensuroCommission = purePremium.wadMul(p.ensuroPpFee) + (jrCoc + srCoc).wadMul(p.ensuroCocFee);
|
|
297
|
-
return purePremium + ensuroCommission + (jrCoc + srCoc);
|
|
293
|
+
) internal pure returns (uint256) {
|
|
294
|
+
return Policy.getMinimumPremium(p, payout, lossProb, expiration, start).totalPremium;
|
|
298
295
|
}
|
|
299
296
|
|
|
300
297
|
/**
|
|
@@ -334,11 +331,11 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
|
|
|
334
331
|
uint96 internalId,
|
|
335
332
|
Params memory params_
|
|
336
333
|
) internal returns (Policy.PolicyData memory policy) {
|
|
334
|
+
uint40 now_ = uint40(block.timestamp);
|
|
337
335
|
if (premium == type(uint256).max) {
|
|
338
|
-
premium = _getMinimumPremium(payout, lossProb, expiration, params_);
|
|
336
|
+
premium = _getMinimumPremium(payout, lossProb, expiration, now_, params_);
|
|
339
337
|
}
|
|
340
338
|
require(premium < payout, "Premium must be less than payout");
|
|
341
|
-
uint40 now_ = uint40(block.timestamp);
|
|
342
339
|
require(expiration > now_, "Expiration must be in the future");
|
|
343
340
|
require(((expiration - now_) / 3600) < _params.maxDuration, "Policy exceeds max duration");
|
|
344
341
|
require(onBehalfOf != address(0), "Customer can't be zero address");
|
|
@@ -381,7 +378,7 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
|
|
|
381
378
|
Params memory params_
|
|
382
379
|
) internal virtual returns (Policy.PolicyData memory policy) {
|
|
383
380
|
if (premium == type(uint256).max) {
|
|
384
|
-
premium = _getMinimumPremium(payout, lossProb, expiration, params_);
|
|
381
|
+
premium = _getMinimumPremium(payout, lossProb, expiration, oldPolicy.start, params_);
|
|
385
382
|
}
|
|
386
383
|
require(premium < payout, "Premium must be less than payout");
|
|
387
384
|
require(oldPolicy.expiration > uint40(block.timestamp), "Old policy is expired");
|