@ensuro/core 1.2.7 → 2.0.0-beta10

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 (109) hide show
  1. package/README.md +63 -27
  2. package/build/contracts/AccessManager.sol/AccessManager.json +559 -0
  3. package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +219 -0
  4. package/build/contracts/EToken.sol/EToken.json +217 -190
  5. package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +17 -4
  6. package/build/contracts/{extras/IPriceRiskModule.sol/IPriceRiskModule.json → LiquidityThresholdAssetManager.sol/LiquidityThresholdAssetManager.json} +81 -131
  7. package/build/contracts/Policy.sol/Policy.json +2 -2
  8. package/build/contracts/PolicyPool.sol/PolicyPool.json +425 -295
  9. package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +15 -2
  10. package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +868 -0
  11. package/build/contracts/{BaseAssetManager.sol/BaseAssetManager.json → Reserve.sol/Reserve.json} +37 -166
  12. package/build/contracts/RiskModule.sol/RiskModule.json +85 -312
  13. package/build/contracts/SignedQuoteRiskModule.sol/SignedQuoteRiskModule.json +960 -0
  14. package/build/contracts/{DataTypes.sol/DataTypes.json → TimeScaled.sol/TimeScaled.json} +4 -4
  15. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +134 -336
  16. package/build/contracts/dependencies/ERC1967Proxy.sol/ERC1967Proxy.json +64 -0
  17. package/build/{interfaces/IExchange.sol/IExchange.json → contracts/dependencies/IERC20Metadata.sol/IERC20Metadata.json} +83 -79
  18. package/build/contracts/{WadRayMath.sol → dependencies/WadRayMath.sol}/WadRayMath.json +3 -3
  19. package/build/{interfaces/IPolicyPoolConfig.sol/IPolicyPoolConfig.json → contracts/interfaces/IAccessManager.sol/IAccessManager.json} +79 -77
  20. package/build/contracts/interfaces/IAssetManager.sol/IAssetManager.json +109 -0
  21. package/build/{interfaces → contracts/interfaces}/IEToken.sol/IEToken.json +39 -91
  22. package/build/{interfaces → contracts/interfaces}/ILPWhitelist.sol/ILPWhitelist.json +1 -1
  23. package/build/{interfaces → contracts/interfaces}/IPolicyHolder.sol/IPolicyHolder.json +1 -1
  24. package/build/{interfaces → contracts/interfaces}/IPolicyPool.sol/IPolicyPool.json +137 -100
  25. package/build/{interfaces → contracts/interfaces}/IPolicyPoolComponent.sol/IPolicyPoolComponent.json +1 -1
  26. package/build/contracts/interfaces/IPremiumsAccount.sol/IPremiumsAccount.json +315 -0
  27. package/build/{interfaces → contracts/interfaces}/IRiskModule.sol/IRiskModule.json +58 -34
  28. package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +736 -0
  29. package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +43 -0
  30. package/build/{interfaces/IInsolvencyHook.sol/IInsolvencyHook.json → contracts/mocks/IMintableERC20.sol/IMintableERC20.json} +13 -8
  31. package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +228 -0
  32. package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +35 -0
  33. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +702 -0
  34. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +92 -0
  35. package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +764 -0
  36. package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +343 -0
  37. package/build/contracts/mocks/TestNFT.sol/TestNFT.json +388 -0
  38. package/contracts/AccessManager.sol +103 -0
  39. package/contracts/ERC4626AssetManager.sol +52 -0
  40. package/contracts/EToken.sol +254 -299
  41. package/contracts/LPManualWhitelist.sol +4 -4
  42. package/contracts/LiquidityThresholdAssetManager.sol +160 -0
  43. package/contracts/Policy.sol +49 -45
  44. package/contracts/PolicyPool.sol +379 -514
  45. package/contracts/PolicyPoolComponent.sol +41 -41
  46. package/contracts/PremiumsAccount.sol +480 -0
  47. package/contracts/Reserve.sol +213 -0
  48. package/contracts/RiskModule.sol +233 -174
  49. package/contracts/SignedQuoteRiskModule.sol +241 -0
  50. package/contracts/TimeScaled.sol +138 -0
  51. package/contracts/TrustfulRiskModule.sol +85 -23
  52. package/contracts/dependencies/ERC1967Proxy.sol +19 -0
  53. package/contracts/dependencies/IERC20Metadata.sol +19 -0
  54. package/contracts/dependencies/WadRayMath.sol +126 -0
  55. package/contracts/interfaces/IAccessManager.sol +148 -0
  56. package/contracts/interfaces/IAssetManager.sol +84 -0
  57. package/contracts/interfaces/IEToken.sol +195 -0
  58. package/contracts/interfaces/ILPWhitelist.sol +40 -0
  59. package/{interfaces → contracts/interfaces}/IPolicyHolder.sol +0 -0
  60. package/contracts/interfaces/IPolicyPool.sol +145 -0
  61. package/{interfaces → contracts/interfaces}/IPolicyPoolComponent.sol +3 -0
  62. package/contracts/interfaces/IPremiumsAccount.sol +76 -0
  63. package/contracts/interfaces/IRiskModule.sol +123 -0
  64. package/contracts/mocks/FixedRateVault.sol +85 -0
  65. package/contracts/mocks/ForwardProxy.sol +66 -0
  66. package/contracts/mocks/IMintableERC20.sol +13 -0
  67. package/contracts/mocks/PolicyHolderMock.sol +89 -0
  68. package/contracts/mocks/PolicyPoolComponentMock.sol +17 -0
  69. package/contracts/mocks/PolicyPoolMock.sol +148 -0
  70. package/contracts/mocks/RiskModuleMock.sol +75 -0
  71. package/contracts/mocks/TestCurrency.sol +35 -0
  72. package/contracts/mocks/TestNFT.sol +23 -0
  73. package/js/test-utils.js +356 -0
  74. package/package.json +2 -2
  75. package/build/contracts/AaveAssetManager.sol/AaveAssetManager.json +0 -742
  76. package/build/contracts/Exchange.sol/Exchange.json +0 -591
  77. package/build/contracts/FlightDelayRiskModule.sol/FlightDelayRiskModule.json +0 -1112
  78. package/build/contracts/PolicyNFT.sol/PolicyNFT.json +0 -570
  79. package/build/contracts/PolicyPoolConfig.sol/PolicyPoolConfig.json +0 -686
  80. package/build/contracts/dependencies/ChainlinkClientUpgradeable.sol/ChainlinkClientUpgradeable.json +0 -50
  81. package/build/contracts/extras/PriceRiskModule.sol/PriceRiskModule.json +0 -1055
  82. package/build/contracts/upgraded/IPolicyNFTv1.sol/IPolicyNFTv1.json +0 -322
  83. package/build/contracts/upgraded/PolicyNFTv1.sol/PolicyNFTv1.json +0 -571
  84. package/build/contracts/upgraded/PolicyNFTv1.sol/PolicyNFTv1_Upgrade.json +0 -602
  85. package/build/interfaces/IAssetManager.sol/IAssetManager.json +0 -31
  86. package/build/interfaces/IExchange.sol/IPriceOracle.json +0 -30
  87. package/build/interfaces/IPolicyNFT.sol/IPolicyNFT.json +0 -321
  88. package/contracts/AaveAssetManager.sol +0 -298
  89. package/contracts/BaseAssetManager.sol +0 -301
  90. package/contracts/DataTypes.sol +0 -287
  91. package/contracts/Exchange.sol +0 -189
  92. package/contracts/FlightDelayRiskModule.sol +0 -208
  93. package/contracts/PolicyNFT.sol +0 -96
  94. package/contracts/PolicyPoolConfig.sol +0 -247
  95. package/contracts/WadRayMath.sol +0 -135
  96. package/contracts/dependencies/ChainlinkClientUpgradeable.sol +0 -371
  97. package/contracts/extras/IPriceRiskModule.sol +0 -41
  98. package/contracts/extras/PriceRiskModule.sol +0 -243
  99. package/contracts/upgraded/IPolicyNFTv1.sol +0 -15
  100. package/contracts/upgraded/PolicyNFTv1.sol +0 -126
  101. package/interfaces/IAssetManager.sol +0 -23
  102. package/interfaces/IEToken.sol +0 -48
  103. package/interfaces/IExchange.sol +0 -59
  104. package/interfaces/IInsolvencyHook.sol +0 -27
  105. package/interfaces/ILPWhitelist.sol +0 -23
  106. package/interfaces/IPolicyNFT.sol +0 -15
  107. package/interfaces/IPolicyPool.sol +0 -44
  108. package/interfaces/IPolicyPoolConfig.sol +0 -87
  109. package/interfaces/IRiskModule.sol +0 -29
