@gearbox-protocol/sdk 16.3.2-next.1 → 16.3.2

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 (72) hide show
  1. package/dist/cjs/dev/midasUtils.js +46 -11
  2. package/dist/cjs/model/errors/index.js +0 -1
  3. package/dist/cjs/model/errors/operation-errors.js +0 -9
  4. package/dist/cjs/model/index.js +0 -1
  5. package/dist/cjs/onchain/accounts/intents/guards.js +3 -15
  6. package/dist/cjs/onchain/accounts/intents/index.js +18 -21
  7. package/dist/cjs/onchain/accounts/intents/maxWithdrawCollateral.js +38 -12
  8. package/dist/cjs/onchain/accounts/intents/realize.js +2 -10
  9. package/dist/cjs/onchain/accounts/intents/tail.js +1 -1
  10. package/dist/cjs/onchain/index.js +0 -2
  11. package/dist/cjs/onchain/market/adapters/abi/conctructorAbi.js +1 -1
  12. package/dist/cjs/onchain/validation/checks/index.js +0 -2
  13. package/dist/cjs/onchain/validation/index.js +0 -2
  14. package/dist/cjs/sdk/prepare/PrepareApi.js +2 -3
  15. package/dist/esm/dev/AccountOpener.js +1 -1
  16. package/dist/esm/dev/midasUtils.js +47 -12
  17. package/dist/esm/dev/withdrawalUtils.js +1 -1
  18. package/dist/esm/history/trace/extractTransfers.js +1 -1
  19. package/dist/esm/model/errors/index.js +2 -2
  20. package/dist/esm/model/errors/operation-errors.js +1 -9
  21. package/dist/esm/model/index.js +2 -2
  22. package/dist/esm/onchain/accounts/CreditAccountsServiceV310.js +2 -2
  23. package/dist/esm/onchain/accounts/intents/guards.js +3 -15
  24. package/dist/esm/onchain/accounts/intents/index.js +18 -21
  25. package/dist/esm/onchain/accounts/intents/maxWithdrawCollateral.js +38 -12
  26. package/dist/esm/onchain/accounts/intents/realize.js +2 -10
  27. package/dist/esm/onchain/accounts/intents/tail.js +1 -1
  28. package/dist/esm/onchain/accounts/liquidations/LiquidationsService.js +1 -1
  29. package/dist/esm/onchain/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  30. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  31. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  32. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  33. package/dist/esm/onchain/base/TokensMeta.js +3 -3
  34. package/dist/esm/onchain/core/createAddressProvider.js +1 -1
  35. package/dist/esm/onchain/index.js +1 -2
  36. package/dist/esm/onchain/market/adapters/abi/conctructorAbi.js +1 -1
  37. package/dist/esm/onchain/market/adapters/contracts/AccountMigratorAdapterContract.js +1 -1
  38. package/dist/esm/onchain/market/adapters/contracts/ERC4626AdapterContract.js +1 -1
  39. package/dist/esm/onchain/market/credit/CreditFacadeV310BaseContract.js +1 -1
  40. package/dist/esm/onchain/market/pool/PoolV310Contract.js +1 -1
  41. package/dist/esm/onchain/market/rwa/createDegenNFT.js +1 -1
  42. package/dist/esm/onchain/market/zapper/IETHZapperContract.js +1 -1
  43. package/dist/esm/onchain/market/zapper/ZapperContract.js +1 -1
  44. package/dist/esm/onchain/preview/preview/previewPoolPositionOperation.js +2 -2
  45. package/dist/esm/onchain/utils/viem/simulateWithPriceUpdates.js +1 -1
  46. package/dist/esm/onchain/validation/checks/index.js +1 -2
  47. package/dist/esm/onchain/validation/index.js +1 -2
  48. package/dist/esm/sdk/prepare/PrepareApi.js +2 -3
  49. package/dist/types/dev/midasUtils.d.ts +4 -3
  50. package/dist/types/model/errors/index.d.ts +2 -2
  51. package/dist/types/model/errors/operation-errors.d.ts +1 -41
  52. package/dist/types/model/index.d.ts +2 -2
  53. package/dist/types/onchain/accounts/intents/guards.d.ts +2 -18
  54. package/dist/types/onchain/accounts/intents/index.d.ts +14 -23
  55. package/dist/types/onchain/accounts/intents/maxWithdrawCollateral.d.ts +8 -3
  56. package/dist/types/onchain/accounts/intents/types.d.ts +4 -26
  57. package/dist/types/onchain/index.d.ts +1 -2
  58. package/dist/types/onchain/validation/checks/index.d.ts +1 -2
  59. package/dist/types/onchain/validation/index.d.ts +1 -2
  60. package/dist/types/onchain/validation/raise.d.ts +2 -2
  61. package/dist/types/sdk/prepare/PrepareApi.d.ts +1 -1
  62. package/dist/types/sdk/prepare/types.d.ts +16 -23
  63. package/package.json +1 -1
  64. package/dist/cjs/onchain/accounts/intents/collateral-money.js +0 -41
  65. package/dist/cjs/onchain/accounts/intents/withdraw-limits.js +0 -97
  66. package/dist/cjs/onchain/validation/checks/checkReservePriceLimited.js +0 -30
  67. package/dist/esm/onchain/accounts/intents/collateral-money.js +0 -40
  68. package/dist/esm/onchain/accounts/intents/withdraw-limits.js +0 -95
  69. package/dist/esm/onchain/validation/checks/checkReservePriceLimited.js +0 -29
  70. package/dist/types/onchain/accounts/intents/collateral-money.d.ts +0 -42
  71. package/dist/types/onchain/accounts/intents/withdraw-limits.d.ts +0 -80
  72. package/dist/types/onchain/validation/checks/checkReservePriceLimited.d.ts +0 -31
