@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.js CHANGED
@@ -43,6 +43,7 @@ __export(index_exports, {
43
43
  AssetOperationStatus: () => AssetOperationStatus,
44
44
  AssetOperationType: () => AssetOperationType,
45
45
  AutoCompounderSTRK: () => AutoCompounderSTRK,
46
+ AvnuAdapter: () => AvnuAdapter,
46
47
  AvnuWrapper: () => AvnuWrapper,
47
48
  BaseAdapter: () => BaseAdapter,
48
49
  BaseStrategy: () => BaseStrategy,
@@ -126,6 +127,7 @@ __export(index_exports, {
126
127
  calculateExtendedLevergae: () => calculateExtendedLevergae,
127
128
  calculateVesUPositionSizeGivenExtended: () => calculateVesUPositionSizeGivenExtended,
128
129
  calculateVesuLeverage: () => calculateVesuLeverage,
130
+ calculateWBTCAmountToMaintainLTV: () => calculateWBTCAmountToMaintainLTV,
129
131
  extensionMap: () => extensionMap,
130
132
  getAPIUsingHeadlessBrowser: () => getAPIUsingHeadlessBrowser,
131
133
  getContractDetails: () => getContractDetails,
@@ -28351,6 +28353,21 @@ var calculateAmountDepositOnExtendedWhenIncurringLosses = async (client) => {
28351
28353
  return null;
28352
28354
  }
28353
28355
  };
28356
+ var calculateWBTCAmountToMaintainLTV = (collateralAmount, debtAmount, debtPrice, maxLtv = MAX_LIQUIDATION_RATIO, collateralPrice, targetHF = TARGET_HF) => {
28357
+ try {
28358
+ const numerator1 = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLtv);
28359
+ const numerator2 = debtAmount.multipliedBy(debtPrice).multipliedBy(targetHF);
28360
+ const denominator = maxLtv;
28361
+ const collateralAmountToMaintainLTV = numerator2.minus(numerator1).dividedBy(denominator);
28362
+ let deltaCollateralAmountUnits = new Web3Number(
28363
+ collateralAmountToMaintainLTV.dividedBy(collateralPrice).toFixed(WBTC_TOKEN_DECIMALS),
28364
+ WBTC_TOKEN_DECIMALS
28365
+ );
28366
+ return { deltaCollateralAmountUnits };
28367
+ } catch (err) {
28368
+ return { deltaCollateralAmountUnits: null };
28369
+ }
28370
+ };
28354
28371
  var calculateExposureDelta = (exposure_extended, exposure_vesu) => {
28355
28372
  const exposure_delta = new Web3Number(exposure_extended - exposure_vesu, 2);
28356
28373
  return exposure_delta.absoluteValue().toNumber();
@@ -30090,26 +30107,38 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30090
30107
  try {
30091
30108
  if (!this.client) {
30092
30109
  logger.error("Client not initialized");
30093
- return false;
30110
+ return {
30111
+ status: false,
30112
+ receivedTxnHash: false
30113
+ };
30094
30114
  }
30095
30115
  if (amount.lessThanOrEqualTo(0)) {
30096
30116
  logger.error(
30097
30117
  `Invalid withdrawal amount: ${amount.toNumber()}. Amount must be positive.`
30098
30118
  );
30099
- return false;
30119
+ return {
30120
+ status: false,
30121
+ receivedTxnHash: false
30122
+ };
30100
30123
  }
30101
30124
  if (amount.lessThanOrEqualTo(this.minimumExtendedMovementAmount)) {
30102
30125
  logger.warn(
30103
30126
  `Withdrawal amount ${amount.toNumber()} is below minimum Extended movement amount ${this.minimumExtendedMovementAmount}. Skipping withdrawal.`
30104
30127
  );
30105
- return false;
30128
+ return {
30129
+ status: false,
30130
+ receivedTxnHash: false
30131
+ };
30106
30132
  }
30107
30133
  const holdings = await this.getExtendedDepositAmount();
30108
30134
  if (!holdings) {
30109
30135
  logger.error(
30110
30136
  "Cannot get holdings - unable to validate withdrawal amount"
30111
30137
  );
30112
- return false;
30138
+ return {
30139
+ status: false,
30140
+ receivedTxnHash: false
30141
+ };
30113
30142
  }
30114
30143
  const availableForWithdrawal = parseFloat(
30115
30144
  holdings.availableForWithdrawal
@@ -30118,14 +30147,20 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30118
30147
  logger.error(
30119
30148
  `Invalid availableForWithdrawal: ${holdings.availableForWithdrawal}. Expected a finite, non-negative number.`
30120
30149
  );
30121
- return false;
30150
+ return {
30151
+ status: false,
30152
+ receivedTxnHash: false
30153
+ };
30122
30154
  }
30123
30155
  const withdrawalAmount = amount.toNumber();
30124
30156
  if (withdrawalAmount > availableForWithdrawal) {
30125
30157
  logger.error(
30126
30158
  `Withdrawal amount ${withdrawalAmount} exceeds available balance ${availableForWithdrawal}`
30127
30159
  );
30128
- return false;
30160
+ return {
30161
+ status: false,
30162
+ receivedTxnHash: false
30163
+ };
30129
30164
  }
30130
30165
  logger.info(
30131
30166
  `Withdrawing ${withdrawalAmount} from Extended. Available balance: ${availableForWithdrawal}`
@@ -30138,15 +30173,24 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30138
30173
  withdrawalRequest.data,
30139
30174
  "WITHDRAWAL" /* WITHDRAWAL */
30140
30175
  );
30141
- return withdrawalStatus;
30176
+ return {
30177
+ status: true,
30178
+ receivedTxnHash: withdrawalStatus
30179
+ };
30142
30180
  }
30143
30181
  logger.error(
30144
30182
  `Withdrawal request failed with status: ${withdrawalRequest.status}`
30145
30183
  );
30146
- return false;
30184
+ return {
30185
+ status: false,
30186
+ receivedTxnHash: false
30187
+ };
30147
30188
  } catch (error) {
30148
30189
  logger.error(`Error creating Withdraw Call: ${error}`);
30149
- return false;
30190
+ return {
30191
+ status: false,
30192
+ receivedTxnHash: false
30193
+ };
30150
30194
  }
30151
30195
  }
30152
30196
  async getHealthFactor() {
@@ -30632,6 +30676,336 @@ var UnusedBalanceAdapter = class _UnusedBalanceAdapter extends BaseAdapter {
30632
30676
  }
30633
30677
  };
30634
30678
 
30679
+ // src/strategies/universal-adapters/avnu-adapter.ts
30680
+ var import_starknet23 = require("starknet");
30681
+ var import_axios9 = __toESM(require("axios"));
30682
+ var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
30683
+ constructor(config) {
30684
+ super(config, _AvnuAdapter.name, Protocols.AVNU);
30685
+ this.config = config;
30686
+ this.avnuWrapper = new AvnuWrapper();
30687
+ }
30688
+ //abstract means the method has no implementation in this class; instead, child classes must implement it.
30689
+ async getAPY(supportedPosition) {
30690
+ return Promise.resolve({ apy: 0, type: "base" /* BASE */ });
30691
+ }
30692
+ async getPosition(supportedPosition) {
30693
+ return Promise.resolve({ amount: new Web3Number(0, 0), remarks: "" });
30694
+ }
30695
+ async maxDeposit(amount) {
30696
+ return Promise.resolve({
30697
+ tokenInfo: this.config.baseToken,
30698
+ amount: new Web3Number(0, 0),
30699
+ usdValue: 0,
30700
+ apy: { apy: 0, type: "base" /* BASE */ },
30701
+ protocol: Protocols.AVNU,
30702
+ remarks: ""
30703
+ });
30704
+ }
30705
+ async maxWithdraw() {
30706
+ return Promise.resolve({
30707
+ tokenInfo: this.config.baseToken,
30708
+ amount: new Web3Number(0, 0),
30709
+ usdValue: 0,
30710
+ apy: { apy: 0, type: "base" /* BASE */ },
30711
+ protocol: Protocols.AVNU,
30712
+ remarks: ""
30713
+ });
30714
+ }
30715
+ _getDepositLeaf() {
30716
+ const vaultAllocator = ContractAddr.from(
30717
+ this.config.vaultAllocator.address
30718
+ );
30719
+ return [
30720
+ {
30721
+ target: this.config.supportedPositions[0].asset.address,
30722
+ method: "approve",
30723
+ packedArguments: [
30724
+ AVNU_EXCHANGE.toBigInt()
30725
+ ],
30726
+ sanitizer: SIMPLE_SANITIZER,
30727
+ id: `approve_${this.config.supportedPositions[0].asset.symbol}`
30728
+ },
30729
+ {
30730
+ target: AVNU_EXCHANGE,
30731
+ method: "multi_route_swap",
30732
+ packedArguments: [
30733
+ this.config.supportedPositions[0].asset.address.toBigInt(),
30734
+ //usdc
30735
+ this.config.supportedPositions[1].asset.address.toBigInt(),
30736
+ //wbtc
30737
+ vaultAllocator.toBigInt()
30738
+ ],
30739
+ sanitizer: SIMPLE_SANITIZER,
30740
+ id: `asutb_${this.config.supportedPositions[0].asset.symbol}_${this.config.supportedPositions[1].asset.symbol}`
30741
+ }
30742
+ ];
30743
+ }
30744
+ _getWithdrawLeaf() {
30745
+ const vaultAllocator = ContractAddr.from(
30746
+ this.config.vaultAllocator.address
30747
+ );
30748
+ const toToken = this.config.supportedPositions[0].asset;
30749
+ const fromToken = this.config.supportedPositions[1].asset;
30750
+ return [
30751
+ {
30752
+ target: fromToken.address,
30753
+ method: "approve",
30754
+ packedArguments: [
30755
+ AVNU_EXCHANGE.toBigInt()
30756
+ ],
30757
+ sanitizer: SIMPLE_SANITIZER,
30758
+ id: `approve_${fromToken.symbol}`
30759
+ },
30760
+ {
30761
+ target: AVNU_EXCHANGE,
30762
+ method: "multi_route_swap",
30763
+ packedArguments: [
30764
+ fromToken.address.toBigInt(),
30765
+ //wbtc
30766
+ toToken.address.toBigInt(),
30767
+ //usdc
30768
+ vaultAllocator.toBigInt()
30769
+ ],
30770
+ sanitizer: SIMPLE_SANITIZER,
30771
+ id: `asbtu_${fromToken.symbol}_${fromToken.symbol}`
30772
+ }
30773
+ ];
30774
+ }
30775
+ _getLegacySwapLeaf() {
30776
+ return [];
30777
+ }
30778
+ async getDepositCall(params) {
30779
+ try {
30780
+ const fromToken = this.config.supportedPositions[0].asset;
30781
+ const toToken = this.config.supportedPositions[1].asset;
30782
+ const vaultAllocator = ContractAddr.from(
30783
+ this.config.vaultAllocator.address
30784
+ );
30785
+ const quote = await this.getQuotesAvnu(
30786
+ fromToken.address.toString(),
30787
+ toToken.address.toString(),
30788
+ params.amount.toNumber(),
30789
+ vaultAllocator.address.toString(),
30790
+ toToken.decimals,
30791
+ true
30792
+ );
30793
+ if (!quote) {
30794
+ logger.error("error getting quote from avnu");
30795
+ return [];
30796
+ }
30797
+ const getCalldata = await this.avnuWrapper.getSwapCallData(
30798
+ quote,
30799
+ vaultAllocator.address
30800
+ );
30801
+ const swapCallData = getCalldata[0];
30802
+ const amount = import_starknet23.uint256.bnToUint256(quote.sellAmountInUsd * 10 ** 7);
30803
+ return [
30804
+ {
30805
+ sanitizer: SIMPLE_SANITIZER,
30806
+ call: {
30807
+ contractAddress: fromToken.address,
30808
+ selector: import_starknet23.hash.getSelectorFromName("approve"),
30809
+ calldata: [
30810
+ AVNU_EXCHANGE.toBigInt(),
30811
+ toBigInt(amount.low.toString()),
30812
+ // amount low
30813
+ toBigInt(amount.high.toString())
30814
+ // amount high
30815
+ ]
30816
+ }
30817
+ },
30818
+ {
30819
+ sanitizer: SIMPLE_SANITIZER,
30820
+ call: {
30821
+ contractAddress: AVNU_EXCHANGE,
30822
+ selector: import_starknet23.hash.getSelectorFromName("multi_route_swap"),
30823
+ calldata: swapCallData
30824
+ }
30825
+ }
30826
+ ];
30827
+ } catch (error) {
30828
+ logger.error(`Error getting Avnu quote: ${error}`);
30829
+ return [];
30830
+ }
30831
+ }
30832
+ //Swap wbtc to usdc
30833
+ async getWithdrawCall(params) {
30834
+ try {
30835
+ const toToken = this.config.supportedPositions[0].asset;
30836
+ const fromToken = this.config.supportedPositions[1].asset;
30837
+ const vaultAllocator = ContractAddr.from(
30838
+ this.config.vaultAllocator.address
30839
+ );
30840
+ const quote = await this.getQuotesAvnu(
30841
+ fromToken.address.toString(),
30842
+ toToken.address.toString(),
30843
+ params.amount.toNumber(),
30844
+ vaultAllocator.address.toString(),
30845
+ fromToken.decimals,
30846
+ false
30847
+ );
30848
+ if (!quote) {
30849
+ logger.error("No quotes available for this swap, error in quotes avnu");
30850
+ return [];
30851
+ }
30852
+ const getCalldata = await this.avnuWrapper.getSwapCallData(
30853
+ quote,
30854
+ vaultAllocator.address
30855
+ );
30856
+ const swapCallData = getCalldata[0];
30857
+ const amount = import_starknet23.uint256.bnToUint256(params.amount.toWei());
30858
+ return [
30859
+ {
30860
+ sanitizer: SIMPLE_SANITIZER,
30861
+ call: {
30862
+ contractAddress: fromToken.address,
30863
+ selector: import_starknet23.hash.getSelectorFromName("approve"),
30864
+ calldata: [
30865
+ AVNU_EXCHANGE.toBigInt(),
30866
+ toBigInt(amount.low.toString()),
30867
+ // amount low
30868
+ toBigInt(amount.high.toString())
30869
+ // amount high
30870
+ ]
30871
+ }
30872
+ },
30873
+ {
30874
+ sanitizer: SIMPLE_SANITIZER,
30875
+ call: {
30876
+ contractAddress: AVNU_EXCHANGE,
30877
+ selector: import_starknet23.hash.getSelectorFromName("multi_route_swap"),
30878
+ calldata: swapCallData
30879
+ }
30880
+ }
30881
+ ];
30882
+ } catch (error) {
30883
+ logger.error(`Error getting Avnu quote: ${error}`);
30884
+ return [];
30885
+ }
30886
+ }
30887
+ async getSwapCallData(quote) {
30888
+ return await this.avnuWrapper.getSwapCallData(quote, this.config.vaultAllocator.address);
30889
+ }
30890
+ async getHealthFactor() {
30891
+ return Promise.resolve(1);
30892
+ }
30893
+ async fetchQuoteWithRetry(params, retries = 5) {
30894
+ for (let attempt = 0; attempt < retries; attempt++) {
30895
+ try {
30896
+ const response = await import_axios9.default.get(this.config.baseUrl, { params });
30897
+ if (response.data && response.data.length > 0) {
30898
+ return response;
30899
+ }
30900
+ throw new Error("Empty response data");
30901
+ } catch (err) {
30902
+ logger.error(`Error fetching quote with retry: ${err}`);
30903
+ if (attempt === retries - 1) {
30904
+ throw err;
30905
+ }
30906
+ await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
30907
+ }
30908
+ }
30909
+ throw new Error("Failed to fetch quote after retries");
30910
+ }
30911
+ async getQuotesAvnu(from_token_address, to_token_address, amount, takerAddress, toTokenDecimals, usdcToBtc, maxIterations = 5, tolerance = 5e3) {
30912
+ try {
30913
+ const fromToken = this.config.supportedPositions[0].asset;
30914
+ const toToken = this.config.supportedPositions[1].asset;
30915
+ if (!usdcToBtc) {
30916
+ const sellAmount2 = returnFormattedAmount(amount, toTokenDecimals);
30917
+ const params2 = {
30918
+ sellTokenAddress: from_token_address,
30919
+ buyTokenAddress: to_token_address,
30920
+ takerAddress,
30921
+ sellAmount: sellAmount2
30922
+ };
30923
+ const finalQuote2 = await this.fetchQuoteWithRetry(params2);
30924
+ if (!finalQuote2.data.length) {
30925
+ logger.error("No quotes available for this swap, error in quotes avnu");
30926
+ return null;
30927
+ }
30928
+ const dataObject2 = finalQuote2.data[0];
30929
+ return dataObject2;
30930
+ }
30931
+ const btcPrice = await this.getPriceOfToken(toToken.address.toString());
30932
+ if (!btcPrice) {
30933
+ logger.error(`error getting btc price: ${btcPrice}`);
30934
+ return null;
30935
+ }
30936
+ const estimatedUsdcAmount = Math.floor(amount * btcPrice);
30937
+ const targetBtcBig = BigInt(returnFormattedAmount(amount, toTokenDecimals));
30938
+ let low = BigInt(
30939
+ Math.floor(
30940
+ estimatedUsdcAmount * 10 ** fromToken.decimals * 0.9
30941
+ )
30942
+ );
30943
+ let high = BigInt(
30944
+ Math.floor(
30945
+ estimatedUsdcAmount * 10 ** fromToken.decimals * 1.1
30946
+ )
30947
+ );
30948
+ let mid = 0n;
30949
+ for (let i = 0; i < maxIterations; i++) {
30950
+ mid = (low + high) / 2n;
30951
+ const sellAmount2 = returnFormattedAmount(Number(mid), 0);
30952
+ const quote = await this.fetchQuoteWithRetry({
30953
+ sellTokenAddress: from_token_address,
30954
+ buyTokenAddress: to_token_address,
30955
+ takerAddress,
30956
+ sellAmount: sellAmount2
30957
+ });
30958
+ const gotBtc = BigInt(quote.data[0].buyAmount);
30959
+ if (gotBtc === targetBtcBig) return quote.data[0];
30960
+ if (gotBtc > targetBtcBig) {
30961
+ high = mid;
30962
+ } else {
30963
+ low = mid;
30964
+ }
30965
+ if (gotBtc >= targetBtcBig && gotBtc <= targetBtcBig + BigInt(tolerance)) {
30966
+ return quote.data[0];
30967
+ }
30968
+ }
30969
+ let sellAmount = returnFormattedAmount(
30970
+ Number(mid),
30971
+ 0
30972
+ );
30973
+ const params = {
30974
+ sellTokenAddress: from_token_address,
30975
+ buyTokenAddress: to_token_address,
30976
+ takerAddress,
30977
+ sellAmount
30978
+ };
30979
+ const finalQuote = await this.fetchQuoteWithRetry(params);
30980
+ if (!finalQuote.data.length) {
30981
+ logger.error("No quotes available for this swap, error in quotes avnu");
30982
+ return null;
30983
+ }
30984
+ const dataObject = finalQuote.data[0];
30985
+ return dataObject;
30986
+ } catch (err) {
30987
+ logger.error(`No quotes available for this swap: ${err}`);
30988
+ return null;
30989
+ }
30990
+ }
30991
+ async getPriceOfToken(tokenAddress, retries = MAX_RETRIES) {
30992
+ try {
30993
+ const url = `https://starknet.impulse.avnu.fi/v1/tokens/${tokenAddress}/prices/line`;
30994
+ const response = await import_axios9.default.get(url);
30995
+ const length = response.data.length;
30996
+ return response.data[length - 1].value;
30997
+ } catch (err) {
30998
+ if (retries > 0) {
30999
+ await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
31000
+ return this.getPriceOfToken(tokenAddress, retries - 1);
31001
+ } else {
31002
+ logger.error(`Failed to fetch price for ${tokenAddress} after ${MAX_RETRIES} attempts`);
31003
+ return null;
31004
+ }
31005
+ }
31006
+ }
31007
+ };
31008
+
30635
31009
  // src/strategies/universal-strategy.tsx
