@ensuro/core 2.0.0-beta8 → 2.0.0-beta9

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 (50) hide show
  1. package/README.md +17 -14
  2. package/build/contracts/AccessManager.sol/AccessManager.json +2 -2
  3. package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +9 -3
  4. package/build/contracts/EToken.sol/EToken.json +2 -15
  5. package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +2 -2
  6. package/build/contracts/LiquidityThresholdAssetManager.sol/LiquidityThresholdAssetManager.json +7 -1
  7. package/build/contracts/Policy.sol/Policy.json +2 -2
  8. package/build/contracts/PolicyPool.sol/PolicyPool.json +21 -2
  9. package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +2 -15
  10. package/build/contracts/Reserve.sol/Reserve.json +0 -13
  11. package/build/contracts/TimeScaled.sol/TimeScaled.json +3 -17
  12. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +2 -2
  13. package/build/contracts/{WadRayMath.sol → dependencies/WadRayMath.sol}/WadRayMath.json +3 -3
  14. package/build/contracts/interfaces/IAssetManager.sol/IAssetManager.json +7 -1
  15. package/build/contracts/interfaces/IPolicyPool.sol/IPolicyPool.json +19 -0
  16. package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +2 -2
  17. package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +2 -2
  18. package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +28 -2
  19. package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +2 -2
  20. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +96 -2
  21. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +2 -2
  22. package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +92 -2
  23. package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +2 -2
  24. package/build/contracts/mocks/TestNFT.sol/TestNFT.json +2 -2
  25. package/contracts/AccessManager.sol +1 -1
  26. package/contracts/ERC4626AssetManager.sol +5 -2
  27. package/contracts/EToken.sol +43 -44
  28. package/contracts/LiquidityThresholdAssetManager.sol +11 -10
  29. package/contracts/Policy.sol +1 -1
  30. package/contracts/PolicyPool.sol +152 -19
  31. package/contracts/PolicyPoolComponent.sol +7 -22
  32. package/contracts/PremiumsAccount.sol +159 -19
  33. package/contracts/Reserve.sol +112 -17
  34. package/contracts/RiskModule.sol +8 -8
  35. package/contracts/TimeScaled.sol +19 -15
  36. package/contracts/TrustfulRiskModule.sol +3 -3
  37. package/contracts/dependencies/WadRayMath.sol +126 -0
  38. package/contracts/interfaces/IAccessManager.sol +68 -13
  39. package/contracts/interfaces/IAssetManager.sol +63 -1
  40. package/contracts/interfaces/IEToken.sol +4 -1
  41. package/contracts/interfaces/ILPWhitelist.sol +17 -0
  42. package/contracts/interfaces/IPolicyPool.sol +7 -0
  43. package/contracts/interfaces/IPolicyPoolComponent.sol +3 -0
  44. package/contracts/interfaces/IRiskModule.sol +67 -4
  45. package/contracts/mocks/PolicyHolderMock.sol +21 -0
  46. package/contracts/mocks/PolicyPoolMock.sol +27 -0
  47. package/contracts/mocks/RiskModuleMock.sol +7 -1
  48. package/js/test-utils.js +49 -36
  49. package/package.json +1 -1
  50. package/contracts/WadRayMath.sol +0 -135
@@ -2,7 +2,8 @@
2
2
 
3
3
  pragma solidity ^0.8.0;
4
4
 
5
- import {WadRayMath} from "./WadRayMath.sol";
5
+ import {WadRayMath} from "./dependencies/WadRayMath.sol";
6
+ import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
6
7
 
7
8
  /**
8
9
  * @title TimeScaled
@@ -12,13 +13,15 @@ import {WadRayMath} from "./WadRayMath.sol";
12
13
  */
