@gearbox-protocol/sdk 3.0.0-vfour.283 → 3.0.0-vfour.285

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.
@@ -56,17 +56,7 @@ class RouterV300Contract extends import_AbstractRouterContract.AbstractRouterCon
56
56
  this.#connectors = (0, import_sdk_gov_legacy.getConnectors)(sdk.provider.networkType);
57
57
  }
58
58
  /**
59
- * Finds all available swaps for given tokens; technically should be avoided to use, since doesn't have any advantage over findOneTokenPath.
60
- * Deduplicates results by minAmount + strigified call path and returns only unique ones.
61
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
62
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
63
- * @param {SwapOperation} swapOperation - {@link SwapOperation} = "EXACT_INPUT" | "EXACT_INPUT_ALL" | "EXACT_OUTPUT"; however router stopped to support EXACT_OUTPUT
64
- * @param {Address} tokenIn - address of input token
65
- * @param {Address} tokenOut - address of output token
66
- * @param {number | bigint} slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
67
- * @param {bigint} amount - amount of token in to swap
68
- * @param {bigint} leftoverAmount - amount that should be left on account after swap; technically equals to 0 in the most of the cases
69
- * @returns Array of {@link RouterResult}
59
+ * Implements {@link IRouterContract.findAllSwaps}
70
60
  */