30636
31010
  var AUMTypes = /* @__PURE__ */ ((AUMTypes2) => {
30637
31011
  AUMTypes2["FINALISED"] = "finalised";
@@ -30670,7 +31044,7 @@ function getContractDetails(settings) {
30670
31044
  }
30671
31045
 
30672
31046
  // src/strategies/svk-strategy.ts
30673
- var import_starknet23 = require("starknet");
31047
+ var import_starknet24 = require("starknet");
30674
31048
 
30675
31049
  // src/data/universal-vault.abi.json
30676
31050
  var universal_vault_abi_default = [
@@ -32997,12 +33371,12 @@ var SVKStrategy = class extends BaseStrategy {
32997
33371
  this.pricer = pricer;
32998
33372
  this.metadata = metadata;
32999
33373
  this.address = metadata.address;
33000
- this.contract = new import_starknet23.Contract({
33374
+ this.contract = new import_starknet24.Contract({
33001
33375
  abi: universal_vault_abi_default,
33002
33376
  address: this.address.address,
33003
33377
  providerOrAccount: this.config.provider
33004
33378
  });
33005
- this.managerContract = new import_starknet23.Contract({
33379
+ this.managerContract = new import_starknet24.Contract({
33006
33380
  abi: vault_manager_abi_default,
33007
33381
  address: this.metadata.additionalInfo.manager.address,
33008
33382
  providerOrAccount: this.config.provider
@@ -33115,7 +33489,7 @@ var SVKStrategy = class extends BaseStrategy {
33115
33489
  getSetManagerCall(strategist, root = this.getMerkleRoot()) {
33116
33490
  return this.managerContract.populate("set_manage_root", [
33117
33491
  strategist.address,
33118
- import_starknet23.num.getHexString(root)
33492
+ import_starknet24.num.getHexString(root)
33119
33493
  ]);
33120
33494
  }
33121
33495
  /**
@@ -34053,336 +34427,6 @@ var HyperLSTStrategies = [
34053
34427
  getStrategySettings("mRe7YIELD", "mRe7YIELD", hypermRe7YIELD, false, false)
34054
34428
  ];
34055
34429
 
34056
- // src/strategies/universal-adapters/avnu-adapter.ts
34057
- var import_starknet24 = require("starknet");
34058
- var import_axios9 = __toESM(require("axios"));
34059
- var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
34060
- constructor(config) {
34061
- super(config, _AvnuAdapter.name, Protocols.AVNU);
34062
- this.config = config;
34063
- this.avnuWrapper = new AvnuWrapper();
34064
- }
34065
- //abstract means the method has no implementation in this class; instead, child classes must implement it.
34066
- async getAPY(supportedPosition) {
34067
- return Promise.resolve({ apy: 0, type: "base" /* BASE */ });
34068
- }
34069
- async getPosition(supportedPosition) {
34070
- return Promise.resolve({ amount: new Web3Number(0, 0), remarks: "" });
34071
- }
34072
- async maxDeposit(amount) {
34073
- return Promise.resolve({
34074
- tokenInfo: this.config.baseToken,
34075
- amount: new Web3Number(0, 0),
34076
- usdValue: 0,
34077
- apy: { apy: 0, type: "base" /* BASE */ },
34078
- protocol: Protocols.AVNU,
34079
- remarks: ""
34080
- });
34081
- }
34082
- async maxWithdraw() {
34083
- return Promise.resolve({
34084
- tokenInfo: this.config.baseToken,
34085
- amount: new Web3Number(0, 0),
34086
- usdValue: 0,
34087
- apy: { apy: 0, type: "base" /* BASE */ },
34088
- protocol: Protocols.AVNU,
34089
- remarks: ""
34090
- });
34091
- }
34092
- _getDepositLeaf() {
34093
- const vaultAllocator = ContractAddr.from(
34094
- this.config.vaultAllocator.address
34095
- );
34096
- return [
34097
- {
34098
- target: this.config.supportedPositions[0].asset.address,
34099
- method: "approve",
34100
- packedArguments: [
34101
- AVNU_EXCHANGE.toBigInt()
34102
- ],
34103
- sanitizer: SIMPLE_SANITIZER,
34104
- id: `approve_${this.config.supportedPositions[0].asset.symbol}`
34105
- },
34106
- {
34107
- target: AVNU_EXCHANGE,
34108
- method: "multi_route_swap",
34109
- packedArguments: [
34110
- this.config.supportedPositions[0].asset.address.toBigInt(),
34111
- //usdc
34112
- this.config.supportedPositions[1].asset.address.toBigInt(),
34113
- //wbtc
34114
- vaultAllocator.toBigInt()
34115
- ],
34116
- sanitizer: SIMPLE_SANITIZER,
34117
- id: `asutb_${this.config.supportedPositions[0].asset.symbol}_${this.config.supportedPositions[1].asset.symbol}`
34118
- }
34119
- ];
34120
- }
34121
- _getWithdrawLeaf() {
34122
- const vaultAllocator = ContractAddr.from(
34123
- this.config.vaultAllocator.address
34124
- );
34125
- const toToken = this.config.supportedPositions[0].asset;
34126
- const fromToken = this.config.supportedPositions[1].asset;
34127
- return [
34128
- {
34129
- target: fromToken.address,
34130
- method: "approve",
34131
- packedArguments: [
34132
- AVNU_EXCHANGE.toBigInt()
34133
- ],
34134
- sanitizer: SIMPLE_SANITIZER,
34135
- id: `approve_${fromToken.symbol}`
34136
- },
34137
- {
34138
- target: AVNU_EXCHANGE,
34139
- method: "multi_route_swap",
34140
- packedArguments: [
34141
- fromToken.address.toBigInt(),
34142
- //wbtc
34143
- toToken.address.toBigInt(),
34144
- //usdc
34145
- vaultAllocator.toBigInt()
34146
- ],
34147
- sanitizer: SIMPLE_SANITIZER,
34148
- id: `asbtu_${fromToken.symbol}_${fromToken.symbol}`
34149
- }
34150
- ];
34151
- }
34152
- _getLegacySwapLeaf() {
34153
- return [];
34154
- }
34155
- async getDepositCall(params) {
34156
- try {
34157
- const fromToken = this.config.supportedPositions[0].asset;
34158
- const toToken = this.config.supportedPositions[1].asset;
34159
- const vaultAllocator = ContractAddr.from(
34160
- this.config.vaultAllocator.address
34161
- );
34162
- const quote = await this.getQuotesAvnu(
34163
- fromToken.address.toString(),
34164
- toToken.address.toString(),
34165
- params.amount.toNumber(),
34166
- vaultAllocator.address.toString(),
34167
- toToken.decimals,
34168
- true
34169
- );
34170
- if (!quote) {
34171
- logger.error("error getting quote from avnu");
34172
- return [];
34173
- }
34174
- const getCalldata = await this.avnuWrapper.getSwapCallData(
34175
- quote,
34176
- vaultAllocator.address
34177
- );
34178
- const swapCallData = getCalldata[0];
34179
- const amount = import_starknet24.uint256.bnToUint256(quote.sellAmountInUsd * 10 ** 7);
34180
- return [
34181
- {
34182
- sanitizer: SIMPLE_SANITIZER,
34183
- call: {
34184
- contractAddress: fromToken.address,
34185
- selector: import_starknet24.hash.getSelectorFromName("approve"),
34186
- calldata: [
34187
- AVNU_EXCHANGE.toBigInt(),
34188
- toBigInt(amount.low.toString()),
34189
- // amount low
34190
- toBigInt(amount.high.toString())
34191
- // amount high
34192
- ]
34193
- }
34194
- },
34195
- {
34196
- sanitizer: SIMPLE_SANITIZER,
34197
- call: {
34198
- contractAddress: AVNU_EXCHANGE,
34199
- selector: import_starknet24.hash.getSelectorFromName("multi_route_swap"),
34200
- calldata: swapCallData
34201
- }
34202
- }
34203
- ];
34204
- } catch (error) {
34205
- logger.error(`Error getting Avnu quote: ${error}`);
34206
- return [];
34207
- }
34208
- }
34209
- //Swap wbtc to usdc
34210
- async getWithdrawCall(params) {
34211
- try {
34212
- const toToken = this.config.supportedPositions[0].asset;
34213
- const fromToken = this.config.supportedPositions[1].asset;
34214
- const vaultAllocator = ContractAddr.from(
34215
- this.config.vaultAllocator.address
34216
- );
34217
- const quote = await this.getQuotesAvnu(
34218
- fromToken.address.toString(),
34219
- toToken.address.toString(),
34220
- params.amount.toNumber(),
34221
- vaultAllocator.address.toString(),
34222
- fromToken.decimals,
34223
- false
34224
- );
34225
- if (!quote) {
34226
- logger.error("No quotes available for this swap, error in quotes avnu");
34227
- return [];
34228
- }
34229
- const getCalldata = await this.avnuWrapper.getSwapCallData(
34230
- quote,
34231
- vaultAllocator.address
34232
- );
34233
- const swapCallData = getCalldata[0];
34234
- const amount = import_starknet24.uint256.bnToUint256(params.amount.toWei());
34235
- return [
34236
- {
34237
- sanitizer: SIMPLE_SANITIZER,
34238
- call: {
34239
- contractAddress: fromToken.address,
34240
- selector: import_starknet24.hash.getSelectorFromName("approve"),
34241
- calldata: [
34242
- AVNU_EXCHANGE.toBigInt(),
34243
- toBigInt(amount.low.toString()),
34244
- // amount low
34245
- toBigInt(amount.high.toString())
34246
- // amount high
34247
- ]
34248
- }
34249
- },
34250
- {
34251
- sanitizer: SIMPLE_SANITIZER,
34252
- call: {
34253
- contractAddress: AVNU_EXCHANGE,
34254
- selector: import_starknet24.hash.getSelectorFromName("multi_route_swap"),
34255
- calldata: swapCallData
34256
- }
34257
- }
34258
- ];
34259
- } catch (error) {
34260
- logger.error(`Error getting Avnu quote: ${error}`);
34261
- return [];
34262
- }
34263
- }
34264
- async getSwapCallData(quote) {
34265
- return await this.avnuWrapper.getSwapCallData(quote, this.config.vaultAllocator.address);
34266
- }
34267
- async getHealthFactor() {
34268
- return Promise.resolve(1);
34269
- }
34270
- async fetchQuoteWithRetry(params, retries = 5) {
34271
- for (let attempt = 0; attempt < retries; attempt++) {
34272
- try {
34273
- const response = await import_axios9.default.get(this.config.baseUrl, { params });
34274
- if (response.data && response.data.length > 0) {
34275
- return response;
34276
- }
34277
- throw new Error("Empty response data");
34278
- } catch (err) {
34279
- logger.error(`Error fetching quote with retry: ${err}`);
34280
- if (attempt === retries - 1) {
34281
- throw err;
34282
- }
34283
- await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
34284
- }
34285
- }
34286
- throw new Error("Failed to fetch quote after retries");
34287
- }
34288
- async getQuotesAvnu(from_token_address, to_token_address, amount, takerAddress, toTokenDecimals, usdcToBtc, maxIterations = 5, tolerance = 5e3) {
34289
- try {
34290
- const fromToken = this.config.supportedPositions[0].asset;
34291
- const toToken = this.config.supportedPositions[1].asset;
34292
- if (!usdcToBtc) {
34293
- const sellAmount2 = returnFormattedAmount(amount, toTokenDecimals);
34294
- const params2 = {
34295
- sellTokenAddress: from_token_address,
34296
- buyTokenAddress: to_token_address,
34297
- takerAddress,
34298
- sellAmount: sellAmount2
34299
- };
34300
- const finalQuote2 = await this.fetchQuoteWithRetry(params2);
34301
- if (!finalQuote2.data.length) {
34302
- logger.error("No quotes available for this swap, error in quotes avnu");
34303
- return null;
34304
- }
34305
- const dataObject2 = finalQuote2.data[0];
34306
- return dataObject2;
34307
- }
34308
- const btcPrice = await this.getPriceOfToken(toToken.address.toString());
34309
- if (!btcPrice) {
34310
- logger.error(`error getting btc price: ${btcPrice}`);
34311
- return null;
34312
- }
34313
- const estimatedUsdcAmount = Math.floor(amount * btcPrice);
34314
- const targetBtcBig = BigInt(returnFormattedAmount(amount, toTokenDecimals));
34315
- let low = BigInt(
34316
- Math.floor(
34317
- estimatedUsdcAmount * 10 ** fromToken.decimals * 0.9
34318
- )
34319
- );
34320
- let high = BigInt(
34321
- Math.floor(
34322
- estimatedUsdcAmount * 10 ** fromToken.decimals * 1.1
34323
- )
34324
- );
34325
- let mid = 0n;
34326
- for (let i = 0; i < maxIterations; i++) {
34327
- mid = (low + high) / 2n;
34328
- const sellAmount2 = returnFormattedAmount(Number(mid), 0);
34329
- const quote = await this.fetchQuoteWithRetry({
34330
- sellTokenAddress: from_token_address,
34331
- buyTokenAddress: to_token_address,
34332
- takerAddress,
34333
- sellAmount: sellAmount2
34334
- });
34335
- const gotBtc = BigInt(quote.data[0].buyAmount);
34336
- if (gotBtc === targetBtcBig) return quote.data[0];
34337
- if (gotBtc > targetBtcBig) {
34338
- high = mid;
34339
- } else {
34340
- low = mid;
34341
- }
34342
- if (gotBtc >= targetBtcBig && gotBtc <= targetBtcBig + BigInt(tolerance)) {
34343
- return quote.data[0];
34344
- }
34345
- }
34346
- let sellAmount = returnFormattedAmount(
34347
- Number(mid),
34348
- 0
34349
- );
34350
- const params = {
34351
- sellTokenAddress: from_token_address,
34352
- buyTokenAddress: to_token_address,
34353
- takerAddress,
34354
- sellAmount
34355
- };
34356
- const finalQuote = await this.fetchQuoteWithRetry(params);
34357
- if (!finalQuote.data.length) {
34358
- logger.error("No quotes available for this swap, error in quotes avnu");
34359
- return null;
34360
- }
34361
- const dataObject = finalQuote.data[0];
34362
- return dataObject;
34363
- } catch (err) {
34364
- logger.error(`No quotes available for this swap: ${err}`);
34365
- return null;
34366
- }
34367
- }
34368
- async getPriceOfToken(tokenAddress, retries = MAX_RETRIES) {
34369
- try {
34370
- const url = `https://starknet.impulse.avnu.fi/v1/tokens/${tokenAddress}/prices/line`;
34371
- const response = await import_axios9.default.get(url);
34372
- const length = response.data.length;
34373
- return response.data[length - 1].value;
34374
- } catch (err) {
34375
- if (retries > 0) {
34376
- await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
34377
- return this.getPriceOfToken(tokenAddress, retries - 1);
34378
- } else {
34379
- logger.error(`Failed to fetch price for ${tokenAddress} after ${MAX_RETRIES} attempts`);
34380
- return null;
34381
- }
34382
- }
34383
- }
34384
- };
34385
-
34386
34430
  // src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx
34387
34431
  var import_jsx_runtime5 = require("react/jsx-runtime");
34388
34432
  var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy extends SVKStrategy {
@@ -34499,10 +34543,16 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34499
34543
  proofGroups,
34500
34544
  await proofsInfo.callConstructor({ amount })
34501
34545
  );
34502
- return [approveCall, transferCall, call];
34546
+ return {
34547
+ calls: [approveCall, transferCall, call],
34548
+ status: true
34549
+ };
34503
34550
  } catch (err) {
34504
34551
  logger.error(`error moving assets to vault allocator: ${err}`);
34505
- return [];
34552
+ return {
34553
+ calls: [],
34554
+ status: false
34555
+ };
34506
34556
  }
34507
34557
  }
34508
34558
  async shouldInvest() {
@@ -34751,9 +34801,10 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34751
34801
  const vesuAmountDifferenceAbs = vesuAmountDifference.abs();
34752
34802
  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()}`);
34753
34803
  let calls = [];
34804
+ let transactionResults = [];
34754
34805
  if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34755
34806
  try {
34756
- const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
34807
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
34757
34808
  {
34758
34809
  to: Protocols.VAULT.name,
34759
34810
  from: Protocols.EXTENDED.name,
@@ -34763,17 +34814,25 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34763
34814
  vesuAdapter
34764
34815
  );
34765
34816
  if (extendedStatus) {
34766
- calls.push(...extendedCalls);
34817
+ transactionResults.push({
34818
+ status: extendedStatus,
34819
+ calls: extendedCalls,
34820
+ transactionMetadata: {
34821
+ ...extendedTransactionMetadata,
34822
+ transactionType: "DEPOSIT"
34823
+ }
34824
+ });
34767
34825
  } else {
34768
- return [];
34826
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmount.abs() }, "NONE")];
34769
34827
  }
34770
34828
  } catch (err) {
34771
34829
  logger.error(`Failed moving assets to vault: ${err}`);
34830
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmount.abs() }, "NONE")];
34772
34831
  }
34773
34832
  }
34774
34833
  if (vesuAmount.isNegative() && vesuAmount.abs().greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
34775
34834
  try {
34776
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34835
+ const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
34777
34836
  {
34778
34837
  to: Protocols.EXTENDED.name,
34779
34838
  from: Protocols.VESU.name,
@@ -34782,18 +34841,26 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34782
34841
  extendedAdapter,
34783
34842
  vesuAdapter
34784
34843
  );
34785
- calls.push(...vesuCalls);
34786
34844
  if (!vesuStatus) {
34787
- return [];
34788
- }
34845
+ return [this.createTransactionResult([], false, { from: Protocols.VESU.name, to: Protocols.EXTENDED.name, amount: vesuAmount.abs() }, "NONE")];
34846
+ }
34847
+ transactionResults.push({
34848
+ status: vesuStatus,
34849
+ calls: vesuCalls,
34850
+ transactionMetadata: {
34851
+ ...vesuTransactionMetadata,
34852
+ transactionType: "DEPOSIT"
34853
+ }
34854
+ });
34789
34855
  } catch (err) {
34790
- logger.error(`Failed moving assets to vault: ${err}`);
34856
+ logger.error(`Failed moving assets to extended via vault allocator: ${err}`);
34857
+ return [this.createTransactionResult([], false, { from: Protocols.VESU.name, to: Protocols.EXTENDED.name, amount: vesuAmount.abs() }, "NONE")];
34791
34858
  }
34792
34859
  }
34793
34860
  if (extendedAmountDifferenceAbs.greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34794
34861
  if (extendedAmountDifference.greaterThan(0)) {
34795
34862
  try {
34796
- const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
34863
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
34797
34864
  {
34798
34865
  to: Protocols.EXTENDED.name,
34799
34866
  from: Protocols.VAULT.name,
@@ -34803,18 +34870,22 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34803
34870
  vesuAdapter
34804
34871
  );
34805
34872
  if (extendedStatus) {
34806
- calls.push(...extendedCalls);
34873
+ transactionResults.push({
34874
+ status: extendedStatus,
34875
+ calls: extendedCalls,
34876
+ transactionMetadata: extendedTransactionMetadata
34877
+ });
34807
34878
  } else {
34808
34879
  logger.error(`Failed to move assets to extended - operation returned false status`);
34809
- return [];
34880
+ return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.EXTENDED.name, amount: extendedAmountDifference }, "NONE")];
34810
34881
  }
34811
34882
  } catch (err) {
34812
34883
  logger.error(`Failed moving assets to extended: ${err}`);
34813
- return [];
34884
+ return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.EXTENDED.name, amount: extendedAmountDifference }, "NONE")];
34814
34885
  }
34815
34886
  } else if (extendedAmountDifference.lessThan(0)) {
34816
34887
  try {
34817
- const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
34888
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
34818
34889
  {
34819
34890
  to: Protocols.VAULT.name,
34820
34891
  from: Protocols.EXTENDED.name,
@@ -34824,14 +34895,21 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34824
34895
  vesuAdapter
34825
34896
  );
34826
34897
  if (extendedStatus) {
34827
- calls.push(...extendedCalls);
34898
+ transactionResults.push({
34899
+ status: extendedStatus,
34900
+ calls: extendedCalls,
34901
+ transactionMetadata: {
34902
+ ...extendedTransactionMetadata,
34903
+ transactionType: "DEPOSIT"
34904
+ }
34905
+ });
34828
34906
  } else {
34829
34907
  logger.error(`Failed to withdraw from extended - operation returned false status`);
34830
- return [];
34908
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmountDifferenceAbs }, "NONE")];
34831
34909
  }
34832
34910
  } catch (err) {
34833
34911
  logger.error(`Failed moving assets from extended to vault: ${err}`);
34834
- return [];
34912
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmountDifferenceAbs }, "NONE")];
34835
34913
  }
34836
34914
  }
34837
34915
  }
@@ -34842,7 +34920,7 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34842
34920
  );
34843
34921
  } else {
34844
34922
  try {
34845
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34923
+ const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
34846
34924
  {
34847
34925
  to: Protocols.VAULT.name,
34848
34926
  from: Protocols.EXTENDED.name,
@@ -34853,31 +34931,54 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34853
34931
  );
34854
34932
  if (!vesuStatus) {
34855
34933
  logger.error(`Failed to move assets to vesu - operation returned false status`);
34856
- return [];
34934
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: vesuAmountDifference }, "NONE")];
34857
34935
  }
34858
- calls.push(...vesuCalls);
34936
+ transactionResults.push({
34937
+ status: vesuStatus,
34938
+ calls: vesuCalls,
34939
+ transactionMetadata: {
34940
+ ...vesuTransactionMetadata,
34941
+ transactionType: "DEPOSIT"
34942
+ }
34943
+ });
34859
34944
  } catch (err) {
34860
34945
  logger.error(`Failed moving assets to vault: ${err}`);
34861
- return [];
34946
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: vesuAmountDifference }, "NONE")];
34862
34947
  }
34863
34948
  }
34864
34949
  }
34865
- return calls;
34950
+ return transactionResults;
34866
34951
  } catch (err) {
34867
34952
  logger.error(`Failed moving assets to vesu: ${err}`);
34868
- return [];
34953
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: new Web3Number(0, USDC_TOKEN_DECIMALS) }, "NONE")];
34869
34954
  }
34870
34955
  }
34956
+ /**
34957
+ * Helper method to create transaction result with metadata
34958
+ */
34959
+ createTransactionResult(calls, status, params, transactionType) {
34960
+ if (status) {
34961
+ return {
34962
+ calls,
34963
+ status,
34964
+ transactionMetadata: {
34965
+ protocolFrom: params.from,
34966
+ protocolTo: params.to,
34967
+ transactionType,
34968
+ usdAmount: params.amount.abs().toFixed(),
34969
+ status: "PENDING"
34970
+ }
34971
+ };
34972
+ }
34973
+ return { calls: [], status: false, transactionMetadata: { protocolFrom: "", protocolTo: "", transactionType: "DEPOSIT", usdAmount: "0", status: "FAILED" } };
34974
+ }
34871
34975
  async moveAssets(params, extendedAdapter, vesuAdapter) {
34872
34976
  try {
34873
34977
  if (params.amount.lessThanOrEqualTo(0)) {
34874
34978
  logger.error(
34875
34979
  `Invalid amount for moveAssets: ${params.amount.toNumber()}. Amount must be positive.`
34876
34980
  );
34877
- return {
34878
- calls: [],
34879
- status: false
34880
- };
34981
+ return this.createTransactionResult([], false, params, "NONE");
34881
34982
  }
34882
34983
  const amountAbs = params.amount.abs();
34883
34984
  if (params.from === Protocols.EXTENDED.name || params.to === Protocols.EXTENDED.name) {
@@ -34885,10 +34986,7 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34885
34986
  logger.warn(
34886
34987
  `Amount ${amountAbs.toNumber()} is below minimum Extended movement amount ${extendedAdapter.minimumExtendedMovementAmount}. Skipping operation.`
34887
34988
  );
34888
- return {
34889
- calls: [],
34890
- status: false
34891
- };
34989
+ return this.createTransactionResult([], false, params, "NONE");
34892
34990
  }
34893
34991
  }
34894
34992
  if (params.from === Protocols.VESU.name || params.to === Protocols.VESU.name) {
@@ -34896,19 +34994,13 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34896
34994
  logger.warn(
34897
34995
  `Amount ${amountAbs.toNumber()} is below minimum Vesu movement amount ${vesuAdapter.minimumVesuMovementAmount}. Skipping operation.`
34898
34996
  );
34899
- return {
34900
- calls: [],
34901
- status: false
34902
- };
34997
+ return this.createTransactionResult([], false, params, "NONE");
34903
34998
  }
34904
34999
  }
34905
35000
  const avnuAdapter = await this.getAvnuAdapter();
34906
35001
  if (!avnuAdapter) {
34907
35002
  logger.error(`avnu adapter not found: ${avnuAdapter}`);
34908
- return {
34909
- calls: [],
34910
- status: false
34911
- };
35003
+ return this.createTransactionResult([], false, params, "NONE");
34912
35004
  }
34913
35005
  logger.info(`moveAssets params, ${JSON.stringify(params)}`);
34914
35006
  const collateralToken = vesuAdapter.config.supportedPositions[0].asset;
@@ -34927,19 +35019,13 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34927
35019
  await proofsInfo.callConstructor({ amount: params.amount })
34928
35020
  );
34929
35021
  calls.push(call);
34930
- return {
34931
- calls: [call],
34932
- status: true
34933
- };
35022
+ return this.createTransactionResult(calls, true, params, "DEPOSIT");
34934
35023
  } else if (params.to === Protocols.VAULT.name && params.from === Protocols.EXTENDED.name) {
34935
35024
  const extendedLeverage = calculateExtendedLevergae();
34936
35025
  const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34937
35026
  if (!extendedHoldings) {
34938
35027
  logger.error(`error getting extended holdings: ${extendedHoldings}`);
34939
- return {
34940
- calls: [],
34941
- status: false
34942
- };
35028
+ return this.createTransactionResult([], false, params, "NONE");
34943
35029
  }
34944
35030
  const extendedHoldingAmount = new Web3Number(
34945
35031
  extendedHoldings.availableForWithdrawal,
@@ -34966,36 +35052,36 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34966
35052
  const updatedHoldings = await extendedAdapter.getExtendedDepositAmount();
34967
35053
  if (!updatedHoldings || new Web3Number(updatedHoldings.availableForWithdrawal, USDC_TOKEN_DECIMALS).lessThan(params.amount.abs())) {
34968
35054
  logger.error(`Insufficient balance after opening position. Available: ${updatedHoldings?.availableForWithdrawal}, Needed: ${params.amount.abs()}`);
34969
- return { calls: [], status: false };
35055
+ return this.createTransactionResult([], false, params, "NONE");
34970
35056
  }
34971
35057
  }
34972
- const withdrawalFromExtended = await extendedAdapter.withdrawFromExtended(params.amount);
34973
- if (withdrawalFromExtended) {
35058
+ const {
35059
+ status: withdrawalFromExtendedStatus,
35060
+ receivedTxnHash: withdrawalFromExtendedTxnHash
35061
+ } = await extendedAdapter.withdrawFromExtended(params.amount);
35062
+ logger.info(`withdrawalFromExtendedStatus: ${withdrawalFromExtendedStatus}, withdrawalFromExtendedTxnHash: ${withdrawalFromExtendedTxnHash}`);
35063
+ if (withdrawalFromExtendedStatus && withdrawalFromExtendedTxnHash) {
34974
35064
  const extendedHoldings2 = await extendedAdapter.getExtendedDepositAmount();
34975
35065
  logger.info(`extendedHoldings after withdrawal ${extendedHoldings2?.availableForWithdrawal}`);
34976
35066
  await new Promise((resolve) => setTimeout(resolve, 5e3));
34977
- const calls = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
34978
- if (calls.length > 0) {
34979
- return {
34980
- calls,
34981
- status: true
34982
- };
35067
+ const { calls, status } = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
35068
+ if (calls.length > 0 && status) {
35069
+ return this.createTransactionResult(calls, true, params, "WITHDRAWAL");
35070
+ } else {
35071
+ return this.createTransactionResult([], true, params, "WITHDRAWAL");
34983
35072
  }
35073
+ } else if (withdrawalFromExtendedStatus && !withdrawalFromExtendedTxnHash) {
35074
+ logger.error("withdrawal from extended successful, but funds didn't get transferred to the wallet");
35075
+ return this.createTransactionResult([], true, params, "WITHDRAWAL");
34984
35076
  } else {
34985
35077
  logger.error("withdrawal from extended failed");
34986
- return {
34987
- calls: [],
34988
- status: false
34989
- };
35078
+ return this.createTransactionResult([], false, params, "NONE");
34990
35079
  }
34991
35080
  } else if (params.to === Protocols.VAULT.name && params.from === Protocols.VESU.name) {
34992
35081
  const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, "close" /* CLOSE */);
34993
35082
  if (!isPriceDifferenceBetweenAvnuAndExtended) {
34994
35083
  logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
34995
- return {
34996
- calls: [],
34997
- status: false
34998
- };
35084
+ return this.createTransactionResult([], false, params, "NONE");
34999
35085
  }
35000
35086
  const vesuAmountInBTC = new Web3Number(
35001
35087
  params.amount.dividedBy(collateralPrice.price).toFixed(WBTC_TOKEN_DECIMALS),
@@ -35016,18 +35102,12 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
35016
35102
  await swapProofsInfo.callConstructor({ amount: vesuAmountInBTC })
35017
35103
  );
35018
35104
  calls.push(swapCall);
35019
- return {
35020
- calls,
35021
- status: true
35022
- };
35105
+ return this.createTransactionResult(calls, true, params, "WITHDRAWAL");
35023
35106
  } else if (params.to === Protocols.EXTENDED.name && params.from === Protocols.VESU.name) {
35024
35107
  const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, "close" /* CLOSE */);
35025
35108
  if (!isPriceDifferenceBetweenAvnuAndExtended) {
35026
35109
  logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
35027
- return {
35028
- calls: [],
35029
- status: false
35030
- };
35110
+ return this.createTransactionResult([], false, params, "NONE");
35031
35111
  }
35032
35112
  const vesuAmountInBTC = new Web3Number(
35033
35113
  params.amount.dividedBy(collateralPrice.price).toNumber(),
@@ -35058,127 +35138,21 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
35058
35138
  await proofsInfoDeposit.callConstructor({ amount: params.amount })
35059
35139
  );
35060
35140
  calls.push(callDeposit);
35061
- return {
35062
- calls,
35063
- status: true
35064
- };
35141
+ return this.createTransactionResult(calls, true, params, "DEPOSIT");
35065
35142
  }
35066
- return {
35067
- calls: [],
35068
- status: false
35069
- };
35143
+ logger.error(`Unsupported assets movement: ${params.from} to ${params.to}`);
35144
+ return this.createTransactionResult([], false, params, "NONE");
35070
35145
  } catch (err) {
35071
35146
  logger.error(`error moving assets: ${err}`);
35072
- return {
35073
- calls: [],
35074
- status: false
35075
- };
35147
+ return this.createTransactionResult([], false, params, "NONE");
35076
35148
  }
35077
35149
  }
35078
35150
  async handleDeposit() {
35079
35151
  try {
35080
- const vesuAdapter = await this.getVesuAdapter();
35081
- const extendedAdapter = await this.getExtendedAdapter();
35082
- const avnuAdapter = await this.getAvnuAdapter();
35083
- if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client || !avnuAdapter) {
35084
- logger.error(
35085
- "vesu or extended adapter not found",
35086
- vesuAdapter,
35087
- extendedAdapter
35088
- );
35089
- return {
35090
- extendedAmountInBTC: new Web3Number(0, 0),
35091
- calls: []
35092
- };
35093
- }
35094
- const extendedLeverage = calculateExtendedLevergae();
35095
- const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, "open" /* OPEN */);
35096
- if (!isPriceDifferenceBetweenAvnuAndExtended) {
35097
- logger.error("price difference between avnu and extended doesn't fit the range");
35098
- return {
35099
- extendedAmountInBTC: new Web3Number(0, 0),
35100
- calls: []
35101
- };
35102
- }
35103
- const position = await extendedAdapter.getAllOpenPositions();
35104
- if (!position) {
35105
- logger.error("error getting extended position", position);
35106
- return {
35107
- extendedAmountInBTC: new Web3Number(0, 0),
35108
- calls: []
35109
- };
35110
- }
35111
- const extendedPositionValue = position.length > 0 ? parseFloat(position[0].value) : 0;
35112
- const BUFFER_AMOUNT_IN_AVAILABLE_FOR_TRADE = BUFFER_USDC_IN_WITHDRAWAL;
35113
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
35114
- if (!extendedHoldings) {
35115
- logger.error(`error getting extended holdings: ${extendedHoldings}`);
35116
- return {
35117
- extendedAmountInBTC: new Web3Number(0, 0),
35118
- calls: []
35119
- };
35120
- }
35121
- const extendedHoldingAmount = new Web3Number(
35122
- extendedHoldings.availableForWithdrawal,
35123
- USDC_TOKEN_DECIMALS
35124
- );
35125
- const {
35126
- collateralTokenAmount
35127
- } = await vesuAdapter.vesuAdapter.getAssetPrices();
35128
- const { collateralPrice } = await this.getAssetPrices();
35129
- const { vesuAmountInBTC, extendedAmountInBTC } = calculateVesUPositionSizeGivenExtended(
35130
- extendedPositionValue,
35131
- extendedHoldingAmount.minus(BUFFER_AMOUNT_IN_AVAILABLE_FOR_TRADE),
35132
- collateralTokenAmount,
35133
- collateralPrice.price
35134
- );
35135
- logger.info(`vesuAmountInBTC ${vesuAmountInBTC}, extendedAmountInBTC ${extendedAmountInBTC}`);
35136
- let calls = [];
35137
- if (vesuAmountInBTC.greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)) {
35138
- const proofsInfo = vesuAdapter.getProofs(true, this.getMerkleTree());
35139
- const proofGroups = proofsInfo.proofs;
35140
- const call = this.getManageCall(
35141
- proofGroups,
35142
- await proofsInfo.callConstructor({
35143
- amount: vesuAmountInBTC
35144
- })
35145
- );
35146
- const { amount: wbtcAmountInVaultAllocator } = await this.getUnusedBalanceWBTC();
35147
- if (wbtcAmountInVaultAllocator.lessThan(vesuAmountInBTC)) {
35148
- const swapProofsInfo = avnuAdapter.getProofs(true, this.getMerkleTree());
35149
- const swapProofGroups = swapProofsInfo.proofs;
35150
- const swapCall = this.getManageCall(
35151
- swapProofGroups,
35152
- await swapProofsInfo.callConstructor({
35153
- amount: vesuAmountInBTC
35154
- })
35155
- );
35156
- calls.push(swapCall);
35157
- }
35158
- calls.push(call);
35159
- }
35160
- const shortPosition = extendedAmountInBTC.multipliedBy(3).abs().greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
35161
- extendedLeverage.toString(),
35162
- extendedAmountInBTC.toNumber(),
35163
- "SELL" /* SELL */
35164
- ) : null;
35165
- if (!shortPosition && extendedAmountInBTC.multipliedBy(3).abs().greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)) {
35166
- logger.error(`error creating short position thus no position to be opened on vesu: ${shortPosition}`);
35167
- return {
35168
- extendedAmountInBTC: new Web3Number(0, 0),
35169
- calls: []
35170
- };
35171
- }
35172
- return {
35173
- extendedAmountInBTC,
35174
- calls
35175
- };
35152
+ return this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.VAULT.name, amount: new Web3Number(0, 0) }, "NONE");
35176
35153
  } catch (err) {
35177
35154
  logger.error(`error handling deposit: ${err}`);
35178
- return {
35179
- extendedAmountInBTC: new Web3Number(0, 0),
35180
- calls: []
35181
- };
35155
+ return this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.VAULT.name, amount: new Web3Number(0, 0) }, "NONE");
35182
35156
  }
35183
35157
  }
35184
35158
  async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, positionType) {
@@ -35223,12 +35197,8 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
35223
35197
  const withdrawCall2 = await this.getBringLiquidityCall({
35224
35198
  amount: usdcBalanceVaultAllocator.amount
35225
35199
  });
35226
- logger.info("withdraw call", withdrawCall2);
35227
35200
  calls.push(withdrawCall2);
35228
- return {
35229
- calls,
35230
- status: true
35231
- };
35201
+ return [this.createTransactionResult(calls, true, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "WITHDRAWAL")];
35232
35202
  }
35233
35203
  const vesuAdapter = await this.getVesuAdapter();
35234
35204
  const extendedAdapter = await this.getExtendedAdapter();
@@ -35237,11 +35207,9 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
35237
35207
  logger.error(
35238
35208
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
35239
35209
  );
35240
- return {
35241
- calls,
35242
- status
35243
- };
35210
+ return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE")];
35244
35211
  }
35212
+ let transactionResults = [];
35245
35213
  const { collateralTokenAmount } = await vesuAdapter.vesuAdapter.getAssetPrices();
35246
35214
  const {
35247
35215
  collateralPrice
@@ -35250,10 +35218,7 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
35250
35218
  if (!extendedPositon) {
35251
35219
  status = false;
35252
35220
  logger.error("error getting extended position", extendedPositon);
35253
- return {
35254
- calls,
35255
- status
35256
- };
35221
+ return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE")];
35257
35222
  }
35258
35223
  const amountDistributionForWithdrawal = await calculateAmountDistributionForWithdrawal(
35259
35224
  usdcBalanceDifference,
@@ -35266,14 +35231,11 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
35266
35231
  logger.error(
35267
35232
  `error calculating amount distribution for withdrawal: ${amountDistributionForWithdrawal}`
35268
35233
  );
35269
- return {
35270
- calls,
35271
- status
35272
- };
35234
+ return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE")];
35273
35235
  }
35274
35236
  const { vesu_amount, extended_amount } = amountDistributionForWithdrawal;
35275
35237
  if (status && vesu_amount.greaterThan(0)) {
35276
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
35238
+ const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
35277
35239
  {
35278
35240
  amount: vesu_amount,
35279
35241
  from: Protocols.VESU.name,
@@ -35283,10 +35245,14 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
35283
35245
  vesuAdapter
35284
35246
  );
35285
35247
  status = vesuStatus;
35286
- calls.push(...vesuCalls);
35248
+ transactionResults.push({
35249
+ status: vesuStatus,
35250
+ calls: vesuCalls,
35251
+ transactionMetadata: vesuTransactionMetadata
35252
+ });
35287
35253
  }
35288
35254
  if (status && extended_amount.greaterThan(0)) {
35289
- const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
35255
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
35290
35256
  {
35291
35257
  amount: extended_amount,
35292
35258
  from: Protocols.EXTENDED.name,
@@ -35297,30 +35263,35 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
35297
35263
  );
35298
35264
  status = extendedStatus;
35299
35265
  if (status) {
35300
- calls.push(...extendedCalls);
35266
+ transactionResults.push({
35267
+ status: extendedStatus,
35268
+ calls: extendedCalls,
35269
+ transactionMetadata: extendedTransactionMetadata
35270
+ });
35301
35271
  } else {
35302
35272
  logger.error("error moving assets to vault: extendedStatus: ${extendedStatus}");
35303
- return {
35304
- calls: [],
35305
- status
35306
- };
35273
+ return [this.createTransactionResult([], status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE")];
35307
35274
  }
35308
35275
  }
35309
35276
  const withdrawCall = await this.getBringLiquidityCall({
35310
35277
  amount
35311
35278
  });
35312
35279
  logger.info("withdraw call", withdrawCall);
35313
- calls.push(withdrawCall);
35314
- return {
35315
- calls,
35316
- status
35317
- };
35280
+ transactionResults.push({
35281
+ status,
35282
+ calls: [withdrawCall],
35283
+ transactionMetadata: {
35284
+ protocolFrom: Protocols.VAULT.name,
35285
+ protocolTo: Protocols.NONE.name,
35286
+ transactionType: "WITHDRAWAL",
35287
+ usdAmount: amount.toFixed(),
35288
+ status: "PENDING"
35289
+ }
35290
+ });
35291
+ return transactionResults;
35318
35292
  } catch (err) {
35319
35293
  logger.error(`error handling withdrawal: ${err}`);
35320
- return {
35321
- calls: [],
35322
- status: false
35323
- };
35294
+ return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE")];
35324
35295
  }
35325
35296
  }
35326
35297
  async getAUM() {
@@ -35367,6 +35338,36 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
35367
35338
  splits: [realAUM, estimatedAUMDelta]
35368
35339
  };
35369
35340
  }
35341
+ async processTransactionDataFromSDK(txnData) {
35342
+ try {
35343
+ const txnsToBeExecuted = txnData.filter((txn) => {
35344
+ return txn.transactionMetadata.transactionType !== "NONE" && txn.transactionMetadata.protocolFrom !== "" && txn.transactionMetadata.protocolTo !== "";
35345
+ });
35346
+ const callsToBeExecutedFinal = txnsToBeExecuted.flatMap((txn) => txn.calls);
35347
+ const txnMetadata = txnsToBeExecuted.map((txn) => txn.transactionMetadata);
35348
+ return { callsToBeExecutedFinal, txnMetadata };
35349
+ } catch (err) {
35350
+ logger.error(`error processing transaction data from SDK: ${err}`);
35351
+ return null;
35352
+ }
35353
+ }
35354
+ async processTransactionMetadata(txnMetadata, extendedIntentFulfilled) {
35355
+ try {
35356
+ const txnMetadataNew = txnMetadata.map((txn) => {
35357
+ const isExtendedProtocol = txn.protocolFrom === Protocols.EXTENDED.name || txn.protocolTo === Protocols.EXTENDED.name;
35358
+ if (isExtendedProtocol) {
35359
+ txn.status = extendedIntentFulfilled ? "COMPLETED" : "PENDING";
35360
+ } else {
35361
+ txn.status = "COMPLETED";
35362
+ }
35363
+ return txn;
35364
+ });
35365
+ return txnMetadataNew;
35366
+ } catch (err) {
35367
+ logger.error(`error processing transaction data from SDK: ${err}`);
35368
+ return null;
35369
+ }
35370
+ }
35370
35371
  };
35371
35372
  function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, extendedBackendUrl, extendedApiKey, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing) {
35372
35373
  vaultSettings.leafAdapters = [];
@@ -39800,6 +39801,7 @@ var deployer_default = Deployer;
39800
39801
  AssetOperationStatus,
39801
39802
  AssetOperationType,
39802
39803
  AutoCompounderSTRK,
39804
+ AvnuAdapter,
39803
39805
  AvnuWrapper,
39804
39806
  BaseAdapter,
39805
39807
  BaseStrategy,
@@ -39883,6 +39885,7 @@ var deployer_default = Deployer;
39883
39885
  calculateExtendedLevergae,
39884
39886
  calculateVesUPositionSizeGivenExtended,
39885
39887
  calculateVesuLeverage,
39888
+ calculateWBTCAmountToMaintainLTV,
39886
39889
  extensionMap,
39887
39890
  getAPIUsingHeadlessBrowser,
39888
39891
  getContractDetails,