@suilend/sdk 14.1.0 → 14.2.0-next.ge5d3397

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.
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@suilend/sdk","version":"14.1.0","private":false,"description":"A TypeScript SDK for interacting with the Suilend program","author":"Suilend","license":"MIT","main":"./index.js","exports":{".":"./index.js","./client":"./client.js","./mmt":"./mmt.js","./strategies":"./strategies.js","./api/events":"./api/events.js","./api":"./api/index.js","./lib/constants":"./lib/constants.js","./lib":"./lib/index.js","./lib/initialize":"./lib/initialize.js","./lib/liquidityMining":"./lib/liquidityMining.js","./lib/proCompatible":"./lib/proCompatible.js","./lib/pyth":"./lib/pyth.js","./lib/strategyOwnerCap":"./lib/strategyOwnerCap.js","./lib/transactions":"./lib/transactions.js","./lib/types":"./lib/types.js","./margin":"./margin/index.js","./parsers/apiReserveAssetDataEvent":"./parsers/apiReserveAssetDataEvent.js","./parsers":"./parsers/index.js","./parsers/lendingMarket":"./parsers/lendingMarket.js","./parsers/obligation":"./parsers/obligation.js","./parsers/rateLimiter":"./parsers/rateLimiter.js","./parsers/reserve":"./parsers/reserve.js","./swap":"./swap/index.js","./swap/quote":"./swap/quote.js","./swap/transaction":"./swap/transaction.js","./utils/events":"./utils/events.js","./utils/feedId":"./utils/feedId.js","./utils":"./utils/index.js","./utils/interpolate":"./utils/interpolate.js","./utils/obligation":"./utils/obligation.js","./utils/priceGuard":"./utils/priceGuard.js","./utils/simulate":"./utils/simulate.js","./_generated/_envs":"./_generated/_envs/index.js","./_generated/_envs/mainnet":"./_generated/_envs/mainnet.js","./_generated/_framework/env":"./_generated/_framework/env.js","./_generated/_framework/reified":"./_generated/_framework/reified.js","./_generated/_framework/util":"./_generated/_framework/util.js","./_generated/_framework/vector":"./_generated/_framework/vector.js","./_generated/suilend":"./_generated/suilend/index.js","./margin/margin/admin_cap":"./margin/margin/admin_cap.js","./margin/margin/market":"./margin/margin/market.js","./margin/margin/permissions":"./margin/margin/permissions.js","./margin/margin/position":"./margin/margin/position.js","./margin/margin/router":"./margin/margin/router.js","./margin/margin/version":"./margin/margin/version.js","./margin/utils":"./margin/utils/index.js","./_generated/suilend/cell/structs":"./_generated/suilend/cell/structs.js","./_generated/suilend/decimal/structs":"./_generated/suilend/decimal/structs.js","./_generated/suilend/lending-market/functions":"./_generated/suilend/lending-market/functions.js","./_generated/suilend/lending-market/structs":"./_generated/suilend/lending-market/structs.js","./_generated/suilend/lending-market-registry/functions":"./_generated/suilend/lending-market-registry/functions.js","./_generated/suilend/liquidity-mining/structs":"./_generated/suilend/liquidity-mining/structs.js","./_generated/suilend/obligation/structs":"./_generated/suilend/obligation/structs.js","./_generated/suilend/rate-limiter/functions":"./_generated/suilend/rate-limiter/functions.js","./_generated/suilend/rate-limiter/structs":"./_generated/suilend/rate-limiter/structs.js","./_generated/suilend/reserve/structs":"./_generated/suilend/reserve/structs.js","./_generated/suilend/reserve-config/functions":"./_generated/suilend/reserve-config/functions.js","./_generated/suilend/reserve-config/structs":"./_generated/suilend/reserve-config/structs.js","./_generated/_dependencies/pyth-2/price-identifier/structs":"./_generated/_dependencies/pyth-2/price-identifier/structs.js","./_generated/_dependencies/std/ascii/structs":"./_generated/_dependencies/std/ascii/structs.js","./_generated/_dependencies/std/option/structs":"./_generated/_dependencies/std/option/structs.js","./_generated/_dependencies/std/type-name/structs":"./_generated/_dependencies/std/type-name/structs.js","./_generated/_dependencies/sui/bag/structs":"./_generated/_dependencies/sui/bag/structs.js","./_generated/_dependencies/sui/balance/structs":"./_generated/_dependencies/sui/balance/structs.js","./_generated/_dependencies/sui/object/structs":"./_generated/_dependencies/sui/object/structs.js","./_generated/_dependencies/sui/object-table/structs":"./_generated/_dependencies/sui/object-table/structs.js","./margin/margin/deps/std/type_name":"./margin/margin/deps/std/type_name.js","./margin/margin/deps/sui/vec_set":"./margin/margin/deps/sui/vec_set.js","./margin/margin/deps/suilend/lending_market":"./margin/margin/deps/suilend/lending_market.js"},"types":"./index.d.ts","scripts":{"codegen":"node ./codegen.js","codegen:install":"node ./install-codegen.js","build":"rm -rf ./dist && tsc && node ./fix-esm-imports.js","typecheck":"tsc --noEmit && tsc --noEmit -p tsconfig.test.json","test":"vitest run","lint:ci":"yarn run typecheck","prettier":"prettier --write src/ tests/","release":"yarn run build && node ./release.js && cd ./dist && npm publish --access public"},"repository":{"type":"git","url":"git+https://github.com/fireflyprotocol/lending-mono.git","directory":"ts/sdks/sdk"},"dependencies":{"@cetusprotocol/aggregator-sdk":"1.7.3","@flowx-finance/sdk":"2.1.0","@pythnetwork/hermes-client":"3.1.0","@pythnetwork/pyth-sui-js":"4.0.0","@suilend/springsui-sdk":"4.1.0","bignumber.js":"11.1.5","bn.js":"5.2.5","crypto-js":"4.2.0","lodash":"4.18.1","p-limit":"7.3.3","uuid":"14.0.2"},"devDependencies":{"@mysten/bcs":"2.1.2","@mysten/sui":"2.35.0","@suilend/sui-core":"2.2.0","@tsconfig/recommended":"1.0.13","@types/bn.js":"5.2.0","@types/lodash":"4.17.26","@types/node":"26.6.5","fast-check":"4.10.2","prettier":"3.9.10","ts-node":"10.9.2","typescript":"6.0.3","vite":"8.3.4","vitest":"5.0.4"},"peerDependencies":{"@mysten/bcs":"^2.1.1","@mysten/sui":">=2.31.3 <3","@suilend/sui-core":"^2.0.1"},"type":"module"}
1
+ {"name":"@suilend/sdk","version":"14.2.0-next.ge5d3397","private":false,"description":"A TypeScript SDK for interacting with the Suilend program","author":"Suilend","license":"MIT","main":"./index.js","exports":{".":"./index.js","./client":"./client.js","./mmt":"./mmt.js","./strategies":"./strategies.js","./api/events":"./api/events.js","./api":"./api/index.js","./lib/constants":"./lib/constants.js","./lib":"./lib/index.js","./lib/initialize":"./lib/initialize.js","./lib/liquidityMining":"./lib/liquidityMining.js","./lib/proCompatible":"./lib/proCompatible.js","./lib/pyth":"./lib/pyth.js","./lib/strategyOwnerCap":"./lib/strategyOwnerCap.js","./lib/transactions":"./lib/transactions.js","./lib/types":"./lib/types.js","./margin":"./margin/index.js","./parsers/apiReserveAssetDataEvent":"./parsers/apiReserveAssetDataEvent.js","./parsers":"./parsers/index.js","./parsers/lendingMarket":"./parsers/lendingMarket.js","./parsers/obligation":"./parsers/obligation.js","./parsers/rateLimiter":"./parsers/rateLimiter.js","./parsers/reserve":"./parsers/reserve.js","./swap":"./swap/index.js","./swap/quote":"./swap/quote.js","./swap/transaction":"./swap/transaction.js","./utils/events":"./utils/events.js","./utils/feedId":"./utils/feedId.js","./utils":"./utils/index.js","./utils/interpolate":"./utils/interpolate.js","./utils/obligation":"./utils/obligation.js","./utils/priceGuard":"./utils/priceGuard.js","./utils/simulate":"./utils/simulate.js","./_generated/_envs":"./_generated/_envs/index.js","./_generated/_envs/mainnet":"./_generated/_envs/mainnet.js","./_generated/_framework/env":"./_generated/_framework/env.js","./_generated/_framework/reified":"./_generated/_framework/reified.js","./_generated/_framework/util":"./_generated/_framework/util.js","./_generated/_framework/vector":"./_generated/_framework/vector.js","./_generated/suilend":"./_generated/suilend/index.js","./margin/margin/admin_cap":"./margin/margin/admin_cap.js","./margin/margin/market":"./margin/margin/market.js","./margin/margin/permissions":"./margin/margin/permissions.js","./margin/margin/position":"./margin/margin/position.js","./margin/margin/router":"./margin/margin/router.js","./margin/margin/version":"./margin/margin/version.js","./margin/utils":"./margin/utils/index.js","./_generated/suilend/cell/structs":"./_generated/suilend/cell/structs.js","./_generated/suilend/decimal/structs":"./_generated/suilend/decimal/structs.js","./_generated/suilend/lending-market/functions":"./_generated/suilend/lending-market/functions.js","./_generated/suilend/lending-market/structs":"./_generated/suilend/lending-market/structs.js","./_generated/suilend/lending-market-registry/functions":"./_generated/suilend/lending-market-registry/functions.js","./_generated/suilend/liquidity-mining/structs":"./_generated/suilend/liquidity-mining/structs.js","./_generated/suilend/obligation/structs":"./_generated/suilend/obligation/structs.js","./_generated/suilend/rate-limiter/functions":"./_generated/suilend/rate-limiter/functions.js","./_generated/suilend/rate-limiter/structs":"./_generated/suilend/rate-limiter/structs.js","./_generated/suilend/reserve/structs":"./_generated/suilend/reserve/structs.js","./_generated/suilend/reserve-config/functions":"./_generated/suilend/reserve-config/functions.js","./_generated/suilend/reserve-config/structs":"./_generated/suilend/reserve-config/structs.js","./_generated/_dependencies/pyth-2/price-identifier/structs":"./_generated/_dependencies/pyth-2/price-identifier/structs.js","./_generated/_dependencies/std/ascii/structs":"./_generated/_dependencies/std/ascii/structs.js","./_generated/_dependencies/std/option/structs":"./_generated/_dependencies/std/option/structs.js","./_generated/_dependencies/std/type-name/structs":"./_generated/_dependencies/std/type-name/structs.js","./_generated/_dependencies/sui/bag/structs":"./_generated/_dependencies/sui/bag/structs.js","./_generated/_dependencies/sui/balance/structs":"./_generated/_dependencies/sui/balance/structs.js","./_generated/_dependencies/sui/object/structs":"./_generated/_dependencies/sui/object/structs.js","./_generated/_dependencies/sui/object-table/structs":"./_generated/_dependencies/sui/object-table/structs.js","./margin/margin/deps/std/type_name":"./margin/margin/deps/std/type_name.js","./margin/margin/deps/sui/vec_set":"./margin/margin/deps/sui/vec_set.js","./margin/margin/deps/suilend/lending_market":"./margin/margin/deps/suilend/lending_market.js"},"types":"./index.d.ts","scripts":{"codegen":"node ./codegen.js","codegen:install":"node ./install-codegen.js","build":"rm -rf ./dist && tsc && node ./fix-esm-imports.js","typecheck":"tsc --noEmit && tsc --noEmit -p tsconfig.test.json","test":"vitest run","lint:ci":"yarn run typecheck","prettier":"prettier --write src/ tests/","release":"yarn run build && node ./release.js && cd ./dist && npm publish --access public"},"repository":{"type":"git","url":"git+https://github.com/fireflyprotocol/lending-mono.git","directory":"ts/sdks/sdk"},"dependencies":{"@cetusprotocol/aggregator-sdk":"1.7.3","@flowx-finance/sdk":"2.1.0","@pythnetwork/hermes-client":"3.1.0","@pythnetwork/pyth-sui-js":"4.0.0","@suilend/springsui-sdk":"4.1.0","bignumber.js":"11.1.5","bn.js":"5.2.5","crypto-js":"4.2.0","lodash":"4.18.1","p-limit":"7.3.3","uuid":"14.0.2"},"devDependencies":{"@mysten/bcs":"2.1.2","@mysten/sui":"2.35.0","@suilend/sui-core":"2.2.0","@tsconfig/recommended":"1.0.13","@types/bn.js":"5.2.0","@types/lodash":"4.17.26","@types/node":"26.6.5","fast-check":"4.10.2","prettier":"3.9.10","ts-node":"10.9.2","typescript":"6.0.3","vite":"8.3.4","vitest":"5.0.4"},"peerDependencies":{"@mysten/bcs":"^2.1.1","@mysten/sui":">=2.31.3 <3","@suilend/sui-core":"^2.0.1"},"type":"module"}
package/strategies.d.ts CHANGED
@@ -13,6 +13,7 @@ import { ParsedObligation, ParsedReserve } from "./parsers";
13
13
  export declare const STRATEGY_E: number;