71
61
  async findAllSwaps({
72
62
  creditAccount: ca,
@@ -106,16 +96,7 @@ class RouterV300Contract extends import_AbstractRouterContract.AbstractRouterCon
106
96
  return Object.values(unique);
107
97
  }
108
98
  /**
109
- * Find the best path to swap token A to token B.
110
- * - Connectors - list of tokens which can be used as a token to align path through, for ex. when swapping sUSDe it is good to check swaps through USDe.
111
- * - #overridePTRedeem - if token is PT token and PT token is already redeemable, we need to claim it manually, since old router can't do it. This can work in old app only because you cannot swap pt_sUSDe into sUSde before maturity and when it is matured, override takes place.
112
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
113
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
114
- * @param {Address} tokenIn - address of input token
115
- * @param {Address} tokenOut - address of output token
116
- * @param {number | bigint} slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
117
- * @param {bigint} amount - amount of token in to swap
118
- * @returns minAmount, avgAmount found and array of calls to execute swap
99
+ * Implements {@link IRouterContract.findOneTokenPath}
119
100
  */
120
101
  async findOneTokenPath(props) {
121
102
  const {
@@ -150,22 +131,7 @@ class RouterV300Contract extends import_AbstractRouterContract.AbstractRouterCon
150
131
  };
151
132
  }
152
133
  /**
153
- * @dev Finds the best path for opening Credit Account; converts all expectedBalances besides leftoverBalances into target token
154
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
155
- * @param {Array<Asset>} expectedBalances - Collateral assets + debt asset, nominated in ther respective tokens.
156
- * For example, if you open an USDC Credit Account, borrow 50_000 USDC and provide 10 WETH and 10_000 DAI as collateral
157
- * from your own funds, expectedBalances should be: [{amount: 10*10**wethDecimals}, {amount: 10000*10**daiDecimals}, {amount: 10000*10**usdcDecimals}]
158
- * @param leftoverBalances - balances to keep on account after opening.
159
- * For example if don't want to swap WETH in the example above, leftoverBalances should be: [{amount: 10*10**wethDecimals}]
160
- * @param target - Address of desired token to swap into
161
- * @param slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
162
- * @returns Router return list of all balances (including 0 balances) after operation, but it doesn't include original balance
163
- * - For example you had 5k sUSDS and 5k DAI as collateral, debt is 20k DAI, router will return 25k sUDS and all other token allowed on CM will be 0n or 1n
164
- * Since FE is interested in FULL balances structure, we override target balance in the following way:
165
- * min = record[sUSDS] = 5k from collateral + 25k of minAmount; avg = record[sUSDS] = 5k from collateral + 25.5k of avgAmount
166
- * - minAmount
167
- * - avgAmount
168
- * - array of calls to execute swap
134
+ * Implements {@link IRouterContract.findOpenStrategyPath}
169
135
  */
170
136
  async findOpenStrategyPath({
171
137
  creditManager: cm,
@@ -213,26 +179,7 @@ class RouterV300Contract extends import_AbstractRouterContract.AbstractRouterCon
213
179
  };
214
180
  }
215
181
  /**
216
- * @dev Finds the path to swap / withdraw all assets from CreditAccount into underlying asset
217
- * Can bu used for closing Credit Account and for liquidations as well.
218
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
219
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
220
- * @param {number | bigint} slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
221
- * @param {ClosePathBalances | undefined} balances - Balances {@link ClosePathBalances} to close account with, if not provided, all assets will be swapped according to inner logic.
222
- * Consists of:
223
- * @param {Array<Asset>} expectedBalances - list of all credit account balances nominated in their respective tokens.
224
- * For example: [{amount: 10x10^wethDecimals}, {amount: 10000x10^daiDecimals}]
225
- * @param {Array<Asset>} leftoverBalances - list of all credit account balances that shouldn't be swapped nominated in their respective tokens.
226
- * Used for credit account repaying; in this mode leftover assets list should include all assets besides underlying token.
227
- * For example considering account above is on DAI CM: [{amount: 10x10^wethDecimals}]
228
- * @return The best option in PathFinderCloseResult format, which
229
- * - underlyingBalance - since this method swaps only tokens different from underlying,
230
- * we are more interested in TOTAL balance of underlying token after all swaps are done
231
- * for this reason we sum up underlying token that was on account before swap
232
- * with underlying token amount found during swap and call it underlyingBalance
233
- * - calls - list of calls which should be done to swap & unwrap everything to underlying token
234
- * - amount
235
- * - minAmount
182
+ * Implements {@link IRouterContract.findBestClosePath}
236
183
  */
237
184
  async findBestClosePath({
238
185
  creditAccount: ca,
@@ -295,11 +242,7 @@ class RouterV300Contract extends import_AbstractRouterContract.AbstractRouterCon
295
242
  return result;
296
243
  }
297
244
  /**
298
- * Finds input to be used with findBestClosePath
299
- * Is used by batch liquidator
300
- * @param ca
301
- * @param cm
302
- * @returns
245
+ * Implements {@link IRouterContract.getFindClosePathInput}
303
246
  */
304
247
  getFindClosePathInput(ca, cm, balances) {
305
248
  const { expectedBalances, leftoverBalances } = this.getExpectedAndLeftover(
@@ -321,7 +264,7 @@ class RouterV300Contract extends import_AbstractRouterContract.AbstractRouterCon
321
264
  };
322
265
  }
323
266
  /**
324
- * Connectors - list of tokens which can be used as a token to align path through, for ex. when swapping sUSDe it is good to check swaps through USDe.
267
+ * Implements {@link IRouterContract.getAvailableConnectors}
325
268
  */
326
269
  getAvailableConnectors(collateralTokens) {
327
270
  return collateralTokens.filter(
@@ -329,9 +272,9 @@ class RouterV300Contract extends import_AbstractRouterContract.AbstractRouterCon
329
272
  );
330
273
  }
331
274
  /**
332
- * if token is PT token and PT token is already redeemable, we need to claim it manually, since old router can't do it.
333
- This can work in old app only because you cannot swap pt_sUSDe into sUSde before maturity and when it is matured, override takes place.
334
- */
275
+ * If token is PT token and PT token is already redeemable, we need to claim it manually, since old router can't do it.
276
+ * This can work in old app only because you cannot swap pt_sUSDe into sUSde before maturity and when it is matured, override takes place.
277
+ */
335
278
  async #overridePTRedeem({
336
279
  creditAccount,
337
280
  creditManager,
@@ -21,7 +21,10 @@ __export(RouterV310Contract_exports, {
21
21
  RouterV310Contract: () => RouterV310Contract
22
22
  });
23
23
  module.exports = __toCommonJS(RouterV310Contract_exports);
24
+ var import_viem = require("viem");
24
25
  var import_routerV310 = require("../../abi/routerV310.js");
26
+ var import_sdk_legacy = require("../sdk-legacy/index.js");
27
+ var import_AddressMap = require("../utils/AddressMap.js");
25
28
  var import_AbstractRouterContract = require("./AbstractRouterContract.js");
26
29
  var import_helpers = require("./helpers.js");
27
30
  const abi = import_routerV310.iGearboxRouterV310Abi;
@@ -30,29 +33,45 @@ class RouterV310Contract extends import_AbstractRouterContract.AbstractRouterCon
30
33
  constructor(sdk, address) {
31
34
  super(sdk, {
32
35
  addr: address,
33
- name: "RouterV300",
36
+ name: "RouterV310",
34
37
  abi
35
38
  });
36
39
  }
37
40
  /**
38
- * Finds best path to swap all Normal tokens and tokens "on the way" to target one and vice versa
39
- * @param creditAccount
40
- * @param creditManager
41
- * @param tokenIn
42
- * @param tokenOut
43
- * @param amount
44
- * @param slippage
45
- * @returns
41
+ * Implements {@link IRouterContract.findOneTokenPath}
46
42
  */
47
43
  async findOneTokenPath(props) {
44
+ const {
45
+ creditAccount,
46
+ creditManager,
47
+ amount,
48
+ slippage,
49
+ tokenIn,
50
+ tokenOut
51
+ } = props;
52
+ const numSplits = this.#numSplitsGetter(
53
+ creditManager,
54
+ creditAccount.tokens
55
+ )(tokenIn);
56
+ this.logger?.debug(
57
+ {
58
+ creditAccount: creditAccount.creditAccount,
59
+ creditManager: this.labelAddress(creditManager.address),
60
+ tokenIn: this.labelAddress(tokenIn),
61
+ target: this.labelAddress(tokenOut),
62
+ amount,
63
+ slippage,
64
+ numSplits
65
+ },
66
+ "calling routeOneToOne"
67
+ );
48
68
  const { result } = await this.contract.simulate.routeOneToOne([
49
- props.creditAccount.creditAccount,
50
- props.tokenIn,
51
- props.amount,
52
- props.tokenOut,
53
- BigInt(props.slippage),
54
- 4n
55
- // TODO:? how many 4n or 0n for underlying
69
+ creditAccount.creditAccount,
70
+ tokenIn,
71
+ amount,
72
+ tokenOut,
73
+ BigInt(slippage),
74
+ numSplits
56
75
  ]);
57
76
  return {
58
77
  amount: result.amount,
@@ -61,15 +80,7 @@ class RouterV310Contract extends import_AbstractRouterContract.AbstractRouterCon
61
80
  };
62
81
  }
63
82
  /**
64
- * @dev Finds the best path for opening Credit Account and converting all NORMAL tokens and LP token in the way to TARGET
65
- * @param creditManager CreditManagerData which represents credit manager you want to use to open Credit Account
66
- * @param expectedBalances Expected balances which would be on account accounting also debt. For example,
67
- * if you open an USDC Credit Account, borrow 50_000 USDC and provide 10 WETH and 10_USDC as collateral
68
- * from your own funds, expectedBalances should be: { "USDC": 60_000 * (10**6), "<address of WETH>": WAD.mul(10) }
69
- * @param leftoverBalances Balances to keep on account after opening
70
- * @param target Address of symbol of desired token
71
- * @param slippage Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
72
- * @returns PathFinderOpenStrategyResult which
83
+ * Implements {@link IRouterContract.findOpenStrategyPath}
73
84
  */
74
85
  async findOpenStrategyPath(props) {
75
86
  const {
@@ -83,15 +94,24 @@ class RouterV310Contract extends import_AbstractRouterContract.AbstractRouterCon
83
94
  (0, import_helpers.balancesMap)(expectedBalances),
84
95
  (0, import_helpers.balancesMap)(leftoverBalances)
85
96
  ];
97
+ const getNumSplits = this.#numSplitsGetter(cm, expectedBalances);
86
98
  const tData = cm.collateralTokens.map(
87
99
  (token) => ({
88
100
  token,
89
101
  balance: expectedMap.get(token) ?? 0n,
90
102
  leftoverBalance: leftoverMap.get(token) ?? 0n,
91
- numSplits: 4n
92
- // TODO:? how many 4n or 0n for underlying
103
+ numSplits: getNumSplits(token)
93
104
  })
94
105
  );
106
+ this.logger?.debug(
107
+ {
108
+ creditManager: this.labelAddress(cm.address),
109
+ target: this.labelAddress(target),
110
+ slippage,
111
+ tData: this.#debugTokenData(tData)
112
+ },
113
+ "calling routeOpenManyToOne"
114
+ );
95
115
  const { result } = await this.contract.simulate.routeOpenManyToOne([
96
116
  cm.address,
97
117
  target,
@@ -99,24 +119,25 @@ class RouterV310Contract extends import_AbstractRouterContract.AbstractRouterCon
99
119
  tData
100
120
  ]);
101
121
  return {
102
- balances: {},
103
- // TODO:?
104
- minBalances: {},
105
- // TODO:?
122
+ balances: balancesAfterOpen(
123
+ target,
124
+ result.amount,
125
+ expectedMap,
126
+ leftoverMap
127
+ ),
128
+ minBalances: balancesAfterOpen(
129
+ target,
130
+ result.minAmount,
131
+ expectedMap,
132
+ leftoverMap
133
+ ),
106
134
  amount: result.amount,
107
135
  minAmount: result.minAmount,
108
136
  calls: [...result.calls]
109
137
  };
110
138
  }
111
139
  /**
112
- * @dev Finds the path to swap / withdraw all assets from CreditAccount into underlying asset
113
- * Can bu used for closing Credit Account and for liquidations as well.
114
- * @param creditAccount CreditAccountStruct object used for close path computation
115
- * @param creditManager CreditManagerSlice for corresponding credit manager
116
- * @param slippage Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
117
- * @return The best option in PathFinderCloseResult format, which
118
- * - underlyingBalance - total balance of underlying token
119
- * - calls - list of calls which should be done to swap & unwrap everything to underlying token
140
+ * Implements {@link IRouterContract.findBestClosePath}
120
141
  */
121
142
  async findBestClosePath(props) {
122
143
  const { creditAccount: ca, creditManager: cm, slippage, balances } = props;
@@ -128,16 +149,26 @@ class RouterV310Contract extends import_AbstractRouterContract.AbstractRouterCon
128
149
  leftoverBalances: (0, import_helpers.assetsMap)(balances.leftoverBalances)
129
150
  } : void 0
130
151
  );
152
+ const getNumSplits = this.#numSplitsGetter(cm, expectedBalances.values());
131
153
  const tData = [];