@@ -1,12 +1,13 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  pragma solidity ^0.8.0;
3
3
 
4
- import {WadRayMath} from "./WadRayMath.sol";
5
- import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
6
- import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
4
+ import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
5
+ import {WadRayMath} from "./dependencies/WadRayMath.sol";
6
+ import {IPolicyPool} from "./interfaces/IPolicyPool.sol";
7
7
  import {PolicyPoolComponent} from "./PolicyPoolComponent.sol";
8
- import {IRiskModule} from "../interfaces/IRiskModule.sol";
9
- import {IPolicyPoolConfig} from "../interfaces/IPolicyPoolConfig.sol";
8
+ import {IRiskModule} from "./interfaces/IRiskModule.sol";
9
+ import {IPremiumsAccount} from "./interfaces/IPremiumsAccount.sol";
10
+ import {IAccessManager} from "./interfaces/IAccessManager.sol";
10
11
  import {Policy} from "./Policy.sol";
11
12
 
12
13
  /**
@@ -15,62 +16,79 @@ import {Policy} from "./Policy.sol";
15
16
  * @custom:security-contact security@ensuro.co
16
17
  * @author Ensuro
17
18
  */
18
- abstract contract RiskModule is IRiskModule, AccessControlUpgradeable, PolicyPoolComponent {
19
+ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
19
20
  using Policy for Policy.PolicyData;
20
21
  using WadRayMath for uint256;
22
+ using SafeCast for uint256;
21
23
 
22
- uint256 internal constant SECONDS_IN_YEAR_RAY = 31536000e27; /* 365 * 24 * 3600 * 10e27 */
24
+ uint256 internal constant SECONDS_IN_YEAR_WAD = 31536000e18; /* 365 * 24 * 3600 * 10e18 */
23
25
 
24
26
  // For parameters that can be changed by the risk module provider
25
27
  bytes32 public constant RM_PROVIDER_ROLE = keccak256("RM_PROVIDER_ROLE");
26
28
 
29
+ /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
30
+ IPremiumsAccount internal immutable _premiumsAccount;
31
+
27
32
  string private _name;
28
- uint256 internal _scrPercentage; // in ray - Solvency Capital Requirement percentage, to calculate
29
- // capital requirement as % of (payout - premium)
30
- uint256 internal _moc; // in ray - Margin Of Conservativism - factor that multiplies lossProb
31
- // to calculate purePremium
32
- uint256 internal _ensuroFee; // in ray - % of pure premium that will go for Ensuro treasury
33
- uint256 internal _scrInterestRate; // in ray - % of interest to charge for the SCR
34
- uint256 internal _maxScrPerPolicy; // in wad - Max SCR per policy
35
- uint256 internal _scrLimit; // in wad - Max SCR to be allocated to this module
36
- uint256 internal _totalScr; // in wad - Current SCR allocated to this module
33
+
34
+ struct PackedParams {
35
+ uint16 moc; // Margin Of Conservativism - factor that multiplies lossProb - 4 decimals
36
+ uint16 jrCollRatio; // Collateralization Ratio to compute Junior solvency as % of payout - 4 decimals
37
+ uint16 collRatio; // Collateralization Ratio to compute solvency requirement as % of payout - 4 decimals
38
+ uint16 ensuroPpFee; // % of pure premium that will go for Ensuro treasury - 4 decimals
39
+ uint16 ensuroCocFee; // % of CoC that will go for Ensuro treasury - 4 decimals
40
+ uint16 jrRoc; // Return on Capital paid to Junior LPs - Annualized Percentage - 4 decimals
41
+ uint16 srRoc; // Return on Capital paid to Senior LPs - Annualized Percentage - 4 decimals
42
+ uint32 maxPayoutPerPolicy; // Max Payout per Policy - 2 decimals
43
+ uint32 exposureLimit; // Max exposure (sum of payouts) to be allocated to this module - 0 decimals
44
+ uint16 maxDuration; // Max policy duration (in hours)
45
+ }
46
+
47
+ PackedParams internal _params;
48
+
49
+ uint256 internal _activeExposure; // in wad - Current exposure of active policies
37
50
 
38
51
  address internal _wallet; // Address of the RiskModule provider
39
52
 
40
53
  /// @custom:oz-upgrades-unsafe-allow constructor
41
- // solhint-disable-next-line no-empty-blocks
42
- constructor(IPolicyPool policyPool_) PolicyPoolComponent(policyPool_) {}
54
+ constructor(IPolicyPool policyPool_, IPremiumsAccount premiumsAccount_)
55
+ PolicyPoolComponent(policyPool_)
56
+ {
57
+ require(
58
+ PolicyPoolComponent(address(premiumsAccount_)).policyPool() == policyPool_,
59
+ "The PremiumsAccount must be part of the Pool"
60
+ );
61
+ _premiumsAccount = premiumsAccount_;
62
+ }
43
63
 
44
64
  /**
45
65
  * @dev Initializes the RiskModule
46
66
  * @param name_ Name of the Risk Module
47
- * @param scrPercentage_ Solvency Capital Requirement percentage, to calculate
48
- capital requirement as % of (payout - premium) (in ray)
49
- * @param ensuroFee_ % of pure premium that will go for Ensuro treasury (in ray)
50
- * @param scrInterestRate_ % of interest to charge for the SCR (in ray)
51
- * @param maxScrPerPolicy_ Max SCR to be allocated to this module (in wad)
52
- * @param scrLimit_ Max SCR to be allocated to this module (in wad)
67
+ * @param collRatio_ Collateralization ratio to compute solvency requirement as % of payout (in wad)
68
+ * @param ensuroPpFee_ % of pure premium that will go for Ensuro treasury (in wad)
69
+ * @param srRoc_ return on capital paid to LPs (annualized percentage - in wad)
70
+ * @param maxPayoutPerPolicy_ Maximum payout per policy (in wad)
71
+ * @param exposureLimit_ Max exposure (sum of payouts) to be allocated to this module (in wad)
53
72
  * @param wallet_ Address of the RiskModule provider
54
73
  */
55
74
  // solhint-disable-next-line func-name-mixedcase
56
75
  function __RiskModule_init(
57
76
  string memory name_,
58
- uint256 scrPercentage_,
59
- uint256 ensuroFee_,
60
- uint256 scrInterestRate_,
61
- uint256 maxScrPerPolicy_,
62
- uint256 scrLimit_,
77
+ uint256 collRatio_,
78
+ uint256 ensuroPpFee_,
79
+ uint256 srRoc_,
80
+ uint256 maxPayoutPerPolicy_,
81
+ uint256 exposureLimit_,
63
82
  address wallet_
64
83
  ) internal initializer {
65
- __AccessControl_init();
66
84
  __PolicyPoolComponent_init();
67
85
  __RiskModule_init_unchained(
68
86
  name_,
69
- scrPercentage_,
70
- ensuroFee_,
71
- scrInterestRate_,
72
- maxScrPerPolicy_,
73
- scrLimit_,
87
+ collRatio_,
88
+ ensuroPpFee_,
89
+ srRoc_,
90
+ maxPayoutPerPolicy_,
91
+ exposureLimit_,
74
92
  wallet_
75
93
  );
76
94
  }
@@ -78,40 +96,50 @@ abstract contract RiskModule is IRiskModule, AccessControlUpgradeable, PolicyPoo
78
96
  // solhint-disable-next-line func-name-mixedcase
79
97
  function __RiskModule_init_unchained(
80
98
  string memory name_,
81
- uint256 scrPercentage_,
82
- uint256 ensuroFee_,
83
- uint256 scrInterestRate_,
84
- uint256 maxScrPerPolicy_,
85
- uint256 scrLimit_,
99
+ uint256 collRatio_,
100
+ uint256 ensuroPpFee_,
101
+ uint256 srRoc_,
102
+ uint256 maxPayoutPerPolicy_,
103
+ uint256 exposureLimit_,
86
104
  address wallet_
87
105
  ) internal initializer {
88
106
  _name = name_;
89
- _scrPercentage = scrPercentage_;
90
- _moc = WadRayMath.RAY;
91
- _ensuroFee = ensuroFee_;
92
- _scrInterestRate = scrInterestRate_;
93
- _maxScrPerPolicy = maxScrPerPolicy_;
94
- _scrLimit = scrLimit_;
95
- _totalScr = 0;
107
+ _params = PackedParams({
108
+ moc: 1e4,
109
+ jrCollRatio: 0,
110
+ collRatio: _wadTo4(collRatio_),
111
+ ensuroPpFee: _wadTo4(ensuroPpFee_),
112
+ ensuroCocFee: 0,
113
+ jrRoc: 0,
114
+ srRoc: _wadTo4(srRoc_),
115
+ maxPayoutPerPolicy: _amountToX(2, maxPayoutPerPolicy_),
116
+ exposureLimit: _amountToX(0, exposureLimit_),
117
+ maxDuration: 24 * 365 // default = 1 year
118
+ });
119
+ _activeExposure = 0;
96
120
  _wallet = wallet_;
97
- _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
98
121
  _validateParameters();
99
122
  }
100
123
 
101
124
  // runs validation on RiskModule parameters
102
125
  function _validateParameters() internal view override {
126
+ require(_params.jrCollRatio <= 1e4, "Validation: jrCollRatio must be <=1");
127
+ require(_params.collRatio <= 1e4 && _params.collRatio > 0, "Validation: collRatio must be <=1");
128
+ require(_params.collRatio >= _params.jrCollRatio, "Validation: collRatio >= jrCollRatio");
129
+ require(_params.moc <= 4e4 && _params.moc >= 5e3, "Validation: moc must be [0.5, 4]");
130
+ require(_params.ensuroPpFee <= 1e4, "Validation: ensuroPpFee must be <= 1");
131
+ require(_params.ensuroCocFee <= 1e4, "Validation: ensuroCocFee must be <= 1");
132
+ require(_params.srRoc <= 1e4, "Validation: srRoc must be <= 1 (100%)");
133
+ require(_params.jrRoc <= 1e4, "Validation: jrRoc must be <= 1 (100%)");
134
+ // _maxPayoutPerPolicy no limits
103
135
  require(
104
- _scrPercentage <= WadRayMath.RAY && _scrPercentage > 0,
105
- "Validation: scrPercentage must be <=1"
136
+ exposureLimit() >= _activeExposure,
137
+ "Validation: exposureLimit can't be less than actual activeExposure"
106
138
  );
107
139
  require(
108
- _moc <= (2 * WadRayMath.RAY) && _moc >= (WadRayMath.RAY / 2),
109
- "Validation: moc must be [0.5, 2]"
140
+ _params.exposureLimit > 0 && _params.maxPayoutPerPolicy > 0,
141
+ "Exposure and MaxPayout must be >0"
110
142
  );
111
- require(_ensuroFee <= WadRayMath.RAY, "Validation: ensuroFee must be <= 1");
112
- require(_scrInterestRate <= WadRayMath.RAY, "Validation: scrInterestRate must be <= 1 (100%)");
113
- // _maxScrPerPolicy no limits
114
- require(_scrLimit >= _totalScr, "Validation: scrLimit can't be less than actual totalScr");
115
143
  require(_wallet != address(0), "Validation: Wallet can't be zero address");
116
144
  }
117
145
 
@@ -119,133 +147,123 @@ abstract contract RiskModule is IRiskModule, AccessControlUpgradeable, PolicyPoo
119
147
  return _name;
120
148
  }