14
14
  export declare const STRATEGY_FLASH_REPAY_MAX_RESIDUAL_USD = 0.1;
15
15
  export declare const STRATEGY_RATE_LIMITED_ERROR_MESSAGE = "This withdrawal exceeds the lending market's outflow limit for now. Withdraw a smaller amount, or wait and try again.";
16
+ export declare const STRATEGY_WITHDRAWN_COIN_CONSUMER_ERROR_MESSAGE = "Failed to use the withdrawn coin";
16
17
  /**
17
18
  * Below this, a levered position is uneconomic no matter what the slippage
18
19
  * tolerance says. The aggregator's dust regime dominates: routes go multi-hop
@@ -356,9 +357,10 @@ export declare const strategyDepositAndLoopToExposureTx: (reserveMap: Record<str
356
357
  borrowedAmount: BigNumber;
357
358
  transaction: Transaction;
358
359
  }>;
360
+ export type StrategyWithdrawnCoinConsumer = (transaction: Transaction, coin: TransactionObjectArgument, estimatedAmount: BigNumber) => Promise<void>;
359
361
  export declare const strategyWithdrawTx: (reserveMap: Record<string, ParsedReserve>, lstMap: StrategyLstMap, strategyType: StrategyType, suiGrpcClient: SuiGrpcClient, suilendClient: SuilendClient, cetusSdk: CetusSdk, cetusPartnerId: string, _address: string, strategyOwnerCapId: TransactionObjectInput, obligationId: string, _deposits: StrategyDeposit[], _borrowedAmount: BigNumber, withdraw: StrategyWithdraw, transaction: Transaction, dryRunTransaction: (transaction: Transaction, setGasBudget?: boolean) => Promise<SuiClientTypes.SimulateTransactionResult<{
360
362
  commandResults: true;
361
- }>>, returnWithdrawnCoin?: boolean, rewardsMap?: RewardsMap) => Promise<{
363
+ }>>, returnWithdrawnCoin?: boolean, rewardsMap?: RewardsMap, consumeWithdrawnCoin?: StrategyWithdrawnCoinConsumer) => Promise<{
362
364
  deposits: StrategyDeposit[];
363
365
  borrowedAmount: BigNumber;
364
366
  transaction: Transaction;
@@ -366,7 +368,7 @@ export declare const strategyWithdrawTx: (reserveMap: Record<string, ParsedReser
366
368
  }>;
367
369
  export declare const strategyMaxWithdrawTx: (reserveMap: Record<string, ParsedReserve>, rewardsMap: RewardsMap, lstMap: StrategyLstMap, strategyType: StrategyType, suiGrpcClient: SuiGrpcClient, suilendClient: SuilendClient, cetusSdk: CetusSdk, cetusPartnerId: string, _address: string, strategyOwnerCapId: TransactionObjectInput, obligationId: string, _deposits: StrategyDeposit[], _borrowedAmount: BigNumber, withdrawCoinType: string, transaction: Transaction, _dryRunTransaction: (transaction: Transaction, setGasBudget?: boolean) => Promise<SuiClientTypes.SimulateTransactionResult<{
368
370
  commandResults: true;
369
- }>>) => Promise<{
371
+ }>>, consumeWithdrawnCoin?: StrategyWithdrawnCoinConsumer) => Promise<{
370
372
  deposits: StrategyDeposit[];
371
373
  borrowedAmount: BigNumber;
372
374
  transaction: Transaction;
package/strategies.js CHANGED
@@ -14,6 +14,7 @@ import { bisectionMethod, getWeightedBorrowsUsd } from "./utils/index.js";
14
14
  export const STRATEGY_E = 10 ** -7;
15
15
  export const STRATEGY_FLASH_REPAY_MAX_RESIDUAL_USD = 0.1;
16
16
  export const STRATEGY_RATE_LIMITED_ERROR_MESSAGE = "This withdrawal exceeds the lending market's outflow limit for now. Withdraw a smaller amount, or wait and try again.";
17
+ export const STRATEGY_WITHDRAWN_COIN_CONSUMER_ERROR_MESSAGE = "Failed to use the withdrawn coin";
17
18
  const isRateLimitExceeded = (err) => /abort code: 2, in '[^']*::rate_limiter::process_qty'/.test(err instanceof Error ? err.message : String(err));
18
19
  // Every step dry-runs and rolls back on failure, so the builders only see that
19
20
  // no step landed. Recording why lets them name the market's outflow limit
@@ -2262,6 +2263,31 @@ const isStrategyPositionClosed = (reserveMap, deposits) => deposits.every((d) =>
2262
2263
  .decimalPlaces(reserve.token.decimals, BigNumber.ROUND_DOWN)
2263
2264
  .lte(0));
2264
2265
  });
2266
+ const sendStrategyWithdrawnCoin = async (transaction, coin, estimatedAmount, address, consumeWithdrawnCoin, dryRunTransaction) => {
2267
+ if (!consumeWithdrawnCoin) {
2268
+ transaction.transferObjects([coin], address);
2269
+ return;
2270
+ }
2271
+ const transactionBeforeConsumer = Transaction.from(transaction);
2272
+ await consumeWithdrawnCoin(transaction, coin, estimatedAmount);
2273
+ try {
2274
+ await dryRunTransaction(transaction);
2275
+ }
2276
+ catch (err) {
2277
+ transactionBeforeConsumer.transferObjects([coin], address);
2278
+ try {
2279
+ await dryRunTransaction(transactionBeforeConsumer);
2280
+ }
2281
+ catch {
2282
+ return;
2283
+ }
2284
+ console.error(err);
2285
+ throw new Error(STRATEGY_WITHDRAWN_COIN_CONSUMER_ERROR_MESSAGE);
2286
+ }
2287
+ };
2288
+ const getRedeemedSuiAmount = (lstAmount, lst) => lstAmount
2289
+ .times(new BigNumber(lst?.lstToSuiExchangeRate ?? 1).times(1 - +(lst?.redeemFeePercent ?? 0) / 100))
2290
+ .decimalPlaces(SUI_DECIMALS, BigNumber.ROUND_DOWN);
2265
2291
  const tryClaimStrategyRewardsToUser = async (strategyType, rewardsMap, strategyOwnerCapId, address, transaction, dryRunTransaction) => {
2266
2292
  const transactionBeforeClaim = Transaction.from(transaction);
2267
2293
  try {
@@ -2281,7 +2307,9 @@ export const strategyWithdrawTx = async (
2281
2307
  // AppContext
2282
2308
  reserveMap,
2283
2309
  // Strategy
2284
- lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, withdraw, transaction, dryRunTransaction, returnWithdrawnCoin, rewardsMap = {}) => {
2310
+ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, withdraw, transaction, dryRunTransaction, returnWithdrawnCoin, rewardsMap = {}, consumeWithdrawnCoin) => {
2311
+ if (returnWithdrawnCoin && consumeWithdrawnCoin)
2312
+ throw new Error("Pass returnWithdrawnCoin or consumeWithdrawnCoin, not both");
2285
2313
  const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
2286
2314
  const lst = strategyInfo.depositLstCoinType !== undefined
2287
2315
  ? lstMap[strategyInfo.depositLstCoinType]
@@ -2399,6 +2427,7 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2399
2427
  newTvlAmountUsd: newTvlAmountUsd.toFixed(20),
2400
2428
  }, null, 2));
2401
2429
  // 3) Transfer coin to user, or return coin
2430
+ const sendWithdrawnCoin = (coin, estimatedAmount) => sendStrategyWithdrawnCoin(transaction, coin, estimatedAmount, _address, consumeWithdrawnCoin, dryRunTransaction);
2402
2431
  if (returnWithdrawnCoin)
2403
2432
  return { deposits, borrowedAmount, transaction, withdrawnCoin };
2404
2433
  else {
@@ -2416,7 +2445,8 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2416
2445
  });
2417
2446
  if (!routers)
2418
2447
  throw new Error("No swap quote found");
2419
- const { slippagePercent } = resolveSwapSlippage(finalWithdrawnAmount, new BigNumber(routers.amountOut.toString()).div(10 ** reserveMap[withdraw.coinType].token.decimals), depositReserve, reserveMap[withdraw.coinType]);
2448
+ const swappedAmount = new BigNumber(routers.amountOut.toString()).div(10 ** reserveMap[withdraw.coinType].token.decimals);
2449
+ const { slippagePercent } = resolveSwapSlippage(finalWithdrawnAmount, swappedAmount, depositReserve, reserveMap[withdraw.coinType]);
2420
2450
  let swappedCoin;
2421
2451
  try {
2422
2452
  swappedCoin = (await cetusSdk.fixableRouterSwapV3({
@@ -2430,10 +2460,10 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2430
2460
  catch (err) {
2431
2461
  throw new Error("No swap quote found");
2432
2462
  }
2433
- transaction.transferObjects([swappedCoin], _address);
2463
+ await sendWithdrawnCoin(swappedCoin, swappedAmount);
2434
2464
  }
2435
2465
  else {
2436
- transaction.transferObjects([withdrawnCoin], _address);
2466
+ await sendWithdrawnCoin(withdrawnCoin, finalWithdrawnAmount);
2437
2467
  }
2438
2468
  }
2439
2469
  else {
@@ -2441,11 +2471,11 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2441
2471
  // 3.1) Unstake LST for SUI
2442
2472
  const suiWithdrawnCoin = lst.client.redeem(transaction, withdrawnCoin);
2443
2473
  // 3.2) Transfer SUI to user
2444
- transaction.transferObjects([suiWithdrawnCoin], _address);
2474
+ await sendWithdrawnCoin(suiWithdrawnCoin, getRedeemedSuiAmount(finalWithdrawnAmount, lst));
2445
2475
  }
2446
2476
  else {
2447
2477
  // 3.1) Transfer LST to user
2448
- transaction.transferObjects([withdrawnCoin], _address);
2478
+ await sendWithdrawnCoin(withdrawnCoin, finalWithdrawnAmount);
2449
2479
  }
2450
2480
  }
2451
2481
  }
@@ -2458,7 +2488,7 @@ export const strategyMaxWithdrawTx = async (
2458
2488
  // AppContext
2459
2489
  reserveMap, rewardsMap,
2460
2490
  // Strategy
2461
- lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, withdrawCoinType, transaction, _dryRunTransaction) => {
2491
+ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, withdrawCoinType, transaction, _dryRunTransaction, consumeWithdrawnCoin) => {
2462
2492
  const { rateLimit, dryRunTransaction } = trackRateLimit(_dryRunTransaction);
2463
2493
  const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
2464
2494
  const lst = strategyInfo.depositLstCoinType !== undefined
@@ -2604,6 +2634,7 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2604
2634
  receipt,
2605
2635
  borrowedBalanceA,
2606
2636
  remainingCoin: flashLoanBorrowedCoin,
2637
+ borrowedAmount: flashLoanBorrowedAmount,
2607
2638
  };
2608
2639
  }
2609
2640
  const estimatedWithdrawnAmount = deposits.find((d) => d.coinType === depositReserve.coinType)
@@ -2618,6 +2649,7 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2618
2649
  })),
2619
2650
  borrowedAmount: borrowedAmount.toFixed(20),
2620
2651
  }, null, 2));
2652
+ const sendWithdrawnCoin = (coin, estimatedAmount) => sendStrategyWithdrawnCoin(transaction, coin, estimatedAmount, _address, consumeWithdrawnCoin, dryRunTransaction);
2621
2653
  // 3) Transfer coin to user
2622
2654
  if (depositReserve.coinType === depositReserves.base?.coinType) {
2623
2655
  if (withdrawCoinType !== depositReserve.coinType) {
@@ -2633,7 +2665,8 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2633
2665
  });
2634
2666
  if (!routers)
2635
2667
  throw new Error("No swap quote found");
2636
- const { slippagePercent } = resolveSwapSlippage(estimatedWithdrawnAmount, new BigNumber(routers.amountOut.toString()).div(10 ** reserveMap[withdrawCoinType].token.decimals), depositReserve, reserveMap[withdrawCoinType]);
2668
+ const swappedAmount = new BigNumber(routers.amountOut.toString()).div(10 ** reserveMap[withdrawCoinType].token.decimals);
2669
+ const { slippagePercent } = resolveSwapSlippage(estimatedWithdrawnAmount, swappedAmount, depositReserve, reserveMap[withdrawCoinType]);
2637
2670
  let swappedCoin;
2638
2671
  try {
2639
2672
  swappedCoin = (await cetusSdk.fixableRouterSwapV3({
@@ -2647,10 +2680,10 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2647
2680
  catch (err) {
2648
2681
  throw new Error("No swap quote found");
2649
2682
  }
2650
- transaction.transferObjects([swappedCoin], _address);
2683
+ await sendWithdrawnCoin(swappedCoin, swappedAmount);
2651
2684
  }
2652
2685
  else {
2653
- transaction.transferObjects([withdrawnCoin], _address);
2686
+ await sendWithdrawnCoin(withdrawnCoin, estimatedWithdrawnAmount);
2654
2687
  }
2655
2688
  }
2656
2689
  else {
@@ -2686,11 +2719,11 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2686
2719
  });
2687
2720
  }
2688
2721
  // 3.3) Transfer SUI to user
2689
- transaction.transferObjects([suiWithdrawnCoin], _address);
2722
+ await sendWithdrawnCoin(suiWithdrawnCoin, BigNumber.max(0, getRedeemedSuiAmount(estimatedWithdrawnAmount, lst).minus(flashLoan?.borrowedAmount ?? 0)));
2690
2723
  }
2691
2724
  else {
2692
2725
  // 3.1) Transfer LST to user
2693
- transaction.transferObjects([withdrawnCoin], _address);
2726
+ await sendWithdrawnCoin(withdrawnCoin, estimatedWithdrawnAmount);
2694
2727
  }
2695
2728
  }
2696
2729
  // 4) Claim rewards and transfer to user