@suilend/sdk 1.1.92 → 1.1.94
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 +5 -1
- package/lib/initialize.d.ts +1 -1
- package/lib/initialize.js +18 -9
- package/lib/pyth.d.ts +12 -0
- package/lib/pyth.js +53 -0
- package/lib/strategyOwnerCap.d.ts +5 -2
- package/lib/strategyOwnerCap.js +117 -52
- package/package.json +1 -1
- package/strategies.d.ts +6 -1
- package/strategies.js +251 -27
package/client.js
CHANGED
|
@@ -24,6 +24,7 @@ const functions_2 = require("./_generated/suilend/lending-market-registry/functi
|
|
|
24
24
|
const structs_3 = require("./_generated/suilend/obligation/structs");
|
|
25
25
|
const functions_3 = require("./_generated/suilend/rate-limiter/functions");
|
|
26
26
|
const functions_4 = require("./_generated/suilend/reserve-config/functions");
|
|
27
|
+
const pyth_1 = require("./lib/pyth");
|
|
27
28
|
const types_1 = require("./lib/types");
|
|
28
29
|
const SUI_COINTYPE = "0x2::sui::SUI";
|
|
29
30
|
const NORMALIZED_SUI_COINTYPE = (0, utils_1.normalizeStructTag)(SUI_COINTYPE);
|
|
@@ -74,7 +75,10 @@ class SuilendClient {
|
|
|
74
75
|
this.lendingMarket = lendingMarket;
|
|
75
76
|
this.client = client;
|
|
76
77
|
this.pythClient = new pyth_sui_js_1.SuiPythClient(client, PYTH_STATE_ID, WORMHOLE_STATE_ID);
|
|
77
|
-
|
|
78
|
+
const pythEndpoint = pyth_1.PRIMARY_PYTH_ENDPOINT; // TODO: Use getWorkingPythEndpoint
|
|
79
|
+
this.pythConnection = new pyth_sui_js_1.SuiPriceServiceConnection(pythEndpoint, {
|
|
80
|
+
timeout: 30 * 1000,
|
|
81
|
+
});
|
|
78
82
|
}
|
|
79
83
|
static initialize(lendingMarketId, lendingMarketType, client, logPackageId) {
|
|
80
84
|
return __awaiter(this, void 0, void 0, function* () {
|
package/lib/initialize.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare const RESERVES_CUSTOM_ORDER: Record<string, string[]>;
|
|
|
8
8
|
export declare const NORMALIZED_MAYA_COINTYPE: string;
|
|
9
9
|
export declare const NORMALIZED_mPOINTS_COINTYPE: string;
|
|
10
10
|
export declare const NORMALIZED_TREATS_COINTYPE: string;
|
|
11
|
-
export declare const initializeSuilend: (suiClient: SuiClient, suilendClient: SuilendClient, lendingMarketMetadata?: LendingMarketMetadata) => Promise<{
|
|
11
|
+
export declare const initializeSuilend: (suiClient: SuiClient, suilendClient: SuilendClient, lendingMarketMetadata?: LendingMarketMetadata, fallbackPythEndpoint?: string) => Promise<{
|
|
12
12
|
lendingMarket: {
|
|
13
13
|
version: bigint;
|
|
14
14
|
reserves: {
|
package/lib/initialize.js
CHANGED
|
@@ -54,6 +54,7 @@ const client_1 = require("../client");
|
|
|
54
54
|
const parsers_1 = require("../parsers");
|
|
55
55
|
const simulate = __importStar(require("../utils/simulate"));
|
|
56
56
|
const constants_1 = require("./constants");
|
|
57
|
+
const pyth_1 = require("./pyth");
|
|
57
58
|
const strategyOwnerCap_1 = require("./strategyOwnerCap");
|
|
58
59
|
exports.RESERVES_CUSTOM_ORDER = {
|
|
59
60
|
[client_1.LENDING_MARKET_ID]: [
|
|
@@ -79,7 +80,8 @@ exports.RESERVES_CUSTOM_ORDER = {
|
|
|
79
80
|
sui_fe_1.NORMALIZED_wUSDT_COINTYPE,
|
|
80
81
|
sui_fe_1.NORMALIZED_AUSD_COINTYPE,
|
|
81
82
|
sui_fe_1.NORMALIZED_LBTC_COINTYPE,
|
|
82
|
-
sui_fe_1.
|
|
83
|
+
sui_fe_1.NORMALIZED_suiWBTC_COINTYPE,
|
|
84
|
+
sui_fe_1.NORMALIZED_WBTC_COINTYPE,
|
|
83
85
|
sui_fe_1.NORMALIZED_xBTC_COINTYPE,
|
|
84
86
|
sui_fe_1.NORMALIZED_suiETH_COINTYPE,
|
|
85
87
|
sui_fe_1.NORMALIZED_WETH_COINTYPE,
|
|
@@ -101,14 +103,18 @@ exports.RESERVES_CUSTOM_ORDER = {
|
|
|
101
103
|
sui_fe_1.NORMALIZED_HIPPO_COINTYPE,
|
|
102
104
|
sui_fe_1.NORMALIZED_FUD_COINTYPE,
|
|
103
105
|
],
|
|
104
|
-
"0x0d3a7f758d19d11e8526f66cca43403a99da16862c570c43efe0f8c4a500f7f2": [
|
|
105
|
-
sui_fe_1.NORMALIZED_sdeUSD_COINTYPE,
|
|
106
|
-
sui_fe_1.NORMALIZED_USDC_COINTYPE,
|
|
107
|
-
],
|
|
108
106
|
"0x8a8d8e138a28de1c637d0b0955e621b017da7010de388db5a18493eca99c5e82": [
|
|
109
107
|
sui_fe_1.NORMALIZED_XAUm_COINTYPE,
|
|
110
108
|
sui_fe_1.NORMALIZED_USDC_COINTYPE,
|
|
111
109
|
],
|
|
110
|
+
// "0xc1549fd5db74c3aad37a260c9fd251d93d6f2f3ccfacc277398a57718c275a17": [
|
|
111
|
+
// NORMALIZED_SEND_COINTYPE,
|
|
112
|
+
// NORMALIZED_USDC_COINTYPE,
|
|
113
|
+
// ],
|
|
114
|
+
"0x0d3a7f758d19d11e8526f66cca43403a99da16862c570c43efe0f8c4a500f7f2": [
|
|
115
|
+
sui_fe_1.NORMALIZED_sdeUSD_COINTYPE,
|
|
116
|
+
sui_fe_1.NORMALIZED_USDC_COINTYPE,
|
|
117
|
+
],
|
|
112
118
|
};
|
|
113
119
|
const MAYA_COINTYPE = "0x3bf0aeb7b9698b18ec7937290a5701088fcd5d43ad11a2564b074d022a6d71ec::maya::MAYA";
|
|
114
120
|
const mPOINTS_COINTYPE = "0x7bae0b3b7b6c3da899fe3f4af95b7110633499c02b8c6945110d799d99deaa68::mpoints::MPOINTS";
|
|
@@ -116,7 +122,7 @@ const TREATS_COINTYPE = "0x0dadb7fa2771c2952f96161fc1f0c105d1f22d53926b9ff2498a8
|
|
|
116
122
|
exports.NORMALIZED_MAYA_COINTYPE = (0, utils_1.normalizeStructTag)(MAYA_COINTYPE);
|
|
117
123
|
exports.NORMALIZED_mPOINTS_COINTYPE = (0, utils_1.normalizeStructTag)(mPOINTS_COINTYPE);
|
|
118
124
|
exports.NORMALIZED_TREATS_COINTYPE = (0, utils_1.normalizeStructTag)(TREATS_COINTYPE);
|
|
119
|
-
const initializeSuilend = (suiClient, suilendClient, lendingMarketMetadata) => __awaiter(void 0, void 0, void 0, function* () {
|
|
125
|
+
const initializeSuilend = (suiClient, suilendClient, lendingMarketMetadata, fallbackPythEndpoint) => __awaiter(void 0, void 0, void 0, function* () {
|
|
120
126
|
const nowMs = Date.now();
|
|
121
127
|
const nowS = Math.floor(nowMs / 1000);
|
|
122
128
|
const interestCompoundedRawReserves = suilendClient.lendingMarket.reserves.map((r) => simulate.compoundReserveInterest(r, nowS));
|
|
@@ -131,10 +137,13 @@ const initializeSuilend = (suiClient, suilendClient, lendingMarketMetadata) => _
|
|
|
131
137
|
reservesWithoutTemporaryPythPriceFeeds.push(reserve);
|
|
132
138
|
}
|
|
133
139
|
}
|
|
140
|
+
// Get a working Pyth endpoint (try primary, fallback to fallbackPythEndpoint if provided)
|
|
141
|
+
const pythEndpoint = yield (0, pyth_1.getWorkingPythEndpoint)(fallbackPythEndpoint);
|
|
142
|
+
const pythConnection = new pyth_sui_js_1.SuiPriceServiceConnection(pythEndpoint, {
|
|
143
|
+
timeout: 30 * 1000,
|
|
144
|
+
});
|
|
134
145
|
const [refreshedReservesWithoutTemporaryPythPriceFeeds] = yield Promise.all([
|
|
135
|
-
simulate.refreshReservePrice(reservesWithoutTemporaryPythPriceFeeds,
|
|
136
|
-
timeout: 30 * 1000,
|
|
137
|
-
})),
|
|
146
|
+
simulate.refreshReservePrice(reservesWithoutTemporaryPythPriceFeeds, pythConnection),
|
|
138
147
|
Promise.all(reservesWithTemporaryPythPriceFeeds.map((reserve) => (() => __awaiter(void 0, void 0, void 0, function* () {
|
|
139
148
|
let cachedUsdPrice;
|
|
140
149
|
try {
|
package/lib/pyth.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const PRIMARY_PYTH_ENDPOINT = "https://hermes.pyth.network";
|
|
2
|
+
/**
|
|
3
|
+
* Tests if the primary Pyth connection endpoint is working by checking the /live endpoint
|
|
4
|
+
* @returns true if the connection is working, false otherwise
|
|
5
|
+
*/
|
|
6
|
+
export declare const testPrimaryPythConnection: () => Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* Gets a working Pyth connection endpoint, trying primary first, then fallback if provided
|
|
9
|
+
* @param fallbackPythEndpoint Optional fallback endpoint
|
|
10
|
+
* @returns The endpoint URL that is working, or the primary endpoint if fallback fails
|
|
11
|
+
*/
|
|
12
|
+
export declare const getWorkingPythEndpoint: (fallbackPythEndpoint?: string) => Promise<string>;
|
package/lib/pyth.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getWorkingPythEndpoint = exports.testPrimaryPythConnection = exports.PRIMARY_PYTH_ENDPOINT = void 0;
|
|
13
|
+
exports.PRIMARY_PYTH_ENDPOINT = "https://hermes.pyth.network";
|
|
14
|
+
/**
|
|
15
|
+
* Tests if the primary Pyth connection endpoint is working by checking the /live endpoint
|
|
16
|
+
* @returns true if the connection is working, false otherwise
|
|
17
|
+
*/
|
|
18
|
+
const testPrimaryPythConnection = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
try {
|
|
20
|
+
const res = yield fetch(`${exports.PRIMARY_PYTH_ENDPOINT}/live`, {
|
|
21
|
+
signal: AbortSignal.timeout(5 * 1000), // 5 second timeout
|
|
22
|
+
});
|
|
23
|
+
return res.ok;
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
console.warn(`[testPrimaryPythConnection] Pyth connection test failed for ${exports.PRIMARY_PYTH_ENDPOINT}:`, err);
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
exports.testPrimaryPythConnection = testPrimaryPythConnection;
|
|
31
|
+
/**
|
|
32
|
+
* Gets a working Pyth connection endpoint, trying primary first, then fallback if provided
|
|
33
|
+
* @param fallbackPythEndpoint Optional fallback endpoint
|
|
34
|
+
* @returns The endpoint URL that is working, or the primary endpoint if fallback fails
|
|
35
|
+
*/
|
|
36
|
+
const getWorkingPythEndpoint = (fallbackPythEndpoint) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
+
// Test primary endpoint first
|
|
38
|
+
const primaryWorking = yield (0, exports.testPrimaryPythConnection)();
|
|
39
|
+
if (primaryWorking) {
|
|
40
|
+
console.log(`[getWorkingPythEndpoint] Using primary Pyth endpoint: ${exports.PRIMARY_PYTH_ENDPOINT}`);
|
|
41
|
+
return exports.PRIMARY_PYTH_ENDPOINT;
|
|
42
|
+
}
|
|
43
|
+
// If primary fails and fallback is provided, use fallback
|
|
44
|
+
if (!!fallbackPythEndpoint) {
|
|
45
|
+
console.warn(`[getWorkingPythEndpoint] Primary Pyth endpoint failed, using fallback: ${fallbackPythEndpoint}`);
|
|
46
|
+
return fallbackPythEndpoint;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.error(`[getWorkingPythEndpoint] Primary Pyth endpoint failed, no fallback provided, using primary anyway`);
|
|
50
|
+
return exports.PRIMARY_PYTH_ENDPOINT;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
exports.getWorkingPythEndpoint = getWorkingPythEndpoint;
|
|
@@ -10,8 +10,11 @@ export declare enum StrategyType {
|
|
|
10
10
|
USDC_sSUI_SUI_LOOPING = "3",
|
|
11
11
|
AUSD_sSUI_SUI_LOOPING = "4",
|
|
12
12
|
xBTC_sSUI_SUI_LOOPING = "100",// Used to be for Slush Strategies #0
|
|
13
|
-
|
|
14
|
-
suiUSDT_sSUI_SUI_LOOPING = "5"
|
|
13
|
+
xBTC_suiWBTC_LOOPING = "101",// Used to be for Slush Strategies #1
|
|
14
|
+
suiUSDT_sSUI_SUI_LOOPING = "5",
|
|
15
|
+
AUSD_USDC_LOOPING = "6",
|
|
16
|
+
AUSD_suiUSDT_LOOPING = "7",
|
|
17
|
+
USDC_suiUSDT_LOOPING = "8"
|
|
15
18
|
}
|
|
16
19
|
export declare const STRATEGY_TYPE_INFO_MAP: Record<StrategyType, {
|
|
17
20
|
queryParam: string;
|
package/lib/strategyOwnerCap.js
CHANGED
|
@@ -28,8 +28,11 @@ var StrategyType;
|
|
|
28
28
|
StrategyType["USDC_sSUI_SUI_LOOPING"] = "3";
|
|
29
29
|
StrategyType["AUSD_sSUI_SUI_LOOPING"] = "4";
|
|
30
30
|
StrategyType["xBTC_sSUI_SUI_LOOPING"] = "100";
|
|
31
|
-
StrategyType["
|
|
31
|
+
StrategyType["xBTC_suiWBTC_LOOPING"] = "101";
|
|
32
32
|
StrategyType["suiUSDT_sSUI_SUI_LOOPING"] = "5";
|
|
33
|
+
StrategyType["AUSD_USDC_LOOPING"] = "6";
|
|
34
|
+
StrategyType["AUSD_suiUSDT_LOOPING"] = "7";
|
|
35
|
+
StrategyType["USDC_suiUSDT_LOOPING"] = "8";
|
|
33
36
|
})(StrategyType || (exports.StrategyType = StrategyType = {}));
|
|
34
37
|
exports.STRATEGY_TYPE_INFO_MAP = {
|
|
35
38
|
[StrategyType.sSUI_SUI_LOOPING]: {
|
|
@@ -102,18 +105,18 @@ exports.STRATEGY_TYPE_INFO_MAP = {
|
|
|
102
105
|
currencyCoinTypes: [sui_fe_1.NORMALIZED_xBTC_COINTYPE],
|
|
103
106
|
defaultCurrencyCoinType: sui_fe_1.NORMALIZED_xBTC_COINTYPE,
|
|
104
107
|
},
|
|
105
|
-
[StrategyType.
|
|
106
|
-
queryParam: "xBTC-
|
|
108
|
+
[StrategyType.xBTC_suiWBTC_LOOPING]: {
|
|
109
|
+
queryParam: "xBTC-suiWBTC-looping",
|
|
107
110
|
header: {
|
|
108
|
-
coinTypes: [sui_fe_1.NORMALIZED_xBTC_COINTYPE, sui_fe_1.
|
|
109
|
-
title: "xBTC/
|
|
110
|
-
tooltip: "Sets up an xBTC/
|
|
111
|
+
coinTypes: [sui_fe_1.NORMALIZED_xBTC_COINTYPE, sui_fe_1.NORMALIZED_suiWBTC_COINTYPE],
|
|
112
|
+
title: "xBTC/suiWBTC",
|
|
113
|
+
tooltip: "Sets up an xBTC/suiWBTC Looping strategy by depositing xBTC and borrowing suiWBTC to the desired leverage",
|
|
111
114
|
type: "Looping",
|
|
112
115
|
},
|
|
113
116
|
depositBaseCoinType: sui_fe_1.NORMALIZED_xBTC_COINTYPE,
|
|
114
117
|
depositLstCoinType: undefined,
|
|
115
|
-
borrowCoinType: sui_fe_1.
|
|
116
|
-
currencyCoinTypes: [sui_fe_1.NORMALIZED_xBTC_COINTYPE, sui_fe_1.
|
|
118
|
+
borrowCoinType: sui_fe_1.NORMALIZED_suiWBTC_COINTYPE,
|
|
119
|
+
currencyCoinTypes: [sui_fe_1.NORMALIZED_xBTC_COINTYPE, sui_fe_1.NORMALIZED_suiWBTC_COINTYPE],
|
|
117
120
|
defaultCurrencyCoinType: sui_fe_1.NORMALIZED_xBTC_COINTYPE,
|
|
118
121
|
},
|
|
119
122
|
[StrategyType.suiUSDT_sSUI_SUI_LOOPING]: {
|
|
@@ -130,6 +133,48 @@ exports.STRATEGY_TYPE_INFO_MAP = {
|
|
|
130
133
|
currencyCoinTypes: [sui_fe_1.NORMALIZED_suiUSDT_COINTYPE],
|
|
131
134
|
defaultCurrencyCoinType: sui_fe_1.NORMALIZED_suiUSDT_COINTYPE,
|
|
132
135
|
},
|
|
136
|
+
[StrategyType.AUSD_USDC_LOOPING]: {
|
|
137
|
+
queryParam: "AUSD-USDC-looping",
|
|
138
|
+
header: {
|
|
139
|
+
coinTypes: [sui_fe_1.NORMALIZED_AUSD_COINTYPE, sui_fe_1.NORMALIZED_USDC_COINTYPE],
|
|
140
|
+
title: "AUSD/USDC",
|
|
141
|
+
tooltip: "Sets up an AUSD/USDC Looping strategy by depositing AUSD and borrowing USDC to the desired leverage",
|
|
142
|
+
type: "Looping",
|
|
143
|
+
},
|
|
144
|
+
depositBaseCoinType: sui_fe_1.NORMALIZED_AUSD_COINTYPE,
|
|
145
|
+
depositLstCoinType: undefined,
|
|
146
|
+
borrowCoinType: sui_fe_1.NORMALIZED_USDC_COINTYPE,
|
|
147
|
+
currencyCoinTypes: [sui_fe_1.NORMALIZED_AUSD_COINTYPE, sui_fe_1.NORMALIZED_USDC_COINTYPE],
|
|
148
|
+
defaultCurrencyCoinType: sui_fe_1.NORMALIZED_AUSD_COINTYPE,
|
|
149
|
+
},
|
|
150
|
+
[StrategyType.AUSD_suiUSDT_LOOPING]: {
|
|
151
|
+
queryParam: "AUSD-suiUSDT-looping",
|
|
152
|
+
header: {
|
|
153
|
+
coinTypes: [sui_fe_1.NORMALIZED_AUSD_COINTYPE, sui_fe_1.NORMALIZED_suiUSDT_COINTYPE],
|
|
154
|
+
title: "AUSD/suiUSDT",
|
|
155
|
+
tooltip: "Sets up an AUSD/suiUSDT Looping strategy by depositing AUSD and borrowing suiUSDT to the desired leverage",
|
|
156
|
+
type: "Looping",
|
|
157
|
+
},
|
|
158
|
+
depositBaseCoinType: sui_fe_1.NORMALIZED_AUSD_COINTYPE,
|
|
159
|
+
depositLstCoinType: undefined,
|
|
160
|
+
borrowCoinType: sui_fe_1.NORMALIZED_suiUSDT_COINTYPE,
|
|
161
|
+
currencyCoinTypes: [sui_fe_1.NORMALIZED_AUSD_COINTYPE, sui_fe_1.NORMALIZED_suiUSDT_COINTYPE],
|
|
162
|
+
defaultCurrencyCoinType: sui_fe_1.NORMALIZED_AUSD_COINTYPE,
|
|
163
|
+
},
|
|
164
|
+
[StrategyType.USDC_suiUSDT_LOOPING]: {
|
|
165
|
+
queryParam: "USDC-suiUSDT-looping",
|
|
166
|
+
header: {
|
|
167
|
+
coinTypes: [sui_fe_1.NORMALIZED_USDC_COINTYPE, sui_fe_1.NORMALIZED_suiUSDT_COINTYPE],
|
|
168
|
+
title: "USDC/suiUSDT",
|
|
169
|
+
tooltip: "Sets up a USDC/suiUSDT Looping strategy by depositing USDC and borrowing suiUSDT to the desired leverage",
|
|
170
|
+
type: "Looping",
|
|
171
|
+
},
|
|
172
|
+
depositBaseCoinType: sui_fe_1.NORMALIZED_USDC_COINTYPE,
|
|
173
|
+
depositLstCoinType: undefined,
|
|
174
|
+
borrowCoinType: sui_fe_1.NORMALIZED_suiUSDT_COINTYPE,
|
|
175
|
+
currencyCoinTypes: [sui_fe_1.NORMALIZED_USDC_COINTYPE, sui_fe_1.NORMALIZED_suiUSDT_COINTYPE],
|
|
176
|
+
defaultCurrencyCoinType: sui_fe_1.NORMALIZED_USDC_COINTYPE,
|
|
177
|
+
},
|
|
133
178
|
};
|
|
134
179
|
const strategyDeposit = (coin, coinType, strategyOwnerCap, reserveArrayIndex, transaction) => transaction.moveCall({
|
|
135
180
|
target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::deposit_liquidity_and_deposit_into_obligation`,
|
|
@@ -273,23 +318,29 @@ const strategyClaimRewardsAndSwapForCoinType = (address, cetusSdk, cetusPartnerI
|
|
|
273
318
|
if (routers === undefined)
|
|
274
319
|
continue; // Skip coin if no swap quote found
|
|
275
320
|
console.log("[strategyClaimRewardsAndSwapForCoinType] swapping coinType", coinType);
|
|
276
|
-
let coinOut;
|
|
277
321
|
try {
|
|
278
|
-
coinOut
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
322
|
+
let coinOut;
|
|
323
|
+
try {
|
|
324
|
+
coinOut = yield cetusSdk.fixableRouterSwapV3({
|
|
325
|
+
router: routers,
|
|
326
|
+
inputCoin: coinIn,
|
|
327
|
+
slippage: 3 / 100,
|
|
328
|
+
txb: transaction,
|
|
329
|
+
partner: cetusPartnerId,
|
|
330
|
+
});
|
|
331
|
+
if (resultCoin)
|
|
332
|
+
transaction.mergeCoins(resultCoin, [coinOut]);
|
|
333
|
+
else
|
|
334
|
+
resultCoin = coinOut;
|
|
335
|
+
}
|
|
336
|
+
catch (err) {
|
|
337
|
+
throw new Error(`No swap quote found for ${coinType}`);
|
|
338
|
+
}
|
|
285
339
|
}
|
|
286
340
|
catch (err) {
|
|
287
|
-
|
|
341
|
+
console.error(err);
|
|
342
|
+
continue; // Skip coin if swap fails
|
|
288
343
|
}
|
|
289
|
-
if (resultCoin)
|
|
290
|
-
transaction.mergeCoins(resultCoin, [coinOut]);
|
|
291
|
-
else
|
|
292
|
-
resultCoin = coinOut;
|
|
293
344
|
}
|
|
294
345
|
// 4) Deposit
|
|
295
346
|
if (!resultCoin)
|
|
@@ -329,46 +380,60 @@ depositReserve, strategyOwnerCap, transaction) => __awaiter(void 0, void 0, void
|
|
|
329
380
|
let resultCoin = undefined;
|
|
330
381
|
// 2.1) Get routers
|
|
331
382
|
const amountsAndSortedQuotesMap = Object.fromEntries(yield Promise.all(Object.entries(withdrawnCoinsMap).map(([coinType, { deposit, coin }]) => (() => __awaiter(void 0, void 0, void 0, function* () {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
.
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
383
|
+
try {
|
|
384
|
+
// Get amount
|
|
385
|
+
const amount = new bignumber_js_1.default(deposit.depositedAmount.times(swapPercent.div(100)))
|
|
386
|
+
.times(10 ** deposit.reserve.token.decimals)
|
|
387
|
+
.integerValue(bignumber_js_1.default.ROUND_DOWN); // Use underestimate (deposits keep accruing if deposit APR >0)
|
|
388
|
+
// Get routes
|
|
389
|
+
const routers = yield cetusSdk.findRouters({
|
|
390
|
+
from: deposit.coinType,
|
|
391
|
+
target: depositReserve.coinType,
|
|
392
|
+
amount: new bn_js_1.default(amount.toString()), // Underestimate (deposits keep accruing if deposit APR >0)
|
|
393
|
+
byAmountIn: true,
|
|
394
|
+
});
|
|
395
|
+
if (!routers)
|
|
396
|
+
throw new Error(`No swap quote found for ${deposit.coinType}`);
|
|
397
|
+
console.log("[strategySwapSomeDepositsForCoinType] routers", {
|
|
398
|
+
coinType: deposit.coinType,
|
|
399
|
+
routers,
|
|
400
|
+
});
|
|
401
|
+
return [deposit.coinType, { coin, routers }];
|
|
402
|
+
}
|
|
403
|
+
catch (err) {
|
|
404
|
+
console.error(err);
|
|
405
|
+
return [coinType, { coin, routers: undefined }];
|
|
406
|
+
}
|
|
350
407
|
}))())));
|
|
351
408
|
console.log("[strategySwapSomeDepositsForCoinType] amountsAndSortedQuotesMap", { amountsAndSortedQuotesMap });
|
|
352
409
|
// 2.2) Swap
|
|
353
410
|
for (const [coinType, { coin: coinIn, routers }] of Object.entries(amountsAndSortedQuotesMap)) {
|
|
411
|
+
if (routers === undefined)
|
|
412
|
+
continue; // Skip coin if no swap quote found
|
|
354
413
|
console.log("[strategySwapSomeDepositsForCoinType] swapping coinType", coinType);
|
|
355
|
-
let coinOut;
|
|
356
414
|
try {
|
|
357
|
-
coinOut
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
415
|
+
let coinOut;
|
|
416
|
+
try {
|
|
417
|
+
coinOut = yield cetusSdk.fixableRouterSwapV3({
|
|
418
|
+
router: routers,
|
|
419
|
+
inputCoin: coinIn,
|
|
420
|
+
slippage: 3 / 100,
|
|
421
|
+
txb: transaction,
|
|
422
|
+
partner: cetusPartnerId,
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
catch (err) {
|
|
426
|
+
throw new Error(`No swap quote found for ${coinType}`);
|
|
427
|
+
}
|
|
428
|
+
if (resultCoin)
|
|
429
|
+
transaction.mergeCoins(resultCoin, [coinOut]);
|
|
430
|
+
else
|
|
431
|
+
resultCoin = coinOut;
|
|
364
432
|
}
|
|
365
433
|
catch (err) {
|
|
366
|
-
|
|
434
|
+
console.error(err);
|
|
435
|
+
continue; // Skip coin if swap fails
|
|
367
436
|
}
|
|
368
|
-
if (resultCoin)
|
|
369
|
-
transaction.mergeCoins(resultCoin, [coinOut]);
|
|
370
|
-
else
|
|
371
|
-
resultCoin = coinOut;
|
|
372
437
|
}
|
|
373
438
|
// 3) Deposit
|
|
374
439
|
if (!resultCoin)
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@suilend/sdk","version":"1.1.
|
|
1
|
+
{"name":"@suilend/sdk","version":"1.1.94","private":false,"description":"A TypeScript SDK for interacting with the Suilend program","author":"Suilend","license":"MIT","main":"./index.js","exports":{".":"./index.js","./client":"./client.js","./mmt":"./mmt.js","./strategies":"./strategies.js","./api/events":"./api/events.js","./api":"./api/index.js","./lib/constants":"./lib/constants.js","./lib":"./lib/index.js","./lib/initialize":"./lib/initialize.js","./lib/liquidityMining":"./lib/liquidityMining.js","./lib/pyth":"./lib/pyth.js","./lib/strategyOwnerCap":"./lib/strategyOwnerCap.js","./lib/transactions":"./lib/transactions.js","./lib/types":"./lib/types.js","./parsers/apiReserveAssetDataEvent":"./parsers/apiReserveAssetDataEvent.js","./parsers":"./parsers/index.js","./parsers/lendingMarket":"./parsers/lendingMarket.js","./parsers/obligation":"./parsers/obligation.js","./parsers/rateLimiter":"./parsers/rateLimiter.js","./parsers/reserve":"./parsers/reserve.js","./swap":"./swap/index.js","./swap/quote":"./swap/quote.js","./swap/transaction":"./swap/transaction.js","./utils/events":"./utils/events.js","./utils":"./utils/index.js","./utils/obligation":"./utils/obligation.js","./utils/simulate":"./utils/simulate.js","./_generated/_framework/reified":"./_generated/_framework/reified.js","./_generated/_framework/util":"./_generated/_framework/util.js","./_generated/_framework/vector":"./_generated/_framework/vector.js","./_generated/suilend":"./_generated/suilend/index.js","./_generated/suilend/cell/structs":"./_generated/suilend/cell/structs.js","./_generated/suilend/decimal/structs":"./_generated/suilend/decimal/structs.js","./_generated/suilend/lending-market/functions":"./_generated/suilend/lending-market/functions.js","./_generated/suilend/lending-market/structs":"./_generated/suilend/lending-market/structs.js","./_generated/suilend/lending-market-registry/functions":"./_generated/suilend/lending-market-registry/functions.js","./_generated/suilend/liquidity-mining/structs":"./_generated/suilend/liquidity-mining/structs.js","./_generated/suilend/obligation/structs":"./_generated/suilend/obligation/structs.js","./_generated/suilend/rate-limiter/functions":"./_generated/suilend/rate-limiter/functions.js","./_generated/suilend/rate-limiter/structs":"./_generated/suilend/rate-limiter/structs.js","./_generated/suilend/reserve/structs":"./_generated/suilend/reserve/structs.js","./_generated/suilend/reserve-config/functions":"./_generated/suilend/reserve-config/functions.js","./_generated/suilend/reserve-config/structs":"./_generated/suilend/reserve-config/structs.js","./_generated/_dependencies/source/0x1":"./_generated/_dependencies/source/0x1/index.js","./_generated/_dependencies/source/0x2":"./_generated/_dependencies/source/0x2/index.js","./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e":"./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/index.js","./_generated/_dependencies/source/0x1/ascii/structs":"./_generated/_dependencies/source/0x1/ascii/structs.js","./_generated/_dependencies/source/0x1/option/structs":"./_generated/_dependencies/source/0x1/option/structs.js","./_generated/_dependencies/source/0x1/type-name/structs":"./_generated/_dependencies/source/0x1/type-name/structs.js","./_generated/_dependencies/source/0x2/bag/structs":"./_generated/_dependencies/source/0x2/bag/structs.js","./_generated/_dependencies/source/0x2/balance/structs":"./_generated/_dependencies/source/0x2/balance/structs.js","./_generated/_dependencies/source/0x2/object/structs":"./_generated/_dependencies/source/0x2/object/structs.js","./_generated/_dependencies/source/0x2/object-table/structs":"./_generated/_dependencies/source/0x2/object-table/structs.js","./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/i64/structs":"./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/i64/structs.js","./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price/structs":"./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price/structs.js","./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-feed/structs":"./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-feed/structs.js","./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-identifier/structs":"./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-identifier/structs.js","./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-info/structs":"./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-info/structs.js"},"types":"./index.js","scripts":{"build":"rm -rf ./dist && bun tsc","eslint":"eslint --fix \"./src/**/*.ts\"","prettier":"prettier --write \"./src/**/*\"","lint":"bun eslint && bun prettier && bun tsc --noEmit","release":"bun run build && bun ts-node ./release.ts && cd ./dist && npm publish --access public"},"repository":{"type":"git","url":"git+https://github.com/suilend/suilend-fe-public.git"},"bugs":{"url":"https://github.com/suilend/suilend-fe-public/issues"},"dependencies":{"@7kprotocol/sdk-ts":"^3.5.0","@cetusprotocol/aggregator-sdk":"^1.4.2","@flowx-finance/sdk":"^1.14.0","@pythnetwork/pyth-sui-js":"^2.2.0","@suilend/springsui-sdk":"^1.0.27","aftermath-ts-sdk":"^1.3.24","bignumber.js":"^9.1.2","bn.js":"^5.2.2","crypto-js":"^4.2.0","lodash":"^4.17.21","p-limit":"3.1.0","uuid":"^11.0.3"},"devDependencies":{"@types/bn.js":"^5.2.0","@types/lodash":"^4.17.20","ts-node":"^10.9.2"},"peerDependencies":{"@mysten/bcs":"1.8.1","@mysten/sui":"1.42.0","@suilend/sui-fe":"^0.3.44"},"overrides":{"chalk":"5.3.0","strip-ansi":"7.1.0","color-convert":"2.0.1","color-name":"1.1.4","is-core-module":"2.13.1","error-ex":"1.3.2","has-ansi":"5.0.1"}}
|
package/strategies.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export type StrategyWithdraw = {
|
|
|
22
22
|
export declare enum StrategyFlashLoanProvider {
|
|
23
23
|
MMT = "mmt"
|
|
24
24
|
}
|
|
25
|
-
export declare const STRATEGY_TYPE_FLASH_LOAN_OBJ_MAP: Record<
|
|
25
|
+
export declare const STRATEGY_TYPE_FLASH_LOAN_OBJ_MAP: Record<StrategyType, {
|
|
26
26
|
provider: StrategyFlashLoanProvider;
|
|
27
27
|
poolId: string;
|
|
28
28
|
coinTypeA: string;
|
|
@@ -336,6 +336,11 @@ export declare const strategyMaxWithdrawTx: (reserveMap: Record<string, ParsedRe
|
|
|
336
336
|
borrowedAmount: BigNumber;
|
|
337
337
|
transaction: Transaction;
|
|
338
338
|
}>;
|
|
339
|
+
export declare const strategyAdjustRepayTx: (reserveMap: Record<string, ParsedReserve>, lstMap: StrategyLstMap, strategyType: StrategyType, suiClient: SuiClient, suilendClient: SuilendClient, cetusSdk: CetusSdk, cetusPartnerId: string, _address: string, strategyOwnerCapId: TransactionObjectInput, obligationId: string, _deposits: StrategyDeposit[], _borrowedAmount: BigNumber, flashLoanBorrowedAmount: BigNumber, transaction: Transaction, dryRunTransaction: (transaction: Transaction, setGasBudget?: boolean) => Promise<DevInspectResults>) => Promise<{
|
|
340
|
+
deposits: StrategyDeposit[];
|
|
341
|
+
borrowedAmount: BigNumber;
|
|
342
|
+
transaction: Transaction;
|
|
343
|
+
}>;
|
|
339
344
|
export declare const strategyDepositAdjustWithdrawTx: (reserveMap: Record<string, ParsedReserve>, lstMap: StrategyLstMap, strategyType: StrategyType, suiClient: SuiClient, suilendClient: SuilendClient, cetusSdk: CetusSdk, cetusPartnerId: string, _address: string, strategyOwnerCapId: TransactionObjectInput, obligationId: string, _deposits: StrategyDeposit[], _borrowedAmount: BigNumber, flashLoanBorrowedAmount: BigNumber, transaction: Transaction, dryRunTransaction: (transaction: Transaction, setGasBudget?: boolean) => Promise<DevInspectResults>) => Promise<{
|
|
340
345
|
deposits: StrategyDeposit[];
|
|
341
346
|
borrowedAmount: BigNumber;
|
package/strategies.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.strategyAdjustTx = exports.strategyDepositAdjustWithdrawTx = exports.strategyMaxWithdrawTx = exports.strategyWithdrawTx = exports.strategyDepositAndLoopToExposureTx = exports.strategyDepositTx = exports.strategyUnloopToExposureTx = exports.strategyLoopToExposureTx = exports.getStrategyLiquidationPrice = exports.getStrategyHealthPercent = exports.getStrategyAprPercent = exports.getStrategyUnclaimedRewardsAmount = exports.fetchStrategyGlobalTvlAmountUsdMap = exports.strategySimulateDepositAndLoopToExposure = exports.strategySimulateDeposit = exports.strategySimulateLoopToExposure = exports.getStrategyStepMaxWithdrawnAmount = exports.getStrategyStepMaxBorrowedAmount = exports.getStrategyExposure = exports.getStrategyTvlAmount = exports.getStrategyBorrowedAmount = exports.getStrategyDepositedAmount = exports.getStrategySimulatedObligation = exports.getStrategyDefaultCurrencyReserve = exports.getStrategyBorrowReserve = exports.getStrategyDepositReserves = exports.STRATEGY_TYPE_EXPOSURE_MAP = exports.getStrategyLstRedeemFee = exports.getStrategyLstMintFee = exports.fetchStrategyLstMap = exports.getStrategySuiReserve = exports.hasStrategyPosition = exports.addOrInsertStrategyDeposit = exports.getReserveSafeDepositLimit = exports.STRATEGY_TYPE_FLASH_LOAN_OBJ_MAP = exports.StrategyFlashLoanProvider = exports.LST_DECIMALS = exports.STRATEGY_E = void 0;
|
|
15
|
+
exports.strategyAdjustTx = exports.strategyDepositAdjustWithdrawTx = exports.strategyAdjustRepayTx = exports.strategyMaxWithdrawTx = exports.strategyWithdrawTx = exports.strategyDepositAndLoopToExposureTx = exports.strategyDepositTx = exports.strategyUnloopToExposureTx = exports.strategyLoopToExposureTx = exports.getStrategyLiquidationPrice = exports.getStrategyHealthPercent = exports.getStrategyAprPercent = exports.getStrategyUnclaimedRewardsAmount = exports.fetchStrategyGlobalTvlAmountUsdMap = exports.strategySimulateDepositAndLoopToExposure = exports.strategySimulateDeposit = exports.strategySimulateLoopToExposure = exports.getStrategyStepMaxWithdrawnAmount = exports.getStrategyStepMaxBorrowedAmount = exports.getStrategyExposure = exports.getStrategyTvlAmount = exports.getStrategyBorrowedAmount = exports.getStrategyDepositedAmount = exports.getStrategySimulatedObligation = exports.getStrategyDefaultCurrencyReserve = exports.getStrategyBorrowReserve = exports.getStrategyDepositReserves = exports.STRATEGY_TYPE_EXPOSURE_MAP = exports.getStrategyLstRedeemFee = exports.getStrategyLstMintFee = exports.fetchStrategyLstMap = exports.getStrategySuiReserve = exports.hasStrategyPosition = exports.addOrInsertStrategyDeposit = exports.getReserveSafeDepositLimit = exports.STRATEGY_TYPE_FLASH_LOAN_OBJ_MAP = exports.StrategyFlashLoanProvider = exports.LST_DECIMALS = exports.STRATEGY_E = void 0;
|
|
16
16
|
const bcs_1 = require("@mysten/bcs");
|
|
17
17
|
const transactions_1 = require("@mysten/sui/transactions");
|
|
18
18
|
const utils_1 = require("@mysten/sui/utils");
|
|
@@ -67,17 +67,17 @@ exports.STRATEGY_TYPE_FLASH_LOAN_OBJ_MAP = {
|
|
|
67
67
|
},
|
|
68
68
|
[strategyOwnerCap_1.StrategyType.xBTC_sSUI_SUI_LOOPING]: {
|
|
69
69
|
provider: StrategyFlashLoanProvider.MMT,
|
|
70
|
-
poolId: "0x57a662791cea065610455797dfd2751a3c10d929455d3ea88154a2b40cf6614e", // xBTC-
|
|
70
|
+
poolId: "0x57a662791cea065610455797dfd2751a3c10d929455d3ea88154a2b40cf6614e", // xBTC-suiWBTC 0.01% https://app.mmt.finance/liquidity/0x57a662791cea065610455797dfd2751a3c10d929455d3ea88154a2b40cf6614e
|
|
71
71
|
coinTypeA: sui_fe_1.NORMALIZED_xBTC_COINTYPE,
|
|
72
|
-
coinTypeB: sui_fe_1.
|
|
72
|
+
coinTypeB: sui_fe_1.NORMALIZED_suiWBTC_COINTYPE,
|
|
73
73
|
borrowA: true,
|
|
74
74
|
feePercent: 0.01,
|
|
75
75
|
},
|
|
76
|
-
[strategyOwnerCap_1.StrategyType.
|
|
76
|
+
[strategyOwnerCap_1.StrategyType.xBTC_suiWBTC_LOOPING]: {
|
|
77
77
|
provider: StrategyFlashLoanProvider.MMT,
|
|
78
|
-
poolId: "0x57a662791cea065610455797dfd2751a3c10d929455d3ea88154a2b40cf6614e", // xBTC-
|
|
78
|
+
poolId: "0x57a662791cea065610455797dfd2751a3c10d929455d3ea88154a2b40cf6614e", // xBTC-suiWBTC 0.01% https://app.mmt.finance/liquidity/0x57a662791cea065610455797dfd2751a3c10d929455d3ea88154a2b40cf6614e
|
|
79
79
|
coinTypeA: sui_fe_1.NORMALIZED_xBTC_COINTYPE,
|
|
80
|
-
coinTypeB: sui_fe_1.
|
|
80
|
+
coinTypeB: sui_fe_1.NORMALIZED_suiWBTC_COINTYPE,
|
|
81
81
|
borrowA: true,
|
|
82
82
|
feePercent: 0.01,
|
|
83
83
|
},
|
|
@@ -89,6 +89,30 @@ exports.STRATEGY_TYPE_FLASH_LOAN_OBJ_MAP = {
|
|
|
89
89
|
borrowA: true,
|
|
90
90
|
feePercent: 0.001,
|
|
91
91
|
},
|
|
92
|
+
[strategyOwnerCap_1.StrategyType.AUSD_USDC_LOOPING]: {
|
|
93
|
+
provider: StrategyFlashLoanProvider.MMT,
|
|
94
|
+
poolId: "0x900f25b27d2b1686886277d763223988d802f3b6152d02872c382d4dce05e25b", // AUSD-USDC 0.01% https://app.mmt.finance/liquidity/0x900f25b27d2b1686886277d763223988d802f3b6152d02872c382d4dce05e25b
|
|
95
|
+
coinTypeA: sui_fe_1.NORMALIZED_AUSD_COINTYPE,
|
|
96
|
+
coinTypeB: sui_fe_1.NORMALIZED_USDC_COINTYPE,
|
|
97
|
+
borrowA: true,
|
|
98
|
+
feePercent: 0.01,
|
|
99
|
+
},
|
|
100
|
+
[strategyOwnerCap_1.StrategyType.AUSD_suiUSDT_LOOPING]: {
|
|
101
|
+
provider: StrategyFlashLoanProvider.MMT,
|
|
102
|
+
poolId: "0x900f25b27d2b1686886277d763223988d802f3b6152d02872c382d4dce05e25b", // AUSD-USDC 0.01% https://app.mmt.finance/liquidity/0x900f25b27d2b1686886277d763223988d802f3b6152d02872c382d4dce05e25b
|
|
103
|
+
coinTypeA: sui_fe_1.NORMALIZED_AUSD_COINTYPE,
|
|
104
|
+
coinTypeB: sui_fe_1.NORMALIZED_USDC_COINTYPE,
|
|
105
|
+
borrowA: true,
|
|
106
|
+
feePercent: 0.01,
|
|
107
|
+
},
|
|
108
|
+
[strategyOwnerCap_1.StrategyType.USDC_suiUSDT_LOOPING]: {
|
|
109
|
+
provider: StrategyFlashLoanProvider.MMT,
|
|
110
|
+
poolId: "0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9", // suiUSDT-USDC 0.001% https://app.mmt.finance/liquidity/0x737ec6a4d3ed0c7e6cc18d8ba04e7ffd4806b726c97efd89867597368c4d06a9
|
|
111
|
+
coinTypeA: sui_fe_1.NORMALIZED_suiUSDT_COINTYPE,
|
|
112
|
+
coinTypeB: sui_fe_1.NORMALIZED_USDC_COINTYPE,
|
|
113
|
+
borrowA: false,
|
|
114
|
+
feePercent: 0.001,
|
|
115
|
+
},
|
|
92
116
|
};
|
|
93
117
|
const getReserveSafeDepositLimit = (reserve) => {
|
|
94
118
|
// Calculate safe deposit limit (subtract 10 mins of deposit APR from cap)
|
|
@@ -222,7 +246,7 @@ exports.STRATEGY_TYPE_EXPOSURE_MAP = {
|
|
|
222
246
|
max: new bignumber_js_1.default(2.5), // Actual max: 1 + (xBTC Open LTV %) * (1 / (1 - (sSUI Open LTV %))) = 3x, where xBTC Open LTV % = 60% and sSUI Open LTV % = 70%
|
|
223
247
|
default: new bignumber_js_1.default(2.5),
|
|
224
248
|
},
|
|
225
|
-
[strategyOwnerCap_1.StrategyType.
|
|
249
|
+
[strategyOwnerCap_1.StrategyType.xBTC_suiWBTC_LOOPING]: {
|
|
226
250
|
min: new bignumber_js_1.default(1),
|
|
227
251
|
max: new bignumber_js_1.default(2.2), // Actual max: 1 / (1 - (xBTC Open LTV %)) = 2.5x, where xBTC Open LTV % = 60%
|
|
228
252
|
default: new bignumber_js_1.default(2.2),
|
|
@@ -232,6 +256,21 @@ exports.STRATEGY_TYPE_EXPOSURE_MAP = {
|
|
|
232
256
|
max: new bignumber_js_1.default(3), // Actual max: 1 + (suiUSDT Open LTV %) * (1 / (1 - (sSUI Open LTV %))) = 3.5666x, where suiUSDT Open LTV % = 77% and sSUI Open LTV % = 70%
|
|
233
257
|
default: new bignumber_js_1.default(3),
|
|
234
258
|
},
|
|
259
|
+
[strategyOwnerCap_1.StrategyType.AUSD_USDC_LOOPING]: {
|
|
260
|
+
min: new bignumber_js_1.default(1),
|
|
261
|
+
max: new bignumber_js_1.default(4), // Actual max: 1 / (1 - (AUSD Open LTV %)) = 4.347x, where AUSD Open LTV % = 77%
|
|
262
|
+
default: new bignumber_js_1.default(4),
|
|
263
|
+
},
|
|
264
|
+
[strategyOwnerCap_1.StrategyType.AUSD_suiUSDT_LOOPING]: {
|
|
265
|
+
min: new bignumber_js_1.default(1),
|
|
266
|
+
max: new bignumber_js_1.default(4), // Actual max: 1 / (1 - (AUSD Open LTV %)) = 4.347x, where AUSD Open LTV % = 77%
|
|
267
|
+
default: new bignumber_js_1.default(4),
|
|
268
|
+
},
|
|
269
|
+
[strategyOwnerCap_1.StrategyType.USDC_suiUSDT_LOOPING]: {
|
|
270
|
+
min: new bignumber_js_1.default(1),
|
|
271
|
+
max: new bignumber_js_1.default(4), // Actual max: 1 / (1 - (USDC Open LTV %)) = 4.347x, where USDC Open LTV % = 77%
|
|
272
|
+
default: new bignumber_js_1.default(4),
|
|
273
|
+
},
|
|
235
274
|
};
|
|
236
275
|
// Reserves
|
|
237
276
|
const getStrategyDepositReserves = (
|
|
@@ -765,7 +804,7 @@ lstMap, strategyType, obligation, exposure) => {
|
|
|
765
804
|
const weightedBorrowsUsd = (0, utils_2.getWeightedBorrowsUsd)(_obligation);
|
|
766
805
|
const borrowLimitUsd = _obligation.minPriceBorrowLimitUsd.times(depositReserves.base !== undefined
|
|
767
806
|
? 0.99 // 1% buffer
|
|
768
|
-
:
|
|
807
|
+
: 1);
|
|
769
808
|
const liquidationThresholdUsd = _obligation.unhealthyBorrowValueUsd;
|
|
770
809
|
if (weightedBorrowsUsd.lte(borrowLimitUsd))
|
|
771
810
|
return new bignumber_js_1.default(100);
|
|
@@ -1102,8 +1141,14 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1102
1141
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
1103
1142
|
if (depositReserves.lst === undefined)
|
|
1104
1143
|
throw new Error("LST reserve not found");
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1144
|
+
const borrowedAmountUsd = borrowedAmount.times(borrowReserve.price);
|
|
1145
|
+
const fullRepaymentAmount = (borrowedAmountUsd.lt(0.1)
|
|
1146
|
+
? new bignumber_js_1.default(0.1).div(borrowReserve.price) // $0.1 in borrow coinType
|
|
1147
|
+
: borrowedAmountUsd.lt(1)
|
|
1148
|
+
? borrowedAmount.times(1.1) // 10% buffer
|
|
1149
|
+
: borrowedAmountUsd.lt(10)
|
|
1150
|
+
? borrowedAmount.times(1.01) // 1% buffer
|
|
1151
|
+
: borrowedAmount.times(1.001)) // 0.1% buffer
|
|
1107
1152
|
.decimalPlaces(borrowReserve.token.decimals, bignumber_js_1.default.ROUND_DOWN);
|
|
1108
1153
|
console.log(`[unloopStrategyToExposure.fullyRepayBorrowsUsingLst] |`, JSON.stringify({
|
|
1109
1154
|
borrowedAmount: borrowedAmount.toFixed(20),
|
|
@@ -1217,9 +1262,9 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1217
1262
|
.toFixed(20),
|
|
1218
1263
|
});
|
|
1219
1264
|
// 2.2) Swap
|
|
1220
|
-
let
|
|
1265
|
+
let swapCoin;
|
|
1221
1266
|
try {
|
|
1222
|
-
|
|
1267
|
+
swapCoin = yield cetusSdk.fixableRouterSwapV3({
|
|
1223
1268
|
router: routers,
|
|
1224
1269
|
inputCoin: withdrawnRemainingLstCoin,
|
|
1225
1270
|
slippage: 100 / 100,
|
|
@@ -1231,14 +1276,22 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1231
1276
|
throw new Error("No swap quote found");
|
|
1232
1277
|
}
|
|
1233
1278
|
// 3) Deposit base
|
|
1234
|
-
(0, strategyOwnerCap_1.strategyDeposit)(
|
|
1279
|
+
(0, strategyOwnerCap_1.strategyDeposit)(swapCoin, depositReserves.base.coinType, strategyOwnerCapId, suilendClient.findReserveArrayIndex(depositReserves.base.coinType), transaction);
|
|
1235
1280
|
}
|
|
1236
1281
|
});
|
|
1237
1282
|
const fullyRepayBorrowsUsingBase = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1238
1283
|
var _a, _b;
|
|
1239
1284
|
if (depositReserves.base === undefined)
|
|
1240
1285
|
throw new Error("Base reserve not found");
|
|
1241
|
-
const
|
|
1286
|
+
const borrowedAmountUsd = borrowedAmount.times(borrowReserve.price);
|
|
1287
|
+
const fullRepaymentAmount = (borrowedAmountUsd.lt(0.1)
|
|
1288
|
+
? new bignumber_js_1.default(0.1).div(borrowReserve.price) // $0.1 in borrow coinType
|
|
1289
|
+
: borrowedAmountUsd.lt(1)
|
|
1290
|
+
? borrowedAmount.times(1.1) // 10% buffer
|
|
1291
|
+
: borrowedAmountUsd.lt(10)
|
|
1292
|
+
? borrowedAmount.times(1.01) // 1% buffer
|
|
1293
|
+
: borrowedAmount.times(1.001)) // 0.1% buffer
|
|
1294
|
+
.decimalPlaces(borrowReserve.token.decimals, bignumber_js_1.default.ROUND_DOWN);
|
|
1242
1295
|
console.log(`[unloopStrategyToExposure.fullyRepayBorrowsUsingBase] |`, JSON.stringify({
|
|
1243
1296
|
borrowedAmount: borrowedAmount.toFixed(20),
|
|
1244
1297
|
fullRepaymentAmount: fullRepaymentAmount.toFixed(20),
|
|
@@ -1267,7 +1320,8 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1267
1320
|
// 2) Withdraw base
|
|
1268
1321
|
const baseWithdrawnAmount = new bignumber_js_1.default(fullRepaymentAmount.times(borrowReserve.price))
|
|
1269
1322
|
.div(depositReserves.base.price)
|
|
1270
|
-
.times(1.03)
|
|
1323
|
+
.times(1.03) // 3% buffer
|
|
1324
|
+
.decimalPlaces(depositReserves.base.token.decimals, bignumber_js_1.default.ROUND_UP);
|
|
1271
1325
|
console.log(`[unloopStrategyToExposure.fullyRepayBorrowsUsingBase] withdraw_base |`, JSON.stringify({
|
|
1272
1326
|
baseWithdrawnAmount: baseWithdrawnAmount.toFixed(20),
|
|
1273
1327
|
}, null, 2));
|
|
@@ -1316,9 +1370,9 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1316
1370
|
.toFixed(20),
|
|
1317
1371
|
});
|
|
1318
1372
|
// 3.2) Swap
|
|
1319
|
-
let
|
|
1373
|
+
let swapCoin;
|
|
1320
1374
|
try {
|
|
1321
|
-
|
|
1375
|
+
swapCoin = yield cetusSdk.fixableRouterSwapV3({
|
|
1322
1376
|
router: routers,
|
|
1323
1377
|
inputCoin: withdrawnBaseCoin,
|
|
1324
1378
|
slippage: 1 / 100,
|
|
@@ -1337,15 +1391,15 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1337
1391
|
}, null, 2));
|
|
1338
1392
|
try {
|
|
1339
1393
|
const txCopy = transactions_1.Transaction.from(transaction);
|
|
1340
|
-
suilendClient.repay(obligationId, borrowReserve.coinType,
|
|
1341
|
-
txCopy.transferObjects([
|
|
1394
|
+
suilendClient.repay(obligationId, borrowReserve.coinType, swapCoin, txCopy);
|
|
1395
|
+
txCopy.transferObjects([swapCoin], _address); // Transfer remaining to user
|
|
1342
1396
|
yield dryRunTransaction(txCopy); // Throws error if fails
|
|
1343
1397
|
transaction = txCopy;
|
|
1344
1398
|
}
|
|
1345
1399
|
catch (err) {
|
|
1346
1400
|
// Don't block user if fails
|
|
1347
1401
|
console.error(err);
|
|
1348
|
-
transaction.transferObjects([
|
|
1402
|
+
transaction.transferObjects([swapCoin], _address); // Transfer to user
|
|
1349
1403
|
}
|
|
1350
1404
|
// 4.2) Update state
|
|
1351
1405
|
borrowedAmount = bignumber_js_1.default.max(borrowedAmount.minus(repaidAmount), new bignumber_js_1.default(0));
|
|
@@ -1356,7 +1410,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1356
1410
|
})),
|
|
1357
1411
|
borrowedAmount: borrowedAmount.toFixed(20),
|
|
1358
1412
|
}, null, 2));
|
|
1359
|
-
// 5) Swap remaining
|
|
1413
|
+
// 5) Swap remaining to base and redeposit (not possible because coin is a mutable reference (?))
|
|
1360
1414
|
});
|
|
1361
1415
|
for (let i = 0; i < 30; i++) {
|
|
1362
1416
|
const exposure = (0, exports.getStrategyExposure)(reserveMap, lstMap, strategyType, (0, exports.getStrategySimulatedObligation)(reserveMap, lstMap, strategyType, deposits, borrowedAmount));
|
|
@@ -1382,7 +1436,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1382
1436
|
if (lstDeposit.depositedAmount.lte(exports.STRATEGY_E)) {
|
|
1383
1437
|
// 1. MAX withdraws LST (transferred to user as SUI)
|
|
1384
1438
|
// 2. Withdraws base to cover borrows
|
|
1385
|
-
// - Leftover transferred to user as borrow coinType, e.g. SUI or
|
|
1439
|
+
// - Leftover transferred to user as borrow coinType, e.g. SUI or suiWBTC
|
|
1386
1440
|
yield fullyRepayBorrowsUsingBase();
|
|
1387
1441
|
break;
|
|
1388
1442
|
}
|
|
@@ -1390,7 +1444,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1390
1444
|
if (pendingBorrowedAmount.lte(exports.STRATEGY_E)) {
|
|
1391
1445
|
try {
|
|
1392
1446
|
// 1. Withdraws LST to cover borrows
|
|
1393
|
-
// - Leftover transferred to user as borrow coinType, e.g. SUI or
|
|
1447
|
+
// - Leftover transferred to user as borrow coinType, e.g. SUI or suiWBTC
|
|
1394
1448
|
// 2. MAX withdraws remaining LST and redeposits as base
|
|
1395
1449
|
yield fullyRepayBorrowsUsingLst(true);
|
|
1396
1450
|
break;
|
|
@@ -1400,7 +1454,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1400
1454
|
}
|
|
1401
1455
|
// 1. MAX withdraws LST (transferred to user as SUI)
|
|
1402
1456
|
// 2. Withdraws base to cover borrows
|
|
1403
|
-
// - Leftover transferred to user as borrow coinType, e.g. SUI or
|
|
1457
|
+
// - Leftover transferred to user as borrow coinType, e.g. SUI or suiWBTC
|
|
1404
1458
|
yield fullyRepayBorrowsUsingBase();
|
|
1405
1459
|
break;
|
|
1406
1460
|
}
|
|
@@ -1409,7 +1463,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1409
1463
|
// Borrows almost fully repaid
|
|
1410
1464
|
if (pendingBorrowedAmount.lte(exports.STRATEGY_E)) {
|
|
1411
1465
|
// 1. Withdraws LST to cover borrows
|
|
1412
|
-
// - Leftover transferred to user as borrow coinType, e.g. SUI or
|
|
1466
|
+
// - Leftover transferred to user as borrow coinType, e.g. SUI or suiWBTC
|
|
1413
1467
|
yield fullyRepayBorrowsUsingLst(false);
|
|
1414
1468
|
break;
|
|
1415
1469
|
}
|
|
@@ -1512,7 +1566,7 @@ transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
1512
1566
|
// Borrows almost fully repaid
|
|
1513
1567
|
if (pendingBorrowedAmount.lte(exports.STRATEGY_E)) {
|
|
1514
1568
|
// 1. Withdraws base to cover borrows
|
|
1515
|
-
// - Leftover transferred to user as borrow coinType, e.g. SUI or
|
|
1569
|
+
// - Leftover transferred to user as borrow coinType, e.g. SUI or suiWBTC
|
|
1516
1570
|
yield fullyRepayBorrowsUsingBase();
|
|
1517
1571
|
break;
|
|
1518
1572
|
}
|
|
@@ -2006,6 +2060,176 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2006
2060
|
return { deposits, borrowedAmount, transaction };
|
|
2007
2061
|
});
|
|
2008
2062
|
exports.strategyMaxWithdrawTx = strategyMaxWithdrawTx;
|
|
2063
|
+
const strategyAdjustRepayTx = (
|
|
2064
|
+
// AppContext
|
|
2065
|
+
reserveMap,
|
|
2066
|
+
// Strategy
|
|
2067
|
+
lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, _deposits, _borrowedAmount, flashLoanBorrowedAmount, transaction, dryRunTransaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
2068
|
+
var _a, _b, _c, _d;
|
|
2069
|
+
const strategyInfo = strategyOwnerCap_1.STRATEGY_TYPE_INFO_MAP[strategyType];
|
|
2070
|
+
const lst = strategyInfo.depositLstCoinType !== undefined
|
|
2071
|
+
? lstMap[strategyInfo.depositLstCoinType]
|
|
2072
|
+
: undefined;
|
|
2073
|
+
const depositReserves = (0, exports.getStrategyDepositReserves)(reserveMap, strategyType);
|
|
2074
|
+
const borrowReserve = (0, exports.getStrategyBorrowReserve)(reserveMap, strategyType);
|
|
2075
|
+
const defaultCurrencyReserve = (0, exports.getStrategyDefaultCurrencyReserve)(reserveMap, strategyType);
|
|
2076
|
+
const adjustRepayExposure = exports.STRATEGY_TYPE_EXPOSURE_MAP[strategyType].min;
|
|
2077
|
+
console.log(`[strategyAdjustRepay] args |`, JSON.stringify({
|
|
2078
|
+
_address,
|
|
2079
|
+
strategyOwnerCapId,
|
|
2080
|
+
obligationId,
|
|
2081
|
+
_deposits: _deposits.map((d) => ({
|
|
2082
|
+
coinType: d.coinType,
|
|
2083
|
+
depositedAmount: d.depositedAmount.toFixed(20),
|
|
2084
|
+
})),
|
|
2085
|
+
_borrowedAmount: _borrowedAmount.toFixed(20),
|
|
2086
|
+
flashLoanBorrowedAmount: flashLoanBorrowedAmount.toFixed(20),
|
|
2087
|
+
}, null, 2));
|
|
2088
|
+
// const depositReserve = (depositReserves.base ?? depositReserves.lst)!; // Must have LST if no base
|
|
2089
|
+
if (!depositReserves.base)
|
|
2090
|
+
throw new Error("Base reserve not found");
|
|
2091
|
+
//
|
|
2092
|
+
let deposits = (0, lodash_1.cloneDeep)(_deposits);
|
|
2093
|
+
let borrowedAmount = _borrowedAmount;
|
|
2094
|
+
// 1) Flash loan base
|
|
2095
|
+
const flashLoanObj = exports.STRATEGY_TYPE_FLASH_LOAN_OBJ_MAP[strategyType];
|
|
2096
|
+
let borrowedBalanceA, borrowedBalanceB, receipt;
|
|
2097
|
+
if (flashLoanObj.provider === StrategyFlashLoanProvider.MMT) {
|
|
2098
|
+
[borrowedBalanceA, borrowedBalanceB, receipt] = transaction.moveCall({
|
|
2099
|
+
target: `${mmt_1.MMT_CONTRACT_PACKAGE_ID}::trade::flash_loan`,
|
|
2100
|
+
typeArguments: [flashLoanObj.coinTypeA, flashLoanObj.coinTypeB],
|
|
2101
|
+
arguments: [
|
|
2102
|
+
transaction.object(flashLoanObj.poolId),
|
|
2103
|
+
transaction.pure.u64(flashLoanObj.borrowA
|
|
2104
|
+
? flashLoanBorrowedAmount
|
|
2105
|
+
.times(10 ** depositReserves.base.token.decimals)
|
|
2106
|
+
.integerValue(bignumber_js_1.default.ROUND_DOWN)
|
|
2107
|
+
.toString()
|
|
2108
|
+
: 0),
|
|
2109
|
+
transaction.pure.u64(flashLoanObj.borrowA
|
|
2110
|
+
? 0
|
|
2111
|
+
: flashLoanBorrowedAmount
|
|
2112
|
+
.times(10 ** depositReserves.base.token.decimals)
|
|
2113
|
+
.integerValue(bignumber_js_1.default.ROUND_DOWN)
|
|
2114
|
+
.toString()),
|
|
2115
|
+
transaction.object(mmt_1.MMT_VERSION_OBJECT_ID),
|
|
2116
|
+
],
|
|
2117
|
+
});
|
|
2118
|
+
}
|
|
2119
|
+
else {
|
|
2120
|
+
throw new Error("Invalid flash loan provider");
|
|
2121
|
+
}
|
|
2122
|
+
const flashLoanBorrowedCoin = transaction.moveCall({
|
|
2123
|
+
target: "0x2::coin::from_balance",
|
|
2124
|
+
typeArguments: [
|
|
2125
|
+
flashLoanObj.borrowA ? flashLoanObj.coinTypeA : flashLoanObj.coinTypeB,
|
|
2126
|
+
],
|
|
2127
|
+
arguments: [flashLoanObj.borrowA ? borrowedBalanceA : borrowedBalanceB],
|
|
2128
|
+
});
|
|
2129
|
+
// 2) Swap flash loaned base for borrow
|
|
2130
|
+
// 2.1) Get routers
|
|
2131
|
+
const routers = yield cetusSdk.findRouters({
|
|
2132
|
+
from: depositReserves.base.coinType,
|
|
2133
|
+
target: borrowReserve.coinType,
|
|
2134
|
+
amount: new bn_js_1.BN(flashLoanBorrowedAmount
|
|
2135
|
+
.times(10 ** depositReserves.base.token.decimals)
|
|
2136
|
+
.integerValue(bignumber_js_1.default.ROUND_DOWN)
|
|
2137
|
+
.toString()),
|
|
2138
|
+
byAmountIn: true,
|
|
2139
|
+
});
|
|
2140
|
+
if (!routers)
|
|
2141
|
+
throw new Error("No swap quote found");
|
|
2142
|
+
console.log(`[strategyAdjustRepay] swap_flash_loan_base_for_borrows.get_routers`, {
|
|
2143
|
+
routers,
|
|
2144
|
+
amountIn: new bignumber_js_1.default(routers.amountIn.toString())
|
|
2145
|
+
.div(10 ** depositReserves.base.token.decimals)
|
|
2146
|
+
.decimalPlaces(depositReserves.base.token.decimals, bignumber_js_1.default.ROUND_DOWN)
|
|
2147
|
+
.toFixed(20),
|
|
2148
|
+
amountOut: new bignumber_js_1.default(routers.amountOut.toString())
|
|
2149
|
+
.div(10 ** borrowReserve.token.decimals)
|
|
2150
|
+
.decimalPlaces(borrowReserve.token.decimals, bignumber_js_1.default.ROUND_DOWN)
|
|
2151
|
+
.toFixed(20),
|
|
2152
|
+
});
|
|
2153
|
+
// 2.2) Swap
|
|
2154
|
+
let swapCoin;
|
|
2155
|
+
try {
|
|
2156
|
+
swapCoin = yield cetusSdk.fixableRouterSwapV3({
|
|
2157
|
+
router: routers,
|
|
2158
|
+
inputCoin: flashLoanBorrowedCoin,
|
|
2159
|
+
slippage: 1 / 100,
|
|
2160
|
+
txb: transaction,
|
|
2161
|
+
partner: cetusPartnerId,
|
|
2162
|
+
});
|
|
2163
|
+
}
|
|
2164
|
+
catch (err) {
|
|
2165
|
+
throw new Error("No swap quote found");
|
|
2166
|
+
}
|
|
2167
|
+
// 3) Fully repay borrows
|
|
2168
|
+
// 3.1) Repay
|
|
2169
|
+
suilendClient.repay(obligationId, borrowReserve.coinType, swapCoin, transaction);
|
|
2170
|
+
transaction.transferObjects([swapCoin], _address); // Transfer remaining to user
|
|
2171
|
+
// 3.2) Update state
|
|
2172
|
+
borrowedAmount = new bignumber_js_1.default(0);
|
|
2173
|
+
console.log(`[strategyAdjustRepay] repay_borrows.update_state |`, JSON.stringify({
|
|
2174
|
+
deposits: deposits.map((d) => ({
|
|
2175
|
+
coinType: d.coinType,
|
|
2176
|
+
depositedAmount: d.depositedAmount.toFixed(20),
|
|
2177
|
+
})),
|
|
2178
|
+
borrowedAmount: borrowedAmount.toFixed(20),
|
|
2179
|
+
}, null, 2));
|
|
2180
|
+
// 4) Swap remaining to base and redeposit (not possible because coin is a mutable reference (?))
|
|
2181
|
+
// 5) Repay flash loan + fee
|
|
2182
|
+
const receiptDebts = transaction.moveCall({
|
|
2183
|
+
target: `${mmt_1.MMT_CONTRACT_PACKAGE_ID}::trade::flash_receipt_debts`,
|
|
2184
|
+
typeArguments: [],
|
|
2185
|
+
arguments: [receipt],
|
|
2186
|
+
});
|
|
2187
|
+
const dryRunResults = yield dryRunTransaction(transaction);
|
|
2188
|
+
const flashLoanRepayAmount = new bignumber_js_1.default(bcs_1.bcs
|
|
2189
|
+
.u64()
|
|
2190
|
+
.parse(new Uint8Array((_d = (_c = (_b = (_a = dryRunResults.results) === null || _a === void 0 ? void 0 : _a.find((r, index) => index === receiptDebts.Result)) === null || _b === void 0 ? void 0 : _b.returnValues) === null || _c === void 0 ? void 0 : _c[flashLoanObj.borrowA ? 0 : 1][0]) !== null && _d !== void 0 ? _d : [0])))
|
|
2191
|
+
.div(10 ** depositReserves.base.token.decimals)
|
|
2192
|
+
.decimalPlaces(depositReserves.base.token.decimals, bignumber_js_1.default.ROUND_UP);
|
|
2193
|
+
// 5.1) Withdraw base + fee
|
|
2194
|
+
const withdrawnAmount = flashLoanRepayAmount;
|
|
2195
|
+
const { deposits: newDeposits2, borrowedAmount: newBorrowedAmount2, transaction: newTransaction2, withdrawnCoin, } = yield (0, exports.strategyWithdrawTx)(reserveMap, lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _address, strategyOwnerCapId, obligationId, deposits, borrowedAmount, {
|
|
2196
|
+
coinType: depositReserves.base.coinType,
|
|
2197
|
+
withdrawnAmount,
|
|
2198
|
+
}, transaction, dryRunTransaction, true);
|
|
2199
|
+
if (!withdrawnCoin)
|
|
2200
|
+
throw new Error("Withdrawn coin not found");
|
|
2201
|
+
// 5.2) Update state
|
|
2202
|
+
deposits = newDeposits2;
|
|
2203
|
+
borrowedAmount = newBorrowedAmount2;
|
|
2204
|
+
transaction = newTransaction2;
|
|
2205
|
+
// 5.3) Repay flash loan
|
|
2206
|
+
const flashLoanRepayCoin = withdrawnCoin;
|
|
2207
|
+
const flashLoanRepayBalance = transaction.moveCall({
|
|
2208
|
+
target: "0x2::coin::into_balance",
|
|
2209
|
+
typeArguments: [
|
|
2210
|
+
flashLoanObj.borrowA ? flashLoanObj.coinTypeA : flashLoanObj.coinTypeB,
|
|
2211
|
+
],
|
|
2212
|
+
arguments: [flashLoanRepayCoin],
|
|
2213
|
+
});
|
|
2214
|
+
if (flashLoanObj.provider === StrategyFlashLoanProvider.MMT) {
|
|
2215
|
+
transaction.moveCall({
|
|
2216
|
+
target: `${mmt_1.MMT_CONTRACT_PACKAGE_ID}::trade::repay_flash_loan`,
|
|
2217
|
+
typeArguments: [flashLoanObj.coinTypeA, flashLoanObj.coinTypeB],
|
|
2218
|
+
arguments: [
|
|
2219
|
+
transaction.object(flashLoanObj.poolId),
|
|
2220
|
+
receipt,
|
|
2221
|
+
flashLoanObj.borrowA ? flashLoanRepayBalance : borrowedBalanceA,
|
|
2222
|
+
flashLoanObj.borrowA ? borrowedBalanceB : flashLoanRepayBalance,
|
|
2223
|
+
transaction.object(mmt_1.MMT_VERSION_OBJECT_ID),
|
|
2224
|
+
],
|
|
2225
|
+
});
|
|
2226
|
+
}
|
|
2227
|
+
else {
|
|
2228
|
+
throw new Error("Invalid flash loan provider");
|
|
2229
|
+
}
|
|
2230
|
+
return { deposits, borrowedAmount, transaction };
|
|
2231
|
+
});
|
|
2232
|
+
exports.strategyAdjustRepayTx = strategyAdjustRepayTx;
|
|
2009
2233
|
const strategyDepositAdjustWithdrawTx = (
|
|
2010
2234
|
// AppContext
|
|
2011
2235
|
reserveMap,
|
|
@@ -2035,7 +2259,7 @@ lstMap, strategyType, suiClient, suilendClient, cetusSdk, cetusPartnerId, _addre
|
|
|
2035
2259
|
//
|
|
2036
2260
|
let deposits = (0, lodash_1.cloneDeep)(_deposits);
|
|
2037
2261
|
let borrowedAmount = _borrowedAmount;
|
|
2038
|
-
// 1) Flash loan
|
|
2262
|
+
// 1) Flash loan base/LST
|
|
2039
2263
|
const flashLoanObj = exports.STRATEGY_TYPE_FLASH_LOAN_OBJ_MAP[strategyType];
|
|
2040
2264
|
if (depositReserve.coinType === ((_b = depositReserves.lst) === null || _b === void 0 ? void 0 : _b.coinType)) {
|
|
2041
2265
|
// TODO: Account for LST mint fees
|