132
154
  for (const token of cm.collateralTokens) {
133
155
  tData.push({
134
156
  token,
135
157
  balance: expectedBalances.get(token)?.balance || 0n,
136
158
  leftoverBalance: leftoverBalances.get(token)?.balance || 0n,
137
- numSplits: 4n
138
- // TODO:? how many 4n or 0n for underlying
159
+ numSplits: getNumSplits(token)
139
160
  });
140
161
  }
162
+ this.logger?.debug(
163
+ {
164
+ creditAccount: ca.creditAccount,
165
+ creditManager: this.labelAddress(cm.address),
166
+ target: this.labelAddress(ca.underlying),
167
+ slippage,
168
+ tData: this.#debugTokenData(tData)
169
+ },
170
+ "calling routeManyToOne"
171
+ );
141
172
  const { result } = await this.contract.simulate.routeManyToOne([
142
173
  cm.address,
143
174
  ca.underlying,
@@ -152,16 +183,74 @@ class RouterV310Contract extends import_AbstractRouterContract.AbstractRouterCon
152
183
  calls: [...result.calls]
153
184
  };
154
185
  }
186
+ #numSplitsGetter(creditManager, assets) {
187
+ const { priceOracle } = this.sdk.marketRegister.findByCreditManager(
188
+ creditManager.address
189
+ );
190
+ const inUSD = assets.filter(({ token, balance }) => {
191
+ const decimals = this.sdk.tokensMeta.decimals(token);
192
+ const minBalance = 10n ** BigInt(Math.max(8, decimals) - 8);
193
+ return balance >= minBalance;
194
+ }).map(({ token, balance }) => {
195
+ return {
196
+ token,
197
+ balance: priceOracle.convertToUSD(token, balance)
198
+ };
199
+ }).sort((a, b) => {
200
+ return b.balance > a.balance ? -1 : 1;
201
+ });
202
+ const map = new import_AddressMap.AddressMap(
203
+ inUSD.map(({ token }, i) => [token, i === 0 ? 4n : 1n])
204
+ );
205
+ return (token) => map.get(token) ?? 1n;
206
+ }
207
+ #debugTokenData(tData) {
208
+ return tData.map((t) => ({
209
+ token: this.labelAddress(t.token),
210
+ balance: this.sdk.tokensMeta.formatBN(t.token, t.balance),
211
+ leftoverBalance: this.sdk.tokensMeta.formatBN(t.token, t.leftoverBalance),
212
+ numSplits: t.numSplits
213
+ }));
214
+ }
215
+ /**
216
+ * Implements {@link IRouterContract.findAllSwaps}
217
+ * @deprecated v3.0 legacy method
218
+ */
155
219
  findAllSwaps(props) {
156
220
  throw ERR_NOT_IMPLEMENTED;
157
221
  }
222
+ /**
223
+ * Implements {@link IRouterContract.getAvailableConnectors}
224
+ * @deprecated v3.0 legacy method
225
+ */
158
226
  getAvailableConnectors(collateralTokens) {
159
227
  throw ERR_NOT_IMPLEMENTED;
160
228
  }
229
+ /**
230
+ * Implements {@link IRouterContract.getFindClosePathInput}
231
+ * @deprecated v3.0 legacy method
232
+ */
161
233
  getFindClosePathInput(ca, cm, balances) {
162
234
  throw ERR_NOT_IMPLEMENTED;
163
235
  }
164
236
  }
237
+ function balancesAfterOpen(target, targetAmount, expected, leftover) {
238
+ const result = {};
239
+ const targetAddr = (0, import_viem.getAddress)(target);
240
+ const tokens = /* @__PURE__ */ new Set([
241
+ ...expected.keys(),
242
+ ...leftover.keys(),
243
+ targetAddr
244
+ ]);
245
+ for (const t of tokens) {
246
+ if (t === targetAddr) {
247
+ result[t] = expected.get(t) ?? 0n + targetAmount;
248
+ } else {
249
+ result[t] = import_sdk_legacy.BigIntMath.min(expected.get(t) ?? 0n, leftover.get(t) ?? 0n);
250
+ }
251
+ }
252
+ return result;
253
+ }
165
254
  // Annotate the CommonJS export names for ESM import in node:
