@strkfarm/sdk 2.0.0-dev.33 → 2.0.0-dev.35

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
@@ -106,6 +106,7 @@ __export(index_exports, {
106
106
  SIMPLE_SANITIZER: () => SIMPLE_SANITIZER,
107
107
  SIMPLE_SANITIZER_V2: () => SIMPLE_SANITIZER_V2,
108
108
  SIMPLE_SANITIZER_VESU_V1_DELEGATIONS: () => SIMPLE_SANITIZER_VESU_V1_DELEGATIONS,
109
+ SVK_SIMPLE_SANITIZER: () => SVK_SIMPLE_SANITIZER,
109
110
  SenseiStrategies: () => SenseiStrategies,
110
111
  SenseiVault: () => SenseiVault,
111
112
  SolveBudget: () => SolveBudget,
@@ -125,6 +126,8 @@ __export(index_exports, {
125
126
  TokenTransferAdapter: () => TokenTransferAdapter,
126
127
  UNIVERSAL_ADAPTERS: () => UNIVERSAL_ADAPTERS,
127
128
  UNIVERSAL_MANAGE_IDS: () => UNIVERSAL_MANAGE_IDS,
129
+ USDCBoostedStrategies: () => USDCBoostedStrategies,
130
+ USDCBoostedStrategy: () => USDCBoostedStrategy,
128
131
  UniversalLstMultiplierStrategy: () => UniversalLstMultiplierStrategy,
129
132
  UniversalStrategies: () => UniversalStrategies,
130
133
  UniversalStrategy: () => UniversalStrategy,
@@ -21932,6 +21935,7 @@ var import_starknet19 = require("starknet");
21932
21935
 
21933
21936
  // src/strategies/universal-adapters/adapter-utils.ts
21934
21937
  var SIMPLE_SANITIZER = ContractAddr.from("0x5a2e3ceb3da368b983a8717898427ab7b6daf04014b70f321e777f9aad940b4");
21938
+ var SVK_SIMPLE_SANITIZER = ContractAddr.from("0x03dcde04343257c3ce14574676cb9c5b2eda16e332c1b8caf5dc4c95ac568d2f");
21935
21939
  var EXTENDED_SANITIZER = ContractAddr.from("0x65891708362b24dcf4c40c8e218cce6e82d1d6b3a3404c9ab00a48f08e2c110");
21936
21940
  var AVNU_LEGACY_SANITIZER = ContractAddr.from("0x0656fBE853f116DD53956176a553eDe8fE65632252f8aceB50C1B9B6c8237309");
21937
21941
  var SIMPLE_SANITIZER_V2 = ContractAddr.from("0x7b6f98311af8aa425278570e62abf523e6462eaa01a38c1feab9b2f416492e2");
@@ -35795,7 +35799,14 @@ var VesuModifyPositionAdapter = class _VesuModifyPositionAdapter extends BaseAda
35795
35799
  }
35796
35800
  const normalizedDebtAmount = this._normalizeDebtAmountFromHelper(
35797
35801
  helperOutput
35798
- );
35802
+ ).minus(state.currentDebt);
35803
+ if (normalizedDebtAmount.lessThan(0)) {
35804
+ logger.warn(`VesuModifyPositionAdapter: deposit debt delta is negative (${normalizedDebtAmount.toNumber()}), clamping to zero`);
35805
+ return {
35806
+ collateral: this._toSigned(collateralToAdd, false),
35807
+ debt: this._toSigned(Web3Number.fromWei(0, this.config.debt.decimals), false)
35808
+ };
35809
+ }
35799
35810
  return {
35800
35811
  collateral: this._toSigned(collateralToAdd, false),
35801
35812
  debt: this._toSigned(normalizedDebtAmount, false)
@@ -35813,8 +35824,8 @@ var VesuModifyPositionAdapter = class _VesuModifyPositionAdapter extends BaseAda
35813
35824
  state.debtPrice,
35814
35825
  this.config.debt
35815
35826
  );
35816
- if (!helperOutput || helperOutput.greaterThan(0)) {
35817
- throw new Error(`Failed to calculate default withdraw debt delta: ${helperOutput?.toNumber()}`);
35827
+ if (!helperOutput || helperOutput.lessThan(0)) {
35828
+ throw new Error(`Failed to calculate max debt amount for withdraw: ${helperOutput?.toNumber()}`);
35818
35829
  }
35819
35830
  const normalizedDebtAmount = this._normalizeDebtAmountFromHelper(
35820
35831
  helperOutput
@@ -36011,6 +36022,24 @@ var VesuModifyPositionAdapter = class _VesuModifyPositionAdapter extends BaseAda
36011
36022
  this._prepareVesuAdapter();
36012
36023
  return this._vesuAdapter.getHealthFactor();
36013
36024
  }
36025
+ /**
36026
+ * Simulates a deposit of `depositAmount` collateral and returns how much
36027
+ * debt (STRK) would be incrementally borrowed to reach the target LTV.
36028
+ * Used upstream to size the AVNU swap call in the same transaction batch.
36029
+ */
36030
+ async getExpectedDepositDebtDelta(depositAmount) {
36031
+ const defaults = await this._buildDefaultDepositDeltas({ amount: depositAmount });
36032
+ return defaults.debt.amount;
36033
+ }
36034
+ /**
36035
+ * Simulates a withdrawal of `withdrawAmount` collateral and returns the
36036
+ * incremental debt delta needed to keep the target health factor.
36037
+ * Positive means borrow, negative means repay.
36038
+ */
36039
+ async getExpectedWithdrawDebtDelta(withdrawAmount) {
36040
+ const defaults = await this._buildDefaultWithdrawDeltas({ amount: withdrawAmount });
36041
+ return defaults.debt.amount;
36042
+ }
36014
36043
  };
36015
36044
 
36016
36045
  // src/strategies/universal-adapters/extended-adapter.ts
@@ -36568,6 +36597,25 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
36568
36597
  return { success: false, data: [] };
36569
36598
  }
36570
36599
  }
