@ensuro/core 2.0.1 → 2.1.0-beta2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/build/contracts/AccessManager.sol/AccessManager.json +2 -2
  2. package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +2 -2
  3. package/build/contracts/EToken.sol/EToken.json +71 -7
  4. package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +193 -9
  5. package/build/contracts/Policy.sol/Policy.json +2 -2
  6. package/build/contracts/PolicyPool.sol/PolicyPool.json +2 -2
  7. package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +46 -2
  8. package/build/contracts/SignedQuoteRiskModule.sol/SignedQuoteRiskModule.json +2 -2
  9. package/build/contracts/TimeScaled.sol/TimeScaled.json +2 -2
  10. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +2 -2
  11. package/build/contracts/interfaces/IEToken.sol/IEToken.json +0 -5
  12. package/build/contracts/interfaces/ILPWhitelist.sol/ILPWhitelist.json +29 -0
  13. package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +2 -2
  14. package/build/contracts/mocks/InterfaceIdCalculator.sol/InterfaceIdCalculator.json +2 -2
  15. package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +2 -2
  16. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +2 -2
  17. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +2 -2
  18. package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +2 -2
  19. package/contracts/EToken.sol +64 -17
  20. package/contracts/LPManualWhitelist.sol +97 -11
  21. package/contracts/PremiumsAccount.sol +90 -11
  22. package/contracts/RiskModule.sol +2 -2
  23. package/contracts/TimeScaled.sol +2 -9
  24. package/contracts/interfaces/IAccessManager.sol +4 -4
  25. package/contracts/interfaces/IEToken.sol +1 -7
  26. package/contracts/interfaces/ILPWhitelist.sol +14 -0
  27. package/js/deploy.js +21 -12
  28. package/js/test-utils.js +2 -2
  29. package/package.json +1 -1
@@ -220,6 +220,36 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
220
220
  return _tsScaled.getScale(tokenInterestRate()).rayMul(principalBalance.wadToRay()).rayToWad();
221
221
  }
222
222
 
223
+ // Methods following AAVE's IScaledBalanceToken, to simplify future integrations
224
+
225
+ /**
226
+ * @dev Returns the scaled balance of the user. The scaled balance is the sum of all the
227
+ * updated stored balance divided by the EToken's scale index
228
+ * @param user The user whose balance is calculated
229
+ * @return The scaled balance of the user
230
+ **/
231
+ function scaledBalanceOf(address user) external view returns (uint256) {
232
+ return _balances[user];
233
+ }
234
+
235
+ /**
236
+ * @dev Returns the scaled balance of the user and the scaled total supply.
237
+ * @param user The address of the user
238
+ * @return The scaled balance of the user
239
+ * @return The scaled balance and the scaled total supply
240
+ **/
241
+ function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256) {
242
+ return (_balances[user], uint256(_tsScaled.amount));
243
+ }
244
+
245
+ /**
246
+ * @dev Returns the (un)scaled total supply of the EToken. Equals to the sum of `scaledBalanceOf(x)` of all users
247
+ * @return The scaled total supply
248
+ **/
249
+ function scaledTotalSupply() external view returns (uint256) {
250
+ return uint256(_tsScaled.amount);
251
+ }
252
+
223
253
  /**
224
254
  * @dev See {IERC20-transfer}.
225
255
  *
@@ -481,10 +511,14 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
481
511
  uint256 totalSupply_ = this.totalSupply();
482
512
  if (totalSupply_ == 0) _scr.tokenInterestRate = 0;
483
513
  else {
484
- _scr.tokenInterestRate = uint256(_scr.interestRate)
485
- .wadMul(uint256(_scr.scr))
486
- .wadDiv(totalSupply_)
487
- .toUint64();
514
+ uint256 newTokenInterestRate = uint256(_scr.interestRate).wadMul(uint256(_scr.scr)).wadDiv(
515
+ totalSupply_
516
+ );
517
+ _scr.tokenInterestRate = (newTokenInterestRate > type(uint64).max)
518
+ ? type(uint64).max
519
+ : newTokenInterestRate.toUint64();
520
+ // This is not the mathematically correct value, but the max we can set. The actual value of the total supply
521
+ // will be adjusted when the policies expire or are resolved and the SCR is unlocked.
488
522
  }
489
523
  }
490
524
 
@@ -500,9 +534,8 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
500
534
  }
501
535
 
502
536
  function fundsAvailableToLock() public view returns (uint256) {
503
- uint256 totalSupply_ = this.totalSupply();
504
- if (totalSupply_ > uint256(_scr.scr))
505
- return (totalSupply_ - uint256(_scr.scr)).wadMul(maxUtilizationRate());
537
+ uint256 supply = this.totalSupply().wadMul(maxUtilizationRate());
538
+ if (supply > uint256(_scr.scr)) return supply - uint256(_scr.scr);
506
539
  else return 0;
507
540
  }
508
541
 
@@ -645,8 +678,15 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
645
678
  * The only limit for withdraws is the `totalWithdrawable()` function, that's affected by the relation between the
646
679
  * scr and the totalSupply.
647
680
  */
