@suilend/sdk 2.0.4 → 2.0.5
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/client.js +11 -32
- package/lib/coin.d.ts +3 -0
- package/lib/coin.js +67 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/initialize.js +4 -3
- package/lib/strategyOwnerCap.d.ts +12 -7
- package/lib/strategyOwnerCap.js +159 -156
- package/package.json +1 -1
- package/strategies.d.ts +1 -1
- package/strategies.js +302 -82
- package/swap/transaction.js +3 -11
package/strategies.js
CHANGED
|
@@ -14,10 +14,11 @@ import BigNumber from "bignumber.js";
|
|
|
14
14
|
import { BN } from "bn.js";
|
|
15
15
|
import { cloneDeep } from "lodash";
|
|
16
16
|
import { LstClient, SPRING_SUI_UPGRADE_CAP_ID, getLatestPackageId as getLatestSpringSuiPackageId, } from "@suilend/springsui-sdk";
|
|
17
|
-
import { API_URL, MAX_U64, MS_PER_YEAR, NORMALIZED_AUSD_COINTYPE, NORMALIZED_SUI_COINTYPE, NORMALIZED_USDC_COINTYPE, NORMALIZED_sSUI_COINTYPE, NORMALIZED_suiUSDT_COINTYPE, NORMALIZED_suiWBTC_COINTYPE, NORMALIZED_xBTC_COINTYPE,
|
|
17
|
+
import { API_URL, MAX_U64, MS_PER_YEAR, NORMALIZED_AUSD_COINTYPE, NORMALIZED_SUI_COINTYPE, NORMALIZED_USDC_COINTYPE, NORMALIZED_sSUI_COINTYPE, NORMALIZED_suiUSDT_COINTYPE, NORMALIZED_suiWBTC_COINTYPE, NORMALIZED_xBTC_COINTYPE, isSui, } from "@suilend/sui-fe";
|
|
18
18
|
import { getNetAprPercent } from "./lib";
|
|
19
|
+
import { getSpendableCoin } from "./lib/coin";
|
|
19
20
|
import { getRewardsMap } from "./lib/liquidityMining";
|
|
20
|
-
import { STRATEGY_TYPE_INFO_MAP, StrategyType, strategyBorrow,
|
|
21
|
+
import { STRATEGY_TYPE_INFO_MAP, StrategyType, strategyBorrow, strategyClaimRewardsAndMergeCoins, strategyDeposit, strategyWithdraw, } from "./lib/strategyOwnerCap";
|
|
21
22
|
import { MMT_CONTRACT_PACKAGE_ID, MMT_VERSION_OBJECT_ID } from "./mmt";
|
|
22
23
|
import { getWeightedBorrowsUsd } from "./utils";
|
|
23
24
|
export const STRATEGY_E = 10 ** -7;
|
|
@@ -35,20 +36,28 @@ export const STRATEGY_TYPE_FLASH_LOAN_OBJ_MAP = {
|
|
|
35
36
|
borrowA: false,
|
|
36
37
|
feePercent: 0.01,
|
|
37
38
|
},
|
|
38
|
-
[StrategyType.
|
|
39
|
+
[StrategyType.USDC_sSUI_SUI_LOOPING]: {
|
|
39
40
|
provider: StrategyFlashLoanProvider.MMT,
|
|
40
|
-
poolId: "
|
|
41
|
-
coinTypeA:
|
|
42
|
-
coinTypeB:
|
|
41
|
+
poolId: "0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9", // suiUSDT-USDC 0.001% https://app.mmt.finance/liquidity/0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9
|
|
42
|
+
coinTypeA: NORMALIZED_suiUSDT_COINTYPE,
|
|
43
|
+
coinTypeB: NORMALIZED_USDC_COINTYPE,
|
|
43
44
|
borrowA: false,
|
|
44
|
-
feePercent: 0.
|
|
45
|
+
feePercent: 0.001,
|
|
45
46
|
},
|
|
46
|
-
[StrategyType.
|
|
47
|
+
[StrategyType.USDsui_USDC_LOOPING]: {
|
|
47
48
|
provider: StrategyFlashLoanProvider.MMT,
|
|
48
49
|
poolId: "0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9", // suiUSDT-USDC 0.001% https://app.mmt.finance/liquidity/0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9
|
|
49
50
|
coinTypeA: NORMALIZED_suiUSDT_COINTYPE,
|
|
50
51
|
coinTypeB: NORMALIZED_USDC_COINTYPE,
|
|
51
|
-
borrowA: false,
|
|
52
|
+
borrowA: false, // Requires swap from USDT to USDsui
|
|
53
|
+
feePercent: 0.001,
|
|
54
|
+
},
|
|
55
|
+
[StrategyType.eEARN_USDC_LOOPING]: {
|
|
56
|
+
provider: StrategyFlashLoanProvider.MMT,
|
|
57
|
+
poolId: "0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9", // suiUSDT-USDC 0.001% https://app.mmt.finance/liquidity/0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9
|
|
58
|
+
coinTypeA: NORMALIZED_suiUSDT_COINTYPE,
|
|
59
|
+
coinTypeB: NORMALIZED_USDC_COINTYPE,
|
|
60
|
+
borrowA: false, // Requires swap from USDC to eEARN
|
|
52
61
|
feePercent: 0.001,
|
|
53
62
|
},
|
|
54
63
|
[StrategyType.AUSD_sSUI_SUI_LOOPING]: {
|
|
@@ -107,6 +116,23 @@ export const STRATEGY_TYPE_FLASH_LOAN_OBJ_MAP = {
|
|
|
107
116
|
borrowA: false,
|
|
108
117
|
feePercent: 0.001,
|
|
109
118
|
},
|
|
119
|
+
// TODO: Update poolId for USDsui sSUI-SUI
|
|
120
|
+
[StrategyType.USDsui_sSUI_SUI_LOOPING]: {
|
|
121
|
+
provider: StrategyFlashLoanProvider.MMT,
|
|
122
|
+
poolId: "0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9", // suiUSDT-USDC 0.001% https://app.mmt.finance/liquidity/0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9
|
|
123
|
+
coinTypeA: NORMALIZED_suiUSDT_COINTYPE,
|
|
124
|
+
coinTypeB: NORMALIZED_USDC_COINTYPE,
|
|
125
|
+
borrowA: false,
|
|
126
|
+
feePercent: 0.001,
|
|
127
|
+
},
|
|
128
|
+
[StrategyType.stratSUI_SUI_LOOPING]: {
|
|
129
|
+
provider: StrategyFlashLoanProvider.MMT,
|
|
130
|
+
poolId: "0x9c92c5b8e9d83e485fb4c86804ac8b920bb0beaace5e61a5b0239218f627f8e9", // xSUI-SUI 0.01% https://app.mmt.finance/liquidity/0x9c92c5b8e9d83e485fb4c86804ac8b920bb0beaace5e61a5b0239218f627f8e9
|
|
131
|
+
coinTypeA: "0x2b6602099970374cf58a2a1b9d96f005fccceb81e92eb059873baf420eb6c717::x_sui::X_SUI",
|
|
132
|
+
coinTypeB: NORMALIZED_SUI_COINTYPE,
|
|
133
|
+
borrowA: false,
|
|
134
|
+
feePercent: 0.01,
|
|
135
|
+
},
|
|
110
136
|
};
|
|
111
137
|
export const getReserveSafeDepositLimit = (reserve) => {
|
|
112
138
|
// Calculate safe deposit limit (subtract 10 mins of deposit APR from cap)
|
|
@@ -133,7 +159,10 @@ export const hasStrategyPosition = (obligation) => obligation.deposits.length >
|
|
|
133
159
|
// SUI
|
|
134
160
|
export const getStrategySuiReserve = (
|
|
135
161
|
// AppContext
|
|
136
|
-
reserveMap) =>
|
|
162
|
+
reserveMap) => {
|
|
163
|
+
var _a;
|
|
164
|
+
return (_a = reserveMap[NORMALIZED_SUI_COINTYPE]) !== null && _a !== void 0 ? _a : { price: new BigNumber(1) };
|
|
165
|
+
};
|
|
137
166
|
export const fetchStrategyLstMap = (suiClient) => __awaiter(void 0, void 0, void 0, function* () {
|
|
138
167
|
try {
|
|
139
168
|
const lstCoinTypes = Array.from(new Set([
|
|
@@ -213,16 +242,21 @@ export const STRATEGY_TYPE_EXPOSURE_MAP = {
|
|
|
213
242
|
max: new BigNumber(3), // Actual max: 1 / (1 - (sSUI Open LTV %)) = 3.333x, where sSUI Open LTV % = 70%
|
|
214
243
|
default: new BigNumber(3),
|
|
215
244
|
},
|
|
216
|
-
[StrategyType.stratSUI_SUI_LOOPING]: {
|
|
217
|
-
min: new BigNumber(1),
|
|
218
|
-
max: new BigNumber(3), // Actual max: 1 / (1 - (sSUI Open LTV %)) = 3.333x, where sSUI Open LTV % = 70%
|
|
219
|
-
default: new BigNumber(3),
|
|
220
|
-
},
|
|
221
245
|
[StrategyType.USDC_sSUI_SUI_LOOPING]: {
|
|
222
246
|
min: new BigNumber(1),
|
|
223
247
|
max: new BigNumber(3), // Actual max: 1 + (USDC Open LTV %) * (1 / (1 - (sSUI Open LTV %))) = 3.5666x, where USDC Open LTV % = 77% and sSUI Open LTV % = 70%
|
|
224
248
|
default: new BigNumber(3),
|
|
225
249
|
},
|
|
250
|
+
[StrategyType.USDsui_USDC_LOOPING]: {
|
|
251
|
+
min: new BigNumber(1),
|
|
252
|
+
max: new BigNumber(4), // Actual max: 1 / (1 - (USDsui Open LTV %)) = 4.347x, where USDsui Open LTV % = 77%
|
|
253
|
+
default: new BigNumber(4),
|
|
254
|
+
},
|
|
255
|
+
[StrategyType.eEARN_USDC_LOOPING]: {
|
|
256
|
+
min: new BigNumber(1),
|
|
257
|
+
max: new BigNumber(4.5), // Actual max: 1 / (1 - (eEARN Open LTV %)) = 5x, where eEARN Open LTV % = 80%
|
|
258
|
+
default: new BigNumber(4.5),
|
|
259
|
+
},
|
|
226
260
|
[StrategyType.AUSD_sSUI_SUI_LOOPING]: {
|
|
227
261
|
min: new BigNumber(1),
|
|
228
262
|
max: new BigNumber(3), // Actual max: 1 + (AUSD Open LTV %) * (1 / (1 - (sSUI Open LTV %))) = 3.5666x, where AUSD Open LTV % = 77% and sSUI Open LTV % = 70%
|
|
@@ -258,6 +292,16 @@ export const STRATEGY_TYPE_EXPOSURE_MAP = {
|
|
|
258
292
|
max: new BigNumber(4), // Actual max: 1 / (1 - (USDC Open LTV %)) = 4.347x, where USDC Open LTV % = 77%
|
|
259
293
|
default: new BigNumber(4),
|
|
260
294
|
},
|
|
295
|
+
[StrategyType.USDsui_sSUI_SUI_LOOPING]: {
|
|
296
|
+
min: new BigNumber(1),
|
|
297
|
+
max: new BigNumber(3), // Actual max: 1 + (USDsui Open LTV %) * (1 / (1 - (sSUI Open LTV %))) = 3.5666x, where USDsui Open LTV % = 77% and sSUI Open LTV % = 70%
|
|
298
|
+
default: new BigNumber(3),
|
|
299
|
+
},
|
|
300
|
+
[StrategyType.stratSUI_SUI_LOOPING]: {
|
|
301
|
+
min: new BigNumber(1),
|
|
302
|
+
max: new BigNumber(3), // Actual max: 1 / (1 - (sSUI Open LTV %)) = 3.333x, where sSUI Open LTV % = 70%
|
|
303
|
+
default: new BigNumber(3),
|
|
304
|
+
},
|
|
261
305
|
};
|
|
262
306
|
// Reserves
|
|
263
307
|
export const getStrategyDepositReserves = (
|
|
@@ -801,6 +845,7 @@ lstMap, strategyType, obligation, exposure) => {
|
|
|
801
845
|
StrategyType.AUSD_sSUI_SUI_LOOPING,
|
|
802
846
|
StrategyType.xBTC_sSUI_SUI_LOOPING,
|
|
803
847
|
StrategyType.suiUSDT_sSUI_SUI_LOOPING,
|
|
848
|
+
StrategyType.USDsui_sSUI_SUI_LOOPING,
|
|
804
849
|
].includes(strategyType))
|
|
805
850
|
return new BigNumber(0); // Not shown in UI
|
|
806
851
|
let _obligation;
|
|
@@ -897,12 +942,14 @@ transaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
897
942
|
}, null, 2));
|
|
898
943
|
// 1.2) Borrow
|
|
899
944
|
const stepBorrowedAmount = BigNumber.min(pendingBorrowedAmount, stepMaxBorrowedAmount).decimalPlaces(borrowReserve.token.decimals, BigNumber.ROUND_DOWN);
|
|
945
|
+
if (stepBorrowedAmount.lte(0))
|
|
946
|
+
break;
|
|
900
947
|
const isMaxBorrow = stepBorrowedAmount.eq(stepMaxBorrowedAmount);
|
|
901
948
|
console.log(`[loopStrategyToExposure] ${i} borrow_sui.borrow |`, JSON.stringify({
|
|
902
949
|
stepBorrowedAmount: stepBorrowedAmount.toFixed(20),
|
|
903
950
|
isMaxBorrow,
|
|
904
951
|
}, null, 2));
|
|
905
|
-
const [borrowedCoin] = strategyBorrow(borrowReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(borrowReserve.coinType), BigInt(stepBorrowedAmount
|
|
952
|
+
const [borrowedCoin] = strategyBorrow(strategyType, borrowReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(borrowReserve.coinType), BigInt(stepBorrowedAmount
|
|
906
953
|
.times(10 ** borrowReserve.token.decimals)
|
|
907
954
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
908
955
|
.toString()), transaction);
|
|
@@ -927,7 +974,7 @@ transaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
927
974
|
stepDepositedAmount: stepDepositedAmount.toFixed(20),
|
|
928
975
|
isMaxDeposit,
|
|
929
976
|
}, null, 2));
|
|
930
|
-
strategyDeposit(stepLstCoin, loopingDepositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(loopingDepositReserve.coinType), transaction);
|
|
977
|
+
strategyDeposit(strategyType, stepLstCoin, loopingDepositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(loopingDepositReserve.coinType), transaction);
|
|
931
978
|
// 2.3) Update state
|
|
932
979
|
deposits = addOrInsertStrategyDeposit(deposits, {
|
|
933
980
|
coinType: loopingDepositReserve.coinType,
|
|
@@ -983,12 +1030,14 @@ transaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
983
1030
|
}, null, 2));
|
|
984
1031
|
// 1.2) Borrow
|
|
985
1032
|
const stepBorrowedAmount = BigNumber.min(pendingBorrowedAmount, stepMaxBorrowedAmount).decimalPlaces(borrowReserve.token.decimals, BigNumber.ROUND_DOWN);
|
|
1033
|
+
if (stepBorrowedAmount.lte(0))
|
|
1034
|
+
break;
|
|
986
1035
|
const isMaxBorrow = stepBorrowedAmount.eq(stepMaxBorrowedAmount);
|
|
987
1036
|
console.log(`[loopStrategyToExposure] ${i} borrow.borrow |`, JSON.stringify({
|
|
988
1037
|
stepBorrowedAmount: stepBorrowedAmount.toFixed(20),
|
|
989
1038
|
isMaxBorrow,
|
|
990
1039
|
}, null, 2));
|
|
991
|
-
const [stepBorrowedCoin] = strategyBorrow(borrowReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(borrowReserve.coinType), BigInt(stepBorrowedAmount
|
|
1040
|
+
const [stepBorrowedCoin] = strategyBorrow(strategyType, borrowReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(borrowReserve.coinType), BigInt(stepBorrowedAmount
|
|
992
1041
|
.times(10 ** borrowReserve.token.decimals)
|
|
993
1042
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
994
1043
|
.toString()), transaction);
|
|
@@ -1045,7 +1094,7 @@ transaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
1045
1094
|
stepDepositedAmount: stepDepositedAmount.toFixed(20),
|
|
1046
1095
|
isMaxDeposit,
|
|
1047
1096
|
}, null, 2));
|
|
1048
|
-
strategyDeposit(stepBaseCoin, loopingDepositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(loopingDepositReserve.coinType), transaction);
|
|
1097
|
+
strategyDeposit(strategyType, stepBaseCoin, loopingDepositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(loopingDepositReserve.coinType), transaction);
|
|
1049
1098
|
// 2.3) Update state
|
|
1050
1099
|
deposits = addOrInsertStrategyDeposit(deposits, {
|
|
1051
1100
|
coinType: loopingDepositReserve.coinType,
|
|
@@ -1135,7 +1184,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1135
1184
|
lstWithdrawnAmount: lstWithdrawnAmount.toFixed(20),
|
|
1136
1185
|
}));
|
|
1137
1186
|
// 1.1) Withdraw
|
|
1138
|
-
const [withdrawnLstCoin] = strategyWithdraw(depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), BigInt(new BigNumber(lstWithdrawnAmount
|
|
1187
|
+
const [withdrawnLstCoin] = strategyWithdraw(strategyType, depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), BigInt(new BigNumber(lstWithdrawnAmount
|
|
1139
1188
|
.times(10 ** LST_DECIMALS)
|
|
1140
1189
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
1141
1190
|
.toString())
|
|
@@ -1194,7 +1243,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1194
1243
|
remainingLstWithdrawnAmount: remainingLstWithdrawnAmount.toFixed(20),
|
|
1195
1244
|
}));
|
|
1196
1245
|
// 1.1) MAX Withdraw
|
|
1197
|
-
const [withdrawnRemainingLstCoin] = strategyWithdraw(depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), BigInt(MAX_U64.toString()), transaction);
|
|
1246
|
+
const [withdrawnRemainingLstCoin] = strategyWithdraw(strategyType, depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), BigInt(MAX_U64.toString()), transaction);
|
|
1198
1247
|
// 1.2) Update state
|
|
1199
1248
|
deposits = addOrInsertStrategyDeposit(deposits, {
|
|
1200
1249
|
coinType: depositReserves.lst.coinType,
|
|
@@ -1246,7 +1295,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1246
1295
|
throw new Error("No swap quote found");
|
|
1247
1296
|
}
|
|
1248
1297
|
// 3) Deposit base
|
|
1249
|
-
strategyDeposit(swapCoin, depositReserves.base.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.base.coinType), transaction);
|
|
1298
|
+
strategyDeposit(strategyType, swapCoin, depositReserves.base.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.base.coinType), transaction);
|
|
1250
1299
|
}
|
|
1251
1300
|
});
|
|
1252
1301
|
const fullyRepayBorrowsUsingBase = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -1269,7 +1318,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1269
1318
|
// 1) MAX withdraw LST
|
|
1270
1319
|
if (depositReserves.lst !== undefined) {
|
|
1271
1320
|
// 1.1) MAX withdraw
|
|
1272
|
-
const [withdrawnMaxLstCoin] = strategyWithdraw(depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), BigInt(MAX_U64.toString()), transaction);
|
|
1321
|
+
const [withdrawnMaxLstCoin] = strategyWithdraw(strategyType, depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), BigInt(MAX_U64.toString()), transaction);
|
|
1273
1322
|
// 1.2) Update state
|
|
1274
1323
|
deposits = addOrInsertStrategyDeposit(deposits, {
|
|
1275
1324
|
coinType: depositReserves.lst.coinType,
|
|
@@ -1296,7 +1345,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1296
1345
|
baseWithdrawnAmount: baseWithdrawnAmount.toFixed(20),
|
|
1297
1346
|
}, null, 2));
|
|
1298
1347
|
// 2.1) Withdraw
|
|
1299
|
-
const [withdrawnBaseCoin] = strategyWithdraw(depositReserves.base.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.base.coinType), BigInt(new BigNumber(baseWithdrawnAmount
|
|
1348
|
+
const [withdrawnBaseCoin] = strategyWithdraw(strategyType, depositReserves.base.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.base.coinType), BigInt(new BigNumber(baseWithdrawnAmount
|
|
1300
1349
|
.times(10 ** depositReserves.base.token.decimals)
|
|
1301
1350
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
1302
1351
|
.toString())
|
|
@@ -1463,7 +1512,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1463
1512
|
stepWithdrawnAmount: stepWithdrawnAmount.toFixed(20),
|
|
1464
1513
|
isMaxWithdraw,
|
|
1465
1514
|
}, null, 2));
|
|
1466
|
-
const [stepWithdrawnCoin] = strategyWithdraw(loopingDepositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(loopingDepositReserve.coinType), BigInt(new BigNumber(stepWithdrawnAmount
|
|
1515
|
+
const [stepWithdrawnCoin] = strategyWithdraw(strategyType, loopingDepositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(loopingDepositReserve.coinType), BigInt(new BigNumber(stepWithdrawnAmount
|
|
1467
1516
|
.times(10 ** loopingDepositReserve.token.decimals)
|
|
1468
1517
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
1469
1518
|
.toString())
|
|
@@ -1564,7 +1613,13 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1564
1613
|
stepWithdrawnAmount: stepWithdrawnAmount.toFixed(20),
|
|
1565
1614
|
isMaxWithdraw,
|
|
1566
1615
|
}, null, 2));
|
|
1567
|
-
|
|
1616
|
+
// `pendingBorrowedAmount` can fall below a single unit of base after
|
|
1617
|
+
// rounding down to the deposit coin's decimals, leaving
|
|
1618
|
+
// `stepWithdrawnAmount = 0`. Cetus returns "No swap quote found" for a
|
|
1619
|
+
// zero-amount quote — there's nothing meaningful left to unloop, so stop.
|
|
1620
|
+
if (stepWithdrawnAmount.lte(0))
|
|
1621
|
+
break;
|
|
1622
|
+
const [stepWithdrawnCoin] = strategyWithdraw(strategyType, loopingDepositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(loopingDepositReserve.coinType), BigInt(new BigNumber(stepWithdrawnAmount
|
|
1568
1623
|
.times(10 ** loopingDepositReserve.token.decimals)
|
|
1569
1624
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
1570
1625
|
.toString())
|
|
@@ -1621,7 +1676,14 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1621
1676
|
}, null, 2), routers);
|
|
1622
1677
|
// 3) Repay borrows
|
|
1623
1678
|
// 3.1) Repay
|
|
1624
|
-
|
|
1679
|
+
// Actual on-chain swap output can be up to `slippagePercent`% less than the
|
|
1680
|
+
// Cetus quote — track pessimistically so `borrowedAmount` stays ≥ real debt.
|
|
1681
|
+
// Otherwise per-step under-counting accumulates and the final
|
|
1682
|
+
// `fullyRepayBorrowsUsingBase` sizes off a near-zero tracked value, stranding
|
|
1683
|
+
// dust borrow that blocks the subsequent `MAX_U64` deposit withdraw.
|
|
1684
|
+
const stepRepaidAmount = new BigNumber(new BigNumber(routers.amountOut.toString())
|
|
1685
|
+
.times(1 - slippagePercent / 100)
|
|
1686
|
+
.div(10 ** borrowReserve.token.decimals)).decimalPlaces(borrowReserve.token.decimals, BigNumber.ROUND_DOWN);
|
|
1625
1687
|
const isMaxRepay = stepRepaidAmount.eq(stepMaxRepaidAmount);
|
|
1626
1688
|
console.log(`[unloopStrategyToExposure] ${i} repay_borrows.repay |`, JSON.stringify({
|
|
1627
1689
|
stepRepaidAmount: stepRepaidAmount.toFixed(20),
|
|
@@ -1705,7 +1767,7 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1705
1767
|
// 1.1.2) Stake SUI for LST
|
|
1706
1768
|
const lstCoin = lst.client.mint(transaction, suiCoin);
|
|
1707
1769
|
// 1.1.3) Deposit LST (1x exposure)
|
|
1708
|
-
strategyDeposit(lstCoin, depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), transaction);
|
|
1770
|
+
strategyDeposit(strategyType, lstCoin, depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), transaction);
|
|
1709
1771
|
// 1.1.4) Update state
|
|
1710
1772
|
deposits = addOrInsertStrategyDeposit(deposits, {
|
|
1711
1773
|
coinType: depositReserves.lst.coinType,
|
|
@@ -1715,16 +1777,12 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1715
1777
|
// 1.2) LST
|
|
1716
1778
|
else if (deposit.coinType === ((_c = depositReserves.lst) === null || _c === void 0 ? void 0 : _c.coinType)) {
|
|
1717
1779
|
// 1.2.1) Split coins
|
|
1718
|
-
const
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
.times(10 ** LST_DECIMALS)
|
|
1723
|
-
.integerValue(BigNumber.ROUND_DOWN)
|
|
1724
|
-
.toString()),
|
|
1725
|
-
]);
|
|
1780
|
+
const lstCoin = yield getSpendableCoin(suiClient, _address, depositReserves.lst.coinType, deposit.depositedAmount
|
|
1781
|
+
.times(10 ** LST_DECIMALS)
|
|
1782
|
+
.integerValue(BigNumber.ROUND_DOWN)
|
|
1783
|
+
.toString(), transaction);
|
|
1726
1784
|
// 1.2.2) Deposit LST (1x exposure)
|
|
1727
|
-
strategyDeposit(lstCoin, depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), transaction);
|
|
1785
|
+
strategyDeposit(strategyType, lstCoin, depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), transaction);
|
|
1728
1786
|
// 1.2.3) Update state
|
|
1729
1787
|
deposits = addOrInsertStrategyDeposit(deposits, deposit);
|
|
1730
1788
|
// 1.3) Other
|
|
@@ -1732,18 +1790,53 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1732
1790
|
else {
|
|
1733
1791
|
const otherReserve = reserveMap[deposit.coinType];
|
|
1734
1792
|
// 1.3.1) Split coins
|
|
1735
|
-
const
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1793
|
+
const otherCoin = yield getSpendableCoin(suiClient, _address, otherReserve.coinType, deposit.depositedAmount
|
|
1794
|
+
.times(10 ** otherReserve.token.decimals)
|
|
1795
|
+
.integerValue(BigNumber.ROUND_DOWN)
|
|
1796
|
+
.toString(), transaction);
|
|
1797
|
+
// 1.3.2) If the deposit coin is the same as the borrow coin, swap to base first
|
|
1798
|
+
if (deposit.coinType === borrowReserve.coinType && depositReserve) {
|
|
1799
|
+
const routers = yield cetusSdk.findRouters({
|
|
1800
|
+
from: otherReserve.coinType,
|
|
1801
|
+
target: depositReserve.coinType,
|
|
1802
|
+
amount: new BN(deposit.depositedAmount
|
|
1803
|
+
.times(10 ** otherReserve.token.decimals)
|
|
1804
|
+
.integerValue(BigNumber.ROUND_DOWN)
|
|
1805
|
+
.toString()),
|
|
1806
|
+
byAmountIn: true,
|
|
1807
|
+
splitCount: 0,
|
|
1808
|
+
});
|
|
1809
|
+
if (!routers)
|
|
1810
|
+
throw new Error("No swap quote found");
|
|
1811
|
+
const slippagePercent = 1;
|
|
1812
|
+
let baseCoin;
|
|
1813
|
+
try {
|
|
1814
|
+
baseCoin = (yield cetusSdk.fixableRouterSwapV3({
|
|
1815
|
+
router: routers,
|
|
1816
|
+
inputCoin: otherCoin,
|
|
1817
|
+
slippage: slippagePercent / 100,
|
|
1818
|
+
txb: transaction,
|
|
1819
|
+
partner: cetusPartnerId,
|
|
1820
|
+
}));
|
|
1821
|
+
}
|
|
1822
|
+
catch (err) {
|
|
1823
|
+
throw new Error("No swap quote found");
|
|
1824
|
+
}
|
|
1825
|
+
const swappedAmount = new BigNumber(routers.amountOut.toString())
|
|
1826
|
+
.div(10 ** depositReserve.token.decimals)
|
|
1827
|
+
.decimalPlaces(depositReserve.token.decimals, BigNumber.ROUND_DOWN);
|
|
1828
|
+
strategyDeposit(strategyType, baseCoin, depositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserve.coinType), transaction);
|
|
1829
|
+
deposits = addOrInsertStrategyDeposit(deposits, {
|
|
1830
|
+
coinType: depositReserve.coinType,
|
|
1831
|
+
depositedAmount: swappedAmount,
|
|
1832
|
+
});
|
|
1833
|
+
}
|
|
1834
|
+
else {
|
|
1835
|
+
// 1.3.3) Deposit other (1x exposure)
|
|
1836
|
+
strategyDeposit(strategyType, otherCoin, otherReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(otherReserve.coinType), transaction);
|
|
1837
|
+
// 1.3.4) Update state
|
|
1838
|
+
deposits = addOrInsertStrategyDeposit(deposits, deposit);
|
|
1839
|
+
}
|
|
1747
1840
|
}
|
|
1748
1841
|
console.log(`[deposit] deposit |`, JSON.stringify({
|
|
1749
1842
|
deposits: deposits.map((d) => ({
|
|
@@ -1885,7 +1978,7 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1885
1978
|
}
|
|
1886
1979
|
// 2) Withdraw base or LST
|
|
1887
1980
|
// 2.1) Withdraw
|
|
1888
|
-
const [withdrawnCoin] = strategyWithdraw(depositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserve.coinType), BigInt(new BigNumber(withdrawnAmount
|
|
1981
|
+
const [withdrawnCoin] = strategyWithdraw(strategyType, depositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserve.coinType), BigInt(new BigNumber(withdrawnAmount
|
|
1889
1982
|
.times(10 ** depositReserve.token.decimals)
|
|
1890
1983
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
1891
1984
|
.toString())
|
|
@@ -1916,8 +2009,38 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1916
2009
|
return { deposits, borrowedAmount, transaction, withdrawnCoin };
|
|
1917
2010
|
else {
|
|
1918
2011
|
if (depositReserve.coinType === ((_h = depositReserves.base) === null || _h === void 0 ? void 0 : _h.coinType)) {
|
|
1919
|
-
|
|
1920
|
-
|
|
2012
|
+
if (withdraw.coinType !== depositReserve.coinType) {
|
|
2013
|
+
const routers = yield cetusSdk.findRouters({
|
|
2014
|
+
from: depositReserve.coinType,
|
|
2015
|
+
target: withdraw.coinType,
|
|
2016
|
+
amount: new BN(withdrawnAmount
|
|
2017
|
+
.times(10 ** depositReserve.token.decimals)
|
|
2018
|
+
.integerValue(BigNumber.ROUND_DOWN)
|
|
2019
|
+
.toString()),
|
|
2020
|
+
byAmountIn: true,
|
|
2021
|
+
splitCount: 0,
|
|
2022
|
+
});
|
|
2023
|
+
if (!routers)
|
|
2024
|
+
throw new Error("No swap quote found");
|
|
2025
|
+
const slippagePercent = 1;
|
|
2026
|
+
let swappedCoin;
|
|
2027
|
+
try {
|
|
2028
|
+
swappedCoin = (yield cetusSdk.fixableRouterSwapV3({
|
|
2029
|
+
router: routers,
|
|
2030
|
+
inputCoin: withdrawnCoin,
|
|
2031
|
+
slippage: slippagePercent / 100,
|
|
2032
|
+
txb: transaction,
|
|
2033
|
+
partner: cetusPartnerId,
|
|
2034
|
+
}));
|
|
2035
|
+
}
|
|
2036
|
+
catch (err) {
|
|
2037
|
+
throw new Error("No swap quote found");
|
|
2038
|
+
}
|
|
2039
|
+
transaction.transferObjects([swappedCoin], _address);
|
|
2040
|
+
}
|
|
2041
|
+
else {
|
|
2042
|
+
transaction.transferObjects([withdrawnCoin], _address);
|
|
2043
|
+
}
|
|
1921
2044
|
}
|
|
1922
2045
|
else {
|
|
1923
2046
|
if (isSui(withdraw.coinType)) {
|
|
@@ -1936,10 +2059,10 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1936
2059
|
});
|
|
1937
2060
|
export const strategyMaxWithdrawTx = (
|
|
1938
2061
|
// AppContext
|
|
1939
|
-
reserveMap,
|
|
2062
|
+
reserveMap, rewardsMap,
|
|
1940
2063
|
// Strategy
|
|
1941
2064
|
lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, withdrawCoinType, transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1942
|
-
var _a, _b;
|
|
2065
|
+
var _a, _b, _c, _d;
|
|
1943
2066
|
const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
1944
2067
|
const lst = strategyInfo.depositLstCoinType !== undefined
|
|
1945
2068
|
? lstMap[strategyInfo.depositLstCoinType]
|
|
@@ -1982,7 +2105,8 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1982
2105
|
}, null, 2));
|
|
1983
2106
|
}
|
|
1984
2107
|
// 2) MAX withdraw base or LST
|
|
1985
|
-
const
|
|
2108
|
+
const estimatedWithdrawnAmount = (_c = (_b = deposits.find((d) => d.coinType === depositReserve.coinType)) === null || _b === void 0 ? void 0 : _b.depositedAmount) !== null && _c !== void 0 ? _c : new BigNumber(0);
|
|
2109
|
+
const [withdrawnCoin] = strategyWithdraw(strategyType, depositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserve.coinType), BigInt(MAX_U64.toString()), transaction);
|
|
1986
2110
|
// 2.2) Update state
|
|
1987
2111
|
deposits = [];
|
|
1988
2112
|
console.log(`[strategyMaxWithdraw] max_withdraw.update_state |`, JSON.stringify({
|
|
@@ -1993,9 +2117,39 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1993
2117
|
borrowedAmount: borrowedAmount.toFixed(20),
|
|
1994
2118
|
}, null, 2));
|
|
1995
2119
|
// 3) Transfer coin to user
|
|
1996
|
-
if (depositReserve.coinType === ((
|
|
1997
|
-
|
|
1998
|
-
|
|
2120
|
+
if (depositReserve.coinType === ((_d = depositReserves.base) === null || _d === void 0 ? void 0 : _d.coinType)) {
|
|
2121
|
+
if (withdrawCoinType !== depositReserve.coinType) {
|
|
2122
|
+
const routers = yield cetusSdk.findRouters({
|
|
2123
|
+
from: depositReserve.coinType,
|
|
2124
|
+
target: withdrawCoinType,
|
|
2125
|
+
amount: new BN(estimatedWithdrawnAmount
|
|
2126
|
+
.times(10 ** depositReserve.token.decimals)
|
|
2127
|
+
.integerValue(BigNumber.ROUND_DOWN)
|
|
2128
|
+
.toString()),
|
|
2129
|
+
byAmountIn: true,
|
|
2130
|
+
splitCount: 0,
|
|
2131
|
+
});
|
|
2132
|
+
if (!routers)
|
|
2133
|
+
throw new Error("No swap quote found");
|
|
2134
|
+
const slippagePercent = 1;
|
|
2135
|
+
let swappedCoin;
|
|
2136
|
+
try {
|
|
2137
|
+
swappedCoin = (yield cetusSdk.fixableRouterSwapV3({
|
|
2138
|
+
router: routers,
|
|
2139
|
+
inputCoin: withdrawnCoin,
|
|
2140
|
+
slippage: slippagePercent / 100,
|
|
2141
|
+
txb: transaction,
|
|
2142
|
+
partner: cetusPartnerId,
|
|
2143
|
+
}));
|
|
2144
|
+
}
|
|
2145
|
+
catch (err) {
|
|
2146
|
+
throw new Error("No swap quote found");
|
|
2147
|
+
}
|
|
2148
|
+
transaction.transferObjects([swappedCoin], _address);
|
|
2149
|
+
}
|
|
2150
|
+
else {
|
|
2151
|
+
transaction.transferObjects([withdrawnCoin], _address);
|
|
2152
|
+
}
|
|
1999
2153
|
}
|
|
2000
2154
|
else {
|
|
2001
2155
|
if (isSui(withdrawCoinType)) {
|
|
@@ -2009,14 +2163,13 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2009
2163
|
transaction.transferObjects([withdrawnCoin], _address);
|
|
2010
2164
|
}
|
|
2011
2165
|
}
|
|
2012
|
-
// 4) Claim rewards
|
|
2166
|
+
// 4) Claim rewards and transfer to user
|
|
2013
2167
|
if (hasClaimableRewards) {
|
|
2014
2168
|
try {
|
|
2015
|
-
const
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
transaction = txCopy;
|
|
2169
|
+
const mergedCoinsMap = strategyClaimRewardsAndMergeCoins(strategyType, rewardsMap, strategyOwnerCapId, transaction);
|
|
2170
|
+
for (const coin of Object.values(mergedCoinsMap)) {
|
|
2171
|
+
transaction.transferObjects([coin], _address);
|
|
2172
|
+
}
|
|
2020
2173
|
}
|
|
2021
2174
|
catch (err) {
|
|
2022
2175
|
// Don't block user if fails
|
|
@@ -2199,7 +2352,7 @@ export const strategyDepositAdjustWithdrawTx = (
|
|
|
2199
2352
|
reserveMap,
|
|
2200
2353
|
// Strategy
|
|
2201
2354
|
lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, flashLoanBorrowedAmount, transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
2202
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
2355
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
2203
2356
|
const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
2204
2357
|
const lst = strategyInfo.depositLstCoinType !== undefined
|
|
2205
2358
|
? lstMap[strategyInfo.depositLstCoinType]
|
|
@@ -2225,12 +2378,23 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2225
2378
|
let borrowedAmount = _borrowedAmount;
|
|
2226
2379
|
// 1) Flash loan base/LST
|
|
2227
2380
|
const flashLoanObj = STRATEGY_TYPE_FLASH_LOAN_OBJ_MAP[strategyType];
|
|
2228
|
-
|
|
2381
|
+
const flashLoanCoinType = flashLoanObj.borrowA
|
|
2382
|
+
? flashLoanObj.coinTypeA
|
|
2383
|
+
: flashLoanObj.coinTypeB;
|
|
2384
|
+
const flashLoanCoinReserve = (_b = reserveMap[flashLoanCoinType]) !== null && _b !== void 0 ? _b : depositReserve;
|
|
2385
|
+
const needsFlashLoanCoinSwap = flashLoanCoinType !== depositReserve.coinType;
|
|
2386
|
+
if (depositReserve.coinType === ((_c = depositReserves.lst) === null || _c === void 0 ? void 0 : _c.coinType)) {
|
|
2229
2387
|
// TODO: Account for LST mint fees
|
|
2230
2388
|
flashLoanBorrowedAmount = flashLoanBorrowedAmount
|
|
2231
|
-
.times((
|
|
2389
|
+
.times((_d = lst === null || lst === void 0 ? void 0 : lst.lstToSuiExchangeRate) !== null && _d !== void 0 ? _d : 1)
|
|
2232
2390
|
.decimalPlaces(SUI_DECIMALS, BigNumber.ROUND_UP);
|
|
2233
2391
|
}
|
|
2392
|
+
let flashLoanBorrowAmountForLoan = flashLoanBorrowedAmount;
|
|
2393
|
+
if (needsFlashLoanCoinSwap) {
|
|
2394
|
+
flashLoanBorrowAmountForLoan = flashLoanBorrowAmountForLoan
|
|
2395
|
+
.times(1.01) // Buffer for swap slippage
|
|
2396
|
+
.decimalPlaces(flashLoanCoinReserve.token.decimals, BigNumber.ROUND_UP);
|
|
2397
|
+
}
|
|
2234
2398
|
let borrowedBalanceA, borrowedBalanceB, receipt;
|
|
2235
2399
|
if (flashLoanObj.provider === StrategyFlashLoanProvider.MMT) {
|
|
2236
2400
|
[borrowedBalanceA, borrowedBalanceB, receipt] = transaction.moveCall({
|
|
@@ -2239,9 +2403,9 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2239
2403
|
arguments: [
|
|
2240
2404
|
transaction.object(flashLoanObj.poolId),
|
|
2241
2405
|
transaction.pure.u64(flashLoanObj.borrowA
|
|
2242
|
-
?
|
|
2406
|
+
? flashLoanBorrowAmountForLoan
|
|
2243
2407
|
.times(10 **
|
|
2244
|
-
(depositReserve.coinType === ((
|
|
2408
|
+
(depositReserve.coinType === ((_e = depositReserves.lst) === null || _e === void 0 ? void 0 : _e.coinType)
|
|
2245
2409
|
? SUI_DECIMALS
|
|
2246
2410
|
: depositReserve.token.decimals))
|
|
2247
2411
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
@@ -2249,11 +2413,11 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2249
2413
|
: 0),
|
|
2250
2414
|
transaction.pure.u64(flashLoanObj.borrowA
|
|
2251
2415
|
? 0
|
|
2252
|
-
:
|
|
2416
|
+
: flashLoanBorrowAmountForLoan
|
|
2253
2417
|
.times(10 **
|
|
2254
|
-
(depositReserve.coinType === ((
|
|
2418
|
+
(depositReserve.coinType === ((_f = depositReserves.lst) === null || _f === void 0 ? void 0 : _f.coinType)
|
|
2255
2419
|
? SUI_DECIMALS
|
|
2256
|
-
:
|
|
2420
|
+
: flashLoanCoinReserve.token.decimals))
|
|
2257
2421
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
2258
2422
|
.toString()),
|
|
2259
2423
|
transaction.object(MMT_VERSION_OBJECT_ID),
|
|
@@ -2266,9 +2430,9 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2266
2430
|
// 2) Deposit additional (to get back up to 100% health, so the user can then unloop back down to the max leverage shown in the UI)
|
|
2267
2431
|
// 2.1) Deposit
|
|
2268
2432
|
let depositedAmount = flashLoanBorrowedAmount;
|
|
2269
|
-
if (depositReserve.coinType === ((
|
|
2433
|
+
if (depositReserve.coinType === ((_g = depositReserves.lst) === null || _g === void 0 ? void 0 : _g.coinType))
|
|
2270
2434
|
depositedAmount = new BigNumber(depositedAmount.minus(getStrategyLstMintFee(lstMap, depositReserve.coinType, depositedAmount)))
|
|
2271
|
-
.times((
|
|
2435
|
+
.times((_h = lst === null || lst === void 0 ? void 0 : lst.suiToLstExchangeRate) !== null && _h !== void 0 ? _h : 1)
|
|
2272
2436
|
.decimalPlaces(depositReserve.token.decimals, BigNumber.ROUND_DOWN);
|
|
2273
2437
|
let flashLoanBorrowedCoin = transaction.moveCall({
|
|
2274
2438
|
target: "0x2::coin::from_balance",
|
|
@@ -2277,9 +2441,35 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2277
2441
|
],
|
|
2278
2442
|
arguments: [flashLoanObj.borrowA ? borrowedBalanceA : borrowedBalanceB],
|
|
2279
2443
|
});
|
|
2280
|
-
if (depositReserve.coinType === ((
|
|
2444
|
+
if (depositReserve.coinType === ((_j = depositReserves.lst) === null || _j === void 0 ? void 0 : _j.coinType))
|
|
2281
2445
|
flashLoanBorrowedCoin = lst.client.mint(transaction, flashLoanBorrowedCoin);
|
|
2282
|
-
|
|
2446
|
+
if (needsFlashLoanCoinSwap) {
|
|
2447
|
+
const depositRouters = yield cetusSdk.findRouters({
|
|
2448
|
+
from: flashLoanCoinType,
|
|
2449
|
+
target: depositReserve.coinType,
|
|
2450
|
+
amount: new BN(flashLoanBorrowAmountForLoan
|
|
2451
|
+
.times(10 ** flashLoanCoinReserve.token.decimals)
|
|
2452
|
+
.integerValue(BigNumber.ROUND_DOWN)
|
|
2453
|
+
.toString()),
|
|
2454
|
+
byAmountIn: true,
|
|
2455
|
+
splitCount: 0,
|
|
2456
|
+
});
|
|
2457
|
+
if (!depositRouters)
|
|
2458
|
+
throw new Error("No swap quote found");
|
|
2459
|
+
try {
|
|
2460
|
+
flashLoanBorrowedCoin = (yield cetusSdk.fixableRouterSwapV3({
|
|
2461
|
+
router: depositRouters,
|
|
2462
|
+
inputCoin: flashLoanBorrowedCoin,
|
|
2463
|
+
slippage: 1 / 100,
|
|
2464
|
+
txb: transaction,
|
|
2465
|
+
partner: cetusPartnerId,
|
|
2466
|
+
}));
|
|
2467
|
+
}
|
|
2468
|
+
catch (err) {
|
|
2469
|
+
throw new Error("No swap quote found");
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
strategyDeposit(strategyType, flashLoanBorrowedCoin, depositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserve.coinType), transaction);
|
|
2283
2473
|
// 2.2) Update state
|
|
2284
2474
|
deposits = addOrInsertStrategyDeposit(deposits, {
|
|
2285
2475
|
coinType: depositReserve.coinType,
|
|
@@ -2303,14 +2493,18 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2303
2493
|
const dryRunResults = yield dryRunTransaction(transaction);
|
|
2304
2494
|
const flashLoanRepayAmount = new BigNumber(bcs
|
|
2305
2495
|
.u64()
|
|
2306
|
-
.parse(new Uint8Array((
|
|
2307
|
-
.div(10 **
|
|
2308
|
-
.decimalPlaces(
|
|
2496
|
+
.parse(new Uint8Array((_o = (_m = (_l = (_k = dryRunResults.results) === null || _k === void 0 ? void 0 : _k.find((r, index) => index === receiptDebts.Result)) === null || _l === void 0 ? void 0 : _l.returnValues) === null || _m === void 0 ? void 0 : _m[flashLoanObj.borrowA ? 0 : 1][0]) !== null && _o !== void 0 ? _o : [0])))
|
|
2497
|
+
.div(10 ** flashLoanCoinReserve.token.decimals)
|
|
2498
|
+
.decimalPlaces(flashLoanCoinReserve.token.decimals, BigNumber.ROUND_UP);
|
|
2309
2499
|
// 4.1) Withdraw additional + fee
|
|
2310
2500
|
let withdrawnAmount = flashLoanRepayAmount;
|
|
2311
|
-
if (
|
|
2501
|
+
if (needsFlashLoanCoinSwap)
|
|
2502
|
+
withdrawnAmount = flashLoanRepayAmount
|
|
2503
|
+
.times(1.01) // Buffer for swap slippage
|
|
2504
|
+
.decimalPlaces(depositReserve.token.decimals, BigNumber.ROUND_UP);
|
|
2505
|
+
else if (depositReserve.coinType === ((_p = depositReserves.lst) === null || _p === void 0 ? void 0 : _p.coinType))
|
|
2312
2506
|
withdrawnAmount = withdrawnAmount
|
|
2313
|
-
.div(1 - +((
|
|
2507
|
+
.div(1 - +((_q = lst === null || lst === void 0 ? void 0 : lst.redeemFeePercent) !== null && _q !== void 0 ? _q : 0) / 100) // Potential rounding issue (max 1 MIST)
|
|
2314
2508
|
.decimalPlaces(depositReserve.token.decimals, BigNumber.ROUND_UP);
|
|
2315
2509
|
const { deposits: newDeposits2, borrowedAmount: newBorrowedAmount2, transaction: newTransaction2, withdrawnCoin, } = yield strategyWithdrawTx(reserveMap, lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, deposits, borrowedAmount, {
|
|
2316
2510
|
coinType: depositReserve.coinType,
|
|
@@ -2324,8 +2518,34 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2324
2518
|
transaction = newTransaction2;
|
|
2325
2519
|
// 4.3) Repay flash loan
|
|
2326
2520
|
let flashLoanRepayCoin = withdrawnCoin;
|
|
2327
|
-
if (depositReserve.coinType === ((
|
|
2521
|
+
if (depositReserve.coinType === ((_r = depositReserves.lst) === null || _r === void 0 ? void 0 : _r.coinType))
|
|
2328
2522
|
flashLoanRepayCoin = lst.client.redeem(transaction, flashLoanRepayCoin);
|
|
2523
|
+
if (needsFlashLoanCoinSwap) {
|
|
2524
|
+
const repayRouters = yield cetusSdk.findRouters({
|
|
2525
|
+
from: depositReserve.coinType,
|
|
2526
|
+
target: flashLoanCoinType,
|
|
2527
|
+
amount: new BN(withdrawnAmount
|
|
2528
|
+
.times(10 ** depositReserve.token.decimals)
|
|
2529
|
+
.integerValue(BigNumber.ROUND_DOWN)
|
|
2530
|
+
.toString()),
|
|
2531
|
+
byAmountIn: true,
|
|
2532
|
+
splitCount: 0,
|
|
2533
|
+
});
|
|
2534
|
+
if (!repayRouters)
|
|
2535
|
+
throw new Error("No swap quote found");
|
|
2536
|
+
try {
|
|
2537
|
+
flashLoanRepayCoin = (yield cetusSdk.fixableRouterSwapV3({
|
|
2538
|
+
router: repayRouters,
|
|
2539
|
+
inputCoin: flashLoanRepayCoin,
|
|
2540
|
+
slippage: 1 / 100,
|
|
2541
|
+
txb: transaction,
|
|
2542
|
+
partner: cetusPartnerId,
|
|
2543
|
+
}));
|
|
2544
|
+
}
|
|
2545
|
+
catch (err) {
|
|
2546
|
+
throw new Error("No swap quote found");
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2329
2549
|
const flashLoanRepayBalance = transaction.moveCall({
|
|
2330
2550
|
target: "0x2::coin::into_balance",
|
|
2331
2551
|
typeArguments: [
|