@@ -10,14 +10,24 @@ const iMidasPausableVaultAbi = (0, viem.parseAbi)([
10
10
  "function paused() external view returns (bool)",
11
11
  "function pause() external",
12
12
  "function unpause() external",
13
+ "function fnPaused(bytes4 fn) external view returns (bool)",
14
+ "function pauseFn(bytes4 fn) external",
15
+ "function unpauseFn(bytes4 fn) external",
13
16
  "function pauseAdminRole() external view returns (bytes32)",
14
17
  "function accessControl() external view returns (address)"
15
18
  ]);
16
19
  const iMidasAccessControlAbi = (0, viem.parseAbi)(["function hasRole(bytes32 role, address account) external view returns (bool)", "function grantRole(bytes32 role, address account) external"]);
17
20
  /**
18
- * Unpauses a globally paused Midas issuance vault on an anvil fork, so that
19
- * `depositInstant` stops reverting with `Pausable: paused`, and returns a
20
- * callback that restores the original pause state.
21
+ * Selector for `DepositVault.depositInstant(address,uint256,uint256,bytes32)`,
22
+ * the 4-arg mint Gearbox adapters encode. Distinct from the custom-recipient
23
+ * overload.
24
+ */
25
+ const DEPOSIT_INSTANT_SELECTOR = (0, viem.toFunctionSelector)("depositInstant(address,uint256,uint256,bytes32)");
26
+ /**
27
+ * Unpauses a Midas issuance vault on an anvil fork so that `depositInstant`
28
+ * stops reverting with `Pausable: paused` (global) or `Pausable: fn paused`
29
+ * (per-selector), and returns a callback that restores the original pause
30
+ * state of each layer that was cleared.
21
31
  *
22
32
  * Impersonates `admin` and grants it `pauseAdminRole()` when missing, same as
23
33
  * `greenlistMidasGateway` does with the greenlist roles. The grant is not
@@ -25,11 +35,20 @@ const iMidasAccessControlAbi = (0, viem.parseAbi)(["function hasRole(bytes32 rol
25
35
  */
