@gearbox-protocol/sdk 16.5.2 → 16.6.0-next.1

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.
@@ -16,7 +16,6 @@ require("../market/index.js");
16
16
  const require_onchain_accounts_credit_account_compressor_CreditAccountCompressor = require("./credit-account-compressor/CreditAccountCompressor.js");
17
17
  require("./credit-account-compressor/index.js");
18
18
  const require_onchain_accounts_multicall_utils = require("./multicall-utils.js");
19
- const require_onchain_accounts_utils_midasUtils = require("./utils/midasUtils.js");
20
19
  let viem = require("viem");
21
20
  //#region src/onchain/accounts/CreditAccountsServiceV310.ts
22
21
  /**
@@ -213,7 +212,7 @@ var CreditAccountsServiceV310 = class extends require_onchain_base_SDKConstruct.
213
212
  }),
214
213
  ...callsAfter ?? []
215
214
  ];
216
- calls = await this.#prependMidasReceiveGreenlist(cm.address, calls);
215
+ calls = [...await cmSuite.openingCalls(), ...calls];
217
216
  calls = await this.prependPriceUpdates(cm.address, calls);
218
217
  const tx = reopenCreditAccount ? cmSuite.multicallTx(reopenCreditAccount, calls, rwaOptions) : cmSuite.openCreditAccountTx(to, calls, referralCode, rwaOptions);
219
218
  tx.value = ethAmount.toString(10);
@@ -440,18 +439,6 @@ var CreditAccountsServiceV310 = class extends require_onchain_base_SDKConstruct.
440
439
  return this.sdk.addressProvider.mustGetLatest(require_onchain_constants_address_provider.AP_REWARDS_COMPRESSOR, require_onchain_constants_versions.VERSION_RANGE_310)[0];
441
440
  }
442
441
  /**
443
- * {@inheritDoc ICreditAccountsService.prependMidasReceiveGreenlist}
444
- */
445
- async #prependMidasReceiveGreenlist(creditManager, calls) {
446
- const cm = this.sdk.marketRegister.findCreditManager(creditManager);
447
- return require_onchain_accounts_utils_midasUtils.prependMidasReceiveGreenlist({
448
- cm,
449
- client: this.client,
450
- calls,
451
- logger: this.logger
452
- });
453
- }
454
- /**
455
442
  * Withdrawal compressor of the current chain.
456
443
  * @throws If no withdrawal compressor is supported on the current chain.
457
444
  **/
@@ -129,6 +129,12 @@ var AbstractAdapterContract = class extends require_onchain_base_BaseContract.Ba
129
129
  return false;
130
130
  }
