@strkfarm/sdk 2.0.0-dev.13 → 2.0.0-dev.15
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 +557 -556
- package/dist/index.browser.mjs +1333 -1332
- package/dist/index.d.ts +78 -28
- package/dist/index.js +565 -562
- package/dist/index.mjs +1333 -1332
- package/package.json +1 -1
- package/src/strategies/index.ts +2 -1
- package/src/strategies/universal-adapters/extended-adapter.ts +40 -11
- package/src/strategies/universal-adapters/index.ts +2 -1
- package/src/strategies/vesu-extended-strategy/services/operationService.ts +23 -13
- package/src/strategies/vesu-extended-strategy/types/transaction-metadata.ts +25 -0
- package/src/strategies/vesu-extended-strategy/utils/helper.ts +40 -0
- package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +203 -235
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
import { SingleTokenInfo } from "../base-strategy";
|
|
55
55
|
import { Call } from "starknet";
|
|
56
56
|
import { PositionTypeAvnuExtended} from "../universal-strategy";
|
|
57
|
+
import { TransactionMetadata, TransactionResult } from "./types/transaction-metadata";
|
|
57
58
|
|
|
58
59
|
|
|
59
60
|
export interface VesuExtendedStrategySettings
|
|
@@ -179,7 +180,10 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
179
180
|
return extendedAdapter.adapter as ExtendedAdapter;
|
|
180
181
|
}
|
|
181
182
|
|
|
182
|
-
async moveAssetsToVaultAllocator(amount: Web3Number, extendedAdapter: ExtendedAdapter): Promise<
|
|
183
|
+
async moveAssetsToVaultAllocator(amount: Web3Number, extendedAdapter: ExtendedAdapter): Promise<{
|
|
184
|
+
calls:Call[],
|
|
185
|
+
status: boolean,
|
|
186
|
+
}> {
|
|
183
187
|
try {
|
|
184
188
|
const usdceToken = Global.getDefaultTokens().find(
|
|
185
189
|
(token) => token.symbol === "USDCe"
|
|
@@ -202,10 +206,16 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
202
206
|
proofGroups,
|
|
203
207
|
await proofsInfo.callConstructor({ amount: amount })
|
|
204
208
|
);
|
|
205
|
-
return
|
|
209
|
+
return {
|
|
210
|
+
calls: [approveCall, transferCall, call],
|
|
211
|
+
status: true,
|
|
212
|
+
};
|
|
206
213
|
} catch (err) {
|
|
207
214
|
logger.error(`error moving assets to vault allocator: ${err}`);
|
|
208
|
-
return
|
|
215
|
+
return {
|
|
216
|
+
calls: [],
|
|
217
|
+
status: false,
|
|
218
|
+
};
|
|
209
219
|
}
|
|
210
220
|
}
|
|
211
221
|
|
|
@@ -442,7 +452,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
442
452
|
}
|
|
443
453
|
}
|
|
444
454
|
|
|
445
|
-
async shouldMoveAssets(extendedAmount: Web3Number, vesuAmount: Web3Number): Promise<
|
|
455
|
+
async shouldMoveAssets(extendedAmount: Web3Number, vesuAmount: Web3Number): Promise<TransactionResult[]> {
|
|
446
456
|
try {
|
|
447
457
|
const vesuAdapter = await this.getVesuAdapter();
|
|
448
458
|
const extendedAdapter = await this.getExtendedAdapter();
|
|
@@ -502,11 +512,12 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
502
512
|
|
|
503
513
|
logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculated movements - Extended withdrawal: ${totalExtendedWithdrawal.toNumber()}, Extended deposit: ${totalExtendedDeposit.toNumber()}, Extended diff: ${extendedAmountDifference.toNumber()}, Projected wallet: ${projectedWalletBalance.toNumber()}, Vesu diff: ${vesuAmountDifference.toNumber()}`);
|
|
504
514
|
let calls: Call[] = [];
|
|
515
|
+
let transactionResults: TransactionResult[] = [];
|
|
505
516
|
|
|
506
517
|
// Handle negative extendedAmount (initial withdrawal needed)
|
|
507
518
|
if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
|
|
508
519
|
try {
|
|
509
|
-
const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
|
|
520
|
+
const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
|
|
510
521
|
{
|
|
511
522
|
to: Protocols.VAULT.name,
|
|
512
523
|
from: Protocols.EXTENDED.name,
|
|
@@ -516,18 +527,26 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
516
527
|
vesuAdapter
|
|
517
528
|
);
|
|
518
529
|
if (extendedStatus) {
|
|
519
|
-
|
|
530
|
+
transactionResults.push({
|
|
531
|
+
status: extendedStatus,
|
|
532
|
+
calls: extendedCalls,
|
|
533
|
+
transactionMetadata: {
|
|
534
|
+
...extendedTransactionMetadata,
|
|
535
|
+
transactionType: "DEPOSIT",
|
|
536
|
+
},
|
|
537
|
+
})
|
|
520
538
|
} else {
|
|
521
|
-
return [];
|
|
539
|
+
return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmount.abs() }, "NONE")];
|
|
522
540
|
}
|
|
523
541
|
} catch (err) {
|
|
524
542
|
logger.error(`Failed moving assets to vault: ${err}`);
|
|
543
|
+
return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmount.abs() }, "NONE")];
|
|
525
544
|
}
|
|
526
545
|
}
|
|
527
546
|
|
|
528
547
|
if (vesuAmount.isNegative() && vesuAmount.abs().greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
|
|
529
548
|
try {
|
|
530
|
-
const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
|
|
549
|
+
const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
|
|
531
550
|
{
|
|
532
551
|
to: Protocols.EXTENDED.name,
|
|
533
552
|
from: Protocols.VESU.name,
|
|
@@ -536,12 +555,20 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
536
555
|
extendedAdapter,
|
|
537
556
|
vesuAdapter
|
|
538
557
|
);
|
|
539
|
-
calls.push(...vesuCalls);
|
|
540
558
|
if (!vesuStatus) {
|
|
541
|
-
return [];
|
|
559
|
+
return [this.createTransactionResult([], false, { from: Protocols.VESU.name, to: Protocols.EXTENDED.name, amount: vesuAmount.abs() }, "NONE")];
|
|
542
560
|
}
|
|
561
|
+
transactionResults.push({
|
|
562
|
+
status: vesuStatus,
|
|
563
|
+
calls: vesuCalls,
|
|
564
|
+
transactionMetadata: {
|
|
565
|
+
...vesuTransactionMetadata,
|
|
566
|
+
transactionType: "DEPOSIT",
|
|
567
|
+
}
|
|
568
|
+
})
|
|
543
569
|
} catch (err) {
|
|
544
|
-
logger.error(`Failed moving assets to vault: ${err}`);
|
|
570
|
+
logger.error(`Failed moving assets to extended via vault allocator: ${err}`);
|
|
571
|
+
return [this.createTransactionResult([], false, { from: Protocols.VESU.name, to: Protocols.EXTENDED.name, amount: vesuAmount.abs() }, "NONE")];
|
|
545
572
|
}
|
|
546
573
|
}
|
|
547
574
|
|
|
@@ -549,7 +576,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
549
576
|
if (extendedAmountDifferenceAbs.greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
|
|
550
577
|
if (extendedAmountDifference.greaterThan(0)) {
|
|
551
578
|
try {
|
|
552
|
-
const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
|
|
579
|
+
const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
|
|
553
580
|
{
|
|
554
581
|
to: Protocols.EXTENDED.name,
|
|
555
582
|
from: Protocols.VAULT.name,
|
|
@@ -559,18 +586,22 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
559
586
|
vesuAdapter
|
|
560
587
|
);
|
|
561
588
|
if (extendedStatus) {
|
|
562
|
-
|
|
589
|
+
transactionResults.push({
|
|
590
|
+
status: extendedStatus,
|
|
591
|
+
calls: extendedCalls,
|
|
592
|
+
transactionMetadata: extendedTransactionMetadata
|
|
593
|
+
})
|
|
563
594
|
} else {
|
|
564
595
|
logger.error(`Failed to move assets to extended - operation returned false status`);
|
|
565
|
-
return [];
|
|
596
|
+
return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.EXTENDED.name, amount: extendedAmountDifference }, "NONE")];
|
|
566
597
|
}
|
|
567
598
|
} catch (err) {
|
|
568
599
|
logger.error(`Failed moving assets to extended: ${err}`);
|
|
569
|
-
return [];
|
|
600
|
+
return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.EXTENDED.name, amount: extendedAmountDifference }, "NONE")];
|
|
570
601
|
}
|
|
571
602
|
} else if (extendedAmountDifference.lessThan(0)) {
|
|
572
603
|
try {
|
|
573
|
-
const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
|
|
604
|
+
const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
|
|
574
605
|
{
|
|
575
606
|
to: Protocols.VAULT.name,
|
|
576
607
|
from: Protocols.EXTENDED.name,
|
|
@@ -580,14 +611,21 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
580
611
|
vesuAdapter
|
|
581
612
|
);
|
|
582
613
|
if (extendedStatus) {
|
|
583
|
-
|
|
614
|
+
transactionResults.push({
|
|
615
|
+
status: extendedStatus,
|
|
616
|
+
calls: extendedCalls,
|
|
617
|
+
transactionMetadata: {
|
|
618
|
+
...extendedTransactionMetadata,
|
|
619
|
+
transactionType: "DEPOSIT",
|
|
620
|
+
}
|
|
621
|
+
})
|
|
584
622
|
} else {
|
|
585
623
|
logger.error(`Failed to withdraw from extended - operation returned false status`);
|
|
586
|
-
return [];
|
|
624
|
+
return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmountDifferenceAbs }, "NONE")];
|
|
587
625
|
}
|
|
588
626
|
} catch (err) {
|
|
589
627
|
logger.error(`Failed moving assets from extended to vault: ${err}`);
|
|
590
|
-
return [];
|
|
628
|
+
return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmountDifferenceAbs }, "NONE")];
|
|
591
629
|
}
|
|
592
630
|
}
|
|
593
631
|
}
|
|
@@ -601,7 +639,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
601
639
|
} else {
|
|
602
640
|
// Move assets from Extended to Vault (which will then go to Vesu)
|
|
603
641
|
try {
|
|
604
|
-
const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
|
|
642
|
+
const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
|
|
605
643
|
{
|
|
606
644
|
to: Protocols.VAULT.name,
|
|
607
645
|
from: Protocols.EXTENDED.name,
|
|
@@ -612,21 +650,53 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
612
650
|
);
|
|
613
651
|
if (!vesuStatus) {
|
|
614
652
|
logger.error(`Failed to move assets to vesu - operation returned false status`);
|
|
615
|
-
return [];
|
|
653
|
+
return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: vesuAmountDifference }, "NONE")];
|
|
616
654
|
}
|
|
617
|
-
|
|
655
|
+
transactionResults.push({
|
|
656
|
+
status: vesuStatus,
|
|
657
|
+
calls: vesuCalls,
|
|
658
|
+
transactionMetadata: {
|
|
659
|
+
...vesuTransactionMetadata,
|
|
660
|
+
transactionType: "DEPOSIT",
|
|
661
|
+
}
|
|
662
|
+
})
|
|
618
663
|
} catch (err) {
|
|
619
664
|
logger.error(`Failed moving assets to vault: ${err}`);
|
|
620
|
-
return [];
|
|
665
|
+
return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: vesuAmountDifference }, "NONE")];
|
|
621
666
|
}
|
|
622
667
|
}
|
|
623
668
|
}
|
|
624
669
|
|
|
625
|
-
return
|
|
670
|
+
return transactionResults;
|
|
626
671
|
} catch (err) {
|
|
627
672
|
logger.error(`Failed moving assets to vesu: ${err}`);
|
|
628
|
-
return [];
|
|
673
|
+
return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: new Web3Number(0, USDC_TOKEN_DECIMALS) }, "NONE")];
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Helper method to create transaction result with metadata
|
|
679
|
+
*/
|
|
680
|
+
private createTransactionResult(
|
|
681
|
+
calls: Call[],
|
|
682
|
+
status: boolean,
|
|
683
|
+
params: { from: string; to: string; amount: Web3Number },
|
|
684
|
+
transactionType: 'DEPOSIT' | 'WITHDRAWAL' | 'NONE'
|
|
685
|
+
): TransactionResult {
|
|
686
|
+
if (status) {
|
|
687
|
+
return {
|
|
688
|
+
calls,
|
|
689
|
+
status: status,
|
|
690
|
+
transactionMetadata: {
|
|
691
|
+
protocolFrom: params.from,
|
|
692
|
+
protocolTo: params.to,
|
|
693
|
+
transactionType: transactionType,
|
|
694
|
+
usdAmount: params.amount.abs().toFixed(),
|
|
695
|
+
status: 'PENDING',
|
|
696
|
+
}
|
|
697
|
+
};
|
|
629
698
|
}
|
|
699
|
+
return { calls: [], status: false, transactionMetadata: { protocolFrom: '', protocolTo: '', transactionType: 'DEPOSIT', usdAmount: '0', status: 'FAILED' } };
|
|
630
700
|
}
|
|
631
701
|
|
|
632
702
|
async moveAssets(
|
|
@@ -637,20 +707,14 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
637
707
|
},
|
|
638
708
|
extendedAdapter: ExtendedAdapter,
|
|
639
709
|
vesuAdapter: VesuMultiplyAdapter
|
|
640
|
-
): Promise<{
|
|
641
|
-
calls: Call[];
|
|
642
|
-
status: boolean;
|
|
643
|
-
}> {
|
|
710
|
+
): Promise<TransactionResult> {
|
|
644
711
|
try {
|
|
645
712
|
// Validate amount is positive before starting operations
|
|
646
713
|
if (params.amount.lessThanOrEqualTo(0)) {
|
|
647
714
|
logger.error(
|
|
648
715
|
`Invalid amount for moveAssets: ${params.amount.toNumber()}. Amount must be positive.`
|
|
649
716
|
);
|
|
650
|
-
return
|
|
651
|
-
calls: [],
|
|
652
|
-
status: false
|
|
653
|
-
};
|
|
717
|
+
return this.createTransactionResult([], false, params, "NONE");
|
|
654
718
|
}
|
|
655
719
|
|
|
656
720
|
// Check minimum movement amounts before starting operations
|
|
@@ -660,10 +724,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
660
724
|
logger.warn(
|
|
661
725
|
`Amount ${amountAbs.toNumber()} is below minimum Extended movement amount ${extendedAdapter.minimumExtendedMovementAmount}. Skipping operation.`
|
|
662
726
|
);
|
|
663
|
-
return
|
|
664
|
-
calls: [],
|
|
665
|
-
status: false
|
|
666
|
-
};
|
|
727
|
+
return this.createTransactionResult([], false, params, "NONE");
|
|
667
728
|
}
|
|
668
729
|
}
|
|
669
730
|
if (params.from === Protocols.VESU.name || params.to === Protocols.VESU.name) {
|
|
@@ -671,20 +732,14 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
671
732
|
logger.warn(
|
|
672
733
|
`Amount ${amountAbs.toNumber()} is below minimum Vesu movement amount ${vesuAdapter.minimumVesuMovementAmount}. Skipping operation.`
|
|
673
734
|
);
|
|
674
|
-
return
|
|
675
|
-
calls: [],
|
|
676
|
-
status: false
|
|
677
|
-
};
|
|
735
|
+
return this.createTransactionResult([], false, params, "NONE");
|
|
678
736
|
}
|
|
679
737
|
}
|
|
680
738
|
|
|
681
739
|
const avnuAdapter = await this.getAvnuAdapter();
|
|
682
740
|
if (!avnuAdapter) {
|
|
683
741
|
logger.error(`avnu adapter not found: ${avnuAdapter}`);
|
|
684
|
-
return
|
|
685
|
-
calls: [],
|
|
686
|
-
status: false
|
|
687
|
-
};
|
|
742
|
+
return this.createTransactionResult([], false, params, "NONE");
|
|
688
743
|
}
|
|
689
744
|
logger.info(`moveAssets params, ${JSON.stringify(params)}`);
|
|
690
745
|
const collateralToken = vesuAdapter.config.supportedPositions[0].asset;
|
|
@@ -704,19 +759,13 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
704
759
|
await proofsInfo.callConstructor({ amount: params.amount })
|
|
705
760
|
);
|
|
706
761
|
calls.push(call);
|
|
707
|
-
return
|
|
708
|
-
calls: [call],
|
|
709
|
-
status: true
|
|
710
|
-
};
|
|
762
|
+
return this.createTransactionResult(calls, true, params, "DEPOSIT");
|
|
711
763
|
} else if (params.to === Protocols.VAULT.name && params.from === Protocols.EXTENDED.name) {
|
|
712
764
|
const extendedLeverage = calculateExtendedLevergae();
|
|
713
765
|
const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
|
|
714
766
|
if (!extendedHoldings) {
|
|
715
767
|
logger.error(`error getting extended holdings: ${extendedHoldings}`);
|
|
716
|
-
return
|
|
717
|
-
calls: [],
|
|
718
|
-
status: false
|
|
719
|
-
};
|
|
768
|
+
return this.createTransactionResult([], false, params, "NONE");
|
|
720
769
|
}
|
|
721
770
|
const extendedHoldingAmount = new Web3Number(
|
|
722
771
|
extendedHoldings.availableForWithdrawal,
|
|
@@ -742,40 +791,48 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
742
791
|
const updatedHoldings = await extendedAdapter.getExtendedDepositAmount();
|
|
743
792
|
if (!updatedHoldings || new Web3Number(updatedHoldings.availableForWithdrawal, USDC_TOKEN_DECIMALS).lessThan(params.amount.abs())) {
|
|
744
793
|
logger.error(`Insufficient balance after opening position. Available: ${updatedHoldings?.availableForWithdrawal}, Needed: ${params.amount.abs()}`);
|
|
745
|
-
return
|
|
794
|
+
return this.createTransactionResult([], false, params, "NONE");
|
|
746
795
|
}
|
|
747
796
|
}
|
|
748
|
-
const
|
|
797
|
+
const {
|
|
798
|
+
status: withdrawalFromExtendedStatus,
|
|
799
|
+
receivedTxnHash: withdrawalFromExtendedTxnHash,
|
|
800
|
+
} =
|
|
749
801
|
await extendedAdapter.withdrawFromExtended(params.amount);
|
|
750
|
-
|
|
802
|
+
/**
|
|
803
|
+
* This logic needs fixing
|
|
804
|
+
*/
|
|
805
|
+
logger.info(`withdrawalFromExtendedStatus: ${withdrawalFromExtendedStatus}, withdrawalFromExtendedTxnHash: ${withdrawalFromExtendedTxnHash}`);
|
|
806
|
+
if (withdrawalFromExtendedStatus && withdrawalFromExtendedTxnHash) {
|
|
751
807
|
/**
|
|
752
808
|
* We need to move assets from my wallet back to vault contract
|
|
753
809
|
*/
|
|
754
810
|
const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
|
|
755
811
|
logger.info(`extendedHoldings after withdrawal ${extendedHoldings?.availableForWithdrawal}`);
|
|
756
812
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
757
|
-
const calls = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
|
|
758
|
-
if (calls.length > 0) {
|
|
759
|
-
return
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
813
|
+
const {calls, status} = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
|
|
814
|
+
if (calls.length > 0 && status) {
|
|
815
|
+
return this.createTransactionResult(calls, true, params, "WITHDRAWAL");
|
|
816
|
+
}else {
|
|
817
|
+
/**
|
|
818
|
+
* This is a fallback scenario, where the funds were withdrawn from extended, but didn't get transferred to the wallet
|
|
819
|
+
* We need to return a successful transaction result, but with no calls
|
|
820
|
+
* Db update will be handled by the risk engine for this specific case
|
|
821
|
+
*/
|
|
822
|
+
return this.createTransactionResult([], true, params, "WITHDRAWAL");
|
|
763
823
|
}
|
|
824
|
+
}else if(withdrawalFromExtendedStatus && !withdrawalFromExtendedTxnHash){
|
|
825
|
+
logger.error("withdrawal from extended successful, but funds didn't get transferred to the wallet");
|
|
826
|
+
return this.createTransactionResult([], true, params, "WITHDRAWAL");
|
|
764
827
|
} else {
|
|
765
828
|
logger.error("withdrawal from extended failed");
|
|
766
|
-
return
|
|
767
|
-
calls: [],
|
|
768
|
-
status: false
|
|
769
|
-
};
|
|
829
|
+
return this.createTransactionResult([], false, params, "NONE");
|
|
770
830
|
}
|
|
771
831
|
} else if (params.to === Protocols.VAULT.name && params.from === Protocols.VESU.name) {
|
|
772
832
|
const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, PositionTypeAvnuExtended.CLOSE);
|
|
773
833
|
if (!isPriceDifferenceBetweenAvnuAndExtended) {
|
|
774
834
|
logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
|
|
775
|
-
return
|
|
776
|
-
calls: [],
|
|
777
|
-
status: false
|
|
778
|
-
};
|
|
835
|
+
return this.createTransactionResult([], false, params, "NONE");
|
|
779
836
|
}
|
|
780
837
|
//withdraw from vesu
|
|
781
838
|
const vesuAmountInBTC = new Web3Number(
|
|
@@ -797,18 +854,12 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
797
854
|
await swapProofsInfo.callConstructor({ amount: vesuAmountInBTC })
|
|
798
855
|
);
|
|
799
856
|
calls.push(swapCall);
|
|
800
|
-
return
|
|
801
|
-
calls: calls,
|
|
802
|
-
status: true
|
|
803
|
-
};
|
|
857
|
+
return this.createTransactionResult(calls, true, params, "WITHDRAWAL");
|
|
804
858
|
} else if (params.to === Protocols.EXTENDED.name && params.from === Protocols.VESU.name) {
|
|
805
859
|
const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, PositionTypeAvnuExtended.CLOSE);
|
|
806
860
|
if (!isPriceDifferenceBetweenAvnuAndExtended) {
|
|
807
861
|
logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
|
|
808
|
-
return
|
|
809
|
-
calls: [],
|
|
810
|
-
status: false
|
|
811
|
-
};
|
|
862
|
+
return this.createTransactionResult([], false, params, "NONE");
|
|
812
863
|
}
|
|
813
864
|
const vesuAmountInBTC = new Web3Number(
|
|
814
865
|
params.amount.dividedBy(collateralPrice.price).toNumber(),
|
|
@@ -840,137 +891,25 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
840
891
|
await proofsInfoDeposit.callConstructor({ amount: params.amount })
|
|
841
892
|
);
|
|
842
893
|
calls.push(callDeposit);
|
|
843
|
-
return
|
|
844
|
-
calls: calls,
|
|
845
|
-
status: true
|
|
846
|
-
};
|
|
894
|
+
return this.createTransactionResult(calls, true, params, "DEPOSIT");
|
|
847
895
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
status: false
|
|
851
|
-
};
|
|
896
|
+
logger.error(`Unsupported assets movement: ${params.from} to ${params.to}`);
|
|
897
|
+
return this.createTransactionResult([], false, params, "NONE");
|
|
852
898
|
} catch (err) {
|
|
853
899
|
logger.error(`error moving assets: ${err}`);
|
|
854
|
-
return
|
|
855
|
-
calls: [],
|
|
856
|
-
status: false
|
|
857
|
-
};
|
|
900
|
+
return this.createTransactionResult([], false, params,"NONE");
|
|
858
901
|
}
|
|
859
902
|
}
|
|
860
903
|
|
|
861
|
-
async handleDeposit(): Promise<{
|
|
862
|
-
extendedAmountInBTC: Web3Number,
|
|
863
|
-
calls: Call[]
|
|
864
|
-
}> {
|
|
904
|
+
async handleDeposit(): Promise<TransactionResult> {
|
|
865
905
|
try {
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
!vesuAdapter ||
|
|
871
|
-
!extendedAdapter ||
|
|
872
|
-
!extendedAdapter.client ||
|
|
873
|
-
!avnuAdapter
|
|
874
|
-
) {
|
|
875
|
-
logger.error(
|
|
876
|
-
"vesu or extended adapter not found",
|
|
877
|
-
vesuAdapter,
|
|
878
|
-
extendedAdapter
|
|
879
|
-
);
|
|
880
|
-
return {
|
|
881
|
-
extendedAmountInBTC: new Web3Number(0, 0),
|
|
882
|
-
calls: [],
|
|
883
|
-
};
|
|
884
|
-
}
|
|
885
|
-
const extendedLeverage = calculateExtendedLevergae();
|
|
886
|
-
const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, PositionTypeAvnuExtended.OPEN);
|
|
887
|
-
if (!isPriceDifferenceBetweenAvnuAndExtended) {
|
|
888
|
-
logger.error("price difference between avnu and extended doesn't fit the range");
|
|
889
|
-
return {
|
|
890
|
-
extendedAmountInBTC: new Web3Number(0, 0),
|
|
891
|
-
calls: [],
|
|
892
|
-
};
|
|
893
|
-
}
|
|
894
|
-
const position = await extendedAdapter.getAllOpenPositions();
|
|
895
|
-
if (!position) {
|
|
896
|
-
logger.error("error getting extended position", position);
|
|
897
|
-
return {
|
|
898
|
-
extendedAmountInBTC: new Web3Number(0, 0),
|
|
899
|
-
calls: [],
|
|
900
|
-
};
|
|
901
|
-
}
|
|
902
|
-
const extendedPositionValue = position.length > 0 ? parseFloat(position[0].value) : 0;
|
|
903
|
-
const BUFFER_AMOUNT_IN_AVAILABLE_FOR_TRADE = BUFFER_USDC_IN_WITHDRAWAL;
|
|
904
|
-
const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
|
|
905
|
-
if (!extendedHoldings) {
|
|
906
|
-
logger.error(`error getting extended holdings: ${extendedHoldings}`);
|
|
907
|
-
return {
|
|
908
|
-
extendedAmountInBTC: new Web3Number(0, 0),
|
|
909
|
-
calls: [],
|
|
910
|
-
};
|
|
911
|
-
}
|
|
912
|
-
const extendedHoldingAmount = new Web3Number(
|
|
913
|
-
extendedHoldings.availableForWithdrawal,
|
|
914
|
-
USDC_TOKEN_DECIMALS
|
|
915
|
-
);
|
|
916
|
-
const {
|
|
917
|
-
collateralTokenAmount,
|
|
918
|
-
} = await vesuAdapter.vesuAdapter.getAssetPrices();
|
|
919
|
-
const { collateralPrice } = await this.getAssetPrices();
|
|
920
|
-
const { vesuAmountInBTC, extendedAmountInBTC } = calculateVesUPositionSizeGivenExtended(
|
|
921
|
-
extendedPositionValue,
|
|
922
|
-
extendedHoldingAmount.minus(BUFFER_AMOUNT_IN_AVAILABLE_FOR_TRADE),
|
|
923
|
-
collateralTokenAmount,
|
|
924
|
-
collateralPrice.price
|
|
925
|
-
);
|
|
926
|
-
logger.info(`vesuAmountInBTC ${vesuAmountInBTC}, extendedAmountInBTC ${extendedAmountInBTC}`);
|
|
927
|
-
|
|
928
|
-
let calls: Call[] = [];
|
|
929
|
-
if (vesuAmountInBTC.greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)) {
|
|
930
|
-
const proofsInfo = vesuAdapter.getProofs(true, this.getMerkleTree());
|
|
931
|
-
const proofGroups = proofsInfo.proofs;
|
|
932
|
-
const call = this.getManageCall(
|
|
933
|
-
proofGroups,
|
|
934
|
-
await proofsInfo.callConstructor({
|
|
935
|
-
amount: vesuAmountInBTC,
|
|
936
|
-
})
|
|
937
|
-
);
|
|
938
|
-
const { amount: wbtcAmountInVaultAllocator } = await this.getUnusedBalanceWBTC();
|
|
939
|
-
if (wbtcAmountInVaultAllocator.lessThan(vesuAmountInBTC)) {
|
|
940
|
-
const swapProofsInfo = avnuAdapter.getProofs(true, this.getMerkleTree());
|
|
941
|
-
const swapProofGroups = swapProofsInfo.proofs;
|
|
942
|
-
const swapCall = this.getManageCall(
|
|
943
|
-
swapProofGroups,
|
|
944
|
-
await swapProofsInfo.callConstructor({
|
|
945
|
-
amount: vesuAmountInBTC,
|
|
946
|
-
})
|
|
947
|
-
);
|
|
948
|
-
calls.push(swapCall);
|
|
949
|
-
}
|
|
950
|
-
calls.push(call);
|
|
951
|
-
}
|
|
952
|
-
const shortPosition = extendedAmountInBTC.multipliedBy(3).abs().greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
|
|
953
|
-
extendedLeverage.toString(),
|
|
954
|
-
extendedAmountInBTC.toNumber(),
|
|
955
|
-
OrderSide.SELL
|
|
956
|
-
) : null;
|
|
957
|
-
if (!shortPosition && extendedAmountInBTC.multipliedBy(3).abs().greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)) {
|
|
958
|
-
logger.error(`error creating short position thus no position to be opened on vesu: ${shortPosition}`);
|
|
959
|
-
return {
|
|
960
|
-
extendedAmountInBTC: new Web3Number(0, 0),
|
|
961
|
-
calls: [],
|
|
962
|
-
};
|
|
963
|
-
}
|
|
964
|
-
return {
|
|
965
|
-
extendedAmountInBTC: extendedAmountInBTC,
|
|
966
|
-
calls: calls,
|
|
967
|
-
};
|
|
906
|
+
/**
|
|
907
|
+
* Just a demo function, not used in the risk engine
|
|
908
|
+
*/
|
|
909
|
+
return this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.VAULT.name, amount: new Web3Number(0, 0) }, "NONE");
|
|
968
910
|
} catch (err) {
|
|
969
911
|
logger.error(`error handling deposit: ${err}`);
|
|
970
|
-
return {
|
|
971
|
-
extendedAmountInBTC: new Web3Number(0, 0),
|
|
972
|
-
calls: [],
|
|
973
|
-
};
|
|
912
|
+
return this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.VAULT.name, amount: new Web3Number(0, 0) }, "NONE");
|
|
974
913
|
}
|
|
975
914
|
}
|
|
976
915
|
|
|
@@ -1006,7 +945,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
1006
945
|
}
|
|
1007
946
|
}
|
|
1008
947
|
|
|
1009
|
-
async handleWithdraw(amount: Web3Number): Promise<
|
|
948
|
+
async handleWithdraw(amount: Web3Number): Promise<TransactionResult[]> {
|
|
1010
949
|
try {
|
|
1011
950
|
const usdcBalanceVaultAllocator = await this.getUnusedBalance();
|
|
1012
951
|
const usdcBalanceDifference = amount.plus(BUFFER_USDC_IN_WITHDRAWAL).minus(usdcBalanceVaultAllocator.usdValue);
|
|
@@ -1017,12 +956,8 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
1017
956
|
const withdrawCall = await this.getBringLiquidityCall({
|
|
1018
957
|
amount: usdcBalanceVaultAllocator.amount
|
|
1019
958
|
})
|
|
1020
|
-
logger.info("withdraw call", withdrawCall);
|
|
1021
959
|
calls.push(withdrawCall);
|
|
1022
|
-
return {
|
|
1023
|
-
calls: calls,
|
|
1024
|
-
status: true
|
|
1025
|
-
};
|
|
960
|
+
return [this.createTransactionResult(calls, true, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "WITHDRAWAL")];
|
|
1026
961
|
}
|
|
1027
962
|
const vesuAdapter = await this.getVesuAdapter();
|
|
1028
963
|
const extendedAdapter = await this.getExtendedAdapter();
|
|
@@ -1031,11 +966,9 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
1031
966
|
logger.error(
|
|
1032
967
|
`vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
|
|
1033
968
|
);
|
|
1034
|
-
return {
|
|
1035
|
-
calls: calls,
|
|
1036
|
-
status: status
|
|
1037
|
-
};
|
|
969
|
+
return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "NONE")];
|
|
1038
970
|
}
|
|
971
|
+
let transactionResults: TransactionResult[] = [];
|
|
1039
972
|
const { collateralTokenAmount } =
|
|
1040
973
|
await vesuAdapter.vesuAdapter.getAssetPrices();
|
|
1041
974
|
const {
|
|
@@ -1045,10 +978,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
1045
978
|
if (!extendedPositon) {
|
|
1046
979
|
status = false;
|
|
1047
980
|
logger.error("error getting extended position", extendedPositon);
|
|
1048
|
-
return {
|
|
1049
|
-
calls: calls,
|
|
1050
|
-
status: status
|
|
1051
|
-
}
|
|
981
|
+
return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "NONE")];
|
|
1052
982
|
}
|
|
1053
983
|
const amountDistributionForWithdrawal =
|
|
1054
984
|
await calculateAmountDistributionForWithdrawal(
|
|
@@ -1062,15 +992,12 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
1062
992
|
logger.error(
|
|
1063
993
|
`error calculating amount distribution for withdrawal: ${amountDistributionForWithdrawal}`
|
|
1064
994
|
);
|
|
1065
|
-
return {
|
|
1066
|
-
calls: calls,
|
|
1067
|
-
status: status
|
|
1068
|
-
};
|
|
995
|
+
return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "NONE")];
|
|
1069
996
|
}
|
|
1070
997
|
const { vesu_amount, extended_amount } = amountDistributionForWithdrawal;
|
|
1071
998
|
|
|
1072
999
|
if (status && vesu_amount.greaterThan(0)) {
|
|
1073
|
-
const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
|
|
1000
|
+
const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
|
|
1074
1001
|
{
|
|
1075
1002
|
amount: vesu_amount,
|
|
1076
1003
|
from: Protocols.VESU.name,
|
|
@@ -1080,10 +1007,14 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
1080
1007
|
vesuAdapter
|
|
1081
1008
|
);
|
|
1082
1009
|
status = vesuStatus;
|
|
1083
|
-
|
|
1010
|
+
transactionResults.push({
|
|
1011
|
+
status: vesuStatus,
|
|
1012
|
+
calls: vesuCalls,
|
|
1013
|
+
transactionMetadata: vesuTransactionMetadata
|
|
1014
|
+
})
|
|
1084
1015
|
}
|
|
1085
1016
|
if (status && extended_amount.greaterThan(0)) {
|
|
1086
|
-
const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
|
|
1017
|
+
const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
|
|
1087
1018
|
{
|
|
1088
1019
|
amount: extended_amount,
|
|
1089
1020
|
from: Protocols.EXTENDED.name,
|
|
@@ -1094,30 +1025,35 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
1094
1025
|
);
|
|
1095
1026
|
status = extendedStatus;
|
|
1096
1027
|
if (status) {
|
|
1097
|
-
|
|
1028
|
+
transactionResults.push({
|
|
1029
|
+
status: extendedStatus,
|
|
1030
|
+
calls: extendedCalls,
|
|
1031
|
+
transactionMetadata: extendedTransactionMetadata
|
|
1032
|
+
})
|
|
1098
1033
|
} else {
|
|
1099
1034
|
logger.error("error moving assets to vault: extendedStatus: ${extendedStatus}");
|
|
1100
|
-
return {
|
|
1101
|
-
calls: [],
|
|
1102
|
-
status: status
|
|
1103
|
-
};
|
|
1035
|
+
return [this.createTransactionResult([], status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "NONE")];
|
|
1104
1036
|
}
|
|
1105
1037
|
}
|
|
1106
1038
|
const withdrawCall = await this.getBringLiquidityCall({
|
|
1107
1039
|
amount: amount
|
|
1108
1040
|
})
|
|
1109
1041
|
logger.info("withdraw call", withdrawCall);
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
calls:
|
|
1113
|
-
|
|
1114
|
-
|
|
1042
|
+
transactionResults.push({
|
|
1043
|
+
status: status,
|
|
1044
|
+
calls: [withdrawCall],
|
|
1045
|
+
transactionMetadata: {
|
|
1046
|
+
protocolFrom: Protocols.VAULT.name,
|
|
1047
|
+
protocolTo: Protocols.NONE.name,
|
|
1048
|
+
transactionType: "WITHDRAWAL",
|
|
1049
|
+
usdAmount: amount.toFixed(),
|
|
1050
|
+
status: 'PENDING',
|
|
1051
|
+
}
|
|
1052
|
+
})
|
|
1053
|
+
return transactionResults;
|
|
1115
1054
|
} catch (err) {
|
|
1116
1055
|
logger.error(`error handling withdrawal: ${err}`);
|
|
1117
|
-
return {
|
|
1118
|
-
calls: [],
|
|
1119
|
-
status: false
|
|
1120
|
-
};
|
|
1056
|
+
return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "NONE")];
|
|
1121
1057
|
}
|
|
1122
1058
|
}
|
|
1123
1059
|
|
|
@@ -1165,7 +1101,39 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
1165
1101
|
}, prevAum: prevAum, splits: [realAUM, estimatedAUMDelta]
|
|
1166
1102
|
};
|
|
1167
1103
|
}
|
|
1104
|
+
|
|
1105
|
+
async processTransactionDataFromSDK(txnData: TransactionResult<any>[]): Promise<{ callsToBeExecutedFinal: Call[], txnMetadata: TransactionMetadata[] } | null> {
|
|
1106
|
+
try {
|
|
1107
|
+
const txnsToBeExecuted = txnData.filter(txn => {
|
|
1108
|
+
return txn.transactionMetadata.transactionType !== 'NONE' && txn.transactionMetadata.protocolFrom !== "" && txn.transactionMetadata.protocolTo !== "";
|
|
1109
|
+
})
|
|
1110
|
+
const callsToBeExecutedFinal = txnsToBeExecuted.flatMap(txn => txn.calls);
|
|
1111
|
+
const txnMetadata = txnsToBeExecuted.map(txn => txn.transactionMetadata);
|
|
1112
|
+
return { callsToBeExecutedFinal, txnMetadata };
|
|
1113
|
+
} catch (err) {
|
|
1114
|
+
logger.error(`error processing transaction data from SDK: ${err}`);
|
|
1115
|
+
return null;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1168
1118
|
|
|
1119
|
+
async processTransactionMetadata(txnMetadata: TransactionMetadata[], extendedIntentFulfilled: boolean): Promise<TransactionMetadata[] | null> {
|
|
1120
|
+
try {
|
|
1121
|
+
const txnMetadataNew = txnMetadata.map(txn => {
|
|
1122
|
+
const isExtendedProtocol = txn.protocolFrom === Protocols.EXTENDED.name || txn.protocolTo === Protocols.EXTENDED.name;
|
|
1123
|
+
// Only update status for extended protocol transactions since thsoe only cause delays
|
|
1124
|
+
if (isExtendedProtocol) {
|
|
1125
|
+
txn.status = extendedIntentFulfilled ? 'COMPLETED' : 'PENDING';
|
|
1126
|
+
} else {
|
|
1127
|
+
txn.status = 'COMPLETED';
|
|
1128
|
+
}
|
|
1129
|
+
return txn;
|
|
1130
|
+
})
|
|
1131
|
+
return txnMetadataNew;
|
|
1132
|
+
} catch (err) {
|
|
1133
|
+
logger.error(`error processing transaction data from SDK: ${err}`);
|
|
1134
|
+
return null;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1169
1137
|
}
|
|
1170
1138
|
|
|
1171
1139
|
function getLooperSettings(
|