26
36
  async function unpauseMidasIssuanceVault(props) {
27
37
  const { anvil, vault, admin, logger } = props;
28
- if (!await anvil.readContract({
29
- address: vault,
30
- abi: iMidasPausableVaultAbi,
31
- functionName: "paused"
32
- })) {
38
+ const [paused, depositInstantPaused] = await anvil.multicall({
39
+ allowFailure: false,
40
+ contracts: [{
41
+ address: vault,
42
+ abi: iMidasPausableVaultAbi,
43
+ functionName: "paused"
44
+ }, {
45
+ address: vault,
46
+ abi: iMidasPausableVaultAbi,
47
+ functionName: "fnPaused",
48
+ args: [DEPOSIT_INSTANT_SELECTOR]
49
+ }]
50
+ });
51
+ if (!paused && !depositInstantPaused) {
33
52
  logger?.debug(`midas: issuance vault ${vault} is not paused`);
34
53
  return async () => {};
35
54
  }
@@ -51,7 +70,7 @@ async function unpauseMidasIssuanceVault(props) {
51
70
  functionName: "hasRole",
52
71
  args: [pauseAdminRole, admin]
53
72
  });
54
- logger?.debug(`midas: unpausing issuance vault ${vault} as ${admin}, access control ${accessControl}, pause admin role ${pauseAdminRole}`);
73
+ logger?.debug(`midas: unpausing issuance vault ${vault} as ${admin}, access control ${accessControl}, pause admin role ${pauseAdminRole}` + (paused ? ", global" : "") + (depositInstantPaused ? ", depositInstant" : ""));
55
74
  await anvil.impersonateAccount({ address: admin });
56
75
  try {
57
76
  await anvil.setBalance({
@@ -69,13 +88,21 @@ async function unpauseMidasIssuanceVault(props) {
69
88
  });
70
89
  logger?.debug(`midas: granted pause admin role to ${admin}`);
71
90
  }
72
- await require_dev_kycUtils.writeAndWait(anvil, {
91
+ if (paused) await require_dev_kycUtils.writeAndWait(anvil, {
73
92
  account: admin,
74
93
  chain: anvil.chain,
75
94
  address: vault,
76
95
  abi: iMidasPausableVaultAbi,
77
96
  functionName: "unpause"
78
97
  });
98
+ if (depositInstantPaused) await require_dev_kycUtils.writeAndWait(anvil, {
99
+ account: admin,
100
+ chain: anvil.chain,
101
+ address: vault,
102
+ abi: iMidasPausableVaultAbi,
103
+ functionName: "unpauseFn",
104
+ args: [DEPOSIT_INSTANT_SELECTOR]
105
+ });
79
106
  } finally {
80
107
  await anvil.stopImpersonatingAccount({ address: admin });
81
108
  }
@@ -90,13 +117,21 @@ async function unpauseMidasIssuanceVault(props) {
90
117
  address: admin,
91
118
  value: (0, viem.parseEther)("100")
92
119
  });
93
- await require_dev_kycUtils.writeAndWait(anvil, {
120
+ if (paused) await require_dev_kycUtils.writeAndWait(anvil, {
94
121
  account: admin,
95
122
  chain: anvil.chain,
96
123
  address: vault,
97
124
  abi: iMidasPausableVaultAbi,
98
125
  functionName: "pause"
99
126
  });
127
+ if (depositInstantPaused) await require_dev_kycUtils.writeAndWait(anvil, {
128
+ account: admin,
129
+ chain: anvil.chain,
130
+ address: vault,
131
+ abi: iMidasPausableVaultAbi,
132
+ functionName: "pauseFn",
133
+ args: [DEPOSIT_INSTANT_SELECTOR]
134
+ });
100
135
  } catch (e) {
101
136
  logger?.warn(`midas: failed to pause issuance vault ${vault} back: ${e}`);
102
137
  } finally {
@@ -28,7 +28,6 @@ exports.poolPaused = require_model_errors_operation_errors.poolPaused;
28
28
  exports.poolSunset = require_model_errors_operation_errors.poolSunset;
29
29
  exports.quotaCountExceeded = require_model_errors_operation_errors.quotaCountExceeded;
30
30
  exports.quotaLimitReached = require_model_errors_operation_errors.quotaLimitReached;
31
- exports.reservePriceLimited = require_model_errors_operation_errors.reservePriceLimited;
32
31
  exports.rwaOpenRequirementsNotMet = require_model_errors_operation_errors.rwaOpenRequirementsNotMet;
33
32
  exports.unexpectedFailure = require_model_errors_prepare_errors.unexpectedFailure;
34
33
  exports.unpriceableTokenError = require_model_errors_oracle_errors.unpriceableTokenError;
@@ -67,14 +67,6 @@ function insufficientCollateral(args) {
67
67
  ...args
68
68
  };
69
69
  }
70
- /** {@inheritDoc ReservePriceLimitedError} */
71
- function reservePriceLimited(args) {
72
- return {
73
- code: "reservePriceLimited",
74
- message: `The reserve price feed values this collateral below what the operation pays out: the account covers its debt at ${args.atMainPrices} on the main feed and only ${args.healthFactor} at the reserve one, below ${args.healthFactorThreshold}.`,
75
- ...args
76
- };
77
- }
78
70
  /** {@inheritDoc ForbiddenTokenError} */
79
71
  function forbiddenToken(token) {
80
72
  return {
@@ -140,5 +132,4 @@ exports.poolPaused = poolPaused;
140
132
  exports.poolSunset = poolSunset;
141
133
  exports.quotaCountExceeded = quotaCountExceeded;
142
134
  exports.quotaLimitReached = quotaLimitReached;
143
- exports.reservePriceLimited = reservePriceLimited;
144
135
  exports.rwaOpenRequirementsNotMet = rwaOpenRequirementsNotMet;
@@ -175,7 +175,6 @@ exports.quotaLimitReached = require_model_errors_operation_errors.quotaLimitReac
175
175
  exports.rateCurvePointSchema = require_model_opportunities_schema.rateCurvePointSchema;
176
176
  exports.rateCurveSchema = require_model_opportunities_schema.rateCurveSchema;
177
177
  exports.receivedAssetSchema = require_model_liquidations_schema.receivedAssetSchema;
178
- exports.reservePriceLimited = require_model_errors_operation_errors.reservePriceLimited;
179
178
  exports.responseMetadataSchema = require_model_response_schema.responseMetadataSchema;
180
179
  exports.responseSchema = require_model_response_schema.responseSchema;
181
180
  exports.rewardsPnLSchema = require_model_positions_schema.rewardsPnLSchema;
@@ -7,7 +7,6 @@ const require_onchain_validation_checks_checkCreditManagerPaused = require("../.
7
7
  const require_onchain_validation_checks_checkForbiddenToken = require("../../validation/checks/checkForbiddenToken.js");
8
8
  const require_onchain_validation_checks_checkMarketExpired = require("../../validation/checks/checkMarketExpired.js");
9
9
  const require_onchain_validation_checks_checkQuotaLimit = require("../../validation/checks/checkQuotaLimit.js");
10
- const require_onchain_validation_checks_checkReservePriceLimited = require("../../validation/checks/checkReservePriceLimited.js");
11
10
  const require_onchain_validation_raise = require("../../validation/raise.js");
12
11
  require("../../validation/index.js");
13
12
  const require_onchain_accounts_intents_utils_common = require("./utils/common.js");
@@ -113,24 +112,13 @@ function assertGrowthAllowed(args) {
113
112
  * whose reserve feed the SDK cannot read keeps its main price, so a plan can
114
113
  * still be refused on-chain after passing here.
115
114
  */
116
- function assertCollateralised(healthFactorBps, safePrices, atSafePrices) {
115
+ function assertCollateralised(healthFactorBps, safePrices) {
117
116
  const healthFactorThreshold = require_onchain_validation_helpers_health_factor_limits.MIN_HEALTH_FACTOR_FACADE;
118
- const errors = require_onchain_validation_checks_checkCollateralised.checkCollateralised({
117
+ require_onchain_validation_raise.raise(require_onchain_validation_checks_checkCollateralised.checkCollateralised({
119
118
  healthFactor: healthFactorBps,
120
119
  healthFactorThreshold,
121
120
  safePrices
122
- });
123
- if (errors.length === 0) return;
124
- if (safePrices && atSafePrices) {
125
- const { atMainPrices, withdrawable } = atSafePrices();
126
- require_onchain_validation_raise.raise(require_onchain_validation_checks_checkReservePriceLimited.checkReservePriceLimited({
127
- healthFactor: healthFactorBps,
128
- atMainPrices,
129
- healthFactorThreshold,
130
- withdrawable
131
- }), `the account covers its debt at ${atMainPrices} on the main feed and only ${healthFactorBps} at the reserve one, below ${healthFactorThreshold}`);
132
- }
133
- require_onchain_validation_raise.raise(errors, `the account would end at a health factor of ${healthFactorBps}, below ${healthFactorThreshold}`);
121
+ }), `the account would end at a health factor of ${healthFactorBps}, below ${healthFactorThreshold}`);
134
122
  }
135
123
  /**
136
124
  * A quota can only be raised as far as the market still has room for: past the
@@ -9,13 +9,13 @@ require("../../validation/index.js");
9
9
  const require_onchain_accounts_intents_utils_pick_token = require("./utils/pick-token.js");
10
10
  const require_onchain_accounts_intents_guards = require("./guards.js");
11
11
  const require_onchain_accounts_intents_leverage_band = require("./leverage-band.js");
12
+ const require_onchain_accounts_intents_math = require("./math.js");
12
13
  const require_onchain_accounts_intents_maxWithdrawCollateral = require("./maxWithdrawCollateral.js");
13
14
  const require_onchain_accounts_intents_utils_credit_account_slice = require("./utils/credit-account-slice.js");
14
15
  const require_onchain_accounts_intents_open_strategy = require("./open-strategy.js");
15
16
  const require_onchain_accounts_intents_plan = require("./plan.js");
16
- const require_onchain_accounts_intents_view = require("./view.js");
17
- const require_onchain_accounts_intents_withdraw_limits = require("./withdraw-limits.js");
18
17
  const require_onchain_accounts_intents_realize = require("./realize.js");
18
+ const require_onchain_accounts_intents_view = require("./view.js");
19
19
  const require_onchain_accounts_intents_tail = require("./tail.js");
20
20
  //#region src/onchain/accounts/intents/index.ts
21
21
  /**
@@ -51,29 +51,26 @@ var CreditAccountOperationsService = class extends require_onchain_base_SDKConst
51
51
  }
52
52
  /**
53
53
  * Both ends of what a `WITHDRAW` can take out, in underlying: the largest
54
- * partial withdrawal that keeps leverage, and the net value an exit hands
55
- * over. They are reported together because a withdraw form needs both — the
56
- * range it may offer, and the one amount past it that is allowed — and
57
- * because the distance between them is the account's own, not a constant a
58
- * caller could assume.
59
- *
60
- * Two rules bound the partial end and both are reported: the facade's
61
- * `debtLimits` as `partial`, and the safe-price collateral check on top of
62
- * it as `safePartial`. The second is the one to offer — see
63
- * {@link WithdrawCeilings}.
54
+ * partial withdrawal that keeps leverage and stays inside the facade's
55
+ * `debtLimits`, and the net value an exit hands over. They are reported together
56
+ * because a withdraw form needs both — the range it may offer, and the one
57
+ * amount past it that is allowed — and because the distance between them is
58
+ * the account's own, not a constant a caller could assume.
64
59
  *
65
- * Takes no target health factor, unlike {@link maxWithdrawCollateral}. A
66
- * proportional withdrawal leaves the factor where it found it, so there is
67
- * no room to choose: what these answer to is the facade's own threshold,
68
- * which is also what {@link startIntent} refuses against.
60
+ * Takes no target health factor, unlike {@link maxWithdrawCollateral}: a
61
+ * proportional withdrawal leaves the factor where it found it, and the
62
+ * facade's `minDebt` is what bounds it.
69
63
  *
70
- * @param props - Account slice, the SDK holding its market, and optionally
71
- * the collateral the withdrawal would be funded from
72
- * @returns The three limits, see {@link WithdrawCeilings} for the gap
73
- * between them
64
+ * @param props - Account slice and the SDK holding its market
65
+ * @returns The two ceilings, see {@link WithdrawCeilings} for the gap between
66
+ * them
74
67
  */
75
68
  maxWithdraw(props) {
76
- return require_onchain_accounts_intents_withdraw_limits.withdrawLimits(props);
69
+ const view = require_onchain_accounts_intents_view.accountView(props.creditAccount, props.sdk);
70
+ return {
71
+ partial: require_onchain_accounts_intents_math.maxProportionalWithdrawal(view, view.debtLimits),
72
+ exit: view.collateral > 0n ? view.collateral : 0n
73
+ };
77
74
  }
78
75
  /**
79
76
  * Debt a `REPAY` would have to cover to settle the account, in underlying
@@ -1,18 +1,22 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_onchain_utils_bigint_math = require("../../utils/bigint-math.js");
3
- require("../../constants/math.js");
3
+ const require_onchain_constants_math = require("../../constants/math.js");
4
4
  require("../../utils/index.js");
5
5
  const require_onchain_accounts_intents_utils_common = require("./utils/common.js");
6
- const require_onchain_accounts_intents_collateral_money = require("./collateral-money.js");
7
6
  //#region src/onchain/accounts/intents/maxWithdrawCollateral.ts
8
7
  /**
9
8
  * Largest amount of one collateral the account can withdraw while its health
10
9
  * factor stays at or above `targetHF`.
11
10
  *
12
11
  * This is the collateral check solved for one balance, and it counts what that
13
- * check counts — see {@link collateralMoney} for the valuation, safe prices
14
- * included. The debt is valued at the main feed, as the check does. Zero debt
15
- * frees the whole balance.
12
+ * check counts: a holding backed by a quota contributes the lesser of the
13
+ * quota and its threshold-weighted value, an unquoted one — the underlying —
14
+ * its weighted value alone, and dust or a disabled balance nothing at all.
15
+ * Collateral is valued at the protocol safe price (`min` of the two feeds,
16
+ * 0 when there is no reserve), the way the facade values a call that hands
17
+ * funds over; the underlying is exempt and is valued at the main feed, as
18
+ * `CreditManagerV3._safeConvertToUSD` does. The debt is valued at the main
19
+ * feed, as the check does. Zero debt frees the whole balance.
16
20
  *
17
21
  * Rounding always favours the account, so the answer clears the check rather
18
22
  * than landing a wei short of it.
@@ -23,27 +27,49 @@ const require_onchain_accounts_intents_collateral_money = require("./collateral-
23
27
  **/
24
28
  function maxWithdrawCollateral(props) {
25
29
  const { creditAccount, sdk, token, targetHF } = props;
30
+ const { market, creditManager } = sdk.marketRegister.findCreditManager(creditAccount.creditManager);
31
+ const { priceOracle } = market;
32
+ const { pqk } = market.pool;
33
+ const underlying = market.pool.underlying;
26
34
  const target = creditAccount.tokens.find((t) => require_onchain_accounts_intents_utils_common.eq(t.token, token));
27
35
  if (!target || target.balance <= 10n) return 0n;
28
36
  if (creditAccount.totalDebt === 0n) return target.balance;
29
- const money = require_onchain_accounts_intents_collateral_money.collateralMoney(creditAccount, sdk);
37
+ const masked = creditAccount.enabledTokensMask !== 0n;
38
+ const counts = (t) => t.balance > 10n && (!masked || (t.mask & creditAccount.enabledTokensMask) !== 0n);
39
+ /** What a holding backs, in the check's units: USD × PERCENTAGE_FACTOR. */
40
+ const weigh = (t) => {
41
+ const lt = BigInt(creditManager.liquidationThresholds.get(t.token) ?? 0);
42
+ const weighted = (require_onchain_accounts_intents_utils_common.eq(t.token, underlying) ? usd(priceOracle, t.token, t.balance) ?? 0n : priceOracle.safeConvertMinUSD(t.token, t.balance).value) * lt;
43
+ if (t.quota === 0n) return weighted;
44
+ return require_onchain_utils_bigint_math.BigIntMath.min(quotaUsd(t) * require_onchain_constants_math.PERCENTAGE_FACTOR, weighted);
45
+ };
46
+ /** A quota is underlying-denominated, and a closed market backs nothing. */
47
+ const quotaUsd = (t) => pqk.hasActiveQuota(t.token) ? usd(priceOracle, underlying, t.quota) ?? 0n : 0n;
30
48
  let otherMoney = 0n;
31
49
  for (const t of creditAccount.tokens) {
32
- if (require_onchain_accounts_intents_utils_common.eq(t.token, token) || !money.counts(t)) continue;
33
- otherMoney += money.weigh(t);
50
+ if (require_onchain_accounts_intents_utils_common.eq(t.token, token) || !counts(t)) continue;
51
+ otherMoney += weigh(t);
34
52
  }
35
- const borrowed = money.mainUsd(money.underlying, creditAccount.totalDebt);
53
+ const borrowed = usd(priceOracle, underlying, creditAccount.totalDebt);
36
54
  if (borrowed === void 0 || borrowed <= 0n) return 0n;
37
55
  const required = borrowed * targetHF;
38
56
  if (required <= otherMoney) return target.balance;
39
57
  const shortfall = required - otherMoney;
40
- if (target.quota > 0n && money.quotaMoney(target) < shortfall) return 0n;
41
- const targetLt = money.lt(target.token);
42
- const targetUsd = money.checkedUsd(target);
58
+ if (target.quota > 0n && quotaUsd(target) * 10000n < shortfall) return 0n;
59
+ const targetLt = BigInt(creditManager.liquidationThresholds.get(target.token) ?? 0);
60
+ const targetUsd = require_onchain_accounts_intents_utils_common.eq(target.token, underlying) ? usd(priceOracle, target.token, target.balance) ?? 0n : priceOracle.safeConvertMinUSD(target.token, target.balance).value;
43
61
  if (targetLt === 0n || targetUsd === 0n) return 0n;
44
62
  const keptUsd = require_onchain_utils_bigint_math.BigIntMath.ceilDiv(shortfall, targetLt);
45
63
  const kept = require_onchain_utils_bigint_math.BigIntMath.ceilDiv(target.balance * keptUsd, targetUsd);
46
64
  return kept >= target.balance ? 0n : target.balance - kept;
47
65
  }
66
+ /** USD value at the main feed, or `undefined` when the token has no price. */
67
+ function usd(oracle, token, amount) {
68
+ try {
69
+ return oracle.convertToUSD(token, amount);
70
+ } catch {
71
+ return;
72
+ }
73
+ }
48
74
  //#endregion
49
75
  exports.maxWithdrawCollateral = maxWithdrawCollateral;
@@ -12,7 +12,6 @@ const require_onchain_accounts_intents_utils_price_impact = require("./utils/pri
12
12
  const require_onchain_accounts_intents_utils_quotas_for_update = require("./utils/quotas-for-update.js");
13
13
  const require_onchain_accounts_intents_utils_router_path = require("./utils/router-path.js");
14
14
  const require_onchain_accounts_intents_operations = require("./operations.js");
15
- const require_onchain_accounts_intents_withdraw_limits = require("./withdraw-limits.js");
16
15
  //#region src/onchain/accounts/intents/realize.ts
17
16
  /**
18
17
  * Turns a plan into operations: the one place that talks to the router, knows
@@ -321,18 +320,11 @@ async function realize(steps, props) {
321
320
  totalValue: projected.totalValue
322
321
  };
323
322
  const projection = sdk.positions.projection(snapshot, { availableLiquidityChange: creditAccount.totalDebt - debt });
324
- const settled = {
323
+ require_onchain_accounts_intents_guards.assertCollateralised(sdk.positions.healthFactor({
325
324
  ...snapshot,
326
325
  assets,
327
326
  totalValue: floor.totalValue
328
- };
329
- require_onchain_accounts_intents_guards.assertCollateralised(sdk.positions.healthFactor(settled, { safePrices: withdrawsCollateral }), withdrawsCollateral, () => ({
330
- atMainPrices: sdk.positions.healthFactor(settled, { safePrices: false }),
331
- withdrawable: require_onchain_validation_helpers_token.toTokenAmount(sdk, underlying, require_onchain_accounts_intents_withdraw_limits.withdrawLimits({
332
- creditAccount,
333
- sdk
334
- }).safePartial)
335
- }));
327
+ }, { safePrices: withdrawsCollateral }), withdrawsCollateral);
336
328
  const priceImpact = await require_onchain_accounts_intents_utils_price_impact.collectPriceImpact(probes, {
337
329
  totalValue: projected.totalValue,
338
330
  netValue: projected.totalValue - debt,
@@ -8,8 +8,8 @@ const require_onchain_accounts_intents_utils_common = require("./utils/common.js
8
8
  const require_onchain_accounts_intents_utils_router_path = require("./utils/router-path.js");
9
9
  const require_onchain_accounts_intents_plan = require("./plan.js");
10
10
  const require_onchain_accounts_intents_operations = require("./operations.js");
11
- const require_onchain_accounts_intents_view = require("./view.js");
12
11
  const require_onchain_accounts_intents_realize = require("./realize.js");
12
+ const require_onchain_accounts_intents_view = require("./view.js");
13
13
  //#region src/onchain/accounts/intents/tail.ts
14
14
  /**
15
15
  * The second half of a delayed intent: the claim, then whatever the intent
@@ -213,7 +213,6 @@ 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");
217
216
  const require_onchain_validation_bundles_checkAccountQuotas = require("./validation/bundles/checkAccountQuotas.js");
218
217
  const require_onchain_validation_bundles_checkWalletAllowance = require("./validation/bundles/checkWalletAllowance.js");
219
218
  const require_onchain_validation_bundles_checkWalletBalance = require("./validation/bundles/checkWalletBalance.js");
@@ -587,7 +586,6 @@ exports.checkQuotaCount = require_onchain_validation_checks_checkQuotaCount.chec
587
586
  exports.checkQuotaLimit = require_onchain_validation_checks_checkQuotaLimit.checkQuotaLimit;
588
587
  exports.checkRWAOpenRequirements = require_onchain_validation_bundles_checkRWAOpenRequirements.checkRWAOpenRequirements;
589
588
  exports.checkRWAOpening = require_onchain_validation_bundles_checkRWAOpening.checkRWAOpening;
590
- exports.checkReservePriceLimited = require_onchain_validation_checks_checkReservePriceLimited.checkReservePriceLimited;
591
589
  exports.checkSimulation = require_onchain_validation_checkSimulation.checkSimulation;
592
590
  exports.checkWallet = require_onchain_validation_bundles_checkWallet.checkWallet;
593
591
  exports.checkWalletAllowance = require_onchain_validation_bundles_checkWalletAllowance.checkWalletAllowance;
@@ -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.BASIC_ADAPTER_ABI },
23
+ ["MIDAS_GATEWAY"]: { 311: require_onchain_market_adapters_abi_conctructorAbiPatterns.REFERER_ID_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
@@ -14,7 +14,6 @@ const require_onchain_validation_checks_checkPoolPaused = require("./checkPoolPa
14
14
  const require_onchain_validation_checks_checkPoolSunset = require("./checkPoolSunset.js");
15
15
  const require_onchain_validation_checks_checkQuotaCount = require("./checkQuotaCount.js");
16
16
  const require_onchain_validation_checks_checkQuotaLimit = require("./checkQuotaLimit.js");
17
- const require_onchain_validation_checks_checkReservePriceLimited = require("./checkReservePriceLimited.js");
18
17
  exports.checkBorrowLimit = require_onchain_validation_checks_checkBorrowLimit.checkBorrowLimit;
19
18
  exports.checkCollateralised = require_onchain_validation_checks_checkCollateralised.checkCollateralised;
20
19
  exports.checkCreditAccountFrozen = require_onchain_validation_checks_checkCreditAccountFrozen.checkCreditAccountFrozen;
@@ -30,4 +29,3 @@ exports.checkPoolPaused = require_onchain_validation_checks_checkPoolPaused.chec
30
29
  exports.checkPoolSunset = require_onchain_validation_checks_checkPoolSunset.checkPoolSunset;
31
30
  exports.checkQuotaCount = require_onchain_validation_checks_checkQuotaCount.checkQuotaCount;
32
31
  exports.checkQuotaLimit = require_onchain_validation_checks_checkQuotaLimit.checkQuotaLimit;
33
- exports.checkReservePriceLimited = require_onchain_validation_checks_checkReservePriceLimited.checkReservePriceLimited;
@@ -18,7 +18,6 @@ const require_onchain_validation_checks_checkPoolPaused = require("./checks/chec
18
18
  const require_onchain_validation_checks_checkPoolSunset = require("./checks/checkPoolSunset.js");
19
19
  const require_onchain_validation_checks_checkQuotaCount = require("./checks/checkQuotaCount.js");
20
20
  const require_onchain_validation_checks_checkQuotaLimit = require("./checks/checkQuotaLimit.js");
21
- const require_onchain_validation_checks_checkReservePriceLimited = require("./checks/checkReservePriceLimited.js");
22
21
  require("./checks/index.js");
23
22
  const require_onchain_validation_bundles_checkAccountQuotas = require("./bundles/checkAccountQuotas.js");
24
23
  const require_onchain_validation_bundles_checkWalletAllowance = require("./bundles/checkWalletAllowance.js");
@@ -78,7 +77,6 @@ exports.checkQuotaCount = require_onchain_validation_checks_checkQuotaCount.chec
78
77
  exports.checkQuotaLimit = require_onchain_validation_checks_checkQuotaLimit.checkQuotaLimit;
79
78
  exports.checkRWAOpenRequirements = require_onchain_validation_bundles_checkRWAOpenRequirements.checkRWAOpenRequirements;
80
79
  exports.checkRWAOpening = require_onchain_validation_bundles_checkRWAOpening.checkRWAOpening;
81
- exports.checkReservePriceLimited = require_onchain_validation_checks_checkReservePriceLimited.checkReservePriceLimited;
82
80
  exports.checkSimulation = require_onchain_validation_checkSimulation.checkSimulation;
83
81
  exports.checkWallet = require_onchain_validation_bundles_checkWallet.checkWallet;
84
82
  exports.checkWalletAllowance = require_onchain_validation_bundles_checkWalletAllowance.checkWalletAllowance;
@@ -259,13 +259,12 @@ var PrepareApi = class extends require_onchain_base_MultichainConstruct.Multicha
259
259
  /**
260
260
  * {@inheritDoc IOpportunitiesPrepare.maxWithdraw}
261
261
  **/
262
- async maxWithdraw(position, sourceToken) {
262
+ async maxWithdraw(position) {
263
263
  const sdk = await this.#chain(position.chainId);
264
264
  const creditAccount = await this.#account(sdk, position);
265
265
  return service(sdk).maxWithdraw({
266
266
  creditAccount,
267
- sdk,
268
- sourceToken
267
+ sdk
269
268
  });
270
269
  }
271
270
  /**
@@ -1,5 +1,5 @@
1
- import { iCreditFacadeV310Abi } from "../abi/310/generated.js";
2
1
  import { ierc20Abi } from "../abi/iERC20.js";
2
+ import { iCreditFacadeV310Abi } from "../abi/310/generated.js";
3
3
  import { AddressMap } from "../onchain/utils/AddressMap.js";
4
4
  import { AddressSet } from "../onchain/utils/AddressSet.js";
5
5
  import { AssetsMap } from "../onchain/utils/AssetsMap.js";
@@ -1,5 +1,5 @@
1
1
  import { writeAndWait } from "./kycUtils.js";
2
- import { parseAbi, parseEther } from "viem";
2
+ import { parseAbi, parseEther, toFunctionSelector } from "viem";
3
3
  //#region src/dev/midasUtils.ts
4
4
  /**
5
5
  * Midas vaults inherit their own `Pausable`, whose global pause is guarded by
@@ -9,14 +9,24 @@ const iMidasPausableVaultAbi = parseAbi([
9
9
  "function paused() external view returns (bool)",
10
10
  "function pause() external",
11
11
  "function unpause() external",
12
+ "function fnPaused(bytes4 fn) external view returns (bool)",
13
+ "function pauseFn(bytes4 fn) external",
14
+ "function unpauseFn(bytes4 fn) external",
12
15
  "function pauseAdminRole() external view returns (bytes32)",
13
16
  "function accessControl() external view returns (address)"
14
17
  ]);
15
18
  const iMidasAccessControlAbi = parseAbi(["function hasRole(bytes32 role, address account) external view returns (bool)", "function grantRole(bytes32 role, address account) external"]);
16
19
  /**
17
- * Unpauses a globally paused Midas issuance vault on an anvil fork, so that
18
- * `depositInstant` stops reverting with `Pausable: paused`, and returns a
19
- * callback that restores the original pause state.
20
+ * Selector for `DepositVault.depositInstant(address,uint256,uint256,bytes32)`,
21
+ * the 4-arg mint Gearbox adapters encode. Distinct from the custom-recipient
22
+ * overload.
23
+ */
24
+ const DEPOSIT_INSTANT_SELECTOR = toFunctionSelector("depositInstant(address,uint256,uint256,bytes32)");
25
+ /**
26
+ * Unpauses a Midas issuance vault on an anvil fork so that `depositInstant`
27
+ * stops reverting with `Pausable: paused` (global) or `Pausable: fn paused`
28
+ * (per-selector), and returns a callback that restores the original pause
29
+ * state of each layer that was cleared.
20
30
  *
21
31
  * Impersonates `admin` and grants it `pauseAdminRole()` when missing, same as
22
32
  * `greenlistMidasGateway` does with the greenlist roles. The grant is not
@@ -24,11 +34,20 @@ const iMidasAccessControlAbi = parseAbi(["function hasRole(bytes32 role, address
24
34
  */
25
35
  async function unpauseMidasIssuanceVault(props) {
26
36
  const { anvil, vault, admin, logger } = props;
27
- if (!await anvil.readContract({
28
- address: vault,
29
- abi: iMidasPausableVaultAbi,
30
- functionName: "paused"
31
- })) {
37
+ const [paused, depositInstantPaused] = await anvil.multicall({
38
+ allowFailure: false,
39
+ contracts: [{
40
+ address: vault,
41
+ abi: iMidasPausableVaultAbi,
42
+ functionName: "paused"
43
+ }, {
44
+ address: vault,
45
+ abi: iMidasPausableVaultAbi,
46
+ functionName: "fnPaused",
47
+ args: [DEPOSIT_INSTANT_SELECTOR]
48
+ }]
49
+ });
50
+ if (!paused && !depositInstantPaused) {
32
51
  logger?.debug(`midas: issuance vault ${vault} is not paused`);
33
52
  return async () => {};
34
53
  }
@@ -50,7 +69,7 @@ async function unpauseMidasIssuanceVault(props) {
50
69
  functionName: "hasRole",
51
70
  args: [pauseAdminRole, admin]
52
71
  });
53
- logger?.debug(`midas: unpausing issuance vault ${vault} as ${admin}, access control ${accessControl}, pause admin role ${pauseAdminRole}`);
72
+ logger?.debug(`midas: unpausing issuance vault ${vault} as ${admin}, access control ${accessControl}, pause admin role ${pauseAdminRole}` + (paused ? ", global" : "") + (depositInstantPaused ? ", depositInstant" : ""));
54
73
  await anvil.impersonateAccount({ address: admin });
55
74
  try {
56
75
  await anvil.setBalance({
@@ -68,13 +87,21 @@ async function unpauseMidasIssuanceVault(props) {
68
87
  });
69
88
  logger?.debug(`midas: granted pause admin role to ${admin}`);
70
89
  }
71
- await writeAndWait(anvil, {
90
+ if (paused) await writeAndWait(anvil, {
72
91
  account: admin,
73
92
  chain: anvil.chain,
74
93
  address: vault,
75
94
  abi: iMidasPausableVaultAbi,
76
95
  functionName: "unpause"
77
96
  });
97
+ if (depositInstantPaused) await writeAndWait(anvil, {
98
+ account: admin,
99
+ chain: anvil.chain,
100
+ address: vault,
101
+ abi: iMidasPausableVaultAbi,
102
+ functionName: "unpauseFn",
103
+ args: [DEPOSIT_INSTANT_SELECTOR]
104
+ });
78
105
  } finally {
79
106
  await anvil.stopImpersonatingAccount({ address: admin });
80
107
  }
@@ -89,13 +116,21 @@ async function unpauseMidasIssuanceVault(props) {
89
116
  address: admin,
90
117
  value: parseEther("100")
91
118
  });
92
- await writeAndWait(anvil, {
119
+ if (paused) await writeAndWait(anvil, {
93
120
  account: admin,
94
121
  chain: anvil.chain,
95
122
  address: vault,
96
123
  abi: iMidasPausableVaultAbi,
97
124
  functionName: "pause"
98
125
  });
126
+ if (depositInstantPaused) await writeAndWait(anvil, {
127
+ account: admin,
128
+ chain: anvil.chain,
129
+ address: vault,
130
+ abi: iMidasPausableVaultAbi,
131
+ functionName: "pauseFn",
132
+ args: [DEPOSIT_INSTANT_SELECTOR]
133
+ });
99
134
  } catch (e) {
100
135
  logger?.warn(`midas: failed to pause issuance vault ${vault} back: ${e}`);
101
136
  } finally {
@@ -1,6 +1,6 @@
1
+ import { iWithdrawalCompressorV313Abi } from "../abi/IWithdrawalCompressorV313.js";
1
2
  import { getNetworkType } from "../onchain/chain/chains.js";
2
3
  import { getWithdrawalCompressorAddress } from "../onchain/accounts/withdrawal-compressor/addresses.js";
3
- import { iWithdrawalCompressorV313Abi } from "../abi/IWithdrawalCompressorV313.js";
4
4
  import "../onchain/index.js";
5
5
  import { iMidasDataFeedAbi, iMidasRedemptionVaultAbi, midasGatewayAbi, midasRedeemerAbi, midasRedemptionVaultPhantomTokenAbi, securitizeRedeemerAbi, securitizeRedemptionGatewayAbi, securitizeRedemptionPhantomTokenAbi } from "./withdrawalAbi.js";
6
6
  import { erc20Abi, hexToString, parseAbi, parseEther } from "viem";
@@ -1,5 +1,5 @@
1
- import { iCreditFacadeV310Abi } from "../../abi/310/generated.js";
2
1
  import { ierc20Abi } from "../../abi/iERC20.js";
2
+ import { iCreditFacadeV310Abi } from "../../abi/310/generated.js";
3
3
  import { AddressMap } from "../../onchain/utils/AddressMap.js";
4
4
  import "../../onchain/index.js";
5
5
  import { UnexpectedFacadeEventOrderError } from "./errors.js";
@@ -1,7 +1,7 @@
1
1
  import "./base.js";
2
2
  import { creditAccountFrozen, liquidatorNotEligible, notEmergencyLiquidator } from "./liquidation-errors.js";
3
- import { creditManagerPaused, debtOutOfRange, forbiddenToken, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, leverageOutOfRange, marketExpired, poolPaused, poolSunset, quotaCountExceeded, quotaLimitReached, reservePriceLimited, rwaOpenRequirementsNotMet } from "./operation-errors.js";
3
+ import { creditManagerPaused, debtOutOfRange, forbiddenToken, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, leverageOutOfRange, marketExpired, poolPaused, poolSunset, quotaCountExceeded, quotaLimitReached, rwaOpenRequirementsNotMet } from "./operation-errors.js";
4
4
  import { unpriceableTokenError } from "./oracle-errors.js";
5
5
  import { creditAccountNotEmpty, creditAccountNotFound, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, unexpectedFailure, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress } from "./prepare-errors.js";
6
6
  import { malformedTransaction } from "./preview-errors.js";
7
- export { creditAccountFrozen, creditAccountNotEmpty, creditAccountNotFound, creditManagerPaused, debtOutOfRange, forbiddenToken, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, leverageOutOfRange, liquidatorNotEligible, malformedTransaction, marketExpired, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, notEmergencyLiquidator, poolPaused, poolSunset, quotaCountExceeded, quotaLimitReached, reservePriceLimited, rwaOpenRequirementsNotMet, unexpectedFailure, unpriceableTokenError, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress };
7
+ export { creditAccountFrozen, creditAccountNotEmpty, creditAccountNotFound, creditManagerPaused, debtOutOfRange, forbiddenToken, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, leverageOutOfRange, liquidatorNotEligible, malformedTransaction, marketExpired, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, notEmergencyLiquidator, poolPaused, poolSunset, quotaCountExceeded, quotaLimitReached, rwaOpenRequirementsNotMet, unexpectedFailure, unpriceableTokenError, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress };
@@ -66,14 +66,6 @@ function insufficientCollateral(args) {
66
66
  ...args
67
67
  };
68
68
  }
69
- /** {@inheritDoc ReservePriceLimitedError} */
70
- function reservePriceLimited(args) {
71
- return {
72
- code: "reservePriceLimited",
73
- message: `The reserve price feed values this collateral below what the operation pays out: the account covers its debt at ${args.atMainPrices} on the main feed and only ${args.healthFactor} at the reserve one, below ${args.healthFactorThreshold}.`,
74
- ...args
75
- };
76
- }
77
69
  /** {@inheritDoc ForbiddenTokenError} */
78
70
  function forbiddenToken(token) {
79
71
  return {
@@ -126,4 +118,4 @@ function rwaOpenRequirementsNotMet(args) {
126
118
  };
127
119
  }
128
120
  //#endregion
129
- export { creditManagerPaused, debtOutOfRange, forbiddenToken, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, leverageOutOfRange, marketExpired, poolPaused, poolSunset, quotaCountExceeded, quotaLimitReached, reservePriceLimited, rwaOpenRequirementsNotMet };
121
+ export { creditManagerPaused, debtOutOfRange, forbiddenToken, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, leverageOutOfRange, marketExpired, poolPaused, poolSunset, quotaCountExceeded, quotaLimitReached, rwaOpenRequirementsNotMet };