121
149
 
122
- function scrPercentage() public view override returns (uint256) {
123
- return _scrPercentage;
150
+ // solhint-disable-next-line func-name-mixedcase
151
+ function _4toWad(uint16 value) internal pure returns (uint256) {
152
+ // 4 decimals to Wad (18 decimals)
153
+ return uint256(value) * 1e14;
124
154
  }
125
155
 
126
- function moc() public view override returns (uint256) {
127
- return _moc;
156
+ function _wadTo4(uint256 value) internal pure returns (uint16) {
157
+ // Wad to 4 decimals
158
+ return (value / 1e14).toUint16();
128
159
  }
129
160
 
130
- function ensuroFee() public view override returns (uint256) {
131
- return _ensuroFee;
161
+ // solhint-disable-next-line func-name-mixedcase
162
+ function _XtoAmount(uint8 decimals, uint32 value) internal view returns (uint256) {
163
+ // X decimals to Wad (18 decimals)
164
+ return uint256(value) * 10**(currency().decimals() - decimals);
132
165
  }
133
166
 
134
- function scrInterestRate() public view override returns (uint256) {
135
- return _scrInterestRate;
167
+ function _amountToX(uint8 decimals, uint256 value) internal view returns (uint32) {
168
+ // Wad to X decimals
169
+ return (value / 10**(currency().decimals() - decimals)).toUint32();
136
170
  }
137
171
 
138
- function maxScrPerPolicy() public view override returns (uint256) {
139
- return _maxScrPerPolicy;
172
+ function maxPayoutPerPolicy() public view override returns (uint256) {
173
+ return _XtoAmount(2, _params.maxPayoutPerPolicy);
140
174
  }
141
175
 
142
- function scrLimit() public view override returns (uint256) {
143
- return _scrLimit;
176
+ function exposureLimit() public view override returns (uint256) {
177
+ return _XtoAmount(0, _params.exposureLimit);
144
178
  }
145
179
 
146
- function totalScr() public view override returns (uint256) {
147
- return _totalScr;
180
+ function maxDuration() public view override returns (uint256) {
181
+ return _params.maxDuration;
148
182
  }
149
183
 
150
- function wallet() public view override returns (address) {
151
- return _wallet;
184
+ function activeExposure() public view override returns (uint256) {
185
+ return _activeExposure;
152
186
  }
153
187
 
154
- function setScrPercentage(uint256 newScrPercentage)
155
- external
156
- onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE)
157
- {
158
- bool tweak = !hasPoolRole(LEVEL2_ROLE);
159
- require(
160
- !tweak || _isTweakRay(_scrPercentage, newScrPercentage, 1e26),
161
- "Tweak exceeded: scrPercentage tweaks only up to 10%"
162
- );
163
- _scrPercentage = newScrPercentage;
164
- _parameterChanged(
165
- IPolicyPoolConfig.GovernanceActions.setScrPercentage,
166
- newScrPercentage,
167
- tweak
168
- );
169
- }
170
-
171
- function setMoc(uint256 newMoc) external onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE) {
172
- bool tweak = !hasPoolRole(LEVEL2_ROLE);
173
- require(!tweak || _isTweakRay(_moc, newMoc, 1e26), "Tweak exceeded: moc tweaks only up to 10%");
174
- _moc = newMoc;
175
- _parameterChanged(IPolicyPoolConfig.GovernanceActions.setMoc, newMoc, tweak);
176
- }
177
-
178
- function setScrInterestRate(uint256 newScrInterestRate)
179
- external
180
- onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE)
181
- {
182
- bool tweak = !hasPoolRole(LEVEL2_ROLE);
183
- require(
184
- !tweak || _isTweakRay(_scrInterestRate, newScrInterestRate, 3e26),
185
- "Tweak exceeded: scrInterestRate tweaks only up to 30%"
186
- );
187
- _scrInterestRate = newScrInterestRate;
188
- _parameterChanged(
189
- IPolicyPoolConfig.GovernanceActions.setScrInterestRate,
190
- newScrInterestRate,
191
- tweak
192
- );
193
- }
194
-
195
- function setEnsuroFee(uint256 newEnsuroFee) external onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE) {
196
- bool tweak = !hasPoolRole(LEVEL2_ROLE);
197
- require(
198
- !tweak || _isTweakRay(_ensuroFee, newEnsuroFee, 3e26),
199
- "Tweak exceeded: ensuroFee tweaks only up to 30%"
200
- );
201
- _ensuroFee = newEnsuroFee;
202
- _parameterChanged(IPolicyPoolConfig.GovernanceActions.setEnsuroFee, newEnsuroFee, tweak);
188
+ function wallet() public view override returns (address) {
189
+ return _wallet;
203
190
  }
204
191
 
205
- function setMaxScrPerPolicy(uint256 newMaxScrPerPolicy)
192
+ function setParam(Parameter param, uint256 newValue)
206
193
  external
207
- onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE)
194
+ onlyGlobalOrComponentRole3(LEVEL1_ROLE, LEVEL2_ROLE, LEVEL3_ROLE)
208
195
  {
209
- bool tweak = !hasPoolRole(LEVEL2_ROLE);
210
- require(
211
- !tweak || _isTweakWad(_maxScrPerPolicy, newMaxScrPerPolicy, 3e17),
212
- "Tweak exceeded: maxScrPerPolicy tweaks only up to 30%"
213
- );
214
- _maxScrPerPolicy = newMaxScrPerPolicy;
196
+ bool tweak = !hasPoolRole(LEVEL2_ROLE) && !hasPoolRole(LEVEL1_ROLE);
197
+ if (param == Parameter.moc) {
198
+ require(!tweak || _isTweakWad(_4toWad(_params.moc), newValue, 1e17), "Tweak exceeded");
199
+ _params.moc = _wadTo4(newValue);
200
+ } else if (param == Parameter.jrCollRatio) {
201
+ require(
202
+ !tweak || _isTweakWad(_4toWad(_params.jrCollRatio), newValue, 1e17),
203
+ "Tweak exceeded"
204
+ );
205
+ _params.jrCollRatio = _wadTo4(newValue);
206
+ } else if (param == Parameter.collRatio) {
207
+ require(!tweak || _isTweakWad(_4toWad(_params.collRatio), newValue, 1e17), "Tweak exceeded");
208
+ _params.collRatio = _wadTo4(newValue);
209
+ } else if (param == Parameter.ensuroPpFee) {
210
+ require(
211
+ !tweak || _isTweakWad(_4toWad(_params.ensuroPpFee), newValue, 1e17),
212
+ "Tweak exceeded"
213
+ );
214
+ _params.ensuroPpFee = _wadTo4(newValue);
215
+ } else if (param == Parameter.ensuroCocFee) {
216
+ require(
217
+ !tweak || _isTweakWad(_4toWad(_params.ensuroCocFee), newValue, 1e17),
218
+ "Tweak exceeded"
219
+ );
220
+ _params.ensuroCocFee = _wadTo4(newValue);
221
+ } else if (param == Parameter.jrRoc) {
222
+ require(!tweak || _isTweakWad(_4toWad(_params.jrRoc), newValue, 1e17), "Tweak exceeded");
223
+ _params.jrRoc = _wadTo4(newValue);
224
+ } else if (param == Parameter.srRoc) {
225
+ require(!tweak || _isTweakWad(_4toWad(_params.srRoc), newValue, 1e17), "Tweak exceeded");
226
+ _params.srRoc = _wadTo4(newValue);
227
+ } else if (param == Parameter.maxPayoutPerPolicy) {
228
+ require(!tweak || _isTweakWad(maxPayoutPerPolicy(), newValue, 1e17), "Tweak exceeded");
229
+ _params.maxPayoutPerPolicy = _amountToX(2, newValue);
230
+ } else if (param == Parameter.exposureLimit) {
231
+ require(newValue >= _activeExposure, "Can't set exposureLimit less than active exposure");
232
+ require(!tweak || _isTweakWad(exposureLimit(), newValue, 1e17), "Tweak exceeded");
233
+ require(
234
+ newValue <= exposureLimit() || hasPoolRole(LEVEL1_ROLE),
235
+ "Tweak exceeded: Increase requires LEVEL1_ROLE"
236
+ );
237
+ _params.exposureLimit = _amountToX(0, newValue);
238
+ } else if (param == Parameter.maxDuration) {
239
+ require(!tweak, "Tweak exceeded");
240
+ _params.maxDuration = newValue.toUint16();
241
+ }
215
242
  _parameterChanged(
216
- IPolicyPoolConfig.GovernanceActions.setMaxScrPerPolicy,
217
- newMaxScrPerPolicy,
243
+ IAccessManager.GovernanceActions(
244
+ uint256(IAccessManager.GovernanceActions.setMoc) + uint256(param)
245
+ ),
246
+ newValue,
218
247
  tweak
219
248
  );
220
249
  }
221
250
 
222
- function setScrLimit(uint256 newScrLimit)
223
- external
224
- onlyPoolRole3(LEVEL1_ROLE, LEVEL2_ROLE, LEVEL3_ROLE)
225
- {
226
- bool tweak = !hasPoolRole(LEVEL2_ROLE) && !hasPoolRole(LEVEL1_ROLE);
227
- require(
228
- !tweak || _isTweakWad(_scrLimit, newScrLimit, 1e17),
229
- "Tweak exceeded: scrLimit tweaks only up to 10%"
230
- );
231
- require(
232
- newScrLimit <= _scrLimit ||
233
- hasPoolRole(LEVEL1_ROLE) ||
234
- _policyPool.totalETokenSupply().wadMul(1e17) > newScrLimit,
235
- "Tweak exceeded: Increase, >=10% of the total liquidity, requires LEVEL1_ROLE"
236
- );
237
- require(newScrLimit >= _totalScr, "Can't set SCR less than current SCR allocation");
238
- _scrLimit = newScrLimit;
239
- _parameterChanged(IPolicyPoolConfig.GovernanceActions.setScrLimit, newScrLimit, tweak);
251
+ function params() public view override returns (Params memory ret) {
252
+ return
253
+ Params({
254
+ moc: _4toWad(_params.moc),
255
+ jrCollRatio: _4toWad(_params.jrCollRatio),
256
+ collRatio: _4toWad(_params.collRatio),
257
+ ensuroPpFee: _4toWad(_params.ensuroPpFee),
258
+ ensuroCocFee: _4toWad(_params.ensuroCocFee),
259
+ jrRoc: _4toWad(_params.jrRoc),
260
+ srRoc: _4toWad(_params.srRoc)
261
+ });
240
262
  }
241
263
 
242
- function setWallet(address wallet_) external onlyRole(RM_PROVIDER_ROLE) {
264
+ function setWallet(address wallet_) external onlyComponentRole(RM_PROVIDER_ROLE) {
243
265
  _wallet = wallet_;
244
- _parameterChanged(
245
- IPolicyPoolConfig.GovernanceActions.setWallet,
246
- uint256(uint160(wallet_)),
247
- false
248
- );
266
+ _parameterChanged(IAccessManager.GovernanceActions.setWallet, uint256(uint160(wallet_)), false);
249
267
  }
250
268
 
251
269
  function getMinimumPremium(
@@ -253,50 +271,91 @@ abstract contract RiskModule is IRiskModule, AccessControlUpgradeable, PolicyPoo
253
271
  uint256 lossProb,
254
272
  uint40 expiration
255
273
  ) public view returns (uint256) {
256
- uint256 purePremium = payout.wadToRay().rayMul(lossProb.rayMul(moc())).rayToWad();
257
- uint256 scr = payout.wadMul(scrPercentage().rayToWad()) - purePremium;
258
- uint256 interestRate = (
259
- (scrInterestRate() * (expiration - block.timestamp)).rayDiv(SECONDS_IN_YEAR_RAY)
260
- ).rayToWad();
261
- uint256 premiumForLps = scr.wadMul(interestRate);
262
- uint256 premiumForEnsuro = (purePremium + premiumForLps).wadMul(ensuroFee().rayToWad());
263
- return purePremium + premiumForEnsuro + premiumForLps;
274
+ Params memory p = params();
275
+ uint256 purePremium = payout.wadMul(lossProb.wadMul(p.moc));
276
+ uint256 jrScr = payout.wadMul(p.jrCollRatio);
277
+ if (jrScr > purePremium) {
278
+ jrScr -= purePremium;
279
+ } else {
280
+ jrScr = 0;
281
+ }
282
+ uint256 srScr = payout.wadMul(p.collRatio);
283
+ if (srScr > (purePremium + jrScr)) {
284
+ srScr -= purePremium + jrScr;
285
+ } else {
286
+ srScr = 0;
287
+ }
288
+ uint256 jrCoc = jrScr.wadMul(
289
+ (p.jrRoc * (expiration - block.timestamp)).wadDiv(SECONDS_IN_YEAR_WAD)
290
+ );
291
+ uint256 srCoc = srScr.wadMul(
292
+ (p.srRoc * (expiration - block.timestamp)).wadDiv(SECONDS_IN_YEAR_WAD)
293
+ );
294
+ uint256 ensuroCommission = purePremium.wadMul(p.ensuroPpFee) +
295
+ (jrCoc + srCoc).wadMul(p.ensuroCocFee);
296
+ return purePremium + ensuroCommission + (jrCoc + srCoc);
264
297
  }
265
298
 
299
+ /**
300
+ * @dev Called from child contracts to create policies (after they validated the pricing)
301
+ *
302
+ * @param payout The exposure (maximum payout) of the policy
303
+ * @param premium The premium that will be paid by the policyHolder
304
+ * @param lossProb The probability of having to pay the maximum payout (wad)
305
+ * @param payer The account that pays for the premium
306
+ * @param expiration The expiration of the policy (timestamp)
307
+ * @param onBehalfOf The policy holder
308
+ * @param internalId An id that's unique within this module and it will be used to identify the policy
309
+ */
266
310
  function _newPolicy(
267
311
  uint256 payout,
268
312
  uint256 premium,
269
313
  uint256 lossProb,
270
314
  uint40 expiration,
271
- address customer,
315
+ address payer,
316
+ address onBehalfOf,
272
317
  uint96 internalId
273
318
  ) internal whenNotPaused returns (Policy.PolicyData memory) {
319
+ if (premium == type(uint256).max) {
320
+ premium = getMinimumPremium(payout, lossProb, expiration);
321
+ }
274
322
  require(premium < payout, "Premium must be less than payout");
275
- require(expiration > uint40(block.timestamp), "Expiration must be in the future");
276
- require(customer != address(0), "Customer can't be zero address");
323
+ uint40 now_ = uint40(block.timestamp);
324
+ require(expiration > now_, "Expiration must be in the future");
325
+ require(((expiration - now_) / 3600) < _params.maxDuration, "Policy exceeds max duration");
326
+ require(onBehalfOf != address(0), "Customer can't be zero address");
277
327
  require(
278
- _policyPool.currency().allowance(customer, address(_policyPool)) >= premium,
328
+ _policyPool.currency().allowance(payer, address(_policyPool)) >= premium,
279
329
  "You must allow ENSURO to transfer the premium"
280
330
  );
331
+ require(
332
+ payer == _msgSender() || _policyPool.currency().allowance(payer, _msgSender()) >= premium,
333
+ "Payer must allow caller to transfer the premium"
334
+ );
335
+ require(payout <= maxPayoutPerPolicy(), "RiskModule: Payout is more than maximum per policy");
281
336
  Policy.PolicyData memory policy = Policy.initialize(
282
337
  this,
338
+ params(),
283
339
  premium,
284
340
  payout,
285
341
  lossProb,
286
342
  expiration
287
343
  );
288
- require(policy.scr <= _maxScrPerPolicy, "RiskModule: SCR is more than maximum per policy");
289
- _totalScr += policy.scr;
290
- require(_totalScr <= _scrLimit, "RiskModule: SCR limit exceeded");
291
- uint256 policyId = _policyPool.newPolicy(policy, customer, internalId);
344
+ _activeExposure += policy.payout;
345
+ require(_activeExposure <= exposureLimit(), "RiskModule: Exposure limit exceeded");
346
+ uint256 policyId = _policyPool.newPolicy(policy, payer, onBehalfOf, internalId);
292
347
  policy.id = policyId;
293
348
  return policy;
294
349
  }
295
350
 
296
- function releaseScr(uint256 scrAmount) external override onlyPolicyPool {
351
+ function releaseExposure(uint256 payout) external override onlyPolicyPool {
297
352
  // In the Python protype this function is called `remove_policy` and receives
298
353
  // all the policy. Since we just need the amount, for performance reasons
299
- // we just send the amount and the method is called releaseScr
300
- _totalScr -= scrAmount;
354
+ // we just send the amount and the method is called releaseExposure
355
+ _activeExposure -= payout;
356
+ }
357
+
358
+ function premiumsAccount() external view override returns (IPremiumsAccount) {
359
+ return _premiumsAccount;
301
360
  }
302
361
  }