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