@gearbox-protocol/sdk 16.3.2 → 16.4.0-next.10

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 (139) hide show
  1. package/dist/cjs/dev/index.js +3 -2
  2. package/dist/cjs/dev/kycUtils.js +18 -35
  3. package/dist/cjs/dev/midasUtils.js +40 -11
  4. package/dist/cjs/dev/securitizeUtils.js +14 -10
  5. package/dist/cjs/dev/withdrawalUtils.js +3 -6
  6. package/dist/cjs/model/errors/index.js +2 -0
  7. package/dist/cjs/model/errors/operation-errors.js +18 -0
  8. package/dist/cjs/model/index.js +2 -0
  9. package/dist/cjs/onchain/accounts/CreditAccountsServiceV310.js +0 -1
  10. package/dist/cjs/onchain/accounts/intents/borrow.js +139 -0
  11. package/dist/cjs/onchain/accounts/intents/collateral-valuation.js +41 -0
  12. package/dist/cjs/onchain/accounts/intents/guards.js +15 -3
  13. package/dist/cjs/onchain/accounts/intents/index.js +107 -20
  14. package/dist/cjs/onchain/accounts/intents/leverage-band.js +2 -12
  15. package/dist/cjs/onchain/accounts/intents/maxBorrow.js +89 -0
  16. package/dist/cjs/onchain/accounts/intents/maxWithdrawCollateral.js +15 -41
  17. package/dist/cjs/onchain/accounts/intents/open-strategy.js +6 -45
  18. package/dist/cjs/onchain/accounts/intents/realize.js +54 -2
  19. package/dist/cjs/onchain/accounts/intents/tail.js +1 -1
  20. package/dist/cjs/onchain/accounts/intents/testing/sdk-mock.js +1 -0
  21. package/dist/cjs/onchain/accounts/intents/utils/common.js +19 -0
  22. package/dist/cjs/onchain/accounts/intents/utils/credit-account-slice.js +21 -0
  23. package/dist/cjs/onchain/accounts/intents/utils/index.js +2 -0
  24. package/dist/cjs/onchain/accounts/intents/utils/price-impact.js +3 -3
  25. package/dist/cjs/onchain/accounts/intents/withdraw-limits.js +97 -0
  26. package/dist/cjs/onchain/core/createAddressProvider.js +2 -5
  27. package/dist/cjs/onchain/index.js +6 -0
  28. package/dist/cjs/onchain/market/adapters/abi/conctructorAbi.js +1 -1
  29. package/dist/cjs/onchain/market/adapters/contracts/MidasGatewayAdapterContract.js +11 -3
  30. package/dist/cjs/onchain/positions/calcHealthFactor.js +3 -3
  31. package/dist/cjs/onchain/preview/index.js +2 -0
  32. package/dist/cjs/onchain/preview/preview/index.js +2 -0
  33. package/dist/cjs/onchain/preview/preview/midasGreenlistsAccount.js +17 -0
  34. package/dist/cjs/onchain/preview/preview/previewOpenStrategyPosition.js +13 -16
  35. package/dist/cjs/onchain/preview/preview/previewOperation.js +19 -11
  36. package/dist/cjs/onchain/preview/preview/replayMulticall.js +4 -3
  37. package/dist/cjs/onchain/validation/bundles/checkCollateralFunding.js +3 -3
  38. package/dist/cjs/onchain/validation/bundles/checkCreditOperation.js +4 -3
  39. package/dist/cjs/onchain/validation/bundles/checkMidasAccountGreenlist.js +44 -0
  40. package/dist/cjs/onchain/validation/bundles/checkRWAOpening.js +16 -7
  41. package/dist/cjs/onchain/validation/bundles/index.js +2 -0
  42. package/dist/cjs/onchain/validation/checkOperation.js +0 -1
  43. package/dist/cjs/onchain/validation/checks/checkReservePriceLimited.js +30 -0
  44. package/dist/cjs/onchain/validation/checks/index.js +2 -0
  45. package/dist/cjs/onchain/validation/index.js +4 -0
  46. package/dist/cjs/sdk/execute/ExecuteApi.js +65 -5
  47. package/dist/cjs/sdk/prepare/PrepareApi.js +89 -14
  48. package/dist/esm/dev/index.js +3 -3
  49. package/dist/esm/dev/kycUtils.js +17 -33
  50. package/dist/esm/dev/midasUtils.js +39 -12
  51. package/dist/esm/dev/securitizeUtils.js +15 -11
  52. package/dist/esm/dev/withdrawalUtils.js +3 -6
  53. package/dist/esm/model/errors/index.js +2 -2
  54. package/dist/esm/model/errors/operation-errors.js +17 -1
  55. package/dist/esm/model/index.js +2 -2
  56. package/dist/esm/onchain/accounts/CreditAccountsServiceV310.js +0 -1
  57. package/dist/esm/onchain/accounts/intents/borrow.js +137 -0
  58. package/dist/esm/onchain/accounts/intents/collateral-valuation.js +40 -0
  59. package/dist/esm/onchain/accounts/intents/guards.js +15 -3
  60. package/dist/esm/onchain/accounts/intents/index.js +107 -20
  61. package/dist/esm/onchain/accounts/intents/leverage-band.js +2 -12
  62. package/dist/esm/onchain/accounts/intents/maxBorrow.js +87 -0
  63. package/dist/esm/onchain/accounts/intents/maxWithdrawCollateral.js +15 -41
  64. package/dist/esm/onchain/accounts/intents/open-strategy.js +6 -45
  65. package/dist/esm/onchain/accounts/intents/realize.js +54 -2
  66. package/dist/esm/onchain/accounts/intents/tail.js +1 -1
  67. package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +1 -0
  68. package/dist/esm/onchain/accounts/intents/utils/common.js +19 -1
  69. package/dist/esm/onchain/accounts/intents/utils/credit-account-slice.js +21 -1
  70. package/dist/esm/onchain/accounts/intents/utils/index.js +3 -3
  71. package/dist/esm/onchain/accounts/intents/utils/price-impact.js +3 -3
  72. package/dist/esm/onchain/accounts/intents/withdraw-limits.js +95 -0
  73. package/dist/esm/onchain/core/createAddressProvider.js +2 -5
  74. package/dist/esm/onchain/index.js +4 -1
  75. package/dist/esm/onchain/market/adapters/abi/conctructorAbi.js +1 -1
  76. package/dist/esm/onchain/market/adapters/contracts/MidasGatewayAdapterContract.js +11 -3
  77. package/dist/esm/onchain/positions/calcHealthFactor.js +3 -3
  78. package/dist/esm/onchain/preview/index.js +2 -1
  79. package/dist/esm/onchain/preview/preview/index.js +2 -1
  80. package/dist/esm/onchain/preview/preview/midasGreenlistsAccount.js +16 -0
  81. package/dist/esm/onchain/preview/preview/previewOpenStrategyPosition.js +14 -17
  82. package/dist/esm/onchain/preview/preview/previewOperation.js +19 -11
  83. package/dist/esm/onchain/preview/preview/replayMulticall.js +4 -3
  84. package/dist/esm/onchain/validation/bundles/checkCollateralFunding.js +3 -3
  85. package/dist/esm/onchain/validation/bundles/checkCreditOperation.js +4 -3
  86. package/dist/esm/onchain/validation/bundles/checkMidasAccountGreenlist.js +43 -0
  87. package/dist/esm/onchain/validation/bundles/checkRWAOpening.js +16 -7
  88. package/dist/esm/onchain/validation/bundles/index.js +2 -1
  89. package/dist/esm/onchain/validation/checkOperation.js +0 -1
  90. package/dist/esm/onchain/validation/checks/checkReservePriceLimited.js +29 -0
  91. package/dist/esm/onchain/validation/checks/index.js +2 -1
  92. package/dist/esm/onchain/validation/index.js +3 -1
  93. package/dist/esm/sdk/execute/ExecuteApi.js +65 -5
  94. package/dist/esm/sdk/prepare/PrepareApi.js +89 -14
  95. package/dist/types/dev/index.d.ts +3 -3
  96. package/dist/types/dev/kycUtils.d.ts +1 -5
  97. package/dist/types/dev/midasUtils.d.ts +11 -1
  98. package/dist/types/model/errors/index.d.ts +2 -2
  99. package/dist/types/model/errors/operation-errors.d.ts +54 -1
  100. package/dist/types/model/index.d.ts +3 -3
  101. package/dist/types/model/previews.d.ts +25 -19
  102. package/dist/types/onchain/accounts/index.d.ts +4 -3
  103. package/dist/types/onchain/accounts/intents/borrow.d.ts +141 -0
  104. package/dist/types/onchain/accounts/intents/collateral-valuation.d.ts +42 -0
  105. package/dist/types/onchain/accounts/intents/guards.d.ts +18 -2
  106. package/dist/types/onchain/accounts/intents/index.d.ts +102 -14
  107. package/dist/types/onchain/accounts/intents/maxBorrow.d.ts +54 -0
  108. package/dist/types/onchain/accounts/intents/maxWithdrawCollateral.d.ts +3 -8
  109. package/dist/types/onchain/accounts/intents/open-strategy.d.ts +3 -17
  110. package/dist/types/onchain/accounts/intents/testing/sdk-mock.d.ts +2 -0
  111. package/dist/types/onchain/accounts/intents/tests/open-strategy.fixtures.d.ts +2 -2
  112. package/dist/types/onchain/accounts/intents/types.d.ts +41 -5
  113. package/dist/types/onchain/accounts/intents/utils/common.d.ts +15 -1
  114. package/dist/types/onchain/accounts/intents/utils/credit-account-slice.d.ts +14 -1
  115. package/dist/types/onchain/accounts/intents/utils/index.d.ts +3 -3
  116. package/dist/types/onchain/accounts/intents/withdraw-limits.d.ts +80 -0
  117. package/dist/types/onchain/index.d.ts +8 -4
  118. package/dist/types/onchain/market/adapters/contracts/MidasGatewayAdapterContract.d.ts +8 -2
  119. package/dist/types/onchain/preview/index.d.ts +2 -1
  120. package/dist/types/onchain/preview/preview/index.d.ts +2 -1
  121. package/dist/types/onchain/preview/preview/midasGreenlistsAccount.d.ts +13 -0
  122. package/dist/types/onchain/preview/preview/previewOpenStrategyPosition.d.ts +5 -3
  123. package/dist/types/onchain/preview/preview/replayMulticall.d.ts +8 -7
  124. package/dist/types/onchain/validation/bundles/checkCreditOperation.d.ts +2 -2
  125. package/dist/types/onchain/validation/bundles/checkMidasAccountGreenlist.d.ts +22 -0
  126. package/dist/types/onchain/validation/bundles/checkRWAOpening.d.ts +6 -4
  127. package/dist/types/onchain/validation/bundles/index.d.ts +3 -2
  128. package/dist/types/onchain/validation/checks/checkDebtLimits.d.ts +2 -2
  129. package/dist/types/onchain/validation/checks/checkReservePriceLimited.d.ts +31 -0
  130. package/dist/types/onchain/validation/checks/index.d.ts +2 -1
  131. package/dist/types/onchain/validation/index.d.ts +4 -2
  132. package/dist/types/onchain/validation/raise.d.ts +2 -2
  133. package/dist/types/sdk/execute/index.d.ts +2 -2
  134. package/dist/types/sdk/execute/types.d.ts +48 -6
  135. package/dist/types/sdk/index.d.ts +5 -4
  136. package/dist/types/sdk/prepare/PrepareApi.d.ts +16 -4
  137. package/dist/types/sdk/prepare/index.d.ts +4 -3
  138. package/dist/types/sdk/prepare/types.d.ts +199 -65
  139. package/package.json +1 -1