36600
+ /** Account funding payment history via `GET /api/v1/account/funding-payments` (USDC amounts). */
36601
+ async getFundingPayments(side, startTime, limit) {
36602
+ try {
36603
+ const response = await this.client.getUserFundingPayments(
36604
+ this.config.extendedMarketName,
36605
+ side,
36606
+ startTime ?? Date.now() - 30 * 24 * 60 * 60 * 1e3,
36607
+ limit ?? 200
36608
+ );
36609
+ if (response.status !== "OK") {
36610
+ logger.error("error getting funding payments", response.data);
36611
+ return { success: false, data: [] };
36612
+ }
36613
+ return { success: true, data: response.data ?? [] };
36614
+ } catch (err) {
36615
+ logger.error("error getting funding payments", err);
36616
+ return { success: false, data: [] };
36617
+ }
36618
+ }
36571
36619
  async getPosition(supportedPosition) {
36572
36620
  const holdings = await this.getExtendedDepositAmount();
36573
36621
  if (!holdings) {
@@ -39207,6 +39255,760 @@ var universal_vault_abi_default = [
39207
39255
  }
39208
39256
  ];
39209
39257
 
39258
+ // src/data/redeem-request-nft.abi.json
39259
+ var redeem_request_nft_abi_default = [
39260
+ {
39261
+ type: "impl",
39262
+ name: "RedeemRequestImpl",
39263
+ interface_name: "vault::redeem_request::interface::IRedeemRequest"
39264
+ },
39265
+ {
39266
+ type: "struct",
39267
+ name: "core::integer::u256",
39268
+ members: [
39269
+ {
39270
+ name: "low",
39271
+ type: "core::integer::u128"
39272
+ },
39273
+ {
39274
+ name: "high",
39275
+ type: "core::integer::u128"
39276
+ }
39277
+ ]
39278
+ },
39279
+ {
39280
+ type: "struct",
39281
+ name: "vault::redeem_request::interface::RedeemRequestInfo",
39282
+ members: [
39283
+ {
39284
+ name: "epoch",
39285
+ type: "core::integer::u256"
39286
+ },
39287
+ {
39288
+ name: "nominal",
39289
+ type: "core::integer::u256"
39290
+ }
39291
+ ]
39292
+ },
39293
+ {
39294
+ type: "interface",
39295
+ name: "vault::redeem_request::interface::IRedeemRequest",
39296
+ items: [
39297
+ {
39298
+ type: "function",
39299
+ name: "vault",
39300
+ inputs: [],
39301
+ outputs: [
39302
+ {
39303
+ type: "core::starknet::contract_address::ContractAddress"
39304
+ }
39305
+ ],
39306
+ state_mutability: "view"
39307
+ },
39308
+ {
39309
+ type: "function",
39310
+ name: "id_to_info",
39311
+ inputs: [
39312
+ {
39313
+ name: "id",
39314
+ type: "core::integer::u256"
39315
+ }
39316
+ ],
39317
+ outputs: [
39318
+ {
39319
+ type: "vault::redeem_request::interface::RedeemRequestInfo"
39320
+ }
39321
+ ],
39322
+ state_mutability: "view"
39323
+ },
39324
+ {
39325
+ type: "function",
39326
+ name: "id_len",
39327
+ inputs: [],
39328
+ outputs: [
39329
+ {
39330
+ type: "core::integer::u256"
39331
+ }
39332
+ ],
39333
+ state_mutability: "view"
39334
+ },
39335
+ {
39336
+ type: "function",
39337
+ name: "mint",
39338
+ inputs: [
39339
+ {
39340
+ name: "to",
39341
+ type: "core::starknet::contract_address::ContractAddress"
39342
+ },
39343
+ {
39344
+ name: "redeem_request_info",
39345
+ type: "vault::redeem_request::interface::RedeemRequestInfo"
39346
+ }
39347
+ ],
39348
+ outputs: [
39349
+ {
39350
+ type: "core::integer::u256"
39351
+ }
39352
+ ],
39353
+ state_mutability: "external"
39354
+ },
39355
+ {
39356
+ type: "function",
39357
+ name: "burn",
39358
+ inputs: [
39359
+ {
39360
+ name: "id",
39361
+ type: "core::integer::u256"
39362
+ }
39363
+ ],
39364
+ outputs: [],
39365
+ state_mutability: "external"
39366
+ }
39367
+ ]
39368
+ },
39369
+ {
39370
+ type: "impl",
39371
+ name: "UpgradeableImpl",
39372
+ interface_name: "openzeppelin_interfaces::upgrades::IUpgradeable"
39373
+ },
39374
+ {
39375
+ type: "interface",
39376
+ name: "openzeppelin_interfaces::upgrades::IUpgradeable",
39377
+ items: [
39378
+ {
39379
+ type: "function",
39380
+ name: "upgrade",
39381
+ inputs: [
39382
+ {
39383
+ name: "new_class_hash",
39384
+ type: "core::starknet::class_hash::ClassHash"
39385
+ }
39386
+ ],
39387
+ outputs: [],
39388
+ state_mutability: "external"
39389
+ }
39390
+ ]
39391
+ },
39392
+ {
39393
+ type: "impl",
39394
+ name: "ERC721MixinImpl",
39395
+ interface_name: "openzeppelin_interfaces::token::erc721::ERC721ABI"
39396
+ },
39397
+ {
39398
+ type: "struct",
39399
+ name: "core::array::Span::<core::felt252>",
39400
+ members: [
39401
+ {
39402
+ name: "snapshot",
39403
+ type: "@core::array::Array::<core::felt252>"
39404
+ }
39405
+ ]
39406
+ },
39407
+ {
39408
+ type: "enum",
39409
+ name: "core::bool",
39410
+ variants: [
39411
+ {
39412
+ name: "False",
39413
+ type: "()"
39414
+ },
39415
+ {
39416
+ name: "True",
39417
+ type: "()"
39418
+ }
39419
+ ]
39420
+ },
39421
+ {
39422
+ type: "struct",
39423
+ name: "core::byte_array::ByteArray",
39424
+ members: [
39425
+ {
39426
+ name: "data",
39427
+ type: "core::array::Array::<core::bytes_31::bytes31>"
39428
+ },
39429
+ {
39430
+ name: "pending_word",
39431
+ type: "core::felt252"
39432
+ },
39433
+ {
39434
+ name: "pending_word_len",
39435
+ type: "core::integer::u32"
39436
+ }
39437
+ ]
39438
+ },
39439
+ {
39440
+ type: "interface",
39441
+ name: "openzeppelin_interfaces::token::erc721::ERC721ABI",
39442
+ items: [
39443
+ {
39444
+ type: "function",
39445
+ name: "balance_of",
39446
+ inputs: [
39447
+ {
39448
+ name: "account",
39449
+ type: "core::starknet::contract_address::ContractAddress"
39450
+ }
39451
+ ],
39452
+ outputs: [
39453
+ {
39454
+ type: "core::integer::u256"
39455
+ }
39456
+ ],
39457
+ state_mutability: "view"
39458
+ },
39459
+ {
39460
+ type: "function",
39461
+ name: "owner_of",
39462
+ inputs: [
39463
+ {
39464
+ name: "token_id",
39465
+ type: "core::integer::u256"
39466
+ }
39467
+ ],
39468
+ outputs: [
39469
+ {
39470
+ type: "core::starknet::contract_address::ContractAddress"
39471
+ }
39472
+ ],
39473
+ state_mutability: "view"
39474
+ },
39475
+ {
39476
+ type: "function",
39477
+ name: "safe_transfer_from",
39478
+ inputs: [
39479
+ {
39480
+ name: "from",
39481
+ type: "core::starknet::contract_address::ContractAddress"
39482
+ },
39483
+ {
39484
+ name: "to",
39485
+ type: "core::starknet::contract_address::ContractAddress"
39486
+ },
39487
+ {
39488
+ name: "token_id",
39489
+ type: "core::integer::u256"
39490
+ },
39491
+ {
39492
+ name: "data",
39493
+ type: "core::array::Span::<core::felt252>"
39494
+ }
39495
+ ],
39496
+ outputs: [],
39497
+ state_mutability: "external"
39498
+ },
39499
+ {
39500
+ type: "function",
39501
+ name: "transfer_from",
39502
+ inputs: [
39503
+ {
39504
+ name: "from",
39505
+ type: "core::starknet::contract_address::ContractAddress"
39506
+ },
39507
+ {
39508
+ name: "to",
39509
+ type: "core::starknet::contract_address::ContractAddress"
39510
+ },
39511
+ {
39512
+ name: "token_id",
39513
+ type: "core::integer::u256"
39514
+ }
39515
+ ],
39516
+ outputs: [],
39517
+ state_mutability: "external"
39518
+ },
39519
+ {
39520
+ type: "function",
39521
+ name: "approve",
39522
+ inputs: [
39523
+ {
39524
+ name: "to",
39525
+ type: "core::starknet::contract_address::ContractAddress"
39526
+ },
39527
+ {
39528
+ name: "token_id",
39529
+ type: "core::integer::u256"
39530
+ }
39531
+ ],
39532
+ outputs: [],
39533
+ state_mutability: "external"
39534
+ },
39535
+ {
39536
+ type: "function",
39537
+ name: "set_approval_for_all",
39538
+ inputs: [
39539
+ {
39540
+ name: "operator",
39541
+ type: "core::starknet::contract_address::ContractAddress"
39542
+ },
39543
+ {
39544
+ name: "approved",
39545
+ type: "core::bool"
39546
+ }
39547
+ ],
39548
+ outputs: [],
39549
+ state_mutability: "external"
39550
+ },
39551
+ {
39552
+ type: "function",
39553
+ name: "get_approved",
39554
+ inputs: [
39555
+ {
39556
+ name: "token_id",
39557
+ type: "core::integer::u256"
39558
+ }
39559
+ ],
39560
+ outputs: [
39561
+ {
39562
+ type: "core::starknet::contract_address::ContractAddress"
39563
+ }
39564
+ ],
39565
+ state_mutability: "view"
39566
+ },
39567
+ {
39568
+ type: "function",
39569
+ name: "is_approved_for_all",
39570
+ inputs: [
39571
+ {
39572
+ name: "owner",
39573
+ type: "core::starknet::contract_address::ContractAddress"
39574
+ },
39575
+ {
39576
+ name: "operator",
39577
+ type: "core::starknet::contract_address::ContractAddress"
39578
+ }
39579
+ ],
39580
+ outputs: [
39581
+ {
39582
+ type: "core::bool"
39583
+ }
39584
+ ],
39585
+ state_mutability: "view"
39586
+ },
39587
+ {
39588
+ type: "function",
39589
+ name: "supports_interface",
39590
+ inputs: [
39591
+ {
39592
+ name: "interface_id",
39593
+ type: "core::felt252"
39594
+ }
39595
+ ],
39596
+ outputs: [
39597
+ {
39598
+ type: "core::bool"
39599
+ }
39600
+ ],
39601
+ state_mutability: "view"
39602
+ },
39603
+ {
39604
+ type: "function",
39605
+ name: "name",
39606
+ inputs: [],
39607
+ outputs: [
39608
+ {
39609
+ type: "core::byte_array::ByteArray"
39610
+ }
39611
+ ],
39612
+ state_mutability: "view"
39613
+ },
39614
+ {
39615
+ type: "function",
39616
+ name: "symbol",
39617
+ inputs: [],
39618
+ outputs: [
39619
+ {
39620
+ type: "core::byte_array::ByteArray"
39621
+ }
39622
+ ],
39623
+ state_mutability: "view"
39624
+ },
39625
+ {
39626
+ type: "function",
39627
+ name: "token_uri",
39628
+ inputs: [
39629
+ {
39630
+ name: "token_id",
39631
+ type: "core::integer::u256"
39632
+ }
39633
+ ],
39634
+ outputs: [
39635
+ {
39636
+ type: "core::byte_array::ByteArray"
39637
+ }
39638
+ ],
39639
+ state_mutability: "view"
39640
+ },
39641
+ {
39642
+ type: "function",
39643
+ name: "balanceOf",
39644
+ inputs: [
39645
+ {
39646
+ name: "account",
39647
+ type: "core::starknet::contract_address::ContractAddress"
39648
+ }
39649
+ ],
39650
+ outputs: [
39651
+ {
39652
+ type: "core::integer::u256"
39653
+ }
39654
+ ],
39655
+ state_mutability: "view"
39656
+ },
39657
+ {
39658
+ type: "function",
39659
+ name: "ownerOf",
39660
+ inputs: [
39661
+ {
39662
+ name: "tokenId",
39663
+ type: "core::integer::u256"
39664
+ }
39665
+ ],
39666
+ outputs: [
39667
+ {
39668
+ type: "core::starknet::contract_address::ContractAddress"
39669
+ }
39670
+ ],
39671
+ state_mutability: "view"
39672
+ },
39673
+ {
39674
+ type: "function",
39675
+ name: "safeTransferFrom",
39676
+ inputs: [
39677
+ {
39678
+ name: "from",
39679
+ type: "core::starknet::contract_address::ContractAddress"
39680
+ },
39681
+ {
39682
+ name: "to",
39683
+ type: "core::starknet::contract_address::ContractAddress"
39684
+ },
39685
+ {
39686
+ name: "tokenId",
39687
+ type: "core::integer::u256"
39688
+ },
39689
+ {
39690
+ name: "data",
39691
+ type: "core::array::Span::<core::felt252>"
39692
+ }
39693
+ ],
39694
+ outputs: [],
39695
+ state_mutability: "external"
39696
+ },
39697
+ {
39698
+ type: "function",
39699
+ name: "transferFrom",
39700
+ inputs: [
39701
+ {
39702
+ name: "from",
39703
+ type: "core::starknet::contract_address::ContractAddress"
39704
+ },
39705
+ {
39706
+ name: "to",
39707
+ type: "core::starknet::contract_address::ContractAddress"
39708
+ },
39709
+ {
39710
+ name: "tokenId",
39711
+ type: "core::integer::u256"
39712
+ }
39713
+ ],
39714
+ outputs: [],
39715
+ state_mutability: "external"
39716
+ },
39717
+ {
39718
+ type: "function",
39719
+ name: "setApprovalForAll",
39720
+ inputs: [
39721
+ {
39722
+ name: "operator",
39723
+ type: "core::starknet::contract_address::ContractAddress"
39724
+ },
39725
+ {
39726
+ name: "approved",
39727
+ type: "core::bool"
39728
+ }
39729
+ ],
39730
+ outputs: [],
39731
+ state_mutability: "external"
39732
+ },
39733
+ {
39734
+ type: "function",
39735
+ name: "getApproved",
39736
+ inputs: [
39737
+ {
39738
+ name: "tokenId",
39739
+ type: "core::integer::u256"
39740
+ }
39741
+ ],
39742
+ outputs: [
39743
+ {
39744
+ type: "core::starknet::contract_address::ContractAddress"
39745
+ }
39746
+ ],
39747
+ state_mutability: "view"
39748
+ },
39749
+ {
39750
+ type: "function",
39751
+ name: "isApprovedForAll",
39752
+ inputs: [
39753
+ {
39754
+ name: "owner",
39755
+ type: "core::starknet::contract_address::ContractAddress"
39756
+ },
39757
+ {
39758
+ name: "operator",
39759
+ type: "core::starknet::contract_address::ContractAddress"
39760
+ }
39761
+ ],
39762
+ outputs: [
39763
+ {
39764
+ type: "core::bool"
39765
+ }
39766
+ ],
39767
+ state_mutability: "view"
39768
+ },
39769
+ {
39770
+ type: "function",
39771
+ name: "tokenURI",
39772
+ inputs: [
39773
+ {
39774
+ name: "tokenId",
39775
+ type: "core::integer::u256"
39776
+ }
39777
+ ],
39778
+ outputs: [
39779
+ {
39780
+ type: "core::byte_array::ByteArray"
39781
+ }
39782
+ ],
39783
+ state_mutability: "view"
39784
+ }
39785
+ ]
39786
+ },
39787
+ {
39788
+ type: "impl",
39789
+ name: "ERC721EnumerableImpl",
39790
+ interface_name: "openzeppelin_interfaces::token::erc721::IERC721Enumerable"
39791
+ },
39792
+ {
39793
+ type: "interface",
39794
+ name: "openzeppelin_interfaces::token::erc721::IERC721Enumerable",
39795
+ items: [
39796
+ {
39797
+ type: "function",
39798
+ name: "total_supply",
39799
+ inputs: [],
39800
+ outputs: [
39801
+ {
39802
+ type: "core::integer::u256"
39803
+ }
39804
+ ],
39805
+ state_mutability: "view"
39806
+ },
39807
+ {
39808
+ type: "function",
39809
+ name: "token_by_index",
39810
+ inputs: [
39811
+ {
39812
+ name: "index",
39813
+ type: "core::integer::u256"
39814
+ }
39815
+ ],
39816
+ outputs: [
39817
+ {
39818
+ type: "core::integer::u256"
39819
+ }
39820
+ ],
39821
+ state_mutability: "view"
39822
+ },
39823
+ {
39824
+ type: "function",
39825
+ name: "token_of_owner_by_index",
39826
+ inputs: [
39827
+ {
39828
+ name: "owner",
39829
+ type: "core::starknet::contract_address::ContractAddress"
39830
+ },
39831
+ {
39832
+ name: "index",
39833
+ type: "core::integer::u256"
39834
+ }
39835
+ ],
39836
+ outputs: [
39837
+ {
39838
+ type: "core::integer::u256"
39839
+ }
39840
+ ],
39841
+ state_mutability: "view"
39842
+ }
39843
+ ]
39844
+ },
39845
+ {
39846
+ type: "constructor",
39847
+ name: "constructor",
39848
+ inputs: [
39849
+ {
39850
+ name: "owner",
39851
+ type: "core::starknet::contract_address::ContractAddress"
39852
+ },
39853
+ {
39854
+ name: "vault",
39855
+ type: "core::starknet::contract_address::ContractAddress"
39856
+ }
39857
+ ]
39858
+ },
39859
+ {
39860
+ type: "event",
39861
+ name: "openzeppelin_token::erc721::erc721::ERC721Component::Transfer",
39862
+ kind: "struct",
39863
+ members: [
39864
+ {
39865
+ name: "from",
39866
+ type: "core::starknet::contract_address::ContractAddress",
39867
+ kind: "key"
39868
+ },
39869
+ {
39870
+ name: "to",
39871
+ type: "core::starknet::contract_address::ContractAddress",
39872
+ kind: "key"
39873
+ },
39874
+ {
39875
+ name: "token_id",
39876
+ type: "core::integer::u256",
39877
+ kind: "key"
39878
+ }
39879
+ ]
39880
+ },
39881
+ {
39882
+ type: "event",
39883
+ name: "openzeppelin_token::erc721::erc721::ERC721Component::Approval",
39884
+ kind: "struct",
39885
+ members: [
39886
+ {
39887
+ name: "owner",
39888
+ type: "core::starknet::contract_address::ContractAddress",
39889
+ kind: "key"
39890
+ },
39891
+ {
39892
+ name: "approved",
39893
+ type: "core::starknet::contract_address::ContractAddress",
39894
+ kind: "key"
39895
+ },
39896
+ {
39897
+ name: "token_id",
39898
+ type: "core::integer::u256",
39899
+ kind: "key"
39900
+ }
39901
+ ]
39902
+ },
39903
+ {
39904
+ type: "event",
39905
+ name: "openzeppelin_token::erc721::erc721::ERC721Component::ApprovalForAll",
39906
+ kind: "struct",
39907
+ members: [
39908
+ {
39909
+ name: "owner",
39910
+ type: "core::starknet::contract_address::ContractAddress",
39911
+ kind: "key"
39912
+ },
39913
+ {
39914
+ name: "operator",
39915
+ type: "core::starknet::contract_address::ContractAddress",
39916
+ kind: "key"
39917
+ },
39918
+ {
39919
+ name: "approved",
39920
+ type: "core::bool",
39921
+ kind: "data"
39922
+ }
39923
+ ]
39924
+ },
39925
+ {
39926
+ type: "event",
39927
+ name: "openzeppelin_token::erc721::erc721::ERC721Component::Event",
39928
+ kind: "enum",
39929
+ variants: [
39930
+ {
39931
+ name: "Transfer",
39932
+ type: "openzeppelin_token::erc721::erc721::ERC721Component::Transfer",
39933
+ kind: "nested"
39934
+ },
39935
+ {
39936
+ name: "Approval",
39937
+ type: "openzeppelin_token::erc721::erc721::ERC721Component::Approval",
39938
+ kind: "nested"
39939
+ },
39940
+ {
39941
+ name: "ApprovalForAll",
39942
+ type: "openzeppelin_token::erc721::erc721::ERC721Component::ApprovalForAll",
39943
+ kind: "nested"
39944
+ }
39945
+ ]
39946
+ },
39947
+ {
39948
+ type: "event",
39949
+ name: "openzeppelin_token::erc721::extensions::erc721_enumerable::erc721_enumerable::ERC721EnumerableComponent::Event",
39950
+ kind: "enum",
39951
+ variants: []
39952
+ },
39953
+ {
39954
+ type: "event",
39955
+ name: "openzeppelin_introspection::src5::SRC5Component::Event",
39956
+ kind: "enum",
39957
+ variants: []
39958
+ },
39959
+ {
39960
+ type: "event",
39961
+ name: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Upgraded",
39962
+ kind: "struct",
39963
+ members: [
39964
+ {
39965
+ name: "class_hash",
39966
+ type: "core::starknet::class_hash::ClassHash",
39967
+ kind: "data"
39968
+ }
39969
+ ]
39970
+ },
39971
+ {
39972
+ type: "event",
39973
+ name: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Event",
39974
+ kind: "enum",
39975
+ variants: [
39976
+ {
39977
+ name: "Upgraded",
39978
+ type: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Upgraded",
39979
+ kind: "nested"
39980
+ }
39981
+ ]
39982
+ },
39983
+ {
39984
+ type: "event",
39985
+ name: "vault::redeem_request::redeem_request::RedeemRequest::Event",
39986
+ kind: "enum",
39987
+ variants: [
39988
+ {
39989
+ name: "ERC721Event",
39990
+ type: "openzeppelin_token::erc721::erc721::ERC721Component::Event",
39991
+ kind: "flat"
39992
+ },
39993
+ {
39994
+ name: "ERC721EnumerableEvent",
39995
+ type: "openzeppelin_token::erc721::extensions::erc721_enumerable::erc721_enumerable::ERC721EnumerableComponent::Event",
39996
+ kind: "flat"
39997
+ },
39998
+ {
39999
+ name: "SRC5Event",
40000
+ type: "openzeppelin_introspection::src5::SRC5Component::Event",
40001
+ kind: "flat"
40002
+ },
40003
+ {
40004
+ name: "UpgradeableEvent",
40005
+ type: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Event",
40006
+ kind: "flat"
40007
+ }
40008
+ ]
40009
+ }
40010
+ ];
40011
+
39210
40012
  // src/strategies/universal-adapters/svk-troves-adapter.ts
39211
40013
  var DEFAULT_TROVES_STRATEGIES_API = "https://app.troves.fi/api/strategies";
39212
40014
  function parseTrovesApyField(raw) {
@@ -39320,6 +40122,100 @@ var SvkTrovesAdapter = class _SvkTrovesAdapter extends BaseAdapter {
39320
40122
  throw error;
39321
40123
  }
39322
40124
  }
40125
+ async getPendingAssetsFromOwner(owner = this._positionOwner(), decimals = this.config.baseToken.decimals) {
40126
+ const vault = new import_starknet30.Contract({
40127
+ abi: universal_vault_abi_default,
40128
+ address: this.config.strategyVault.address,
40129
+ providerOrAccount: this.config.networkConfig.provider
40130
+ });
40131
+ try {
40132
+ const dueRaw = await vault.call("due_assets_from_owner", [owner.address]);
40133
+ return Web3Number.fromWei(dueRaw.toString(), decimals);
40134
+ } catch (e) {
40135
+ logger.warn(
40136
+ `${_SvkTrovesAdapter.name}::getPendingAssetsFromOwner: due_assets_from_owner failed (treating as 0): ${e.message}`
40137
+ );
40138
+ return Web3Number.fromWei("0", decimals);
40139
+ }
40140
+ }
40141
+ /**
40142
+ * Get pending assets from owner by scanning redeem request NFTs.
40143
+ * This method iterates backwards through NFT IDs to find all pending redemptions for a specific owner.
40144
+ *
40145
+ * @param redeemRequestNFT - The redeem request NFT contract address
40146
+ * @param owner - The owner address to check for pending redemptions (defaults to positionOwner)
40147
+ * @param decimals - Token decimals for conversion (defaults to baseToken decimals)
40148
+ * @returns Total pending assets from all NFTs owned by the specified address
40149
+ */
40150
+ async getPendingAssetsFromOwnerNFTMethod(redeemRequestNFT, owner = this._positionOwner(), decimals = this.config.baseToken.decimals) {
40151
+ try {
40152
+ const nftContract = new import_starknet30.Contract({
40153
+ abi: redeem_request_nft_abi_default,
40154
+ address: redeemRequestNFT.address,
40155
+ providerOrAccount: this.config.networkConfig.provider
40156
+ });
40157
+ const idLenRaw = await nftContract.id_len();
40158
+ const latestId = BigInt(idLenRaw.toString());
40159
+ if (latestId === 0n) {
40160
+ logger.info(
40161
+ `${_SvkTrovesAdapter.name}::getPendingAssetsFromOwnerNFTMethod: No NFTs minted yet`
40162
+ );
40163
+ return Web3Number.fromWei("0", decimals);
40164
+ }
40165
+ const matchingIds = [];
40166
+ let currentId = latestId - 1n;
40167
+ while (currentId >= 0n) {
40168
+ try {
40169
+ const idU256 = import_starknet30.uint256.bnToUint256(currentId);
40170
+ const ownerRaw = await nftContract.owner_of(idU256);
40171
+ const nftOwnerAddr = ContractAddr.from(ownerRaw.toString());
40172
+ if (nftOwnerAddr.eq(owner)) {
40173
+ matchingIds.push(currentId);
40174
+ logger.debug(
40175
+ `${_SvkTrovesAdapter.name}::getPendingAssetsFromOwnerNFTMethod: Found matching NFT ID ${currentId} for owner ${owner.address}`
40176
+ );
40177
+ }
40178
+ currentId--;
40179
+ } catch (e) {
40180
+ logger.info(
40181
+ `${_SvkTrovesAdapter.name}::getPendingAssetsFromOwnerNFTMethod: Reached last pending NFT at id ${currentId}`
40182
+ );
40183
+ break;
40184
+ }
40185
+ }
40186
+ if (matchingIds.length === 0) {
40187
+ logger.info(
40188
+ `${_SvkTrovesAdapter.name}::getPendingAssetsFromOwnerNFTMethod: No matching NFTs found for owner ${owner.address}`
40189
+ );
40190
+ return Web3Number.fromWei("0", decimals);
40191
+ }
40192
+ let totalNominal = 0n;
40193
+ for (const nftId of matchingIds) {
40194
+ try {
40195
+ const idU256 = import_starknet30.uint256.bnToUint256(nftId);
40196
+ const infoRaw = await nftContract.id_to_info(idU256);
40197
+ const nominal = BigInt(infoRaw.nominal.toString());
40198
+ totalNominal += nominal;
40199
+ logger.debug(
40200
+ `${_SvkTrovesAdapter.name}::getPendingAssetsFromOwnerNFTMethod: NFT ID ${nftId} has nominal ${nominal}`
40201
+ );
40202
+ } catch (e) {
40203
+ logger.warn(
40204
+ `${_SvkTrovesAdapter.name}::getPendingAssetsFromOwnerNFTMethod: Failed to get info for NFT ID ${nftId}: ${e.message}`
40205
+ );
40206
+ }
40207
+ }
40208
+ logger.info(
40209
+ `${_SvkTrovesAdapter.name}::getPendingAssetsFromOwnerNFTMethod: Found ${matchingIds.length} NFTs with total nominal ${totalNominal}`
40210
+ );
40211
+ return Web3Number.fromWei(totalNominal.toString(), decimals);
40212
+ } catch (error) {
40213
+ logger.error(
40214
+ `${_SvkTrovesAdapter.name}::getPendingAssetsFromOwnerNFTMethod: ${error.message}`
40215
+ );
40216
+ return Web3Number.fromWei("0", decimals);
40217
+ }
40218
+ }
39323
40219
  async maxDeposit(amount) {
39324
40220
  const baseToken = this.config.baseToken;
39325
40221
  if (!amount) {
@@ -39384,9 +40280,9 @@ var SvkTrovesAdapter = class _SvkTrovesAdapter extends BaseAdapter {
39384
40280
  return [
39385
40281
  {
39386
40282
  target: strategyVault,
39387
- method: "withdraw",
40283
+ method: "request_redeem",
39388
40284
  packedArguments: [recv.toBigInt(), owner.toBigInt()],
39389
- sanitizer: SIMPLE_SANITIZER,
40285
+ sanitizer: SVK_SIMPLE_SANITIZER,
39390
40286
  id: this._withdrawCallProofReadableId()
39391
40287
  }
39392
40288
  ];
@@ -39448,16 +40344,23 @@ var SvkTrovesAdapter = class _SvkTrovesAdapter extends BaseAdapter {
39448
40344
  const uint256Amount = import_starknet30.uint256.bnToUint256(amount.toWei());
39449
40345
  const recv = this.config.vaultAllocator;
39450
40346
  const owner = this.config.vaultAllocator;
40347
+ const vault = new import_starknet30.Contract({
40348
+ abi: universal_vault_abi_default,
40349
+ address: strategyVault.address,
40350
+ providerOrAccount: this.config.networkConfig.provider
40351
+ });
40352
+ const sharesRaw = await vault.convert_to_shares(uint256Amount);
40353
+ const sharesU256 = import_starknet30.uint256.bnToUint256(sharesRaw.toString());
39451
40354
  return [
39452
40355
  {
39453
40356
  proofReadableId: this._withdrawCallProofReadableId(),
39454
- sanitizer: SIMPLE_SANITIZER,
40357
+ sanitizer: SVK_SIMPLE_SANITIZER,
39455
40358
  call: {
39456
40359
  contractAddress: strategyVault,
39457
- selector: import_starknet30.hash.getSelectorFromName("withdraw"),
40360
+ selector: import_starknet30.hash.getSelectorFromName("request_redeem"),
39458
40361
  calldata: [
39459
- toBigInt(uint256Amount.low.toString()),
39460
- toBigInt(uint256Amount.high.toString()),
40362
+ toBigInt(sharesU256.low.toString()),
40363
+ toBigInt(sharesU256.high.toString()),
39461
40364
  recv.toBigInt(),
39462
40365
  owner.toBigInt()
39463
40366
  ]
@@ -41242,9 +42145,9 @@ var SVKStrategy = class extends BaseStrategy {
41242
42145
  * Builds a manage call from an adapter's proof tree.
41243
42146
  * DRY helper for the repeated getProofs → getManageCall pattern.
41244
42147
  */
41245
- async buildManageCallFromAdapter(adapter, isDeposit, amount) {
42148
+ async buildManageCallFromAdapter(adapter, isDeposit, amount, additionalParams) {
41246
42149
  const proofsInfo = adapter.getProofs(isDeposit, this.getMerkleTree());
41247
- const manageCalls = await proofsInfo.callConstructor({ amount });
42150
+ const manageCalls = await proofsInfo.callConstructor({ amount, ...additionalParams });
41248
42151
  return this.getManageCall(
41249
42152
  this.getProofGroupsForManageCalls(manageCalls),
41250
42153
  manageCalls
@@ -42436,6 +43339,526 @@ var HyperLSTStrategies = [
42436
43339
  getStrategySettings("mRe7YIELD", "mRe7YIELD", hypermRe7YIELD, false, false)
42437
43340
  ];
42438
43341
 
43342
+ // src/strategies/usdc-boosted-strategy.tsx
43343
+ var import_starknet34 = require("starknet");
43344
+ var USDCBoostedStrategy = class _USDCBoostedStrategy extends SVKStrategy {
43345
+ constructor(config, pricer, metadata) {
43346
+ super(config, pricer, metadata);
43347
+ this.metadata.additionalInfo.adapters.forEach((adapter) => {
43348
+ adapter.adapter.config.networkConfig = this.config;
43349
+ adapter.adapter.config.pricer = this.pricer;
43350
+ if (adapter.adapter._vesuAdapter) {
43351
+ adapter.adapter._vesuAdapter.networkConfig = this.config;
43352
+ adapter.adapter._vesuAdapter.pricer = this.pricer;
43353
+ }
43354
+ });
43355
+ }
43356
+ getTag() {
43357
+ return `${_USDCBoostedStrategy.name}:${this.metadata.name}`;
43358
+ }
43359
+ getAdapterById(id) {
43360
+ const entry = this.metadata.additionalInfo.adapters.find(
43361
+ (a) => a.id === id
43362
+ );
43363
+ if (!entry) {
43364
+ throw new Error(
43365
+ `${this.getTag()}::getAdapterById: adapter not found for id "${id}"`
43366
+ );
43367
+ }
43368
+ return entry.adapter;
43369
+ }
43370
+ async getVesuModifyPositionCall(params) {
43371
+ logger.verbose(
43372
+ `${this.getTag()}::getVesuModifyPositionCall isDeposit=${params.isDeposit}, amount=${params.leg1DepositAmount}, debtAmount=${params.debtAmount?.toNumber()}`
43373
+ );
43374
+ return this.buildManageCallFromAdapter(
43375
+ this.getAdapterById("vesu_usdc_strk"),
43376
+ params.isDeposit,
43377
+ params.leg1DepositAmount,
43378
+ params.debtAmount ? { debtAmount: params.debtAmount } : void 0
43379
+ );
43380
+ }
43381
+ async getVesuPositions() {
43382
+ const positions = await this.getAdapterById(
43383
+ "vesu_usdc_strk"
43384
+ ).getPositions();
43385
+ return positions.map((p) => ({
43386
+ amount: p.amount,
43387
+ usdValue: p.usdValue,
43388
+ remarks: p.remarks ?? "",
43389
+ token: p.tokenInfo,
43390
+ protocol: p.protocol
43391
+ }));
43392
+ }
43393
+ async getVesuHealthFactor(blockNumber = "latest") {
43394
+ const vesuAdapter = this.getAdapterById("vesu_usdc_strk");
43395
+ return await vesuAdapter._vesuAdapter.getHealthFactor(blockNumber);
43396
+ }
43397
+ // TODO: will have to still modify for instant withdrawals as of now
43398
+ async getModifyHyperPositionCall(params) {
43399
+ logger.verbose(
43400
+ `${this.getTag()}::getModifyHyperPositionCall isDeposit=${params.isDeposit}, amount=${params.amount}`
43401
+ );
43402
+ return this.buildManageCallFromAdapter(
43403
+ this.getAdapterById("hyper_xstrk"),
43404
+ params.isDeposit,
43405
+ params.amount
43406
+ );
43407
+ }
43408
+ async getAvnuSwapCall(params) {
43409
+ logger.verbose(
43410
+ `${this.getTag()}::getAvnuSwapCall isDeposit=${params.isDeposit}, amount=${params.amount}`
43411
+ );
43412
+ return this.buildManageCallFromAdapter(
43413
+ this.getAdapterById("avnu_strk_xstrk"),
43414
+ params.isDeposit,
43415
+ params.amount
43416
+ );
43417
+ }
43418
+ /**
43419
+ * Returns the USDC balance sitting idle inside the vault contract itself.
43420
+ * This balance can offset the required liquidity during withdrawal processing.
43421
+ */
43422
+ async getUnusedBalanceVault() {
43423
+ const collateralToken = this.metadata.additionalInfo.collateralToken;
43424
+ return new ERC20(this.config).balanceOf(
43425
+ collateralToken.address,
43426
+ this.metadata.additionalInfo.vaultAddress,
43427
+ collateralToken.decimals
43428
+ );
43429
+ }
43430
+ /**
43431
+ * Returns the current STRK balance sitting unused in the vault allocator.
43432
+ * This covers STRK from prior borrow cycles that hasn't been swapped yet.
43433
+ */
43434
+ // Technically we can use this or we can even use the avnu-adapter to get the unused debt
43435
+ async getUnusedDebt() {
43436
+ const debtToken = this.metadata.additionalInfo.debtToken;
43437
+ return new ERC20(this.config).balanceOf(
43438
+ debtToken.address,
43439
+ this.metadata.additionalInfo.vaultAllocator,
43440
+ debtToken.decimals
43441
+ );
43442
+ }
43443
+ /**
43444
+ * Returns the xSTRK balance sitting in the vault allocator.
43445
+ * This is non-zero when the previous cycle's request_redeem on the HyperPosition
43446
+ * has been settled — the redeemed xSTRK lands here and is ready to be swapped.
43447
+ */
43448
+ async getxSTRKInVault() {
43449
+ const xstrkToken = Global.getDefaultTokens().find(
43450
+ (t) => t.symbol === "xSTRK"
43451
+ );
43452
+ if (!xstrkToken) {
43453
+ throw new Error(`${this.getTag()}:: xSTRK token not found`);
43454
+ }
43455
+ return new ERC20(this.config).balanceOf(
43456
+ xstrkToken.address.address,
43457
+ this.metadata.additionalInfo.vaultAllocator,
43458
+ xstrkToken.decimals
43459
+ );
43460
+ }
43461
+ /**
43462
+ * Simulates depositing `depositAmount` USDC on Vesu and returns the
43463
+ * incremental STRK that would be borrowed. Needed to size the AVNU swap
43464
+ * call that is batched together with the Vesu call in the same transaction.
43465
+ */
43466
+ async computeVesuDepositBorrowAmount(depositAmount) {
43467
+ return this.getAdapterById(
43468
+ "vesu_usdc_strk"
43469
+ ).getExpectedDepositDebtDelta(depositAmount);
43470
+ }
43471
+ async computeVesuWithdrawDebtDelta(withdrawAmount) {
43472
+ return this.getAdapterById(
43473
+ "vesu_usdc_strk"
43474
+ ).getExpectedWithdrawDebtDelta(withdrawAmount);
43475
+ }
43476
+ async getPendingHyperAssets() {
43477
+ const xstrkToken = Global.getDefaultTokens().find(
43478
+ (t) => t.symbol === "xSTRK"
43479
+ );
43480
+ const hyperXstrkRedeemNFT = ContractAddr.from(
43481
+ "0x51e40b839dc0c2feca923f863072673b94abfa2483345be3b30b457a90d095"
43482
+ );
43483
+ return this.getAdapterById(
43484
+ "hyper_xstrk"
43485
+ ).getPendingAssetsFromOwnerNFTMethod(
43486
+ hyperXstrkRedeemNFT,
43487
+ this.metadata.additionalInfo.vaultAllocator,
43488
+ xstrkToken.decimals
43489
+ );
43490
+ }
43491
+ // TODO: rn we are just making these functions in the strategy itself but
43492
+ // later on we will move them to the SVKStrategy for generalization
43493
+ async getUserTVL(user, blockIdentifier = "latest") {
43494
+ const shares = await this.contract.call("balanceOf", [user.address], {
43495
+ blockIdentifier
43496
+ });
43497
+ const assets = await this.contract.call(
43498
+ "convert_to_assets",
43499
+ [import_starknet34.uint256.bnToUint256(shares)],
43500
+ { blockIdentifier }
43501
+ );
43502
+ const amount = Web3Number.fromWei(
43503
+ assets.toString(),
43504
+ this.metadata.depositTokens[0].decimals
43505
+ );
43506
+ const blockNumber = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : void 0;
43507
+ const price = await this.pricer.getPrice(
43508
+ this.metadata.depositTokens[0].symbol,
43509
+ blockNumber
43510
+ );
43511
+ const usdValue = Number(amount.toFixed(6)) * price.price;
43512
+ return {
43513
+ tokenInfo: this.asset(),
43514
+ amount,
43515
+ usdValue
43516
+ };
43517
+ }
43518
+ async getTVL() {
43519
+ const assets = await this.contract.total_assets();
43520
+ const amount = Web3Number.fromWei(
43521
+ assets.toString(),
43522
+ this.metadata.depositTokens[0].decimals
43523
+ );
43524
+ const price = await this.pricer.getPrice(
43525
+ this.metadata.depositTokens[0].symbol
43526
+ );
43527
+ const usdValue = Number(amount.toFixed(6)) * price.price;
43528
+ return {
43529
+ tokenInfo: this.asset(),
43530
+ amount,
43531
+ usdValue
43532
+ };
43533
+ }
43534
+ async getAUM() {
43535
+ const underlying = this.asset();
43536
+ const usdcPrice = await this.pricer.getPrice(underlying.symbol);
43537
+ const allPositions = [];
43538
+ for (const adapter of this.metadata.additionalInfo.adapters) {
43539
+ const positions = await adapter.adapter.getPositions();
43540
+ allPositions.push(...positions);
43541
+ }
43542
+ let netAUM = new Web3Number(0, underlying.decimals);
43543
+ for (const position of allPositions) {
43544
+ if (position.tokenInfo.address.eq(underlying.address)) {
43545
+ netAUM = netAUM.plus(position.amount);
43546
+ } else {
43547
+ const valueInUSDC = position.usdValue;
43548
+ netAUM = netAUM.plus(valueInUSDC);
43549
+ }
43550
+ }
43551
+ const unusedBalance = await this.getUnusedBalance();
43552
+ logger.verbose(
43553
+ `${this.getTag()} unused balance: ${unusedBalance.amount.toNumber()}`
43554
+ );
43555
+ netAUM = netAUM.plus(unusedBalance.amount);
43556
+ const prevAum = await this.getPrevAUM();
43557
+ logger.verbose(`${this.getTag()} AUM: ${netAUM}`);
43558
+ const realAUM = {
43559
+ tokenInfo: underlying,
43560
+ amount: netAUM,
43561
+ usdValue: netAUM.toNumber() * usdcPrice.price,
43562
+ apy: { apy: 0, type: "base" /* BASE */ },
43563
+ remarks: "finalised" /* FINALISED */,
43564
+ protocol: Protocols.NONE
43565
+ };
43566
+ const estimatedAUMDelta = {
43567
+ tokenInfo: underlying,
43568
+ amount: Web3Number.fromWei("0", underlying.decimals),
43569
+ usdValue: 0,
43570
+ apy: { apy: 0, type: "base" /* BASE */ },
43571
+ remarks: "defispring" /* DEFISPRING */,
43572
+ protocol: Protocols.NONE
43573
+ };
43574
+ return {
43575
+ net: {
43576
+ tokenInfo: underlying,
43577
+ amount: netAUM,
43578
+ usdValue: netAUM.toNumber() * usdcPrice.price
43579
+ },
43580
+ prevAum,
43581
+ splits: [realAUM, estimatedAUMDelta]
43582
+ };
43583
+ }
43584
+ // TODO: can refactor later but seems redundant since not being used ANYWHERE
43585
+ // Most of the fund management done through adapters only
43586
+ async getFundManagementCall(params) {
43587
+ logger.verbose(
43588
+ `${this.getTag()}::getFundManagementCall params: ${JSON.stringify(params)}`
43589
+ );
43590
+ const allAdapters = this.metadata.additionalInfo.adapters.map(
43591
+ (a) => a.adapter
43592
+ );
43593
+ if (!params.isDeposit) {
43594
+ const unusedBalance = await this.getUnusedBalance();
43595
+ logger.verbose(
43596
+ `${this.getTag()}::getFundManagementCall unusedBalance: ${unusedBalance.amount}, required: ${params.leg1DepositAmount}`
43597
+ );
43598
+ if (unusedBalance.amount.gte(params.leg1DepositAmount)) {
43599
+ return null;
43600
+ }
43601
+ const adapters2 = await AdapterOptimizer.getAdapterToUse(
43602
+ allAdapters,
43603
+ false,
43604
+ params.leg1DepositAmount
43605
+ );
43606
+ if (adapters2.length > 0) {
43607
+ const proofsInfo = adapters2.map(
43608
+ (adapter) => adapter.getProofs(false, this.getMerkleTree())
43609
+ );
43610
+ const calls = [];
43611
+ for (const info of proofsInfo) {
43612
+ const manageCalls = await info.callConstructor({
43613
+ amount: params.leg1DepositAmount
43614
+ });
43615
+ const call = this.getManageCall(
43616
+ this.getProofGroupsForManageCalls(manageCalls),
43617
+ manageCalls
43618
+ );
43619
+ calls.push(call);
43620
+ }
43621
+ return calls;
43622
+ }
43623
+ throw new Error(
43624
+ `${this.getTag()}::getFundManagementCall: no adapters for withdraw: ${unusedBalance.amount}`
43625
+ );
43626
+ }
43627
+ const adapters = await AdapterOptimizer.getAdapterToUse(
43628
+ allAdapters,
43629
+ true,
43630
+ params.leg1DepositAmount
43631
+ );
43632
+ if (adapters.length > 0) {
43633
+ const proofsInfo = adapters.map(
43634
+ (adapter) => adapter.getProofs(true, this.getMerkleTree())
43635
+ );
43636
+ const calls = [];
43637
+ for (const info of proofsInfo) {
43638
+ const manageCalls = await info.callConstructor({
43639
+ amount: params.leg1DepositAmount
43640
+ });
43641
+ const call = this.getManageCall(
43642
+ this.getProofGroupsForManageCalls(manageCalls),
43643
+ manageCalls
43644
+ );
43645
+ calls.push(call);
43646
+ }
43647
+ return calls;
43648
+ }
43649
+ throw new Error(
43650
+ `${this.getTag()}::getFundManagementCall: no adapters for deposit: ${params.leg1DepositAmount}`
43651
+ );
43652
+ }
43653
+ };
43654
+ function getUSDCBoostedSettings(vaultSettings) {
43655
+ vaultSettings.leafAdapters = [];
43656
+ const xSTRKToken = Global.getDefaultTokens().find(
43657
+ (t) => t.symbol === "xSTRK"
43658
+ );
43659
+ const USDCToken = Global.getDefaultTokens().find((t) => t.symbol === "USDC");
43660
+ const STRKToken = Global.getDefaultTokens().find((t) => t.symbol === "STRK");
43661
+ const baseAdapterConfig = {
43662
+ baseToken: USDCToken,
43663
+ supportedPositions: [{ asset: USDCToken, isDebt: false }],
43664
+ networkConfig: getMainnetConfig(),
43665
+ pricer: new PricerFromApi(getMainnetConfig(), Global.getDefaultTokens()),
43666
+ vaultAllocator: vaultSettings.vaultAllocator,
43667
+ vaultAddress: vaultSettings.vaultAddress
43668
+ };
43669
+ const vesuModifyPositionAdapter = new VesuModifyPositionAdapter({
43670
+ poolId: vaultSettings.vesuPoolId,
43671
+ collateral: vaultSettings.collateralToken,
43672
+ debt: vaultSettings.debtToken,
43673
+ targetLtv: vaultSettings.targetLTV,
43674
+ maxLtv: vaultSettings.maxLTV,
43675
+ ...baseAdapterConfig,
43676
+ supportedPositions: [
43677
+ { asset: USDCToken, isDebt: false },
43678
+ { asset: STRKToken, isDebt: true }
43679
+ ]
43680
+ });
43681
+ const avnuAdapter = new AvnuAdapter({
43682
+ baseUrl: AVNU_QUOTE_URL,
43683
+ avnuContract: AVNU_EXCHANGE,
43684
+ slippage: 0.01,
43685
+ minimumExtendedPriceDifferenceForSwapOpen: 0,
43686
+ maximumExtendedPriceDifferenceForSwapClosing: 0,
43687
+ ...baseAdapterConfig,
43688
+ baseToken: STRKToken,
43689
+ supportedPositions: [
43690
+ { asset: STRKToken, isDebt: false },
43691
+ { asset: xSTRKToken, isDebt: false }
43692
+ ]
43693
+ });
43694
+ const svkTrovesAdapter = new SvkTrovesAdapter({
43695
+ ...baseAdapterConfig,
43696
+ baseToken: xSTRKToken,
43697
+ supportedPositions: [{ asset: xSTRKToken, isDebt: false }],
43698
+ strategyVault: vaultSettings.hyperxSTRKVaultAddress,
43699
+ trovesStrategyId: "hyper_xstrk"
43700
+ });
43701
+ const usdcTransferAdapter = new TokenTransferAdapter({
43702
+ ...baseAdapterConfig,
43703
+ fromAddress: vaultSettings.vaultAllocator,
43704
+ toAddress: vaultSettings.vaultAddress
43705
+ });
43706
+ const commonAdapter = new CommonAdapter({
43707
+ id: "flash_loan_init" /* FLASH_LOAN */,
43708
+ vaultAddress: vaultSettings.vaultAddress,
43709
+ vaultAllocator: vaultSettings.vaultAllocator,
43710
+ manager: vaultSettings.manager,
43711
+ asset: USDCToken.address
43712
+ });
43713
+ vaultSettings.adapters.push(
43714
+ // TODO: generalize the ids
43715
+ { id: "vesu_usdc_strk", adapter: vesuModifyPositionAdapter },
43716
+ // Used to track swapped funds in vaultAllocator
43717
+ { id: "avnu_strk_xstrk", adapter: avnuAdapter },
43718
+ { id: "hyper_xstrk", adapter: svkTrovesAdapter },
43719
+ { id: "usdc_transfer", adapter: usdcTransferAdapter }
43720
+ );
43721
+ vaultSettings.leafAdapters.push(
43722
+ () => vesuModifyPositionAdapter.getDepositLeaf()
43723
+ );
43724
+ vaultSettings.leafAdapters.push(
43725
+ () => vesuModifyPositionAdapter.getWithdrawLeaf()
43726
+ );
43727
+ vaultSettings.leafAdapters.push(() => avnuAdapter.getDepositLeaf());
43728
+ vaultSettings.leafAdapters.push(() => avnuAdapter.getWithdrawLeaf());
43729
+ vaultSettings.leafAdapters.push(() => svkTrovesAdapter.getDepositLeaf());
43730
+ vaultSettings.leafAdapters.push(() => svkTrovesAdapter.getWithdrawLeaf());
43731
+ vaultSettings.leafAdapters.push(
43732
+ commonAdapter.getApproveAdapter(
43733
+ USDCToken.address,
43734
+ vaultSettings.vaultAddress,
43735
+ "approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */
43736
+ ).bind(commonAdapter)
43737
+ );
43738
+ vaultSettings.leafAdapters.push(
43739
+ commonAdapter.getBringLiquidityAdapter("bring_liquidity" /* BRING_LIQUIDITY */).bind(commonAdapter)
43740
+ );
43741
+ return vaultSettings;
43742
+ }
43743
+ var usdcBoostedSettings = {
43744
+ vaultAddress: ContractAddr.from(
43745
+ "0xcdb0e3b2e076a2cdc4ee958b726b47c066239ef91c5ac80c94cf814147b84"
43746
+ ),
43747
+ manager: ContractAddr.from(
43748
+ "0x72eea9bac9fa8cfffda637d3b990851446860c6fd8987d6cb50e659b01ee50f"
43749
+ ),
43750
+ vaultAllocator: ContractAddr.from(
43751
+ "0x6d3101cff7f821412a99ebe23bb31a1950f93276285102eb4313e3601f5f927"
43752
+ ),
43753
+ redeemRequestNFT: ContractAddr.from(
43754
+ "0x47dcc6889ca8db4e9eea8f55421e10f8ce7e356ccb45260a1c49a76f733c309"
43755
+ ),
43756
+ // TODO: not applicable in our case -> remove later ( make it optional if needed)
43757
+ aumOracle: ContractAddr.from("0x0"),
43758
+ leafAdapters: [],
43759
+ adapters: [],
43760
+ // Calc using the maxLTV / targetLTV (0.5)
43761
+ targetHealthFactor: 1.32,
43762
+ // Calc using the maxLTV / maxAcceptableLTV (0.55)
43763
+ minHealthFactor: 1.2,
43764
+ vesuPoolId: VesuPools.Prime,
43765
+ collateralToken: Global.getDefaultTokens().find((t) => t.symbol === "USDC"),
43766
+ debtToken: Global.getDefaultTokens().find((t) => t.symbol === "STRK"),
43767
+ maxLTV: 0.66,
43768
+ targetLTV: 0.5,
43769
+ hyperxSTRKVaultAddress: ContractAddr.from(
43770
+ "0x46c7a54c82b1fe374353859f554a40b8bd31d3e30f742901579e7b57b1b5960"
43771
+ )
43772
+ };
43773
+ function getStrategySettings2(settings) {
43774
+ const USDCToken = Global.getDefaultTokens().find((t) => t.symbol === "USDC");
43775
+ const STRKToken = Global.getDefaultTokens().find((t) => t.symbol === "STRK");
43776
+ return {
43777
+ id: "usdc_boosted",
43778
+ name: "USDC Boosted",
43779
+ description: "Deposits USDC as collateral on Vesu, borrows STRK, swaps to xSTRK, and deposits into Hyper-xSTRK for boosted yield",
43780
+ address: settings.vaultAddress,
43781
+ launchBlock: 8742931,
43782
+ type: "ERC4626",
43783
+ vaultType: {
43784
+ // TODO: can change as per need
43785
+ type: "Meta Vault" /* META_VAULT */,
43786
+ description: "Deposits USDC as collateral on Vesu, borrows STRK, swaps to xSTRK, and deposits into Hyper-xSTRK for boosted yield"
43787
+ },
43788
+ depositTokens: [USDCToken],
43789
+ additionalInfo: getUSDCBoostedSettings(settings),
43790
+ // TODO: config lateron
43791
+ risk: {
43792
+ riskFactor: [],
43793
+ netRisk: 0,
43794
+ notARisks: []
43795
+ },
43796
+ protocols: [Protocols.VESU, Protocols.TROVES],
43797
+ curator: {
43798
+ name: "Unwrap Labs",
43799
+ logo: "https://assets.troves.fi/integrations/unwraplabs/white.png"
43800
+ },
43801
+ settings: {
43802
+ maxTVL: Web3Number.fromWei(0, USDCToken.decimals),
43803
+ isPaused: false,
43804
+ isAudited: false,
43805
+ isInstantWithdrawal: false,
43806
+ hideHarvestInfo: true,
43807
+ quoteToken: USDCToken,
43808
+ alerts: [
43809
+ {
43810
+ tab: "withdraw",
43811
+ text: "On withdrawal, you will receive an NFT representing your withdrawal request. The funds will be automatically sent to your wallet (NFT owner) in 1-2 hours. You can monitor the status in transactions tab.",
43812
+ type: "info"
43813
+ }
43814
+ ]
43815
+ },
43816
+ contractDetails: getContractDetails(settings),
43817
+ // TODO: config later
43818
+ faqs: [],
43819
+ investmentSteps: [
43820
+ "Deposit USDC into the vault",
43821
+ "USDC is supplied as collateral on Vesu, STRK is borrowed",
43822
+ "Borrowed STRK is swapped to xSTRK via Avnu",
43823
+ "xSTRK is deposited into the Hyper-xSTRK vault for additional yield",
43824
+ "On withdrawal, the pipeline reverses to return USDC"
43825
+ ],
43826
+ // TODO: config later
43827
+ tags: ["Meta Vaults" /* META_VAULT */],
43828
+ security: {
43829
+ auditStatus: "Audited" /* AUDITED */,
43830
+ sourceCode: {
43831
+ type: "Closed Source" /* CLOSED_SOURCE */,
43832
+ contractLink: "https://github.com/trovesfi/troves-contracts"
43833
+ },
43834
+ accessControl: {
43835
+ type: "Standard Account" /* STANDARD_ACCOUNT */,
43836
+ addresses: [ContractAddr.from("0x0")],
43837
+ timeLock: "2 Days"
43838
+ }
43839
+ },
43840
+ redemptionInfo: {
43841
+ instantWithdrawalVault: "No" /* NO */,
43842
+ redemptionsInfo: [
43843
+ {
43844
+ title: "Typical Duration",
43845
+ description: "1-2 hours"
43846
+ }
43847
+ ],
43848
+ alerts: [
43849
+ {
43850
+ type: "info",
43851
+ text: "Redemption times are estimates and may vary based on network conditions and liquidity requirements.",
43852
+ tab: "withdraw"
43853
+ }
43854
+ ]
43855
+ },
43856
+ usualTimeToEarnings: null,
43857
+ usualTimeToEarningsDescription: null
43858
+ };
43859
+ }
43860
+ var USDCBoostedStrategies = [getStrategySettings2(usdcBoostedSettings)];
43861
+
42439
43862
  // src/strategies/vesu-extended-strategy/services/ltv-imbalance-rebalance-math.ts
42440
43863
  function ceilBtc(v, precision) {
42441
43864
  const f = 10 ** precision;
@@ -43833,6 +45256,142 @@ function createSolveBudgetFromRawState(params) {
43833
45256
  }
43834
45257
  return budget;
43835
45258
  }
45259
+ function assertRouteSanityAndAdjust(route, availableAmount) {
45260
+ if (!route.amount) {
45261
+ throw new Error(`Invalid route given to assertRouteSanityAndAdjust: ${JSON.stringify(route)}`);
45262
+ }
45263
+ const routeAmount = route.amount.toNumber();
45264
+ if (routeAmount <= availableAmount) {
45265
+ return route;
45266
+ }
45267
+ if (routeAmount - availableAmount <= CASE_THRESHOLD_USD) {
45268
+ return { ...route, amount: new Web3Number(availableAmount, route.amount.decimals) };
45269
+ }
45270
+ throw new Error(`Route amount ${routeAmount} exceeds available amount ${availableAmount}, Route name: ${route.type}`);
45271
+ }
45272
+ function assertVesuMultiplyRouteSanityAndAdjust(route, availableAmount, state, isIncrease) {
45273
+ const btcPrice = state.vesuPoolState.collateralPrice;
45274
+ const totalCollateralAmount = isIncrease ? route.marginAmount.plus(route.swappedCollateralAmount).plus(state.vesuPoolState.collateralAmount) : state.vesuPoolState.collateralAmount.minus(route.marginAmount.plus(route.swappedCollateralAmount));
45275
+ const totalDebtAmount = isIncrease ? route.debtAmount.plus(state.vesuPoolState.debtAmount) : state.vesuPoolState.debtAmount.minus(route.debtAmount);
45276
+ const newHF = HealthFactorMath.getHealthFactor(
45277
+ totalCollateralAmount,
45278
+ btcPrice,
45279
+ VesuConfig.maxLtv,
45280
+ totalDebtAmount,
45281
+ state.vesuPoolState.debtPrice
45282
+ );
45283
+ const idealHF = VesuConfig.maxLtv / VesuConfig.targetLtv - 0.05;
45284
+ assert(newHF >= idealHF, `SolveBudget::applyRoutesAndVerifyLtvState newHF=${newHF} < idealHF=${idealHF}`);
45285
+ }
45286
+ function applyRoutesAndVerifyLtvState(state, routes) {
45287
+ const btcPrice = state.vesuPoolState.collateralPrice;
45288
+ const adjustedRouters = [...routes];
45289
+ let index = 0;
45290
+ for (const r of routes) {
45291
+ switch (r.type) {
45292
+ case "WALLET_TO_VA" /* WALLET_TO_VA */: {
45293
+ const adjustedRoute = assertRouteSanityAndAdjust(r, state.walletUsd);
45294
+ const amt = adjustedRoute.amount.toNumber();
45295
+ state.spendWallet(amt);
45296
+ state.addToVA(amt);
45297
+ break;
45298
+ }
45299
+ case "VESU_REPAY" /* VESU_REPAY */: {
45300
+ const adjustedRoute = assertRouteSanityAndAdjust(r, state.vaRawUsd);
45301
+ const amt = Math.abs(adjustedRoute.amount.toNumber());
45302
+ state.repayVesuBorrowCapacity(amt);
45303
+ state.spendVA(amt);
45304
+ break;
45305
+ }
45306
+ case "EXTENDED_TO_WALLET" /* EXTENDED_TO_WALLET */: {
45307
+ const adjustedRoute = assertRouteSanityAndAdjust(r, state.extAvailWithdraw);
45308
+ const amt = adjustedRoute.amount.toNumber();
45309
+ state.addToWallet(amt);
45310
+ state.spendExtAvailTrade(amt);
45311
+ break;
45312
+ }
45313
+ case "REALISE_PNL" /* REALISE_PNL */: {
45314
+ const amt = r.amount.toNumber();
45315
+ state.spendExtAvailUpnl(amt);
45316
+ state.addToExtAvailTrade(amt);
45317
+ break;
45318
+ }
45319
+ case "VA_TO_EXTENDED" /* VA_TO_EXTENDED */: {
45320
+ const adjustedRoute = assertRouteSanityAndAdjust(r, state.vaRawUsd);
45321
+ const amt = adjustedRoute.amount.toNumber();
45322
+ state.spendVA(amt);
45323
+ state.addToExtAvailTrade(amt);
45324
+ break;
45325
+ }
45326
+ case "WALLET_TO_EXTENDED" /* WALLET_TO_EXTENDED */: {
45327
+ const adjustedRoute = assertRouteSanityAndAdjust(r, state.walletUsd);
45328
+ const amt = adjustedRoute.amount.toNumber();
45329
+ state.spendWallet(amt);
45330
+ state.addToExtAvailTrade(amt);
45331
+ break;
45332
+ }
45333
+ case "VESU_BORROW" /* VESU_BORROW */: {
45334
+ const borrowedAmount = r.amount.toNumber();
45335
+ const currentCollateralAmount = state.vesuPoolState.collateralAmount.toNumber();
45336
+ const currentDebtAmount = state.vesuPoolState.debtAmount.toNumber();
45337
+ const maxDebtAmount = HealthFactorMath.getMaxDebtAmount(
45338
+ new Web3Number(currentCollateralAmount, state.vesuPoolState.collateralToken.decimals),
45339
+ state.vesuPoolState.collateralPrice,
45340
+ VesuConfig.maxLtv,
45341
+ VesuConfig.maxLtv / VesuConfig.targetLtv - 0.05,
45342
+ // e.g. if ideal HF is 1.4, upto 1.35 is ok.
45343
+ state.vesuPoolState.debtPrice,
45344
+ state.vesuPoolState.debtToken
45345
+ );
45346
+ const availableDebtAmount = maxDebtAmount.minus(new Web3Number(currentDebtAmount, state.vesuPoolState.debtToken.decimals));
45347
+ if (!availableDebtAmount.plus(CASE_THRESHOLD_USD).greaterThan(borrowedAmount)) {
45348
+ throw new Error(`SolveBudget::applyRoutesAndVerifyLtvState availableDebtAmount=${availableDebtAmount.toNumber()} < borrowedAmount=${borrowedAmount}`);
45349
+ }
45350
+ state.spendVesuBorrowCapacity(borrowedAmount);
45351
+ state.addToVA(borrowedAmount);
45352
+ break;
45353
+ }
45354
+ case "VESU_MULTIPLY_INCREASE_LEVER" /* VESU_MULTIPLY_INCREASE_LEVER */: {
45355
+ const mr = r;
45356
+ assertVesuMultiplyRouteSanityAndAdjust(mr, state.vaRawUsd, state, true);
45357
+ state.applyVesuDelta(
45358
+ mr.poolId,
45359
+ mr.collateralToken,
45360
+ mr.debtToken,
45361
+ mr.marginAmount.plus(mr.swappedCollateralAmount),
45362
+ mr.debtAmount
45363
+ );
45364
+ state.spendVA(mr.marginAmount.toNumber() * btcPrice);
45365
+ break;
45366
+ }
45367
+ case "VESU_MULTIPLY_DECREASE_LEVER" /* VESU_MULTIPLY_DECREASE_LEVER */: {
45368
+ const mr = r;
45369
+ assertVesuMultiplyRouteSanityAndAdjust(mr, state.vaRawUsd, state, false);
45370
+ state.applyVesuDelta(
45371
+ mr.poolId,
45372
+ mr.collateralToken,
45373
+ mr.debtToken,
45374
+ new Web3Number(mr.marginAmount.negated().minus(mr.swappedCollateralAmount).toFixed(8), mr.marginAmount.decimals),
45375
+ mr.debtAmount
45376
+ );
45377
+ const marginBtc = mr.marginAmount.toNumber();
45378
+ if (marginBtc > 10 ** -COLLATERAL_PRECISION) {
45379
+ state.addToVA(marginBtc * btcPrice);
45380
+ }
45381
+ break;
45382
+ }
45383
+ case "EXTENDED_DECREASE_LEVER" /* EXTENDED_DECREASE_LEVER */:
45384
+ case "EXTENDED_INCREASE_LEVER" /* EXTENDED_INCREASE_LEVER */: {
45385
+ const er = r;
45386
+ state.applyExtendedExposureDelta(er.instrument, er.amount, btcPrice);
45387
+ break;
45388
+ }
45389
+ case "RETURN_TO_WAIT" /* RETURN_TO_WAIT */:
45390
+ break;
45391
+ }
45392
+ index++;
45393
+ }
45394
+ }
43836
45395
  var ExtendedSVKVesuStateManager = class {
43837
45396
  constructor(config) {
43838
45397
  this._tag = "ExtendedSVKVesuStateManager";
@@ -43851,13 +45410,19 @@ var ExtendedSVKVesuStateManager = class {
43851
45410
  * Pass 0 (default) for normal investment / rebalancing cycles.
43852
45411
  */
43853
45412
  async solve(withdrawAmount = new Web3Number(0, USDC_TOKEN_DECIMALS)) {
43854
- await this._refresh();
45413
+ const gaurdrailBudget = await this._refresh();
43855
45414
  if (Math.abs(this._budget.extPendingDeposit) > 0) {
43856
45415
  logger.warn(`${this._tag}::solve extPendingDeposit=${this._budget.extPendingDeposit}`);
43857
45416
  return null;
43858
45417
  }
43859
45418
  this._validateRefreshedState();
43860
45419
  const cases = this._classifyCases(withdrawAmount);
45420
+ for (const c of cases) {
45421
+ applyRoutesAndVerifyLtvState(gaurdrailBudget, c.routes);
45422
+ }
45423
+ const extendedPositionSize = gaurdrailBudget.extendedPositionsView[0].size.toNumber();
45424
+ const vesuPositionSize = gaurdrailBudget.vesuPoolState.collateralAmount.toNumber();
45425
+ assert(Math.abs(extendedPositionSize - vesuPositionSize) <= 1e-5, "extended positions size mismatch");
43861
45426
  const result = {
43862
45427
  cases,
43863
45428
  // ignore these fields for now. only cases are relevant.
@@ -43905,7 +45470,7 @@ var ExtendedSVKVesuStateManager = class {
43905
45470
  vaultUsdcBalance,
43906
45471
  walletBalance
43907
45472
  );
43908
- this._budget = createSolveBudgetFromRawState({
45473
+ const data = {
43909
45474
  assetToken: this._config.assetToken,
43910
45475
  usdcToken: this._config.usdcToken,
43911
45476
  unusedBalance,
@@ -43922,7 +45487,9 @@ var ExtendedSVKVesuStateManager = class {
43922
45487
  pendingDeposit: extendedBalance?.pendingDeposit || new Web3Number(0, USDC_TOKEN_DECIMALS)
43923
45488
  },
43924
45489
  vesuPoolStates
43925
- });
45490
+ };
45491
+ this._budget = createSolveBudgetFromRawState(data);
45492
+ const gaurdrailBudget = createSolveBudgetFromRawState({ ...data });
43926
45493
  this._budget.logStateSummary();
43927
45494
  const totalUnusedUsd = unusedBalance.reduce(
43928
45495
  (acc, b) => acc + b.usdValue,
@@ -43931,6 +45498,7 @@ var ExtendedSVKVesuStateManager = class {
43931
45498
  logger.info(
43932
45499
  `${this._tag}::_refresh completed \u2014 unusedBalances: ${unusedBalance.length} tokens [${unusedBalance.map((b) => `${b.token.symbol}=$${b.usdValue.toFixed(2)}`).join(", ")}], totalUnusedUsd: ${totalUnusedUsd.toFixed(2)}, extendedPositions: ${extendedPositions.length} [${extendedPositions.map((p) => `${p.instrument}=${p.size.toFixed(6)} ${p.side}, ${p.valueUsd.toFixed(6)} ${p.instrument}`).join(", ")}], vesuPools: ${vesuPoolStates.length} [${vesuPoolStates.map((p) => `${p.poolId.shortString()}=${p.debtAmount.toFixed(6)} ${p.debtToken.symbol}, ${p.collateralAmount.toFixed(6)} ${p.collateralToken.symbol}`).join(", ")}], availableForTrade: ${extendedBalance?.availableForTrade.toNumber()} - availableForWithdrawal: ${extendedBalance?.availableForWithdrawal.toNumber()} - unrealisedPnl: ${extendedBalance?.unrealisedPnl.toNumber()} - extendedBalance::balance: ${extendedBalance?.balance.toNumber()} - extendedBalance::pendingDeposit: ${extendedBalance?.pendingDeposit.toNumber()} - extendedBalance::equity: ${extendedBalance?.equity.toNumber()}`
43933
45500
  );
45501
+ return gaurdrailBudget;
43934
45502
  }
43935
45503
  // todo add communication check with python server of extended. if not working, throw error in solve function.
43936
45504
  /** True when strategy asset and USDC share one token — VA idle balance is tracked as USDC, not as asset. */
@@ -45674,7 +47242,7 @@ var ExtendedSVKVesuStateManager = class {
45674
47242
  };
45675
47243
 
45676
47244
  // src/strategies/vesu-extended-strategy/services/executionService.ts
45677
- var import_starknet34 = require("starknet");
47245
+ var import_starknet35 = require("starknet");
45678
47246
 
45679
47247
  // src/strategies/vesu-extended-strategy/types/transaction-metadata.ts
45680
47248
  var CycleType = /* @__PURE__ */ ((CycleType2) => {
@@ -46606,7 +48174,7 @@ var _ExecutionService = class _ExecutionService {
46606
48174
  const extendedContract = extendedAdapter.config.extendedContract;
46607
48175
  const vaultId = extendedAdapter.config.vaultIdExtended;
46608
48176
  const salt = Math.floor(Math.random() * 10 ** usdcToken.decimals);
46609
- const uint256Amount = import_starknet34.uint256.bnToUint256(amount.toWei());
48177
+ const uint256Amount = import_starknet35.uint256.bnToUint256(amount.toWei());
46610
48178
  const approveCall = {
46611
48179
  contractAddress: usdcToken.address.address,
46612
48180
  entrypoint: "approve",
@@ -48563,12 +50131,12 @@ var PricerRedis = class extends Pricer {
48563
50131
 
48564
50132
  // src/node/deployer.ts
48565
50133
  var import_assert = __toESM(require("assert"));
48566
- var import_starknet36 = require("starknet");
50134
+ var import_starknet37 = require("starknet");
48567
50135
  var import_fs3 = require("fs");
48568
50136
 
48569
50137
  // src/utils/store.ts
48570
50138
  var import_fs2 = __toESM(require("fs"));
48571
- var import_starknet35 = require("starknet");
50139
+ var import_starknet36 = require("starknet");
48572
50140
  var crypto2 = __toESM(require("crypto"));
48573
50141
 
48574
50142
  // src/utils/encrypt.ts
@@ -48662,7 +50230,7 @@ var Store = class _Store {
48662
50230
  }
48663
50231
  logger.verbose(`Account loaded: ${accountKey} from network: ${this.config.network}`);
48664
50232
  logger.verbose(`Address: ${data.address}`);
48665
- const acc = new import_starknet35.Account({
50233
+ const acc = new import_starknet36.Account({
48666
50234
  provider: this.config.provider,
48667
50235
  address: data.address,
48668
50236
  signer: data.pk,
@@ -48757,10 +50325,10 @@ function getAccount(accountKey, config, password = process.env.ACCOUNT_SECURE_PA
48757
50325
  }
48758
50326
  async function myDeclare(contract_name, package_name = "strkfarm", config, acc) {
48759
50327
  const provider2 = config.provider;
48760
- const compiledSierra = import_starknet36.json.parse(
50328
+ const compiledSierra = import_starknet37.json.parse(
48761
50329
  (0, import_fs3.readFileSync)(`./target/release/${package_name}_${contract_name}.contract_class.json`).toString("ascii")
48762
50330
  );
48763
- const compiledCasm = import_starknet36.json.parse(
50331
+ const compiledCasm = import_starknet37.json.parse(
48764
50332
  (0, import_fs3.readFileSync)(`./target/release/${package_name}_${contract_name}.compiled_contract_class.json`).toString("ascii")
48765
50333
  );
48766
50334
  const contracts = getContracts();
@@ -48768,7 +50336,7 @@ async function myDeclare(contract_name, package_name = "strkfarm", config, acc)
48768
50336
  contract: compiledSierra,
48769
50337
  casm: compiledCasm
48770
50338
  };
48771
- const result = (0, import_starknet36.extractContractHashes)(payload);
50339
+ const result = (0, import_starknet37.extractContractHashes)(payload);
48772
50340
  console.log("classhash:", result.classHash);
48773
50341
  try {
48774
50342
  const cls = await provider2.getClassByHash(result.classHash);
@@ -48786,7 +50354,7 @@ async function myDeclare(contract_name, package_name = "strkfarm", config, acc)
48786
50354
  const tx = await acc.declareIfNot(payload);
48787
50355
  console.log(`Declaring: ${contract_name}, tx:`, tx.transaction_hash);
48788
50356
  await provider2.waitForTransaction(tx.transaction_hash, {
48789
- successStates: [import_starknet36.TransactionExecutionStatus.SUCCEEDED]
50357
+ successStates: [import_starknet37.TransactionExecutionStatus.SUCCEEDED]
48790
50358
  });
48791
50359
  if (!contracts.class_hashes) {
48792
50360
  contracts["class_hashes"] = {};
@@ -48810,7 +50378,7 @@ async function deployContract(contract_name, classHash, constructorData, config,
48810
50378
  });
48811
50379
  console.log("Deploy tx: ", tx.transaction_hash);
48812
50380
  await provider2.waitForTransaction(tx.transaction_hash, {
48813
- successStates: [import_starknet36.TransactionExecutionStatus.SUCCEEDED]
50381
+ successStates: [import_starknet37.TransactionExecutionStatus.SUCCEEDED]
48814
50382
  });
48815
50383
  const contracts = getContracts();
48816
50384
  if (!contracts.contracts) {
@@ -48827,7 +50395,7 @@ async function prepareMultiDeployContracts(contracts, config, acc) {
48827
50395
  for (const { contract_name, package_name, constructorData } of contracts) {
48828
50396
  const declaredInfo = await myDeclare(contract_name, package_name, config, acc);
48829
50397
  const classHash = declaredInfo.class_hash;
48830
- const { calls, addresses } = new import_starknet36.Deployer().buildDeployerCall({
50398
+ const { calls, addresses } = new import_starknet37.Deployer().buildDeployerCall({
48831
50399
  classHash,
48832
50400
  constructorCalldata: constructorData
48833
50401
  }, acc.address);
@@ -48845,7 +50413,7 @@ async function prepareMultiDeployContracts(contracts, config, acc) {
48845
50413
  }
48846
50414
  async function executeDeployCalls(contractsInfo, acc, provider2) {
48847
50415
  for (let contractInfo of contractsInfo) {
48848
- (0, import_assert.default)(import_starknet36.num.toHexString(contractInfo.call.contractAddress) == import_starknet36.num.toHexString(import_starknet36.constants.UDC.ADDRESS), "Must be pointed at UDC address");
50416
+ (0, import_assert.default)(import_starknet37.num.toHexString(contractInfo.call.contractAddress) == import_starknet37.num.toHexString(import_starknet37.constants.UDC.ADDRESS), "Must be pointed at UDC address");
48849
50417
  }
48850
50418
  const allCalls = contractsInfo.map((info) => info.call);
48851
50419
  await executeTransactions(allCalls, acc, provider2, `Deploying contracts: ${contractsInfo.map((info) => info.contract_name).join(", ")}`);
@@ -48869,7 +50437,7 @@ async function executeTransactions(calls, acc, provider2, remarks) {
48869
50437
  if (remarks)
48870
50438
  console.log(`Remarks: ${remarks}`);
48871
50439
  await provider2.waitForTransaction(tx.transaction_hash, {
48872
- successStates: [import_starknet36.TransactionExecutionStatus.SUCCEEDED]
50440
+ successStates: [import_starknet37.TransactionExecutionStatus.SUCCEEDED]
48873
50441
  });
48874
50442
  console.log(`Transaction confirmed: ${tx.transaction_hash}`);
48875
50443
  return tx;
@@ -48880,10 +50448,10 @@ async function myWaitForTransaction(transaction_hash, provider2, retry = 0) {
48880
50448
  try {
48881
50449
  const status = await provider2.getTransactionStatus(transaction_hash);
48882
50450
  logger.verbose(`Transaction status: ${JSON.stringify(status.execution_status)}`);
48883
- if (status.execution_status == import_starknet36.TransactionExecutionStatus.SUCCEEDED) {
50451
+ if (status.execution_status == import_starknet37.TransactionExecutionStatus.SUCCEEDED) {
48884
50452
  return true;
48885
50453
  }
48886
- if (status.execution_status == import_starknet36.TransactionExecutionStatus.REVERTED) {
50454
+ if (status.execution_status == import_starknet37.TransactionExecutionStatus.REVERTED) {
48887
50455
  throw new Error(`Transaction reverted: ${transaction_hash}`);
48888
50456
  }
48889
50457
  if (retry > MAX_RETRIES2) {
@@ -48990,6 +50558,7 @@ var deployer_default = Deployer;
48990
50558
  SIMPLE_SANITIZER,
48991
50559
  SIMPLE_SANITIZER_V2,
48992
50560
  SIMPLE_SANITIZER_VESU_V1_DELEGATIONS,
50561
+ SVK_SIMPLE_SANITIZER,
48993
50562
  SenseiStrategies,
48994
50563
  SenseiVault,
48995
50564
  SolveBudget,
@@ -49009,6 +50578,8 @@ var deployer_default = Deployer;
49009
50578
  TokenTransferAdapter,
49010
50579
  UNIVERSAL_ADAPTERS,
49011
50580
  UNIVERSAL_MANAGE_IDS,
50581
+ USDCBoostedStrategies,
50582
+ USDCBoostedStrategy,
49012
50583
  UniversalLstMultiplierStrategy,
49013
50584
  UniversalStrategies,
49014
50585
  UniversalStrategy,