@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
|
@@ -13,7 +13,7 @@ import { logger } from "@/utils";
|
|
|
13
13
|
import { AUDIT_URL } from "../universal-lst-muliplier-strategy";
|
|
14
14
|
import { getNoRiskTags } from "@/interfaces";
|
|
15
15
|
import { _riskFactor } from "../universal-lst-muliplier-strategy";
|
|
16
|
-
import { EXTENDED_QTY_PRECISION, LIMIT_BALANCE, MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED, MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED, MINIMUM_EXTENDED_POSITION_SIZE, USDC_TOKEN_DECIMALS, WBTC_TOKEN_DECIMALS } from "./utils/constants";
|
|
16
|
+
import { BUFFER_USDC_IN_WITHDRAWAL, EXTENDED_QTY_PRECISION, LIMIT_BALANCE, MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED, MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED, MINIMUM_EXTENDED_POSITION_SIZE, USDC_TOKEN_DECIMALS, WALLET_ADDRESS, WBTC_TOKEN_DECIMALS } from "./utils/constants";
|
|
17
17
|
import { PricerBase } from "@/modules/pricerBase";
|
|
18
18
|
import { ContractAddr, Web3Number } from "@/dataTypes";
|
|
19
19
|
import { Global } from "@/global";
|
|
@@ -108,6 +108,26 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
108
108
|
debtPrice,
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
|
+
|
|
112
|
+
async getUnusedBalanceUSDCE(): Promise<SingleTokenInfo> {
|
|
113
|
+
const usdceToken = Global.getDefaultTokens().find(
|
|
114
|
+
(token) => token.symbol === "USDCe"
|
|
115
|
+
)!;
|
|
116
|
+
const balance = await new ERC20(this.config).balanceOf(
|
|
117
|
+
usdceToken.address,
|
|
118
|
+
WALLET_ADDRESS,
|
|
119
|
+
usdceToken.decimals
|
|
120
|
+
);
|
|
121
|
+
const price = await this.pricer.getPrice(usdceToken.symbol);
|
|
122
|
+
const usdValue =
|
|
123
|
+
Number(balance.toFixed(usdceToken.decimals)) * price.price;
|
|
124
|
+
return {
|
|
125
|
+
tokenInfo: usdceToken,
|
|
126
|
+
amount: balance,
|
|
127
|
+
usdValue,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
111
131
|
|
|
112
132
|
async getUnusedBalanceWBTC(): Promise<SingleTokenInfo> {
|
|
113
133
|
const collateralToken = this.metadata.additionalInfo.borrowable_assets[0]!;
|
|
@@ -159,23 +179,31 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
159
179
|
return extendedAdapter.adapter as ExtendedAdapter;
|
|
160
180
|
}
|
|
161
181
|
|
|
162
|
-
async moveAssetsToVaultAllocator(amount: Web3Number): Promise<Call[]> {
|
|
163
|
-
try{
|
|
164
|
-
const
|
|
165
|
-
(token) => token.symbol === "
|
|
182
|
+
async moveAssetsToVaultAllocator(amount: Web3Number, extendedAdapter: ExtendedAdapter): Promise<Call[]> {
|
|
183
|
+
try {
|
|
184
|
+
const usdceToken = Global.getDefaultTokens().find(
|
|
185
|
+
(token) => token.symbol === "USDCe"
|
|
166
186
|
)!;
|
|
167
187
|
const approveCall = new ERC20(this.config).approve(
|
|
168
|
-
|
|
188
|
+
usdceToken.address,
|
|
169
189
|
this.metadata.additionalInfo.vaultAllocator,
|
|
170
190
|
amount
|
|
171
191
|
);
|
|
172
192
|
const transferCall = new ERC20(this.config).transfer(
|
|
173
|
-
|
|
193
|
+
usdceToken.address,
|
|
174
194
|
this.metadata.additionalInfo.vaultAllocator,
|
|
175
195
|
amount
|
|
176
196
|
);
|
|
177
|
-
|
|
178
|
-
|
|
197
|
+
const proofsInfo = extendedAdapter.getProofsForFromLegacySwap(
|
|
198
|
+
this.getMerkleTree()
|
|
199
|
+
);
|
|
200
|
+
const proofGroups = proofsInfo.proofs;
|
|
201
|
+
const call = this.getManageCall(
|
|
202
|
+
proofGroups,
|
|
203
|
+
await proofsInfo.callConstructor({ amount: amount })
|
|
204
|
+
);
|
|
205
|
+
return [approveCall, transferCall, call];
|
|
206
|
+
} catch (err) {
|
|
179
207
|
logger.error(`error moving assets to vault allocator: ${err}`);
|
|
180
208
|
return [];
|
|
181
209
|
}
|
|
@@ -307,11 +335,9 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
307
335
|
);
|
|
308
336
|
return calls;
|
|
309
337
|
}
|
|
310
|
-
console.log("extendedAmount", extendedAmount);
|
|
311
|
-
console.log("vesuAmount", vesuAmount);
|
|
312
338
|
if (extendedAmount.lessThan(0)) {
|
|
313
339
|
try {
|
|
314
|
-
const extendedCalls = await this.moveAssets(
|
|
340
|
+
const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
|
|
315
341
|
{
|
|
316
342
|
to: Protocols.VAULT.name,
|
|
317
343
|
from: Protocols.EXTENDED.name,
|
|
@@ -320,7 +346,12 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
320
346
|
extendedAdapter,
|
|
321
347
|
vesuAdapter
|
|
322
348
|
);
|
|
323
|
-
|
|
349
|
+
//If withdrawal succesfull, then do further
|
|
350
|
+
if (extendedStatus) {
|
|
351
|
+
calls.push(...extendedCalls);
|
|
352
|
+
} else {
|
|
353
|
+
return [];
|
|
354
|
+
}
|
|
324
355
|
} catch (err) {
|
|
325
356
|
logger.error(`Failed moving assets to vault: ${err}`);
|
|
326
357
|
}
|
|
@@ -328,7 +359,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
328
359
|
|
|
329
360
|
if (vesuAmount.lessThan(0)) {
|
|
330
361
|
try {
|
|
331
|
-
const vesuCalls = await this.moveAssets(
|
|
362
|
+
const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
|
|
332
363
|
{
|
|
333
364
|
to: Protocols.EXTENDED.name,
|
|
334
365
|
from: Protocols.VESU.name,
|
|
@@ -338,6 +369,9 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
338
369
|
vesuAdapter
|
|
339
370
|
);
|
|
340
371
|
calls.push(...vesuCalls);
|
|
372
|
+
if (!vesuStatus) {
|
|
373
|
+
return [];
|
|
374
|
+
}
|
|
341
375
|
} catch (err) {
|
|
342
376
|
logger.error(`Failed moving assets to vault: ${err}`);
|
|
343
377
|
}
|
|
@@ -350,16 +384,16 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
350
384
|
}
|
|
351
385
|
const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
|
|
352
386
|
const usdcAmountOnExtended = parseFloat(
|
|
353
|
-
extendedHoldings.
|
|
387
|
+
extendedHoldings.availableForTrade
|
|
354
388
|
);
|
|
355
|
-
if (extendedAmount.minus(usdcAmountOnExtended).greaterThan(0)) {
|
|
389
|
+
if (extendedAmount.plus(BUFFER_USDC_IN_WITHDRAWAL).minus(usdcAmountOnExtended).greaterThan(0)) {
|
|
356
390
|
//move assets to extended
|
|
357
391
|
try {
|
|
358
|
-
const extendedCalls = await this.moveAssets(
|
|
392
|
+
const { calls: extendedCalls } = await this.moveAssets(
|
|
359
393
|
{
|
|
360
394
|
to: Protocols.EXTENDED.name,
|
|
361
395
|
from: Protocols.VAULT.name,
|
|
362
|
-
amount: extendedAmount.minus(usdcAmountOnExtended),
|
|
396
|
+
amount: extendedAmount.plus(BUFFER_USDC_IN_WITHDRAWAL).minus(usdcAmountOnExtended),
|
|
363
397
|
},
|
|
364
398
|
extendedAdapter,
|
|
365
399
|
vesuAdapter
|
|
@@ -372,15 +406,18 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
372
406
|
if (vesuAmount.minus(usdcAmountInWallet).greaterThan(0)) {
|
|
373
407
|
//move assets to vesu
|
|
374
408
|
try {
|
|
375
|
-
const vesuCalls = await this.moveAssets(
|
|
409
|
+
const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
|
|
376
410
|
{
|
|
377
|
-
to: Protocols.
|
|
411
|
+
to: Protocols.VAULT.name,
|
|
378
412
|
from: Protocols.EXTENDED.name,
|
|
379
413
|
amount: vesuAmount.minus(usdcAmountInWallet),
|
|
380
414
|
},
|
|
381
415
|
extendedAdapter,
|
|
382
416
|
vesuAdapter
|
|
383
417
|
);
|
|
418
|
+
if (!vesuStatus) {
|
|
419
|
+
return [];
|
|
420
|
+
}
|
|
384
421
|
calls.push(...vesuCalls);
|
|
385
422
|
} catch (err) {
|
|
386
423
|
logger.error(`Failed moving assets to vault: ${err}`);
|
|
@@ -401,18 +438,25 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
401
438
|
},
|
|
402
439
|
extendedAdapter: ExtendedAdapter,
|
|
403
440
|
vesuAdapter: VesuMultiplyAdapter
|
|
404
|
-
): Promise<
|
|
441
|
+
): Promise<{
|
|
442
|
+
calls: Call[];
|
|
443
|
+
status: boolean;
|
|
444
|
+
}> {
|
|
405
445
|
try {
|
|
406
446
|
const avnuAdapter = await this.getAvnuAdapter();
|
|
407
447
|
if (!avnuAdapter) {
|
|
408
448
|
logger.error(`avnu adapter not found: ${avnuAdapter}`);
|
|
409
|
-
return
|
|
449
|
+
return {
|
|
450
|
+
calls: [],
|
|
451
|
+
status: false
|
|
452
|
+
};
|
|
410
453
|
}
|
|
411
|
-
logger.info(
|
|
454
|
+
logger.info(`moveAssets params, ${JSON.stringify(params)}`);
|
|
412
455
|
const collateralToken = vesuAdapter.config.supportedPositions[0].asset;
|
|
413
456
|
const {
|
|
414
457
|
collateralPrice,
|
|
415
458
|
} = await this.getAssetPrices();
|
|
459
|
+
|
|
416
460
|
if (params.to === Protocols.EXTENDED.name && params.from === Protocols.VAULT.name) {
|
|
417
461
|
const proofsInfo = extendedAdapter.getProofs(
|
|
418
462
|
true,
|
|
@@ -425,22 +469,70 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
425
469
|
await proofsInfo.callConstructor({ amount: params.amount })
|
|
426
470
|
);
|
|
427
471
|
calls.push(call);
|
|
428
|
-
return
|
|
472
|
+
return {
|
|
473
|
+
calls: [call],
|
|
474
|
+
status: true
|
|
475
|
+
};
|
|
429
476
|
} else if (params.to === Protocols.VAULT.name && params.from === Protocols.EXTENDED.name) {
|
|
477
|
+
const extendedLeverage = calculateExtendedLevergae();
|
|
478
|
+
const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
|
|
479
|
+
if (!extendedHoldings) {
|
|
480
|
+
logger.error(`error getting extended holdings: ${extendedHoldings}`);
|
|
481
|
+
return {
|
|
482
|
+
calls: [],
|
|
483
|
+
status: false
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
const extendedHoldingAmount = new Web3Number(
|
|
487
|
+
extendedHoldings.availableForWithdrawal,
|
|
488
|
+
USDC_TOKEN_DECIMALS
|
|
489
|
+
);
|
|
490
|
+
logger.info(`${VesuExtendedMultiplierStrategy.name}::moveAssets extendedHoldingAmount: ${extendedHoldingAmount.toNumber()}`);
|
|
491
|
+
if (params.amount.abs().greaterThan(extendedHoldingAmount)) {
|
|
492
|
+
const leftAmountAfterWithdrawalAmountInAccount = params.amount.abs().minus(extendedHoldingAmount);
|
|
493
|
+
logger.info(`${VesuExtendedMultiplierStrategy.name}::moveAssets leftAmountAfterWithdrawalAmountInAccount: ${leftAmountAfterWithdrawalAmountInAccount.toNumber()}`);
|
|
494
|
+
const btcAmount = leftAmountAfterWithdrawalAmountInAccount.dividedBy(collateralPrice.price);
|
|
495
|
+
const openLongPosition = btcAmount.multipliedBy(3).greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
|
|
496
|
+
extendedLeverage.toString(),
|
|
497
|
+
btcAmount.toNumber(),
|
|
498
|
+
OrderSide.BUY
|
|
499
|
+
) : await extendedAdapter.createOrder(
|
|
500
|
+
extendedLeverage.toString(),
|
|
501
|
+
0.000035, // just in case amount falls short then we need to create a withdrawal
|
|
502
|
+
OrderSide.BUY
|
|
503
|
+
)
|
|
504
|
+
if (!openLongPosition) {
|
|
505
|
+
logger.error(`error opening long position: ${openLongPosition}`);
|
|
506
|
+
return {
|
|
507
|
+
calls: [],
|
|
508
|
+
status: false
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
512
|
+
}
|
|
430
513
|
const withdrawalFromExtended =
|
|
431
514
|
await extendedAdapter.withdrawFromExtended(params.amount);
|
|
432
515
|
if (withdrawalFromExtended) {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
const
|
|
516
|
+
/**
|
|
517
|
+
* We need to move assets from my wallet back to vault contract
|
|
518
|
+
*/
|
|
519
|
+
const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
|
|
520
|
+
logger.info(`extendedHoldings after withdrawal ${extendedHoldings}`);
|
|
521
|
+
await new Promise(resolve => setTimeout(resolve, 10000));
|
|
522
|
+
const calls = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
|
|
437
523
|
if (calls.length > 0) {
|
|
438
|
-
return
|
|
524
|
+
return {
|
|
525
|
+
calls: calls,
|
|
526
|
+
status: true
|
|
527
|
+
};
|
|
439
528
|
}
|
|
440
529
|
} else {
|
|
441
530
|
logger.error("withdrawal from extended failed");
|
|
531
|
+
return {
|
|
532
|
+
calls: [],
|
|
533
|
+
status: false
|
|
534
|
+
};
|
|
442
535
|
}
|
|
443
|
-
return [];
|
|
444
536
|
} else if (params.to === Protocols.VAULT.name && params.from === Protocols.VESU.name) {
|
|
445
537
|
//withdraw from vesu
|
|
446
538
|
const vesuAmountInBTC = new Web3Number(
|
|
@@ -462,7 +554,10 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
462
554
|
await swapProofsInfo.callConstructor({ amount: vesuAmountInBTC })
|
|
463
555
|
);
|
|
464
556
|
calls.push(swapCall);
|
|
465
|
-
return
|
|
557
|
+
return {
|
|
558
|
+
calls: calls,
|
|
559
|
+
status: true
|
|
560
|
+
};
|
|
466
561
|
} else if (params.to === Protocols.EXTENDED.name && params.from === Protocols.VESU.name) {
|
|
467
562
|
const vesuAmountInBTC = new Web3Number(
|
|
468
563
|
params.amount.dividedBy(collateralPrice.price).toNumber(),
|
|
@@ -494,19 +589,28 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
494
589
|
await proofsInfoDeposit.callConstructor({ amount: params.amount })
|
|
495
590
|
);
|
|
496
591
|
calls.push(callDeposit);
|
|
497
|
-
return
|
|
592
|
+
return {
|
|
593
|
+
calls: calls,
|
|
594
|
+
status: true
|
|
595
|
+
};
|
|
498
596
|
}
|
|
499
|
-
|
|
500
|
-
|
|
597
|
+
return {
|
|
598
|
+
calls: [],
|
|
599
|
+
status: false
|
|
600
|
+
};
|
|
501
601
|
} catch (err) {
|
|
502
602
|
logger.error(`error moving assets: ${err}`);
|
|
503
|
-
return
|
|
603
|
+
return {
|
|
604
|
+
calls: [],
|
|
605
|
+
status: false
|
|
606
|
+
};
|
|
504
607
|
}
|
|
505
608
|
}
|
|
506
609
|
|
|
507
610
|
async handleDeposit(): Promise<{
|
|
508
|
-
extendedAmountInBTC
|
|
509
|
-
calls:Call[]
|
|
611
|
+
extendedAmountInBTC: Web3Number,
|
|
612
|
+
calls: Call[]
|
|
613
|
+
}> {
|
|
510
614
|
try {
|
|
511
615
|
const vesuAdapter = await this.getVesuAdapter();
|
|
512
616
|
const extendedAdapter = await this.getExtendedAdapter();
|
|
@@ -545,6 +649,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
545
649
|
};
|
|
546
650
|
}
|
|
547
651
|
const extendedPositionValue = position.length > 0 ? parseFloat(position[0].value) : 0;
|
|
652
|
+
const BUFFER_AMOUNT_IN_AVAILABLE_FOR_TRADE = BUFFER_USDC_IN_WITHDRAWAL;
|
|
548
653
|
const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
|
|
549
654
|
if (!extendedHoldings) {
|
|
550
655
|
logger.error(`error getting extended holdings: ${extendedHoldings}`);
|
|
@@ -554,7 +659,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
554
659
|
};
|
|
555
660
|
}
|
|
556
661
|
const extendedHoldingAmount = new Web3Number(
|
|
557
|
-
extendedHoldings.
|
|
662
|
+
extendedHoldings.availableForTrade,
|
|
558
663
|
USDC_TOKEN_DECIMALS
|
|
559
664
|
);
|
|
560
665
|
const {
|
|
@@ -563,14 +668,14 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
563
668
|
const { collateralPrice } = await this.getAssetPrices();
|
|
564
669
|
const { vesuAmountInBTC, extendedAmountInBTC } = calculateVesUPositionSizeGivenExtended(
|
|
565
670
|
extendedPositionValue,
|
|
566
|
-
extendedHoldingAmount,
|
|
671
|
+
extendedHoldingAmount.minus(BUFFER_AMOUNT_IN_AVAILABLE_FOR_TRADE),
|
|
567
672
|
collateralTokenAmount,
|
|
568
673
|
collateralPrice.price
|
|
569
674
|
);
|
|
570
|
-
|
|
571
|
-
|
|
675
|
+
logger.info(`vesuAmountInBTC ${vesuAmountInBTC}, extendedAmountInBTC ${extendedAmountInBTC}`);
|
|
676
|
+
|
|
572
677
|
let calls: Call[] = [];
|
|
573
|
-
if(vesuAmountInBTC.greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)){
|
|
678
|
+
if (vesuAmountInBTC.greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)) {
|
|
574
679
|
const proofsInfo = vesuAdapter.getProofs(true, this.getMerkleTree());
|
|
575
680
|
const proofGroups = proofsInfo.proofs;
|
|
576
681
|
const call = this.getManageCall(
|
|
@@ -581,7 +686,6 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
581
686
|
);
|
|
582
687
|
const { amount: wbtcAmountInVaultAllocator } = await this.getUnusedBalanceWBTC();
|
|
583
688
|
if (wbtcAmountInVaultAllocator.lessThan(vesuAmountInBTC)) {
|
|
584
|
-
console.log("error wbtc amount in vault allocator is less than vesu amount in btc", wbtcAmountInVaultAllocator, vesuAmountInBTC);
|
|
585
689
|
const swapProofsInfo = avnuAdapter.getProofs(true, this.getMerkleTree());
|
|
586
690
|
const swapProofGroups = swapProofsInfo.proofs;
|
|
587
691
|
const swapCall = this.getManageCall(
|
|
@@ -594,7 +698,6 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
594
698
|
}
|
|
595
699
|
calls.push(call);
|
|
596
700
|
}
|
|
597
|
-
|
|
598
701
|
const shortPosition = extendedAmountInBTC.multipliedBy(3).abs().greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
|
|
599
702
|
extendedLeverage.toString(),
|
|
600
703
|
extendedAmountInBTC.toNumber(),
|
|
@@ -620,44 +723,54 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
620
723
|
}
|
|
621
724
|
}
|
|
622
725
|
|
|
623
|
-
async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter:ExtendedAdapter, vesuAdapter:VesuMultiplyAdapter, avnuAdapter:AvnuAdapter): Promise<boolean> {
|
|
726
|
+
async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter: ExtendedAdapter, vesuAdapter: VesuMultiplyAdapter, avnuAdapter: AvnuAdapter): Promise<boolean> {
|
|
624
727
|
const {
|
|
625
728
|
ask, bid
|
|
626
|
-
}= await extendedAdapter.fetchOrderBookBTCUSDC();
|
|
729
|
+
} = await extendedAdapter.fetchOrderBookBTCUSDC();
|
|
627
730
|
const price = ask.plus(bid).dividedBy(2);
|
|
628
|
-
const btcToken = vesuAdapter.config.supportedPositions[
|
|
731
|
+
const btcToken = vesuAdapter.config.supportedPositions[0].asset;
|
|
629
732
|
const btcPriceAvnu = await avnuAdapter.getPriceOfToken(btcToken.address.toString());
|
|
630
733
|
if (!btcPriceAvnu) {
|
|
631
734
|
logger.error(`error getting btc price avnu: ${btcPriceAvnu}`);
|
|
632
735
|
return false;
|
|
633
736
|
}
|
|
634
737
|
const priceDifference = price.minus(btcPriceAvnu).toNumber();
|
|
635
|
-
if(priceDifference < MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED && priceDifference > MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED){
|
|
738
|
+
if (priceDifference < MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED && priceDifference > MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED) {
|
|
636
739
|
return true;
|
|
637
740
|
}
|
|
638
741
|
logger.error(`price difference between avnu and extended doesn't fit the range, priceDifference: ${priceDifference}`);
|
|
639
742
|
return false;
|
|
640
743
|
}
|
|
641
744
|
|
|
642
|
-
async handleWithdraw(amount: Web3Number): Promise<Call[]> {
|
|
745
|
+
async handleWithdraw(amount: Web3Number): Promise<{ calls: Call[], status: boolean }> {
|
|
643
746
|
try {
|
|
644
747
|
const usdcBalanceVaultAllocator = await this.getUnusedBalance()
|
|
645
|
-
const usdcBalanceDifference = amount.minus(usdcBalanceVaultAllocator.usdValue);
|
|
748
|
+
const usdcBalanceDifference = amount.plus(BUFFER_USDC_IN_WITHDRAWAL).minus(usdcBalanceVaultAllocator.usdValue);
|
|
646
749
|
logger.info(`usdcBalanceDifference, ${usdcBalanceDifference.toNumber()}`);
|
|
750
|
+
let calls: Call[] = [];
|
|
751
|
+
let status: boolean = true;
|
|
647
752
|
if (usdcBalanceDifference.lessThan(0)) {
|
|
648
753
|
const withdrawCall = await this.getBringLiquidityCall({
|
|
649
|
-
amount: amount
|
|
754
|
+
amount: usdcBalanceVaultAllocator.amount
|
|
650
755
|
})
|
|
651
756
|
logger.info("withdraw call", withdrawCall);
|
|
652
|
-
|
|
757
|
+
calls.push(withdrawCall);
|
|
758
|
+
return {
|
|
759
|
+
calls: calls,
|
|
760
|
+
status: true
|
|
761
|
+
};
|
|
653
762
|
}
|
|
654
763
|
const vesuAdapter = await this.getVesuAdapter();
|
|
655
764
|
const extendedAdapter = await this.getExtendedAdapter();
|
|
656
765
|
if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
|
|
766
|
+
status = false;
|
|
657
767
|
logger.error(
|
|
658
768
|
`vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
|
|
659
769
|
);
|
|
660
|
-
return
|
|
770
|
+
return {
|
|
771
|
+
calls: calls,
|
|
772
|
+
status: status
|
|
773
|
+
};
|
|
661
774
|
}
|
|
662
775
|
const { collateralTokenAmount } =
|
|
663
776
|
await vesuAdapter.vesuAdapter.getAssetPrices();
|
|
@@ -665,22 +778,35 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
665
778
|
collateralPrice
|
|
666
779
|
} = await this.getAssetPrices();
|
|
667
780
|
const extendedPositon = await extendedAdapter.getAllOpenPositions();
|
|
781
|
+
if (!extendedPositon) {
|
|
782
|
+
status = false;
|
|
783
|
+
logger.error("error getting extended position", extendedPositon);
|
|
784
|
+
return {
|
|
785
|
+
calls: calls,
|
|
786
|
+
status: status
|
|
787
|
+
}
|
|
788
|
+
}
|
|
668
789
|
const amountDistributionForWithdrawal =
|
|
669
790
|
await calculateAmountDistributionForWithdrawal(
|
|
670
|
-
|
|
791
|
+
usdcBalanceDifference,
|
|
671
792
|
collateralPrice.price,
|
|
672
793
|
collateralTokenAmount,
|
|
673
794
|
extendedPositon
|
|
674
795
|
);
|
|
675
796
|
if (!amountDistributionForWithdrawal) {
|
|
797
|
+
status = false;
|
|
676
798
|
logger.error(
|
|
677
799
|
`error calculating amount distribution for withdrawal: ${amountDistributionForWithdrawal}`
|
|
678
800
|
);
|
|
679
|
-
return
|
|
801
|
+
return {
|
|
802
|
+
calls: calls,
|
|
803
|
+
status: status
|
|
804
|
+
};
|
|
680
805
|
}
|
|
681
806
|
const { vesu_amount, extended_amount } = amountDistributionForWithdrawal;
|
|
682
|
-
|
|
683
|
-
|
|
807
|
+
|
|
808
|
+
if (status && vesu_amount.greaterThan(0)) {
|
|
809
|
+
const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
|
|
684
810
|
{
|
|
685
811
|
amount: vesu_amount,
|
|
686
812
|
from: Protocols.VESU.name,
|
|
@@ -689,10 +815,11 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
689
815
|
extendedAdapter,
|
|
690
816
|
vesuAdapter
|
|
691
817
|
);
|
|
692
|
-
|
|
818
|
+
status = vesuStatus;
|
|
819
|
+
calls.push(...vesuCalls);
|
|
693
820
|
}
|
|
694
|
-
if (extended_amount.greaterThan(0)) {
|
|
695
|
-
const
|
|
821
|
+
if (status && extended_amount.greaterThan(0)) {
|
|
822
|
+
const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
|
|
696
823
|
{
|
|
697
824
|
amount: extended_amount,
|
|
698
825
|
from: Protocols.EXTENDED.name,
|
|
@@ -701,12 +828,32 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
701
828
|
extendedAdapter,
|
|
702
829
|
vesuAdapter
|
|
703
830
|
);
|
|
704
|
-
|
|
831
|
+
status = extendedStatus;
|
|
832
|
+
if (status) {
|
|
833
|
+
calls.push(...extendedCalls);
|
|
834
|
+
} else {
|
|
835
|
+
logger.error("error moving assets to vault: extendedStatus: ${extendedStatus}");
|
|
836
|
+
return {
|
|
837
|
+
calls: [],
|
|
838
|
+
status: status
|
|
839
|
+
};
|
|
840
|
+
}
|
|
705
841
|
}
|
|
706
|
-
|
|
842
|
+
const withdrawCall = await this.getBringLiquidityCall({
|
|
843
|
+
amount: amount
|
|
844
|
+
})
|
|
845
|
+
logger.info("withdraw call", withdrawCall);
|
|
846
|
+
calls.push(withdrawCall);
|
|
847
|
+
return {
|
|
848
|
+
calls: calls,
|
|
849
|
+
status: status
|
|
850
|
+
};
|
|
707
851
|
} catch (err) {
|
|
708
852
|
logger.error(`error handling withdrawal: ${err}`);
|
|
709
|
-
return
|
|
853
|
+
return {
|
|
854
|
+
calls: [],
|
|
855
|
+
status: false
|
|
856
|
+
};
|
|
710
857
|
}
|
|
711
858
|
}
|
|
712
859
|
|
|
@@ -714,7 +861,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
714
861
|
const allPositions: PositionInfo[] = [];
|
|
715
862
|
for (let adapter of this.metadata.additionalInfo.adapters) {
|
|
716
863
|
const positions = await adapter.adapter.getPositions();
|
|
717
|
-
|
|
864
|
+
allPositions.push(...positions);
|
|
718
865
|
}
|
|
719
866
|
|
|
720
867
|
const assetPrice = await this.pricer.getPrice(this.asset().symbol);
|
|
@@ -863,6 +1010,7 @@ function getLooperSettings(
|
|
|
863
1010
|
vesuMultiplyAdapter.getWithdrawLeaf()
|
|
864
1011
|
);
|
|
865
1012
|
vaultSettings.leafAdapters.push(() => extendedAdapter.getDepositLeaf());
|
|
1013
|
+
vaultSettings.leafAdapters.push(() => extendedAdapter.getSwapFromLegacyLeaf());
|
|
866
1014
|
vaultSettings.leafAdapters.push(() => avnuAdapter.getDepositLeaf());
|
|
867
1015
|
vaultSettings.leafAdapters.push(() => avnuAdapter.getWithdrawLeaf());
|
|
868
1016
|
// Doubt here, should this be usdcToken.address, or wbtcToken.address?
|