@@ -27,6 +27,26 @@ function toCreditAccountSlice(ca) {
27
27
  };
28
28
  }
29
29
  /**
30
+ * The slice a flow that has no account yet quotes against.
31
+ *
32
+ * Nothing of it exists on chain until the transaction lands, and nothing has
33
+ * to: the pathfinder is asked about the credit manager, and every balance the
34
+ * flow reasons about is one the transaction itself puts there. The zero
35
+ * address stands in for the account so the shape is complete.
36
+ */
37
+ function unopenedAccountSlice(args) {
38
+ return {
39
+ creditAccount: "0x0000000000000000000000000000000000000000",
40
+ creditManager: args.creditManager.toLowerCase(),
41
+ creditFacade: args.creditFacade.toLowerCase(),
42
+ underlying: args.underlying.toLowerCase(),
43
+ enabledTokensMask: 0n,
44
+ totalDebtUSD: 0n,
45
+ totalDebt: 0n,
46
+ tokens: []
47
+ };
48
+ }
49
+ /**
30
50
  * Reads an account by address and narrows it to {@link CreditAccountSlice}.
31
51
  *
32
52
  * The shared read model's `StrategyPosition` carries neither `tokens` nor
@@ -43,3 +63,4 @@ async function fetchCreditAccountSlice(sdk, creditAccount) {
43
63
  //#endregion
44
64
  exports.fetchCreditAccountSlice = fetchCreditAccountSlice;
45
65
  exports.toCreditAccountSlice = toCreditAccountSlice;
66
+ exports.unopenedAccountSlice = unopenedAccountSlice;
@@ -26,7 +26,9 @@ exports.lossRate = require_onchain_accounts_intents_utils_price_impact.lossRate;
26
26
  exports.pickFattestNonPhantomToken = require_onchain_accounts_intents_utils_pick_token.pickFattestNonPhantomToken;
27
27
  exports.quotasAfterUpdate = require_onchain_accounts_intents_utils_quotas_for_update.quotasAfterUpdate;
28
28
  exports.rankAccountTokens = require_onchain_accounts_intents_utils_pick_token.rankAccountTokens;
29
+ exports.resolveCreditManager = require_onchain_accounts_intents_utils_common.resolveCreditManager;
29
30
  exports.startProbe = require_onchain_accounts_intents_utils_price_impact.startProbe;
30
31
  exports.toCreditAccountSlice = require_onchain_accounts_intents_utils_credit_account_slice.toCreditAccountSlice;
31
32
  exports.toRouterCaSlice = require_onchain_accounts_intents_utils_common.toRouterCaSlice;
32
33
  exports.toTargetDecimals = require_onchain_accounts_intents_utils_common.toTargetDecimals;
34
+ exports.unopenedAccountSlice = require_onchain_accounts_intents_utils_credit_account_slice.unopenedAccountSlice;
@@ -19,12 +19,12 @@ function probeBasket(balances, oracle) {
19
19
  if (usd > 0n) basketWad += usd * require_onchain_constants_math.WAD / require_onchain_constants_math.PRICE_DECIMALS;
20
20
  }
21
21
  if (basketWad <= 0n) return;
22
- const probeWad = PROBE_UNIT_USD_WAD;
23
22
  const scaled = balances.map((asset) => ({
24
23
  token: asset.token,
25
- balance: asset.balance * probeWad / basketWad
24
+ balance: asset.balance * PROBE_UNIT_USD_WAD / basketWad
26
25
  }));
27
- if (!scaled.some((a) => a.balance > 0n)) return;
26
+ const probeWad = scaled.reduce((sum, a) => sum + oracle.safeConvertToUSD(a.token, a.balance).value * require_onchain_constants_math.WAD / require_onchain_constants_math.PRICE_DECIMALS, 0n);
27
+ if (probeWad <= 0n) return;
28
28
  return {
29
29
  balances: scaled,
30
30
  basketWad,
@@ -0,0 +1,97 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_onchain_utils_bigint_math = require("../../utils/bigint-math.js");
3
+ require("../../utils/index.js");
4
+ const require_onchain_validation_helpers_health_factor_limits = require("../../validation/helpers/health-factor-limits.js");
5
+ require("../../validation/index.js");
6
+ const require_onchain_accounts_intents_utils_common = require("./utils/common.js");
7
+ const require_onchain_accounts_intents_math = require("./math.js");
8
+ const require_onchain_accounts_intents_collateral_valuation = require("./collateral-valuation.js");
9
+ const require_onchain_accounts_intents_view = require("./view.js");
10
+ //#region src/onchain/accounts/intents/withdraw-limits.ts
11
+ /**
12
+ * Every limit a `WITHDRAW` answers to, in underlying units.
13
+ *
14
+ * The one place they are assembled, so the figure a form is offered and the
15
+ * figure the collateral guard names when it turns a withdrawal down cannot
16
+ * drift apart: `CreditAccountOperationsService` reports this, and the guard
17
+ * quotes it back.
18
+ *
19
+ * @param props - Account slice, the SDK holding its market, and optionally the
20
+ * collateral the withdrawal would be funded from
21
+ * @returns The three limits, see {@link WithdrawCeilings}
22
+ **/
23
+ function withdrawLimits(props) {
24
+ const { creditAccount, sdk } = props;
25
+ const view = require_onchain_accounts_intents_view.accountView(creditAccount, sdk);
26
+ const partial = require_onchain_accounts_intents_math.maxProportionalWithdrawal(view, view.debtLimits);
27
+ const safe = maxSafeWithdrawal({
28
+ ...props,
29
+ targetHF: BigInt(require_onchain_validation_helpers_health_factor_limits.MIN_HEALTH_FACTOR_FACADE)
30
+ });
31
+ return {
32
+ partial,
33
+ safePartial: require_onchain_utils_bigint_math.BigIntMath.min(partial, safe),
34
+ exit: view.collateral > 0n ? view.collateral : 0n
35
+ };
36
+ }
37
+ /**
38
+ * Largest proportional withdrawal the safe-price collateral check still clears,
39
+ * in underlying units.
40
+ *
41
+ * A withdrawal hands funds over, so the facade weighs the account it leaves
42
+ * behind at safe prices rather than main ones — see {@link collateralValuation}.
43
+ * That is a second limit on top of the facade's `debtLimits`, and the two are
44
+ * independent: a caller wanting the amount a form may actually offer takes the
45
+ * lesser of this and `maxProportionalWithdrawal`.
46
+ *
47
+ * The arithmetic is the check solved for the amount. Taking `W` out at fixed
48
+ * leverage repays `dD = D·W/C`, so `W·TVL/C` of value is sold out of the source
49
+ * token; each dollar of that sale costs the check the source's threshold times
50
+ * its safe-to-main price ratio, while the repayment relieves `targetHF` per
51
+ * dollar of debt. Both terms are linear in `W`, which is why one division
52
+ * answers instead of a search — and why the answer is exact rather than a
53
+ * bound, as long as the plan really does fund itself from `sourceToken`.
54
+ *
55
+ * Two consequences worth stating, because they surprise:
56
+ *
57
+ * - An account whose collateral is entirely a token the reserve feed marks
58
+ * down cannot withdraw at all once it is under the threshold. A proportional
59
+ * withdrawal scales collateral and debt together, so it leaves the safe-price
60
+ * factor exactly where it found it — no amount climbs back over.
61
+ * - Leaving entirely is never refused for this reason: the exit settles the
62
+ * debt instead of shrinking it, and a check with no debt to divide by has
63
+ * nothing to refuse.
64
+ *
65
+ * @returns Amount in underlying units. The account's net value when safe prices
66
+ * do not limit the withdrawal at all, so the caller's `min` is a no-op; `0n`
67
+ * when the account already sits below `targetHF` at safe prices, and only the
68
+ * exit is left
69
+ **/
70
+ function maxSafeWithdrawal(props) {
71
+ const { creditAccount, sdk, targetHF } = props;
72
+ const view = require_onchain_accounts_intents_view.accountView(creditAccount, sdk);
73
+ if (view.collateral <= 0n) return 0n;
74
+ if (view.debt === 0n) return view.collateral;
75
+ const valuation = require_onchain_accounts_intents_collateral_valuation.collateralValuation(creditAccount, sdk);
76
+ const source = props.sourceToken ?? view.fattest();
77
+ const holding = source === void 0 ? void 0 : creditAccount.tokens.find((t) => require_onchain_accounts_intents_utils_common.eq(t.token, source));
78
+ if (!holding) return view.collateral;
79
+ let total = 0n;
80
+ for (const t of creditAccount.tokens) if (valuation.counts(t)) total += valuation.weigh(t);
81
+ const debtUsd = valuation.mainUsd(valuation.underlying, view.debt);
82
+ if (debtUsd === void 0 || debtUsd <= 0n) return view.collateral;
83
+ const slack = total - debtUsd * targetHF;
84
+ if (slack < 0n) return 0n;
85
+ const sourceMainUsd = valuation.mainUsd(holding.token, holding.balance);
86
+ if (sourceMainUsd === void 0 || sourceMainUsd <= 0n) return view.collateral;
87
+ const sourceRate = valuation.lt(holding.token) * valuation.checkedUsd(holding);
88
+ const tvlUsd = valuation.mainUsd(valuation.underlying, view.collateral + view.debt);
89
+ if (tvlUsd === void 0) return view.collateral;
90
+ const drain = sourceRate * tvlUsd - targetHF * debtUsd * sourceMainUsd;
91
+ if (drain <= 0n) return view.collateral;
92
+ const limit = view.collateral * slack * sourceMainUsd / drain;
93
+ return limit < view.collateral ? limit : view.collateral;
94
+ }
95
+ //#endregion
96
+ exports.maxSafeWithdrawal = maxSafeWithdrawal;
97
+ exports.withdrawLimits = withdrawLimits;
@@ -1,15 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_abi_iVersion = require("../../abi/iVersion.js");
3
- const require_onchain_constants_address_provider = require("../constants/address-provider.js");
3
+ require("../constants/address-provider.js");
4
4
  const require_onchain_constants_versions = require("../constants/versions.js");
