@strkfarm/sdk 2.0.0-dev.1 → 2.0.0-dev.3
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/dist/index.browser.global.js +319 -104
- package/dist/index.browser.mjs +319 -104
- package/dist/index.d.ts +31 -5
- package/dist/index.js +319 -104
- package/dist/index.mjs +319 -104
- package/package.json +1 -1
- package/src/dataTypes/address.ts +1 -1
- package/src/modules/ekubo-quoter.ts +1 -12
- package/src/strategies/universal-adapters/avnu-adapter.ts +7 -11
- package/src/strategies/universal-adapters/extended-adapter.ts +128 -11
- package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +16 -16
- package/src/strategies/vesu-extended-strategy/services/operationService.ts +8 -2
- package/src/strategies/vesu-extended-strategy/utils/constants.ts +1 -0
- package/src/strategies/vesu-extended-strategy/utils/helper.ts +15 -17
- package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +212 -64
package/package.json
CHANGED
package/src/dataTypes/address.ts
CHANGED
|
@@ -70,21 +70,14 @@ export class EkuboQuoter {
|
|
|
70
70
|
async getDexPrice(baseToken: TokenInfo, quoteToken: TokenInfo, amount: Web3Number) {
|
|
71
71
|
const lstTokenInfo = baseToken;
|
|
72
72
|
const lstUnderlyingTokenInfo = quoteToken;
|
|
73
|
-
console.log("lstTokenInfo", lstTokenInfo);
|
|
74
|
-
console.log("lstUnderlyingTokenInfo", lstUnderlyingTokenInfo);
|
|
75
|
-
console.log("amount", amount);
|
|
76
73
|
const quote = await this.getQuote(
|
|
77
74
|
lstTokenInfo.address.address,
|
|
78
75
|
lstUnderlyingTokenInfo.address.address,
|
|
79
76
|
amount
|
|
80
77
|
);
|
|
81
|
-
console.log("quote", quote);
|
|
82
78
|
// in Underlying
|
|
83
79
|
const outputAmount = Web3Number.fromWei(quote.total_calculated, lstUnderlyingTokenInfo.decimals);
|
|
84
|
-
console.log("outputAmount", outputAmount);
|
|
85
|
-
console.log("amount", amount);
|
|
86
80
|
const price = outputAmount.toNumber() / amount.toNumber();
|
|
87
|
-
console.log("price", price);
|
|
88
81
|
logger.verbose(`${EkuboQuoter.name}:: LST Dex Price: ${price}`);
|
|
89
82
|
return price;
|
|
90
83
|
}
|
|
@@ -105,7 +98,6 @@ export class EkuboQuoter {
|
|
|
105
98
|
// debt collateral
|
|
106
99
|
async getSwapLimitAmount(fromToken: TokenInfo, toToken: TokenInfo, amount: Web3Number, max_slippage: number = 0.002): Promise<Web3Number> {
|
|
107
100
|
const isExactAmountIn = amount.greaterThanOrEqualTo(0);
|
|
108
|
-
console.log("isExactAmountIn", isExactAmountIn);
|
|
109
101
|
logger.verbose(`${EkuboQuoter.name}::getSwapLimitAmount isExactAmountIn: ${isExactAmountIn}, fromToken: ${fromToken.symbol}, toToken: ${toToken.symbol}, amount: ${amount}`);
|
|
110
102
|
const isYieldToken = this.tokenMarketData.isAPYSupported(toToken);
|
|
111
103
|
console.log("isYieldToken", isYieldToken);
|
|
@@ -114,13 +106,10 @@ export class EkuboQuoter {
|
|
|
114
106
|
// wbtc
|
|
115
107
|
const baseToken = isExactAmountIn ? toToken : fromToken; // fromToken -> wbtc,
|
|
116
108
|
const quoteToken = isExactAmountIn ? fromToken : toToken; // toToken -> usdc,
|
|
117
|
-
console.log("baseToken", baseToken);
|
|
118
|
-
console.log("quoteToken", quoteToken);
|
|
119
109
|
// need dex price of from token in toToken
|
|
120
110
|
// from baseToken to underlying token
|
|
121
111
|
// for withdraw, usdc to btc with amount negative
|
|
122
112
|
const dexPrice = await this.getDexPrice(baseToken, quoteToken, amount);
|
|
123
|
-
console.log("dexPrice", dexPrice);
|
|
124
113
|
const trueExchangeRate = isYieldToken ? await this.tokenMarketData.getTruePrice(baseToken) : dexPrice;
|
|
125
114
|
console.log("trueExchangeRate", trueExchangeRate);
|
|
126
115
|
if (isExactAmountIn) {
|
|
@@ -152,9 +141,9 @@ export class EkuboQuoter {
|
|
|
152
141
|
*/
|
|
153
142
|
getVesuMultiplyQuote(quote: EkuboQuote, fromTokenInfo: TokenInfo, toTokenInfo: TokenInfo): Swap[] {
|
|
154
143
|
return quote.splits.map(split => {
|
|
144
|
+
|
|
155
145
|
const isNegativeAmount = BigInt(split.amount_specified) <= 0n;
|
|
156
146
|
const token = isNegativeAmount ? toTokenInfo : fromTokenInfo;
|
|
157
|
-
//console.log("token", token, isNegativeAmount);
|
|
158
147
|
return {
|
|
159
148
|
route: split.route.map(_route => ({
|
|
160
149
|
pool_key: {
|
|
@@ -135,7 +135,7 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
|
|
|
135
135
|
method: "multi_route_swap",
|
|
136
136
|
packedArguments: [
|
|
137
137
|
fromToken.address.toBigInt(), //wbtc
|
|
138
|
-
|
|
138
|
+
toToken.address.toBigInt(), //usdc
|
|
139
139
|
vaultAllocator.toBigInt(),
|
|
140
140
|
],
|
|
141
141
|
sanitizer: SIMPLE_SANITIZER,
|
|
@@ -156,13 +156,11 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
|
|
|
156
156
|
|
|
157
157
|
async getDepositCall(params: DepositParams): Promise<ManageCall[]> {
|
|
158
158
|
try {
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
const toToken = this.config.supportedPositions[1].asset;
|
|
159
|
+
const fromToken = this.config.supportedPositions[0].asset; //usdc
|
|
160
|
+
const toToken = this.config.supportedPositions[1].asset; //wbtc
|
|
162
161
|
const vaultAllocator = ContractAddr.from(
|
|
163
162
|
this.config.vaultAllocator.address
|
|
164
163
|
);
|
|
165
|
-
console.log("vaultAllocator", vaultAllocator);
|
|
166
164
|
const quote = await this.getQuotesAvnu(
|
|
167
165
|
fromToken.address.toString(),
|
|
168
166
|
toToken.address.toString(),
|
|
@@ -171,15 +169,18 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
|
|
|
171
169
|
toToken.decimals,
|
|
172
170
|
true
|
|
173
171
|
)
|
|
172
|
+
//console.log(`${AvnuAdapter.name}::getDepositCall quote: ${JSON.stringify(quote)}`);
|
|
174
173
|
if (!quote) {
|
|
175
174
|
logger.error("error getting quote from avnu");
|
|
176
175
|
return [];
|
|
177
176
|
}
|
|
177
|
+
|
|
178
178
|
const getCalldata = await this.avnuWrapper.getSwapCallData(
|
|
179
179
|
quote,
|
|
180
180
|
vaultAllocator.address
|
|
181
181
|
);
|
|
182
182
|
const swapCallData = getCalldata[0];
|
|
183
|
+
|
|
183
184
|
// const approveCallData = getCalldata[0];
|
|
184
185
|
const amount = uint256.bnToUint256(quote.sellAmountInUsd*10**7)
|
|
185
186
|
return [
|
|
@@ -218,7 +219,6 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
|
|
|
218
219
|
const vaultAllocator = ContractAddr.from(
|
|
219
220
|
this.config.vaultAllocator.address
|
|
220
221
|
);
|
|
221
|
-
console.log("params.amount", params.amount);
|
|
222
222
|
const quote = await this.getQuotesAvnu(
|
|
223
223
|
fromToken.address.toString(),
|
|
224
224
|
toToken.address.toString(),
|
|
@@ -237,8 +237,6 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
|
|
|
237
237
|
);
|
|
238
238
|
const swapCallData = getCalldata[0];
|
|
239
239
|
const amount = uint256.bnToUint256(params.amount.toWei())
|
|
240
|
-
console.log("amount", amount);
|
|
241
|
-
console.log("swapCallData", swapCallData);
|
|
242
240
|
return [
|
|
243
241
|
{
|
|
244
242
|
sanitizer: SIMPLE_SANITIZER,
|
|
@@ -305,7 +303,7 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
|
|
|
305
303
|
toTokenDecimals: number,
|
|
306
304
|
usdcToBtc: boolean,
|
|
307
305
|
maxIterations: number = 5,
|
|
308
|
-
tolerance: number =
|
|
306
|
+
tolerance: number = 1000
|
|
309
307
|
): Promise<Quote | null>{
|
|
310
308
|
try {
|
|
311
309
|
const fromToken = this.config.supportedPositions[0].asset;
|
|
@@ -327,14 +325,12 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
|
|
|
327
325
|
return dataObject;
|
|
328
326
|
}
|
|
329
327
|
const btcPrice = await this.getPriceOfToken(toToken.address.toString());
|
|
330
|
-
console.log("btcPrice", btcPrice);
|
|
331
328
|
if (!btcPrice) {
|
|
332
329
|
logger.error(`error getting btc price: ${btcPrice}`);
|
|
333
330
|
return null;
|
|
334
331
|
}
|
|
335
332
|
const estimatedUsdcAmount = Math.floor(amount * btcPrice);
|
|
336
333
|
const targetBtcBig = BigInt(returnFormattedAmount(amount, toTokenDecimals));
|
|
337
|
-
console.log("targetBtcBig", targetBtcBig);
|
|
338
334
|
let low = BigInt(
|
|
339
335
|
Math.floor(
|
|
340
336
|
(estimatedUsdcAmount * 10 ** fromToken.decimals) * 0.9
|
|
@@ -7,8 +7,10 @@ import { PositionInfo } from "./baseAdapter";
|
|
|
7
7
|
import { ManageCall } from "./baseAdapter";
|
|
8
8
|
import { ContractAddr } from "@/dataTypes";
|
|
9
9
|
import { AVNU_EXCHANGE_FOR_LEGACY_USDC } from "./adapter-utils";
|
|
10
|
+
import { StandardMerkleTree } from "@/utils";
|
|
10
11
|
import { hash, uint256 } from "starknet";
|
|
11
12
|
import { Global } from "@/global";
|
|
13
|
+
import { AdapterLeafType, GenerateCallFn } from "./baseAdapter";
|
|
12
14
|
import { AVNU_LEGACY_SANITIZER, EXTENDED_SANITIZER, SIMPLE_SANITIZER, toBigInt } from "./adapter-utils";
|
|
13
15
|
import ExtendedWrapper, {
|
|
14
16
|
AssetOperationStatus,
|
|
@@ -151,6 +153,50 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
151
153
|
];
|
|
152
154
|
}
|
|
153
155
|
|
|
156
|
+
getSwapFromLegacyLeaf(): AdapterLeafType<DepositParams> {
|
|
157
|
+
const leafConfigs = this._getSwapFromLegacyLeaf();
|
|
158
|
+
const leaves = leafConfigs.map(config => {
|
|
159
|
+
const { target, method, packedArguments, sanitizer, id } = config;
|
|
160
|
+
const leaf = this.constructSimpleLeafData({
|
|
161
|
+
id: id,
|
|
162
|
+
target,
|
|
163
|
+
method,
|
|
164
|
+
packedArguments
|
|
165
|
+
}, sanitizer);
|
|
166
|
+
return leaf;
|
|
167
|
+
});
|
|
168
|
+
return { leaves, callConstructor: this.getSwapFromLegacyCall.bind(this) as unknown as GenerateCallFn<DepositParams> };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
protected _getSwapFromLegacyLeaf(): {
|
|
172
|
+
target: ContractAddr;
|
|
173
|
+
method: string;
|
|
174
|
+
packedArguments: bigint[];
|
|
175
|
+
sanitizer: ContractAddr;
|
|
176
|
+
id: string;
|
|
177
|
+
}[] {
|
|
178
|
+
const usdceToken = Global.getDefaultTokens().find(token => token.symbol === "USDCe");
|
|
179
|
+
return [
|
|
180
|
+
{
|
|
181
|
+
target: usdceToken!.address,
|
|
182
|
+
method: "approve",
|
|
183
|
+
packedArguments: [
|
|
184
|
+
AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt(),
|
|
185
|
+
],
|
|
186
|
+
id: `extendedswaplegacyapprove_${usdceToken!.symbol}`,
|
|
187
|
+
sanitizer: AVNU_LEGACY_SANITIZER,
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
target: AVNU_EXCHANGE_FOR_LEGACY_USDC,
|
|
191
|
+
method: "swap_to_new",
|
|
192
|
+
packedArguments: [],
|
|
193
|
+
id: `extended_swap_to_new_${usdceToken!.symbol}`,
|
|
194
|
+
sanitizer: AVNU_LEGACY_SANITIZER,
|
|
195
|
+
},
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
154
200
|
protected _getWithdrawLeaf(): {
|
|
155
201
|
target: ContractAddr;
|
|
156
202
|
method: string;
|
|
@@ -171,6 +217,7 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
171
217
|
const salt = Math.floor(
|
|
172
218
|
Math.random() * 10 ** usdcToken.decimals
|
|
173
219
|
);
|
|
220
|
+
// Give approval for more amount than the required amount
|
|
174
221
|
const amount = uint256.bnToUint256(params.amount.multipliedBy(10).toWei());
|
|
175
222
|
const quotes = await this.config.avnuAdapter.getQuotesAvnu(
|
|
176
223
|
usdcToken.address.toString(),
|
|
@@ -185,7 +232,6 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
185
232
|
logger.error("error getting quotes from avnu");
|
|
186
233
|
return [];
|
|
187
234
|
}
|
|
188
|
-
|
|
189
235
|
const getCalldata = await this.config.avnuAdapter.getSwapCallData(quotes!);
|
|
190
236
|
const swapCallData = getCalldata[0];
|
|
191
237
|
//change extended sanitizer here
|
|
@@ -241,6 +287,78 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
241
287
|
}
|
|
242
288
|
}
|
|
243
289
|
|
|
290
|
+
getProofsForFromLegacySwap<T>(tree: StandardMerkleTree): { proofs: string[][], callConstructor: GenerateCallFn<DepositParams> | GenerateCallFn<WithdrawParams> } {
|
|
291
|
+
let proofGroups: string[][] = [];
|
|
292
|
+
|
|
293
|
+
const ids = this.getSwapFromLegacyLeaf().leaves.map(l => l.readableId)
|
|
294
|
+
// console.log(`${this.name}::getProofs ids: ${ids}`);
|
|
295
|
+
for (const [i, v] of tree.entries()) {
|
|
296
|
+
// console.log(`${this.name}::getProofs v: ${v.readableId}`);
|
|
297
|
+
if (ids.includes(v.readableId)) {
|
|
298
|
+
//console.log(`${this.name}::getProofs found id: ${v.readableId}`);
|
|
299
|
+
proofGroups.push(tree.getProof(i));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (proofGroups.length != ids.length) {
|
|
303
|
+
throw new Error(`Not all proofs found for IDs: ${ids.join(', ')}`);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// find leaf adapter
|
|
307
|
+
return {
|
|
308
|
+
proofs: proofGroups,
|
|
309
|
+
callConstructor: this.getSwapFromLegacyCall.bind(this)
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
async getSwapFromLegacyCall(params: DepositParams): Promise<ManageCall[]> {
|
|
314
|
+
try {
|
|
315
|
+
const usdcToken = this.config.supportedPositions[0].asset;
|
|
316
|
+
const usdceToken = Global.getDefaultTokens().find(token => token.symbol === "USDCe");
|
|
317
|
+
// Give approval for more amount than the required amount
|
|
318
|
+
const amount = uint256.bnToUint256(params.amount.multipliedBy(10).toWei());
|
|
319
|
+
const quotes = await this.config.avnuAdapter.getQuotesAvnu(
|
|
320
|
+
usdceToken!.address.toString(),
|
|
321
|
+
usdcToken!.address.toString(),
|
|
322
|
+
params.amount.toNumber(),
|
|
323
|
+
this.config.avnuAdapter.config.vaultAllocator.address.toString(),
|
|
324
|
+
usdcToken!.decimals,
|
|
325
|
+
false
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
if (!quotes) {
|
|
329
|
+
logger.error("error getting quotes from avnu");
|
|
330
|
+
return [];
|
|
331
|
+
}
|
|
332
|
+
const getCalldata = await this.config.avnuAdapter.getSwapCallData(quotes!);
|
|
333
|
+
const swapCallData = getCalldata[0];
|
|
334
|
+
//change extended sanitizer here
|
|
335
|
+
return [
|
|
336
|
+
{
|
|
337
|
+
sanitizer: AVNU_LEGACY_SANITIZER,
|
|
338
|
+
call: {
|
|
339
|
+
contractAddress: usdceToken!.address,
|
|
340
|
+
selector: hash.getSelectorFromName("approve"),
|
|
341
|
+
calldata: [
|
|
342
|
+
AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt(),
|
|
343
|
+
toBigInt(amount.low.toString()), // amount low
|
|
344
|
+
toBigInt(amount.high.toString()), // amount high
|
|
345
|
+
],
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
sanitizer: AVNU_LEGACY_SANITIZER,
|
|
350
|
+
call: {
|
|
351
|
+
contractAddress: AVNU_EXCHANGE_FOR_LEGACY_USDC,
|
|
352
|
+
selector: hash.getSelectorFromName("swap_to_new"),
|
|
353
|
+
calldata: swapCallData,
|
|
354
|
+
},
|
|
355
|
+
}
|
|
356
|
+
];
|
|
357
|
+
} catch (error) {
|
|
358
|
+
logger.error(`Error creating Deposit Call: ${error}`);
|
|
359
|
+
return [];
|
|
360
|
+
}
|
|
361
|
+
}
|
|
244
362
|
//Swap wbtc to usdc
|
|
245
363
|
async getWithdrawCall(params: WithdrawParams): Promise<ManageCall[]> {
|
|
246
364
|
try {
|
|
@@ -259,10 +377,10 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
259
377
|
if (!this.client) {
|
|
260
378
|
throw new Error("Client not initialized");
|
|
261
379
|
}
|
|
262
|
-
const withdrawalRequest = this.client.withdrawUSDC(amount.
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
-
return
|
|
380
|
+
const withdrawalRequest = await this.client.withdrawUSDC(amount.toFixed(2));
|
|
381
|
+
if (withdrawalRequest.status === "OK") {
|
|
382
|
+
const withdrawalStatus = await this.getDepositOrWithdrawalStatus(withdrawalRequest.data, AssetOperationType.WITHDRAWAL);
|
|
383
|
+
return withdrawalStatus;
|
|
266
384
|
}
|
|
267
385
|
return false;
|
|
268
386
|
} catch (error) {
|
|
@@ -470,7 +588,7 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
470
588
|
|
|
471
589
|
if (attempt < maxAttempts) {
|
|
472
590
|
const backoff = 1200 * attempt;
|
|
473
|
-
|
|
591
|
+
logger.info(`Retrying after ${backoff}ms...`);
|
|
474
592
|
await new Promise((resolve) => setTimeout(resolve, backoff));
|
|
475
593
|
return this.createOrder(
|
|
476
594
|
leverage,
|
|
@@ -511,7 +629,7 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
511
629
|
}
|
|
512
630
|
return null;
|
|
513
631
|
} catch (err) {
|
|
514
|
-
|
|
632
|
+
logger.error(`Error opening short extended position, ${err}`);
|
|
515
633
|
return null;
|
|
516
634
|
}
|
|
517
635
|
}
|
|
@@ -522,17 +640,16 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
522
640
|
operationsType:[operationsType],
|
|
523
641
|
operationsStatus:[AssetOperationStatus.COMPLETED]
|
|
524
642
|
})
|
|
525
|
-
console.log("transferHistory", transferHistory);
|
|
526
643
|
if(operationsType === AssetOperationType.DEPOSIT){
|
|
527
644
|
const myTransferStatus = transferHistory.data.find(operation => operation.transactionHash === orderId);
|
|
528
645
|
if (!myTransferStatus) {
|
|
529
|
-
return
|
|
646
|
+
return true;
|
|
530
647
|
}
|
|
531
648
|
return true;
|
|
532
649
|
}else{
|
|
533
|
-
const myTransferStatus = transferHistory.data.find(operation => operation.id === orderId);
|
|
650
|
+
const myTransferStatus = transferHistory.data.find(operation => operation.id.toString() === orderId.toString());
|
|
534
651
|
if (!myTransferStatus) {
|
|
535
|
-
return
|
|
652
|
+
return true;
|
|
536
653
|
}
|
|
537
654
|
return true;
|
|
538
655
|
}
|
|
@@ -392,7 +392,7 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
|
|
|
392
392
|
this.config.debt.address.toBigInt(),
|
|
393
393
|
this.config.vaultAllocator.toBigInt(),
|
|
394
394
|
],
|
|
395
|
-
sanitizer: SIMPLE_SANITIZER_V2,
|
|
395
|
+
sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
|
|
396
396
|
// vmw = vesu multiply withdraw
|
|
397
397
|
id: `vmw_${this.config.poolId.shortString()}_${collateral.symbol}_${debt.symbol}`
|
|
398
398
|
},
|
|
@@ -531,7 +531,7 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
|
|
|
531
531
|
},
|
|
532
532
|
// Vesu multiply call
|
|
533
533
|
{
|
|
534
|
-
sanitizer: SIMPLE_SANITIZER_V2,
|
|
534
|
+
sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
|
|
535
535
|
call: {
|
|
536
536
|
contractAddress: vesuMultiply,
|
|
537
537
|
selector: hash.getSelectorFromName('modify_lever'),
|
|
@@ -664,21 +664,21 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
|
|
|
664
664
|
if (debtAmount.greaterThan(0)) {
|
|
665
665
|
// For increase: minimum amount of collateral received
|
|
666
666
|
// from debt token to collateral token
|
|
667
|
-
console.log("debtAmountInCollateralUnits", debtAmountInCollateralUnits.toNumber());
|
|
668
|
-
leverSwapLimitAmount = await ekuboQuoter.getSwapLimitAmount(debtToken, collateralToken, debtAmount, MAX_SLIPPAGE);
|
|
669
|
-
|
|
670
|
-
console.log("anotherleverSwapLimitAmount", anotherleverSwapLimitAmount, leverSwapLimitAmount);
|
|
667
|
+
//console.log("debtAmountInCollateralUnits", debtAmountInCollateralUnits.toNumber());
|
|
668
|
+
//leverSwapLimitAmount = await ekuboQuoter.getSwapLimitAmount(debtToken, collateralToken, debtAmount, MAX_SLIPPAGE);
|
|
669
|
+
leverSwapLimitAmount = debtAmount.multipliedBy(1 + MAX_SLIPPAGE);
|
|
670
|
+
//console.log("anotherleverSwapLimitAmount", anotherleverSwapLimitAmount, leverSwapLimitAmount);
|
|
671
671
|
} else if (debtAmount.lessThan(0)) {
|
|
672
672
|
// For decrease: maximum amount of collateral used
|
|
673
673
|
// from collateral token to debt token
|
|
674
|
-
leverSwapLimitAmount = await ekuboQuoter.getSwapLimitAmount(collateralToken, debtToken, debtAmountInCollateralUnits.multipliedBy(-1), MAX_SLIPPAGE);
|
|
675
|
-
|
|
676
|
-
console.log("anotherleverSwapLimitAmount", anotherleverSwapLimitAmount, leverSwapLimitAmount);
|
|
674
|
+
//leverSwapLimitAmount = await ekuboQuoter.getSwapLimitAmount(collateralToken, debtToken, debtAmountInCollateralUnits.multipliedBy(-1), MAX_SLIPPAGE);
|
|
675
|
+
leverSwapLimitAmount = debtAmount.abs().multipliedBy(1 - MAX_SLIPPAGE);
|
|
676
|
+
//console.log("anotherleverSwapLimitAmount", anotherleverSwapLimitAmount, leverSwapLimitAmount);
|
|
677
677
|
} else {
|
|
678
678
|
leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
|
|
679
679
|
}
|
|
680
680
|
await new Promise((resolve) => setTimeout(resolve, 10000));
|
|
681
|
-
console.log("leverSwapLimitAmount", leverSwapLimitAmount);
|
|
681
|
+
//console.log("leverSwapLimitAmount", leverSwapLimitAmount);
|
|
682
682
|
} else {
|
|
683
683
|
throw new Error(`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`);
|
|
684
684
|
}
|
|
@@ -754,26 +754,26 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
|
|
|
754
754
|
debtPrice.price,
|
|
755
755
|
debtToken.decimals
|
|
756
756
|
);
|
|
757
|
-
console.log("debtAmountToRepay", debtAmountToRepay);
|
|
757
|
+
//console.log("debtAmountToRepay", debtAmountToRepay);
|
|
758
758
|
if(!debtAmountToRepay) {
|
|
759
759
|
throw new Error("error calculating debt amount to repay");
|
|
760
760
|
}
|
|
761
761
|
const ekuboQuoter = new EkuboQuoter(this.config.networkConfig, this.config.pricer);
|
|
762
762
|
const debtInDebtUnits = new Web3Number(debtAmountToRepay, debtToken.decimals).dividedBy(debtPrice.price).multipliedBy(10 ** debtToken.decimals);
|
|
763
|
-
const debtInCollateralUnits = new Web3Number(debtAmountToRepay, debtToken.decimals).dividedBy(collateralPrice.price).multipliedBy(10 ** collateralToken.decimals);
|
|
764
763
|
const swapQuote = await ekuboQuoter.getQuote(
|
|
765
764
|
debtToken.address.address,
|
|
766
765
|
collateralToken.address.address,
|
|
767
766
|
debtInDebtUnits
|
|
768
767
|
)
|
|
769
768
|
const MAX_SLIPPAGE = 0.002; // 0.2% slippag
|
|
770
|
-
if(swapQuote.price_impact < 0.
|
|
771
|
-
leverSwap = ekuboQuoter.getVesuMultiplyQuote(swapQuote,
|
|
769
|
+
if(swapQuote.price_impact < 0.0025) {
|
|
770
|
+
leverSwap = ekuboQuoter.getVesuMultiplyQuote(swapQuote, collateralToken, debtToken);
|
|
772
771
|
} else {
|
|
773
772
|
logger.error(`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`);
|
|
774
773
|
}
|
|
775
|
-
|
|
776
|
-
leverSwapLimitAmount =
|
|
774
|
+
|
|
775
|
+
leverSwapLimitAmount = new Web3Number(debtAmountToRepay, debtToken.decimals).abs().multipliedBy(1 + MAX_SLIPPAGE);
|
|
776
|
+
//leverSwapLimitAmount = await ekuboQuoter.getSwapLimitAmount(debtToken, collateralToken, debtInCollateralUnits, MAX_SLIPPAGE);
|
|
777
777
|
const multiplyParams = await this.getLeverParams(false, params, leverSwap, leverSwapLimitAmount);
|
|
778
778
|
const call = multiplyContract.populate('modify_lever', {
|
|
779
779
|
modify_lever_params: this.formatMultiplyParams(false, multiplyParams)
|
|
@@ -19,10 +19,16 @@ export abstract class Operations {
|
|
|
19
19
|
params: { from: string; to: string; amount: Web3Number },
|
|
20
20
|
extendedAdapter: ExtendedAdapter,
|
|
21
21
|
vesuAdapter: VesuMultiplyAdapter
|
|
22
|
-
): Promise<
|
|
22
|
+
): Promise<{
|
|
23
|
+
calls: Call[];
|
|
24
|
+
status: boolean;
|
|
25
|
+
}>;
|
|
23
26
|
abstract handleDeposit(): Promise<{
|
|
24
27
|
extendedAmountInBTC: Web3Number;
|
|
25
28
|
calls: Call[];
|
|
26
29
|
}>;
|
|
27
|
-
abstract handleWithdraw(amount: Web3Number): Promise<
|
|
30
|
+
abstract handleWithdraw(amount: Web3Number): Promise<{
|
|
31
|
+
calls: Call[];
|
|
32
|
+
status: boolean;
|
|
33
|
+
}> ;
|
|
28
34
|
}
|
|
@@ -3,6 +3,7 @@ export const SLIPPAGE = 0.01;
|
|
|
3
3
|
export const USDC_TOKEN_DECIMALS = 6;
|
|
4
4
|
export const USDC_TOKEN_ADDRESS =
|
|
5
5
|
"0x053C91253BC9682c04929cA02ED00b3E423f6710D2ee7e0D5EBB06F3eCF368A8";
|
|
6
|
+
export const BUFFER_USDC_IN_WITHDRAWAL=5;
|
|
6
7
|
export const WBTC_TOKEN_ADDRESS = "0x3fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac";
|
|
7
8
|
export const WBTC_TOKEN_DECIMALS = 8;
|
|
8
9
|
export const MAINTENANCE_MARGIN = 0.01;
|
|
@@ -127,14 +127,10 @@ export const calculateAmountDistributionForWithdrawal = async (
|
|
|
127
127
|
logger.error("error getting extended positions");
|
|
128
128
|
return null;
|
|
129
129
|
}
|
|
130
|
-
const extendedBTCExposure =
|
|
131
|
-
extendedPosition.length > 0
|
|
132
|
-
? new Web3Number(extendedPosition[0].size, WBTC_TOKEN_DECIMALS)
|
|
133
|
-
: new Web3Number(0, WBTC_TOKEN_DECIMALS);
|
|
134
130
|
const extendedExposureUSD =
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
131
|
+
extendedPosition.length > 0
|
|
132
|
+
? new Web3Number(extendedPosition[0].value, USDC_TOKEN_DECIMALS)
|
|
133
|
+
: new Web3Number(0, USDC_TOKEN_DECIMALS);
|
|
138
134
|
const vesuExposureUSD = collateralUnits.multipliedBy(collateralPrice);
|
|
139
135
|
if (vesuExposureUSD.lessThan(0)) {
|
|
140
136
|
return {
|
|
@@ -152,11 +148,14 @@ export const calculateAmountDistributionForWithdrawal = async (
|
|
|
152
148
|
vesu_leverage,
|
|
153
149
|
};
|
|
154
150
|
}
|
|
155
|
-
|
|
151
|
+
console.log("the vesu exposure usd is", vesuExposureUSD.toNumber());
|
|
152
|
+
console.log("the extended exposure usd is", extendedExposureUSD.toNumber());
|
|
153
|
+
console.log("the amount in usdc is", amountInUsdc.toNumber());
|
|
154
|
+
console.log("the extended leverage is", extended_leverage);
|
|
155
|
+
console.log("the vesu leverage is", vesu_leverage);
|
|
156
156
|
const numerator1 = amountInUsdc.multipliedBy(extended_leverage);
|
|
157
|
-
const numerator2 = vesuExposureUSD
|
|
157
|
+
const numerator2 = vesuExposureUSD;
|
|
158
158
|
const numerator3 = extendedExposureUSD
|
|
159
|
-
.multipliedBy(extended_leverage)
|
|
160
159
|
.multipliedBy(-1);
|
|
161
160
|
const finalNumerator = numerator1.plus(numerator2).plus(numerator3);
|
|
162
161
|
const denominator = extended_leverage + vesu_leverage;
|
|
@@ -168,8 +167,8 @@ export const calculateAmountDistributionForWithdrawal = async (
|
|
|
168
167
|
extendedAmountInUSDC.toNumber()
|
|
169
168
|
);
|
|
170
169
|
//console.log("the vesu amount in usdc is", vesuAmountInUSDC.toNumber());
|
|
171
|
-
//console.log("the extended amount in usdc is", extendedAmountInUSDC.toNumber())
|
|
172
|
-
|
|
170
|
+
//console.log("the extended amount in usdc is", extendedAmountInUSDC.toNumber());\
|
|
171
|
+
await new Promise((resolve) => setTimeout(resolve, 10000));
|
|
173
172
|
return {
|
|
174
173
|
vesu_amount: vesuAmountInUSDC,
|
|
175
174
|
extended_amount: extendedAmountInUSDC,
|
|
@@ -221,16 +220,16 @@ export const calculateDebtAmount = (
|
|
|
221
220
|
collateralAmount: Web3Number,
|
|
222
221
|
debtAmount: Web3Number,
|
|
223
222
|
debtPrice: number,
|
|
224
|
-
maxLtv: number =
|
|
223
|
+
maxLtv: number = MAX_LIQUIDATION_RATIO,
|
|
225
224
|
addedAmount: Web3Number, // this is in btc
|
|
226
225
|
collateralPrice: number,
|
|
227
226
|
isDeposit: boolean
|
|
228
227
|
) => {
|
|
229
228
|
try {
|
|
230
229
|
// => X = (((collateral + legDepositAmount) * collateralPrice * ltv) - (debt * debtPrice * target hf)) / (target hf - ltv)
|
|
231
|
-
const
|
|
232
|
-
const numerator1 = collateralAmount
|
|
233
|
-
.plus(
|
|
230
|
+
const addedCollateral = addedAmount.multipliedBy(isDeposit ? 1 : -1);
|
|
231
|
+
const numerator1 = (collateralAmount
|
|
232
|
+
.plus(addedCollateral))
|
|
234
233
|
.multipliedBy(collateralPrice)
|
|
235
234
|
.multipliedBy(maxLtv);
|
|
236
235
|
const numerator2 = debtAmount
|
|
@@ -306,7 +305,6 @@ export const calculateAmountDepositOnExtendedWhenIncurringLosses = async (
|
|
|
306
305
|
const extendedHoldings = await client.getHoldings();
|
|
307
306
|
const extended_leverage = calculateExtendedLevergae();
|
|
308
307
|
const latestPosition = (await client.getPositions()).data.pop();
|
|
309
|
-
console.log("the latest position is", latestPosition, extendedHoldings);
|
|
310
308
|
if (!extendedHoldings || !latestPosition) {
|
|
311
309
|
logger.error(`error getting extended position: extendedHoldings=${extendedHoldings}, latestPosition=${latestPosition}`);
|
|
312
310
|
return null;
|