131
131
  /**
132
+ * {@inheritDoc IAdapterContract.openingCalls}
133
+ */
134
+ async openingCalls() {
135
+ return [];
136
+ }
137
+ /**
132
138
  * Applies the balance changes of a decoded adapter call to the running
133
139
  * balances, mutating them in place. Overrides should express changes via
134
140
  * {@link setLeftover} (diff-style calls) and {@link spendExact}
@@ -14,6 +14,12 @@ const receiveGreenlistCalldata = (0, viem.encodeFunctionData)({
14
14
  abi,
15
15
  functionName: "receiveGreenlist"
16
16
  });
17
+ const MGLOBAL_MTOKEN = (0, viem.getAddress)("0x7433806912Eae67919e66aea853d46Fa0aef98A8");
18
+ /**
19
+ * Permissionless gateways have no greenlist and reject `receiveGreenlist`,
20
+ * see MidasMode in integrations-v3
21
+ */
22
+ const MIDAS_MODE_PERMISSIONLESS = 0;
17
23
  var MidasGatewayAdapterContract = class extends require_onchain_market_adapters_contracts_AbstractAdapter.AbstractAdapterContract {
18
24
  #version;
19
25
  #gateway;
@@ -21,6 +27,7 @@ var MidasGatewayAdapterContract = class extends require_onchain_market_adapters_
21
27
  #quoteToken;
22
28
  #phantomToken;
23
29
  #referrerId;
30
+ #mode;
24
31
  constructor(sdk, args) {
25
32
  super(sdk, {
26
33
  ...args,
@@ -126,6 +133,35 @@ var MidasGatewayAdapterContract = class extends require_onchain_market_adapters_
126
133
  if (this.#referrerId === void 0) throw new require_onchain_base_errors.MissingSerializedParamsError("referrerId");
127
134
  return this.#referrerId;
128
135
  }
136
+ /**
137
+ * Gateway `mode` is immutable on-chain, so the first read is reused.
138
+ */
139
+ async mode() {
140
+ if (!this.#mode) this.#mode = this.client.readContract({
141
+ address: this.targetContract,
142
+ abi: this.protocolAbi,
143
+ functionName: "mode"
144
+ });
145
+ return this.#mode;
146
+ }
147
+ /**
148
+ * {@inheritDoc IAdapterContract.openingCalls}
149
+ */
150
+ async openingCalls() {
151
+ if ((0, viem.isAddressEqual)(this.mToken, MGLOBAL_MTOKEN)) {
152
+ this.logger?.debug(`midas: skipping receiveGreenlist for mGLOBAL ${this.mToken}`);
153
+ return [];
154
+ }
155
+ if (await this.mode() === MIDAS_MODE_PERMISSIONLESS) {
156
+ this.logger?.debug(`midas: gateway ${this.targetContract} is permissionless, nothing to greenlist`);
157
+ return [];
158
+ }
159
+ this.logger?.debug(`midas: greenlisting the credit account via gateway adapter ${this.address}`);
160
+ return [{
161
+ target: this.address,
162
+ callData: receiveGreenlistCalldata
163
+ }];
164
+ }
129
165
  stateHuman(raw) {
130
166
  return {
131
167
  ...super.stateHuman(raw),
@@ -177,11 +213,11 @@ var MidasGatewayAdapterContract = class extends require_onchain_market_adapters_
177
213
  return calldata === receiveGreenlistCalldata;
178
214
  }
179
215
  /**
180
- * `receiveGreenlist()` is prepended by `prependMidasReceiveGreenlist`
181
- * before the balance bracket when the multicall mints a permissioned
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.
216
+ * `receiveGreenlist()` is prepended by {@link openingCalls} before the
217
+ * balance bracket when a permissioned mToken is minted: it only grants
218
+ * the Midas greenlisted role to the credit account and is
219
+ * balance-neutral, so it is legal outside a bracket and leaves balances
220
+ * untouched.
185
221
  */
186
222
  replayOutOfBracketCall(_balances, calldata) {
187
223
  return this.isReceiveGreenlist(calldata);
@@ -179,6 +179,13 @@ var CreditSuite = class extends require_onchain_base_SDKConstruct.SDKConstruct {
179
179
  return rwaFactory ? rwaFactory.openCreditAccount(this.creditManager.address, calls, rwaOptions) : this.creditFacade.openCreditAccount(to, calls, referralCode ?? 0n);
180
180
  }
181
181
  /**
182
+ * Calls to run first in the multicall of a freshly opened account on this
183
+ * suite; use before {@link openCreditAccountTx}.
184
+ */
185
+ async openingCalls() {
186
+ return (await Promise.all(this.creditManager.adapters.values().map((a) => a.openingCalls()))).flat();
187
+ }
188
+ /**
182
189
  * Router configured for this credit suite.
183
190
  */
184
191
  get router() {
@@ -15,7 +15,6 @@ import "../market/index.js";
15
15
  import { CreditAccountCompressor } from "./credit-account-compressor/CreditAccountCompressor.js";
16
16
  import "./credit-account-compressor/index.js";
17
17
  import { extractPriceUpdates, extractQuotaTokens, mergePriceUpdates } from "./multicall-utils.js";
18
- import { prependMidasReceiveGreenlist } from "./utils/midasUtils.js";
19
18
  import { encodeFunctionData } from "viem";
20
19
  //#region src/onchain/accounts/CreditAccountsServiceV310.ts
21
20
  /**
@@ -212,7 +211,7 @@ var CreditAccountsServiceV310 = class extends SDKConstruct {
212
211
  }),
213
212
  ...callsAfter ?? []
214
213
  ];
215
- calls = await this.#prependMidasReceiveGreenlist(cm.address, calls);
214
+ calls = [...await cmSuite.openingCalls(), ...calls];
216
215
  calls = await this.prependPriceUpdates(cm.address, calls);
217
216
  const tx = reopenCreditAccount ? cmSuite.multicallTx(reopenCreditAccount, calls, rwaOptions) : cmSuite.openCreditAccountTx(to, calls, referralCode, rwaOptions);
218
217
  tx.value = ethAmount.toString(10);
@@ -439,18 +438,6 @@ var CreditAccountsServiceV310 = class extends SDKConstruct {
439
438
  return this.sdk.addressProvider.mustGetLatest(AP_REWARDS_COMPRESSOR, VERSION_RANGE_310)[0];
440
439
  }
441
440
  /**
442
- * {@inheritDoc ICreditAccountsService.prependMidasReceiveGreenlist}
443
- */
444
- async #prependMidasReceiveGreenlist(creditManager, calls) {
445
- const cm = this.sdk.marketRegister.findCreditManager(creditManager);
446
- return prependMidasReceiveGreenlist({
447
- cm,
448
- client: this.client,
449
- calls,
450
- logger: this.logger
451
- });
452
- }
453
- /**
454
441
  * Withdrawal compressor of the current chain.
455
442
  * @throws If no withdrawal compressor is supported on the current chain.
456
443
  **/
@@ -128,6 +128,12 @@ var AbstractAdapterContract = class extends BaseContract {
128
128
  return false;
129
129
  }
130
130
  /**
131
+ * {@inheritDoc IAdapterContract.openingCalls}
132
+ */
133
+ async openingCalls() {
134
+ return [];
135
+ }
136
+ /**
131
137
  * Applies the balance changes of a decoded adapter call to the running
132
138
  * balances, mutating them in place. Overrides should express changes via
133
139
  * {@link setLeftover} (diff-style calls) and {@link spendExact}
@@ -5,7 +5,7 @@ import "../abi/adapters/index.js";
5
5
  import { iMidasGatewayV311Abi } from "../abi/midas/iMidasGatewayV311.js";
6
6
  import "../abi/index.js";
7
7
  import { AbstractAdapterContract } from "./AbstractAdapter.js";
8
- import { decodeAbiParameters, decodeFunctionData, encodeFunctionData, isAddressEqual, zeroAddress } from "viem";
8
+ import { decodeAbiParameters, decodeFunctionData, encodeFunctionData, getAddress, isAddressEqual, zeroAddress } from "viem";
9
9
  //#region src/onchain/market/adapters/contracts/MidasGatewayAdapterContract.ts
10
10
  const abi = iMidasGatewayAdapterV311Abi;
11
11
  const protocolAbi = iMidasGatewayV311Abi;
@@ -13,6 +13,12 @@ const receiveGreenlistCalldata = encodeFunctionData({
13
13
  abi,
14
14
  functionName: "receiveGreenlist"
15
15
  });
16
+ const MGLOBAL_MTOKEN = getAddress("0x7433806912Eae67919e66aea853d46Fa0aef98A8");
17
+ /**
18
+ * Permissionless gateways have no greenlist and reject `receiveGreenlist`,
19
+ * see MidasMode in integrations-v3
20
+ */
21
+ const MIDAS_MODE_PERMISSIONLESS = 0;
16
22
  var MidasGatewayAdapterContract = class extends AbstractAdapterContract {
17
23
  #version;
18
24
  #gateway;
@@ -20,6 +26,7 @@ var MidasGatewayAdapterContract = class extends AbstractAdapterContract {
20
26
  #quoteToken;
21
27
  #phantomToken;
22
28
  #referrerId;
29
+ #mode;
23
30
  constructor(sdk, args) {
24
31
  super(sdk, {
25
32
  ...args,
@@ -125,6 +132,35 @@ var MidasGatewayAdapterContract = class extends AbstractAdapterContract {
125
132
  if (this.#referrerId === void 0) throw new MissingSerializedParamsError("referrerId");
126
133
  return this.#referrerId;
127
134
  }
135
+ /**
136
+ * Gateway `mode` is immutable on-chain, so the first read is reused.
137
+ */
138
+ async mode() {
139
+ if (!this.#mode) this.#mode = this.client.readContract({
140
+ address: this.targetContract,
141
+ abi: this.protocolAbi,
142
+ functionName: "mode"
143
+ });
144
+ return this.#mode;
145
+ }
146
+ /**
147
+ * {@inheritDoc IAdapterContract.openingCalls}
148
+ */
149
+ async openingCalls() {
150
+ if (isAddressEqual(this.mToken, MGLOBAL_MTOKEN)) {
151
+ this.logger?.debug(`midas: skipping receiveGreenlist for mGLOBAL ${this.mToken}`);
152
+ return [];
153
+ }
154
+ if (await this.mode() === MIDAS_MODE_PERMISSIONLESS) {
155
+ this.logger?.debug(`midas: gateway ${this.targetContract} is permissionless, nothing to greenlist`);
156
+ return [];
157
+ }
158
+ this.logger?.debug(`midas: greenlisting the credit account via gateway adapter ${this.address}`);
159
+ return [{
160
+ target: this.address,
161
+ callData: receiveGreenlistCalldata
162
+ }];
163
+ }
128
164
  stateHuman(raw) {
129
165
  return {
130
166
  ...super.stateHuman(raw),
@@ -176,11 +212,11 @@ var MidasGatewayAdapterContract = class extends AbstractAdapterContract {
176
212
  return calldata === receiveGreenlistCalldata;
177
213
  }
178
214
  /**
179
- * `receiveGreenlist()` is prepended by `prependMidasReceiveGreenlist`
180
- * before the balance bracket when the multicall mints a permissioned
181
- * mToken: it only grants the Midas greenlisted role to the credit
182
- * account and is balance-neutral, so it is legal outside a bracket and
183
- * leaves balances untouched.
215
+ * `receiveGreenlist()` is prepended by {@link openingCalls} before the
216
+ * balance bracket when a permissioned mToken is minted: it only grants
217
+ * the Midas greenlisted role to the credit account and is
218
+ * balance-neutral, so it is legal outside a bracket and leaves balances
219
+ * untouched.
184
220
  */
185
221
  replayOutOfBracketCall(_balances, calldata) {
186
222
  return this.isReceiveGreenlist(calldata);
@@ -178,6 +178,13 @@ var CreditSuite = class extends SDKConstruct {
178
178
  return rwaFactory ? rwaFactory.openCreditAccount(this.creditManager.address, calls, rwaOptions) : this.creditFacade.openCreditAccount(to, calls, referralCode ?? 0n);
179
179
  }
180
180
  /**
181
+ * Calls to run first in the multicall of a freshly opened account on this
182
+ * suite; use before {@link openCreditAccountTx}.
183
+ */
184
+ async openingCalls() {
185
+ return (await Promise.all(this.creditManager.adapters.values().map((a) => a.openingCalls()))).flat();
186
+ }
187
+ /**
181
188
  * Router configured for this credit suite.
182
189
  */
183
190
  get router() {
@@ -3,8 +3,10 @@ import { AssetsMap } from "../../../utils/AssetsMap.js";
3
3
  import { AdapterContractStateHuman, AdapterContractType, AdapterProtocolOperation, DelayedWithdrawalClaim, DelayedWithdrawalRequest, IAdapterContract } from "../types.js";
4
4
  import { CallTrace } from "../../../utils/trace.js";
5
5
  import { LegacyAdapterOperation, Transfers } from "../legacyAdapterOperations.js";
6
+ import { MultiCall } from "../../../types/transactions.js";
6
7
  import { OnchainSDK } from "../../../OnchainSDK.js";
7
8
  import "../../../utils/index.js";
9
+ import "../../../types/index.js";
8
10
  import { BaseContract } from "../../../base/BaseContract.js";
9
11
  import "../../../base/index.js";
10
12
  import { Abi, Address, DecodeFunctionDataReturnType, Hex } from "viem";
@@ -69,6 +71,10 @@ declare class AbstractAdapterContract<const abi extends Abi | readonly unknown[]
69
71
  * cannot be decoded
70
72
  */
71
73
  replayOutOfBracketCall(_balances: AssetsMap, _calldata: Hex): boolean;
74
+ /**
75
+ * {@inheritDoc IAdapterContract.openingCalls}
76
+ */
77
+ openingCalls(): Promise<MultiCall[]>;
72
78
  /**
73
79
  * Applies the balance changes of a decoded adapter call to the running
74
80
  * balances, mutating them in place. Overrides should express changes via
@@ -1,8 +1,10 @@
1
1
  import { AssetsMap } from "../../../utils/AssetsMap.js";
2
2
  import { DelayedWithdrawalClaim, DelayedWithdrawalRequest } from "../types.js";
3
3
  import { AbstractAdapterContract, ConcreteAdapterContractOptions } from "./AbstractAdapter.js";
4
+ import { MultiCall } from "../../../types/transactions.js";
4
5
  import { OnchainSDK } from "../../../OnchainSDK.js";
5
6
  import "../../../utils/index.js";
7
+ import "../../../types/index.js";
6
8
  import { Address, DecodeFunctionDataReturnType, Hex } from "viem";
7
9
  //#region src/onchain/market/adapters/contracts/MidasGatewayAdapterContract.d.ts
8
10
  declare const abi: readonly [{
@@ -625,6 +627,14 @@ declare class MidasGatewayAdapterContract extends AbstractAdapterContract<abi, p
625
627
  */
626
628
  get phantomToken(): Address;
627
629
  get referrerId(): string | undefined;
630
+ /**
631
+ * Gateway `mode` is immutable on-chain, so the first read is reused.
632
+ */
633
+ mode(): Promise<number>;
634
+ /**
635
+ * {@inheritDoc IAdapterContract.openingCalls}
636
+ */
637
+ openingCalls(): Promise<MultiCall[]>;
628
638
  stateHuman(raw?: boolean): {
629
639
  address: string;
630
640
  version: number;
@@ -655,11 +665,11 @@ declare class MidasGatewayAdapterContract extends AbstractAdapterContract<abi, p
655
665
  */
656
666
  isReceiveGreenlist(calldata: Hex): boolean;
657
667
  /**
658
- * `receiveGreenlist()` is prepended by `prependMidasReceiveGreenlist`
659
- * before the balance bracket when the multicall mints a permissioned
660
- * mToken: it only grants the Midas greenlisted role to the credit
661
- * account and is balance-neutral, so it is legal outside a bracket and
662
- * leaves balances untouched.
668
+ * `receiveGreenlist()` is prepended by {@link openingCalls} before the
669
+ * balance bracket when a permissioned mToken is minted: it only grants
670
+ * the Midas greenlisted role to the credit account and is
671
+ * balance-neutral, so it is legal outside a bracket and leaves balances
672
+ * untouched.
663
673
  */
664
674
  replayOutOfBracketCall(_balances: AssetsMap, calldata: Hex): boolean;
665
675
  protected applyBalanceChanges(balances: AssetsMap, decoded: DecodeFunctionDataReturnType<abi>): void;
@@ -1,10 +1,18 @@
1
1
  import { IBaseContract } from "../../base/types.js";
2
2
  import { BaseContractStateHuman } from "../../types/state-human.js";
3
+ import { MultiCall } from "../../types/transactions.js";
4
+ import "../../types/index.js";
3
5
  import "../../base/index.js";
4
6
  import { AbiParameter, Address, Hex } from "viem";
5
7
  //#region src/onchain/market/adapters/types.d.ts
6
8
  interface IAdapterContract extends IBaseContract {
7
9
  targetContract: Address;
10
+ /**
11
+ * Multicall entries a freshly opened credit account on this adapter's
12
+ * credit manager must run first. Decided from adapter state alone, not
13
+ * from the rest of the multicall.
14
+ */
15
+ openingCalls(): Promise<MultiCall[]>;
8
16
  }
9
17
  type VersionedAbi = Record<number, readonly AbiParameter[]>;
10
18
  type AdapterContractType = "ADAPTER::ACCOUNT_MIGRATOR" | "ADAPTER::BALANCER_V3_ROUTER" | "ADAPTER::BALANCER_V3_WRAPPER" | "ADAPTER::CAMELOT_V3_ROUTER" | "ADAPTER::CURVE_STABLE_NG" | "ADAPTER::CURVE_V1_2ASSETS" | "ADAPTER::CURVE_V1_3ASSETS" | "ADAPTER::CURVE_V1_4ASSETS" | "ADAPTER::CURVE_V1_STECRV_POOL" | "ADAPTER::CVX_V1_BASE_REWARD_POOL" | "ADAPTER::CVX_V1_BOOSTER" | "ADAPTER::DAI_USDS_EXCHANGE" | "ADAPTER::ERC4626_VAULT" | "ADAPTER::ERC4626_VAULT_REFERRAL" | "ADAPTER::FLUID_DEX" | "ADAPTER::INFINIFI_GATEWAY" | "ADAPTER::INFINIFI_UNWINDING" | "ADAPTER::KELP_DEPOSIT_POOL" | "ADAPTER::KELP_WITHDRAWAL" | "ADAPTER::LIDO_V1" | "ADAPTER::LIDO_WSTETH_V1" | "ADAPTER::MELLOW_CLAIMER" | "ADAPTER::MELLOW_DVV" | "ADAPTER::MELLOW_ERC4626_VAULT" | "ADAPTER::MELLOW_WRAPPER" | "ADAPTER::MIDAS_GATEWAY" | "ADAPTER::MIDAS_ISSUANCE_VAULT" | "ADAPTER::MIDAS_REDEMPTION_VAULT" | "ADAPTER::PENDLE_ROUTER" | "ADAPTER::SECURITIZE_ONRAMP" | "ADAPTER::SECURITIZE_REDEMPTION" | "ADAPTER::STAKING_REWARDS" | "ADAPTER::TRADERJOE_ROUTER" | "ADAPTER::UNISWAP_V2_ROUTER" | "ADAPTER::UNISWAP_V3_ROUTER" | "ADAPTER::UNISWAP_V4_GATEWAY" | "ADAPTER::UPSHIFT_VAULT" | "ADAPTER::VELODROME_V2_ROUTER";
@@ -127,6 +127,11 @@ declare class CreditSuite extends SDKConstruct {
127
127
  * @param rwaOptions - Factory-specific args, ignored on non-RWA markets.
128
128
  */
129
129
  openCreditAccountTx(to: Address, calls: MultiCall[], referralCode?: bigint, rwaOptions?: RWAOperationArgs): RawTx;
130
+ /**
131
+ * Calls to run first in the multicall of a freshly opened account on this
132
+ * suite; use before {@link openCreditAccountTx}.
133
+ */
134
+ openingCalls(): Promise<MultiCall[]>;
130
135
  /**
131
136
  * Router configured for this credit suite.
132
137
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "16.5.2",
3
+ "version": "16.6.0-next.1",
4
4
  "description": "Gearbox SDK",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,76 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_onchain_utils_AddressMap = require("../../utils/AddressMap.js");
3
- let viem = require("viem");
4
- //#region src/onchain/accounts/utils/midasUtils.ts
5
- const ADAPTER_MIDAS_GATEWAY = "ADAPTER::MIDAS_GATEWAY";
6
- const ADAPTER_MIDAS_ISSUANCE_VAULT = "ADAPTER::MIDAS_ISSUANCE_VAULT";
7
- const MGLOBAL_MTOKEN = (0, viem.getAddress)("0x7433806912Eae67919e66aea853d46Fa0aef98A8");
8
- /**
9
- * Permissionless gateways have no greenlist and reject `receiveGreenlist`,
10
- * see MidasMode in integrations-v3
11
- */
12
- const MIDAS_MODE_PERMISSIONLESS = 0;
13
- const iMidasGatewayAdapterExtAbi = (0, viem.parseAbi)(["function receiveGreenlist() external returns (bool)"]);
14
- const iMidasGatewayModeAbi = (0, viem.parseAbi)(["function mode() external view returns (uint8)"]);
15
- const receiveGreenlistCallData = (0, viem.encodeFunctionData)({
16
- abi: iMidasGatewayAdapterExtAbi,
17
- functionName: "receiveGreenlist"
18
- });
19
- /**
20
- * Prepends `MidasGatewayAdapter.receiveGreenlist()` to a credit facade
21
- * multicall that mints an mToken through a Midas issuance vault.
22
- *
23
- * Permissioned and restricted-interface mTokens can only be held by greenlisted
24
- * accounts, and a freshly opened credit account is never greenlisted, so the
25
- * mint reverts with `WMAC: hasnt role` unless the account asks the gateway for
26
- * the greenlist first. Greenlisting the borrower is not enough — the role is
27
- * checked on the token holder, which is the credit account.
28
- *
29
- * Returns `calls` unchanged when nothing has to be greenlisted: no issuance
30
- * vault is called, its mToken has no gateway adapter on this credit manager,
31
- * the gateway is permissionless, the call is already there, or the mToken is
32
- * mGLOBAL (temporary: its gateway cannot grant the greenlist).
33
- */
34
- async function prependMidasReceiveGreenlist(props) {
35
- const { cm, client, calls, logger } = props;
36
- const adapters = Array.from(cm.creditManager.adapters.values());
37
- const gatewayByMToken = require_onchain_utils_AddressMap.AddressMap.fromMappedArray(adapters.filter((a) => a.contractType === ADAPTER_MIDAS_GATEWAY), (a) => a.mToken);
38
- const calledVaults = adapters.filter((a) => a.contractType === ADAPTER_MIDAS_ISSUANCE_VAULT).filter((vault) => calls.some((call) => (0, viem.isAddressEqual)(call.target, vault.address)));
39
- if (gatewayByMToken.size === 0 || calledVaults.length === 0) return calls;
40
- const gateways = new require_onchain_utils_AddressMap.AddressMap();
41
- for (const vault of calledVaults) {
42
- if ((0, viem.isAddressEqual)(vault.mToken, MGLOBAL_MTOKEN)) {
43
- logger?.debug(`midas: skipping receiveGreenlist for mGLOBAL ${vault.mToken}`);
44
- continue;
45
- }
46
- const gateway = gatewayByMToken.get(vault.mToken);
47
- if (!gateway) logger?.debug(`midas: no gateway adapter for mToken ${vault.mToken} minted by ${vault.address} on ${cm.name}, cannot greenlist the credit account`);
48
- else if (calls.some((call) => (0, viem.isAddressEqual)(call.target, gateway.address) && call.callData === receiveGreenlistCallData)) logger?.debug(`midas: gateway adapter ${gateway.address} already receives the greenlist`);
49
- else gateways.upsert(gateway.address, gateway);
50
- }
51
- if (gateways.size === 0) return calls;
52
- const uniqueGateways = gateways.values();
53
- const modes = await client.multicall({
54
- allowFailure: false,
55
- contracts: uniqueGateways.map(({ targetContract }) => ({
56
- address: targetContract,
57
- abi: iMidasGatewayModeAbi,
58
- functionName: "mode"
59
- }))
60
- });
61
- const prepended = [];
62
- for (const [i, gateway] of uniqueGateways.entries()) {
63
- if (modes[i] === MIDAS_MODE_PERMISSIONLESS) {
64
- logger?.debug(`midas: gateway ${gateway.targetContract} is permissionless, nothing to greenlist`);
65
- continue;
66
- }
67
- logger?.debug(`midas: greenlisting the credit account via gateway adapter ${gateway.address}`);
68
- prepended.push({
69
- target: gateway.address,
70
- callData: receiveGreenlistCallData
71
- });
72
- }
73
- return prepended.length > 0 ? [...prepended, ...calls] : calls;
74
- }
75
- //#endregion
76
- exports.prependMidasReceiveGreenlist = prependMidasReceiveGreenlist;
@@ -1,75 +0,0 @@
1
- import { AddressMap } from "../../utils/AddressMap.js";
2
- import { encodeFunctionData, getAddress, isAddressEqual, parseAbi } from "viem";
3
- //#region src/onchain/accounts/utils/midasUtils.ts
4
- const ADAPTER_MIDAS_GATEWAY = "ADAPTER::MIDAS_GATEWAY";
5
- const ADAPTER_MIDAS_ISSUANCE_VAULT = "ADAPTER::MIDAS_ISSUANCE_VAULT";
6
- const MGLOBAL_MTOKEN = getAddress("0x7433806912Eae67919e66aea853d46Fa0aef98A8");
7
- /**
8
- * Permissionless gateways have no greenlist and reject `receiveGreenlist`,
9
- * see MidasMode in integrations-v3
10
- */
11
- const MIDAS_MODE_PERMISSIONLESS = 0;
12
- const iMidasGatewayAdapterExtAbi = parseAbi(["function receiveGreenlist() external returns (bool)"]);
13
- const iMidasGatewayModeAbi = parseAbi(["function mode() external view returns (uint8)"]);
14
- const receiveGreenlistCallData = encodeFunctionData({
15
- abi: iMidasGatewayAdapterExtAbi,
16
- functionName: "receiveGreenlist"
17
- });
18
- /**
19
- * Prepends `MidasGatewayAdapter.receiveGreenlist()` to a credit facade
20
- * multicall that mints an mToken through a Midas issuance vault.
21
- *
22
- * Permissioned and restricted-interface mTokens can only be held by greenlisted
23
- * accounts, and a freshly opened credit account is never greenlisted, so the
24
- * mint reverts with `WMAC: hasnt role` unless the account asks the gateway for
25
- * the greenlist first. Greenlisting the borrower is not enough — the role is
26
- * checked on the token holder, which is the credit account.
27
- *
28
- * Returns `calls` unchanged when nothing has to be greenlisted: no issuance
29
- * vault is called, its mToken has no gateway adapter on this credit manager,
30
- * the gateway is permissionless, the call is already there, or the mToken is
31
- * mGLOBAL (temporary: its gateway cannot grant the greenlist).
32
- */
33
- async function prependMidasReceiveGreenlist(props) {
34
- const { cm, client, calls, logger } = props;
35
- const adapters = Array.from(cm.creditManager.adapters.values());
36
- const gatewayByMToken = AddressMap.fromMappedArray(adapters.filter((a) => a.contractType === ADAPTER_MIDAS_GATEWAY), (a) => a.mToken);
37
- const calledVaults = adapters.filter((a) => a.contractType === ADAPTER_MIDAS_ISSUANCE_VAULT).filter((vault) => calls.some((call) => isAddressEqual(call.target, vault.address)));
38
- if (gatewayByMToken.size === 0 || calledVaults.length === 0) return calls;
39
- const gateways = new AddressMap();
40
- for (const vault of calledVaults) {
41
- if (isAddressEqual(vault.mToken, MGLOBAL_MTOKEN)) {
42
- logger?.debug(`midas: skipping receiveGreenlist for mGLOBAL ${vault.mToken}`);
43
- continue;
44
- }
45
- const gateway = gatewayByMToken.get(vault.mToken);
46
- if (!gateway) logger?.debug(`midas: no gateway adapter for mToken ${vault.mToken} minted by ${vault.address} on ${cm.name}, cannot greenlist the credit account`);
47
- else if (calls.some((call) => isAddressEqual(call.target, gateway.address) && call.callData === receiveGreenlistCallData)) logger?.debug(`midas: gateway adapter ${gateway.address} already receives the greenlist`);
48
- else gateways.upsert(gateway.address, gateway);
49
- }
50
- if (gateways.size === 0) return calls;
51
- const uniqueGateways = gateways.values();
52
- const modes = await client.multicall({
53
- allowFailure: false,
54
- contracts: uniqueGateways.map(({ targetContract }) => ({
55
- address: targetContract,
56
- abi: iMidasGatewayModeAbi,
57
- functionName: "mode"
58
- }))
59
- });
60
- const prepended = [];
61
- for (const [i, gateway] of uniqueGateways.entries()) {
62
- if (modes[i] === MIDAS_MODE_PERMISSIONLESS) {
63
- logger?.debug(`midas: gateway ${gateway.targetContract} is permissionless, nothing to greenlist`);
64
- continue;
65
- }
66
- logger?.debug(`midas: greenlisting the credit account via gateway adapter ${gateway.address}`);
67
- prepended.push({
68
- target: gateway.address,
69
- callData: receiveGreenlistCallData
70
- });
71
- }
72
- return prepended.length > 0 ? [...prepended, ...calls] : calls;
73
- }
74
- //#endregion
75
- export { prependMidasReceiveGreenlist };
@@ -1,39 +0,0 @@
1
- import { ILogger } from "../../types/logger.js";
2
- import { CreditSuite } from "../../market/credit/CreditSuite.js";
3
- import { MultiCall } from "../../types/transactions.js";
4
- import "../../types/index.js";
5
- import { PublicClient } from "viem";
6
- //#region src/onchain/accounts/utils/midasUtils.d.ts
7
- interface PrependMidasReceiveGreenlistProps {
8
- /**
9
- * Credit manager the account is opened on
10
- */
11
- cm: CreditSuite;
12
- /**
13
- * Client to read gateway `mode` with
14
- */
15
- client: PublicClient;
16
- /**
17
- * Calls to run in the credit facade multicall, as produced by the router
18
- */
19
- calls: MultiCall[];
20
- logger?: ILogger;
21
- }
22
- /**
23
- * Prepends `MidasGatewayAdapter.receiveGreenlist()` to a credit facade
24
- * multicall that mints an mToken through a Midas issuance vault.
25
- *
26
- * Permissioned and restricted-interface mTokens can only be held by greenlisted
27
- * accounts, and a freshly opened credit account is never greenlisted, so the
28
- * mint reverts with `WMAC: hasnt role` unless the account asks the gateway for
29
- * the greenlist first. Greenlisting the borrower is not enough — the role is
30
- * checked on the token holder, which is the credit account.
31
- *
32
- * Returns `calls` unchanged when nothing has to be greenlisted: no issuance
33
- * vault is called, its mToken has no gateway adapter on this credit manager,
34
- * the gateway is permissionless, the call is already there, or the mToken is
35
- * mGLOBAL (temporary: its gateway cannot grant the greenlist).
36
- */
37
- declare function prependMidasReceiveGreenlist(props: PrependMidasReceiveGreenlistProps): Promise<MultiCall[]>;
38
- //#endregion
39
- export { PrependMidasReceiveGreenlistProps, prependMidasReceiveGreenlist };