13
14
  library TimeScaled {
14
15
  using WadRayMath for uint256;
16
+ using SafeCast for uint256;
15
17
 
16
- uint256 internal constant SECONDS_PER_YEAR = 365 days;
17
- uint128 public constant MIN_SCALE = 1e17; // 0.0000000001 == 1e-10 in ray
18
+ uint256 private constant SECONDS_PER_YEAR = 365 days;
19
+ uint112 private constant MIN_SCALE = 1e17; // 0.0000000001 == 1e-10 in ray
20
+ uint112 private constant RAY112 = 1e27;
18
21
 
19
22
  struct ScaledAmount {
20
- uint128 scale;
21
- uint96 amount;
23
+ uint112 scale;
24
+ uint112 amount;
22
25
  uint32 lastUpdate;
23
26
  }
24
27
 
@@ -27,7 +30,7 @@ library TimeScaled {
27
30
  if (scaledAmount.amount == 0) {
28
31
  scaledAmount.lastUpdate = uint32(block.timestamp);
29
32
  } else {
30
- scaledAmount.scale = uint128(getScale(scaledAmount, interestRate));
33
+ scaledAmount.scale = getScale(scaledAmount, interestRate).toUint112();
31
34
  scaledAmount.lastUpdate = uint32(block.timestamp);
32
35
  }
33
36
  }
@@ -44,7 +47,7 @@ library TimeScaled {
44
47
  uint256 timeDifference = uint256(now_ - scaledAmount.lastUpdate);
45
48
  return
46
49
  uint256(scaledAmount.scale).rayMul(
47
- ((interestRate.wadToRay() * timeDifference) / SECONDS_PER_YEAR) + WadRayMath.ray()
50
+ ((interestRate.wadToRay() * timeDifference) / SECONDS_PER_YEAR) + WadRayMath.RAY
48
51
  );
49
52
  }
50
53
 
@@ -61,7 +64,7 @@ library TimeScaled {
61
64
  }
62
65
 
63
66
  function init(ScaledAmount storage scaledAmount) internal {
64
- scaledAmount.scale = uint128(WadRayMath.ray());
67
+ scaledAmount.scale = RAY112;
65
68
  scaledAmount.amount = 0;
66
69
  scaledAmount.lastUpdate = uint32(block.timestamp);
67
70
  }
@@ -89,7 +92,7 @@ library TimeScaled {
89
92
  ) internal returns (uint256) {
90
93
  updateScale(scaledAmount, interestRate);
91
94
  uint256 scaledAdd = scaleAmount(scaledAmount, amount);
92
- scaledAmount.amount += uint96(scaledAdd);
95
+ scaledAmount.amount += scaledAdd.toUint96();
93
96
  return scaledAdd;
94
97
  }
95
98
 
@@ -100,10 +103,10 @@ library TimeScaled {
100
103
  ) internal returns (uint256) {
101
104
  updateScale(scaledAmount, interestRate);
102
105
  uint256 scaledSub = scaleAmount(scaledAmount, amount);
103
- scaledAmount.amount -= uint96(scaledSub);
106
+ scaledAmount.amount -= scaledSub.toUint96();
104
107
  if (scaledAmount.amount == 0) {
105
108
  // Reset scale if amount == 0
106
- scaledAmount.scale = uint128(WadRayMath.ray());
109
+ scaledAmount.scale = RAY112;
107
110
  }
108
111
  return scaledSub;
109
112
  }
@@ -115,9 +118,10 @@ library TimeScaled {
115
118
  ) internal {
116
119
  updateScale(scaledAmount, interestRate);
117
120
  uint256 newScaledAmount = uint256(int256(getScaledAmount(scaledAmount, interestRate)) + amount);
118
- scaledAmount.scale = uint128(
119
- newScaledAmount.wadToRay().rayDiv(uint256(scaledAmount.amount).wadToRay())
120
- );
121
+ scaledAmount.scale = newScaledAmount
122
+ .wadToRay()
123
+ .rayDiv(uint256(scaledAmount.amount).wadToRay())
124
+ .toUint112();
121
125
  require(scaledAmount.scale >= MIN_SCALE, "Scale too small, can lead to rounding errors");
122
126
  }
123
127
 
@@ -127,7 +131,7 @@ library TimeScaled {
127
131
  returns (uint256)
128
132
  {
129
133
  uint256 ts = getScaledAmount(scaledAmount, interestRate);
130
- uint256 minTs = uint256(scaledAmount.amount).wadToRay().rayMul(MIN_SCALE * 10).rayToWad();
134
+ uint256 minTs = uint256(scaledAmount.amount).wadToRay().rayMul(MIN_SCALE).rayToWad();
131
135
  if (ts > minTs) return ts - minTs;
132
136
  else return 0;
133
137
  }
@@ -63,9 +63,9 @@ contract TrustfulRiskModule is RiskModule {
63
63
  uint96 internalId
64
64
  ) external onlyComponentRole(PRICER_ROLE) returns (uint256) {
65
65
  address payer = onBehalfOf;
66
- if (payer != msg.sender && _policyPool.currency().allowance(payer, msg.sender) < premium)
66
+ if (payer != _msgSender() && _policyPool.currency().allowance(payer, _msgSender()) < premium)
67
67
  /**
68
- * The standard is the payer should be the msg.sender but usually, in this type of module,
68
+ * The standard is the payer should be the _msgSender() but usually, in this type of module,
69
69
  * the sender is an operative account managed by software, where the onBehalfOf is a more
70
70
  * secure account (hardware wallet) that does the cash movements.
71
71
  * This non standard behaviour allows for a more secure setup, where the sender never manages
@@ -75,7 +75,7 @@ contract TrustfulRiskModule is RiskModule {
75
75
  * Note that this allowance won't be spent, so it can be set as the maximum amount of a single
76
76
  * premium even for multiple policies.
77
77
  */
78
- payer = msg.sender;
78
+ payer = _msgSender();
79
79
 
80
80
  return _newPolicy(payout, premium, lossProb, expiration, payer, onBehalfOf, internalId).id;
81
81
  }
@@ -0,0 +1,126 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.0;
3
+
4
+ /**
5
+ * @title WadRayMath library
6
+ * @author Aave
7
+ * @notice Provides functions to perform calculations with Wad and Ray units
8
+ * @dev Provides mul and div function for wads (decimal numbers with 18 digits of precision) and rays (decimal numbers
9
+ * with 27 digits of precision)
10
+ * @dev Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down.
11
+ **/
12
+ library WadRayMath {
13
+ // HALF_WAD and HALF_RAY expressed with extended notation as constant with operations are not supported in Yul assembly
14
+ uint256 internal constant WAD = 1e18;
15
+ uint256 internal constant HALF_WAD = 0.5e18;
16
+
17
+ uint256 internal constant RAY = 1e27;
18
+ uint256 internal constant HALF_RAY = 0.5e27;
19
+
20
+ uint256 internal constant WAD_RAY_RATIO = 1e9;
21
+
22
+ /**
23
+ * @dev Multiplies two wad, rounding half up to the nearest wad
24
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
25
+ * @param a Wad
26
+ * @param b Wad
27
+ * @return c = a*b, in wad
28
+ **/
29
+ function wadMul(uint256 a, uint256 b) internal pure returns (uint256 c) {
30
+ // to avoid overflow, a <= (type(uint256).max - HALF_WAD) / b
31
+ assembly {
32
+ if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_WAD), b))))) {
33
+ revert(0, 0)
34
+ }
35
+
36
+ c := div(add(mul(a, b), HALF_WAD), WAD)
37
+ }
38
+ }
39
+
40
+ /**
41
+ * @dev Divides two wad, rounding half up to the nearest wad
42
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
43
+ * @param a Wad
44
+ * @param b Wad
45
+ * @return c = a/b, in wad
46
+ **/
47
+ function wadDiv(uint256 a, uint256 b) internal pure returns (uint256 c) {
48
+ // to avoid overflow, a <= (type(uint256).max - halfB) / WAD
49
+ assembly {
50
+ if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), WAD))))) {
51
+ revert(0, 0)
52
+ }
53
+
54
+ c := div(add(mul(a, WAD), div(b, 2)), b)
55
+ }
56
+ }
57
+
58
+ /**
59
+ * @notice Multiplies two ray, rounding half up to the nearest ray
60
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
61
+ * @param a Ray
62
+ * @param b Ray
63
+ * @return c = a raymul b
64
+ **/
65
+ function rayMul(uint256 a, uint256 b) internal pure returns (uint256 c) {
66
+ // to avoid overflow, a <= (type(uint256).max - HALF_RAY) / b
67
+ assembly {
68
+ if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_RAY), b))))) {
69
+ revert(0, 0)
70
+ }
71
+
72
+ c := div(add(mul(a, b), HALF_RAY), RAY)
73
+ }
74
+ }
75
+
76
+ /**
77
+ * @notice Divides two ray, rounding half up to the nearest ray
78
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
79
+ * @param a Ray
80
+ * @param b Ray
81
+ * @return c = a raydiv b
82
+ **/
83
+ function rayDiv(uint256 a, uint256 b) internal pure returns (uint256 c) {
84
+ // to avoid overflow, a <= (type(uint256).max - halfB) / RAY
85
+ assembly {
86
+ if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), RAY))))) {
87
+ revert(0, 0)
88
+ }
89
+
90
+ c := div(add(mul(a, RAY), div(b, 2)), b)
91
+ }
92
+ }
93
+
94
+ /**
95
+ * @dev Casts ray down to wad
96
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
97
+ * @param a Ray
98
+ * @return b = a converted to wad, rounded half up to the nearest wad
99
+ **/
100
+ function rayToWad(uint256 a) internal pure returns (uint256 b) {
101
+ assembly {
102
+ b := div(a, WAD_RAY_RATIO)
103
+ let remainder := mod(a, WAD_RAY_RATIO)
104
+ if iszero(lt(remainder, div(WAD_RAY_RATIO, 2))) {
105
+ b := add(b, 1)
106
+ }
107
+ }
108
+ }
109
+
110
+ /**
111
+ * @dev Converts wad up to ray
112
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
113
+ * @param a Wad
114
+ * @return b = a converted in ray
115
+ **/
116
+ function wadToRay(uint256 a) internal pure returns (uint256 b) {
117
+ // to avoid overflow, b/WAD_RAY_RATIO == a
118
+ assembly {
119
+ b := mul(a, WAD_RAY_RATIO)
120
+
121
+ if iszero(eq(div(b, WAD_RAY_RATIO), a)) {
122
+ revert(0, 0)
123
+ }
124
+ }
125
+ }
126
+ }
@@ -9,18 +9,20 @@ import {IAccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/acc
9
9
  * @author Ensuro
10
10
  */
11
11
  interface IAccessManager is IAccessControlUpgradeable {
12
+ /**
13
+ * @dev Enum with the different governance actions supported in the protocol.
14
+ * It's good to keep actions of the same component consecutive, parts of the code relay on that,
15
+ * so we put some fillers in case new actions are added.
16
+ */
12
17
  enum GovernanceActions {
13
18
  none,
14
19
  setTreasury, // Changes PolicyPool treasury address
15
20
  setAssetManager, // Change in the asset manager strategy of a reserve
16
- setInsolvencyHook, // Changes PolicyPool InsolvencyHook
17
- setLPWhitelist, // Changes PolicyPool Liquidity Providers Whitelist
18
- addRiskModule,
19
- removeRiskModule,
20
21
  setAssetManagerForced, // Change in the asset manager strategy of a reserve, forced (deinvest failed)
21
- cfgFiller2, // Reserve space for future PolicyPoolConfig actions
22
- cfgFiller3, // Reserve space for future PolicyPoolConfig actions
23
- cfgFiller4, // Reserve space for future PolicyPoolConfig actions
22
+ ppFiller1, // Reserve space for future PolicyPool or AccessManager actions
23
+ ppFiller2, // Reserve space for future PolicyPool or AccessManager actions
24
+ ppFiller3, // Reserve space for future PolicyPool or AccessManager actions
25
+ ppFiller4, // Reserve space for future PolicyPool or AccessManager actions
24
26
  // RiskModule Governance Actions
25
27
  setMoc,
26
28
  setJrCollRatio,
@@ -38,6 +40,7 @@ interface IAccessManager is IAccessControlUpgradeable {
38
40
  rmFiller3, // Reserve space for future RM actions
39
41
  rmFiller4, // Reserve space for future RM actions
40
42
  // EToken Governance Actions
43
+ setLPWhitelist, // Changes EToken Liquidity Providers Whitelist
41
44
  setLiquidityRequirement,
42
45
  setMinUtilizationRate,
43
46
  setMaxUtilizationRate,
@@ -46,21 +49,43 @@ interface IAccessManager is IAccessControlUpgradeable {
46
49
  etkFiller2, // Reserve space for future EToken actions
47
50
  etkFiller3, // Reserve space for future EToken actions
48
51
  etkFiller4, // Reserve space for future EToken actions
52
+ // PremiumsAccount Governance Actions
53
+ setDeficitRatio,
54
+ setDeficitRatioWithAdjustment,
55
+ paFiller1,
56
+ paFiller2,
57
+ paFiller3,
58
+ paFiller4,
49
59
  // AssetManager Governance Actions
50
60
  setLiquidityMin,
51
61
  setLiquidityMiddle,
52
62
  setLiquidityMax,
53
- // AaveAssetManager Governance Actions
54
- setClaimRewardsMin,
55
- setReinvestRewardsMin,
56
- setMaxSlippage,
57
- setPriceOracle, // Changes exchange's PriceOracle
58
- setSwapRouter, // Changes exchange's SwapRouter
63
+ amFiller1, // Reserve space for future Asset Manager actions
64
+ amFiller2, // Reserve space for future Asset Manager actions
65
+ amFiller3, // Reserve space for future Asset Manager actions
66
+ amFiller4, // Reserve space for future Asset Manager actions
59
67
  last
60
68
  }
61
69
 
70
+ /**
71
+ * @dev Gets a role identifier mixing the hash of the global role and the address of the component
72
+ *
73
+ * @param component The component where this role will apply
74
+ * @param role A role such as `keccak256("LEVEL1_ROLE")` that's global
75
+ * @return A new role, mixing (XOR) the component address and the role.
76
+ */
62
77
  function getComponentRole(address component, bytes32 role) external view returns (bytes32);
63
78
 
79
+ /**
80
+ * @dev Tells if a user has been granted a given role for a component
81
+ *
82
+ * @param component The component where this role will apply
83
+ * @param role A role such as `keccak256("LEVEL1_ROLE")` that's global
84
+ * @param account The user address for who we want to verify the permission
85
+ * @param alsoGlobal If true, it will return if the users has either the component role, or the role itself.
86
+ * If false, only the component role is accepted
87
+ * @return Whether the user has or not any of the roles
88
+ */
64
89
  function hasComponentRole(
65
90
  address component,
66
91
  bytes32 role,
@@ -68,14 +93,35 @@ interface IAccessManager is IAccessControlUpgradeable {
68
93
  bool alsoGlobal
69
94
  ) external view returns (bool);
70
95
 
96
+ /**
97
+ * @dev Checks if a user has been granted a given role and reverts if it doesn't
98
+ *
99
+ * @param role A role such as `keccak256("LEVEL1_ROLE")` that's global
100
+ * @param account The user address for who we want to verify the permission
101
+ */
71
102
  function checkRole(bytes32 role, address account) external view;
72
103
 
104
+ /**
105
+ * @dev Checks if a user has been granted any of the two roles specified and reverts if it doesn't
106
+ *
107
+ * @param role1 A role such as `keccak256("LEVEL1_ROLE")` that's global
108
+ * @param role2 Another role such as `keccak256("GUARDIAN_ROLE")` that's global
109
+ * @param account The user address for who we want to verify the permission
110
+ */
73
111
  function checkRole2(
74
112
  bytes32 role1,
75
113
  bytes32 role2,
76
114
  address account
77
115
  ) external view;
78
116
 
117
+ /**
118
+ * @dev Checks if a user has been granted a given component role and reverts if it doesn't
119
+ *
120
+ * @param role A role such as `keccak256("LEVEL1_ROLE")` that's global
121
+ * @param account The user address for who we want to verify the permission
122
+ * @param alsoGlobal If true, it will accept not only the component role, but also the (global) `role` itself.
123
+ * If false, only the component role is accepted
124
+ */
79
125
  function checkComponentRole(
80
126
  address component,
81
127
  bytes32 role,
@@ -83,6 +129,15 @@ interface IAccessManager is IAccessControlUpgradeable {
83
129
  bool alsoGlobal
84
130
  ) external view;
85
131
 
132
+ /**
133
+ * @dev Checks if a user has been granted any of the two component roles specified and reverts if it doesn't
134
+ *
135
+ * @param role1 A role such as `keccak256("LEVEL1_ROLE")` that's global
136
+ * @param role2 Another role such as `keccak256("GUARDIAN_ROLE")` that's global
137
+ * @param account The user address for who we want to verify the permission
138
+ * @param alsoGlobal If true, it will accept not only the component roles, but also the global ones.
139
+ * If false, only the component roles are accepted
140
+ */
86
141
  function checkComponentRole2(
87
142
  address component,
88
143
  bytes32 role1,
@@ -3,20 +3,82 @@ pragma solidity ^0.8.0;
3
3
 
4
4
  /**
5
5
  * @title IAssetManager - Interface of the asset management strategy that's plugged into the reserves
6
+ * @dev The asset manager is a contract that's plugged and called with `delegatecall` (operates in the context of the
7
+ * reserve - see {Reserve}). The asset manager contract applies a strategy to invest the reserve funds and
8
+ * get additional yields.
6
9
  * @author Ensuro
7
10
  */
8
11
  interface IAssetManager {
12
+ /**
13
+ * @dev Event emitted when funds are removed from Reserve liquidity and invested in the investment strategy,
14
+ * @param amount The amount invested
15
+ */
9
16
  event MoneyInvested(uint256 amount);
17
+
18
+ /**
19
+ * @dev Event emitted when funds are deinvested from the investment strategy and returned to the reserve as liquid
20
+ * funds.
21
+ *
22
+ * @param amount The amount de-invested
23
+ */
10
24
  event MoneyDeinvested(uint256 amount);
25
+
26
+ /**
27
+ * @dev Event emitted when investment yields are accounted in the reserve
28
+ *
29
+ * @param earnings The amount of earnings generated since last record. It's positive in the case of earnings or
30
+ * negative when there are losses.
31
+ */
11
32
  event EarningsRecorded(int256 earnings);
12
33
 
34
+ /**
35
+ * @dev Function called when an asset manager is plugged into a reserve. Useful for initialization tasks
36
+ */
13
37
  function connect() external;
14
38
 
39
+ /**
40
+ * @dev Gives the opportunity to the asset manager to rebalance the funds between those that are kept liquid in the
41
+ * reserve balance and those that are invested. Called with delegatecall by the reserve from the external function
42
+ * rebalance (see {Reserve-rebalance}).
43
+ *
44
+ * Events:
45
+ * - Emits {MoneyInvested} or {MoneyDeinvested}
46
+ */
15
47
  function rebalance() external;
16
48
 
49
+ /**
50
+ * @dev Gives the opportunity to the asset manager to rebalance the funds between those that are kept liquid in the
51
+ * reserve balance and those that are invested. Called with delegatecall by the reserve from the external function
52
+ * rebalance (see {Reserve-rebalance}).
53
+ *
54
+ * Events:
55
+ * - Emits {MoneyInvested} or {MoneyDeinvested}
56
+ */
17
57
  function recordEarnings() external returns (int256);
18
58
 
19
- function refillWallet(uint256 paymentAmount) external;
59
+ /**
60
+ * @dev Refills the reserve balance with enought money to do a payment. Called from the reserve when a payment needs
61
+ * to be made and there's no enought liquid balance (`currency().balanceOf(reserve) < paymentAmount`)
62
+ *
63
+ * Events:
64
+ * - Emits {MoneyDeinvested} with the amount transferred to the liquid balance.
65
+ *
66
+ * @param paymentAmount The total amount of the payment that needs to be made. If this function is called, it's
67
+ * because paymentAmount > balanceOf(reserve). The minimum amount that needs to be transferred to the reserve is
68
+ * `paymentAmount - balanceOf(reserve)`, but it can transfer more.
69
+ * @return Returns the actual amount transferred
70
+ */
71
+ function refillWallet(uint256 paymentAmount) external returns (uint256);
20
72
 
73
+ /**
74
+ * @dev Deinvests all the funds transfer all the assets to the liquid balance. Called from the reserve when the asset
75
+ * manager is unplugged.
76
+ *
77
+ * Events:
78
+ * - Emits {MoneyDeinvested} with the amount transferred to the liquid balance.
79
+ * - Emits {EarningsRecorded} with the amount of earnings since earnings were recorded last time.
80
+ *
81
+ * @return Returns the earnings or losses (negative) since last time earnings were recorded.
82
+ */
21
83
  function deinvestAll() external returns (int256);
22
84
  }
@@ -9,6 +9,9 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
9
9
  * @author Ensuro
10
10
  */
11
11
  interface IEToken is IERC20 {
12
+ /**
13
+ * @dev Enum of the different parameters that are configurable in an EToken.
14
+ */
12
15
  enum Parameter {
13
16
  liquidityRequirement,
14
17
  minUtilizationRate,
@@ -84,7 +87,7 @@ interface IEToken is IERC20 {
84
87
  *
85
88
  * @param provider The address of the liquidity provider
86
89
  * @param amount The amount deposited.
87
- * @return The actual balance of the provider (TODO)
90
+ * @return The actual balance of the provider
88
91
  */
89
92
  function deposit(address provider, uint256 amount) external returns (uint256);
90
93
 
@@ -8,12 +8,29 @@ import {IEToken} from "./IEToken.sol";
8
8
  * @author Ensuro
9
9
  */
10
10
  interface ILPWhitelist {
11
+ /**
12
+ * @dev Indicates whether or not a liquidity provider can do a deposit in an eToken.
13
+ *
14
+ * @param etoken The eToken (see {EToken}) where the provider wants to deposit money.
15
+ * @param provider The address of the liquidity provider (user) that wants to deposit
16
+ * @param amount The amount of the deposit
17
+ * @return true if `provider` deposit is accepted, false if not
18
+ */
11
19
  function acceptsDeposit(
12
20
  IEToken etoken,
13
21
  address provider,
14
22
  uint256 amount
15
23
  ) external view returns (bool);
16
24
 
25
+ /**
26
+ * @dev Indicates whether or not the eTokens can be transferred from `providerFrom` to `providerTo`
27
+ *
28
+ * @param etoken The eToken (see {EToken}) that the LPs have the intention to transfer.
29
+ * @param providerFrom The current owner of the tokens
30
+ * @param providerTo The destination of the tokens if the transfer is accepted
31
+ * @param amount The amount of tokens to be transferred
32
+ * @return true if the transfer operation is accepted, false if not.
33
+ */
17
34
  function acceptsTransfer(
18
35
  IEToken etoken,
19
36
  address providerFrom,
@@ -100,6 +100,13 @@ interface IPolicyPool {
100
100
  */
101
101
  function expirePolicy(Policy.PolicyData calldata policy) external;
102
102
 
103
+ /**
104
+ * @dev Returns whether or not a policy is active
105
+ * @param policyId The id of the policy we are querying
106
+ * @return Returns true if a policy with that id was created and wasn't yet resolved or expired, or false otherwise.
107
+ */
108
+ function isActive(uint256 policyId) external view returns (bool);
109
+
103
110
  /**
104
111
  * @dev Deposits liquidity into an eToken. Forwards the call to {EToken-deposit}, after transferring the funds.
105
112
  * The user will receive etokens for the same amount deposited.
@@ -9,5 +9,8 @@ import {IPolicyPool} from "./IPolicyPool.sol";
9
9
  * @author Ensuro
10
10
  */
11
11
  interface IPolicyPoolComponent {
12
+ /**
13
+ * @dev Returns the address of the PolicyPool (see {PolicyPool}) where this component belongs.
14
+ */
12
15
  function policyPool() external view returns (IPolicyPool);
13
16
  }
@@ -9,6 +9,9 @@ import {IPremiumsAccount} from "./IPremiumsAccount.sol";
9
9
  * @author Ensuro
10
10
  */
11
11
  interface IRiskModule {
12
+ /**
13
+ * @dev Enum with the different parameters of the risk module, used in {RiskModule-setParam}.
14
+ */
12
15
  enum Parameter {
13
16
  moc,
14
17
  jrCollRatio,
@@ -22,28 +25,85 @@ interface IRiskModule {
22
25
  maxDuration
23
26
  }
24
27
 
28
+ /**
29
+ * Struct of the parameters of the risk module that are used to calculate the different Policy fields (see
30
+ * {Policy-PolicyData}.
31
+ */
25
32
  struct Params {
33
+ /**
34
+ * @dev MoC (Margin of Conservativism) is a factor that multiplies the lossProb to increase or decrease the pure
35
+ * premium.
36
+ */
26
37
  uint256 moc;
38
+ /**
39
+ * @dev Junior Collateralization Ratio is the percentage of policy exposure (payout) that will be covered with the
40
+ * purePremium and the Junior EToken
41
+ */
27
42
  uint256 jrCollRatio;
43
+ /**
44
+ * @dev Collateralization Ratio is the percentage of policy exposure (payout) that will be covered by the
45
+ * purePremium and the Junior and Senior EToken. Usually is calculated as the relation between VAR99.5% and VAR100
46
+ * (full collateralization).
47
+ */
28
48
  uint256 collRatio;
49
+ /**
50
+ * @dev Ensuro PurePremium Fee is the percentage that will be multiplied by the pure premium to obtain the part of
51
+ * the Ensuro Fee that's proportional to the pure premium.
52
+ */
29
53
  uint256 ensuroPpFee;
54
+ /**
55
+ * @dev Ensuro Cost of Capital Fee is the percentage that will be multiplied by the cost of capital (CoC) to
56
+ * obtain the part of the Ensuro Fee that's proportional to the CoC.
57
+ */
30
58
  uint256 ensuroCocFee;
59
+ /**
60
+ * @dev Junior Return on Capital is the annualized interest rate that's charged for the capital locked in the Junior
61
+ * EToken.
62
+ */
31
63
  uint256 jrRoc;
64
+ /**
65
+ * @dev Senior Return on Capital is the annualized interest rate that's charged for the capital locked in the Senior
66
+ * EToken.
67
+ */
32
68
  uint256 srRoc;
33
69
  }
34
70
 
71
+ /**
72
+ * @dev A readable name of this risk module. Never changes.
73
+ */
35
74
  function name() external view returns (string memory);
36
75
 
76
+ /**
77
+ * @dev Returns different parameters of the risk module (see {Params})
78
+ */
37
79
  function params() external view returns (Params memory);
38
80
 
39
- function maxPayoutPerPolicy() external view returns (uint256);
40
-
41
- function exposureLimit() external view returns (uint256);
42
-
81
+ /**
82
+ * @dev Returns the maximum duration (in hours) of the policies of this risk module.
83
+ * The `expiration` of the policies has to be `<= (block.timestamp + 3600 * maxDuration())`
84
+ */
43
85
  function maxDuration() external view returns (uint256);
44
86
 
87
+ /**
88
+ * @dev Returns the maximum payout accepted for new policies.
89
+ */
90
+ function maxPayoutPerPolicy() external view returns (uint256);
91
+
92
+ /**
93
+ * @dev Returns sum of the (maximum) payout of the active policies of this risk module, i.e. the maximum possible
94
+ * amount of money that's exposed for this risk module.
95
+ */
45
96
  function activeExposure() external view returns (uint256);
46
97
 
98
+ /**
99
+ * @dev Returns maximum exposure (sum of the (maximum) payout of the active policies) of this risk module.
100
+ * `activeExposure() <= exposureLimit()` always
101
+ */
102
+ function exposureLimit() external view returns (uint256);
103
+
104
+ /**
105
+ * @dev Returns the address of the partner that receives the partnerCommission
106
+ */
47
107
  function wallet() external view returns (address);
48
108
 
49
109
  /**
@@ -56,5 +116,8 @@ interface IRiskModule {
56
116
  */
57
117
  function releaseExposure(uint256 payout) external;
58
118
 
119
+ /**
120
+ * @dev Returns the {PremiumsAccount} where the premiums of this risk module are collected. Never changes.
121
+ */
59
122
  function premiumsAccount() external view returns (IPremiumsAccount);
60
123
  }