@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
@@ -0,0 +1,76 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IEToken} from "./IEToken.sol";
5
+ import {Policy} from "../Policy.sol";
6
+
7
+ /**
8
+ * @title IPremiumsAccount interface
9
+ * @dev Interface for Premiums Account contracts.
10
+ * @author Ensuro
11
+ */
12
+ interface IPremiumsAccount {
13
+ /**
14
+ * @dev Adds a policy to the PremiumsAccount. Stores the pure premiums and locks the aditional funds from junior and
15
+ * senior eTokens.
16
+ *
17
+ * Requirements:
18
+ * - Must be called by `policyPool()`
19
+ *
20
+ * Events:
21
+ * - {EToken-SCRLocked}
22
+ *
23
+ * @param policy The policy to add (created in this transaction)
24
+ */
25
+ function policyCreated(Policy.PolicyData memory policy) external;
26
+
27
+ /**
28
+ * @dev The PremiumsAccount is notified that the policy was resolved and issues the payout to the policyHolder.
29
+ *
30
+ * Requirements:
31
+ * - Must be called by `policyPool()`
32
+ *
33
+ * Events:
34
+ * - {ERC20-Transfer}: `to == policyHolder`, `amount == payout`
35
+ * - {EToken-InternalLoan}: optional, if a loan needs to be taken
36
+ * - {EToken-SCRUnlocked}
37
+ *
38
+ * @param policyHolder The one that will receive the payout
39
+ * @param policy The policy that was resolved
40
+ * @param payout The amount that has to be transferred to `policyHolder`
41
+ */
42
+ function policyResolvedWithPayout(
43
+ address policyHolder,
44
+ Policy.PolicyData memory policy,
45
+ uint256 payout
46
+ ) external;
47
+
48
+ /**
49
+ * @dev The PremiumsAccount is notified that the policy has expired, unlocks the SCR and earns the pure premium.
50
+ *
51
+ * Requirements:
52
+ * - Must be called by `policyPool()`
53
+ *
54
+ * Events:
55
+ * - {ERC20-Transfer}: `to == policyHolder`, `amount == payout`
56
+ * - {EToken-InternalLoanRepaid}: optional, if a loan was taken before
57
+ *
58
+ * @param policy The policy that has expired
59
+ */
60
+ function policyExpired(Policy.PolicyData memory policy) external;
61
+
62
+ /**
63
+ * @dev The senior eToken, the secondary source of solvency, used if the premiums account is exhausted and junior too
64
+ */
65
+ function seniorEtk() external view returns (IEToken);
66
+
67
+ /**
68
+ * @dev The junior eToken, the primary source of solvency, used if the premiums account is exhausted.
69
+ */
70
+ function juniorEtk() external view returns (IEToken);
71
+
72
+ /**
73
+ * @dev The total amount of premiums hold by this PremiumsAccount
74
+ */
75
+ function purePremiums() external view returns (uint256);
76
+ }
@@ -0,0 +1,123 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IPremiumsAccount} from "./IPremiumsAccount.sol";
5
+
6
+ /**
7
+ * @title IRiskModule interface
8
+ * @dev Interface for RiskModule smart contracts. Gives access to RiskModule configuration parameters
9
+ * @author Ensuro
10
+ */
11
+ interface IRiskModule {
12
+ /**
13
+ * @dev Enum with the different parameters of the risk module, used in {RiskModule-setParam}.
14
+ */
15
+ enum Parameter {
16
+ moc,
17
+ jrCollRatio,
18
+ collRatio,
19
+ ensuroPpFee,
20
+ ensuroCocFee,
21
+ jrRoc,
22
+ srRoc,
23
+ maxPayoutPerPolicy,
24
+ exposureLimit,
25
+ maxDuration
26
+ }
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
68
+ uint256 srRoc;
69
+ }
70
+
71
+ /**
72
+ * @dev A readable name of this risk module. Never changes.
73
+ */
74
+ function name() external view returns (string memory);
75
+
76
+ /**
77
+ * @dev Returns different parameters of the risk module (see {Params})
78
+ */
79
+ function params() external view returns (Params memory);
80
+
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
+ */
85
+ function maxDuration() external view returns (uint256);
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
+ */
96
+ function activeExposure() external view returns (uint256);
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
+ */
107
+ function wallet() external view returns (address);
108
+
109
+ /**
110
+ * @dev Called when a policy expires or is resolved to update the exposure.
111
+ *
112
+ * Requirements:
113
+ * - Must be called by `policyPool()`
114
+ *
115
+ * @param payout The exposure (maximum payout) of the policy
116
+ */
117
+ function releaseExposure(uint256 payout) external;
118
+
119
+ /**
120
+ * @dev Returns the {PremiumsAccount} where the premiums of this risk module are collected. Never changes.
121
+ */
122
+ function premiumsAccount() external view returns (IPremiumsAccount);
123
+ }
@@ -0,0 +1,85 @@
1
+ //SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
5
+ import {ERC4626} from "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol";
6
+ import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
7
+ import {IMintableERC20} from "./IMintableERC20.sol";
8
+ import {TimeScaled} from "../TimeScaled.sol";
9
+
10
+ contract FixedRateVault is ERC4626 {
11
+ using TimeScaled for TimeScaled.ScaledAmount;
12
+
13
+ uint256 internal _interestRate;
14
+ TimeScaled.ScaledAmount internal _totalAssets;
15
+ bool internal _broken;
16
+
17
+ constructor(
18
+ string memory name_,
19
+ string memory symbol_,
20
+ IERC20Metadata asset_,
21
+ uint256 interestRate_
22
+ ) ERC20(name_, symbol_) ERC4626(asset_) {
23
+ _interestRate = interestRate_;
24
+ _totalAssets.init();
25
+ }
26
+
27
+ /** @dev See {IERC4262-totalAssets}. */
28
+ function totalAssets() public view virtual override returns (uint256) {
29
+ require(!_broken, "Vault is broken");
30
+ return _totalAssets.getScaledAmount(_interestRate);
31
+ }
32
+
33
+ /**
34
+ * @dev Deposit/mint common workflow.
35
+ */
36
+ function _deposit(
37
+ address caller,
38
+ address receiver,
39
+ uint256 assets,
40
+ uint256 shares
41
+ ) internal virtual override {
42
+ require(!_broken, "Vault is broken");
43
+ _totalAssets.add(assets, _interestRate);
44
+ super._deposit(caller, receiver, assets, shares);
45
+ }
46
+
47
+ /**
48
+ * @dev Withdraw/redeem common workflow.
49
+ */
50
+ function _withdraw(
51
+ address caller,
52
+ address receiver,
53
+ address owner,
54
+ uint256 assets,
55
+ uint256 shares
56
+ ) internal virtual override {
57
+ require(!_broken, "Vault is broken");
58
+ _totalAssets.sub(assets, _interestRate);
59
+ uint256 balance = IERC20Metadata(asset()).balanceOf(address(this));
60
+ if (balance < assets) {
61
+ // Here comes the magic! Free money!
62
+ IMintableERC20(asset()).mint(address(this), assets - balance);
63
+ }
64
+ super._withdraw(caller, receiver, owner, assets, shares);
65
+ }
66
+
67
+ /*
68
+ * @dev Adds or remove assets not generated by deposits/withdraw - For testing discrete earnings/losses
69
+ */
70
+ function discreteEarning(int256 assets) external {
71
+ if (assets > 0) {
72
+ _totalAssets.add(uint256(assets), _interestRate);
73
+ } else {
74
+ _totalAssets.sub(uint256(-assets), _interestRate);
75
+ }
76
+ }
77
+
78
+ function setBroken(bool broken_) external {
79
+ _broken = broken_;
80
+ }
81
+
82
+ function broken() external view returns (bool) {
83
+ return _broken;
84
+ }
85
+ }
@@ -0,0 +1,66 @@
1
+ //SPDX-License-Identifier: Apache-2.0
2
+
3
+ pragma solidity ^0.8.0;
4
+
5
+ import {Proxy} from "@openzeppelin/contracts/proxy/Proxy.sol";
6
+
7
+ /**
8
+ * @dev This contract provides a fallback function that forwards all calls to another contract using the EVM
9
+ * instruction `call`.
10
+ *
11
+ * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
12
+ * different contract through the {_delegate} function.
13
+ *
14
+ * The success and return data of the delegated call will be returned back to the caller of the proxy.
15
+ */
16
+ contract ForwardProxy is Proxy {
17
+ address internal _forwardTo;
18
+
19
+ constructor(address forwardTo) {
20
+ _forwardTo = forwardTo;
21
+ }
22
+
23
+ /**
24
+ * @dev Delegates the current call to `implementation`.
25
+ *
26
+ * This function does not return to its internall call site, it will return directly to the external caller.
27
+ */
28
+ function _delegate(address implementation) internal virtual override {
29
+ // solhint-disable-next-line no-inline-assembly
30
+ assembly {
31
+ // Copy msg.data. We take full control of memory in this inline assembly
32
+ // block because it will not return to Solidity code. We overwrite the
33
+ // Solidity scratch pad at memory position 0.
34
+ calldatacopy(0, 0, calldatasize())
35
+
36
+ // Call the implementation.
37
+ // out and outsize are 0 because we don't know the size yet.
38
+ // let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
39
+ let result := call(gas(), implementation, 0, 0, calldatasize(), 0, 0)
40
+
41
+ // Copy the returned data.
42
+ returndatacopy(0, 0, returndatasize())
43
+
44
+ switch result
45
+ // delegatecall returns 0 on error.
46
+ case 0 {
47
+ revert(0, returndatasize())
48
+ }
49
+ default {
50
+ return(0, returndatasize())
51
+ }
52
+ }
53
+ }
54
+
55
+ /**
56
+ * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
57
+ * and {_fallback} should delegate.
58
+ */
59
+ function _implementation() internal view virtual override returns (address) {
60
+ return _forwardTo;
61
+ }
62
+
63
+ function setForwardTo(address forwardTo) external {
64
+ _forwardTo = forwardTo;
65
+ }
66
+ }
@@ -0,0 +1,13 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ /**
5
+ * @title IMintableERC20 interface
6
+ * @dev Interface for mintable / burnable ERC20 - for testing
7
+ * @author Ensuro
8
+ */
9
+ interface IMintableERC20 {
10
+ function mint(address recipient, uint256 amount) external;
11
+
12
+ function burn(address recipient, uint256 amount) external;
13
+ }
@@ -0,0 +1,89 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IPolicyHolder} from "../interfaces/IPolicyHolder.sol";
5
+ import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
6
+
7
+ contract PolicyHolderMock is IPolicyHolder {
8
+ uint256 public policyId;
9
+ uint256 public payout;
10
+ bool public fail;
11
+ bool public notImplemented;
12
+
13
+ event NotificationReceived(uint256 kind, uint256 policyId, address operator, address from);
14
+
15
+ constructor(bool fail_) {
16
+ fail = fail_;
17
+ notImplemented = false;
18
+ payout = type(uint256).max;
19
+ }
20
+
21
+ function setFail(bool fail_) external {
22
+ fail = fail_;
23
+ }
24
+
25
+ function setNotImplemented(bool notImplemented_) external {
26
+ notImplemented = notImplemented_;
27
+ }
28
+
29
+ function onERC721Received(
30
+ address operator,
31
+ address from,
32
+ uint256 policyId_,
33
+ bytes calldata
34
+ ) external override returns (bytes4) {
35
+ if (notImplemented)
36
+ // solhint-disable-next-line no-inline-assembly
37
+ assembly {
38
+ revert(0, 0)
39
+ }
40
+ if (fail) revert("onERC721Received: They told me I have to fail");
41
+ policyId = policyId_;
42
+ emit NotificationReceived(0, policyId_, operator, from);
43
+ return IERC721Receiver.onERC721Received.selector;
44
+ }
45
+
46
+ function onPolicyExpired(
47
+ address operator,
48
+ address from,
49
+ uint256 policyId_
50
+ ) external override returns (bytes4) {
51
+ if (notImplemented)
52
+ // solhint-disable-next-line no-inline-assembly
53
+ assembly {
54
+ revert(0, 0)
55
+ }
56
+ if (fail) revert("onPolicyExpired: They told me I have to fail");
57
+ policyId = policyId_;
58
+ payout = 0;
59
+ emit NotificationReceived(1, policyId_, operator, from);
60
+ return IPolicyHolder.onPolicyExpired.selector;
61
+ }
62
+
63
+ /**
64
+ * @dev Whenever an Policy is resolved with payout > 0, this function is called
65
+ *
66
+ * It must return its Solidity selector to confirm the payout.
67
+ * If interface is not implemented by the recipient, it will be ignored and the payout will be successful.
68
+ * If any other value is returned or it reverts, the policy resolution / payout will be reverted.
69
+ *
70
+ * The selector can be obtained in Solidity with `IPolicyPool.onPayoutReceived.selector`.
71
+ */
72
+ function onPayoutReceived(
73
+ address operator,
74
+ address from,
75
+ uint256 policyId_,
76
+ uint256 amount
77
+ ) external override returns (bytes4) {
78
+ if (notImplemented)
79
+ // solhint-disable-next-line no-inline-assembly
80
+ assembly {
81
+ revert(0, 0)
82
+ }
83
+ if (fail) revert("onPayoutReceived: They told me I have to fail");
84
+ policyId = policyId_;
85
+ payout = amount;
86
+ emit NotificationReceived(2, policyId_, operator, from);
87
+ return IPolicyHolder.onPayoutReceived.selector;
88
+ }
89
+ }
@@ -0,0 +1,17 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
5
+ import {IPolicyPoolComponent} from "../interfaces/IPolicyPoolComponent.sol";
6
+
7
+ contract PolicyPoolComponentMock is IPolicyPoolComponent {
8
+ IPolicyPool internal immutable _policyPool;
9
+
10
+ constructor(IPolicyPool policyPool_) {
11
+ _policyPool = policyPool_;
12
+ }
13
+
14
+ function policyPool() external view override returns (IPolicyPool) {
15
+ return _policyPool;
16
+ }
17
+ }
@@ -0,0 +1,148 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
5
+ import {IRiskModule} from "../interfaces/IRiskModule.sol";
6
+ import {IEToken} from "../interfaces/IEToken.sol";
7
+ import {IAccessManager} from "../interfaces/IAccessManager.sol";
8
+ import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
9
+ import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
10
+ import {Policy} from "../Policy.sol";
11
+ import {ForwardProxy} from "./ForwardProxy.sol";
12
+
13
+ contract PolicyPoolMock is IPolicyPool {
14
+ using Policy for Policy.PolicyData;
15
+
16
+ uint256 public constant MAX_INT =
17
+ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
18
+
19
+ IERC20Metadata internal _currency;
20
+ IAccessManager internal _access;
21
+
22
+ mapping(uint256 => Policy.PolicyData) internal policies;
23
+ mapping(uint256 => bytes32) internal policyHashes;
24
+
25
+ event NewPolicy(IRiskModule indexed riskModule, Policy.PolicyData policy);
26
+ event PolicyResolved(IRiskModule indexed riskModule, uint256 indexed policyId, uint256 payout);
27
+
28
+ constructor(IERC20Metadata currency_, IAccessManager access_) {
29
+ _currency = currency_;
30
+ _access = access_;
31
+ }
32
+
33
+ function currency() external view override returns (IERC20Metadata) {
34
+ return _currency;
35
+ }
36
+
37
+ function access() external view override returns (IAccessManager) {
38
+ return _access;
39
+ }
40
+
41
+ function treasury() external pure override returns (address) {
42
+ return address(0);
43
+ }
44
+
45
+ function newPolicy(
46
+ Policy.PolicyData memory policy,
47
+ address, /* caller */
48
+ address, /* policyHolder */
49
+ uint96 internalId
50
+ ) external override returns (uint256) {
51
+ policy.id = (uint256(uint160(address(policy.riskModule))) << 96) + internalId;
52
+ policyHashes[policy.id] = policy.hash();
53
+ emit NewPolicy(IRiskModule(msg.sender), policy);
54
+ return policy.id;
55
+ }
56
+
57
+ function _resolvePolicy(Policy.PolicyData memory policy, uint256 payout) internal {
58
+ require(policy.id != 0, "Policy not found");
59
+ require(policy.hash() == policyHashes[policy.id], "Hash doesn't match");
60
+ require(
61
+ msg.sender == address(policy.riskModule),
62
+ "Only riskModule is authorized to resolve the policy"
63
+ );
64
+ delete policies[policy.id];
65
+ delete policyHashes[policy.id];
66
+ emit PolicyResolved(IRiskModule(msg.sender), policy.id, payout);
67
+ }
68
+
69
+ function resolvePolicy(Policy.PolicyData calldata policy, uint256 payout) external override {
70
+ _resolvePolicy(policy, payout);
71
+ }
72
+
73
+ function expirePolicy(Policy.PolicyData calldata policy) external override {
74
+ _resolvePolicy(policy, 0);
75
+ }
76
+
77
+ function resolvePolicyFullPayout(Policy.PolicyData calldata policy, bool customerWon)
78
+ external
79
+ override
80
+ {
81
+ return _resolvePolicy(policy, customerWon ? policy.payout : 0);
82
+ }
83
+
84
+ function isActive(uint256 policyId) external view override returns (bool) {
85
+ return policyHashes[policyId] != bytes32(0);
86
+ }
87
+
88
+ function deposit(IEToken, uint256) external pure override {
89
+ revert("Not Implemented deposit");
90
+ }
91
+
92
+ function withdraw(IEToken, uint256) external pure override returns (uint256) {
93
+ revert("Not Implemented withdraw");
94
+ }
95
+
96
+ /**
97
+ * @dev Simple passthrough method for testing Policy.initialize
98
+ */
99
+ function initializeAndEmitPolicy(
100
+ IRiskModule riskModule,
101
+ IRiskModule.Params memory rmParams,
102
+ uint256 premium,
103
+ uint256 payout,
104
+ uint256 lossProb,
105
+ uint40 expiration
106
+ ) external {
107
+ Policy.PolicyData memory policy = Policy.initialize(
108
+ riskModule,
109
+ rmParams,
110
+ premium,
111
+ payout,
112
+ lossProb,
113
+ expiration
114
+ );
115
+
116
+ emit NewPolicy(riskModule, policy);
117
+ }
118
+ }
119
+
120
+ /**
121
+ * @title PolicyPoolMockForward
122
+ * @dev PolicyPool that forwards fallback calls to another contract. Used to simulate calls to EToken
123
+ * and other contracts that have functions that can be called only from PolicyPool
124
+ */
125
+ contract PolicyPoolMockForward is ForwardProxy {
126
+ uint256 public constant MAX_INT =
127
+ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
128
+
129
+ IERC20Metadata internal _currency;
130
+ IAccessManager internal _access;
131
+
132
+ constructor(
133
+ address forwardTo,
134
+ IERC20Metadata currency_,
135
+ IAccessManager access_
136
+ ) ForwardProxy(forwardTo) {
137
+ _currency = currency_;
138
+ _access = access_;
139
+ }
140
+
141
+ function currency() external view returns (IERC20Metadata) {
142
+ return _currency;
143
+ }
144
+
145
+ function access() external view returns (IAccessManager) {
146
+ return _access;
147
+ }
148
+ }
@@ -0,0 +1,75 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
5
+ import {IPremiumsAccount} from "../interfaces/IPremiumsAccount.sol";
6
+ import {RiskModule} from "../RiskModule.sol";
7
+ import {Policy} from "../Policy.sol";
8
+
9
+ /**
10
+ * @title Trustful Risk Module
11
+ * @dev Risk Module without any validation, just the newPolicy and resolvePolicy need to be called by
12
+ authorized users
13
+ * @custom:security-contact security@ensuro.co
14
+ * @author Ensuro
15
+ */
16
+
17
+ contract RiskModuleMock is RiskModule {
18
+ bytes32 public constant PRICER_ROLE = keccak256("PRICER_ROLE");
19
+ bytes32 public constant RESOLVER_ROLE = keccak256("RESOLVER_ROLE");
20
+
21
+ /// @custom:oz-upgrades-unsafe-allow constructor
22
+ // solhint-disable-next-line no-empty-blocks
23
+ constructor(IPolicyPool policyPool_, IPremiumsAccount premiumsAccount_)
24
+ RiskModule(policyPool_, premiumsAccount_)
25
+ {} // solhint-disable-line no-empty-blocks
26
+
27
+ /**
28
+ * @dev Initializes the RiskModule
29
+ * @param name_ Name of the Risk Module
30
+ * @param collRatio_ Collateralization ratio to compute solvency requirement as % of payout (in ray)
31
+ * @param ensuroPpFee_ % of pure premium that will go for Ensuro treasury (in ray)
32
+ * @param srRoc_ return on capital paid to Senior LPs (annualized percentage - in ray)
33
+ * @param maxPayoutPerPolicy_ Maximum payout per policy (in wad)
34
+ * @param exposureLimit_ Max exposure (sum of payouts) to be allocated to this module (in wad)
35
+ * @param wallet_ Address of the RiskModule provider
36
+ */
37
+ function initialize(
38
+ string memory name_,
39
+ uint256 collRatio_,
40
+ uint256 ensuroPpFee_,
41
+ uint256 srRoc_,
42
+ uint256 maxPayoutPerPolicy_,
43
+ uint256 exposureLimit_,
44
+ address wallet_
45
+ ) public initializer {
46
+ __RiskModule_init(
47
+ name_,
48
+ collRatio_,
49
+ ensuroPpFee_,
50
+ srRoc_,
51
+ maxPayoutPerPolicy_,
52
+ exposureLimit_,
53
+ wallet_
54
+ );
55
+ }
56
+
57
+ function newPolicy(
58
+ uint256 payout,
59
+ uint256 premium,
60
+ uint256 lossProb,
61
+ uint40 expiration,
62
+ address payer,
63
+ address onBehalfOf,
64
+ uint96 internalId
65
+ ) external onlyComponentRole(PRICER_ROLE) returns (uint256) {
66
+ return _newPolicy(payout, premium, lossProb, expiration, payer, onBehalfOf, internalId).id;
67
+ }
68
+
69
+ function resolvePolicy(Policy.PolicyData calldata policy, uint256 payout)
70
+ external
71
+ onlyComponentRole(RESOLVER_ROLE)
72
+ {
73
+ _policyPool.resolvePolicy(policy, payout);
74
+ }
75
+ }