@ensuro/core 2.7.0 → 2.8.0-beta2

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.
Files changed (79) hide show
  1. package/README.md +13 -7
  2. package/contracts/AccessManager.sol +3 -13
  3. package/contracts/EToken.sol +29 -95
  4. package/contracts/LPManualWhitelist.sol +11 -26
  5. package/contracts/LiquidityThresholdAssetManager.sol +10 -21
  6. package/contracts/Policy.sol +10 -20
  7. package/contracts/PolicyPool.sol +110 -127
  8. package/contracts/PolicyPoolComponent.sol +9 -32
  9. package/contracts/PremiumsAccount.sol +41 -47
  10. package/contracts/Reserve.sol +10 -16
  11. package/contracts/RiskModule.sol +74 -83
  12. package/contracts/SignedBucketRiskModule.sol +18 -80
  13. package/contracts/SignedQuoteRiskModule.sol +13 -44
  14. package/contracts/TieredSignedQuoteRiskModule.sol +7 -13
  15. package/contracts/TimeScaled.sol +8 -39
  16. package/contracts/TrustfulRiskModule.sol +47 -42
  17. package/contracts/interfaces/IAccessManager.sol +2 -11
  18. package/contracts/interfaces/IEToken.sol +1 -5
  19. package/contracts/interfaces/ILPWhitelist.sol +2 -10
  20. package/contracts/interfaces/IPolicyHolder.sol +2 -11
  21. package/contracts/interfaces/IPolicyPool.sol +59 -3
  22. package/contracts/interfaces/IPremiumsAccount.sol +17 -5
  23. package/contracts/migration/LPManualWhitelistV20.sol +3 -15
  24. package/contracts/migration/LPManualWhitelistV20Upgraded.sol +1 -5
  25. package/contracts/mocks/FixedRateVault.sol +1 -6
  26. package/contracts/mocks/InterfaceIdCalculator.sol +2 -0
  27. package/contracts/mocks/PolicyHolderMock.sol +3 -13
  28. package/contracts/mocks/PolicyPoolComponentMock.sol +1 -3
  29. package/contracts/mocks/PolicyPoolMock.sol +25 -25
  30. package/contracts/mocks/RiskModuleMock.sol +39 -16
  31. package/contracts/mocks/TestNFT.sol +1 -1
  32. package/js/deploy.js +44 -39
  33. package/js/test-utils.js +30 -19
  34. package/js/utils.js +62 -29
  35. package/package.json +1 -1
  36. package/scripts/utils.sh +23 -12
  37. package/build/contracts/AccessManager.sol/AccessManager.json +0 -618
  38. package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +0 -238
  39. package/build/contracts/EToken.sol/EToken.json +0 -1277
  40. package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +0 -647
  41. package/build/contracts/LiquidityThresholdAssetManager.sol/LiquidityThresholdAssetManager.json +0 -222
  42. package/build/contracts/Policy.sol/Policy.json +0 -10
  43. package/build/contracts/PolicyPool.sol/PolicyPool.json +0 -1416
  44. package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +0 -332
  45. package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +0 -970
  46. package/build/contracts/Reserve.sol/Reserve.json +0 -403
  47. package/build/contracts/RiskModule.sol/RiskModule.json +0 -559
  48. package/build/contracts/SignedBucketRiskModule.sol/SignedBucketRiskModule.json +0 -1262
  49. package/build/contracts/SignedQuoteRiskModule.sol/SignedQuoteRiskModule.json +0 -1110
  50. package/build/contracts/TieredSignedQuoteRiskModule.sol/TieredSignedQuoteRiskModule.json +0 -1316
  51. package/build/contracts/TimeScaled.sol/TimeScaled.json +0 -10
  52. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +0 -984
  53. package/build/contracts/dependencies/ERC1967Proxy.sol/ERC1967Proxy.json +0 -64
  54. package/build/contracts/dependencies/IERC20Metadata.sol/IERC20Metadata.json +0 -233
  55. package/build/contracts/dependencies/WadRayMath.sol/WadRayMath.json +0 -10
  56. package/build/contracts/interfaces/IAccessManager.sol/IAccessManager.json +0 -343
  57. package/build/contracts/interfaces/IAssetManager.sol/IAssetManager.json +0 -128
  58. package/build/contracts/interfaces/IEToken.sol/IEToken.json +0 -460
  59. package/build/contracts/interfaces/ILPWhitelist.sol/ILPWhitelist.json +0 -103
  60. package/build/contracts/interfaces/IPolicyHolder.sol/IPolicyHolder.json +0 -108
  61. package/build/contracts/interfaces/IPolicyPool.sol/IPolicyPool.json +0 -501
  62. package/build/contracts/interfaces/IPolicyPoolComponent.sol/IPolicyPoolComponent.json +0 -43
  63. package/build/contracts/interfaces/IPremiumsAccount.sol/IPremiumsAccount.json +0 -315
  64. package/build/contracts/interfaces/IRiskModule.sol/IRiskModule.json +0 -165
  65. package/build/contracts/migration/LPManualWhitelistV20.sol/LPManualWhitelistV20.json +0 -481
  66. package/build/contracts/migration/LPManualWhitelistV20Upgraded.sol/LPManualWhitelistV20Upgraded.json +0 -492
  67. package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +0 -736
  68. package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +0 -43
  69. package/build/contracts/mocks/IMintableERC20.sol/IMintableERC20.json +0 -47
  70. package/build/contracts/mocks/InterfaceIdCalculator.sol/InterfaceIdCalculator.json +0 -180
  71. package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +0 -319
  72. package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +0 -54
  73. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +0 -721
  74. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +0 -92
  75. package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +0 -783
  76. package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +0 -343
  77. package/build/contracts/mocks/TestNFT.sol/TestNFT.json +0 -388
  78. package/contracts/dependencies/ERC1967Proxy.sol +0 -19
  79. package/contracts/dependencies/IERC20Metadata.sol +0 -19