648
- amount = Math.min(amount, Math.min(balanceOf(provider), totalWithdrawable()));
681
+ uint256 maxWithdraw = Math.min(balanceOf(provider), totalWithdrawable());
682
+ if (amount == type(uint256).max) amount = maxWithdraw;
649
683
  if (amount == 0) return 0;
684
+ require(amount <= maxWithdraw, "amount > max withdrawable");
685
+ require(
686
+ address(_params.whitelist) == address(0) ||
687
+ _params.whitelist.acceptsWithdrawal(this, provider, amount),
688
+ "Liquidity Provider not whitelisted"
689
+ );
650
690
  _burn(provider, amount);
651
691
  _updateTokenInterestRate();
652
692
  _transferTo(provider, amount);
@@ -669,16 +709,23 @@ contract EToken is Reserve, IERC20Metadata, IEToken {
669
709
  emit InternalBorrowerRemoved(borrower, defaultedDebt);
670
710
  }
671
711
 
672
- function internalLoan(
673
- uint256 amount,
674
- address receiver,
675
- bool fromAvailable
676
- ) external override onlyBorrower whenNotPaused returns (uint256) {
712
+ /**
713
+ * @dev Returns the maximum negative adjustment (discrete loss) the eToken can accept without breaking consistency.
714
+ * The limit comes from limits in the internal scale that takes scaledTotalSupply() to totalSupply()
715
+ */
716
+ function maxNegativeAdjustment() public view returns (uint256) {
717
+ return totalSupply() - _tsScaled.minValue(); // Min value accepted by _tsScaled
718
+ }
719
+
720
+ function internalLoan(uint256 amount, address receiver)
721
+ external
722
+ override
723
+ onlyBorrower
724
+ whenNotPaused
725
+ returns (uint256)
726
+ {
677
727
  uint256 amountAsked = amount;
678
- amount = Math.min(
679
- Math.min(amount, fromAvailable ? fundsAvailable() : totalSupply()),
680
- _tsScaled.maxNegativeAdjustment(tokenInterestRate())
681
- );
728
+ amount = Math.min(amount, maxNegativeAdjustment());
682
729
  if (amount == 0) return amountAsked;
683
730
  TimeScaled.ScaledAmount storage loan = _loans[_msgSender()];
684
731
  loan.add(amount, internalLoanInterestRate());
@@ -14,10 +14,27 @@ import {IEToken} from "./interfaces/IEToken.sol";
14
14
  */
15
15
  contract LPManualWhitelist is ILPWhitelist, PolicyPoolComponent {
16
16
  bytes32 public constant LP_WHITELIST_ROLE = keccak256("LP_WHITELIST_ROLE");
17
+ bytes32 public constant LP_WHITELIST_ADMIN_ROLE = keccak256("LP_WHITELIST_ADMIN_ROLE");
17
18
 
18
- mapping(address => bool) private _whitelisted;
19
+ /**
20
+ * @dev Enum with the different options for whitelisting status
21
+ */
22
+ enum WhitelistOptions {
23
+ undefined,
24
+ whitelisted,
25
+ blacklisted
26
+ }
27
+
28
+ struct WhitelistStatus {
29
+ WhitelistOptions deposit;
30
+ WhitelistOptions withdraw;
31
+ WhitelistOptions sendTransfer;
32
+ WhitelistOptions receiveTransfer;
33
+ }
19
34
 
20
- event LPWhitelisted(address provider, bool whitelisted);
35
+ mapping(address => WhitelistStatus) private _wlStatus;
36
+
37
+ event LPWhitelistStatusChanged(address provider, WhitelistStatus whitelisted);
21
38
 
22
39
  /// @custom:oz-upgrades-unsafe-allow constructor
23
40
  // solhint-disable-next-line no-empty-blocks
@@ -26,18 +43,62 @@ contract LPManualWhitelist is ILPWhitelist, PolicyPoolComponent {
26
43
  /**
27
44
  * @dev Initializes the Whitelist contract
28
45
  */
29
- function initialize() public initializer {
46
+ function initialize(WhitelistStatus calldata defaultStatus) public virtual initializer {
47
+ __LPManualWhitelist_init(defaultStatus);
48
+ }
49
+
50
+ // solhint-disable-next-line func-name-mixedcase
51
+ function __LPManualWhitelist_init(WhitelistStatus calldata defaultStatus)
52
+ internal
53
+ onlyInitializing
54
+ {
30
55
  __PolicyPoolComponent_init();
56
+ __LPManualWhitelist_init_unchained(defaultStatus);
31
57
  }
32
58
 
33
- function whitelistAddress(address provider, bool whitelisted)
59
+ // solhint-disable-next-line func-name-mixedcase
60
+ function __LPManualWhitelist_init_unchained(WhitelistStatus calldata defaultStatus)
61
+ internal
62
+ onlyInitializing
63
+ {
64
+ _checkDefaultStatus(defaultStatus);
65
+ _wlStatus[address(0)] = defaultStatus;
66
+ emit LPWhitelistStatusChanged(address(0), defaultStatus);
67
+ }
68
+
69
+ function whitelistAddress(address provider, WhitelistStatus calldata newStatus)
34
70
  external
35
71
  onlyComponentRole(LP_WHITELIST_ROLE)
36
72
  {
37
- if (_whitelisted[provider] != whitelisted) {
38
- _whitelisted[provider] = whitelisted;
39
- emit LPWhitelisted(provider, whitelisted);
40
- }
73
+ require(provider != address(0), "You can't change the defaults");
74
+ _whitelistAddress(provider, newStatus);
75
+ }
76
+
77
+ function _checkDefaultStatus(WhitelistStatus calldata newStatus) internal pure {
78
+ require(
79
+ newStatus.deposit != WhitelistOptions.undefined &&
80
+ newStatus.withdraw != WhitelistOptions.undefined &&
81
+ newStatus.sendTransfer != WhitelistOptions.undefined &&
82
+ newStatus.receiveTransfer != WhitelistOptions.undefined,
83
+ "You need to define the default status for all the operations"
84
+ );
85
+ }
86
+
87
+ function setWhitelistDefaults(WhitelistStatus calldata newStatus)
88
+ external
89
+ onlyComponentRole(LP_WHITELIST_ADMIN_ROLE)
90
+ {
91
+ _checkDefaultStatus(newStatus);
92
+ _whitelistAddress(address(0), newStatus);
93
+ }
94
+
95
+ function getWhitelistDefaults() external view returns (WhitelistStatus memory) {
96
+ return _wlStatus[address(0)];
97
+ }
98
+
99
+ function _whitelistAddress(address provider, WhitelistStatus memory newStatus) internal {
100
+ _wlStatus[provider] = newStatus;
101
+ emit LPWhitelistStatusChanged(provider, newStatus);
41
102
  }
42
103
 
43
104
  /**
@@ -52,16 +113,41 @@ contract LPManualWhitelist is ILPWhitelist, PolicyPoolComponent {
52
113
  address provider,
53
114
  uint256
54
115
  ) external view override returns (bool) {
55
- return _whitelisted[provider];
116
+ WhitelistOptions wl = _wlStatus[provider].deposit;
117
+ if (wl == WhitelistOptions.undefined) {
118
+ wl = _wlStatus[address(0)].deposit;
119
+ }
120
+ return wl == WhitelistOptions.whitelisted;
121
+ }
122
+
123
+ function acceptsWithdrawal(
124
+ IEToken,
125
+ address provider,
126
+ uint256
127
+ ) external view override returns (bool) {
128
+ WhitelistOptions wl = _wlStatus[provider].withdraw;
129
+ if (wl == WhitelistOptions.undefined) {
130
+ wl = _wlStatus[address(0)].withdraw;
131
+ }
132
+ return wl == WhitelistOptions.whitelisted;
56
133
  }
57
134
 
58
135
  function acceptsTransfer(
59
136
  IEToken,
60
- address,
137
+ address providerFrom,
61
138
  address providerTo,
62
139
  uint256
63
140
  ) external view override returns (bool) {
64
- return _whitelisted[providerTo];
141
+ WhitelistOptions wl = _wlStatus[providerFrom].sendTransfer;
142
+ if (wl == WhitelistOptions.undefined) {
143
+ wl = _wlStatus[address(0)].sendTransfer;
144
+ }
145
+ if (wl != WhitelistOptions.whitelisted) return false;
146
+ wl = _wlStatus[providerTo].receiveTransfer;
147
+ if (wl == WhitelistOptions.undefined) {
148
+ wl = _wlStatus[address(0)].receiveTransfer;
149
+ }
150
+ return wl == WhitelistOptions.whitelisted;
65
151
  }
66
152
 
67
153
  /**
@@ -65,9 +65,20 @@ contract PremiumsAccount is IPremiumsAccount, Reserve {
65
65
  */
66
66
  int256 internal _surplus;
67
67
 
68
+ /**
69
+ * @dev This struct has the parameters that can be modified by governance
70
+ * @member deficitRatio A value between [0, 1] that defines the percentage of active pure premiums that can be used
71
+ * to cover losses.
72
+ * @member assetManager This is the implementation contract that manages the PremiumsAccount's funds. See
73
+ * {IAssetManager}
74
+ * @member jrLoanLimit This is the maximum amount that can be borrowed from the Junior eToken (without decimals)
75
+ * @member srLoanLimit This is the maximum amount that can be borrowed from the Senior eToken (without decimals)
76
+ */
68
77
  struct PackedParams {
69
78
  uint16 deficitRatio;
70
79
  IAssetManager assetManager;
80
+ uint32 jrLoanLimit;
81
+ uint32 srLoanLimit;
71
82
  }
72
83
 
73
84
  PackedParams internal _params;
@@ -120,7 +131,9 @@ contract PremiumsAccount is IPremiumsAccount, Reserve {
120
131
  */
121
132
  _params = PackedParams({
122
133
  deficitRatio: HUNDRED_PERCENT,
123
- assetManager: IAssetManager(address(0))
134
+ assetManager: IAssetManager(address(0)),
135
+ jrLoanLimit: 0,
136
+ srLoanLimit: 0
124
137
  });
125
138
  _validateParameters();
126
139
  }
@@ -240,6 +253,16 @@ contract PremiumsAccount is IPremiumsAccount, Reserve {
240
253
  return -int256(_activePurePremiums.wadMul(ratio));
241
254
  }
242
255
 
256
+ function _toAmount(uint32 value) internal view returns (uint256) {
257
+ // 0 decimals to amount decimals
258
+ return uint256(value) * 10**currency().decimals();
259
+ }
260
+
261
+ function _toZeroDecimals(uint256 amount) internal view returns (uint32) {
262
+ // Removes the decimals from the amount
263
+ return (amount / 10**currency().decimals()).toUint32();
264
+ }
265
+
243
266
  /**
244
267
  * @dev Returns the percentage of the active pure premiums that can be used to cover losses of finalized policies.
245
268
  */
@@ -247,6 +270,20 @@ contract PremiumsAccount is IPremiumsAccount, Reserve {
247
270
  return uint256(_params.deficitRatio) * FOUR_DECIMAL_TO_WAD; // 4 -> 18 decimals
248
271
  }
249
272
 
273
+ /**
274
+ * @dev Returns the limit on the Junior eToken loans (infinite if _params.jrLoanLimit == 0)
275
+ */
276
+ function jrLoanLimit() public view returns (uint256) {
277
+ return _params.jrLoanLimit == 0 ? type(uint256).max : _toAmount(_params.jrLoanLimit);
278
+ }
279
+
280
+ /**
281
+ * @dev Returns the limit on the Senior eToken loans (infinite if _params.srLoanLimit == 0)
282
+ */
283
+ function srLoanLimit() public view returns (uint256) {
284
+ return _params.srLoanLimit == 0 ? type(uint256).max : _toAmount(_params.srLoanLimit);
285
+ }
286
+
250
287
  /**
251
288
  * @dev Changes the `deficitRatio` parameter.
252
289
  *
@@ -262,7 +299,7 @@ contract PremiumsAccount is IPremiumsAccount, Reserve {
262
299
  */
263
300
  function setDeficitRatio(uint256 newRatio, bool adjustment)
264
301
  external
265
- onlyComponentRole(LEVEL2_ROLE)
302
+ onlyGlobalOrComponentRole(LEVEL2_ROLE)
266
303
  {
267
304
  require(newRatio <= 1e18, "Validation: deficitRatio must be <= 1");
268
305
 
@@ -287,6 +324,36 @@ contract PremiumsAccount is IPremiumsAccount, Reserve {
287
324
  _parameterChanged(action, newRatio, false);
288
325
  }
289
326
 
327
+ /**
328
+ * @dev Changes the `jrLoanLimit` or `srLoanLimit` parameter.
329
+ *
330
+ * Requirements:
331
+ * - onlyGlobalOrComponentRole(LEVEL2_ROLE)
332
+ *
333
+ * Events:
334
+ * - Emits GovernanceAction with action = setDeficitRatio or setDeficitRatioWithAdjustment if an adjustment was made.
335
+ *
336
+ * @param newLimitJr The new limit to be set for the loans taken from the Junior eToken.
337
+ If newLimitJr == MAX_UINT, it's ignored. If == 0, means the loans are unbounded.
338
+ * @param newLimitSr The new limit to be set for the loans taken from the Senior eToken.
339
+ If newLimitSr == MAX_UINT, it's ignored. If == 0, means the loans are unbounded.
340
+ */
341
+ function setLoanLimits(uint256 newLimitJr, uint256 newLimitSr)
342
+ external
343
+ onlyGlobalOrComponentRole(LEVEL2_ROLE)
344
+ {
345
+ if (newLimitJr != type(uint256).max) {
346
+ _params.jrLoanLimit = _toZeroDecimals(newLimitJr);
347
+ require(_toAmount(_params.jrLoanLimit) == newLimitJr, "Validation: no decimals allowed");
348
+ _parameterChanged(IAccessManager.GovernanceActions.setJrLoanLimit, newLimitJr, false);
349
+ }
350
+ if (newLimitSr != type(uint256).max) {
351
+ _params.srLoanLimit = _toZeroDecimals(newLimitSr);
352
+ require(_toAmount(_params.srLoanLimit) == newLimitSr, "Validation: no decimals allowed");
353
+ _parameterChanged(IAccessManager.GovernanceActions.setSrLoanLimit, newLimitSr, false);
354
+ }
355
+ }
356
+
290
357
  /**
291
358
  * @dev Internal function called when money in the PremiumsAccount is not enough and we need to borrow from the
292
359
  * eTokens.
@@ -302,17 +369,22 @@ contract PremiumsAccount is IPremiumsAccount, Reserve {
302
369
  bool jrEtk
303
370
  ) internal {
304
371
  require(receiver != address(0), "PremiumsAccount: receiver cannot be the zero address");
305
- uint256 left;
372
+ uint256 left = borrow;
306
373
  if (jrEtk) {
307
- // Consume Junior Pool until exhausted
308
- left = _juniorEtk.internalLoan(borrow, receiver, false);
309
- } else {
310
- left = borrow;
374
+ if (_juniorEtk.getLoan(address(this)) + borrow <= jrLoanLimit()) {
375
+ left = _juniorEtk.internalLoan(borrow, receiver);
376
+ } else if (_juniorEtk.getLoan(address(this)) < jrLoanLimit()) {
377
+ // Partial loan
378
+ uint256 loanExcess = _juniorEtk.getLoan(address(this)) + borrow - jrLoanLimit();
379
+ left = loanExcess + _juniorEtk.internalLoan(borrow - loanExcess, receiver);
380
+ }
311
381
  }
312
382
  if (left > NEGLIGIBLE_AMOUNT) {
313
383
  // Consume Senior Pool only up to SCR
314
- left = _seniorEtk.internalLoan(left, receiver, true);
315
- require(left <= NEGLIGIBLE_AMOUNT, "Don't know where to take the rest of the money");
384
+ if (_seniorEtk.getLoan(address(this)) + left < srLoanLimit()) {
385
+ left = _seniorEtk.internalLoan(left, receiver);
386
+ } // in the senior eToken doesn't make sense to handle partial loan
387
+ require(left <= NEGLIGIBLE_AMOUNT, "Don't know where to source the rest of the money");
316
388
  }
317
389
  }
318
390
 
@@ -360,9 +432,16 @@ contract PremiumsAccount is IPremiumsAccount, Reserve {
360
432
  * @param amount The amount to be transferred.
361
433
  */
362
434
  function receiveGrant(uint256 amount) external {
363
- _storePurePremiumWon(amount);
364
- emit WonPremiumsInOut(true, amount);
435
+ // I need to receive the money first (without following the Check-Effects-Interactions) pattern because I need
436
+ // the money to pay the eTokens
365
437
  currency().safeTransferFrom(_msgSender(), address(this), amount);
438
+ uint256 purePremiumWon = amount;
439
+ if (address(_seniorEtk) != address(0)) purePremiumWon = _repayLoan(purePremiumWon, _seniorEtk);
440
+ if (address(_juniorEtk) != address(0)) purePremiumWon = _repayLoan(purePremiumWon, _juniorEtk);
441
+
442
+ // Finally store purePremiumWon
443
+ _storePurePremiumWon(purePremiumWon);
444
+ emit WonPremiumsInOut(true, amount);
366
445
  }
367
446
 
368
447
  /**
@@ -185,12 +185,12 @@ abstract contract RiskModule is IRiskModule, PolicyPoolComponent {
185
185
 
186
186
  // solhint-disable-next-line func-name-mixedcase
187
187
  function _XtoAmount(uint8 decimals, uint32 value) internal view returns (uint256) {
188
- // X decimals to Wad (18 decimals)
188
+ // X decimals to currency decimals (6 for USDC)
189
189
  return uint256(value) * 10**(currency().decimals() - decimals);
190
190
  }
191
191
 
192
192
  function _amountToX(uint8 decimals, uint256 value) internal view returns (uint32) {
193
- // Wad to X decimals
193
+ // currency decimals to X decimals (assuming X < currency decimals)
194
194
  return (value / 10**(currency().decimals() - decimals)).toUint32();
195
195
  }
196
196
 
@@ -125,14 +125,7 @@ library TimeScaled {
125
125
  require(scaledAmount.scale >= MIN_SCALE, "Scale too small, can lead to rounding errors");
126
126
  }
127
127
 
128
- function maxNegativeAdjustment(ScaledAmount storage scaledAmount, uint256 interestRate)
129
- internal
130
- view
131
- returns (uint256)
132
- {
133
- uint256 ts = getScaledAmount(scaledAmount, interestRate);
134
- uint256 minTs = uint256(scaledAmount.amount).wadToRay().rayMul(MIN_SCALE).rayToWad();
135
- if (ts > minTs) return ts - minTs;
136
- else return 0;
128
+ function minValue(ScaledAmount storage scaledAmount) internal view returns (uint256) {
129
+ return uint256(scaledAmount.amount).wadToRay().rayMul(MIN_SCALE).rayToWad();
137
130
  }
138
131
  }
@@ -52,10 +52,10 @@ interface IAccessManager is IAccessControlUpgradeable {
52
52
  // PremiumsAccount Governance Actions
53
53
  setDeficitRatio,
54
54
  setDeficitRatioWithAdjustment,
55
- paFiller1,
56
- paFiller2,
57
- paFiller3,
58
- paFiller4,
55
+ setJrLoanLimit,
56
+ setSrLoanLimit,
57
+ paFiller3, // Reserve space for future PremiumsAccount actions
58
+ paFiller4, // Reserve space for future PremiumsAccount actions
59
59
  // AssetManager Governance Actions
60
60
  setLiquidityMin,
61
61
  setLiquidityMiddle,
@@ -152,15 +152,9 @@ interface IEToken is IERC20 {
152
152
  *
153
153
  * @param amount The amount required
154
154
  * @param receiver The received of the funds lent. This is usually the policyholder if the loan is used for a payout.
155
- * @param fromAvailable If `true`, the funds that can be lent are only the available ones, i.e., excluding the funds
156
- * locked as `scr()`. If `false`, all the `totalSupply()` is available to be lent.
157
155
  * @return Returns the amount that wasn't able to fulfil. `amount - lent`
158
156
  */
159
- function internalLoan(
160
- uint256 amount,
161
- address receiver,
162
- bool fromAvailable
163
- ) external returns (uint256);
157
+ function internalLoan(uint256 amount, address receiver) external returns (uint256);
164
158
 
165
159
  /**
166
160
  * @dev Repays a loan taken with `internalLoan`.
@@ -37,4 +37,18 @@ interface ILPWhitelist {
37
37
  address providerTo,
38
38
  uint256 amount
39
39
  ) external view returns (bool);
40
+
41
+ /**
42
+ * @dev Indicates whether or not a liquidity provider can withdraw an eToken.
43
+ *
44
+ * @param etoken The eToken (see {EToken}) where the provider wants to withdraw money.
45
+ * @param provider The address of the liquidity provider (user) that wants to withdraw
46
+ * @param amount The amount of the withdrawal
47
+ * @return true if `provider` withdraw request is accepted, false if not
48
+ */
49
+ function acceptsWithdrawal(
50
+ IEToken etoken,
51
+ address provider,
52
+ uint256 amount
53
+ ) external view returns (bool);
40
54
  }
package/js/deploy.js CHANGED
@@ -7,6 +7,12 @@ const _BN = ethers.BigNumber.from;
7
7
  const WAD = _BN(1e10).mul(_BN(1e8)); // 1e10*1e8=1e18
8
8
  const RAY = WAD.mul(_BN(1e9)); // 1e18*1e9=1e27
9
9
 
10
+ const WhitelistStatus = {
11
+ notdefined: 0,
12
+ whitelisted: 1,
13
+ blacklisted: 2,
14
+ };
15
+
10
16
  /**
11
17
  * Creates a fixed-point conversion function for the desired number of decimals
12
18
  * @param decimals The number of decimals. Must be >= 6.
@@ -153,10 +159,8 @@ async function deployProxyContract({ saveAddr, verify, contractClass, constructo
153
159
  }
154
160
 
155
161
  function parseRole(role) {
156
- if (role.startsWith("0x"))
157
- return role;
158
- if (role === "DEFAULT_ADMIN_ROLE")
159
- return ethers.constants.HashZero;
162
+ if (role.startsWith("0x")) return role;
163
+ if (role === "DEFAULT_ADMIN_ROLE") return ethers.constants.HashZero;
160
164
  return ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
161
165
  }
162
166
 
@@ -255,8 +259,7 @@ async function deployEToken(
255
259
  hre
256
260
  );
257
261
  const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
258
- if (opts.addComponent)
259
- await policyPool.addComponent(contract.address, 1);
262
+ if (opts.addComponent) await policyPool.addComponent(contract.address, 1);
260
263
  return contract.address;
261
264
  }
262
265
 
@@ -271,8 +274,7 @@ async function deployPremiumsAccount({ poolAddress, juniorEtk, seniorEtk, ...opt
271
274
  hre
272
275
  );
273
276
  const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
274
- if (opts.addComponent)
275
- await policyPool.addComponent(contract.address, 3);
277
+ if (opts.addComponent) await policyPool.addComponent(contract.address, 3);
276
278
  return contract.address;
277
279
  }
278
280
 
@@ -338,11 +340,10 @@ async function deployRiskModule(
338
340
  await rm.setParam(4, ensuroCocFee);
339
341
  }
340
342
  if (maxDuration != 24 * 365) {
341
- await rm.setParam(9, ensuroCocFee);
343
+ await rm.setParam(9, maxDuration);
342
344
  }
343
345
  const policyPool = await hre.ethers.getContractAt("PolicyPool", poolAddress);
344
- if (opts.addComponent)
345
- await policyPool.addComponent(contract.address, 2);
346
+ if (opts.addComponent) await policyPool.addComponent(contract.address, 2);
346
347
  return contract.address;
347
348
  }
348
349
 
@@ -415,10 +416,16 @@ async function deployAaveAssetManager({ asset, aave, amClass, ...opts }, hre) {
415
416
  }
416
417
 
417
418
  async function deployWhitelist(
418
- { wlClass, poolAddress, extraConstructorArgs, extraArgs, eToken, eToken2, eToken3, ...opts },
419
+ { wlClass, poolAddress, extraConstructorArgs, extraArgs, eToken, eToken2, eToken3, defaultStatus, ...opts },
419
420
  hre
420
421
  ) {
421
422
  extraArgs = extraArgs || [];
423
+ if (defaultStatus !== "") {
424
+ defaultStatus = defaultStatus
425
+ .split("")
426
+ .map((WB) => (WB == "W" ? WhitelistStatus.whitelisted : WhitelistStatus.blacklisted));
427
+ extraArgs.splice(0, 0, defaultStatus);
428
+ }
422
429
  extraConstructorArgs = extraConstructorArgs || [];
423
430
  const { contract } = await deployProxyContract(
424
431
  {
@@ -706,6 +713,7 @@ function add_task() {
706
713
  .addOptionalParam("eToken", "Set the Whitelist to a given eToken", undefined, types.address)
707
714
  .addOptionalParam("eToken2", "Set the Whitelist to a given eToken", undefined, types.address)
708
715
  .addOptionalParam("eToken3", "Set the Whitelist to a given eToken", undefined, types.address)
716
+ .addOptionalParam("defaultStatus", "Default Status Ej: 'BWWB'", "BWWB", types.str)
709
717
  .addParam("poolAddress", "PolicyPool Address", types.address)
710
718
  .setAction(deployWhitelist);
711
719
 
@@ -776,4 +784,5 @@ module.exports = {
776
784
  deploySignedQuoteRM,
777
785
  setAssetManager,
778
786
  deployWhitelist,
787
+ WhitelistStatus,
779
788
  };
package/js/test-utils.js CHANGED
@@ -414,8 +414,8 @@ function makePolicyId(rm, internalId) {
414
414
 
415
415
  exports.makePolicyId = makePolicyId;
416
416
 
417
- async function makePolicy(pool, rm, cust, payout, premium, lossProb, expiration, internalId) {
418
- let tx = await rm.connect(cust).newPolicy(payout, premium, lossProb, expiration, cust.address, internalId);
417
+ async function makePolicy(pool, rm, cust, payout, premium, lossProb, expiration, internalId, method = "newPolicy") {
418
+ let tx = await rm.connect(cust)[method](payout, premium, lossProb, expiration, cust.address, internalId);
419
419
  let receipt = await tx.wait();
420
420
  const newPolicyEvt = getTransactionEvent(pool.interface, receipt, "NewPolicy");
421
421
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ensuro/core",
3
3
  "description": "Ensuro - Decentralized insurance protocol",
4
- "version": "2.0.1",
4
+ "version": "2.1.0-beta2",
5
5
  "files": [
6
6
  "**/*.sol",
7
7
  "/build/contracts/*.json",