@suilend/sdk 2.0.4 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_generated/_dependencies/source/0x1/ascii/structs.d.ts +7 -11
- package/_generated/_dependencies/source/0x1/ascii/structs.js +6 -63
- package/_generated/_dependencies/source/0x1/option/structs.d.ts +3 -9
- package/_generated/_dependencies/source/0x1/option/structs.js +4 -42
- package/_generated/_dependencies/source/0x1/type-name/structs.d.ts +5 -7
- package/_generated/_dependencies/source/0x1/type-name/structs.js +3 -32
- package/_generated/_dependencies/source/0x2/bag/structs.d.ts +7 -9
- package/_generated/_dependencies/source/0x2/bag/structs.js +3 -31
- package/_generated/_dependencies/source/0x2/balance/structs.d.ts +7 -11
- package/_generated/_dependencies/source/0x2/balance/structs.js +7 -82
- package/_generated/_dependencies/source/0x2/object/structs.d.ts +8 -12
- package/_generated/_dependencies/source/0x2/object/structs.js +7 -61
- package/_generated/_dependencies/source/0x2/object-table/structs.d.ts +7 -9
- package/_generated/_dependencies/source/0x2/object-table/structs.js +4 -44
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/i64/structs.d.ts +5 -7
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/i64/structs.js +3 -31
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price/structs.d.ts +11 -13
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price/structs.js +3 -32
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-feed/structs.d.ts +23 -25
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-feed/structs.js +3 -32
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-identifier/structs.d.ts +4 -6
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-identifier/structs.js +3 -33
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-info/structs.d.ts +55 -59
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-info/structs.js +6 -64
- package/_generated/_framework/reified.d.ts +2 -4
- package/_generated/_framework/vector.d.ts +2 -12
- package/_generated/suilend/cell/structs.d.ts +4 -10
- package/_generated/suilend/cell/structs.js +4 -42
- package/_generated/suilend/decimal/structs.d.ts +4 -6
- package/_generated/suilend/decimal/structs.js +3 -32
- package/_generated/suilend/lending-market/structs.d.ts +152 -392
- package/_generated/suilend/lending-market/structs.js +50 -548
- package/_generated/suilend/liquidity-mining/structs.d.ts +50 -158
- package/_generated/suilend/liquidity-mining/structs.js +16 -169
- package/_generated/suilend/obligation/structs.d.ts +108 -148
- package/_generated/suilend/obligation/structs.js +23 -232
- package/_generated/suilend/rate-limiter/structs.d.ts +15 -19
- package/_generated/suilend/rate-limiter/structs.js +6 -64
- package/_generated/suilend/reserve/structs.d.ts +138 -362
- package/_generated/suilend/reserve/structs.js +29 -327
- package/_generated/suilend/reserve-config/structs.d.ts +33 -37
- package/_generated/suilend/reserve-config/structs.js +6 -65
- package/client.d.ts +8 -8
- package/client.js +55 -88
- package/lib/initialize.d.ts +29 -28
- package/lib/initialize.js +16 -12
- package/lib/liquidityMining.d.ts +3 -3
- package/lib/pythAdapter.d.ts +9 -0
- package/lib/pythAdapter.js +121 -0
- package/lib/strategyOwnerCap.d.ts +12 -7
- package/lib/strategyOwnerCap.js +159 -156
- package/margin/margin/admin_cap.d.ts +2 -2
- package/margin/margin/deps/std/type_name.d.ts +1 -1
- package/margin/margin/deps/sui/vec_set.d.ts +3 -5
- package/margin/margin/deps/suilend/lending_market.d.ts +2 -2
- package/margin/margin/market.d.ts +21 -38
- package/margin/margin/position.d.ts +47 -47
- package/margin/margin/router.d.ts +5 -5
- package/margin/margin/version.d.ts +1 -1
- package/package.json +1 -1
- package/parsers/lendingMarket.d.ts +6 -6
- package/parsers/obligation.d.ts +8 -8
- package/parsers/reserve.d.ts +8 -8
- package/strategies.d.ts +38 -21
- package/strategies.js +239 -79
- package/swap/quote.d.ts +1 -9
- package/swap/quote.js +1 -52
- package/swap/transaction.d.ts +2 -4
- package/swap/transaction.js +9 -25
- package/utils/events.d.ts +6 -5
- package/utils/events.js +11 -8
- package/utils/obligation.d.ts +6 -5
- package/utils/obligation.js +118 -117
package/strategies.js
CHANGED
|
@@ -17,7 +17,7 @@ import { LstClient, SPRING_SUI_UPGRADE_CAP_ID, getLatestPackageId as getLatestSp
|
|
|
17
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, getAllCoins, isSui, mergeAllCoins, } 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,15 +35,23 @@ 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
|
+
provider: StrategyFlashLoanProvider.MMT,
|
|
48
|
+
poolId: "0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9", // suiUSDT-USDC 0.001% https://app.mmt.finance/liquidity/0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9
|
|
49
|
+
coinTypeA: NORMALIZED_suiUSDT_COINTYPE,
|
|
50
|
+
coinTypeB: NORMALIZED_USDC_COINTYPE,
|
|
51
|
+
borrowA: false,
|
|
52
|
+
feePercent: 0.001,
|
|
53
|
+
},
|
|
54
|
+
[StrategyType.eEARN_USDC_LOOPING]: {
|
|
47
55
|
provider: StrategyFlashLoanProvider.MMT,
|
|
48
56
|
poolId: "0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9", // suiUSDT-USDC 0.001% https://app.mmt.finance/liquidity/0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9
|
|
49
57
|
coinTypeA: NORMALIZED_suiUSDT_COINTYPE,
|
|
@@ -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,8 +158,11 @@ export const hasStrategyPosition = (obligation) => obligation.deposits.length >
|
|
|
133
158
|
// SUI
|
|
134
159
|
export const getStrategySuiReserve = (
|
|
135
160
|
// AppContext
|
|
136
|
-
reserveMap) =>
|
|
137
|
-
|
|
161
|
+
reserveMap) => {
|
|
162
|
+
var _a;
|
|
163
|
+
return (_a = reserveMap[NORMALIZED_SUI_COINTYPE]) !== null && _a !== void 0 ? _a : { price: new BigNumber(1) };
|
|
164
|
+
};
|
|
165
|
+
export const fetchStrategyLstMap = (suiGrpcClient) => __awaiter(void 0, void 0, void 0, function* () {
|
|
138
166
|
try {
|
|
139
167
|
const lstCoinTypes = Array.from(new Set([
|
|
140
168
|
...Object.values(STRATEGY_TYPE_INFO_MAP)
|
|
@@ -143,7 +171,7 @@ export const fetchStrategyLstMap = (suiClient) => __awaiter(void 0, void 0, void
|
|
|
143
171
|
// LSTs that will be/are/have been used as rewards
|
|
144
172
|
NORMALIZED_sSUI_COINTYPE,
|
|
145
173
|
]));
|
|
146
|
-
const publishedAt = yield getLatestSpringSuiPackageId(
|
|
174
|
+
const publishedAt = yield getLatestSpringSuiPackageId(suiGrpcClient, SPRING_SUI_UPGRADE_CAP_ID);
|
|
147
175
|
const lstInfoUrl = `${API_URL}/springsui/lst-info?${new URLSearchParams({
|
|
148
176
|
coinTypes: lstCoinTypes.join(","),
|
|
149
177
|
})}`;
|
|
@@ -157,7 +185,7 @@ export const fetchStrategyLstMap = (suiClient) => __awaiter(void 0, void 0, void
|
|
|
157
185
|
const result = Object.fromEntries(yield Promise.all(lstCoinTypes.map((lstCoinType) => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
186
|
var _a, _b, _c, _d;
|
|
159
187
|
const lstInfo = lstInfoMap[lstCoinType];
|
|
160
|
-
const lstClient = yield LstClient.initialize(
|
|
188
|
+
const lstClient = yield LstClient.initialize(suiGrpcClient, lstInfo.LIQUID_STAKING_INFO, publishedAt);
|
|
161
189
|
const mintFeePercent = new BigNumber((_b = (_a = lstInfo.liquidStakingInfo.feeConfig.element) === null || _a === void 0 ? void 0 : _a.suiMintFeeBps.toString()) !== null && _b !== void 0 ? _b : 0).div(100);
|
|
162
190
|
const redeemFeePercent = new BigNumber((_d = (_c = lstInfo.liquidStakingInfo.feeConfig.element) === null || _c === void 0 ? void 0 : _c.redeemFeeBps.toString()) !== null && _d !== void 0 ? _d : 0).div(100);
|
|
163
191
|
const res = yield fetch(`${API_URL}/springsui/historical-rates?coinType=${lstCoinType}×tamps=${Math.floor(Date.now() / 1000)}`);
|
|
@@ -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;
|
|
@@ -832,7 +876,7 @@ export const strategyLoopToExposureTx = (
|
|
|
832
876
|
// AppContext
|
|
833
877
|
reserveMap,
|
|
834
878
|
// Strategy
|
|
835
|
-
lstMap, strategyType,
|
|
879
|
+
lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, _targetBorrowedAmount, _targetExposure, // Must be defined if _targetBorrowedAmount is undefined
|
|
836
880
|
transaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
837
881
|
var _a, _b, _c, _d, _e;
|
|
838
882
|
const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
@@ -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,
|
|
@@ -1069,7 +1117,7 @@ export const strategyUnloopToExposureTx = (
|
|
|
1069
1117
|
// AppContext
|
|
1070
1118
|
reserveMap,
|
|
1071
1119
|
// Strategy
|
|
1072
|
-
lstMap, strategyType,
|
|
1120
|
+
lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, _targetBorrowedAmount, _targetExposure, // Must be defined if _targetBorrowedAmount is undefined
|
|
1073
1121
|
transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1074
1122
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
1075
1123
|
const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
@@ -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),
|
|
@@ -1659,7 +1720,7 @@ export const strategyDepositTx = (
|
|
|
1659
1720
|
// AppContext
|
|
1660
1721
|
reserveMap,
|
|
1661
1722
|
// Strategy
|
|
1662
|
-
lstMap, strategyType,
|
|
1723
|
+
lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, deposit, transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1663
1724
|
var _a, _b, _c;
|
|
1664
1725
|
const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
1665
1726
|
const lst = strategyInfo.depositLstCoinType !== undefined
|
|
@@ -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,16 @@ 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 allCoinsLst = yield getAllCoins(
|
|
1779
|
+
const allCoinsLst = yield getAllCoins(suiGrpcClient, _address, depositReserves.lst.coinType);
|
|
1719
1780
|
const mergeCoinLst = mergeAllCoins(depositReserves.lst.coinType, transaction, allCoinsLst);
|
|
1720
|
-
const lstCoin = transaction.splitCoins(transaction.object(mergeCoinLst.
|
|
1781
|
+
const lstCoin = transaction.splitCoins(transaction.object(mergeCoinLst.objectId), [
|
|
1721
1782
|
BigInt(deposit.depositedAmount
|
|
1722
1783
|
.times(10 ** LST_DECIMALS)
|
|
1723
1784
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
1724
1785
|
.toString()),
|
|
1725
1786
|
]);
|
|
1726
1787
|
// 1.2.2) Deposit LST (1x exposure)
|
|
1727
|
-
strategyDeposit(lstCoin, depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), transaction);
|
|
1788
|
+
strategyDeposit(strategyType, lstCoin, depositReserves.lst.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.lst.coinType), transaction);
|
|
1728
1789
|
// 1.2.3) Update state
|
|
1729
1790
|
deposits = addOrInsertStrategyDeposit(deposits, deposit);
|
|
1730
1791
|
// 1.3) Other
|
|
@@ -1732,18 +1793,57 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1732
1793
|
else {
|
|
1733
1794
|
const otherReserve = reserveMap[deposit.coinType];
|
|
1734
1795
|
// 1.3.1) Split coins
|
|
1735
|
-
const allCoinsOther = yield getAllCoins(
|
|
1796
|
+
const allCoinsOther = yield getAllCoins(suiGrpcClient, _address, otherReserve.coinType);
|
|
1736
1797
|
const mergeCoinOther = mergeAllCoins(otherReserve.coinType, transaction, allCoinsOther);
|
|
1737
|
-
const otherCoin = transaction.splitCoins(transaction.object(mergeCoinOther.
|
|
1798
|
+
const otherCoin = transaction.splitCoins(transaction.object(mergeCoinOther.objectId), [
|
|
1738
1799
|
BigInt(deposit.depositedAmount
|
|
1739
1800
|
.times(10 ** otherReserve.token.decimals)
|
|
1740
1801
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
1741
1802
|
.toString()),
|
|
1742
1803
|
]);
|
|
1743
|
-
// 1.3.2)
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1804
|
+
// 1.3.2) If the deposit coin is the same as the borrow coin, swap to base first
|
|
1805
|
+
if (deposit.coinType === borrowReserve.coinType && depositReserve) {
|
|
1806
|
+
const routers = yield cetusSdk.findRouters({
|
|
1807
|
+
from: otherReserve.coinType,
|
|
1808
|
+
target: depositReserve.coinType,
|
|
1809
|
+
amount: new BN(deposit.depositedAmount
|
|
1810
|
+
.times(10 ** otherReserve.token.decimals)
|
|
1811
|
+
.integerValue(BigNumber.ROUND_DOWN)
|
|
1812
|
+
.toString()),
|
|
1813
|
+
byAmountIn: true,
|
|
1814
|
+
splitCount: 0,
|
|
1815
|
+
});
|
|
1816
|
+
if (!routers)
|
|
1817
|
+
throw new Error("No swap quote found");
|
|
1818
|
+
const slippagePercent = 1;
|
|
1819
|
+
let baseCoin;
|
|
1820
|
+
try {
|
|
1821
|
+
baseCoin = (yield cetusSdk.fixableRouterSwapV3({
|
|
1822
|
+
router: routers,
|
|
1823
|
+
inputCoin: otherCoin,
|
|
1824
|
+
slippage: slippagePercent / 100,
|
|
1825
|
+
txb: transaction,
|
|
1826
|
+
partner: cetusPartnerId,
|
|
1827
|
+
}));
|
|
1828
|
+
}
|
|
1829
|
+
catch (err) {
|
|
1830
|
+
throw new Error("No swap quote found");
|
|
1831
|
+
}
|
|
1832
|
+
const swappedAmount = new BigNumber(routers.amountOut.toString())
|
|
1833
|
+
.div(10 ** depositReserve.token.decimals)
|
|
1834
|
+
.decimalPlaces(depositReserve.token.decimals, BigNumber.ROUND_DOWN);
|
|
1835
|
+
strategyDeposit(strategyType, baseCoin, depositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserve.coinType), transaction);
|
|
1836
|
+
deposits = addOrInsertStrategyDeposit(deposits, {
|
|
1837
|
+
coinType: depositReserve.coinType,
|
|
1838
|
+
depositedAmount: swappedAmount,
|
|
1839
|
+
});
|
|
1840
|
+
}
|
|
1841
|
+
else {
|
|
1842
|
+
// 1.3.3) Deposit other (1x exposure)
|
|
1843
|
+
strategyDeposit(strategyType, otherCoin, otherReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(otherReserve.coinType), transaction);
|
|
1844
|
+
// 1.3.4) Update state
|
|
1845
|
+
deposits = addOrInsertStrategyDeposit(deposits, deposit);
|
|
1846
|
+
}
|
|
1747
1847
|
}
|
|
1748
1848
|
console.log(`[deposit] deposit |`, JSON.stringify({
|
|
1749
1849
|
deposits: deposits.map((d) => ({
|
|
@@ -1758,7 +1858,7 @@ export const strategyDepositAndLoopToExposureTx = (
|
|
|
1758
1858
|
// AppContext
|
|
1759
1859
|
reserveMap,
|
|
1760
1860
|
// Strategy
|
|
1761
|
-
lstMap, strategyType,
|
|
1861
|
+
lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, deposit, targetExposure, transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1762
1862
|
const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
1763
1863
|
const lst = strategyInfo.depositLstCoinType !== undefined
|
|
1764
1864
|
? lstMap[strategyInfo.depositLstCoinType]
|
|
@@ -1786,7 +1886,7 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1786
1886
|
let borrowedAmount = _borrowedAmount;
|
|
1787
1887
|
// 1) Deposit (1x exposure)
|
|
1788
1888
|
// 1.1) Deposit
|
|
1789
|
-
const { deposits: newDeposits, borrowedAmount: newBorrowedAmount, transaction: newTransaction, } = yield strategyDepositTx(reserveMap, lstMap, strategyType,
|
|
1889
|
+
const { deposits: newDeposits, borrowedAmount: newBorrowedAmount, transaction: newTransaction, } = yield strategyDepositTx(reserveMap, lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, deposits, borrowedAmount, deposit, transaction, dryRunTransaction);
|
|
1790
1890
|
// 1.2) Update state
|
|
1791
1891
|
deposits = newDeposits;
|
|
1792
1892
|
borrowedAmount = newBorrowedAmount;
|
|
@@ -1794,7 +1894,7 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1794
1894
|
if (targetExposure.gt(1)) {
|
|
1795
1895
|
// 2) Loop to target exposure
|
|
1796
1896
|
// 2.1) Loop
|
|
1797
|
-
const { deposits: newDeposits2, borrowedAmount: newBorrowedAmount2, transaction: newTransaction2, } = yield strategyLoopToExposureTx(reserveMap, lstMap, strategyType,
|
|
1897
|
+
const { deposits: newDeposits2, borrowedAmount: newBorrowedAmount2, transaction: newTransaction2, } = yield strategyLoopToExposureTx(reserveMap, lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, deposits, borrowedAmount, undefined, // Don't pass targetBorrowedAmount
|
|
1798
1898
|
targetExposure, // Pass targetExposure
|
|
1799
1899
|
transaction);
|
|
1800
1900
|
// 2.2) Update state
|
|
@@ -1808,7 +1908,7 @@ export const strategyWithdrawTx = (
|
|
|
1808
1908
|
// AppContext
|
|
1809
1909
|
reserveMap,
|
|
1810
1910
|
// Strategy
|
|
1811
|
-
lstMap, strategyType,
|
|
1911
|
+
lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, withdraw, transaction, dryRunTransaction, returnWithdrawnCoin) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1812
1912
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1813
1913
|
const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
1814
1914
|
const lst = strategyInfo.depositLstCoinType !== undefined
|
|
@@ -1867,7 +1967,7 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1867
1967
|
// 1) Unloop to targetBorrowedAmount borrows
|
|
1868
1968
|
// 1.1) Unloop
|
|
1869
1969
|
if (borrowedAmount.gt(targetBorrowedAmount)) {
|
|
1870
|
-
const { deposits: newDeposits, borrowedAmount: newBorrowedAmount, transaction: newTransaction, } = yield strategyUnloopToExposureTx(reserveMap, lstMap, strategyType,
|
|
1970
|
+
const { deposits: newDeposits, borrowedAmount: newBorrowedAmount, transaction: newTransaction, } = yield strategyUnloopToExposureTx(reserveMap, lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, deposits, borrowedAmount, targetBorrowedAmount, // Pass targetBorrowedAmount
|
|
1871
1971
|
undefined, // Don't pass targetExposure
|
|
1872
1972
|
transaction, dryRunTransaction);
|
|
1873
1973
|
// 1.2) Update state
|
|
@@ -1885,7 +1985,7 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1885
1985
|
}
|
|
1886
1986
|
// 2) Withdraw base or LST
|
|
1887
1987
|
// 2.1) Withdraw
|
|
1888
|
-
const [withdrawnCoin] = strategyWithdraw(depositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserve.coinType), BigInt(new BigNumber(withdrawnAmount
|
|
1988
|
+
const [withdrawnCoin] = strategyWithdraw(strategyType, depositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserve.coinType), BigInt(new BigNumber(withdrawnAmount
|
|
1889
1989
|
.times(10 ** depositReserve.token.decimals)
|
|
1890
1990
|
.integerValue(BigNumber.ROUND_DOWN)
|
|
1891
1991
|
.toString())
|
|
@@ -1916,8 +2016,38 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1916
2016
|
return { deposits, borrowedAmount, transaction, withdrawnCoin };
|
|
1917
2017
|
else {
|
|
1918
2018
|
if (depositReserve.coinType === ((_h = depositReserves.base) === null || _h === void 0 ? void 0 : _h.coinType)) {
|
|
1919
|
-
|
|
1920
|
-
|
|
2019
|
+
if (withdraw.coinType !== depositReserve.coinType) {
|
|
2020
|
+
const routers = yield cetusSdk.findRouters({
|
|
2021
|
+
from: depositReserve.coinType,
|
|
2022
|
+
target: withdraw.coinType,
|
|
2023
|
+
amount: new BN(withdrawnAmount
|
|
2024
|
+
.times(10 ** depositReserve.token.decimals)
|
|
2025
|
+
.integerValue(BigNumber.ROUND_DOWN)
|
|
2026
|
+
.toString()),
|
|
2027
|
+
byAmountIn: true,
|
|
2028
|
+
splitCount: 0,
|
|
2029
|
+
});
|
|
2030
|
+
if (!routers)
|
|
2031
|
+
throw new Error("No swap quote found");
|
|
2032
|
+
const slippagePercent = 1;
|
|
2033
|
+
let swappedCoin;
|
|
2034
|
+
try {
|
|
2035
|
+
swappedCoin = (yield cetusSdk.fixableRouterSwapV3({
|
|
2036
|
+
router: routers,
|
|
2037
|
+
inputCoin: withdrawnCoin,
|
|
2038
|
+
slippage: slippagePercent / 100,
|
|
2039
|
+
txb: transaction,
|
|
2040
|
+
partner: cetusPartnerId,
|
|
2041
|
+
}));
|
|
2042
|
+
}
|
|
2043
|
+
catch (err) {
|
|
2044
|
+
throw new Error("No swap quote found");
|
|
2045
|
+
}
|
|
2046
|
+
transaction.transferObjects([swappedCoin], _address);
|
|
2047
|
+
}
|
|
2048
|
+
else {
|
|
2049
|
+
transaction.transferObjects([withdrawnCoin], _address);
|
|
2050
|
+
}
|
|
1921
2051
|
}
|
|
1922
2052
|
else {
|
|
1923
2053
|
if (isSui(withdraw.coinType)) {
|
|
@@ -1936,10 +2066,10 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1936
2066
|
});
|
|
1937
2067
|
export const strategyMaxWithdrawTx = (
|
|
1938
2068
|
// AppContext
|
|
1939
|
-
reserveMap,
|
|
2069
|
+
reserveMap, rewardsMap,
|
|
1940
2070
|
// Strategy
|
|
1941
|
-
lstMap, strategyType,
|
|
1942
|
-
var _a, _b;
|
|
2071
|
+
lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, withdrawCoinType, transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
2072
|
+
var _a, _b, _c, _d;
|
|
1943
2073
|
const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
1944
2074
|
const lst = strategyInfo.depositLstCoinType !== undefined
|
|
1945
2075
|
? lstMap[strategyInfo.depositLstCoinType]
|
|
@@ -1966,7 +2096,7 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1966
2096
|
// 1) Unloop to 1x (base+LST: no LST and no borrows, LST: no borrows)
|
|
1967
2097
|
if (borrowedAmount.gt(0)) {
|
|
1968
2098
|
// 1.1) Unloop
|
|
1969
|
-
const { deposits: newDeposits, borrowedAmount: newBorrowedAmount, transaction: newTransaction, } = yield strategyUnloopToExposureTx(reserveMap, lstMap, strategyType,
|
|
2099
|
+
const { deposits: newDeposits, borrowedAmount: newBorrowedAmount, transaction: newTransaction, } = yield strategyUnloopToExposureTx(reserveMap, lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, deposits, borrowedAmount, undefined, // Don't pass targetBorrowedAmount
|
|
1970
2100
|
new BigNumber(1), // Pass targetExposure
|
|
1971
2101
|
transaction, dryRunTransaction);
|
|
1972
2102
|
// 1.2) Update state
|
|
@@ -1982,7 +2112,8 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1982
2112
|
}, null, 2));
|
|
1983
2113
|
}
|
|
1984
2114
|
// 2) MAX withdraw base or LST
|
|
1985
|
-
const
|
|
2115
|
+
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);
|
|
2116
|
+
const [withdrawnCoin] = strategyWithdraw(strategyType, depositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserve.coinType), BigInt(MAX_U64.toString()), transaction);
|
|
1986
2117
|
// 2.2) Update state
|
|
1987
2118
|
deposits = [];
|
|
1988
2119
|
console.log(`[strategyMaxWithdraw] max_withdraw.update_state |`, JSON.stringify({
|
|
@@ -1993,9 +2124,39 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
1993
2124
|
borrowedAmount: borrowedAmount.toFixed(20),
|
|
1994
2125
|
}, null, 2));
|
|
1995
2126
|
// 3) Transfer coin to user
|
|
1996
|
-
if (depositReserve.coinType === ((
|
|
1997
|
-
|
|
1998
|
-
|
|
2127
|
+
if (depositReserve.coinType === ((_d = depositReserves.base) === null || _d === void 0 ? void 0 : _d.coinType)) {
|
|
2128
|
+
if (withdrawCoinType !== depositReserve.coinType) {
|
|
2129
|
+
const routers = yield cetusSdk.findRouters({
|
|
2130
|
+
from: depositReserve.coinType,
|
|
2131
|
+
target: withdrawCoinType,
|
|
2132
|
+
amount: new BN(estimatedWithdrawnAmount
|
|
2133
|
+
.times(10 ** depositReserve.token.decimals)
|
|
2134
|
+
.integerValue(BigNumber.ROUND_DOWN)
|
|
2135
|
+
.toString()),
|
|
2136
|
+
byAmountIn: true,
|
|
2137
|
+
splitCount: 0,
|
|
2138
|
+
});
|
|
2139
|
+
if (!routers)
|
|
2140
|
+
throw new Error("No swap quote found");
|
|
2141
|
+
const slippagePercent = 1;
|
|
2142
|
+
let swappedCoin;
|
|
2143
|
+
try {
|
|
2144
|
+
swappedCoin = (yield cetusSdk.fixableRouterSwapV3({
|
|
2145
|
+
router: routers,
|
|
2146
|
+
inputCoin: withdrawnCoin,
|
|
2147
|
+
slippage: slippagePercent / 100,
|
|
2148
|
+
txb: transaction,
|
|
2149
|
+
partner: cetusPartnerId,
|
|
2150
|
+
}));
|
|
2151
|
+
}
|
|
2152
|
+
catch (err) {
|
|
2153
|
+
throw new Error("No swap quote found");
|
|
2154
|
+
}
|
|
2155
|
+
transaction.transferObjects([swappedCoin], _address);
|
|
2156
|
+
}
|
|
2157
|
+
else {
|
|
2158
|
+
transaction.transferObjects([withdrawnCoin], _address);
|
|
2159
|
+
}
|
|
1999
2160
|
}
|
|
2000
2161
|
else {
|
|
2001
2162
|
if (isSui(withdrawCoinType)) {
|
|
@@ -2009,14 +2170,13 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2009
2170
|
transaction.transferObjects([withdrawnCoin], _address);
|
|
2010
2171
|
}
|
|
2011
2172
|
}
|
|
2012
|
-
// 4) Claim rewards
|
|
2173
|
+
// 4) Claim rewards and transfer to user
|
|
2013
2174
|
if (hasClaimableRewards) {
|
|
2014
2175
|
try {
|
|
2015
|
-
const
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
transaction = txCopy;
|
|
2176
|
+
const mergedCoinsMap = strategyClaimRewardsAndMergeCoins(strategyType, rewardsMap, strategyOwnerCapId, transaction);
|
|
2177
|
+
for (const coin of Object.values(mergedCoinsMap)) {
|
|
2178
|
+
transaction.transferObjects([coin], _address);
|
|
2179
|
+
}
|
|
2020
2180
|
}
|
|
2021
2181
|
catch (err) {
|
|
2022
2182
|
// Don't block user if fails
|
|
@@ -2029,8 +2189,8 @@ export const strategyAdjustRepayTx = (
|
|
|
2029
2189
|
// AppContext
|
|
2030
2190
|
reserveMap,
|
|
2031
2191
|
// Strategy
|
|
2032
|
-
lstMap, strategyType,
|
|
2033
|
-
var _a, _b, _c, _d;
|
|
2192
|
+
lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, flashLoanBorrowedAmount, transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
2193
|
+
var _a, _b, _c, _d, _e;
|
|
2034
2194
|
const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
2035
2195
|
const lst = strategyInfo.depositLstCoinType !== undefined
|
|
2036
2196
|
? lstMap[strategyInfo.depositLstCoinType]
|
|
@@ -2152,12 +2312,12 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2152
2312
|
const dryRunResults = yield dryRunTransaction(transaction);
|
|
2153
2313
|
const flashLoanRepayAmount = new BigNumber(bcs
|
|
2154
2314
|
.u64()
|
|
2155
|
-
.parse(
|
|
2315
|
+
.parse((_e = (_d = (_c = (_b = (_a = dryRunResults.commandResults) === null || _a === void 0 ? void 0 : _a[receiptDebts.Result]) === null || _b === void 0 ? void 0 : _b.returnValues) === null || _c === void 0 ? void 0 : _c[flashLoanObj.borrowA ? 0 : 1]) === null || _d === void 0 ? void 0 : _d.bcs) !== null && _e !== void 0 ? _e : new Uint8Array([0])))
|
|
2156
2316
|
.div(10 ** depositReserves.base.token.decimals)
|
|
2157
2317
|
.decimalPlaces(depositReserves.base.token.decimals, BigNumber.ROUND_UP);
|
|
2158
2318
|
// 5.1) Withdraw base + fee
|
|
2159
2319
|
const withdrawnAmount = flashLoanRepayAmount;
|
|
2160
|
-
const { deposits: newDeposits2, borrowedAmount: newBorrowedAmount2, transaction: newTransaction2, withdrawnCoin, } = yield strategyWithdrawTx(reserveMap, lstMap, strategyType,
|
|
2320
|
+
const { deposits: newDeposits2, borrowedAmount: newBorrowedAmount2, transaction: newTransaction2, withdrawnCoin, } = yield strategyWithdrawTx(reserveMap, lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, deposits, borrowedAmount, {
|
|
2161
2321
|
coinType: depositReserves.base.coinType,
|
|
2162
2322
|
withdrawnAmount,
|
|
2163
2323
|
}, transaction, dryRunTransaction, true);
|
|
@@ -2198,8 +2358,8 @@ export const strategyDepositAdjustWithdrawTx = (
|
|
|
2198
2358
|
// AppContext
|
|
2199
2359
|
reserveMap,
|
|
2200
2360
|
// Strategy
|
|
2201
|
-
lstMap, strategyType,
|
|
2202
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
2361
|
+
lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, flashLoanBorrowedAmount, transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
2362
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
2203
2363
|
const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
2204
2364
|
const lst = strategyInfo.depositLstCoinType !== undefined
|
|
2205
2365
|
? lstMap[strategyInfo.depositLstCoinType]
|
|
@@ -2279,7 +2439,7 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2279
2439
|
});
|
|
2280
2440
|
if (depositReserve.coinType === ((_h = depositReserves.lst) === null || _h === void 0 ? void 0 : _h.coinType))
|
|
2281
2441
|
flashLoanBorrowedCoin = lst.client.mint(transaction, flashLoanBorrowedCoin);
|
|
2282
|
-
strategyDeposit(flashLoanBorrowedCoin, depositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserve.coinType), transaction);
|
|
2442
|
+
strategyDeposit(strategyType, flashLoanBorrowedCoin, depositReserve.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserve.coinType), transaction);
|
|
2283
2443
|
// 2.2) Update state
|
|
2284
2444
|
deposits = addOrInsertStrategyDeposit(deposits, {
|
|
2285
2445
|
coinType: depositReserve.coinType,
|
|
@@ -2287,7 +2447,7 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2287
2447
|
});
|
|
2288
2448
|
// 3) Unloop to max exposure
|
|
2289
2449
|
// 3.1) Unloop
|
|
2290
|
-
const { deposits: newDeposits, borrowedAmount: newBorrowedAmount, transaction: newTransaction, } = yield strategyUnloopToExposureTx(reserveMap, lstMap, strategyType,
|
|
2450
|
+
const { deposits: newDeposits, borrowedAmount: newBorrowedAmount, transaction: newTransaction, } = yield strategyUnloopToExposureTx(reserveMap, lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, deposits, borrowedAmount, undefined, // Don't pass targetBorrowedAmount
|
|
2291
2451
|
depositAdjustWithdrawExposure, // Pass targetExposure
|
|
2292
2452
|
transaction, dryRunTransaction);
|
|
2293
2453
|
// 3.2) Update state
|
|
@@ -2303,16 +2463,16 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2303
2463
|
const dryRunResults = yield dryRunTransaction(transaction);
|
|
2304
2464
|
const flashLoanRepayAmount = new BigNumber(bcs
|
|
2305
2465
|
.u64()
|
|
2306
|
-
.parse(
|
|
2466
|
+
.parse((_o = (_m = (_l = (_k = (_j = dryRunResults.commandResults) === null || _j === void 0 ? void 0 : _j[receiptDebts.Result]) === null || _k === void 0 ? void 0 : _k.returnValues) === null || _l === void 0 ? void 0 : _l[flashLoanObj.borrowA ? 0 : 1]) === null || _m === void 0 ? void 0 : _m.bcs) !== null && _o !== void 0 ? _o : new Uint8Array([0])))
|
|
2307
2467
|
.div(10 ** depositReserve.token.decimals)
|
|
2308
2468
|
.decimalPlaces(depositReserve.token.decimals, BigNumber.ROUND_UP);
|
|
2309
2469
|
// 4.1) Withdraw additional + fee
|
|
2310
2470
|
let withdrawnAmount = flashLoanRepayAmount;
|
|
2311
|
-
if (depositReserve.coinType === ((
|
|
2471
|
+
if (depositReserve.coinType === ((_p = depositReserves.lst) === null || _p === void 0 ? void 0 : _p.coinType))
|
|
2312
2472
|
withdrawnAmount = withdrawnAmount
|
|
2313
|
-
.div(1 - +((
|
|
2473
|
+
.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
2474
|
.decimalPlaces(depositReserve.token.decimals, BigNumber.ROUND_UP);
|
|
2315
|
-
const { deposits: newDeposits2, borrowedAmount: newBorrowedAmount2, transaction: newTransaction2, withdrawnCoin, } = yield strategyWithdrawTx(reserveMap, lstMap, strategyType,
|
|
2475
|
+
const { deposits: newDeposits2, borrowedAmount: newBorrowedAmount2, transaction: newTransaction2, withdrawnCoin, } = yield strategyWithdrawTx(reserveMap, lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, deposits, borrowedAmount, {
|
|
2316
2476
|
coinType: depositReserve.coinType,
|
|
2317
2477
|
withdrawnAmount,
|
|
2318
2478
|
}, transaction, dryRunTransaction, true);
|
|
@@ -2324,7 +2484,7 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2324
2484
|
transaction = newTransaction2;
|
|
2325
2485
|
// 4.3) Repay flash loan
|
|
2326
2486
|
let flashLoanRepayCoin = withdrawnCoin;
|
|
2327
|
-
if (depositReserve.coinType === ((
|
|
2487
|
+
if (depositReserve.coinType === ((_r = depositReserves.lst) === null || _r === void 0 ? void 0 : _r.coinType))
|
|
2328
2488
|
flashLoanRepayCoin = lst.client.redeem(transaction, flashLoanRepayCoin);
|
|
2329
2489
|
const flashLoanRepayBalance = transaction.moveCall({
|
|
2330
2490
|
target: "0x2::coin::into_balance",
|
|
@@ -2355,7 +2515,7 @@ export const strategyAdjustTx = (
|
|
|
2355
2515
|
// AppContext
|
|
2356
2516
|
reserveMap,
|
|
2357
2517
|
// Strategy
|
|
2358
|
-
lstMap, strategyType,
|
|
2518
|
+
lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligation, _deposits, _borrowedAmount, targetExposure, transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
2359
2519
|
const strategyInfo = STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
2360
2520
|
const lst = strategyInfo.depositLstCoinType !== undefined
|
|
2361
2521
|
? lstMap[strategyInfo.depositLstCoinType]
|
|
@@ -2380,11 +2540,11 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2380
2540
|
const borrowedAmount = _borrowedAmount;
|
|
2381
2541
|
// 1) Loop or unloop to target exposure
|
|
2382
2542
|
if (targetExposure.gt(exposure))
|
|
2383
|
-
return strategyLoopToExposureTx(reserveMap, lstMap, strategyType,
|
|
2543
|
+
return strategyLoopToExposureTx(reserveMap, lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligation.id, deposits, borrowedAmount, undefined, // Don't pass targetBorrowedAmount
|
|
2384
2544
|
targetExposure, // Pass targetExposure
|
|
2385
2545
|
transaction);
|
|
2386
2546
|
else if (targetExposure.lt(exposure))
|
|
2387
|
-
return strategyUnloopToExposureTx(reserveMap, lstMap, strategyType,
|
|
2547
|
+
return strategyUnloopToExposureTx(reserveMap, lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligation.id, deposits, borrowedAmount, undefined, // Don't pass targetBorrowedAmount
|
|
2388
2548
|
targetExposure, // Pass targetExposure
|
|
2389
2549
|
transaction, dryRunTransaction);
|
|
2390
2550
|
else
|