166
255
  0 && (module.exports = {
167
256
  RouterV310Contract
@@ -33,17 +33,7 @@ class RouterV300Contract extends AbstractRouterContract {
33
33
  this.#connectors = getConnectors(sdk.provider.networkType);
34
34
  }
35
35
  /**
36
- * Finds all available swaps for given tokens; technically should be avoided to use, since doesn't have any advantage over findOneTokenPath.
37
- * Deduplicates results by minAmount + strigified call path and returns only unique ones.
38
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
39
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
40
- * @param {SwapOperation} swapOperation - {@link SwapOperation} = "EXACT_INPUT" | "EXACT_INPUT_ALL" | "EXACT_OUTPUT"; however router stopped to support EXACT_OUTPUT
41
- * @param {Address} tokenIn - address of input token
42
- * @param {Address} tokenOut - address of output token
43
- * @param {number | bigint} slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
44
- * @param {bigint} amount - amount of token in to swap
45
- * @param {bigint} leftoverAmount - amount that should be left on account after swap; technically equals to 0 in the most of the cases
46
- * @returns Array of {@link RouterResult}
36
+ * Implements {@link IRouterContract.findAllSwaps}
47
37
  */
48
38
  async findAllSwaps({
49
39
  creditAccount: ca,
@@ -83,16 +73,7 @@ class RouterV300Contract extends AbstractRouterContract {
83
73
  return Object.values(unique);
84
74
  }
85
75
  /**
86
- * Find the best path to swap token A to token B.
87
- * - Connectors - list of tokens which can be used as a token to align path through, for ex. when swapping sUSDe it is good to check swaps through USDe.
88
- * - #overridePTRedeem - if token is PT token and PT token is already redeemable, we need to claim it manually, since old router can't do it. This can work in old app only because you cannot swap pt_sUSDe into sUSde before maturity and when it is matured, override takes place.
89
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
90
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
91
- * @param {Address} tokenIn - address of input token
92
- * @param {Address} tokenOut - address of output token
93
- * @param {number | bigint} slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
94
- * @param {bigint} amount - amount of token in to swap
95
- * @returns minAmount, avgAmount found and array of calls to execute swap
76
+ * Implements {@link IRouterContract.findOneTokenPath}
96
77
  */
97
78
  async findOneTokenPath(props) {
98
79
  const {
@@ -127,22 +108,7 @@ class RouterV300Contract extends AbstractRouterContract {
127
108
  };
128
109
  }
129
110
  /**
130
- * @dev Finds the best path for opening Credit Account; converts all expectedBalances besides leftoverBalances into target token
131
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
132
- * @param {Array<Asset>} expectedBalances - Collateral assets + debt asset, nominated in ther respective tokens.
133
- * For example, if you open an USDC Credit Account, borrow 50_000 USDC and provide 10 WETH and 10_000 DAI as collateral
134
- * from your own funds, expectedBalances should be: [{amount: 10*10**wethDecimals}, {amount: 10000*10**daiDecimals}, {amount: 10000*10**usdcDecimals}]
135
- * @param leftoverBalances - balances to keep on account after opening.
136
- * For example if don't want to swap WETH in the example above, leftoverBalances should be: [{amount: 10*10**wethDecimals}]
137
- * @param target - Address of desired token to swap into
138
- * @param slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
139
- * @returns Router return list of all balances (including 0 balances) after operation, but it doesn't include original balance
140
- * - For example you had 5k sUSDS and 5k DAI as collateral, debt is 20k DAI, router will return 25k sUDS and all other token allowed on CM will be 0n or 1n
141
- * Since FE is interested in FULL balances structure, we override target balance in the following way:
142
- * min = record[sUSDS] = 5k from collateral + 25k of minAmount; avg = record[sUSDS] = 5k from collateral + 25.5k of avgAmount
143
- * - minAmount
144
- * - avgAmount
145
- * - array of calls to execute swap
111
+ * Implements {@link IRouterContract.findOpenStrategyPath}
146
112
  */
147
113
  async findOpenStrategyPath({
148
114
  creditManager: cm,
@@ -190,26 +156,7 @@ class RouterV300Contract extends AbstractRouterContract {
190
156
  };
191
157
  }
192
158
  /**
193
- * @dev Finds the path to swap / withdraw all assets from CreditAccount into underlying asset
194
- * Can bu used for closing Credit Account and for liquidations as well.
195
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
196
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
197
- * @param {number | bigint} slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
198
- * @param {ClosePathBalances | undefined} balances - Balances {@link ClosePathBalances} to close account with, if not provided, all assets will be swapped according to inner logic.
199
- * Consists of:
200
- * @param {Array<Asset>} expectedBalances - list of all credit account balances nominated in their respective tokens.
201
- * For example: [{amount: 10x10^wethDecimals}, {amount: 10000x10^daiDecimals}]
202
- * @param {Array<Asset>} leftoverBalances - list of all credit account balances that shouldn't be swapped nominated in their respective tokens.
203
- * Used for credit account repaying; in this mode leftover assets list should include all assets besides underlying token.
204
- * For example considering account above is on DAI CM: [{amount: 10x10^wethDecimals}]
205
- * @return The best option in PathFinderCloseResult format, which
206
- * - underlyingBalance - since this method swaps only tokens different from underlying,
207
- * we are more interested in TOTAL balance of underlying token after all swaps are done
208
- * for this reason we sum up underlying token that was on account before swap
209
- * with underlying token amount found during swap and call it underlyingBalance
210
- * - calls - list of calls which should be done to swap & unwrap everything to underlying token
211
- * - amount
212
- * - minAmount
159
+ * Implements {@link IRouterContract.findBestClosePath}
213
160
  */
214
161
  async findBestClosePath({
215
162
  creditAccount: ca,
@@ -272,11 +219,7 @@ class RouterV300Contract extends AbstractRouterContract {
272
219
  return result;
273
220
  }
274
221
  /**
275
- * Finds input to be used with findBestClosePath
276
- * Is used by batch liquidator
277
- * @param ca
278
- * @param cm
279
- * @returns
222
+ * Implements {@link IRouterContract.getFindClosePathInput}
280
223
  */
281
224
  getFindClosePathInput(ca, cm, balances) {
282
225
  const { expectedBalances, leftoverBalances } = this.getExpectedAndLeftover(
@@ -298,7 +241,7 @@ class RouterV300Contract extends AbstractRouterContract {
298
241
  };
299
242
  }
300
243
  /**
301
- * Connectors - list of tokens which can be used as a token to align path through, for ex. when swapping sUSDe it is good to check swaps through USDe.
244
+ * Implements {@link IRouterContract.getAvailableConnectors}
302
245
  */
303
246
  getAvailableConnectors(collateralTokens) {
304
247
  return collateralTokens.filter(
@@ -306,9 +249,9 @@ class RouterV300Contract extends AbstractRouterContract {
306
249
  );
307
250
  }
308
251
  /**
309
- * if token is PT token and PT token is already redeemable, we need to claim it manually, since old router can't do it.
310
- This can work in old app only because you cannot swap pt_sUSDe into sUSde before maturity and when it is matured, override takes place.
311
- */
252
+ * If token is PT token and PT token is already redeemable, we need to claim it manually, since old router can't do it.
253
+ * This can work in old app only because you cannot swap pt_sUSDe into sUSde before maturity and when it is matured, override takes place.
254
+ */
312
255
  async #overridePTRedeem({
313
256
  creditAccount,
314
257
  creditManager,
@@ -1,4 +1,7 @@
1
+ import { getAddress } from "viem";
1
2
  import { iGearboxRouterV310Abi } from "../../abi/routerV310.js";
3
+ import { BigIntMath } from "../sdk-legacy/index.js";
4
+ import { AddressMap } from "../utils/AddressMap.js";
2
5
  import { AbstractRouterContract } from "./AbstractRouterContract.js";
3
6
  import { assetsMap, balancesMap } from "./helpers.js";
4
7
  const abi = iGearboxRouterV310Abi;
@@ -7,29 +10,45 @@ class RouterV310Contract extends AbstractRouterContract {
7
10
  constructor(sdk, address) {
8
11
  super(sdk, {
9
12
  addr: address,
10
- name: "RouterV300",
13
+ name: "RouterV310",
11
14
  abi
12
15
  });
13
16
  }
14
17
  /**
15
- * Finds best path to swap all Normal tokens and tokens "on the way" to target one and vice versa
16
- * @param creditAccount
17
- * @param creditManager
18
- * @param tokenIn
19
- * @param tokenOut
20
- * @param amount
21
- * @param slippage
22
- * @returns
18
+ * Implements {@link IRouterContract.findOneTokenPath}
23
19
  */
24
20
  async findOneTokenPath(props) {
21
+ const {
22
+ creditAccount,
23
+ creditManager,
24
+ amount,
25
+ slippage,
26
+ tokenIn,
27
+ tokenOut
28
+ } = props;
29
+ const numSplits = this.#numSplitsGetter(
30
+ creditManager,
31
+ creditAccount.tokens
32
+ )(tokenIn);
33
+ this.logger?.debug(
34
+ {
35
+ creditAccount: creditAccount.creditAccount,
36
+ creditManager: this.labelAddress(creditManager.address),
37
+ tokenIn: this.labelAddress(tokenIn),
38
+ target: this.labelAddress(tokenOut),
39
+ amount,
40
+ slippage,
41
+ numSplits
42
+ },
43
+ "calling routeOneToOne"
44
+ );
25
45
  const { result } = await this.contract.simulate.routeOneToOne([
26
- props.creditAccount.creditAccount,
27
- props.tokenIn,
28
- props.amount,
29
- props.tokenOut,
30
- BigInt(props.slippage),
31
- 4n
32
- // TODO:? how many 4n or 0n for underlying
46
+ creditAccount.creditAccount,
47
+ tokenIn,
48
+ amount,
49
+ tokenOut,
50
+ BigInt(slippage),
51
+ numSplits
33
52
  ]);
34
53
  return {
35
54
  amount: result.amount,
@@ -38,15 +57,7 @@ class RouterV310Contract extends AbstractRouterContract {
38
57
  };
39
58
  }
40
59
  /**
41
- * @dev Finds the best path for opening Credit Account and converting all NORMAL tokens and LP token in the way to TARGET
42
- * @param creditManager CreditManagerData which represents credit manager you want to use to open Credit Account
43
- * @param expectedBalances Expected balances which would be on account accounting also debt. For example,
44
- * if you open an USDC Credit Account, borrow 50_000 USDC and provide 10 WETH and 10_USDC as collateral
45
- * from your own funds, expectedBalances should be: { "USDC": 60_000 * (10**6), "<address of WETH>": WAD.mul(10) }
46
- * @param leftoverBalances Balances to keep on account after opening
47
- * @param target Address of symbol of desired token
48
- * @param slippage Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
49
- * @returns PathFinderOpenStrategyResult which
60
+ * Implements {@link IRouterContract.findOpenStrategyPath}
50
61
  */
51
62
  async findOpenStrategyPath(props) {
52
63
  const {
@@ -60,15 +71,24 @@ class RouterV310Contract extends AbstractRouterContract {
60
71
  balancesMap(expectedBalances),
61
72
  balancesMap(leftoverBalances)
62
73
  ];
74
+ const getNumSplits = this.#numSplitsGetter(cm, expectedBalances);
63
75
  const tData = cm.collateralTokens.map(
64
76
  (token) => ({
65
77
  token,
66
78
  balance: expectedMap.get(token) ?? 0n,
67
79
  leftoverBalance: leftoverMap.get(token) ?? 0n,
68
- numSplits: 4n
69
- // TODO:? how many 4n or 0n for underlying
80
+ numSplits: getNumSplits(token)
70
81
  })
71
82
  );
83
+ this.logger?.debug(
84
+ {
85
+ creditManager: this.labelAddress(cm.address),
86
+ target: this.labelAddress(target),
87
+ slippage,
88
+ tData: this.#debugTokenData(tData)
89
+ },
90
+ "calling routeOpenManyToOne"
91
+ );
72
92
  const { result } = await this.contract.simulate.routeOpenManyToOne([
73
93
  cm.address,
74
94
  target,
@@ -76,24 +96,25 @@ class RouterV310Contract extends AbstractRouterContract {
76
96
  tData
77
97
  ]);
78
98
  return {
79
- balances: {},
80
- // TODO:?
81
- minBalances: {},
82
- // TODO:?
99
+ balances: balancesAfterOpen(
100
+ target,
101
+ result.amount,
102
+ expectedMap,
103
+ leftoverMap
104
+ ),
105
+ minBalances: balancesAfterOpen(
106
+ target,
107
+ result.minAmount,
108
+ expectedMap,
109
+ leftoverMap
110
+ ),
83
111
  amount: result.amount,
84
112
  minAmount: result.minAmount,
85
113
  calls: [...result.calls]
86
114
  };
87
115
  }
88
116
  /**
89
- * @dev Finds the path to swap / withdraw all assets from CreditAccount into underlying asset
90
- * Can bu used for closing Credit Account and for liquidations as well.
91
- * @param creditAccount CreditAccountStruct object used for close path computation
92
- * @param creditManager CreditManagerSlice for corresponding credit manager
93
- * @param slippage Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
94
- * @return The best option in PathFinderCloseResult format, which
95
- * - underlyingBalance - total balance of underlying token
96
- * - calls - list of calls which should be done to swap & unwrap everything to underlying token
117
+ * Implements {@link IRouterContract.findBestClosePath}
97
118
  */
98
119
  async findBestClosePath(props) {
99
120
  const { creditAccount: ca, creditManager: cm, slippage, balances } = props;
@@ -105,16 +126,26 @@ class RouterV310Contract extends AbstractRouterContract {
105
126
  leftoverBalances: assetsMap(balances.leftoverBalances)
106
127
  } : void 0
107
128
  );
129
+ const getNumSplits = this.#numSplitsGetter(cm, expectedBalances.values());
108
130
  const tData = [];
109
131
  for (const token of cm.collateralTokens) {
110
132
  tData.push({
111
133
  token,
112
134
  balance: expectedBalances.get(token)?.balance || 0n,
113
135
  leftoverBalance: leftoverBalances.get(token)?.balance || 0n,
114
- numSplits: 4n
115
- // TODO:? how many 4n or 0n for underlying
136
+ numSplits: getNumSplits(token)
116
137
  });
117
138
  }
139
+ this.logger?.debug(
140
+ {
141
+ creditAccount: ca.creditAccount,
142
+ creditManager: this.labelAddress(cm.address),
143
+ target: this.labelAddress(ca.underlying),
144
+ slippage,
145
+ tData: this.#debugTokenData(tData)
146
+ },
147
+ "calling routeManyToOne"
148
+ );
118
149
  const { result } = await this.contract.simulate.routeManyToOne([
119
150
  cm.address,
120
151
  ca.underlying,
@@ -129,16 +160,74 @@ class RouterV310Contract extends AbstractRouterContract {
129
160
  calls: [...result.calls]
130
161
  };
131
162
  }
163
+ #numSplitsGetter(creditManager, assets) {
164
+ const { priceOracle } = this.sdk.marketRegister.findByCreditManager(
165
+ creditManager.address
166
+ );
167
+ const inUSD = assets.filter(({ token, balance }) => {
168
+ const decimals = this.sdk.tokensMeta.decimals(token);
169
+ const minBalance = 10n ** BigInt(Math.max(8, decimals) - 8);
170
+ return balance >= minBalance;
171
+ }).map(({ token, balance }) => {
172
+ return {
173
+ token,
174
+ balance: priceOracle.convertToUSD(token, balance)
175
+ };
176
+ }).sort((a, b) => {
177
+ return b.balance > a.balance ? -1 : 1;
178
+ });
179
+ const map = new AddressMap(
180
+ inUSD.map(({ token }, i) => [token, i === 0 ? 4n : 1n])
181
+ );
182
+ return (token) => map.get(token) ?? 1n;
183
+ }
184
+ #debugTokenData(tData) {
185
+ return tData.map((t) => ({
186
+ token: this.labelAddress(t.token),
187
+ balance: this.sdk.tokensMeta.formatBN(t.token, t.balance),
188
+ leftoverBalance: this.sdk.tokensMeta.formatBN(t.token, t.leftoverBalance),
189
+ numSplits: t.numSplits
190
+ }));
191
+ }
192
+ /**
193
+ * Implements {@link IRouterContract.findAllSwaps}
194
+ * @deprecated v3.0 legacy method
195
+ */
132
196
  findAllSwaps(props) {
133
197
  throw ERR_NOT_IMPLEMENTED;
134
198
  }
199
+ /**
200
+ * Implements {@link IRouterContract.getAvailableConnectors}
201
+ * @deprecated v3.0 legacy method
202
+ */
135
203
  getAvailableConnectors(collateralTokens) {
136
204
  throw ERR_NOT_IMPLEMENTED;
137
205
  }
206
+ /**
207
+ * Implements {@link IRouterContract.getFindClosePathInput}
208
+ * @deprecated v3.0 legacy method
209
+ */
138
210
  getFindClosePathInput(ca, cm, balances) {
139
211
  throw ERR_NOT_IMPLEMENTED;
140
212
  }
141
213
  }
214
+ function balancesAfterOpen(target, targetAmount, expected, leftover) {
215
+ const result = {};
216
+ const targetAddr = getAddress(target);
217
+ const tokens = /* @__PURE__ */ new Set([
218
+ ...expected.keys(),
219
+ ...leftover.keys(),
220
+ targetAddr
221
+ ]);
222
+ for (const t of tokens) {
223
+ if (t === targetAddr) {
224
+ result[t] = expected.get(t) ?? 0n + targetAmount;
225
+ } else {
226
+ result[t] = BigIntMath.min(expected.get(t) ?? 0n, leftover.get(t) ?? 0n);
227
+ }
228
+ }
229
+ return result;
230
+ }
142
231
  export {
143
232
  RouterV310Contract
144
233
  };
@@ -9,84 +9,27 @@ export declare class RouterV300Contract extends AbstractRouterContract<abi> impl
9
9
  #private;
10
10
  constructor(sdk: GearboxSDK, address: Address);
11
11
  /**
12
- * Finds all available swaps for given tokens; technically should be avoided to use, since doesn't have any advantage over findOneTokenPath.
13
- * Deduplicates results by minAmount + strigified call path and returns only unique ones.
14
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
15
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
16
- * @param {SwapOperation} swapOperation - {@link SwapOperation} = "EXACT_INPUT" | "EXACT_INPUT_ALL" | "EXACT_OUTPUT"; however router stopped to support EXACT_OUTPUT
17
- * @param {Address} tokenIn - address of input token
18
- * @param {Address} tokenOut - address of output token
19
- * @param {number | bigint} slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
20
- * @param {bigint} amount - amount of token in to swap
21
- * @param {bigint} leftoverAmount - amount that should be left on account after swap; technically equals to 0 in the most of the cases
22
- * @returns Array of {@link RouterResult}
12
+ * Implements {@link IRouterContract.findAllSwaps}
23
13
  */
24
14
  findAllSwaps({ creditAccount: ca, creditManager: cm, swapOperation, tokenIn, tokenOut, amount, leftoverAmount, slippage, }: FindAllSwapsProps): Promise<Array<RouterResult>>;
25
15
  /**
26
- * Find the best path to swap token A to token B.
27
- * - Connectors - list of tokens which can be used as a token to align path through, for ex. when swapping sUSDe it is good to check swaps through USDe.
28
- * - #overridePTRedeem - if token is PT token and PT token is already redeemable, we need to claim it manually, since old router can't do it. This can work in old app only because you cannot swap pt_sUSDe into sUSde before maturity and when it is matured, override takes place.
29
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
30
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
31
- * @param {Address} tokenIn - address of input token
32
- * @param {Address} tokenOut - address of output token
33
- * @param {number | bigint} slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
34
- * @param {bigint} amount - amount of token in to swap
35
- * @returns minAmount, avgAmount found and array of calls to execute swap
16
+ * Implements {@link IRouterContract.findOneTokenPath}
36
17
  */
37
18
  findOneTokenPath(props: FindOneTokenPathProps): Promise<RouterResult>;
38
19
  /**
39
- * @dev Finds the best path for opening Credit Account; converts all expectedBalances besides leftoverBalances into target token
40
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
41
- * @param {Array<Asset>} expectedBalances - Collateral assets + debt asset, nominated in ther respective tokens.
42
- * For example, if you open an USDC Credit Account, borrow 50_000 USDC and provide 10 WETH and 10_000 DAI as collateral
43
- * from your own funds, expectedBalances should be: [{amount: 10*10**wethDecimals}, {amount: 10000*10**daiDecimals}, {amount: 10000*10**usdcDecimals}]
44
- * @param leftoverBalances - balances to keep on account after opening.
45
- * For example if don't want to swap WETH in the example above, leftoverBalances should be: [{amount: 10*10**wethDecimals}]
46
- * @param target - Address of desired token to swap into
47
- * @param slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
48
- * @returns Router return list of all balances (including 0 balances) after operation, but it doesn't include original balance
49
- * - For example you had 5k sUSDS and 5k DAI as collateral, debt is 20k DAI, router will return 25k sUDS and all other token allowed on CM will be 0n or 1n
50
- * Since FE is interested in FULL balances structure, we override target balance in the following way:
51
- * min = record[sUSDS] = 5k from collateral + 25k of minAmount; avg = record[sUSDS] = 5k from collateral + 25.5k of avgAmount
52
- * - minAmount
53
- * - avgAmount
54
- * - array of calls to execute swap
20
+ * Implements {@link IRouterContract.findOpenStrategyPath}
55
21
  */
56
22
  findOpenStrategyPath({ creditManager: cm, expectedBalances, leftoverBalances, target, slippage, }: FindOpenStrategyPathProps): Promise<OpenStrategyResult>;
57
23
  /**
58
- * @dev Finds the path to swap / withdraw all assets from CreditAccount into underlying asset
59
- * Can bu used for closing Credit Account and for liquidations as well.
60
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
61
- * @param {RouterCMSlice} creditManager - minimal credit manager data {@link RouterCMSlice} on which operation is performed
62
- * @param {number | bigint} slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
63
- * @param {ClosePathBalances | undefined} balances - Balances {@link ClosePathBalances} to close account with, if not provided, all assets will be swapped according to inner logic.
64
- * Consists of:
65
- * @param {Array<Asset>} expectedBalances - list of all credit account balances nominated in their respective tokens.
66
- * For example: [{amount: 10x10^wethDecimals}, {amount: 10000x10^daiDecimals}]
67
- * @param {Array<Asset>} leftoverBalances - list of all credit account balances that shouldn't be swapped nominated in their respective tokens.
68
- * Used for credit account repaying; in this mode leftover assets list should include all assets besides underlying token.
69
- * For example considering account above is on DAI CM: [{amount: 10x10^wethDecimals}]
70
- * @return The best option in PathFinderCloseResult format, which
71
- * - underlyingBalance - since this method swaps only tokens different from underlying,
72
- * we are more interested in TOTAL balance of underlying token after all swaps are done
73
- * for this reason we sum up underlying token that was on account before swap
74
- * with underlying token amount found during swap and call it underlyingBalance
75
- * - calls - list of calls which should be done to swap & unwrap everything to underlying token
76
- * - amount
77
- * - minAmount
24
+ * Implements {@link IRouterContract.findBestClosePath}
78
25
  */
79
26
  findBestClosePath({ creditAccount: ca, creditManager: cm, slippage, balances, }: FindBestClosePathProps): Promise<RouterCloseResult>;
80
27
  /**
81
- * Finds input to be used with findBestClosePath
82
- * Is used by batch liquidator
83
- * @param ca
84
- * @param cm
85
- * @returns
28
+ * Implements {@link IRouterContract.getFindClosePathInput}
86
29
  */
87
30
  getFindClosePathInput(ca: RouterCASlice, cm: RouterCMSlice, balances?: Leftovers): FindClosePathInput;
88
31
  /**
89
- * Connectors - list of tokens which can be used as a token to align path through, for ex. when swapping sUSDe it is good to check swaps through USDe.
32
+ * Implements {@link IRouterContract.getAvailableConnectors}
90
33
  */
91
34
  getAvailableConnectors(collateralTokens: Array<Address>): Array<Address>;
92
35
  }
@@ -1,4 +1,4 @@
1
- import type { Address } from "viem";
1
+ import { type Address } from "viem";
2
2
  import type { GearboxSDK } from "../GearboxSDK.js";
3
3
  import type { Leftovers } from "./AbstractRouterContract.js";
4
4
  import { AbstractRouterContract } from "./AbstractRouterContract.js";
@@ -350,43 +350,34 @@ declare const abi: readonly [{
350
350
  }];
351
351
  type abi = typeof abi;
352
352
  export declare class RouterV310Contract extends AbstractRouterContract<abi> implements IRouterContract {
353
+ #private;
353
354
  constructor(sdk: GearboxSDK, address: Address);
354
355
  /**
355
- * Finds best path to swap all Normal tokens and tokens "on the way" to target one and vice versa
356
- * @param creditAccount
357
- * @param creditManager
358
- * @param tokenIn
359
- * @param tokenOut
360
- * @param amount
361
- * @param slippage
362
- * @returns
356
+ * Implements {@link IRouterContract.findOneTokenPath}
363
357
  */
364
358
  findOneTokenPath(props: FindOneTokenPathProps): Promise<RouterResult>;
365
359
  /**
366
- * @dev Finds the best path for opening Credit Account and converting all NORMAL tokens and LP token in the way to TARGET
367
- * @param creditManager CreditManagerData which represents credit manager you want to use to open Credit Account
368
- * @param expectedBalances Expected balances which would be on account accounting also debt. For example,
369
- * if you open an USDC Credit Account, borrow 50_000 USDC and provide 10 WETH and 10_USDC as collateral
370
- * from your own funds, expectedBalances should be: { "USDC": 60_000 * (10**6), "<address of WETH>": WAD.mul(10) }
371
- * @param leftoverBalances Balances to keep on account after opening
372
- * @param target Address of symbol of desired token
373
- * @param slippage Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
374
- * @returns PathFinderOpenStrategyResult which
360
+ * Implements {@link IRouterContract.findOpenStrategyPath}
375
361
  */
376
362
  findOpenStrategyPath(props: FindOpenStrategyPathProps): Promise<OpenStrategyResult>;
377
363
  /**
378
- * @dev Finds the path to swap / withdraw all assets from CreditAccount into underlying asset
379
- * Can bu used for closing Credit Account and for liquidations as well.
380
- * @param creditAccount CreditAccountStruct object used for close path computation
381
- * @param creditManager CreditManagerSlice for corresponding credit manager
382
- * @param slippage Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
383
- * @return The best option in PathFinderCloseResult format, which
384
- * - underlyingBalance - total balance of underlying token
385
- * - calls - list of calls which should be done to swap & unwrap everything to underlying token
364
+ * Implements {@link IRouterContract.findBestClosePath}
386
365
  */
387
366
  findBestClosePath(props: FindBestClosePathProps): Promise<RouterCloseResult>;
367
+ /**
368
+ * Implements {@link IRouterContract.findAllSwaps}
369
+ * @deprecated v3.0 legacy method
370
+ */
388
371
  findAllSwaps(props: FindAllSwapsProps): Promise<RouterResult[]>;
372
+ /**
373
+ * Implements {@link IRouterContract.getAvailableConnectors}
374
+ * @deprecated v3.0 legacy method
375
+ */
389
376
  getAvailableConnectors(collateralTokens: Address[]): Address[];
377
+ /**
378
+ * Implements {@link IRouterContract.getFindClosePathInput}
379
+ * @deprecated v3.0 legacy method
380
+ */
390
381
  getFindClosePathInput(ca: RouterCASlice, cm: RouterCMSlice, balances?: Leftovers): FindClosePathInput;
391
382
  }
392
383
  export {};
@@ -10,31 +10,57 @@ export interface PathOption {
10
10
  totalOptions: number;
11
11
  }
12
12
  export type PathOptionSerie = Array<PathOption>;
13
- export interface SwapTask {
14
- swapOperation: number;
15
- creditAccount: Address;
16
- tokenIn: Address;
17
- tokenOut: Address;
18
- connectors: Array<Address>;
19
- amount: bigint;
20
- leftoverAmount: bigint;
21
- }
13
+ /**
14
+ * Result returned from router contract (both v3.0 and v3.1)
15
+ */
22
16
  export interface RouterResult {
17
+ /**
18
+ * Amount received by router after all swaps in the block where the router is called
19
+ * Always denominated in target token
20
+ */
23
21
  amount: bigint;
22
+ /**
23
+ * amount * (1 - slippage)
24
+ * Always denominated in target token
25
+ */
24
26
  minAmount: bigint;
27
+ /**
28
+ * List of calls swap/unwrap/etc calls to adapters returned by router
29
+ */
25
30
  calls: Array<MultiCall>;
26
31
  }
32
+ /**
33
+ * Router return list of all balances (including 0 balances) after operation, but it doesn't include original balance
34
+ * - For example you had 5k sUSDS and 5k DAI as collateral, debt is 20k DAI, router will return 25k sUDS and all other token allowed on CM will be 0n or 1n
35
+ * Since front-end is interested in FULL balances structure, we override target balance in the following way:
36
+ * min = record[sUSDS] = 5k from collateral + 25k of minAmount; avg = record[sUSDS] = 5k from collateral + 25.5k of avgAmount
37
+ * - minAmount
38
+ * - avgAmount
39
+ * - array of calls to execute swap
40
+ */
27
41
  export interface OpenStrategyResult extends RouterResult {
42
+ /**
43
+ * Balances of opened credit account
44
+ * Leftover balances stay the same
45
+ * All expected balances are converted into target token, which amount is returned in router result
46
+ * This is returned from router contract v3.0, but is calculated here in js in router v3.1
47
+ */
28
48
  balances: Record<Address, bigint>;
49
+ /**
50
+ * Sam as balances, but for min balance in target token
51
+ * @see RouterResult.minAmount
52
+ */
29
53
  minBalances: Record<Address, bigint>;
30
54
  }
31
55
  export interface RouterCloseResult extends RouterResult {
56
+ /**
57
+ * When account is closed, the router swaps only tokens different from underlying,
58
+ * we are more interested in TOTAL balance of underlying token after all swaps are done
59
+ * for this reason we sum up underlying token that was on account before swap
60
+ * with underlying token amount received during swap and call it underlyingBalance
61
+ */
32
62
  underlyingBalance: bigint;
33
63
  }
34
- export interface CurvePoolStruct {
35
- curvePool: Address;
36
- metapoolBase: Address;
37
- }
38
64
  export interface Asset {
39
65
  token: Address;
40
66
  balance: bigint;
@@ -52,13 +78,37 @@ export interface RouterCMSlice {
52
78
  */
53
79
  export type RouterCASlice = Pick<CreditAccountData, "tokens" | "enabledTokensMask" | "underlying" | "creditAccount" | "creditFacade" | "debt" | "creditManager">;
54
80
  export interface FindAllSwapsProps {
81
+ /**
82
+ * Minimal credit account data on which operation is performed
83
+ */
55
84
  creditAccount: RouterCASlice;
85
+ /**
86
+ * Minimal credit manager data on which operation is performed
87
+ */
56
88
  creditManager: RouterCMSlice;
89
+ /**
90
+ * {@link SwapOperation} = "EXACT_INPUT" | "EXACT_INPUT_ALL" | "EXACT_OUTPUT"; however router stopped to support EXACT_OUTPUT
91
+ */
57
92
  swapOperation: SwapOperation;
93
+ /**
94
+ * Address of input token
95
+ */
58
96
  tokenIn: Address;
97
+ /**
98
+ * Address of target token
99
+ */
59
100
  tokenOut: Address;
101
+ /**
102
+ * Incoming amount of tokenIn to swap
103
+ */
60
104
  amount: bigint;
105
+ /**
106
+ * Amount that should be left on account after swap; technically equals to 0 in the most of the cases
107
+ */
61
108
  leftoverAmount: bigint;
109
+ /**
110
+ * Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
111
+ */
62
112
  slippage: number | bigint;
63
113
  }
64
114
  export interface FindClosePathInput {
@@ -68,73 +118,139 @@ export interface FindClosePathInput {
68
118
  connectors: Array<Address>;
69
119
  }
70
120
  export interface FindOneTokenPathProps {
121
+ /**
122
+ * Minimal credit account data on which operation is performed
123
+ */
71
124
  creditAccount: RouterCASlice;
125
+ /**
126
+ * Minimal credit manager data on which operation is performed
127
+ */
72
128
  creditManager: RouterCMSlice;
129
+ /**
130
+ * Address of input token
131
+ */
73
132
  tokenIn: Address;
133
+ /**
134
+ * Adddress of target token
135
+ */
74
136
  tokenOut: Address;
137
+ /**
138
+ * Incominga mount of tokenIn to swap
139
+ */
75
140
  amount: bigint;
141
+ /**
142
+ * Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
143
+ */
76
144
  slippage: number | bigint;
77
145
  }
78
146
  export interface FindOpenStrategyPathProps {
147
+ /**
148
+ * Minimal credit manager data on which operation is performed
149
+ */
79
150
  creditManager: RouterCMSlice;
151
+ /**
152
+ * Collateral assets + debt asset, nominated in ther respective tokens.
153
+ * For example, if you open an USDC Credit Account, borrow 50_000 USDC and provide 10 WETH and 10_000 DAI as collateral
154
+ * from your own funds, expectedBalances should be: [{amount: 10*10**wethDecimals}, {amount: 10000*10**daiDecimals}, {amount: 10000*10**usdcDecimals}]
155
+ */
80
156
  expectedBalances: Array<Asset>;
157
+ /**
158
+ * Balances to keep on account after opening.
159
+ * For example if don't want to swap WETH in the example above, leftoverBalances should be: [{amount: 10*10**wethDecimals}]
160
+ */
81
161
  leftoverBalances: Array<Asset>;
162
+ /**
163
+ * Address of desired token to swap into
164
+ */
82
165
  target: Address;
166
+ /**
167
+ * Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
168
+ */
83
169
  slippage: number | bigint;
84
170
  }
85
171
  export interface FindBestClosePathProps {
172
+ /**
173
+ * Minimal credit account data on which operation is performed
174
+ */
86
175
  creditAccount: RouterCASlice;
176
+ /**
177
+ * Minimal credit manager data on which operation is performed
178
+ */
87
179
  creditManager: RouterCMSlice;
180
+ /**
181
+ * Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
182
+ */
88
183
  slippage: bigint | number;
184
+ /**
185
+ * Balances {@link ClosePathBalances} to close account with, if not provided, all assets will be swapped according to inner logic.
186
+ */
89
187
  balances?: ClosePathBalances;
90
188
  }
91
189
  export interface ClosePathBalances {
190
+ /**
191
+ * List of all credit account balances nominated in their respective tokens.
192
+ * Current balances or expected balances after some actions (add/withdraw collateral, for example),
193
+ * if these actions are before router calls
194
+ */
92
195
  expectedBalances: Array<Asset>;
196
+ /**
197
+ * List of all credit account balances that shouldn't be swapped nominated in their respective tokens.
198
+ * Will be kept on account after all actions.
199
+ * If the final balance is 0, we set 1 for gas optimization, except for forbidden tokens
200
+ */
93
201
  leftoverBalances: Array<Asset>;
94
202
  }
95
203
  export interface IRouterContract extends IBaseContract {
96
204
  /**
97
- * Finds best path to swap all Normal tokens and tokens "on the way" to target one and vice versa
98
- * @param props
99
- * @returns
205
+ * Find the best path to swap token A to token B (target token).
206
+ * @param props - {@link FindOneTokenPathProps}
207
+ * @return result - {@link RouterResult}
100
208
  */
101
209
  findOneTokenPath: (props: FindOneTokenPathProps) => Promise<RouterResult>;
102
210
  /**
103
- * @dev Finds the best path for opening Credit Account and converting all NORMAL tokens and LP token in the way to TARGET
104
- * @param creditManager CreditManagerData which represents credit manager you want to use to open Credit Account
105
- * @param expectedBalances Expected balances which would be on account accounting also debt. For example,
106
- * if you open an USDC Credit Account, borrow 50_000 USDC and provide 10 WETH and 10_USDC as collateral
107
- * from your own funds, expectedBalances should be: { "USDC": 60_000 * (10**6), "<address of WETH>": WAD.mul(10) }
108
- * @param leftoverBalances Balances to keep on account after opening
109
- * @param target Address of symbol of desired token
110
- * @param slippage Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
111
- * @returns PathFinderOpenStrategyResult which
211
+ * Finds the best path for opening Credit Account; converts all expectedBalances besides leftoverBalances into target token
212
+ * @param props - {@link FindOpenStrategyPathProps}
213
+ * @returns result - {@link OpenStrategyResult}
112
214
  */
113
215
  findOpenStrategyPath: (props: FindOpenStrategyPathProps) => Promise<OpenStrategyResult>;
114
216
  /**
115
- * @dev Finds the path to swap / withdraw all assets from CreditAccount into underlying asset
116
- * Can bu used for closing Credit Account and for liquidations as well.
117
- * @param creditAccount CreditAccountStruct object used for close path computation
118
- * @param creditManager CreditManagerSlice for corresponding credit manager
119
- * @param slippage Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
120
- * @return The best option in PathFinderCloseResult format, which
121
- * - underlyingBalance - total balance of underlying token
122
- * - calls - list of calls which should be done to swap & unwrap everything to underlying token
217
+ * Finds the path to swap / withdraw all assets from CreditAccount into underlying asset
218
+ * Can be used for closing Credit Account and for liquidations as well.
219
+ * @param props - {@link FindBestClosePathProps}
220
+ * @return result - {@link RouterCloseResult}
123
221
  */
124
222
  findBestClosePath: (props: FindBestClosePathProps) => Promise<RouterCloseResult>;
223
+ /**
224
+ * Finds all available swaps for given tokens; technically should be avoided to use, since doesn't have any advantage over findOneTokenPath.
225
+ * Deduplicates results by minAmount + stringified call path and returns only unique ones.
226
+ *
227
+ * @deprecated v3.0 legacy method
228
+ *
229
+ * @param props - {@link FindAllSwapsProps}
230
+ * @returns array of {@link RouterResult}
231
+ */
125
232
  findAllSwaps: (props: FindAllSwapsProps) => Promise<RouterResult[]>;
126
233
  /**
127
- * V3.0 sdk-gov legacy method
128
- * Should be removed after migration to V3.1
234
+ * Returns list of tokens which can be used as a token to align path through,
235
+ * for ex. when swapping sUSDe it is good to check swaps through USDe.
236
+ *
237
+ * @deprecated V3.0 sdk-gov legacy method
238
+ *
129
239
  * @param collateralTokens
130
240
  * @returns
131
241
  */
132
242
  getAvailableConnectors: (collateralTokens: Address[]) => Address[];
133
243
  /**
134
- * V3.0 legacy method
135
- * Used by batch liquidator
244
+ * Finds input to be used with findBestClosePath
245
+ * Used by batch liquidator.
246
+ *
247
+ * Params are same as in findBestClosePath, just different shape
248
+ *
249
+ * @deprecated V3.0 legacy method
250
+ *
136
251
  * @param ca
137
252
  * @param cm
253
+ * @param balances
138
254
  * @returns
139
255
  */
140
256
  getFindClosePathInput: (ca: RouterCASlice, cm: RouterCMSlice, balances?: Leftovers) => FindClosePathInput;
@@ -142,6 +258,7 @@ export interface IRouterContract extends IBaseContract {
142
258
  export type RouterHooks = {
143
259
  /**
144
260
  * Internal router event
261
+ * @deprecated v3.0 legacy event
145
262
  */
146
263
  foundPathOptions: [{
147
264
  creditAccount: Address;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "3.0.0-vfour.283",
3
+ "version": "3.0.0-vfour.285",
4
4
  "description": "Gearbox SDK",
5
5
  "license": "MIT",
6
6
  "main": "./dist/cjs/sdk/index.js",