@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,31 +0,0 @@
1
- {
2
- "_format": "hh-sol-artifact-1",
3
- "contractName": "IAssetManager",
4
- "sourceName": "interfaces/IAssetManager.sol",
5
- "abi": [
6
- {
7
- "inputs": [],
8
- "name": "deinvestAll",
9
- "outputs": [],
10
- "stateMutability": "nonpayable",
11
- "type": "function"
12
- },
13
- {
14
- "inputs": [
15
- {
16
- "internalType": "uint256",
17
- "name": "paymentAmount",
18
- "type": "uint256"
19
- }
20
- ],
21
- "name": "refillWallet",
22
- "outputs": [],
23
- "stateMutability": "nonpayable",
24
- "type": "function"
25
- }
26
- ],
27
- "bytecode": "0x",
28
- "deployedBytecode": "0x",
29
- "linkReferences": {},
30
- "deployedLinkReferences": {}
31
- }
@@ -1,30 +0,0 @@
1
- {
2
- "_format": "hh-sol-artifact-1",
3
- "contractName": "IPriceOracle",
4
- "sourceName": "interfaces/IExchange.sol",
5
- "abi": [
6
- {
7
- "inputs": [
8
- {
9
- "internalType": "address",
10
- "name": "asset",
11
- "type": "address"
12
- }
13
- ],
14
- "name": "getAssetPrice",
15
- "outputs": [
16
- {
17
- "internalType": "uint256",
18
- "name": "",
19
- "type": "uint256"
20
- }
21
- ],
22
- "stateMutability": "view",
23
- "type": "function"
24
- }
25
- ],
26
- "bytecode": "0x",
27
- "deployedBytecode": "0x",
28
- "linkReferences": {},
29
- "deployedLinkReferences": {}
30
- }
@@ -1,321 +0,0 @@
1
- {
2
- "_format": "hh-sol-artifact-1",
3
- "contractName": "IPolicyNFT",
4
- "sourceName": "interfaces/IPolicyNFT.sol",
5
- "abi": [
6
- {
7
- "anonymous": false,
8
- "inputs": [
9
- {
10
- "indexed": true,
11
- "internalType": "address",
12
- "name": "owner",
13
- "type": "address"
14
- },
15
- {
16
- "indexed": true,
17
- "internalType": "address",
18
- "name": "approved",
19
- "type": "address"
20
- },
21
- {
22
- "indexed": true,
23
- "internalType": "uint256",
24
- "name": "tokenId",
25
- "type": "uint256"
26
- }
27
- ],
28
- "name": "Approval",
29
- "type": "event"
30
- },
31
- {
32
- "anonymous": false,
33
- "inputs": [
34
- {
35
- "indexed": true,
36
- "internalType": "address",
37
- "name": "owner",
38
- "type": "address"
39
- },
40
- {
41
- "indexed": true,
42
- "internalType": "address",
43
- "name": "operator",
44
- "type": "address"
45
- },
46
- {
47
- "indexed": false,
48
- "internalType": "bool",
49
- "name": "approved",
50
- "type": "bool"
51
- }
52
- ],
53
- "name": "ApprovalForAll",
54
- "type": "event"
55
- },
56
- {
57
- "anonymous": false,
58
- "inputs": [
59
- {
60
- "indexed": true,
61
- "internalType": "address",
62
- "name": "from",
63
- "type": "address"
64
- },
65
- {
66
- "indexed": true,
67
- "internalType": "address",
68
- "name": "to",
69
- "type": "address"
70
- },
71
- {
72
- "indexed": true,
73
- "internalType": "uint256",
74
- "name": "tokenId",
75
- "type": "uint256"
76
- }
77
- ],
78
- "name": "Transfer",
79
- "type": "event"
80
- },
81
- {
82
- "inputs": [
83
- {
84
- "internalType": "address",
85
- "name": "to",
86
- "type": "address"
87
- },
88
- {
89
- "internalType": "uint256",
90
- "name": "tokenId",
91
- "type": "uint256"
92
- }
93
- ],
94
- "name": "approve",
95
- "outputs": [],
96
- "stateMutability": "nonpayable",
97
- "type": "function"
98
- },
99
- {
100
- "inputs": [
101
- {
102
- "internalType": "address",
103
- "name": "owner",
104
- "type": "address"
105
- }
106
- ],
107
- "name": "balanceOf",
108
- "outputs": [
109
- {
110
- "internalType": "uint256",
111
- "name": "balance",
112
- "type": "uint256"
113
- }
114
- ],
115
- "stateMutability": "view",
116
- "type": "function"
117
- },
118
- {
119
- "inputs": [],
120
- "name": "connect",
121
- "outputs": [],
122
- "stateMutability": "nonpayable",
123
- "type": "function"
124
- },
125
- {
126
- "inputs": [
127
- {
128
- "internalType": "uint256",
129
- "name": "tokenId",
130
- "type": "uint256"
131
- }
132
- ],
133
- "name": "getApproved",
134
- "outputs": [
135
- {
136
- "internalType": "address",
137
- "name": "operator",
138
- "type": "address"
139
- }
140
- ],
141
- "stateMutability": "view",
142
- "type": "function"
143
- },
144
- {
145
- "inputs": [
146
- {
147
- "internalType": "address",
148
- "name": "owner",
149
- "type": "address"
150
- },
151
- {
152
- "internalType": "address",
153
- "name": "operator",
154
- "type": "address"
155
- }
156
- ],
157
- "name": "isApprovedForAll",
158
- "outputs": [
159
- {
160
- "internalType": "bool",
161
- "name": "",
162
- "type": "bool"
163
- }
164
- ],
165
- "stateMutability": "view",
166
- "type": "function"
167
- },
168
- {
169
- "inputs": [
170
- {
171
- "internalType": "uint256",
172
- "name": "tokenId",
173
- "type": "uint256"
174
- }
175
- ],
176
- "name": "ownerOf",
177
- "outputs": [
178
- {
179
- "internalType": "address",
180
- "name": "owner",
181
- "type": "address"
182
- }
183
- ],
184
- "stateMutability": "view",
185
- "type": "function"
186
- },
187
- {
188
- "inputs": [
189
- {
190
- "internalType": "address",
191
- "name": "to",
192
- "type": "address"
193
- },
194
- {
195
- "internalType": "uint256",
196
- "name": "policyId",
197
- "type": "uint256"
198
- }
199
- ],
200
- "name": "safeMint",
201
- "outputs": [],
202
- "stateMutability": "nonpayable",
203
- "type": "function"
204
- },
205
- {
206
- "inputs": [
207
- {
208
- "internalType": "address",
209
- "name": "from",
210
- "type": "address"
211
- },
212
- {
213
- "internalType": "address",
214
- "name": "to",
215
- "type": "address"
216
- },
217
- {
218
- "internalType": "uint256",
219
- "name": "tokenId",
220
- "type": "uint256"
221
- }
222
- ],
223
- "name": "safeTransferFrom",
224
- "outputs": [],
225
- "stateMutability": "nonpayable",
226
- "type": "function"
227
- },
228
- {
229
- "inputs": [
230
- {
231
- "internalType": "address",
232
- "name": "from",
233
- "type": "address"
234
- },
235
- {
236
- "internalType": "address",
237
- "name": "to",
238
- "type": "address"
239
- },
240
- {
241
- "internalType": "uint256",
242
- "name": "tokenId",
243
- "type": "uint256"
244
- },
245
- {
246
- "internalType": "bytes",
247
- "name": "data",
248
- "type": "bytes"
249
- }
250
- ],
251
- "name": "safeTransferFrom",
252
- "outputs": [],
253
- "stateMutability": "nonpayable",
254
- "type": "function"
255
- },
256
- {
257
- "inputs": [
258
- {
259
- "internalType": "address",
260
- "name": "operator",
261
- "type": "address"
262
- },
263
- {
264
- "internalType": "bool",
265
- "name": "_approved",
266
- "type": "bool"
267
- }
268
- ],
269
- "name": "setApprovalForAll",
270
- "outputs": [],
271
- "stateMutability": "nonpayable",
272
- "type": "function"
273
- },
274
- {
275
- "inputs": [
276
- {
277
- "internalType": "bytes4",
278
- "name": "interfaceId",
279
- "type": "bytes4"
280
- }
281
- ],
282
- "name": "supportsInterface",
283
- "outputs": [
284
- {
285
- "internalType": "bool",
286
- "name": "",
287
- "type": "bool"
288
- }
289
- ],
290
- "stateMutability": "view",
291
- "type": "function"
292
- },
293
- {
294
- "inputs": [
295
- {
296
- "internalType": "address",
297
- "name": "from",
298
- "type": "address"
299
- },
300
- {
301
- "internalType": "address",
302
- "name": "to",
303
- "type": "address"
304
- },
305
- {
306
- "internalType": "uint256",
307
- "name": "tokenId",
308
- "type": "uint256"
309
- }
310
- ],
311
- "name": "transferFrom",
312
- "outputs": [],
313
- "stateMutability": "nonpayable",
314
- "type": "function"
315
- }
316
- ],
317
- "bytecode": "0x",
318
- "deployedBytecode": "0x",
319
- "linkReferences": {},
320
- "deployedLinkReferences": {}
321
- }
@@ -1,298 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- pragma solidity ^0.8.0;
3
-
4
- import {AddressUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
5
- import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
6
- import {BaseAssetManager} from "./BaseAssetManager.sol";
7
- import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
8
- import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
9
- import {IPolicyPoolConfig} from "../interfaces/IPolicyPoolConfig.sol";
10
- import {IExchange} from "../interfaces/IExchange.sol";
11
- import {WadRayMath} from "./WadRayMath.sol";
12
- import {ILendingPoolAddressesProvider} from "@aave/protocol-v2/contracts/interfaces/ILendingPoolAddressesProvider.sol";
13
- import {ILendingPool} from "@aave/protocol-v2/contracts/interfaces/ILendingPool.sol";
14
- import {IAToken} from "@aave/protocol-v2/contracts/interfaces/IAToken.sol";
15
- import {AaveProtocolDataProvider} from "@aave/protocol-v2/contracts/misc/AaveProtocolDataProvider.sol";
16
-
17
- /**
18
- * @title AssetManager that reinvests the capital in AAVE
19
- * @dev Deposits and withdraw from AAVE, also converts the rewards.
20
- * Invest into AAVE AToken for the underlying asset (ex. USDC) getting lending interests.
21
- * When needs to deinvest, first deinvest from AAVE, but also can liquidate the rewards
22
- * (AAVE in mainnet or MATIC in Polygon) using a DEX.
23
- * Above a given threshold, the rewards are claimed. Also, above a given threshold they are also reinvested
24
- * to accrue additional interests and rewards.
25
- * An authorized user (SWAP_REWARDS_ROLE) can force the swap of the rewards for the pool's currency.
26
- * @custom:security-contact security@ensuro.co
27
- * @author Ensuro
28
- */
29
- contract AaveAssetManager is BaseAssetManager {
30
- using SafeERC20 for IERC20Metadata;
31
- using WadRayMath for uint256;
32
- using AddressUpgradeable for address;
33
-
34
- bytes32 public constant SWAP_REWARDS_ROLE = keccak256("SWAP_REWARDS_ROLE");
35
-
36
- /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
37
- ILendingPoolAddressesProvider internal immutable _aaveAddrProv;
38
- /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
39
- IAToken internal immutable _aToken;
40
- /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
41
- IAToken internal immutable _rewardAToken;
42
- /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
43
- IERC20Metadata internal immutable _rewardToken;
44
- /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
45
- uint256 internal _claimRewardsMin; // Minimum amount of rewards accumulated to claim
46
- uint256 internal _reinvestRewardsMin; // Minimum amount of rewards to reinvest into AAVE
47
-
48
- bytes32 internal constant DATA_PROVIDER_ID =
49
- 0x0100000000000000000000000000000000000000000000000000000000000000;
50
-
51
- uint256 internal constant SECONDS_PER_YEAR = 365 days;
52
-
53
- event RewardSwapped(uint256 rewardIn, uint256 currencyOut);
54
-
55
- /// @custom:oz-upgrades-unsafe-allow constructor
56
- constructor(IPolicyPool policyPool_, ILendingPoolAddressesProvider aaveAddrProv_)
57
- BaseAssetManager(policyPool_)
58
- {
59
- _aaveAddrProv = aaveAddrProv_;
60
- AaveProtocolDataProvider dataProvider = AaveProtocolDataProvider(
61
- aaveAddrProv_.getAddress(DATA_PROVIDER_ID)
62
- );
63
- (address aToken_, , ) = dataProvider.getReserveTokensAddresses(address(policyPool_.currency()));
64
- _aToken = IAToken(aToken_);
65
- address rewardToken_ = IAToken(aToken_).getIncentivesController().REWARD_TOKEN();
66
- _rewardToken = IERC20Metadata(rewardToken_);
67
- (address rewardAToken_, , ) = dataProvider.getReserveTokensAddresses(address(rewardToken_));
68
- _rewardAToken = IAToken(rewardAToken_);
69
- }
70
-
71
- function initialize(
72
- uint256 liquidityMin_,
73
- uint256 liquidityMiddle_,
74
- uint256 liquidityMax_,
75
- uint256 claimRewardsMin_,
76
- uint256 reinvestRewardsMin_
77
- ) public initializer {
78
- __BaseAssetManager_init(liquidityMin_, liquidityMiddle_, liquidityMax_);
79
- __AaveAssetManager_init(claimRewardsMin_, reinvestRewardsMin_);
80
- }
81
-
82
- // solhint-disable-next-line func-name-mixedcase
83
- function __AaveAssetManager_init(uint256 claimRewardsMin_, uint256 reinvestRewardsMin_)
84
- internal
85
- initializer
86
- {
87
- _claimRewardsMin = claimRewardsMin_;
88
- _reinvestRewardsMin = reinvestRewardsMin_;
89
- }
90
-
91
- function getInvestmentValue() public view override returns (uint256) {
92
- uint256 balance = aToken().balanceOf(address(this));
93
- uint256 rewardBalance = rewardToken().balanceOf(address(this)) +
94
- rewardAToken().balanceOf(address(this));
95
- // Don't count unclaimedRewards as part of investmentValue to save gas and because if doing that will
96
- // also need to claim rewards as part of _deinvest process
97
- return balance + _rewardToCurrency(rewardBalance);
98
- }
99
-
100
- function unclaimedRewards() public view returns (uint256) {
101
- // Also add unclaimed rewards
102
- IAToken atk = aToken();
103
- address[] memory atks = new address[](2);
104
- atks[0] = address(atk);
105
- atks[1] = address(rewardAToken());
106
- return atk.getIncentivesController().getRewardsBalance(atks, address(this));
107
- }
108
-
109
- function _claimRewards(bool ignoreMin) internal returns (uint256) {
110
- if (ignoreMin || unclaimedRewards() > _claimRewardsMin) {
111
- IAToken atk = aToken();
112
- address[] memory atks = new address[](2);
113
- atks[0] = address(atk);
114
- atks[1] = address(rewardAToken());
115
- return atk.getIncentivesController().claimRewards(atks, type(uint256).max, address(this));
116
- } else {
117
- return 0;
118
- }
119
- }
120
-
121
- function lendingPool() public view returns (ILendingPool) {
122
- return ILendingPool(_aaveAddrProv.getLendingPool());
123
- }
124
-
125
- function _aaveDataProvider() internal view returns (AaveProtocolDataProvider) {
126
- return AaveProtocolDataProvider(_aaveAddrProv.getAddress(DATA_PROVIDER_ID));
127
- }
128
-
129
- function _exchange() internal view returns (IExchange) {
130
- return policyPool().config().exchange();
131
- }
132
-
133
- function aToken() public view returns (IAToken) {
134
- return _aToken;
135
- }
136
-
137
- function rewardToken() public view returns (IERC20Metadata) {
138
- return _rewardToken;
139
- }
140
-
141
- function rewardAToken() public view returns (IAToken) {
142
- return _rewardAToken;
143
- }
144
-
145
- function _exchangePath() internal view returns (address[] memory) {
146
- address[] memory path = new address[](2);
147
- path[0] = address(rewardToken());
148
- path[1] = address(currency());
149
- return path;
150
- }
151
-
152
- function _rewardToCurrency(uint256 amount) internal view returns (uint256) {
153
- return _exchange().convert(address(rewardToken()), address(currency()), amount);
154
- }
155
-
156
- function reinvestRewardToken() public {
157
- ILendingPool lendingPool_ = lendingPool();
158
- IERC20Metadata token = rewardToken();
159
- uint256 rewardBalance = token.balanceOf(address(this));
160
- if (rewardBalance <= _reinvestRewardsMin) return;
161
- token.approve(address(lendingPool_), rewardBalance);
162
- lendingPool_.deposit(address(token), rewardBalance, address(this), 0);
163
- }
164
-
165
- function _swapRewards(uint256 amount, address outAddr) internal returns (uint256, uint256) {
166
- IERC20Metadata rw = rewardToken();
167
- uint256 swapIn = rw.balanceOf(address(this));
168
- if (swapIn < amount) {
169
- uint256 toWithdraw = amount - swapIn;
170
- if (rewardAToken().balanceOf(address(this)) < toWithdraw) {
171
- toWithdraw = type(uint256).max; // if not enought withdraw all
172
- }
173
- swapIn += lendingPool().withdraw(address(rw), toWithdraw, address(this));
174
- } else {
175
- swapIn = amount;
176
- }
177
- address swapRouter = _exchange().getSwapRouter();
178
- rw.approve(swapRouter, swapIn);
179
- bytes memory swapCall = _exchange().sell(
180
- address(rw),
181
- address(currency()),
182
- swapIn,
183
- outAddr,
184
- block.timestamp
185
- );
186
-
187
- bytes memory response = swapRouter.functionCall(swapCall, "Swap operation failed");
188
- uint256 swapOut = _exchange().decodeSwapOut(response);
189
- emit RewardSwapped(swapIn, swapOut);
190
- return (swapIn, swapOut);
191
- }
192
-
193
- function swapRewards(uint256 amount)
194
- external
195
- onlyPoolRole(SWAP_REWARDS_ROLE)
196
- returns (uint256, uint256)
197
- {
198
- (uint256 swapIn, uint256 swapOut) = _swapRewards(amount, address(this));
199
- ILendingPool lendingPool_ = lendingPool();
200
- IERC20Metadata token = currency();
201
- token.approve(address(lendingPool_), swapOut);
202
- lendingPool_.deposit(address(token), swapOut, address(this), 0);
203
- return (swapIn, swapOut);
204
- }
205
-
206
- function rebalance() public virtual override whenNotPaused {
207
- _claimRewards(false);
208
- super.rebalance();
209
- reinvestRewardToken();
210
- }
211
-
212
- function _invest(uint256 amount) internal override {
213
- ILendingPool lendingPool_ = lendingPool();
214
- IERC20Metadata token = currency();
215
- token.safeTransferFrom(address(_policyPool), address(this), amount);
216
- token.approve(address(lendingPool_), amount);
217
- lendingPool_.deposit(address(token), amount, address(this), 0);
218
- super._invest(amount);
219
- }
220
-
221
- function _deinvest(uint256 amount) internal override {
222
- uint256 remainingAmount = amount;
223
- uint256 toWithdraw = amount;
224
- if (aToken().balanceOf(address(this)) < toWithdraw) {
225
- toWithdraw = type(uint256).max;
226
- }
227
- remainingAmount -= lendingPool().withdraw(
228
- address(currency()),
229
- toWithdraw,
230
- address(_policyPool) // Withdraw directly to _policyPool
231
- );
232
- if (remainingAmount > 0) {
233
- // In this case, it's safe using getAmountsIn to compute how many rewards are needed to swap
234
- // but then, when I do the swap I validate the slippage with the market price (given by AAVE's Oracle)
235
- // is acceptable
236
- uint256 requiredRewards = _exchange().getAmountIn(
237
- address(rewardToken()),
238
- address(currency()),
239
- remainingAmount
240
- );
241
- (, uint256 currencyOut) = _swapRewards(requiredRewards, address(_policyPool));
242
- if (currencyOut < remainingAmount) {
243
- remainingAmount -= currencyOut;
244
- } else {
245
- remainingAmount = 0;
246
- }
247
- }
248
- super._deinvest(amount - remainingAmount);
249
- }
250
-
251
- /**
252
- * @dev Deinvest all the assets and return the cash back to the PolicyPool.
253
- * Called from PolicyPool when new asset manager is assigned
254
- */
255
- function _liquidateAll() internal virtual override {
256
- _claimRewards(true);
257
- lendingPool().withdraw(
258
- address(currency()),
259
- type(uint256).max,
260
- address(_policyPool) // Withdraw directly to _policyPool
261
- );
262
- // Withdraw all rewards
263
- lendingPool().withdraw(address(_rewardToken), type(uint256).max, address(this));
264
- _swapRewards(_rewardToken.balanceOf(address(this)), address(_policyPool));
265
- }
266
-
267
- // Contract parameters
268
- function claimRewardsMin() external view returns (uint256) {
269
- return _claimRewardsMin;
270
- }
271
-
272
- function reinvestRewardsMin() external view returns (uint256) {
273
- return _reinvestRewardsMin;
274
- }
275
-
276
- function setClaimRewardsMin(uint256 newValue) external onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE) {
277
- bool tweak = !hasPoolRole(LEVEL2_ROLE);
278
- require(
279
- !tweak || _isTweakWad(_claimRewardsMin, newValue, 3e26),
280
- "Tweak exceeded: claimRewardsMin tweaks only up to 30%"
281
- );
282
- _claimRewardsMin = newValue;
283
- _parameterChanged(IPolicyPoolConfig.GovernanceActions.setClaimRewardsMin, newValue, tweak);
284
- }
285
-
286
- function setReinvestRewardsMin(uint256 newValue)
287
- external
288
- onlyPoolRole2(LEVEL2_ROLE, LEVEL3_ROLE)
289
- {
290
- bool tweak = !hasPoolRole(LEVEL2_ROLE);
291
- require(
292
- !tweak || _isTweakWad(_reinvestRewardsMin, newValue, 3e26),
293
- "Tweak exceeded: reinvestRewardsMin tweaks only up to 30%"
294
- );
295
- _reinvestRewardsMin = newValue;
296
- _parameterChanged(IPolicyPoolConfig.GovernanceActions.setReinvestRewardsMin, newValue, tweak);
297
- }
298
- }