5
5
  require("../constants/index.js");
6
6
  const require_onchain_utils_hex = require("../utils/hex.js");
7
7
  const require_onchain_core_AddressProviderV310Contract = require("./AddressProviderV310Contract.js");
8
8
  //#region src/onchain/core/createAddressProvider.ts
9
- const OVERRIDE_ADDRESSES = { Mainnet: {
10
- [require_onchain_constants_address_provider.AP_PRICE_FEED_COMPRESSOR]: { 311: "0x1fA2637B9fab0CD14290A7EE908DDc9688a15120" },
11
- [require_onchain_constants_address_provider.AP_MARKET_COMPRESSOR]: { 311: "0x0C27F242f6e9F2A9AD3261bE6e439De3B948bcA2" }
12
- } };
9
+ const OVERRIDE_ADDRESSES = {};
13
10
  async function createAddressProvider(sdk, address) {
14
11
  let v;
15
12
  if (require_onchain_utils_hex.hexEq(address, "0xF7f0a609BfAb9a0A98786951ef10e5FE26cC1E38")) v = 310n;
@@ -213,6 +213,7 @@ const require_onchain_validation_checks_checkPoolPaused = require("./validation/
213
213
  const require_onchain_validation_checks_checkPoolSunset = require("./validation/checks/checkPoolSunset.js");
214
214
  const require_onchain_validation_checks_checkQuotaCount = require("./validation/checks/checkQuotaCount.js");
215
215
  const require_onchain_validation_checks_checkQuotaLimit = require("./validation/checks/checkQuotaLimit.js");
216
+ const require_onchain_validation_checks_checkReservePriceLimited = require("./validation/checks/checkReservePriceLimited.js");
216
217
  const require_onchain_validation_bundles_checkAccountQuotas = require("./validation/bundles/checkAccountQuotas.js");
217
218
  const require_onchain_validation_bundles_checkWalletAllowance = require("./validation/bundles/checkWalletAllowance.js");
218
219
  const require_onchain_validation_bundles_checkWalletBalance = require("./validation/bundles/checkWalletBalance.js");
@@ -222,6 +223,7 @@ const require_onchain_validation_bundles_checkIncreaseDebt = require("./validati
222
223
  const require_onchain_validation_bundles_checkIncreaseQuota = require("./validation/bundles/checkIncreaseQuota.js");
223
224
  const require_onchain_validation_bundles_checkMarket = require("./validation/bundles/checkMarket.js");
224
225
  const require_onchain_validation_bundles_checkObtained = require("./validation/bundles/checkObtained.js");
226
+ const require_onchain_validation_bundles_checkMidasAccountGreenlist = require("./validation/bundles/checkMidasAccountGreenlist.js");
225
227
  const require_onchain_validation_bundles_checkRWAOpenRequirements = require("./validation/bundles/checkRWAOpenRequirements.js");
226
228
  const require_onchain_validation_bundles_checkRWAOpening = require("./validation/bundles/checkRWAOpening.js");
227
229
  const require_onchain_validation_bundles_checkCreditOperation = require("./validation/bundles/checkCreditOperation.js");
@@ -292,6 +294,7 @@ const require_onchain_preview_preview_detectCloseOrRepay = require("./preview/pr
292
294
  const require_onchain_preview_preview_detectDelayedClaim = require("./preview/preview/detectDelayedClaim.js");
293
295
  const require_onchain_preview_preview_detectDelayedOperation = require("./preview/preview/detectDelayedOperation.js");
294
296
  const require_onchain_preview_preview_estimateClaimableAt = require("./preview/preview/estimateClaimableAt.js");
297
+ const require_onchain_preview_preview_midasGreenlistsAccount = require("./preview/preview/midasGreenlistsAccount.js");
295
298
  const require_onchain_preview_preview_previewAdjustStrategyPosition = require("./preview/preview/previewAdjustStrategyPosition.js");
296
299
  const require_onchain_preview_preview_previewExitOrRepayStrategyPosition = require("./preview/preview/previewExitOrRepayStrategyPosition.js");
297
300
  const require_onchain_preview_preview_replayInnerOperations = require("./preview/preview/replayInnerOperations.js");
@@ -575,6 +578,7 @@ exports.checkLiquidationFunding = require_onchain_validation_bundles_checkLiquid
575
578
  exports.checkLiquidatorEligible = require_onchain_validation_checks_checkLiquidatorEligible.checkLiquidatorEligible;
576
579
  exports.checkMarket = require_onchain_validation_bundles_checkMarket.checkMarket;
577
580
  exports.checkMarketExpired = require_onchain_validation_checks_checkMarketExpired.checkMarketExpired;
581
+ exports.checkMidasAccountGreenlist = require_onchain_validation_bundles_checkMidasAccountGreenlist.checkMidasAccountGreenlist;
578
582
  exports.checkObtained = require_onchain_validation_bundles_checkObtained.checkObtained;
579
583
  exports.checkOperation = require_onchain_validation_checkOperation.checkOperation;
580
584
  exports.checkPoolFunding = require_onchain_validation_bundles_checkPoolFunding.checkPoolFunding;
@@ -586,6 +590,7 @@ exports.checkQuotaCount = require_onchain_validation_checks_checkQuotaCount.chec
586
590
  exports.checkQuotaLimit = require_onchain_validation_checks_checkQuotaLimit.checkQuotaLimit;
587
591
  exports.checkRWAOpenRequirements = require_onchain_validation_bundles_checkRWAOpenRequirements.checkRWAOpenRequirements;
588
592
  exports.checkRWAOpening = require_onchain_validation_bundles_checkRWAOpening.checkRWAOpening;
593
+ exports.checkReservePriceLimited = require_onchain_validation_checks_checkReservePriceLimited.checkReservePriceLimited;
589
594
  exports.checkSimulation = require_onchain_validation_checkSimulation.checkSimulation;
590
595
  exports.checkWallet = require_onchain_validation_bundles_checkWallet.checkWallet;
591
596
  exports.checkWalletAllowance = require_onchain_validation_bundles_checkWalletAllowance.checkWalletAllowance;
@@ -753,6 +758,7 @@ exports.json_stringify = require_onchain_utils_json.json_stringify;
753
758
  exports.lidoV1_WETHGatewayAbi = require_onchain_market_adapters_abi_targetContractAbi.lidoV1_WETHGatewayAbi;
754
759
  exports.makeReplayState = require_onchain_preview_preview_replayInnerOperations.makeReplayState;
755
760
  exports.mellowDvvAdapterAbi = require_onchain_market_adapters_abi_adapters_mellowDvvAdapter.mellowDvvAdapterAbi;
761
+ exports.midasGreenlistsAccount = require_onchain_preview_preview_midasGreenlistsAccount.midasGreenlistsAccount;
756
762
  exports.minSeizedAmount = require_onchain_market_math.minSeizedAmount;
757
763
  exports.numberWithCommas = require_onchain_utils_formatter.numberWithCommas;
758
764
  exports.onchainSDKOptionsSchema = require_onchain_options.onchainSDKOptionsSchema;
@@ -20,7 +20,7 @@ const adapterConstructorAbi = {
20
20
  ["INFINIFI_GATEWAY"]: { 310: require_onchain_market_adapters_abi_conctructorAbiPatterns.BASIC_ADAPTER_ABI },
21
21
  ["LIDO_V1"]: { 310: require_onchain_market_adapters_abi_conctructorAbiPatterns.BASIC_ADAPTER_ABI },
22
22
  ["LIDO_WSTETH_V1"]: { 310: require_onchain_market_adapters_abi_conctructorAbiPatterns.BASIC_ADAPTER_ABI },
23
- ["MIDAS_GATEWAY"]: { 311: require_onchain_market_adapters_abi_conctructorAbiPatterns.REFERER_ID_ADAPTER_ABI },
23
+ ["MIDAS_GATEWAY"]: { 311: require_onchain_market_adapters_abi_conctructorAbiPatterns.BASIC_ADAPTER_ABI },
24
24
  ["MIDAS_REDEMPTION_VAULT"]: {
25
25
  310: require_onchain_market_adapters_abi_conctructorAbiPatterns.BASIC_ADAPTER_ABI,
26
26
  311: require_onchain_market_adapters_abi_conctructorAbiPatterns.BASIC_ADAPTER_ABI
@@ -170,13 +170,21 @@ var MidasGatewayAdapterContract = class extends require_onchain_market_adapters_
170
170
  return { redeemer };
171
171
  }
172
172
  /**
173
+ * Whether `calldata` is `receiveGreenlist()`, the call that grants the
174
+ * Midas greenlisted role to the credit account.
175
+ */
176
+ isReceiveGreenlist(calldata) {
177
+ return calldata === receiveGreenlistCalldata;
178
+ }
179
+ /**
173
180
  * `receiveGreenlist()` is prepended by `prependMidasReceiveGreenlist`
174
181
  * before the balance bracket when the multicall mints a permissioned
175
- * mToken: it only greenlists the credit account and is balance-neutral,
176
- * so it is legal outside a bracket and leaves balances untouched.
182
+ * mToken: it only grants the Midas greenlisted role to the credit
183
+ * account and is balance-neutral, so it is legal outside a bracket and
184
+ * leaves balances untouched.
177
185
  */
178
186
  replayOutOfBracketCall(_balances, calldata) {
179
- return calldata === receiveGreenlistCalldata;
187
+ return this.isReceiveGreenlist(calldata);
180
188
  }
181
189
  applyBalanceChanges(balances, decoded) {
182
190
  switch (decoded.functionName) {
@@ -36,7 +36,7 @@ function calcHealthFactor(props) {
36
36
  const scale = 10n ** BigInt(decimalsByToken.get(token) ?? 18);
37
37
  return amount * price / scale;
38
38
  };
39
- const assetMoney = snapshot.assets.reduce((acc, { token, balance }) => {
39
+ const assetValue = snapshot.assets.reduce((acc, { token, balance }) => {
40
40
  if (balance <= 10n) return acc;
41
41
  const lt = BigInt(lts.get(token) ?? 0);
42
42
  const tokenLtWeighted = (convertToUSD(token, balance, true) ?? 0n) * lt;
@@ -45,8 +45,8 @@ function calcHealthFactor(props) {
45
45
  const quotaWeighted = (convertToUSD(underlying, quotaBalance) ?? 0n) * require_onchain_constants_math.PERCENTAGE_FACTOR;
46
46
  return acc + (quota ? require_onchain_utils_bigint_math.BigIntMath.min(quotaWeighted, tokenLtWeighted) : tokenLtWeighted);
47
47
  }, 0n);
48
- const borrowedMoney = convertToUSD(underlying, snapshot.totalDebt) ?? 0n;
49
- const hf = borrowedMoney > 0n ? assetMoney / borrowedMoney : 0n;
48
+ const borrowedValue = convertToUSD(underlying, snapshot.totalDebt) ?? 0n;
49
+ const hf = borrowedValue > 0n ? assetValue / borrowedValue : 0n;
50
50
  return Number(hf);
51
51
  }
52
52
  //#endregion
@@ -12,6 +12,7 @@ const require_onchain_preview_preview_detectCloseOrRepay = require("./preview/de
12
12
  const require_onchain_preview_preview_detectDelayedClaim = require("./preview/detectDelayedClaim.js");
13
13
  const require_onchain_preview_preview_detectDelayedOperation = require("./preview/detectDelayedOperation.js");
14
14
  const require_onchain_preview_preview_estimateClaimableAt = require("./preview/estimateClaimableAt.js");
15
+ const require_onchain_preview_preview_midasGreenlistsAccount = require("./preview/midasGreenlistsAccount.js");
15
16
  const require_onchain_preview_preview_previewAdjustStrategyPosition = require("./preview/previewAdjustStrategyPosition.js");
16
17
  const require_onchain_preview_preview_previewExitOrRepayStrategyPosition = require("./preview/previewExitOrRepayStrategyPosition.js");
17
18
  const require_onchain_preview_preview_replayInnerOperations = require("./preview/replayInnerOperations.js");
@@ -29,6 +30,7 @@ exports.isCloseOrRepay = require_onchain_preview_preview_detectCloseOrRepay.isCl
29
30
  exports.isPoolOperation = require_onchain_preview_parse_types.isPoolOperation;
30
31
  exports.isRWAOperation = require_onchain_preview_parse_types.isRWAOperation;
31
32
  exports.makeReplayState = require_onchain_preview_preview_replayInnerOperations.makeReplayState;
33
+ exports.midasGreenlistsAccount = require_onchain_preview_preview_midasGreenlistsAccount.midasGreenlistsAccount;
32
34
  exports.parseFacadeOperationCalldata = require_onchain_preview_parse_parseFacadeOperationCalldata.parseFacadeOperationCalldata;
33
35
  exports.parseOperationCalldata = require_onchain_preview_parse_parseOperationCalldata.parseOperationCalldata;
34
36
  exports.parsePoolOperationCalldata = require_onchain_preview_parse_parsePoolOperationCalldata.parsePoolOperationCalldata;
@@ -5,6 +5,7 @@ const require_onchain_preview_preview_detectCloseOrRepay = require("./detectClos
5
5
  const require_onchain_preview_preview_detectDelayedClaim = require("./detectDelayedClaim.js");
6
6
  const require_onchain_preview_preview_detectDelayedOperation = require("./detectDelayedOperation.js");
7
7
  const require_onchain_preview_preview_estimateClaimableAt = require("./estimateClaimableAt.js");
8
+ const require_onchain_preview_preview_midasGreenlistsAccount = require("./midasGreenlistsAccount.js");
8
9
  const require_onchain_preview_preview_previewAdjustStrategyPosition = require("./previewAdjustStrategyPosition.js");
9
10
  const require_onchain_preview_preview_previewExitOrRepayStrategyPosition = require("./previewExitOrRepayStrategyPosition.js");
10
11
  const require_onchain_preview_preview_replayInnerOperations = require("./replayInnerOperations.js");
@@ -18,6 +19,7 @@ exports.detectDelayedOperation = require_onchain_preview_preview_detectDelayedOp
18
19
  exports.estimateClaimableAt = require_onchain_preview_preview_estimateClaimableAt.estimateClaimableAt;
19
20
  exports.isCloseOrRepay = require_onchain_preview_preview_detectCloseOrRepay.isCloseOrRepay;
20
21
  exports.makeReplayState = require_onchain_preview_preview_replayInnerOperations.makeReplayState;
22
+ exports.midasGreenlistsAccount = require_onchain_preview_preview_midasGreenlistsAccount.midasGreenlistsAccount;
21
23
  exports.previewAdjustStrategyPosition = require_onchain_preview_preview_previewAdjustStrategyPosition.previewAdjustStrategyPosition;
22
24
  exports.previewExitOrRepayStrategyPosition = require_onchain_preview_preview_previewExitOrRepayStrategyPosition.previewExitOrRepayStrategyPosition;
23
25
  exports.previewOperation = require_onchain_preview_preview_previewOperation.previewOperation;
@@ -0,0 +1,17 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_onchain_market_adapters_contracts_MidasGatewayAdapterContract = require("../../market/adapters/contracts/MidasGatewayAdapterContract.js");
3
+ //#region src/onchain/preview/preview/midasGreenlistsAccount.ts
4
+ /**
5
+ * Whether the multicall grants the Midas greenlisted role to the credit
6
+ * account via `receiveGreenlist()`.
7
+ */
8
+ function midasGreenlistsAccount(sdk, multicall) {
9
+ for (const op of multicall) {
10
+ if (op.operation !== "Execute") continue;
11
+ const adapter = sdk.getContract(op.adapter);
12
+ if (adapter instanceof require_onchain_market_adapters_contracts_MidasGatewayAdapterContract.MidasGatewayAdapterContract && adapter.isReceiveGreenlist(op.calldata)) return true;
13
+ }
14
+ return false;
15
+ }
16
+ //#endregion
17
+ exports.midasGreenlistsAccount = midasGreenlistsAccount;
@@ -3,25 +3,23 @@ const require_onchain_constants_address_provider = require("../../constants/addr
3
3
  const require_model_previews = require("../../../model/previews.js");
4
4
  const require_model_result = require("../../../model/result.js");
5
5
  require("../../../model/index.js");
6
- const require_onchain_preview_preview_CreditAccountState = require("./CreditAccountState.js");
6
+ const require_onchain_preview_preview_midasGreenlistsAccount = require("./midasGreenlistsAccount.js");
7
7
  const require_onchain_preview_preview_unwrapNativeCollateral = require("./unwrapNativeCollateral.js");
8
- const require_onchain_preview_preview_replayInnerOperations = require("./replayInnerOperations.js");
9
8
  //#region src/onchain/preview/preview/previewOpenStrategyPosition.ts
10
- function previewOpenStrategyPosition(sdk, input, operation) {
9
+ function previewOpenStrategyPosition(sdk, input, operation, replay) {
11
10
  const { value = 0n } = input;
12
11
  const market = sdk.marketRegister.findByCreditManager(operation.creditManager);
13
12
  const oracle = market.priceOracle;
14
- const state = require_onchain_preview_preview_replayInnerOperations.makeReplayState(require_onchain_preview_preview_CreditAccountState.CreditAccountState.beforeOpen(operation.creditManager, market.underlying));
15
- const replayError = require_onchain_preview_preview_replayInnerOperations.replayInnerOperations(sdk, operation.multicall, state);
16
- if (replayError) return require_model_result.sdkErr(replayError);
17
- const account = state.account;
13
+ const { before, after } = replay;
14
+ const account = after.account;
18
15
  let warning;
19
- const netValue = state.collateralAdded.sum((token, balance) => {
16
+ const price = (token, balance) => {
20
17
  const priced = oracle.safeConvert(token, market.underlying, balance);
21
18
  warning ??= priced.error;
22
19
  return priced.value;
23
- });
24
- const unwrapped = require_onchain_preview_preview_unwrapNativeCollateral.unwrapNativeCollateral(state.collateralAdded.toAssets(), value, sdk.addressProvider.getAddress(require_onchain_constants_address_provider.AP_WETH_TOKEN, 0));
20
+ };
21
+ const netValue = before.balances.sum(price) + after.collateralAdded.sum(price) - after.collateralWithdrawn.sum(price);
22
+ const unwrapped = require_onchain_preview_preview_unwrapNativeCollateral.unwrapNativeCollateral(after.collateralAdded.toAssets(), value, sdk.addressProvider.getAddress(require_onchain_constants_address_provider.AP_WETH_TOKEN, 0));
25
23
  if (!unwrapped.ok) return unwrapped;
26
24
  const collateral = unwrapped.data;
27
25
  const snap = account.toSnapshot(netValue + account.totalDebt);
@@ -30,16 +28,15 @@ function previewOpenStrategyPosition(sdk, input, operation) {
30
28
  ...require_model_previews.asEstimated(sdk.positions.projection(snap, { availableLiquidityChange: -account.totalDebt })),
31
29
  targetCollateral: targetAsset ? oracle.toTokenAmount(targetAsset.token, targetAsset.balance) : void 0,
32
30
  collateralAdded: collateral.map((a) => oracle.toTokenAmount(a.token, a.balance)),
31
+ collateralWithdrawn: after.collateralWithdrawn.toAssets().map((a) => oracle.toTokenAmount(a.token, a.balance)),
33
32
  warning
34
33
  };
35
- if (operation.operation === "RWAOpenCreditAccount") return require_model_result.sdkOk({
36
- ...projection,
37
- operation: "RWAOpenCreditAccount",
38
- rwaArgs: operation.args
39
- });
40
34
  return require_model_result.sdkOk({
41
35
  ...projection,
42
- operation: "OpenCreditAccount"
36
+ operation: "OpenCreditAccount",
37
+ ...operation.operation === "MultiCall" || operation.operation === "BotMulticall" || operation.operation === "RWAMulticall" ? { creditAccount: operation.creditAccount } : {},
38
+ ..."args" in operation ? { rwaArgs: operation.args } : {},
39
+ midasGreenlistsAccount: require_onchain_preview_preview_midasGreenlistsAccount.midasGreenlistsAccount(sdk, operation.multicall)
43
40
  });
44
41
  }
45
42
  /**
@@ -34,9 +34,13 @@ async function previewOperation(sdk, input, options, creditAccount) {
34
34
  if (!parsed.ok) return parsed;
35
35
  const operation = parsed.data;
36
36
  if (require_onchain_preview_parse_types.isPoolOperation(operation)) return require_onchain_preview_preview_previewPoolPositionOperation.previewPoolPositionOperation(sdk, operation, options);
37
- if (operation.operation === "OpenCreditAccount" || operation.operation === "RWAOpenCreditAccount") return require_onchain_preview_preview_previewOpenStrategyPosition.previewOpenStrategyPosition(sdk, input, operation);
37
+ if (operation.operation === "OpenCreditAccount" || operation.operation === "RWAOpenCreditAccount") {
38
+ const replayed = require_onchain_preview_preview_replayMulticall.replayMulticall(sdk, operation);
39
+ if (!replayed.ok) return replayed;
40
+ return require_onchain_preview_preview_previewOpenStrategyPosition.previewOpenStrategyPosition(sdk, input, operation, replayed.data);
41
+ }
38
42
  if (operation.operation === "CloseCreditAccount") {
39
- const resolved = await resolveCreditAccount(sdk, operation, options, creditAccount);
43
+ const resolved = await resolveCreditAccount(sdk, operation.creditAccount, options, creditAccount);
40
44
  if (!resolved.ok) return resolved;
41
45
  const replayed = require_onchain_preview_preview_replayMulticall.replayMulticall(sdk, operation, resolved.data);
42
46
  if (!replayed.ok) return replayed;
@@ -48,7 +52,7 @@ async function previewOperation(sdk, input, options, creditAccount) {
48
52
  return preview;
49
53
  }
50
54
  if (operation.operation === "MultiCall" || operation.operation === "BotMulticall" || operation.operation === "RWAMulticall") {
51
- const resolved = await resolveCreditAccount(sdk, operation, options, creditAccount);
55
+ const resolved = await resolveCreditAccount(sdk, operation.creditAccount, options, creditAccount);
52
56
  if (!resolved.ok) return resolved;
53
57
  const replayed = require_onchain_preview_preview_replayMulticall.replayMulticall(sdk, operation, resolved.data);
54
58
  if (!replayed.ok) return replayed;
@@ -65,20 +69,24 @@ async function previewOperation(sdk, input, options, creditAccount) {
65
69
  * injected state when present, otherwise fetches it from the credit account
66
70
  * compressor.
67
71
  */
68
- async function resolveCreditAccount(sdk, operation, options, creditAccount) {
69
- let resolved = creditAccount;
70
- if (!resolved) resolved = await sdk.accounts.getCreditAccountData(operation.creditAccount, options?.blockNumber);
71
- if (!resolved) return require_model_result.sdkErr(require_model_errors_prepare_errors.creditAccountNotFound(operation.creditAccount));
72
+ async function resolveCreditAccount(sdk, address, options, data) {
73
+ let resolved = data;
74
+ if (!resolved) resolved = await sdk.accounts.getCreditAccountData(address, options?.blockNumber);
75
+ if (!resolved) return require_model_result.sdkErr(require_model_errors_prepare_errors.creditAccountNotFound(address));
72
76
  return require_model_result.sdkOk(resolved);
73
77
  }
74
78
  /**
75
79
  * Previews a plain/bot/RWA multicall: classifies the instant preview
76
- * (zero-debt closure/repay vs adjustment) and, when the multicall requests a
77
- * delayed withdrawal, wraps the instant preview into a
78
- * `DelayedCreditAccountOperation` together with the best-effort preview of
79
- * the state after the withdrawal is claimed.
80
+ * (reopening a zero-debt account, zero-debt closure/repay, or adjustment)
81
+ * and, when the multicall requests a delayed withdrawal, wraps the instant
82
+ * preview into a `DelayedCreditAccountOperation` together with the
83
+ * best-effort preview of the state after the withdrawal is claimed.
84
+ *
85
+ * A reopening is reported as `OpenCreditAccount` and never as a delayed
86
+ * withdrawal: an opening requests no redemption.
80
87
  */
81
88
  async function previewMulticallOperation(sdk, input, operation, replay, blockNumber) {
89
+ if (replay.before.totalDebt === 0n && replay.before.quotas.toAssets(0n).length === 0 && replay.after.account.totalDebt > 0n) return require_onchain_preview_preview_previewOpenStrategyPosition.previewOpenStrategyPosition(sdk, input, operation, replay);
82
90
  let instantPreview;
83
91
  if (require_onchain_preview_preview_detectCloseOrRepay.isCloseOrRepay(operation.multicall)) {
84
92
  const instant = require_onchain_preview_preview_previewExitOrRepayStrategyPosition.previewExitOrRepayStrategyPosition(sdk, input, operation, false, replay);
@@ -5,11 +5,12 @@ const require_onchain_preview_preview_CreditAccountState = require("./CreditAcco
5
5
  const require_onchain_preview_preview_replayInnerOperations = require("./replayInnerOperations.js");
6
6
  //#region src/onchain/preview/preview/replayMulticall.ts
7
7
  /**
8
- * Replays the operation's multicall over the account's pre-resolved
9
- * pre-state via {@link replayInnerOperations}.
8
+ * Replays the operation's multicall via {@link replayInnerOperations}.
9
+ * When `creditAccount` is omitted, the seed is
10
+ * {@link CreditAccountState.beforeOpen} (a fresh opening).
10
11
  */
11
12
  function replayMulticall(sdk, operation, creditAccount) {
12
- const before = require_onchain_preview_preview_CreditAccountState.CreditAccountState.fromCreditAccountData(creditAccount);
13
+ const before = creditAccount ? require_onchain_preview_preview_CreditAccountState.CreditAccountState.fromCreditAccountData(creditAccount) : require_onchain_preview_preview_CreditAccountState.CreditAccountState.beforeOpen(operation.creditManager, sdk.marketRegister.findByCreditManager(operation.creditManager).underlying);
13
14
  const after = require_onchain_preview_preview_replayInnerOperations.makeReplayState(before.clone());
14
15
  const error = require_onchain_preview_preview_replayInnerOperations.replayInnerOperations(sdk, operation.multicall, after);
15
16
  if (error) return require_model_result.sdkErr(error);
@@ -23,13 +23,13 @@ async function checkCollateralFunding(input) {
23
23
  if (held.size === 0) return [];
24
24
  let spender;
25
25
  try {
26
- if (preview.operation === "OpenCreditAccount" || preview.operation === "RWAOpenCreditAccount") spender = await sdk.accounts.getApprovalAddress({
26
+ if (preview.creditAccount) spender = await sdk.accounts.getApprovalAddress({
27
27
  creditManager: preview.creditManager,
28
- borrower: sender
28
+ creditAccount: preview.creditAccount
29
29
  });
30
30
  else spender = await sdk.accounts.getApprovalAddress({
31
31
  creditManager: preview.creditManager,
32
- creditAccount: preview.creditAccount
32
+ borrower: sender
33
33
  });
34
34
  } catch (cause) {
35
35
  return [require_model_errors_prepare_errors.unexpectedFailure(cause, "resolve the approval address")];
@@ -26,7 +26,8 @@ async function checkCreditOperation(args) {
26
26
  const suite = sdk.marketRegister.findCreditManager(preview.creditManager);
27
27
  const market = suite.market;
28
28
  const underlying = require_onchain_validation_helpers_token.toToken(sdk, market.pool.underlying);
29
- const isOpening = preview.operation === "OpenCreditAccount" || preview.operation === "RWAOpenCreditAccount";
29
+ const isOpening = preview.operation === "OpenCreditAccount";
30
+ const isEmptyOpening = preview.operation === "OpenCreditAccount" && preview.totalDebt.value === 0n && preview.collateralAdded.length === 0 && preview.quotas.length === 0;
30
31
  const protocol = [
31
32
  ...require_onchain_validation_bundles_checkMarket.checkMarket(suite),
32
33
  ...require_onchain_validation_checks_checkDebtLimits.checkDebtLimits({
@@ -34,7 +35,7 @@ async function checkCreditOperation(args) {
34
35
  minDebt: suite.creditFacade.minDebt,
35
36
  maxDebt: suite.creditFacade.maxDebt,
36
37
  underlying,
37
- allowZero: !isOpening,
38
+ allowZero: !isOpening || isEmptyOpening,
38
39
  maxBorrowAmount: suite.maxBorrowAmount()
39
40
  }),
40
41
  ...require_onchain_validation_bundles_checkIncreaseDebt.checkIncreaseDebt(suite, preview, underlying),
@@ -52,7 +53,7 @@ async function checkCreditOperation(args) {
52
53
  preview,
53
54
  sender,
54
55
  blockNumber
55
- }), preview.operation === "OpenCreditAccount" || preview.operation === "RWAOpenCreditAccount" ? require_onchain_validation_bundles_checkRWAOpening.checkRWAOpening({
56
+ }), isOpening ? require_onchain_validation_bundles_checkRWAOpening.checkRWAOpening({
56
57
  sdk,
57
58
  preview,
58
59
  sender
@@ -0,0 +1,44 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_model_errors_operation_errors = require("../../../model/errors/operation-errors.js");
3
+ const require_model_errors_prepare_errors = require("../../../model/errors/prepare-errors.js");
4
+ require("../../../model/index.js");
5
+ const require_onchain_validation_helpers_token = require("../helpers/token.js");
6
+ require("../helpers/index.js");
7
+ //#region src/onchain/validation/bundles/checkMidasAccountGreenlist.ts
8
+ /**
9
+ * Whether the credit account already holds the Midas greenlisted role
10
+ * this permissioned mToken requires of its holder.
11
+ */
12
+ async function checkMidasAccountGreenlist(input) {
13
+ const { sdk, preview, nft, tokens } = input;
14
+ if (nft.protocol !== "midas") return [];
15
+ if (tokens.length === 0) return [];
16
+ const account = preview.creditAccount;
17
+ if (!account) return tokens.map((token) => require_model_errors_operation_errors.accountNotMidasGreenlisted({
18
+ token: require_onchain_validation_helpers_token.toToken(sdk, token),
19
+ creditManager: preview.creditManager
20
+ }));
21
+ return (await Promise.all(tokens.map((token) => checkAccountRole({
22
+ sdk,
23
+ nft,
24
+ account,
25
+ token,
26
+ preview
27
+ })))).flat();
28
+ }
29
+ async function checkAccountRole(input) {
30
+ const { sdk, nft, account, token, preview } = input;
31
+ try {
32
+ const requirements = await nft.getOpenAccountRequirements(account, { tokenOutAddress: token });
33
+ if (nft.isRegistered(requirements)) return [];
34
+ return [require_model_errors_operation_errors.accountNotMidasGreenlisted({
35
+ token: require_onchain_validation_helpers_token.toToken(sdk, token),
36
+ creditManager: preview.creditManager,
37
+ creditAccount: account
38
+ })];
39
+ } catch (cause) {
40
+ return [require_model_errors_prepare_errors.unexpectedFailure(cause, "read the Midas account greenlist")];
41
+ }
42
+ }
43
+ //#endregion
44
+ exports.checkMidasAccountGreenlist = checkMidasAccountGreenlist;
@@ -1,25 +1,34 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_onchain_utils_AddressSet = require("../../utils/AddressSet.js");
3
+ const require_onchain_validation_bundles_checkMidasAccountGreenlist = require("./checkMidasAccountGreenlist.js");
3
4
  const require_onchain_validation_bundles_checkRWAOpenRequirements = require("./checkRWAOpenRequirements.js");
4
5
  //#region src/onchain/validation/bundles/checkRWAOpening.ts
5
6
  /**
6
7
  * Per KYC-gated token among `collateralAdded ∪ quotas`, whether the
7
- * borrower still has to register or sign before this opening can land.
8
+ * borrower still has to register or sign before this opening can land,
9
+ * and whether a Midas credit account may hold the mToken.
8
10
  */
9
11
  async function checkRWAOpening(input) {
10
12
  const { sdk, preview, sender } = input;
11
13
  const nft = await sdk.marketRegister.findCreditManager(preview.creditManager).degenNFT();
12
14
  if (!nft) return [];
13
- const gated = new require_onchain_utils_AddressSet.AddressSet(await nft.getTokens());
14
- const candidates = new require_onchain_utils_AddressSet.AddressSet([...preview.collateralAdded.map((a) => a.token.address), ...preview.quotas.map((q) => q.token.address)]);
15
- const providedArgs = preview.operation === "RWAOpenCreditAccount" ? preview.rwaArgs : void 0;
16
- return (await Promise.all([...candidates].filter((token) => gated.has(token)).map((token) => require_onchain_validation_bundles_checkRWAOpenRequirements.checkRWAOpenRequirements({
15
+ const nftTokens = new require_onchain_utils_AddressSet.AddressSet(await nft.getTokens());
16
+ let candidates = new require_onchain_utils_AddressSet.AddressSet([...preview.collateralAdded.map((a) => a.token.address), ...preview.quotas.map((q) => q.token.address)]).asArray();
17
+ candidates = candidates.filter((token) => nftTokens.has(token));
18
+ let tokensToCheck = candidates;
19
+ if (tokensToCheck.length === 0 && !preview.creditAccount && nft.protocol === "midas") tokensToCheck = nftTokens.asArray();
20
+ return (await Promise.all([...tokensToCheck.map((token) => require_onchain_validation_bundles_checkRWAOpenRequirements.checkRWAOpenRequirements({
17
21
  sdk,
18
22
  wallet: sender,
19
23
  creditManager: preview.creditManager,
20
24
  token,
21
- providedArgs
22
- })))).flat();
25
+ providedArgs: preview.rwaArgs
26
+ })), require_onchain_validation_bundles_checkMidasAccountGreenlist.checkMidasAccountGreenlist({
27
+ sdk,
28
+ preview,
29
+ nft,
30
+ tokens: candidates
31
+ })])).flat();
23
32
  }
24
33
  //#endregion
25
34
  exports.checkRWAOpening = checkRWAOpening;
@@ -8,6 +8,7 @@ const require_onchain_validation_bundles_checkIncreaseDebt = require("./checkInc
8
8
  const require_onchain_validation_bundles_checkIncreaseQuota = require("./checkIncreaseQuota.js");
9
9
  const require_onchain_validation_bundles_checkMarket = require("./checkMarket.js");
10
10
  const require_onchain_validation_bundles_checkObtained = require("./checkObtained.js");
11
+ const require_onchain_validation_bundles_checkMidasAccountGreenlist = require("./checkMidasAccountGreenlist.js");
11
12
  const require_onchain_validation_bundles_checkRWAOpenRequirements = require("./checkRWAOpenRequirements.js");
12
13
  const require_onchain_validation_bundles_checkRWAOpening = require("./checkRWAOpening.js");
13
14
  const require_onchain_validation_bundles_checkCreditOperation = require("./checkCreditOperation.js");
@@ -25,6 +26,7 @@ exports.checkIncreaseQuota = require_onchain_validation_bundles_checkIncreaseQuo
25
26
  exports.checkLiquidationEligibility = require_onchain_validation_bundles_checkLiquidationEligibility.checkLiquidationEligibility;
26
27
  exports.checkLiquidationFunding = require_onchain_validation_bundles_checkLiquidationFunding.checkLiquidationFunding;
27
28
  exports.checkMarket = require_onchain_validation_bundles_checkMarket.checkMarket;
29
+ exports.checkMidasAccountGreenlist = require_onchain_validation_bundles_checkMidasAccountGreenlist.checkMidasAccountGreenlist;
28
30
  exports.checkObtained = require_onchain_validation_bundles_checkObtained.checkObtained;
29
31
  exports.checkPoolFunding = require_onchain_validation_bundles_checkPoolFunding.checkPoolFunding;
30
32
  exports.checkPoolOperation = require_onchain_validation_bundles_checkPoolOperation.checkPoolOperation;