@@ -36,7 +36,7 @@ abstract contract Reserve is PolicyPoolComponent {
36
36
  */
37
37
  /// @custom:oz-upgrades-unsafe-allow constructor
38
38
  constructor(IPolicyPool policyPool_) PolicyPoolComponent(policyPool_) {
39
- NEGLIGIBLE_AMOUNT = 10**(policyPool_.currency().decimals() / 2);
39
+ NEGLIGIBLE_AMOUNT = 10 ** (policyPool_.currency().decimals() / 2);
40
40
  }
41
41
 
42
42
  /**
@@ -130,10 +130,10 @@ abstract contract Reserve is PolicyPoolComponent {
130
130
  * `force` is true, an error in the deinvestAll() operation is ignored. When `force` is false, if `deinvestAll()`
131
131
  * fails, it reverts.
132
132
  */
133
- function setAssetManager(IAssetManager newAM, bool force)
134
- external
135
- onlyGlobalOrComponentRole2(GUARDIAN_ROLE, LEVEL1_ROLE)
136
- {
133
+ function setAssetManager(
134
+ IAssetManager newAM,
135
+ bool force
136
+ ) external onlyGlobalOrComponentRole2(GUARDIAN_ROLE, LEVEL1_ROLE) {
137
137
  require(
138
138
  address(newAM) == address(0) || newAM.supportsInterface(type(IAssetManager).interfaceId),
139
139
  "Reserve: asset manager doesn't implements the required interface"
@@ -158,9 +158,7 @@ abstract contract Reserve is PolicyPoolComponent {
158
158
  * the storage in the connect() method (as it is the recommended practice in normal changes of AM).
159
159
  */
160
160
  } else {
161
- bytes memory result = am.functionDelegateCall(
162
- abi.encodeWithSelector(IAssetManager.deinvestAll.selector)
163
- );
161
+ bytes memory result = am.functionDelegateCall(abi.encodeWithSelector(IAssetManager.deinvestAll.selector));
164
162
  _assetEarnings(abi.decode(result, (int256)));
165
163
  }
166
164
  }
@@ -179,9 +177,7 @@ abstract contract Reserve is PolicyPoolComponent {
179
177
  * - Emits {IAssetManager-MoneyInvested} or {IAssetManager-MoneyDeinvested}
180
178
  */
181
179
  function rebalance() public whenNotPaused {
182
- address(assetManager()).functionDelegateCall(
183
- abi.encodeWithSelector(IAssetManager.rebalance.selector)
184
- );
180
+ address(assetManager()).functionDelegateCall(abi.encodeWithSelector(IAssetManager.rebalance.selector));
185
181
  }
186
182
 
187
183
  /**
@@ -217,11 +213,9 @@ abstract contract Reserve is PolicyPoolComponent {
217
213
  * @param functionCall Abi encoded function call to make.
218
214
  * @return Returns the return value of the function called, to be decoded by the receiver.
219
215
  */
220
- function forwardToAssetManager(bytes memory functionCall)
221
- external
222
- onlyGlobalOrComponentRole(LEVEL2_ROLE)
223
- returns (bytes memory)
224
- {
216
+ function forwardToAssetManager(
217
+ bytes memory functionCall
218
+ ) external onlyGlobalOrComponentRole(LEVEL2_ROLE) returns (bytes memory) {
225
219
  return address(assetManager()).functionDelegateCall(functionCall);
226
220
  }
227
221
 
@@ -57,9 +57,7 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
57
57
  address internal _wallet; // Address of the RiskModule provider
58
58
 
59
59
  /// @custom:oz-upgrades-unsafe-allow constructor
60
- constructor(IPolicyPool policyPool_, IPremiumsAccount premiumsAccount_)
61
- PolicyPoolComponent(policyPool_)
62
- {
60
+ constructor(IPolicyPool policyPool_, IPremiumsAccount premiumsAccount_) PolicyPoolComponent(policyPool_) {
63
61
  require(
64
62
  PolicyPoolComponent(address(premiumsAccount_)).policyPool() == policyPool_,
65
63
  "The PremiumsAccount must be part of the Pool"
@@ -88,15 +86,7 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
88
86
  address wallet_
89
87
  ) internal onlyInitializing {
90
88
  __PolicyPoolComponent_init();
91
- __RiskModule_init_unchained(
92
- name_,
93
- collRatio_,
94
- ensuroPpFee_,
95
- srRoc_,
96
- maxPayoutPerPolicy_,
97
- exposureLimit_,
98
- wallet_
99
- );
89
+ __RiskModule_init_unchained(name_, collRatio_, ensuroPpFee_, srRoc_, maxPayoutPerPolicy_, exposureLimit_, wallet_);
100
90
  }
101
91
 
102
92
  // solhint-disable-next-line func-name-mixedcase
@@ -130,10 +120,7 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
130
120
  function _upgradeValidations(address newImpl) internal view virtual override {
131
121
  super._upgradeValidations(newImpl);
132
122
  IRiskModule newRM = IRiskModule(newImpl);
133
- require(
134
- newRM.premiumsAccount() == _premiumsAccount,
135
- "Can't upgrade changing the PremiumsAccount"
136
- );
123
+ require(newRM.premiumsAccount() == _premiumsAccount, "Can't upgrade changing the PremiumsAccount");
137
124
  }
138
125
 
139
126
  /**
@@ -146,30 +133,21 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
146
133
  // runs validation on RiskModule parameters
147
134
  function _validateParameters() internal view virtual override {
148
135
  // _maxPayoutPerPolicy no limits
149
- require(
150
- exposureLimit() >= _activeExposure,
151
- "Validation: exposureLimit can't be less than actual activeExposure"
152
- );
136
+ require(exposureLimit() >= _activeExposure, "Validation: exposureLimit can't be less than actual activeExposure");
153
137
  require(_wallet != address(0), "Validation: Wallet can't be zero address");
154
138
  _validatePackedParams(_params);
155
139
  }
156
140
 
157
141
  function _validatePackedParams(PackedParams storage params_) internal view {
158
142
  require(params_.jrCollRatio <= HUNDRED_PERCENT, "Validation: jrCollRatio must be <=1");
159
- require(
160
- params_.collRatio <= HUNDRED_PERCENT && params_.collRatio > 0,
161
- "Validation: collRatio must be <=1"
162
- );
143
+ require(params_.collRatio <= HUNDRED_PERCENT && params_.collRatio > 0, "Validation: collRatio must be <=1");
163
144
  require(params_.collRatio >= params_.jrCollRatio, "Validation: collRatio >= jrCollRatio");
164
145
  require(params_.moc <= MAX_MOC && params_.moc >= MIN_MOC, "Validation: moc must be [0.5, 4]");
165
146
  require(params_.ensuroPpFee <= HUNDRED_PERCENT, "Validation: ensuroPpFee must be <= 1");
166
147
  require(params_.ensuroCocFee <= HUNDRED_PERCENT, "Validation: ensuroCocFee must be <= 1");
167
148
  require(params_.srRoc <= HUNDRED_PERCENT, "Validation: srRoc must be <= 1 (100%)");
168
149
  require(params_.jrRoc <= HUNDRED_PERCENT, "Validation: jrRoc must be <= 1 (100%)");
169
- require(
170
- params_.exposureLimit > 0 && params_.maxPayoutPerPolicy > 0,
171
- "Exposure and MaxPayout must be >0"
172
- );
150
+ require(params_.exposureLimit > 0 && params_.maxPayoutPerPolicy > 0, "Exposure and MaxPayout must be >0");
173
151
  }
174
152
 
175
153
  function name() public view override returns (string memory) {
@@ -190,12 +168,12 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
190
168
  // solhint-disable-next-line func-name-mixedcase
191
169
  function _XtoAmount(uint8 decimals, uint32 value) internal view returns (uint256) {
192
170
  // X decimals to currency decimals (6 for USDC)
193
- return uint256(value) * 10**(currency().decimals() - decimals);
171
+ return uint256(value) * 10 ** (currency().decimals() - decimals);
194
172
  }
195
173
 
196
174
  function _amountToX(uint8 decimals, uint256 value) internal view returns (uint32) {
197
175
  // currency decimals to X decimals (assuming X < currency decimals)
198
- return (value / 10**(currency().decimals() - decimals)).toUint32();
176
+ return (value / 10 ** (currency().decimals() - decimals)).toUint32();
199
177
  }
200
178
 
201
179
  function maxPayoutPerPolicy() public view override returns (uint256) {
@@ -218,34 +196,25 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
218
196
  return _wallet;
219
197
  }
220
198
 
221
- function setParam(Parameter param, uint256 newValue)
222
- external
223
- onlyGlobalOrComponentRole3(LEVEL1_ROLE, LEVEL2_ROLE, LEVEL3_ROLE)
224
- {
199
+ function setParam(
200
+ Parameter param,
201
+ uint256 newValue
202
+ ) external onlyGlobalOrComponentRole3(LEVEL1_ROLE, LEVEL2_ROLE, LEVEL3_ROLE) {
225
203
  bool tweak = !hasPoolRole(LEVEL2_ROLE) && !hasPoolRole(LEVEL1_ROLE);
226
204
  if (param == Parameter.moc) {
227
205
  require(!tweak || _isTweakWad(_4toWad(_params.moc), newValue, 1e17), "Tweak exceeded");
228
206
  _params.moc = _wadTo4(newValue);
229
207
  } else if (param == Parameter.jrCollRatio) {
230
- require(
231
- !tweak || _isTweakWad(_4toWad(_params.jrCollRatio), newValue, 1e17),
232
- "Tweak exceeded"
233
- );
208
+ require(!tweak || _isTweakWad(_4toWad(_params.jrCollRatio), newValue, 1e17), "Tweak exceeded");
234
209
  _params.jrCollRatio = _wadTo4(newValue);
235
210
  } else if (param == Parameter.collRatio) {
236
211
  require(!tweak || _isTweakWad(_4toWad(_params.collRatio), newValue, 1e17), "Tweak exceeded");
237
212
  _params.collRatio = _wadTo4(newValue);
238
213
  } else if (param == Parameter.ensuroPpFee) {
239
- require(
240
- !tweak || _isTweakWad(_4toWad(_params.ensuroPpFee), newValue, 1e17),
241
- "Tweak exceeded"
242
- );
214
+ require(!tweak || _isTweakWad(_4toWad(_params.ensuroPpFee), newValue, 1e17), "Tweak exceeded");
243
215
  _params.ensuroPpFee = _wadTo4(newValue);
244
216
  } else if (param == Parameter.ensuroCocFee) {
245
- require(
246
- !tweak || _isTweakWad(_4toWad(_params.ensuroCocFee), newValue, 1e17),
247
- "Tweak exceeded"
248
- );
217
+ require(!tweak || _isTweakWad(_4toWad(_params.ensuroCocFee), newValue, 1e17), "Tweak exceeded");
249
218
  _params.ensuroCocFee = _wadTo4(newValue);
250
219
  } else if (param == Parameter.jrRoc) {
251
220
  require(!tweak || _isTweakWad(_4toWad(_params.jrRoc), newValue, 1e17), "Tweak exceeded");
@@ -259,19 +228,14 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
259
228
  } else if (param == Parameter.exposureLimit) {
260
229
  require(newValue >= _activeExposure, "Can't set exposureLimit less than active exposure");
261
230
  require(!tweak || _isTweakWad(exposureLimit(), newValue, 1e17), "Tweak exceeded");
262
- require(
263
- newValue <= exposureLimit() || hasPoolRole(LEVEL1_ROLE),
264
- "Tweak exceeded: Increase requires LEVEL1_ROLE"
265
- );
231
+ require(newValue <= exposureLimit() || hasPoolRole(LEVEL1_ROLE), "Tweak exceeded: Increase requires LEVEL1_ROLE");
266
232
  _params.exposureLimit = _amountToX(0, newValue);
267
233
  } else if (param == Parameter.maxDuration) {
268
234
  require(!tweak, "Tweak exceeded");
269
235
  _params.maxDuration = newValue.toUint16();
270
236
  }
271
237
  _parameterChanged(
272
- IAccessManager.GovernanceActions(
273
- uint256(IAccessManager.GovernanceActions.setMoc) + uint256(param)
274
- ),
238
+ IAccessManager.GovernanceActions(uint256(IAccessManager.GovernanceActions.setMoc) + uint256(param)),
275
239
  newValue,
276
240
  tweak
277
241
  );
@@ -327,14 +291,9 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
327
291
  } else {
328
292
  srScr = 0;
329
293
  }
330
- uint256 jrCoc = jrScr.wadMul(
331
- (p.jrRoc * (expiration - block.timestamp)).wadDiv(SECONDS_IN_YEAR_WAD)
332
- );
333
- uint256 srCoc = srScr.wadMul(
334
- (p.srRoc * (expiration - block.timestamp)).wadDiv(SECONDS_IN_YEAR_WAD)
335
- );
336
- uint256 ensuroCommission = purePremium.wadMul(p.ensuroPpFee) +
337
- (jrCoc + srCoc).wadMul(p.ensuroCocFee);
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);
338
297
  return purePremium + ensuroCommission + (jrCoc + srCoc);
339
298
  }
340
299
 
@@ -359,17 +318,7 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
359
318
  address onBehalfOf,
360
319
  uint96 internalId
361
320
  ) internal virtual returns (Policy.PolicyData memory) {
362
- return
363
- _newPolicyWithParams(
364
- payout,
365
- premium,
366
- lossProb,
367
- expiration,
368
- payer,
369
- onBehalfOf,
370
- internalId,
371
- params()
372
- );
321
+ return _newPolicyWithParams(payout, premium, lossProb, expiration, payer, onBehalfOf, internalId, params());
373
322
  }
374
323
 
375
324
  /**
@@ -384,7 +333,7 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
384
333
  address onBehalfOf,
385
334
  uint96 internalId,
386
335
  Params memory params_
387
- ) internal returns (Policy.PolicyData memory) {
336
+ ) internal returns (Policy.PolicyData memory policy) {
388
337
  if (premium == type(uint256).max) {
389
338
  premium = _getMinimumPremium(payout, lossProb, expiration, params_);
390
339
  }
@@ -402,18 +351,60 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
402
351
  "Payer must allow caller to transfer the premium"
403
352
  );
404
353
  require(payout <= maxPayoutPerPolicy(), "RiskModule: Payout is more than maximum per policy");
405
- Policy.PolicyData memory policy = Policy.initialize(
406
- this,
407
- params_,
408
- premium,
409
- payout,
410
- lossProb,
411
- expiration
412
- );
354
+ policy = Policy.initialize(this, params_, premium, payout, lossProb, expiration, now_);
413
355
  _activeExposure += policy.payout;
414
356
  require(_activeExposure <= exposureLimit(), "RiskModule: Exposure limit exceeded");
415
- uint256 policyId = _policyPool.newPolicy(policy, payer, onBehalfOf, internalId);
416
- policy.id = policyId;
357
+ policy.id = _policyPool.newPolicy(policy, payer, onBehalfOf, internalId);
358
+ return policy;
359
+ }
360
+
361
+ /**
362
+ * @dev Called from child contracts to replace policies (after they validated the pricing).
363
+ * whenNotPaused validation must be done in the external method.
364
+ *
365
+ * @param payout The exposure (maximum payout) of the policy
366
+ * @param premium The premium that will be paid by the policyHolder
367
+ * @param lossProb The probability of having to pay the maximum payout (wad)
368
+ * @param payer The account that pays for the premium
369
+ * @param expiration The expiration of the policy (timestamp)
370
+ * @param internalId An id that's unique within this module and it will be used to identify the policy
371
+ * @param params_ Params to use to create the new policy
372
+ */
373
+ function _replacePolicy(
374
+ Policy.PolicyData calldata oldPolicy,
375
+ uint256 payout,
376
+ uint256 premium,
377
+ uint256 lossProb,
378
+ uint40 expiration,
379
+ address payer,
380
+ uint96 internalId,
381
+ Params memory params_
382
+ ) internal virtual returns (Policy.PolicyData memory policy) {
383
+ if (premium == type(uint256).max) {
384
+ premium = _getMinimumPremium(payout, lossProb, expiration, params_);
385
+ }
386
+ require(premium < payout, "Premium must be less than payout");
387
+ require(oldPolicy.expiration > uint40(block.timestamp), "Old policy is expired");
388
+ require(
389
+ expiration >= oldPolicy.expiration && payout >= oldPolicy.payout && premium >= oldPolicy.premium,
390
+ "Policy replacement must be greater or equal than old policy"
391
+ );
392
+ require(((expiration - oldPolicy.start) / 3600) < _params.maxDuration, "Policy exceeds max duration");
393
+ require(
394
+ _policyPool.currency().allowance(payer, address(_policyPool)) >= (premium - oldPolicy.premium),
395
+ "You must allow ENSURO to transfer the premium"
396
+ );
397
+ require(
398
+ payer == _msgSender() || _policyPool.currency().allowance(payer, _msgSender()) >= (premium - oldPolicy.premium),
399
+ "Payer must allow caller to transfer the premium"
400
+ );
401
+ require(payout <= maxPayoutPerPolicy(), "RiskModule: Payout is more than maximum per policy");
402
+ policy = Policy.initialize(this, params_, premium, payout, lossProb, expiration, oldPolicy.start);
403
+
404
+ _activeExposure += policy.payout - oldPolicy.payout;
405
+ require(_activeExposure <= exposureLimit(), "RiskModule: Exposure limit exceeded");
406
+
407
+ policy.id = _policyPool.replacePolicy(oldPolicy, policy, payer, internalId);
417
408
  return policy;
418
409
  }
419
410
 
@@ -75,15 +75,7 @@ contract SignedBucketRiskModule is RiskModule {
75
75
  uint256 exposureLimit_,
76
76
  address wallet_
77
77
  ) public initializer {
78
- __RiskModule_init(
79
- name_,
80
- collRatio_,
81
- ensuroPpFee_,
82
- srRoc_,
83
- maxPayoutPerPolicy_,
84
- exposureLimit_,
85
- wallet_
86
- );
78
+ __RiskModule_init(name_, collRatio_, ensuroPpFee_, srRoc_, maxPayoutPerPolicy_, exposureLimit_, wallet_);
87
79
  }
88
80
 
89
81
  function _checkSignature(
@@ -98,12 +90,7 @@ contract SignedBucketRiskModule is RiskModule {
98
90
  uint40 quoteValidUntil
99
91
  ) internal view {
100
92
  if (!_creationIsOpen)
101
- _policyPool.access().checkComponentRole(
102
- address(this),
103
- POLICY_CREATOR_ROLE,
104
- _msgSender(),
105
- false
106
- );
93
+ _policyPool.access().checkComponentRole(address(this), POLICY_CREATOR_ROLE, _msgSender(), false);
107
94
  require(quoteValidUntil >= block.timestamp, "Quote expired");
108
95
 
109
96
  /**
@@ -116,16 +103,7 @@ contract SignedBucketRiskModule is RiskModule {
116
103
  * - quoteValidUntil: the maximum validity of the quote
117
104
  */
118
105
  bytes32 quoteHash = ECDSA.toEthSignedMessageHash(
119
- abi.encodePacked(
120
- address(this),
121
- payout,
122
- premium,
123
- lossProb,
124
- expiration,
125
- policyData,
126
- bucketId,
127
- quoteValidUntil
128
- )
106
+ abi.encodePacked(address(this), payout, premium, lossProb, expiration, policyData, bucketId, quoteValidUntil)
129
107
  );
130
108
  address signer = ECDSA.recover(quoteHash, quoteSignatureR, quoteSignatureVS);
131
109
  _policyPool.access().checkComponentRole(address(this), PRICER_ROLE, signer, false);
@@ -141,7 +119,7 @@ contract SignedBucketRiskModule is RiskModule {
141
119
  address payer,
142
120
  address onBehalfOf
143
121
  ) internal returns (Policy.PolicyData memory createdPolicy) {
144
- uint96 internalId = uint96(uint256(policyData) % 2**96);
122
+ uint96 internalId = uint96(uint256(policyData) % 2 ** 96);
145
123
  createdPolicy = _newPolicyWithParams(
146
124
  payout,
147
125
  premium,
@@ -202,17 +180,7 @@ contract SignedBucketRiskModule is RiskModule {
202
180
  quoteSignatureVS,
203
181
  quoteValidUntil
204
182
  );
205
- return
206
- _newPolicySigned(
207
- payout,
208
- premium,
209
- lossProb,
210
- expiration,
211
- policyData,
212
- bucketId,
213
- _msgSender(),
214
- onBehalfOf
215
- );
183
+ return _newPolicySigned(payout, premium, lossProb, expiration, policyData, bucketId, _msgSender(), onBehalfOf);
216
184
  }
217
185
 
218
186
  /**
@@ -261,17 +229,7 @@ contract SignedBucketRiskModule is RiskModule {
261
229
  quoteSignatureVS,
262
230
  quoteValidUntil
263
231
  );
264
- return
265
- _newPolicySigned(
266
- payout,
267
- premium,
268
- lossProb,
269
- expiration,
270
- policyData,
271
- bucketId,
272
- _msgSender(),
273
- onBehalfOf
274
- ).id;
232
+ return _newPolicySigned(payout, premium, lossProb, expiration, policyData, bucketId, _msgSender(), onBehalfOf).id;
275
233
  }
276
234
 
277
235
  /**
@@ -334,24 +292,13 @@ contract SignedBucketRiskModule is RiskModule {
334
292
  quoteSignatureVS,
335
293
  quoteValidUntil
336
294
  );
337
- return
338
- _newPolicySigned(
339
- payout,
340
- premium,
341
- lossProb,
342
- expiration,
343
- policyData,
344
- bucketId,
345
- onBehalfOf,
346
- onBehalfOf
347
- ).id;
295
+ return _newPolicySigned(payout, premium, lossProb, expiration, policyData, bucketId, onBehalfOf, onBehalfOf).id;
348
296
  }
349
297
 
350
- function resolvePolicy(Policy.PolicyData calldata policy, uint256 payout)
351
- external
352
- onlyComponentRole(RESOLVER_ROLE)
353
- whenNotPaused
354
- {
298
+ function resolvePolicy(
299
+ Policy.PolicyData calldata policy,
300
+ uint256 payout
301
+ ) external onlyComponentRole(RESOLVER_ROLE) whenNotPaused {
355
302
  _policyPool.resolvePolicy(policy, payout);
356
303
  }
357
304
 
@@ -365,14 +312,11 @@ contract SignedBucketRiskModule is RiskModule {
365
312
  * @param bucketId Group identifier for the policies that will have these parameters
366
313
  * @param params_ The parameters of the new bucket.
367
314
  */
368
- function setBucketParams(uint256 bucketId, Params calldata params_)
369
- external
370
- onlyGlobalOrComponentRole2(LEVEL1_ROLE, LEVEL2_ROLE)
371
- {
372
- require(
373
- bucketId != 0,
374
- "SignedBucketRiskModule: bucketId can't be zero, set default RM parameters"
375
- );
315
+ function setBucketParams(
316
+ uint256 bucketId,
317
+ Params calldata params_
318
+ ) external onlyGlobalOrComponentRole2(LEVEL1_ROLE, LEVEL2_ROLE) {
319
+ require(bucketId != 0, "SignedBucketRiskModule: bucketId can't be zero, set default RM parameters");
376
320
  _buckets[bucketId] = PackedParams({
377
321
  moc: _wadTo4(params_.moc),
378
322
  jrCollRatio: _wadTo4(params_.jrCollRatio),
@@ -398,14 +342,8 @@ contract SignedBucketRiskModule is RiskModule {
398
342
  *
399
343
  * @param bucketId Group identifier for the policies that will have these parameters
400
344
  */
401
- function deleteBucket(uint256 bucketId)
402
- external
403
- onlyGlobalOrComponentRole2(LEVEL1_ROLE, LEVEL2_ROLE)
404
- {
405
- require(
406
- bucketId != 0,
407
- "SignedBucketRiskModule: bucketId can't be zero, set default RM parameters"
408
- );
345
+ function deleteBucket(uint256 bucketId) external onlyGlobalOrComponentRole2(LEVEL1_ROLE, LEVEL2_ROLE) {
346
+ require(bucketId != 0, "SignedBucketRiskModule: bucketId can't be zero, set default RM parameters");
409
347
  delete _buckets[bucketId];
410
348
  emit BucketDeleted(bucketId);
411
349
  }
@@ -58,15 +58,7 @@ contract SignedQuoteRiskModule is RiskModule {
58
58
  uint256 exposureLimit_,
59
59
  address wallet_
60
60
  ) public initializer {
61
- __RiskModule_init(
62
- name_,
63
- collRatio_,
64
- ensuroPpFee_,
65
- srRoc_,
66
- maxPayoutPerPolicy_,
67
- exposureLimit_,
68
- wallet_
69
- );
61
+ __RiskModule_init(name_, collRatio_, ensuroPpFee_, srRoc_, maxPayoutPerPolicy_, exposureLimit_, wallet_);
70
62
  }
71
63
 
72
64
  function _newPolicySigned(
@@ -82,12 +74,7 @@ contract SignedQuoteRiskModule is RiskModule {
82
74
  address onBehalfOf
83
75
  ) internal returns (Policy.PolicyData memory createdPolicy) {
84
76
  if (!_creationIsOpen)
85
- _policyPool.access().checkComponentRole(
86
- address(this),
87
- POLICY_CREATOR_ROLE,
88
- _msgSender(),
89
- false
90
- );
77
+ _policyPool.access().checkComponentRole(address(this), POLICY_CREATOR_ROLE, _msgSender(), false);
91
78
  require(quoteValidUntil >= block.timestamp, "Quote expired");
92
79
 
93
80
  /**
@@ -100,29 +87,13 @@ contract SignedQuoteRiskModule is RiskModule {
100
87
  * - quoteValidUntil: the maximum validity of the quote
101
88
  */
102
89
  bytes32 quoteHash = ECDSA.toEthSignedMessageHash(
103
- abi.encodePacked(
104
- address(this),
105
- payout,
106
- premium,
107
- lossProb,
108
- expiration,
109
- policyData,
110
- quoteValidUntil
111
- )
90
+ abi.encodePacked(address(this), payout, premium, lossProb, expiration, policyData, quoteValidUntil)
112
91
  );
113
92
  address signer = ECDSA.recover(quoteHash, quoteSignatureR, quoteSignatureVS);
114
93
  _policyPool.access().checkComponentRole(address(this), PRICER_ROLE, signer, false);
115
- uint96 internalId = uint96(uint256(policyData) % 2**96);
94
+ uint96 internalId = uint96(uint256(policyData) % 2 ** 96);
116
95
 
117
- createdPolicy = _newPolicy(
118
- payout,
119
- premium,
120
- lossProb,
121
- expiration,
122
- payer,
123
- onBehalfOf,
124
- internalId
125
- );
96
+ createdPolicy = _newPolicy(payout, premium, lossProb, expiration, payer, onBehalfOf, internalId);
126
97
  emit NewSignedPolicy(createdPolicy.id, policyData);
127
98
  return createdPolicy;
128
99
  }
@@ -285,19 +256,17 @@ contract SignedQuoteRiskModule is RiskModule {
285
256
  ).id;
286
257
  }
287
258
 
288
- function resolvePolicy(Policy.PolicyData calldata policy, uint256 payout)
289
- external
290
- onlyComponentRole(RESOLVER_ROLE)
291
- whenNotPaused
292
- {
259
+ function resolvePolicy(
260
+ Policy.PolicyData calldata policy,
261
+ uint256 payout
262
+ ) external onlyComponentRole(RESOLVER_ROLE) whenNotPaused {
293
263
  _policyPool.resolvePolicy(policy, payout);
294
264
  }
295
265
 
296
- function resolvePolicyFullPayout(Policy.PolicyData calldata policy, bool customerWon)
297
- external
298
- onlyComponentRole(RESOLVER_ROLE)
299
- whenNotPaused
300
- {
266
+ function resolvePolicyFullPayout(
267
+ Policy.PolicyData calldata policy,
268
+ bool customerWon
269
+ ) external onlyComponentRole(RESOLVER_ROLE) whenNotPaused {
301
270
  _policyPool.resolvePolicyFullPayout(policy, customerWon);
302
271
  }
303
272
 
@@ -62,22 +62,16 @@ contract TieredSignedQuoteRiskModule is SignedQuoteRiskModule {
62
62
  * @param lossProb The loss probability of the new bucket.
63
63
  * @param params_ The parameters of the new bucket.
64
64
  */
65
- function pushBucket(uint256 lossProb, Params calldata params_)
66
- external
67
- onlyGlobalOrComponentRole2(LEVEL1_ROLE, LEVEL2_ROLE)
68
- {
65
+ function pushBucket(
66
+ uint256 lossProb,
67
+ Params calldata params_
68
+ ) external onlyGlobalOrComponentRole2(LEVEL1_ROLE, LEVEL2_ROLE) {
69
69
  uint256 newBucket = 0;
70
70
  if (_buckets.lossProbs[0] != 0) {
71
- for (
72
- newBucket = 1;
73
- newBucket < MAX_BUCKETS && _buckets.lossProbs[newBucket] != 0;
74
- newBucket++
75
- ) {} // solhint-disable-line no-empty-blocks
71
+ // solhint-disable-next-line no-empty-blocks
72
+ for (newBucket = 1; newBucket < MAX_BUCKETS && _buckets.lossProbs[newBucket] != 0; newBucket++) {}
76
73
  require(newBucket < MAX_BUCKETS, "No more than 4 buckets accepted");
77
- require(
78
- lossProb > uint256(_buckets.lossProbs[newBucket - 1]),
79
- "lossProb <= last lossProb - reset instead"
80
- );
74
+ require(lossProb > uint256(_buckets.lossProbs[newBucket - 1]), "lossProb <= last lossProb - reset instead");
81
75
  }
82
76
  _buckets.lossProbs[newBucket] = lossProb.toUint64();
83
77
  _bucketParams[newBucket] = PackedParams({