@strkfarm/sdk 1.1.8 → 1.1.10

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.
@@ -64,6 +64,17 @@ var _Web3Number = class extends BigNumber {
64
64
  const answer = _value.greaterThanOrEqualTo(_valueMe) ? _value : _valueMe;
65
65
  return this.construct(answer.toString(), this.decimals);
66
66
  }
67
+ abs() {
68
+ console.warn(`abs: this: ${this}`);
69
+ return this.construct(Math.abs(this.toNumber()).toFixed(12), this.decimals);
70
+ }
71
+ toI129() {
72
+ const sign = this.isNegative() ? 1 : 0;
73
+ return {
74
+ mag: BigInt(this.toWei()) * (this.isNegative() ? -1n : 1n),
75
+ sign
76
+ };
77
+ }
67
78
  };
68
79
  BigNumber.config({ DECIMAL_PLACES: 18, ROUNDING_MODE: BigNumber.ROUND_DOWN });
69
80
  _Web3Number.config({ DECIMAL_PLACES: 18, ROUNDING_MODE: BigNumber.ROUND_DOWN });
@@ -2147,6 +2158,61 @@ var AvnuWrapper = class _AvnuWrapper {
2147
2158
  }
2148
2159
  };
2149
2160
 
2161
+ // src/modules/ekubo-quoter.ts
2162
+ import axios5 from "axios";
2163
+ var EkuboQuoter = class {
2164
+ // e.g. ETH/USDC'
2165
+ constructor(config) {
2166
+ this.config = config;
2167
+ this.ENDPOINT = "https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_FROM_ADDRESS}}/{{TOKEN_TO_ADDRESS}}";
2168
+ }
2169
+ /**
2170
+ *
2171
+ * @param fromToken
2172
+ * @param toToken
2173
+ * @param amount Can be negative too, which would mean to get exact amount out
2174
+ * @returns
2175
+ */
2176
+ async getQuote(fromToken, toToken, amount) {
2177
+ let _fromToken = amount.gt(0) ? fromToken : toToken;
2178
+ let _toToken = amount.gt(0) ? toToken : fromToken;
2179
+ const quote = await axios5.get(this.ENDPOINT.replace("{{AMOUNT}}", amount.toWei()).replace("{{TOKEN_FROM_ADDRESS}}", _fromToken).replace("{{TOKEN_TO_ADDRESS}}", _toToken));
2180
+ console.log(`Ekubo quote from ${_fromToken} to ${_toToken} for ${amount.toString()}: ${JSON.stringify(quote.data)}`);
2181
+ return quote.data;
2182
+ }
2183
+ /**
2184
+ * Formats Ekubo response for Vesu multiple use
2185
+ * @param quote
2186
+ * @param fromTokenInfo
2187
+ * @returns
2188
+ */
2189
+ getVesuMultiplyQuote(quote, fromTokenInfo, toTokenInfo) {
2190
+ return quote.splits.map((split) => {
2191
+ const isNegativeAmount = BigInt(split.amount_specified) < 0n;
2192
+ const token = isNegativeAmount ? toTokenInfo : fromTokenInfo;
2193
+ return {
2194
+ route: split.route.map((_route) => ({
2195
+ pool_key: {
2196
+ token0: ContractAddr.from(_route.pool_key.token0),
2197
+ token1: ContractAddr.from(_route.pool_key.token1),
2198
+ fee: _route.pool_key.fee,
2199
+ tick_spacing: _route.pool_key.tick_spacing.toString(),
2200
+ extension: _route.pool_key.extension
2201
+ },
2202
+ sqrt_ratio_limit: Web3Number.fromWei(_route.sqrt_ratio_limit, 18),
2203
+ // just for use, any decimal works
2204
+ skip_ahead: Web3Number.fromWei(_route.skip_ahead, 0)
2205
+ // no decimal for this
2206
+ })),
2207
+ token_amount: {
2208
+ token: token.address,
2209
+ amount: Web3Number.fromWei(split.amount_specified, token.decimals)
2210
+ }
2211
+ };
2212
+ });
2213
+ }
2214
+ };
2215
+
2150
2216
  // src/interfaces/common.tsx
2151
2217
  import { BlockTag, RpcProvider as RpcProvider2 } from "starknet";
2152
2218
  import { Fragment, jsx } from "react/jsx-runtime";
@@ -3853,9 +3919,9 @@ var BaseStrategy = class extends CacheClass {
3853
3919
  };
3854
3920
 
3855
3921
  // src/node/headless.browser.ts
3856
- import axios5 from "axios";
3922
+ import axios6 from "axios";
3857
3923
  async function getAPIUsingHeadlessBrowser(url) {
3858
- const res = await axios5.get(url);
3924
+ const res = await axios6.get(url);
3859
3925
  return res.data;
3860
3926
  }
3861
3927
 
@@ -16292,20 +16358,27 @@ var _protocol2 = {
16292
16358
  name: "Ekubo",
16293
16359
  logo: "https://app.ekubo.org/favicon.ico"
16294
16360
  };
16295
- var _corelatedPoolRiskFactors = [
16361
+ var _lstPoolRiskFactors = [
16296
16362
  { type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 2 /* WELL_AUDITED */, weight: 34, reason: "Audited smart contracts" },
16297
16363
  { type: "Impermanent Loss Risk" /* IMPERMANENT_LOSS */, value: 1 /* HIGHLY_CORRELATED */, weight: 33, reason: "Low risk due to co-related assets" },
16298
- { type: "Market Risk" /* MARKET_RISK */, value: 1 /* VERY_LOW_VOLATILITY */, weight: 33, reason: "Low risk due to co-related assets" }
16364
+ { type: "Market Risk" /* MARKET_RISK */, value: 1 /* VERY_LOW_VOLATILITY */, weight: 33, reason: "Low risk due to co-related assets" },
16365
+ { type: "Depeg Risk" /* DEPEG_RISK */, value: 2 /* GENERALLY_STABLE */, weight: 33, reason: "Generally stable pegged assets" }
16366
+ ];
16367
+ var _stableCoinPoolRiskFactors = [
16368
+ { type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 1 /* BATTLE_TESTED */, weight: 34, reason: "Audited smart contracts" },
16369
+ { type: "Impermanent Loss Risk" /* IMPERMANENT_LOSS */, value: 1 /* HIGHLY_CORRELATED */, weight: 33, reason: "Low risk due to co-related assets" },
16370
+ { type: "Market Risk" /* MARKET_RISK */, value: 1 /* VERY_LOW_VOLATILITY */, weight: 33, reason: "Low risk due to co-related assets" },
16371
+ { type: "Depeg Risk" /* DEPEG_RISK */, value: 1 /* HIGHLY_STABLE */, weight: 33, reason: "Highly stable assets" }
16299
16372
  ];
16300
16373
  var mediumVolatilityPoolRiskFactors = [
16301
16374
  { type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 2 /* WELL_AUDITED */, weight: 34, reason: "Audited smart contracts" },
16302
- { type: "Impermanent Loss Risk" /* IMPERMANENT_LOSS */, value: 3 /* NON_CORRELATED */, weight: 33, reason: "Low risk due to co-related assets" },
16303
- { type: "Market Risk" /* MARKET_RISK */, value: 3 /* MODERATE_VOLATILITY */, weight: 33, reason: "Low risk due to co-related assets" }
16375
+ { type: "Impermanent Loss Risk" /* IMPERMANENT_LOSS */, value: 3 /* NON_CORRELATED */, weight: 33, reason: "Assets are not correlated, often volatile" },
16376
+ { type: "Market Risk" /* MARKET_RISK */, value: 3 /* MODERATE_VOLATILITY */, weight: 33, reason: "Assets are not correlated, relative volatile can be moderate sometimes" }
16304
16377
  ];
16305
16378
  var highVolatilityPoolRiskFactors = [
16306
16379
  { type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 2 /* WELL_AUDITED */, weight: 34, reason: "Audited smart contracts" },
16307
- { type: "Impermanent Loss Risk" /* IMPERMANENT_LOSS */, value: 3 /* NON_CORRELATED */, weight: 33, reason: "Low risk due to co-related assets" },
16308
- { type: "Market Risk" /* MARKET_RISK */, value: 4 /* HIGH_VOLATILITY */, weight: 33, reason: "Low risk due to co-related assets" }
16380
+ { type: "Impermanent Loss Risk" /* IMPERMANENT_LOSS */, value: 3 /* NON_CORRELATED */, weight: 33, reason: "Assets are not correlated, often volatile" },
16381
+ { type: "Market Risk" /* MARKET_RISK */, value: 4 /* HIGH_VOLATILITY */, weight: 33, reason: "Assets are not correlated, relative volatile is often high" }
16309
16382
  ];
16310
16383
  var mediumRisk = {
16311
16384
  riskFactor: mediumVolatilityPoolRiskFactors,
@@ -16378,9 +16451,9 @@ var xSTRKSTRK = {
16378
16451
  auditUrl: AUDIT_URL2,
16379
16452
  maxTVL: Web3Number.fromWei("0", 18),
16380
16453
  risk: {
16381
- riskFactor: _corelatedPoolRiskFactors,
16382
- netRisk: _corelatedPoolRiskFactors.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _corelatedPoolRiskFactors.reduce((acc, curr) => acc + curr.weight, 0),
16383
- notARisks: getNoRiskTags(_corelatedPoolRiskFactors)
16454
+ riskFactor: _lstPoolRiskFactors,
16455
+ netRisk: _lstPoolRiskFactors.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _lstPoolRiskFactors.reduce((acc, curr) => acc + curr.weight, 0),
16456
+ notARisks: getNoRiskTags(_lstPoolRiskFactors)
16384
16457
  },
16385
16458
  apyMethodology: "APY based on 30-day historical performance, including fees and rewards.",
16386
16459
  additionalInfo: {
@@ -16535,7 +16608,11 @@ var RE7Strategies = [
16535
16608
  Global.getDefaultTokens().find((t) => t.symbol === "USDC"),
16536
16609
  Global.getDefaultTokens().find((t) => t.symbol === "USDT")
16537
16610
  ],
16538
- risk: xSTRKSTRK.risk
16611
+ risk: {
16612
+ riskFactor: _stableCoinPoolRiskFactors,
16613
+ netRisk: _stableCoinPoolRiskFactors.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _stableCoinPoolRiskFactors.reduce((acc, curr) => acc + curr.weight, 0),
16614
+ notARisks: getNoRiskTags(_stableCoinPoolRiskFactors)
16615
+ }
16539
16616
  },
16540
16617
  {
16541
16618
  ...ETHUSDCRe7Strategy,
@@ -18719,6 +18796,7 @@ import { hash, num as num6, shortString } from "starknet";
18719
18796
 
18720
18797
  // src/strategies/universal-adapters/adapter-utils.ts
18721
18798
  var SIMPLE_SANITIZER = ContractAddr.from("0x5a2e3ceb3da368b983a8717898427ab7b6daf04014b70f321e777f9aad940b4");
18799
+ var SIMPLE_SANITIZER_V2 = ContractAddr.from("0x5643d54da70a471cd2b6fa37f52ea7a13cc3f3910689a839f8490a663d2208a");
18722
18800
  var PRICE_ROUTER = ContractAddr.from("0x05e83Fa38D791d2dba8E6f487758A9687FfEe191A6Cf8a6c5761ab0a110DB837");
18723
18801
  var AVNU_MIDDLEWARE = ContractAddr.from("0x4a7972ed3f5d1e74a6d6c4a8f467666953d081c8f2270390cc169d50d17cb0d");
18724
18802
  function toBigInt(value) {
@@ -18733,13 +18811,13 @@ function toBigInt(value) {
18733
18811
 
18734
18812
  // src/strategies/universal-adapters/baseAdapter.ts
18735
18813
  var BaseAdapter = class extends CacheClass {
18736
- constructSimpleLeafData(params) {
18814
+ constructSimpleLeafData(params, sanitizer = SIMPLE_SANITIZER) {
18737
18815
  const { id, target, method, packedArguments } = params;
18738
18816
  return {
18739
18817
  id: BigInt(num6.getDecimalString(shortString.encodeShortString(id))),
18740
18818
  readableId: id,
18741
18819
  data: [
18742
- SIMPLE_SANITIZER.toBigInt(),
18820
+ sanitizer.toBigInt(),
18743
18821
  // sanitizer address
18744
18822
  target.toBigInt(),
18745
18823
  // contract
@@ -21178,172 +21256,833 @@ var vesu_singleton_abi_default = [
21178
21256
  }
21179
21257
  ];
21180
21258
 
21181
- // src/strategies/universal-adapters/vesu-adapter.ts
21182
- var VesuAmountType = /* @__PURE__ */ ((VesuAmountType2) => {
21183
- VesuAmountType2[VesuAmountType2["Delta"] = 0] = "Delta";
21184
- VesuAmountType2[VesuAmountType2["Target"] = 1] = "Target";
21185
- return VesuAmountType2;
21186
- })(VesuAmountType || {});
21187
- var VesuAmountDenomination = /* @__PURE__ */ ((VesuAmountDenomination2) => {
21188
- VesuAmountDenomination2[VesuAmountDenomination2["Native"] = 0] = "Native";
21189
- VesuAmountDenomination2[VesuAmountDenomination2["Assets"] = 1] = "Assets";
21190
- return VesuAmountDenomination2;
21191
- })(VesuAmountDenomination || {});
21192
- var VesuPools = {
21193
- Genesis: ContractAddr.from("0x4dc4f0ca6ea4961e4c8373265bfd5317678f4fe374d76f3fd7135f57763bf28")
21194
- };
21195
- var VesuAdapter = class _VesuAdapter extends BaseAdapter {
21196
- constructor(config) {
21197
- super();
21198
- this.VESU_SINGLETON = ContractAddr.from("0x000d8d6dfec4d33bfb6895de9f3852143a17c6f92fd2a21da3d6924d34870160");
21199
- this.getModifyPosition = () => {
21200
- const positionData = [0n];
21201
- const packedArguments = [
21202
- toBigInt(this.config.poolId.toString()),
21203
- // pool id
21204
- toBigInt(this.config.collateral.address.toString()),
21205
- // collateral
21206
- toBigInt(this.config.debt.address.toString()),
21207
- // debt
21208
- toBigInt(this.config.vaultAllocator.toString()),
21209
- // vault allocator
21210
- toBigInt(positionData.length),
21211
- ...positionData
21212
- ];
21213
- const output = this.constructSimpleLeafData({
21214
- id: this.config.id,
21215
- target: this.VESU_SINGLETON,
21216
- method: "modify_position",
21217
- packedArguments
21218
- });
21219
- return { leaf: output, callConstructor: this.getModifyPositionCall.bind(this) };
21220
- };
21221
- this.getModifyPositionCall = (params) => {
21222
- const _collateral = {
21223
- amount_type: this.formatAmountTypeEnum(params.collateralAmount.amount_type),
21224
- denomination: this.formatAmountDenominationEnum(params.collateralAmount.denomination),
21225
- value: {
21226
- abs: uint2567.bnToUint256(params.collateralAmount.value.abs.toWei()),
21227
- is_negative: params.collateralAmount.value.abs.isZero() ? false : params.collateralAmount.value.is_negative
21228
- }
21229
- };
21230
- logger.verbose(`VesuAdapter::ConstructingModify::Collateral::${JSON.stringify(_collateral)}`);
21231
- const _debt = {
21232
- amount_type: this.formatAmountTypeEnum(params.debtAmount.amount_type),
21233
- denomination: this.formatAmountDenominationEnum(params.debtAmount.denomination),
21234
- value: {
21235
- abs: uint2567.bnToUint256(params.debtAmount.value.abs.toWei()),
21236
- is_negative: params.debtAmount.value.abs.isZero() ? false : params.debtAmount.value.is_negative
21237
- }
21238
- };
21239
- logger.verbose(`VesuAdapter::ConstructingModify::Debt::${JSON.stringify(_debt)}`);
21240
- const singletonContract = new Contract8({ abi: vesu_singleton_abi_default, address: this.VESU_SINGLETON.toString(), providerOrAccount: new RpcProvider4({ nodeUrl: "" }) });
21241
- const call = singletonContract.populate("modify_position", {
21242
- params: {
21243
- pool_id: this.config.poolId.toBigInt(),
21244
- collateral_asset: this.config.collateral.address.toBigInt(),
21245
- debt_asset: this.config.debt.address.toBigInt(),
21246
- user: this.config.vaultAllocator.toBigInt(),
21247
- collateral: _collateral,
21248
- debt: _debt,
21249
- data: [0]
21250
- }
21251
- });
21252
- return {
21253
- sanitizer: SIMPLE_SANITIZER,
21254
- call: {
21255
- contractAddress: this.VESU_SINGLETON,
21256
- selector: hash3.getSelectorFromName("modify_position"),
21257
- calldata: [
21258
- ...call.calldata
21259
- ]
21260
- }
21261
- };
21262
- };
21263
- this.getDefispringRewardsAdapter = (id) => {
21264
- return () => {
21265
- const packedArguments = [];
21266
- const output = {
21267
- id: BigInt(num8.getDecimalString(shortString3.encodeShortString(id))),
21268
- readableId: id,
21269
- data: [
21270
- SIMPLE_SANITIZER.toBigInt(),
21271
- // sanitizer address
21272
- VESU_REWARDS_CONTRACT.toBigInt(),
21273
- // contract
21274
- toBigInt(hash3.getSelectorFromName("claim")),
21275
- // method name
21276
- BigInt(packedArguments.length),
21277
- ...packedArguments
21278
- ]
21279
- };
21280
- return { leaf: output, callConstructor: this.getDefiSpringClaimCall().bind(this) };
21281
- };
21282
- };
21283
- this.getDefiSpringClaimCall = () => {
21284
- return (params) => ({
21285
- sanitizer: SIMPLE_SANITIZER,
21286
- call: {
21287
- contractAddress: VESU_REWARDS_CONTRACT,
21288
- selector: hash3.getSelectorFromName("claim"),
21289
- calldata: [
21290
- BigInt(params.amount.toWei()),
21291
- BigInt(params.proofs.length),
21292
- ...params.proofs.map((proof) => BigInt(num8.hexToDecimalString(proof)))
21293
- ]
21294
- }
21295
- });
21296
- };
21297
- this.config = config;
21298
- }
21299
- static getDefaultModifyPositionCallParams(params) {
21300
- return {
21301
- collateralAmount: {
21302
- amount_type: 0 /* Delta */,
21303
- denomination: 1 /* Assets */,
21304
- value: {
21305
- abs: params.collateralAmount,
21306
- is_negative: !params.isAddCollateral
21307
- }
21259
+ // src/data/vesu-multiple.abi.json
21260
+ var vesu_multiple_abi_default = [
21261
+ {
21262
+ type: "impl",
21263
+ name: "LockerImpl",
21264
+ interface_name: "ekubo::interfaces::core::ILocker"
21265
+ },
21266
+ {
21267
+ type: "struct",
21268
+ name: "core::array::Span::<core::felt252>",
21269
+ members: [
21270
+ {
21271
+ name: "snapshot",
21272
+ type: "@core::array::Array::<core::felt252>"
21273
+ }
21274
+ ]
21275
+ },
21276
+ {
21277
+ type: "interface",
21278
+ name: "ekubo::interfaces::core::ILocker",
21279
+ items: [
21280
+ {
21281
+ type: "function",
21282
+ name: "locked",
21283
+ inputs: [
21284
+ {
21285
+ name: "id",
21286
+ type: "core::integer::u32"
21287
+ },
21288
+ {
21289
+ name: "data",
21290
+ type: "core::array::Span::<core::felt252>"
21291
+ }
21292
+ ],
21293
+ outputs: [
21294
+ {
21295
+ type: "core::array::Span::<core::felt252>"
21296
+ }
21297
+ ],
21298
+ state_mutability: "external"
21299
+ }
21300
+ ]
21301
+ },
21302
+ {
21303
+ type: "impl",
21304
+ name: "MultiplyImpl",
21305
+ interface_name: "vesu_periphery::multiply::IMultiply"
21306
+ },
21307
+ {
21308
+ type: "struct",
21309
+ name: "ekubo::types::keys::PoolKey",
21310
+ members: [
21311
+ {
21312
+ name: "token0",
21313
+ type: "core::starknet::contract_address::ContractAddress"
21308
21314
  },
21309
- debtAmount: {
21310
- amount_type: 0 /* Delta */,
21311
- denomination: 1 /* Assets */,
21312
- value: {
21313
- abs: params.debtAmount,
21314
- is_negative: !params.isBorrow
21315
- }
21315
+ {
21316
+ name: "token1",
21317
+ type: "core::starknet::contract_address::ContractAddress"
21318
+ },
21319
+ {
21320
+ name: "fee",
21321
+ type: "core::integer::u128"
21322
+ },
21323
+ {
21324
+ name: "tick_spacing",
21325
+ type: "core::integer::u128"
21326
+ },
21327
+ {
21328
+ name: "extension",
21329
+ type: "core::starknet::contract_address::ContractAddress"
21316
21330
  }
21317
- };
21318
- }
21319
- formatAmountTypeEnum(amountType) {
21320
- switch (amountType) {
21321
- case 0 /* Delta */:
21322
- return new CairoCustomEnum2({ Delta: {} });
21323
- case 1 /* Target */:
21324
- return new CairoCustomEnum2({ Target: {} });
21325
- }
21326
- throw new Error(`Unknown VesuAmountType: ${amountType}`);
21327
- }
21328
- formatAmountDenominationEnum(denomination) {
21329
- switch (denomination) {
21330
- case 0 /* Native */:
21331
- return new CairoCustomEnum2({ Native: {} });
21332
- case 1 /* Assets */:
21333
- return new CairoCustomEnum2({ Assets: {} });
21334
- }
21335
- throw new Error(`Unknown VesuAmountDenomination: ${denomination}`);
21336
- }
21337
- getVesuSingletonContract(config) {
21338
- return new Contract8({ abi: vesu_singleton_abi_default, address: this.VESU_SINGLETON.address, providerOrAccount: config.provider });
21339
- }
21340
- async getLTVConfig(config) {
21341
- const CACHE_KEY = "ltv_config";
21342
- const cacheData = this.getCache(CACHE_KEY);
21343
- if (cacheData) {
21344
- return cacheData;
21345
- }
21346
- const output = await this.getVesuSingletonContract(config).call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address]);
21331
+ ]
21332
+ },
21333
+ {
21334
+ type: "struct",
21335
+ name: "core::integer::u256",
21336
+ members: [
21337
+ {
21338
+ name: "low",
21339
+ type: "core::integer::u128"
21340
+ },
21341
+ {
21342
+ name: "high",
21343
+ type: "core::integer::u128"
21344
+ }
21345
+ ]
21346
+ },
21347
+ {
21348
+ type: "struct",
21349
+ name: "vesu_periphery::swap::RouteNode",
21350
+ members: [
21351
+ {
21352
+ name: "pool_key",
21353
+ type: "ekubo::types::keys::PoolKey"
21354
+ },
21355
+ {
21356
+ name: "sqrt_ratio_limit",
21357
+ type: "core::integer::u256"
21358
+ },
21359
+ {
21360
+ name: "skip_ahead",
21361
+ type: "core::integer::u128"
21362
+ }
21363
+ ]
21364
+ },
21365
+ {
21366
+ type: "enum",
21367
+ name: "core::bool",
21368
+ variants: [
21369
+ {
21370
+ name: "False",
21371
+ type: "()"
21372
+ },
21373
+ {
21374
+ name: "True",
21375
+ type: "()"
21376
+ }
21377
+ ]
21378
+ },
21379
+ {
21380
+ type: "struct",
21381
+ name: "ekubo::types::i129::i129",
21382
+ members: [
21383
+ {
21384
+ name: "mag",
21385
+ type: "core::integer::u128"
21386
+ },
21387
+ {
21388
+ name: "sign",
21389
+ type: "core::bool"
21390
+ }
21391
+ ]
21392
+ },
21393
+ {
21394
+ type: "struct",
21395
+ name: "vesu_periphery::swap::TokenAmount",
21396
+ members: [
21397
+ {
21398
+ name: "token",
21399
+ type: "core::starknet::contract_address::ContractAddress"
21400
+ },
21401
+ {
21402
+ name: "amount",
21403
+ type: "ekubo::types::i129::i129"
21404
+ }
21405
+ ]
21406
+ },
21407
+ {
21408
+ type: "struct",
21409
+ name: "vesu_periphery::swap::Swap",
21410
+ members: [
21411
+ {
21412
+ name: "route",
21413
+ type: "core::array::Array::<vesu_periphery::swap::RouteNode>"
21414
+ },
21415
+ {
21416
+ name: "token_amount",
21417
+ type: "vesu_periphery::swap::TokenAmount"
21418
+ }
21419
+ ]
21420
+ },
21421
+ {
21422
+ type: "struct",
21423
+ name: "vesu_periphery::multiply::IncreaseLeverParams",
21424
+ members: [
21425
+ {
21426
+ name: "pool_id",
21427
+ type: "core::felt252"
21428
+ },
21429
+ {
21430
+ name: "collateral_asset",
21431
+ type: "core::starknet::contract_address::ContractAddress"
21432
+ },
21433
+ {
21434
+ name: "debt_asset",
21435
+ type: "core::starknet::contract_address::ContractAddress"
21436
+ },
21437
+ {
21438
+ name: "user",
21439
+ type: "core::starknet::contract_address::ContractAddress"
21440
+ },
21441
+ {
21442
+ name: "add_margin",
21443
+ type: "core::integer::u128"
21444
+ },
21445
+ {
21446
+ name: "margin_swap",
21447
+ type: "core::array::Array::<vesu_periphery::swap::Swap>"
21448
+ },
21449
+ {
21450
+ name: "margin_swap_limit_amount",
21451
+ type: "core::integer::u128"
21452
+ },
21453
+ {
21454
+ name: "lever_swap",
21455
+ type: "core::array::Array::<vesu_periphery::swap::Swap>"
21456
+ },
21457
+ {
21458
+ name: "lever_swap_limit_amount",
21459
+ type: "core::integer::u128"
21460
+ }
21461
+ ]
21462
+ },
21463
+ {
21464
+ type: "struct",
21465
+ name: "vesu_periphery::multiply::DecreaseLeverParams",
21466
+ members: [
21467
+ {
21468
+ name: "pool_id",
21469
+ type: "core::felt252"
21470
+ },
21471
+ {
21472
+ name: "collateral_asset",
21473
+ type: "core::starknet::contract_address::ContractAddress"
21474
+ },
21475
+ {
21476
+ name: "debt_asset",
21477
+ type: "core::starknet::contract_address::ContractAddress"
21478
+ },
21479
+ {
21480
+ name: "user",
21481
+ type: "core::starknet::contract_address::ContractAddress"
21482
+ },
21483
+ {
21484
+ name: "sub_margin",
21485
+ type: "core::integer::u128"
21486
+ },
21487
+ {
21488
+ name: "recipient",
21489
+ type: "core::starknet::contract_address::ContractAddress"
21490
+ },
21491
+ {
21492
+ name: "lever_swap",
21493
+ type: "core::array::Array::<vesu_periphery::swap::Swap>"
21494
+ },
21495
+ {
21496
+ name: "lever_swap_limit_amount",
21497
+ type: "core::integer::u128"
21498
+ },
21499
+ {
21500
+ name: "lever_swap_weights",
21501
+ type: "core::array::Array::<core::integer::u128>"
21502
+ },
21503
+ {
21504
+ name: "withdraw_swap",
21505
+ type: "core::array::Array::<vesu_periphery::swap::Swap>"
21506
+ },
21507
+ {
21508
+ name: "withdraw_swap_limit_amount",
21509
+ type: "core::integer::u128"
21510
+ },
21511
+ {
21512
+ name: "withdraw_swap_weights",
21513
+ type: "core::array::Array::<core::integer::u128>"
21514
+ },
21515
+ {
21516
+ name: "close_position",
21517
+ type: "core::bool"
21518
+ }
21519
+ ]
21520
+ },
21521
+ {
21522
+ type: "enum",
21523
+ name: "vesu_periphery::multiply::ModifyLeverAction",
21524
+ variants: [
21525
+ {
21526
+ name: "IncreaseLever",
21527
+ type: "vesu_periphery::multiply::IncreaseLeverParams"
21528
+ },
21529
+ {
21530
+ name: "DecreaseLever",
21531
+ type: "vesu_periphery::multiply::DecreaseLeverParams"
21532
+ }
21533
+ ]
21534
+ },
21535
+ {
21536
+ type: "struct",
21537
+ name: "vesu_periphery::multiply::ModifyLeverParams",
21538
+ members: [
21539
+ {
21540
+ name: "action",
21541
+ type: "vesu_periphery::multiply::ModifyLeverAction"
21542
+ }
21543
+ ]
21544
+ },
21545
+ {
21546
+ type: "struct",
21547
+ name: "alexandria_math::i257::i257",
21548
+ members: [
21549
+ {
21550
+ name: "abs",
21551
+ type: "core::integer::u256"
21552
+ },
21553
+ {
21554
+ name: "is_negative",
21555
+ type: "core::bool"
21556
+ }
21557
+ ]
21558
+ },
21559
+ {
21560
+ type: "struct",
21561
+ name: "vesu_periphery::multiply::ModifyLeverResponse",
21562
+ members: [
21563
+ {
21564
+ name: "collateral_delta",
21565
+ type: "alexandria_math::i257::i257"
21566
+ },
21567
+ {
21568
+ name: "debt_delta",
21569
+ type: "alexandria_math::i257::i257"
21570
+ },
21571
+ {
21572
+ name: "margin_delta",
21573
+ type: "alexandria_math::i257::i257"
21574
+ }
21575
+ ]
21576
+ },
21577
+ {
21578
+ type: "interface",
21579
+ name: "vesu_periphery::multiply::IMultiply",
21580
+ items: [
21581
+ {
21582
+ type: "function",
21583
+ name: "modify_lever",
21584
+ inputs: [
21585
+ {
21586
+ name: "modify_lever_params",
21587
+ type: "vesu_periphery::multiply::ModifyLeverParams"
21588
+ }
21589
+ ],
21590
+ outputs: [
21591
+ {
21592
+ type: "vesu_periphery::multiply::ModifyLeverResponse"
21593
+ }
21594
+ ],
21595
+ state_mutability: "external"
21596
+ }
21597
+ ]
21598
+ },
21599
+ {
21600
+ type: "struct",
21601
+ name: "ekubo::interfaces::core::ICoreDispatcher",
21602
+ members: [
21603
+ {
21604
+ name: "contract_address",
21605
+ type: "core::starknet::contract_address::ContractAddress"
21606
+ }
21607
+ ]
21608
+ },
21609
+ {
21610
+ type: "struct",
21611
+ name: "vesu::singleton::ISingletonDispatcher",
21612
+ members: [
21613
+ {
21614
+ name: "contract_address",
21615
+ type: "core::starknet::contract_address::ContractAddress"
21616
+ }
21617
+ ]
21618
+ },
21619
+ {
21620
+ type: "constructor",
21621
+ name: "constructor",
21622
+ inputs: [
21623
+ {
21624
+ name: "core",
21625
+ type: "ekubo::interfaces::core::ICoreDispatcher"
21626
+ },
21627
+ {
21628
+ name: "singleton",
21629
+ type: "vesu::singleton::ISingletonDispatcher"
21630
+ }
21631
+ ]
21632
+ },
21633
+ {
21634
+ type: "event",
21635
+ name: "vesu_periphery::multiply::Multiply::IncreaseLever",
21636
+ kind: "struct",
21637
+ members: [
21638
+ {
21639
+ name: "pool_id",
21640
+ type: "core::felt252",
21641
+ kind: "key"
21642
+ },
21643
+ {
21644
+ name: "collateral_asset",
21645
+ type: "core::starknet::contract_address::ContractAddress",
21646
+ kind: "key"
21647
+ },
21648
+ {
21649
+ name: "debt_asset",
21650
+ type: "core::starknet::contract_address::ContractAddress",
21651
+ kind: "key"
21652
+ },
21653
+ {
21654
+ name: "user",
21655
+ type: "core::starknet::contract_address::ContractAddress",
21656
+ kind: "key"
21657
+ },
21658
+ {
21659
+ name: "margin",
21660
+ type: "core::integer::u256",
21661
+ kind: "data"
21662
+ },
21663
+ {
21664
+ name: "collateral_delta",
21665
+ type: "core::integer::u256",
21666
+ kind: "data"
21667
+ },
21668
+ {
21669
+ name: "debt_delta",
21670
+ type: "core::integer::u256",
21671
+ kind: "data"
21672
+ }
21673
+ ]
21674
+ },
21675
+ {
21676
+ type: "event",
21677
+ name: "vesu_periphery::multiply::Multiply::DecreaseLever",
21678
+ kind: "struct",
21679
+ members: [
21680
+ {
21681
+ name: "pool_id",
21682
+ type: "core::felt252",
21683
+ kind: "key"
21684
+ },
21685
+ {
21686
+ name: "collateral_asset",
21687
+ type: "core::starknet::contract_address::ContractAddress",
21688
+ kind: "key"
21689
+ },
21690
+ {
21691
+ name: "debt_asset",
21692
+ type: "core::starknet::contract_address::ContractAddress",
21693
+ kind: "key"
21694
+ },
21695
+ {
21696
+ name: "user",
21697
+ type: "core::starknet::contract_address::ContractAddress",
21698
+ kind: "key"
21699
+ },
21700
+ {
21701
+ name: "margin",
21702
+ type: "core::integer::u256",
21703
+ kind: "data"
21704
+ },
21705
+ {
21706
+ name: "collateral_delta",
21707
+ type: "core::integer::u256",
21708
+ kind: "data"
21709
+ },
21710
+ {
21711
+ name: "debt_delta",
21712
+ type: "core::integer::u256",
21713
+ kind: "data"
21714
+ }
21715
+ ]
21716
+ },
21717
+ {
21718
+ type: "event",
21719
+ name: "vesu_periphery::multiply::Multiply::Event",
21720
+ kind: "enum",
21721
+ variants: [
21722
+ {
21723
+ name: "IncreaseLever",
21724
+ type: "vesu_periphery::multiply::Multiply::IncreaseLever",
21725
+ kind: "nested"
21726
+ },
21727
+ {
21728
+ name: "DecreaseLever",
21729
+ type: "vesu_periphery::multiply::Multiply::DecreaseLever",
21730
+ kind: "nested"
21731
+ }
21732
+ ]
21733
+ }
21734
+ ];
21735
+
21736
+ // src/strategies/universal-adapters/vesu-adapter.ts
21737
+ var VesuAmountType = /* @__PURE__ */ ((VesuAmountType2) => {
21738
+ VesuAmountType2[VesuAmountType2["Delta"] = 0] = "Delta";
21739
+ VesuAmountType2[VesuAmountType2["Target"] = 1] = "Target";
21740
+ return VesuAmountType2;
21741
+ })(VesuAmountType || {});
21742
+ var VesuAmountDenomination = /* @__PURE__ */ ((VesuAmountDenomination2) => {
21743
+ VesuAmountDenomination2[VesuAmountDenomination2["Native"] = 0] = "Native";
21744
+ VesuAmountDenomination2[VesuAmountDenomination2["Assets"] = 1] = "Assets";
21745
+ return VesuAmountDenomination2;
21746
+ })(VesuAmountDenomination || {});
21747
+ function getVesuMultiplyParams(isIncrease, params) {
21748
+ if (isIncrease) {
21749
+ const _params2 = params;
21750
+ return {
21751
+ action: new CairoCustomEnum2({ IncreaseLever: {
21752
+ pool_id: _params2.pool_id.toBigInt(),
21753
+ collateral_asset: _params2.collateral_asset.toBigInt(),
21754
+ debt_asset: _params2.debt_asset.toBigInt(),
21755
+ user: _params2.user.toBigInt(),
21756
+ add_margin: BigInt(_params2.add_margin.toWei()),
21757
+ margin_swap: _params2.margin_swap.map((swap) => ({
21758
+ route: swap.route.map((route) => ({
21759
+ pool_key: {
21760
+ token0: route.pool_key.token0.toBigInt(),
21761
+ token1: route.pool_key.token1.toBigInt(),
21762
+ fee: route.pool_key.fee,
21763
+ tick_spacing: route.pool_key.tick_spacing,
21764
+ extension: BigInt(num8.hexToDecimalString(route.pool_key.extension))
21765
+ },
21766
+ sqrt_ratio_limit: uint2567.bnToUint256(route.sqrt_ratio_limit.toWei()),
21767
+ skip_ahead: BigInt(100)
21768
+ })),
21769
+ token_amount: {
21770
+ token: swap.token_amount.token.toBigInt(),
21771
+ amount: swap.token_amount.amount.toI129()
21772
+ }
21773
+ })),
21774
+ margin_swap_limit_amount: BigInt(_params2.margin_swap_limit_amount.toWei()),
21775
+ lever_swap: _params2.lever_swap.map((swap) => ({
21776
+ route: swap.route.map((route) => ({
21777
+ pool_key: {
21778
+ token0: route.pool_key.token0.toBigInt(),
21779
+ token1: route.pool_key.token1.toBigInt(),
21780
+ fee: route.pool_key.fee,
21781
+ tick_spacing: route.pool_key.tick_spacing,
21782
+ extension: BigInt(num8.hexToDecimalString(route.pool_key.extension))
21783
+ },
21784
+ sqrt_ratio_limit: uint2567.bnToUint256(route.sqrt_ratio_limit.toWei()),
21785
+ skip_ahead: BigInt(100)
21786
+ })),
21787
+ token_amount: {
21788
+ token: swap.token_amount.token.toBigInt(),
21789
+ amount: swap.token_amount.amount.toI129()
21790
+ }
21791
+ })),
21792
+ lever_swap_limit_amount: BigInt(_params2.lever_swap_limit_amount.toWei())
21793
+ } })
21794
+ };
21795
+ }
21796
+ const _params = params;
21797
+ return {
21798
+ action: new CairoCustomEnum2({ DecreaseLever: {
21799
+ pool_id: _params.pool_id.toBigInt(),
21800
+ collateral_asset: _params.collateral_asset.toBigInt(),
21801
+ debt_asset: _params.debt_asset.toBigInt(),
21802
+ user: _params.user.toBigInt(),
21803
+ sub_margin: BigInt(_params.sub_margin.toWei()),
21804
+ recipient: _params.recipient.toBigInt(),
21805
+ lever_swap: _params.lever_swap.map((swap) => ({
21806
+ route: swap.route.map((route) => ({
21807
+ pool_key: {
21808
+ token0: route.pool_key.token0.toBigInt(),
21809
+ token1: route.pool_key.token1.toBigInt(),
21810
+ fee: route.pool_key.fee,
21811
+ tick_spacing: route.pool_key.tick_spacing,
21812
+ extension: ContractAddr.from(route.pool_key.extension).toBigInt()
21813
+ },
21814
+ sqrt_ratio_limit: uint2567.bnToUint256(route.sqrt_ratio_limit.toWei()),
21815
+ skip_ahead: BigInt(route.skip_ahead.toWei())
21816
+ })),
21817
+ token_amount: {
21818
+ token: swap.token_amount.token.toBigInt(),
21819
+ amount: swap.token_amount.amount.toI129()
21820
+ }
21821
+ })),
21822
+ lever_swap_limit_amount: BigInt(_params.lever_swap_limit_amount.toWei()),
21823
+ lever_swap_weights: _params.lever_swap_weights.map((weight) => BigInt(weight.toWei())),
21824
+ withdraw_swap: _params.withdraw_swap.map((swap) => ({
21825
+ route: swap.route.map((route) => ({
21826
+ pool_key: {
21827
+ token0: route.pool_key.token0.toBigInt(),
21828
+ token1: route.pool_key.token1.toBigInt(),
21829
+ fee: route.pool_key.fee,
21830
+ tick_spacing: route.pool_key.tick_spacing,
21831
+ extension: ContractAddr.from(route.pool_key.extension).toBigInt()
21832
+ },
21833
+ sqrt_ratio_limit: uint2567.bnToUint256(route.sqrt_ratio_limit.toWei()),
21834
+ skip_ahead: BigInt(route.skip_ahead.toWei())
21835
+ })),
21836
+ token_amount: {
21837
+ token: swap.token_amount.token.toBigInt(),
21838
+ amount: swap.token_amount.amount.toI129()
21839
+ }
21840
+ })),
21841
+ withdraw_swap_limit_amount: BigInt(_params.withdraw_swap_limit_amount.toWei()),
21842
+ withdraw_swap_weights: _params.withdraw_swap_weights.map((weight) => BigInt(weight.toWei())),
21843
+ close_position: _params.close_position
21844
+ } })
21845
+ };
21846
+ }
21847
+ var VesuPools = {
21848
+ Genesis: ContractAddr.from("0x4dc4f0ca6ea4961e4c8373265bfd5317678f4fe374d76f3fd7135f57763bf28"),
21849
+ Re7xSTRK: ContractAddr.from("0x052fb52363939c3aa848f8f4ac28f0a51379f8d1b971d8444de25fbd77d8f161")
21850
+ };
21851
+ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
21852
+ constructor(config) {
21853
+ super();
21854
+ this.VESU_SINGLETON = ContractAddr.from("0x000d8d6dfec4d33bfb6895de9f3852143a17c6f92fd2a21da3d6924d34870160");
21855
+ this.VESU_MULTIPLY = ContractAddr.from("0x3630f1f8e5b8f5c4c4ae9b6620f8a570ae55cddebc0276c37550e7c118edf67");
21856
+ this.getModifyPosition = () => {
21857
+ const positionData = [0n];
21858
+ const packedArguments = [
21859
+ toBigInt(this.config.poolId.toString()),
21860
+ // pool id
21861
+ toBigInt(this.config.collateral.address.toString()),
21862
+ // collateral
21863
+ toBigInt(this.config.debt.address.toString()),
21864
+ // debt
21865
+ toBigInt(this.config.vaultAllocator.toString()),
21866
+ // vault allocator
21867
+ toBigInt(positionData.length),
21868
+ ...positionData
21869
+ ];
21870
+ const output = this.constructSimpleLeafData({
21871
+ id: this.config.id,
21872
+ target: this.VESU_SINGLETON,
21873
+ method: "modify_position",
21874
+ packedArguments
21875
+ });
21876
+ return { leaf: output, callConstructor: this.getModifyPositionCall.bind(this) };
21877
+ };
21878
+ this.getModifyPositionCall = (params) => {
21879
+ const _collateral = {
21880
+ amount_type: this.formatAmountTypeEnum(params.collateralAmount.amount_type),
21881
+ denomination: this.formatAmountDenominationEnum(params.collateralAmount.denomination),
21882
+ value: {
21883
+ abs: uint2567.bnToUint256(params.collateralAmount.value.abs.toWei()),
21884
+ is_negative: params.collateralAmount.value.abs.isZero() ? false : params.collateralAmount.value.is_negative
21885
+ }
21886
+ };
21887
+ logger.verbose(`VesuAdapter::ConstructingModify::Collateral::${JSON.stringify(_collateral)}`);
21888
+ const _debt = {
21889
+ amount_type: this.formatAmountTypeEnum(params.debtAmount.amount_type),
21890
+ denomination: this.formatAmountDenominationEnum(params.debtAmount.denomination),
21891
+ value: {
21892
+ abs: uint2567.bnToUint256(params.debtAmount.value.abs.toWei()),
21893
+ is_negative: params.debtAmount.value.abs.isZero() ? false : params.debtAmount.value.is_negative
21894
+ }
21895
+ };
21896
+ logger.verbose(`VesuAdapter::ConstructingModify::Debt::${JSON.stringify(_debt)}`);
21897
+ const singletonContract = new Contract8({ abi: vesu_singleton_abi_default, address: this.VESU_SINGLETON.toString(), providerOrAccount: new RpcProvider4({ nodeUrl: "" }) });
21898
+ const call = singletonContract.populate("modify_position", {
21899
+ params: {
21900
+ pool_id: this.config.poolId.toBigInt(),
21901
+ collateral_asset: this.config.collateral.address.toBigInt(),
21902
+ debt_asset: this.config.debt.address.toBigInt(),
21903
+ user: this.config.vaultAllocator.toBigInt(),
21904
+ collateral: _collateral,
21905
+ debt: _debt,
21906
+ data: [0]
21907
+ }
21908
+ });
21909
+ return {
21910
+ sanitizer: SIMPLE_SANITIZER,
21911
+ call: {
21912
+ contractAddress: this.VESU_SINGLETON,
21913
+ selector: hash3.getSelectorFromName("modify_position"),
21914
+ calldata: [
21915
+ ...call.calldata
21916
+ ]
21917
+ }
21918
+ };
21919
+ };
21920
+ this.getMultiplyAdapter = () => {
21921
+ const packedArguments = [
21922
+ toBigInt(this.config.poolId.toString()),
21923
+ // pool id
21924
+ toBigInt(this.config.collateral.address.toString()),
21925
+ // collateral
21926
+ toBigInt(this.config.debt.address.toString()),
21927
+ // debt
21928
+ toBigInt(this.config.vaultAllocator.toString())
21929
+ // vault allocator
21930
+ ];
21931
+ const output = this.constructSimpleLeafData({
21932
+ id: this.config.id,
21933
+ target: this.VESU_MULTIPLY,
21934
+ method: "modify_lever",
21935
+ packedArguments
21936
+ }, SIMPLE_SANITIZER_V2);
21937
+ return { leaf: output, callConstructor: this.getMultiplyCall.bind(this) };
21938
+ };
21939
+ this.getMultiplyCall = (params) => {
21940
+ const isIncrease = params.isIncrease;
21941
+ const multiplyParams = isIncrease ? params.increaseParams : params.decreaseParams;
21942
+ if (!multiplyParams) {
21943
+ throw new Error("Multiply params are not provided");
21944
+ }
21945
+ const multiplyContract = new Contract8({ abi: vesu_multiple_abi_default, address: this.VESU_MULTIPLY.toString(), providerOrAccount: new RpcProvider4({ nodeUrl: "" }) });
21946
+ const call = multiplyContract.populate("modify_lever", {
21947
+ modify_lever_params: getVesuMultiplyParams(isIncrease, {
21948
+ ...multiplyParams,
21949
+ user: this.config.vaultAllocator,
21950
+ pool_id: this.config.poolId,
21951
+ collateral_asset: this.config.collateral.address,
21952
+ debt_asset: this.config.debt.address,
21953
+ recipient: this.config.vaultAllocator
21954
+ })
21955
+ });
21956
+ return {
21957
+ sanitizer: SIMPLE_SANITIZER_V2,
21958
+ call: {
21959
+ contractAddress: this.VESU_MULTIPLY,
21960
+ selector: hash3.getSelectorFromName("modify_lever"),
21961
+ calldata: [
21962
+ ...call.calldata
21963
+ ]
21964
+ }
21965
+ };
21966
+ };
21967
+ this.getVesuModifyDelegationAdapter = (id) => {
21968
+ return () => {
21969
+ const packedArguments = [
21970
+ toBigInt(this.config.poolId.toString()),
21971
+ // pool id
21972
+ toBigInt(this.VESU_MULTIPLY.toString())
21973
+ // vault allocator
21974
+ ];
21975
+ const output = this.constructSimpleLeafData({
21976
+ id,
21977
+ target: this.VESU_SINGLETON,
21978
+ method: "modify_delegation",
21979
+ packedArguments
21980
+ }, SIMPLE_SANITIZER_V2);
21981
+ return { leaf: output, callConstructor: this.getVesuModifyDelegationCall.bind(this) };
21982
+ };
21983
+ };
21984
+ this.getVesuModifyDelegationCall = (params) => {
21985
+ const singletonContract = new Contract8({ abi: vesu_singleton_abi_default, address: this.VESU_SINGLETON.toString(), providerOrAccount: new RpcProvider4({ nodeUrl: "" }) });
21986
+ const call = singletonContract.populate("modify_delegation", {
21987
+ pool_id: this.config.poolId.toBigInt(),
21988
+ delegatee: this.VESU_MULTIPLY.toBigInt(),
21989
+ delegation: params.delegation
21990
+ });
21991
+ return {
21992
+ sanitizer: SIMPLE_SANITIZER_V2,
21993
+ call: {
21994
+ contractAddress: this.VESU_SINGLETON,
21995
+ selector: hash3.getSelectorFromName("modify_delegation"),
21996
+ calldata: [
21997
+ ...call.calldata
21998
+ ]
21999
+ }
22000
+ };
22001
+ };
22002
+ this.getDefispringRewardsAdapter = (id) => {
22003
+ return () => {
22004
+ const packedArguments = [];
22005
+ const output = {
22006
+ id: BigInt(num8.getDecimalString(shortString3.encodeShortString(id))),
22007
+ readableId: id,
22008
+ data: [
22009
+ SIMPLE_SANITIZER.toBigInt(),
22010
+ // sanitizer address
22011
+ VESU_REWARDS_CONTRACT.toBigInt(),
22012
+ // contract
22013
+ toBigInt(hash3.getSelectorFromName("claim")),
22014
+ // method name
22015
+ BigInt(packedArguments.length),
22016
+ ...packedArguments
22017
+ ]
22018
+ };
22019
+ return { leaf: output, callConstructor: this.getDefiSpringClaimCall().bind(this) };
22020
+ };
22021
+ };
22022
+ this.getDefiSpringClaimCall = () => {
22023
+ return (params) => ({
22024
+ sanitizer: SIMPLE_SANITIZER,
22025
+ call: {
22026
+ contractAddress: VESU_REWARDS_CONTRACT,
22027
+ selector: hash3.getSelectorFromName("claim"),
22028
+ calldata: [
22029
+ BigInt(params.amount.toWei()),
22030
+ BigInt(params.proofs.length),
22031
+ ...params.proofs.map((proof) => BigInt(num8.hexToDecimalString(proof)))
22032
+ ]
22033
+ }
22034
+ });
22035
+ };
22036
+ this.config = config;
22037
+ }
22038
+ static getDefaultModifyPositionCallParams(params) {
22039
+ return {
22040
+ collateralAmount: {
22041
+ amount_type: 0 /* Delta */,
22042
+ denomination: 1 /* Assets */,
22043
+ value: {
22044
+ abs: params.collateralAmount,
22045
+ is_negative: !params.isAddCollateral
22046
+ }
22047
+ },
22048
+ debtAmount: {
22049
+ amount_type: 0 /* Delta */,
22050
+ denomination: 1 /* Assets */,
22051
+ value: {
22052
+ abs: params.debtAmount,
22053
+ is_negative: !params.isBorrow
22054
+ }
22055
+ }
22056
+ };
22057
+ }
22058
+ formatAmountTypeEnum(amountType) {
22059
+ switch (amountType) {
22060
+ case 0 /* Delta */:
22061
+ return new CairoCustomEnum2({ Delta: {} });
22062
+ case 1 /* Target */:
22063
+ return new CairoCustomEnum2({ Target: {} });
22064
+ }
22065
+ throw new Error(`Unknown VesuAmountType: ${amountType}`);
22066
+ }
22067
+ formatAmountDenominationEnum(denomination) {
22068
+ switch (denomination) {
22069
+ case 0 /* Native */:
22070
+ return new CairoCustomEnum2({ Native: {} });
22071
+ case 1 /* Assets */:
22072
+ return new CairoCustomEnum2({ Assets: {} });
22073
+ }
22074
+ throw new Error(`Unknown VesuAmountDenomination: ${denomination}`);
22075
+ }
22076
+ getVesuSingletonContract(config) {
22077
+ return new Contract8({ abi: vesu_singleton_abi_default, address: this.VESU_SINGLETON.address, providerOrAccount: config.provider });
22078
+ }
22079
+ async getLTVConfig(config) {
22080
+ const CACHE_KEY = "ltv_config";
22081
+ const cacheData = this.getCache(CACHE_KEY);
22082
+ if (cacheData) {
22083
+ return cacheData;
22084
+ }
22085
+ const output = await this.getVesuSingletonContract(config).call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address]);
21347
22086
  this.setCache(CACHE_KEY, Number(output.max_ltv) / 1e18, 3e5);
21348
22087
  return this.getCache(CACHE_KEY);
21349
22088
  }
@@ -23683,10 +24422,10 @@ var vault_manager_abi_default = [
23683
24422
 
23684
24423
  // src/strategies/universal-strategy.tsx
23685
24424
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
23686
- var AUMTypes = /* @__PURE__ */ ((AUMTypes2) => {
23687
- AUMTypes2["FINALISED"] = "finalised";
23688
- AUMTypes2["DEFISPRING"] = "defispring";
23689
- return AUMTypes2;
24425
+ var AUMTypes = /* @__PURE__ */ ((AUMTypes3) => {
24426
+ AUMTypes3["FINALISED"] = "finalised";
24427
+ AUMTypes3["DEFISPRING"] = "defispring";
24428
+ return AUMTypes3;
23690
24429
  })(AUMTypes || {});
23691
24430
  var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
23692
24431
  constructor(config, pricer, metadata) {
@@ -23814,24 +24553,42 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
23814
24553
  * @returns {Promise<number>} The weighted average APY across all pools
23815
24554
  */
23816
24555
  async netAPY() {
23817
- const [vesuAdapter1, vesuAdapter2] = this.getVesuAdapters();
23818
- const pools = await VesuAdapter.getVesuPools();
23819
- const pool1 = pools.pools.find((p) => vesuAdapter1.config.poolId.eqString(num9.getHexString(p.id)));
23820
- const pool2 = pools.pools.find((p) => vesuAdapter2.config.poolId.eqString(num9.getHexString(p.id)));
23821
- if (!pool1 || !pool2) {
24556
+ if (this.metadata.isPreview) {
24557
+ return { net: 0, splits: [{
24558
+ apy: 0,
24559
+ id: "base"
24560
+ }, {
24561
+ apy: 0,
24562
+ id: "defispring"
24563
+ }] };
24564
+ }
24565
+ const prevAUM = await this.getPrevAUM();
24566
+ const vesuAdapters = this.getVesuAdapters();
24567
+ const allVesuPools = await VesuAdapter.getVesuPools();
24568
+ const pools = vesuAdapters.map((vesuAdapter) => {
24569
+ return allVesuPools.pools.find((p) => vesuAdapter.config.poolId.eqString(num9.getHexString(p.id)));
24570
+ });
24571
+ logger.verbose(`${this.metadata.name}::netAPY: vesu-pools: ${JSON.stringify(pools)}`);
24572
+ if (pools.some((p) => !p)) {
23822
24573
  throw new Error("Pool not found");
23823
24574
  }
23824
24575
  ;
23825
- const collateralAsset1 = pool1.assets.find((a) => a.symbol === vesuAdapter1.config.collateral.symbol)?.stats;
23826
- const debtAsset1 = pool1.assets.find((a) => a.symbol === vesuAdapter1.config.debt.symbol)?.stats;
23827
- const collateralAsset2 = pool2.assets.find((a) => a.symbol === vesuAdapter2.config.collateral.symbol)?.stats;
23828
- const debtAsset2 = pool2.assets.find((a) => a.symbol === vesuAdapter2.config.debt.symbol)?.stats;
23829
- const collateral1APY = Number(collateralAsset1.supplyApy.value) / 1e18;
23830
- const debt1APY = Number(debtAsset1.borrowApr.value) / 1e18;
23831
- const collateral2APY = Number(collateralAsset2.supplyApy.value) / 1e18;
23832
- const debt2APY = Number(debtAsset2.borrowApr.value) / 1e18;
23833
- const positions = await this.getVaultPositions();
24576
+ const positions = await this.getVesuPositions();
23834
24577
  logger.verbose(`${this.metadata.name}::netAPY: positions: ${JSON.stringify(positions)}`);
24578
+ const baseAPYs = [];
24579
+ const rewardAPYs = [];
24580
+ for (const [index, pool] of pools.entries()) {
24581
+ const vesuAdapter = vesuAdapters[index];
24582
+ const collateralAsset = pool.assets.find((a) => a.symbol === vesuAdapter.config.collateral.symbol)?.stats;
24583
+ const debtAsset = pool.assets.find((a) => a.symbol === vesuAdapter.config.debt.symbol)?.stats;
24584
+ const supplyApy = Number(collateralAsset.supplyApy.value || 0) / 1e18;
24585
+ const lstAPY = Number(collateralAsset.lstApr?.value || 0) / 1e18;
24586
+ baseAPYs.push(...[supplyApy + lstAPY, Number(debtAsset.borrowApr.value) / 1e18]);
24587
+ rewardAPYs.push(...[Number(collateralAsset.defiSpringSupplyApr.value || "0") / 1e18, 0]);
24588
+ }
24589
+ logger.verbose(`${this.metadata.name}::netAPY: baseAPYs: ${JSON.stringify(baseAPYs)}`);
24590
+ logger.verbose(`${this.metadata.name}::netAPY: rewardAPYs: ${JSON.stringify(rewardAPYs)}`);
24591
+ assert(baseAPYs.length == positions.length, "APYs and positions length mismatch");
23835
24592
  if (positions.every((p) => p.amount.isZero())) {
23836
24593
  return { net: 0, splits: [{
23837
24594
  apy: 0,
@@ -23842,11 +24599,10 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
23842
24599
  }] };
23843
24600
  }
23844
24601
  const weights = positions.map((p, index) => p.usdValue * (index % 2 == 0 ? 1 : -1));
23845
- const baseAPYs = [collateral1APY, debt1APY, collateral2APY, debt2APY];
23846
- assert(positions.length == baseAPYs.length, "Positions and APYs length mismatch");
23847
- const rewardAPYs = [Number(collateralAsset1.defiSpringSupplyApr.value) / 1e18, 0, Number(collateralAsset2.defiSpringSupplyApr.value) / 1e18, 0];
23848
- const baseAPY = this.computeAPY(baseAPYs, weights);
23849
- const rewardAPY = this.computeAPY(rewardAPYs, weights);
24602
+ const price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
24603
+ const prevAUMUSD = prevAUM.multipliedBy(price.price);
24604
+ const baseAPY = this.computeAPY(baseAPYs, weights, prevAUMUSD);
24605
+ const rewardAPY = this.computeAPY(rewardAPYs, weights, prevAUMUSD);
23850
24606
  const netAPY = baseAPY + rewardAPY;
23851
24607
  logger.verbose(`${this.metadata.name}::netAPY: net: ${netAPY}, baseAPY: ${baseAPY}, rewardAPY: ${rewardAPY}`);
23852
24608
  return { net: netAPY, splits: [{
@@ -23857,11 +24613,11 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
23857
24613
  id: "defispring"
23858
24614
  }] };
23859
24615
  }
23860
- computeAPY(apys, weights) {
24616
+ computeAPY(apys, weights, currentAUM) {
23861
24617
  assert(apys.length === weights.length, "APYs and weights length mismatch");
23862
24618
  const weightedSum = apys.reduce((acc, apy, i) => acc + apy * weights[i], 0);
23863
- const totalWeight = weights.reduce((acc, weight) => acc + weight, 0);
23864
- return weightedSum / totalWeight;
24619
+ logger.verbose(`${this.getTag()} computeAPY: apys: ${JSON.stringify(apys)}, weights: ${JSON.stringify(weights)}, weightedSum: ${weightedSum}, currentAUM: ${currentAUM}`);
24620
+ return weightedSum / currentAUM.toNumber();
23865
24621
  }
23866
24622
  /**
23867
24623
  * Calculates the total TVL of the strategy.
@@ -23893,24 +24649,48 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
23893
24649
  usdValue
23894
24650
  };
23895
24651
  }
23896
- async getAUM() {
24652
+ async getVesuAUM(adapter) {
24653
+ const legAUM = await adapter.getPositions(this.config);
24654
+ const underlying = this.asset();
24655
+ let vesuAum = Web3Number.fromWei("0", underlying.decimals);
24656
+ if (legAUM[0].token.address.eq(underlying.address)) {
24657
+ vesuAum = vesuAum.plus(legAUM[0].amount);
24658
+ } else {
24659
+ const tokenPrice = await this.pricer.getPrice(legAUM[1].token.symbol);
24660
+ vesuAum = vesuAum.plus(legAUM[1].usdValue / tokenPrice.price);
24661
+ }
24662
+ if (legAUM[1].token.address.eq(underlying.address)) {
24663
+ vesuAum = vesuAum.minus(legAUM[1].amount);
24664
+ } else {
24665
+ const tokenPrice = await this.pricer.getPrice(legAUM[1].token.symbol);
24666
+ vesuAum = vesuAum.minus(legAUM[1].usdValue / tokenPrice.price);
24667
+ }
24668
+ ;
24669
+ logger.verbose(`${this.getTag()} Vesu AUM: ${vesuAum}, legCollateral: ${legAUM[0].amount.toNumber()}, legDebt: ${legAUM[1].amount.toNumber()}`);
24670
+ return vesuAum;
24671
+ }
24672
+ async getPrevAUM() {
23897
24673
  const currentAUM = await this.contract.call("aum", []);
23898
- const lastReportTime = await this.contract.call("last_report_timestamp", []);
24674
+ const prevAum = Web3Number.fromWei(currentAUM.toString(), this.asset().decimals);
24675
+ logger.verbose(`${this.getTag()} Prev AUM: ${prevAum}`);
24676
+ return prevAum;
24677
+ }
24678
+ async getAUM() {
24679
+ const prevAum = await this.getPrevAUM();
23899
24680
  const token1Price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
23900
- const [vesuAdapter1, vesuAdapter2] = this.getVesuAdapters();
23901
- const leg1AUM = await vesuAdapter1.getPositions(this.config);
23902
- const leg2AUM = await vesuAdapter2.getPositions(this.config);
24681
+ const vesuAdapters = this.getVesuAdapters();
24682
+ let vesuAum = Web3Number.fromWei("0", this.asset().decimals);
24683
+ for (const adapter of vesuAdapters) {
24684
+ vesuAum = vesuAum.plus(await this.getVesuAUM(adapter));
24685
+ }
23903
24686
  const balance = await this.getUnusedBalance();
23904
24687
  logger.verbose(`${this.getTag()} unused balance: ${balance.amount.toNumber()}`);
23905
- const vesuAum = leg1AUM[0].amount.plus(leg2AUM[0].usdValue / token1Price.price).minus(leg1AUM[1].usdValue / token1Price.price).minus(leg2AUM[1].amount);
23906
- logger.verbose(`${this.getTag()} Vesu AUM: leg1: ${leg1AUM[0].amount.toNumber()}, ${leg1AUM[1].amount.toNumber()}, leg2: ${leg2AUM[0].amount.toNumber()}, ${leg2AUM[1].amount.toNumber()}`);
23907
24688
  const zeroAmt = Web3Number.fromWei("0", this.asset().decimals);
23908
24689
  const net = {
23909
24690
  tokenInfo: this.asset(),
23910
24691
  amount: zeroAmt,
23911
24692
  usdValue: 0
23912
24693
  };
23913
- const prevAum = Web3Number.fromWei(currentAUM.toString(), this.asset().decimals);
23914
24694
  if (vesuAum.isZero()) {
23915
24695
  return { net, splits: [{
23916
24696
  aum: zeroAmt,
@@ -23922,16 +24702,7 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
23922
24702
  }
23923
24703
  const aumToken = vesuAum.plus(balance.amount);
23924
24704
  logger.verbose(`${this.getTag()} Actual AUM: ${aumToken}`);
23925
- const netAPY = await this.netAPY();
23926
- const defispringAPY = (netAPY.splits.find((s) => s.id === "defispring")?.apy || 0) * 0.8;
23927
- if (!defispringAPY) throw new Error("DefiSpring APY not found");
23928
- const timeDiff = Math.round(Date.now() / 1e3) - Number(lastReportTime);
23929
- const growthRate = timeDiff * defispringAPY / (365 * 24 * 60 * 60);
23930
- const rewardAssets = prevAum.multipliedBy(growthRate);
23931
- logger.verbose(`${this.getTag()} DefiSpring AUM time difference: ${timeDiff}`);
23932
- logger.verbose(`${this.getTag()} Current AUM: ${currentAUM}`);
23933
- logger.verbose(`${this.getTag()} Net APY: ${JSON.stringify(netAPY)}`);
23934
- logger.verbose(`${this.getTag()} rewards AUM: ${rewardAssets}`);
24705
+ const rewardAssets = await this.getRewardsAUM(prevAum);
23935
24706
  const newAUM = aumToken.plus(rewardAssets);
23936
24707
  logger.verbose(`${this.getTag()} New AUM: ${newAUM}`);
23937
24708
  net.amount = newAUM;
@@ -23945,6 +24716,21 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
23945
24716
  }];
23946
24717
  return { net, splits, prevAum };
23947
24718
  }
24719
+ // account for future rewards (e.g. defispring rewards)
24720
+ async getRewardsAUM(prevAum) {
24721
+ const lastReportTime = await this.contract.call("last_report_timestamp", []);
24722
+ const netAPY = await this.netAPY();
24723
+ const defispringAPY = (netAPY.splits.find((s) => s.id === "defispring")?.apy || 0) * 0.8;
24724
+ if (!defispringAPY) throw new Error("DefiSpring APY not found");
24725
+ const timeDiff = Math.round(Date.now() / 1e3) - Number(lastReportTime);
24726
+ const growthRate = timeDiff * defispringAPY / (365 * 24 * 60 * 60);
24727
+ const rewardAssets = prevAum.multipliedBy(growthRate);
24728
+ logger.verbose(`${this.getTag()} DefiSpring AUM time difference: ${timeDiff}`);
24729
+ logger.verbose(`${this.getTag()} Current AUM: ${prevAum.toString()}`);
24730
+ logger.verbose(`${this.getTag()} Net APY: ${JSON.stringify(netAPY)}`);
24731
+ logger.verbose(`${this.getTag()} rewards AUM: ${rewardAssets}`);
24732
+ return rewardAssets;
24733
+ }
23948
24734
  getVesuAdapters() {
23949
24735
  const vesuAdapter1 = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
23950
24736
  const vesuAdapter2 = this.getAdapter("vesu_leg2_adapter" /* VESU_LEG2 */);
@@ -23954,11 +24740,23 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
23954
24740
  vesuAdapter2.networkConfig = this.config;
23955
24741
  return [vesuAdapter1, vesuAdapter2];
23956
24742
  }
24743
+ async getVesuPositions() {
24744
+ const adapters = this.getVesuAdapters();
24745
+ const positions = [];
24746
+ for (const adapter of adapters) {
24747
+ positions.push(...await adapter.getPositions(this.config));
24748
+ }
24749
+ return positions;
24750
+ }
23957
24751
  async getVaultPositions() {
23958
- const [vesuAdapter1, vesuAdapter2] = this.getVesuAdapters();
23959
- const leg1Positions = await vesuAdapter1.getPositions(this.config);
23960
- const leg2Positions = await vesuAdapter2.getPositions(this.config);
23961
- return [...leg1Positions, ...leg2Positions];
24752
+ const vesuPositions = await this.getVesuPositions();
24753
+ const unusedBalance = await this.getUnusedBalance();
24754
+ return [...vesuPositions, {
24755
+ amount: unusedBalance.amount,
24756
+ usdValue: unusedBalance.usdValue,
24757
+ token: this.asset(),
24758
+ remarks: "Unused Balance"
24759
+ }];
23962
24760
  }
23963
24761
  getSetManagerCall(strategist, root = this.getMerkleRoot()) {
23964
24762
  return this.managerContract.populate("set_manage_root", [strategist.address, num9.getHexString(root)]);
@@ -24096,7 +24894,7 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
24096
24894
  return new Web3Number(newAmount.toFixed(8), debtTokenAmount.decimals);
24097
24895
  }
24098
24896
  }
24099
- async getVesuMultiplyCall(params) {
24897
+ async getVesuModifyPositionCall(params) {
24100
24898
  const [vesuAdapter1, vesuAdapter2] = this.getVesuAdapters();
24101
24899
  const leg1LTV = await vesuAdapter1.getLTVConfig(this.config);
24102
24900
  const leg2LTV = await vesuAdapter2.getLTVConfig(this.config);
@@ -24596,6 +25394,373 @@ var UniversalStrategies = [
24596
25394
  investmentSteps
24597
25395
  }
24598
25396
  ];
25397
+
25398
+ // src/strategies/universal-lst-muliplier-strategy.tsx
25399
+ import { Contract as Contract10, uint256 as uint2569 } from "starknet";
25400
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
25401
+ var UniversalLstMultiplierStrategy = class extends UniversalStrategy {
25402
+ constructor(config, pricer, metadata) {
25403
+ super(config, pricer, metadata);
25404
+ this.quoteAmountToFetchPrice = new Web3Number(1, 18);
25405
+ const STRKToken = Global.getDefaultTokens().find((token) => token.symbol === "STRK");
25406
+ const underlyingToken = this.getLSTUnderlyingTokenInfo();
25407
+ if (underlyingToken.address.eq(STRKToken.address)) {
25408
+ this.quoteAmountToFetchPrice = new Web3Number(100, 18);
25409
+ } else {
25410
+ this.quoteAmountToFetchPrice = new Web3Number(0.01, this.asset().decimals);
25411
+ }
25412
+ }
25413
+ // only one leg is used
25414
+ // todo support lending assets of underlying as well
25415
+ getVesuAdapters() {
25416
+ const vesuAdapter1 = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
25417
+ vesuAdapter1.pricer = this.pricer;
25418
+ vesuAdapter1.networkConfig = this.config;
25419
+ return [vesuAdapter1];
25420
+ }
25421
+ // not applicable for this strategy
25422
+ // No rewards on collateral or borrowing of LST assets
25423
+ async getRewardsAUM(prevAum) {
25424
+ return Web3Number.fromWei("0", this.asset().decimals);
25425
+ }
25426
+ async getLSTDexPrice() {
25427
+ const ekuboQuoter = new EkuboQuoter(this.config);
25428
+ const lstTokenInfo = this.asset();
25429
+ const lstUnderlyingTokenInfo = this.getLSTUnderlyingTokenInfo();
25430
+ const quote = await ekuboQuoter.getQuote(
25431
+ lstTokenInfo.address.address,
25432
+ lstUnderlyingTokenInfo.address.address,
25433
+ this.quoteAmountToFetchPrice
25434
+ );
25435
+ const outputAmount = Web3Number.fromWei(quote.total_calculated, lstUnderlyingTokenInfo.decimals);
25436
+ const price = outputAmount.toNumber() / this.quoteAmountToFetchPrice.toNumber();
25437
+ logger.verbose(`${this.getTag()}:: LST Dex Price: ${price}`);
25438
+ return price;
25439
+ }
25440
+ /**
25441
+ * Uses vesu's multiple call to create leverage on LST
25442
+ * Deposit amount is in LST
25443
+ * @param params
25444
+ */
25445
+ async getVesuMultiplyCall(params) {
25446
+ const [vesuAdapter1] = this.getVesuAdapters();
25447
+ const legLTV = await vesuAdapter1.getLTVConfig(this.config);
25448
+ const existingPositions = await vesuAdapter1.getPositions(this.config);
25449
+ const collateralisation = await vesuAdapter1.getCollateralization(this.config);
25450
+ const existingCollateralInfo = existingPositions[0];
25451
+ const existingDebtInfo = existingPositions[1];
25452
+ logger.debug(`${this.getTag()}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
25453
+ existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
25454
+ const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
25455
+ const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
25456
+ logger.debug(`${this.getTag()}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
25457
+ const addedCollateral = params.leg1DepositAmount.multipliedBy(params.isDeposit ? 1 : -1);
25458
+ const DEXPrice = await this.getLSTDexPrice();
25459
+ logger.verbose(`${this.getTag()}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`);
25460
+ const numeratorPart1 = existingCollateralInfo.amount.plus(addedCollateral).multipliedBy(collateralPrice).multipliedBy(legLTV);
25461
+ const numeratorPart2 = existingDebtInfo.amount.multipliedBy(debtPrice).multipliedBy(this.metadata.additionalInfo.targetHealthFactor);
25462
+ const denominatorPart = this.metadata.additionalInfo.targetHealthFactor - legLTV / DEXPrice;
25463
+ const x_debt_usd = numeratorPart1.minus(numeratorPart2).dividedBy(denominatorPart);
25464
+ logger.verbose(`${this.getTag()}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`);
25465
+ logger.debug(`${this.getTag()}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`);
25466
+ const debtAmount = x_debt_usd.dividedBy(debtPrice);
25467
+ const marginAmount = addedCollateral;
25468
+ logger.verbose(`${this.getTag()}::getVesuMultiplyCall debtAmount: ${debtAmount}, marginAmount: ${marginAmount}`);
25469
+ return this.getModifyLeverCall({
25470
+ marginAmount,
25471
+ debtAmount,
25472
+ isIncrease: debtAmount.greaterThan(0)
25473
+ });
25474
+ }
25475
+ getLSTUnderlyingTokenInfo() {
25476
+ const [vesuAdapter1] = this.getVesuAdapters();
25477
+ return vesuAdapter1.config.debt;
25478
+ }
25479
+ async getLSTExchangeRate() {
25480
+ const [vesuAdapter1] = this.getVesuAdapters();
25481
+ const lstTokenInfo = vesuAdapter1.config.collateral;
25482
+ const lstABI = new Contract10({
25483
+ abi: erc4626_abi_default,
25484
+ address: lstTokenInfo.address.address,
25485
+ providerOrAccount: this.config.provider
25486
+ });
25487
+ const price = await lstABI.call("convert_to_assets", [uint2569.bnToUint256(new Web3Number(1, lstTokenInfo.decimals).toWei())]);
25488
+ const exchangeRate = Number(uint2569.uint256ToBN(price).toString()) / Math.pow(10, lstTokenInfo.decimals);
25489
+ logger.verbose(`${this.getTag()}:: LST Exchange Rate: ${exchangeRate}`);
25490
+ return exchangeRate;
25491
+ }
25492
+ /**
25493
+ *
25494
+ * @param params marginAmount is in LST, debtAmount is in underlying
25495
+ */
25496
+ async getModifyLeverCall(params) {
25497
+ assert(!params.marginAmount.isZero() || !params.debtAmount.isZero(), "Deposit/debt must be non-0");
25498
+ const [vesuAdapter1] = this.getVesuAdapters();
25499
+ const lstTokenInfo = this.asset();
25500
+ const lstUnderlyingTokenInfo = vesuAdapter1.config.debt;
25501
+ const proofsIDs = [];
25502
+ const manageCalls = [];
25503
+ if (params.marginAmount.greaterThan(0)) {
25504
+ const STEP1_ID = "approve_token1" /* APPROVE_TOKEN1 */;
25505
+ const manage1Info = this.getProofs(STEP1_ID);
25506
+ const depositAmount = params.marginAmount;
25507
+ const manageCall1 = manage1Info.callConstructor({
25508
+ amount: depositAmount
25509
+ });
25510
+ proofsIDs.push(STEP1_ID);
25511
+ manageCalls.push(manageCall1);
25512
+ }
25513
+ const ekuboQuoter = new EkuboQuoter(this.config);
25514
+ const lstPrice = await this.getLSTExchangeRate();
25515
+ const marginSwap = [];
25516
+ const MAX_SLIPPAGE = 0.01;
25517
+ const fromToken = params.isIncrease ? lstUnderlyingTokenInfo : lstTokenInfo;
25518
+ const toToken = params.isIncrease ? lstTokenInfo : lstUnderlyingTokenInfo;
25519
+ const leverSwapQuote = await ekuboQuoter.getQuote(
25520
+ fromToken.address.address,
25521
+ toToken.address.address,
25522
+ params.debtAmount
25523
+ // negative for exact amount out
25524
+ );
25525
+ assert(leverSwapQuote.price_impact < MAX_SLIPPAGE, "getIncreaseLeverCall: Price impact is too high [Debt swap]");
25526
+ const leverSwap = ekuboQuoter.getVesuMultiplyQuote(leverSwapQuote, fromToken, toToken);
25527
+ const minExpectedDebt = params.debtAmount.dividedBy(lstPrice).multipliedBy(1 - MAX_SLIPPAGE);
25528
+ const maxUsedCollateral = params.debtAmount.abs().dividedBy(lstPrice).multipliedBy(1 + MAX_SLIPPAGE);
25529
+ const STEP2_ID = "switch_delegation_on" /* SWITCH_DELEGATION_ON */;
25530
+ const manage2Info = this.getProofs(STEP2_ID);
25531
+ const manageCall2 = manage2Info.callConstructor({
25532
+ delegation: true
25533
+ });
25534
+ const STEP3_ID = "multiply_vesu" /* MULTIPLY_VESU */;
25535
+ const manage3Info = this.getProofs(STEP3_ID);
25536
+ const multiplyParams = params.isIncrease ? {
25537
+ isIncrease: true,
25538
+ increaseParams: {
25539
+ add_margin: params.marginAmount,
25540
+ margin_swap: marginSwap,
25541
+ margin_swap_limit_amount: Web3Number.fromWei(0, this.asset().decimals),
25542
+ lever_swap: leverSwap,
25543
+ lever_swap_limit_amount: minExpectedDebt
25544
+ }
25545
+ } : {
25546
+ isIncrease: false,
25547
+ decreaseParams: {
25548
+ sub_margin: params.marginAmount.multipliedBy(-1),
25549
+ lever_swap: leverSwap,
25550
+ lever_swap_limit_amount: maxUsedCollateral,
25551
+ // only required for close position
25552
+ lever_swap_weights: [],
25553
+ // no need to swap collateral to anything, and any residuals return our contract anyways.
25554
+ withdraw_swap: [],
25555
+ withdraw_swap_limit_amount: Web3Number.fromWei(0, this.asset().decimals),
25556
+ withdraw_swap_weights: [],
25557
+ close_position: false
25558
+ }
25559
+ };
25560
+ const manageCall3 = manage3Info.callConstructor(multiplyParams);
25561
+ const STEP4_ID = "switch_delegation_off" /* SWITCH_DELEGATION_OFF */;
25562
+ const manage4Info = this.getProofs(STEP4_ID);
25563
+ const manageCall4 = manage4Info.callConstructor({
25564
+ delegation: false
25565
+ });
25566
+ proofsIDs.push(STEP2_ID, STEP3_ID, STEP4_ID);
25567
+ manageCalls.push(manageCall2, manageCall3, manageCall4);
25568
+ return [this.getManageCall(proofsIDs, manageCalls)];
25569
+ }
25570
+ };
25571
+ function VaultDescription() {
25572
+ const containerStyle = {
25573
+ maxWidth: "800px",
25574
+ margin: "0 auto",
25575
+ backgroundColor: "#111",
25576
+ color: "#eee",
25577
+ fontFamily: "Arial, sans-serif",
25578
+ borderRadius: "12px"
25579
+ };
25580
+ return /* @__PURE__ */ jsxs4("div", { style: containerStyle, children: [
25581
+ /* @__PURE__ */ jsx5("h1", { style: { fontSize: "18px", marginBottom: "10px" }, children: "Meta Vault \u2014 Automated Yield Router" }),
25582
+ /* @__PURE__ */ jsx5("p", { style: { fontSize: "14px", lineHeight: "1.5", marginBottom: "16px" }, children: "This Levered Endur LST vault is a tokenized leveraged Vault, auto-compounding strategy that continuously allocates your deposited asset to the best available yield source in the ecosystem. Depositors receive vault shares that represent a proportional claim on the underlying assets and accrued yield. Allocation shifts are handled programmatically based on on-chain signals and risk filters, minimizing idle capital and maximizing net APY." }),
25583
+ /* @__PURE__ */ jsx5("div", { style: { backgroundColor: "#222", padding: "10px", borderRadius: "8px", marginBottom: "20px", border: "1px solid #444" }, children: /* @__PURE__ */ jsxs4("p", { style: { fontSize: "13px", color: "#ccc" }, children: [
25584
+ /* @__PURE__ */ jsx5("strong", { children: "Withdrawals:" }),
25585
+ " Requests can take up to ",
25586
+ /* @__PURE__ */ jsx5("strong", { children: "1-2 hours" }),
25587
+ " to process as the vault unwinds and settles routing."
25588
+ ] }) })
25589
+ ] });
25590
+ }
25591
+ function getDescription2(tokenSymbol) {
25592
+ return VaultDescription();
25593
+ }
25594
+ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
25595
+ vaultSettings.leafAdapters = [];
25596
+ const lstToken = Global.getDefaultTokens().find((token) => token.symbol === lstSymbol);
25597
+ const underlyingToken = Global.getDefaultTokens().find((token) => token.symbol === underlyingSymbol);
25598
+ const vesuAdapterLST = new VesuAdapter({
25599
+ poolId: pool1,
25600
+ collateral: lstToken,
25601
+ debt: underlyingToken,
25602
+ vaultAllocator: vaultSettings.vaultAllocator,
25603
+ id: "multiply_vesu" /* MULTIPLY_VESU */
25604
+ });
25605
+ const commonAdapter = new CommonAdapter({
25606
+ manager: vaultSettings.manager,
25607
+ asset: lstToken.address,
25608
+ id: "",
25609
+ vaultAddress: vaultSettings.vaultAddress,
25610
+ vaultAllocator: vaultSettings.vaultAllocator
25611
+ });
25612
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, vesuAdapterLST.VESU_MULTIPLY, "approve_token1" /* APPROVE_TOKEN1 */).bind(commonAdapter));
25613
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getMultiplyAdapter.bind(vesuAdapterLST));
25614
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_on" /* SWITCH_DELEGATION_ON */).bind(vesuAdapterLST));
25615
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_off" /* SWITCH_DELEGATION_OFF */).bind(vesuAdapterLST));
25616
+ vaultSettings.adapters.push(...[{
25617
+ id: "vesu_leg1_adapter" /* VESU_LEG1 */,
25618
+ adapter: vesuAdapterLST
25619
+ }, {
25620
+ id: "common_adapter" /* COMMON */,
25621
+ adapter: commonAdapter
25622
+ }]);
25623
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, vaultSettings.vaultAddress, "approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */).bind(commonAdapter));
25624
+ vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter("bring_liquidity" /* BRING_LIQUIDITY */).bind(commonAdapter));
25625
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getDefispringRewardsAdapter("defispring_rewards" /* DEFISPRING_REWARDS */).bind(vesuAdapterLST));
25626
+ const STRKToken = Global.getDefaultTokens().find((token) => token.symbol === "STRK");
25627
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(STRKToken.address, AVNU_MIDDLEWARE, "approve_swap_token1" /* APPROVE_SWAP_TOKEN1 */).bind(commonAdapter));
25628
+ vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(STRKToken.address, lstToken.address, "avnu_swap_rewards" /* AVNU_SWAP_REWARDS */).bind(commonAdapter));
25629
+ return vaultSettings;
25630
+ }
25631
+ function getFAQs2(lstSymbol, underlyingSymbol) {
25632
+ return [
25633
+ {
25634
+ question: `What is the Hyper ${lstSymbol} Vault?`,
25635
+ answer: `The Hyper ${lstSymbol} Vault is a tokenized strategy that automatically loops your ${underlyingSymbol} or ${lstSymbol} to create up to 4x leverage to hence yield in a very low risk manner.`
25636
+ },
25637
+ {
25638
+ question: "How does yield allocation work?",
25639
+ answer: `The strategy uses deposited ${lstSymbol} to collateralize it on Vesu, borrow more ${underlyingSymbol} to loop further. Instead of manually doing this, using flash loan, this leverage is created in a single gas efficient step. Our continuous monitoring systems gauge current yield and available liquidity in real time to make sure yield is optimal. For instance, if the looping becomes in-efficient in future, the strategy will rebalance to reduce leverage or simply hold ${lstSymbol} to continue earning yield.`
25640
+ },
25641
+ {
25642
+ question: "Which protocols/dApp are used??",
25643
+ answer: /* @__PURE__ */ jsxs4("span", { children: [
25644
+ "Currently, the LST is from ",
25645
+ /* @__PURE__ */ jsx5("strong", { children: "Endur" }),
25646
+ " while ",
25647
+ /* @__PURE__ */ jsx5("strong", { children: "Vesu" }),
25648
+ " is used to collateralize the looped position."
25649
+ ] })
25650
+ },
25651
+ {
25652
+ question: "Can I get liquidated?",
25653
+ answer: "The strategy uses highly correlated assets which drastically reduces the risk of liquidation. However, overtime, if left un-monitored, debt can increase enough to trigger a liquidation. But no worries, our continuous monitoring systems look for situations with reduced health factor and balance collateral/debt to bring it back to safe levels. With Troves, you can have a peaceful sleep."
25654
+ },
25655
+ {
25656
+ question: "What do I receive when I deposit?",
25657
+ answer: "Depositors receive vault tokens representing their proportional share of the vault. These tokens entitle holders to both the principal and accrued yield."
25658
+ },
25659
+ {
25660
+ question: "How long do withdrawals take?",
25661
+ answer: "Withdrawals may take up to 1-2 hours to process, as the vault unwinds and settles liquidity routing across integrated protocols. In case of large withdrawals, to avoid slippage, we may slowly unwind the position, which could make the withdrawals longer."
25662
+ },
25663
+ {
25664
+ question: "Is the Hyper xSTRK Vault non-custodial?",
25665
+ answer: "Yes. The Hyper xSTRK Vault operates entirely on-chain. Users always maintain control of their vault tokens, and the strategy is fully transparent."
25666
+ },
25667
+ {
25668
+ question: "Is the Vault audited?",
25669
+ answer: "Yes. The Hyper xSTRK Vault is audited by Zellic. Look for safety icon beside the strategy name for more details."
25670
+ },
25671
+ {
25672
+ question: "Are there any fees?",
25673
+ answer: "Troves charges a performance of 10% on the yield generated. The APY shown is net of this fee. This fee is only applied to the profits earned, ensuring that users retain their initial capital."
25674
+ }
25675
+ ];
25676
+ }
25677
+ var _riskFactor4 = [
25678
+ { type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 2 /* WELL_AUDITED */, weight: 25, reason: "Audited by Zellic" },
25679
+ { type: "Liquidation Risk" /* LIQUIDATION_RISK */, value: 1 /* VERY_LOW_PROBABILITY */, weight: 50, reason: "The collateral and debt are highly correlated" },
25680
+ { type: "Technical Risk" /* TECHNICAL_RISK */, value: 1 /* STABLE_INFRASTRUCTURE */, weight: 50, reason: "Liquidation can only happen if vault is left un-monitored for weeks, which is highly unlikely. We actively monitor all services on a daily basis." }
25681
+ ];
25682
+ var hyperxSTRK = {
25683
+ vaultAddress: ContractAddr.from("0x46c7a54c82b1fe374353859f554a40b8bd31d3e30f742901579e7b57b1b5960"),
25684
+ manager: ContractAddr.from("0x5d499cd333757f461a0bedaca3dfc4d77320c773037e0aa299f22a6dbfdc03a"),
25685
+ vaultAllocator: ContractAddr.from("0x511d07953a09bc7c505970891507c5a2486d2ea22752601a14db092186d7caa"),
25686
+ redeemRequestNFT: ContractAddr.from("0x51e40b839dc0c2feca923f863072673b94abfa2483345be3b30b457a90d095"),
25687
+ aumOracle: ContractAddr.from("0x48cf709870a1a0d453d37de108e0c41b8b89819ef54f95abc0e2e1f98bbe937"),
25688
+ leafAdapters: [],
25689
+ adapters: [],
25690
+ targetHealthFactor: 1.1,
25691
+ minHealthFactor: 1.05
25692
+ };
25693
+ var hyperxWBTC = {
25694
+ vaultAddress: ContractAddr.from("0x2da9d0f96a46b453f55604313785dc866424240b1c6811d13bef594343db818"),
25695
+ manager: ContractAddr.from("0x75866db44c81e6986f06035206ee9c7d15833ddb22d6a22c016cfb5c866a491"),
25696
+ vaultAllocator: ContractAddr.from("0x57b5c1bb457b5e840a2714ae53ada87d77be2f3fd33a59b4fe709ef20c020c1"),
25697
+ redeemRequestNFT: ContractAddr.from("0x7a5dc288325456f05e70e9616e16bc02ffbe448f4b89f80b47c0970b989c7c"),
25698
+ aumOracle: ContractAddr.from(""),
25699
+ leafAdapters: [],
25700
+ adapters: [],
25701
+ targetHealthFactor: 1.1,
25702
+ minHealthFactor: 1.05
25703
+ };
25704
+ var hyperxtBTC = {
25705
+ vaultAddress: ContractAddr.from("0x47d5f68477e5637ce0e56436c6b5eee5a354e6828995dae106b11a48679328"),
25706
+ manager: ContractAddr.from("0xc4cc3e08029a0ae076f5fdfca70575abb78d23c5cd1c49a957f7e697885401"),
25707
+ vaultAllocator: ContractAddr.from("0x50bbd4fe69f841ecb13b2619fe50ebfa4e8944671b5d0ebf7868fd80c61b31e"),
25708
+ redeemRequestNFT: ContractAddr.from("0xeac9032f02057779816e38a6cb9185d12d86b3aacc9949b96b36de359c1e3"),
25709
+ aumOracle: ContractAddr.from(""),
25710
+ leafAdapters: [],
25711
+ adapters: [],
25712
+ targetHealthFactor: 1.1,
25713
+ minHealthFactor: 1.05
25714
+ };
25715
+ var hyperxsBTC = {
25716
+ vaultAddress: ContractAddr.from("0x437ef1e7d0f100b2e070b7a65cafec0b2be31b0290776da8b4112f5473d8d9"),
25717
+ manager: ContractAddr.from("0xc9ac023090625b0be3f6532ca353f086746f9c09f939dbc1b2613f09e5f821"),
25718
+ vaultAllocator: ContractAddr.from("0x60c2d856936b975459a5b4eb28b8672d91f757bd76cebb6241f8d670185dc01"),
25719
+ redeemRequestNFT: ContractAddr.from("0x429e8ee8bc7ecd1ade72630d350a2e0f10f9a2507c45f188ba17fe8f2ab4cf3"),
25720
+ aumOracle: ContractAddr.from(""),
25721
+ leafAdapters: [],
25722
+ adapters: [],
25723
+ targetHealthFactor: 1.1,
25724
+ minHealthFactor: 1.05
25725
+ };
25726
+ function getInvestmentSteps(lstSymbol, underlyingSymbol) {
25727
+ return [
25728
+ `Deposit ${underlyingSymbol} into the vault`,
25729
+ `The vault manager loops the ${underlyingSymbol} to buy ${lstSymbol}`,
25730
+ `The vault manager collateralizes the ${lstSymbol} on Vesu`,
25731
+ `The vault manager borrows more ${underlyingSymbol} to loop further`,
25732
+ `Claim BTCFi STRK rewards weekly to swap to ${lstSymbol} and reinvest`,
25733
+ `If required, adjust leverage or re-allocate assets within LST pool on Vesu to optimize yield`
25734
+ ];
25735
+ }
25736
+ function getStrategySettings(lstSymbol, underlyingSymbol, addresses, isPreview = false) {
25737
+ return {
25738
+ name: `Hyper ${lstSymbol}`,
25739
+ description: getDescription2(lstSymbol),
25740
+ address: addresses.vaultAddress,
25741
+ launchBlock: 0,
25742
+ type: "Other",
25743
+ depositTokens: [Global.getDefaultTokens().find((token) => token.symbol === lstSymbol)],
25744
+ additionalInfo: getLooperSettings2(lstSymbol, underlyingSymbol, addresses, VesuPools.Re7xSTRK),
25745
+ risk: {
25746
+ riskFactor: _riskFactor4,
25747
+ netRisk: _riskFactor4.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor4.reduce((acc, curr) => acc + curr.weight, 0),
25748
+ notARisks: getNoRiskTags(_riskFactor4)
25749
+ },
25750
+ protocols: [Protocols.ENDUR, Protocols.VESU],
25751
+ maxTVL: Web3Number.fromWei(0, 18),
25752
+ contractDetails: getContractDetails(addresses),
25753
+ faqs: getFAQs2(lstSymbol, underlyingSymbol),
25754
+ investmentSteps: getInvestmentSteps(lstSymbol, underlyingSymbol),
25755
+ isPreview
25756
+ };
25757
+ }
25758
+ var HyperLSTStrategies = [
25759
+ getStrategySettings("xSTRK", "STRK", hyperxSTRK, false),
25760
+ getStrategySettings("xWBTC", "WBTC", hyperxWBTC, true),
25761
+ getStrategySettings("xtBTC", "tBTC", hyperxtBTC, true),
25762
+ getStrategySettings("xsBTC", "solvBTC", hyperxsBTC, true)
25763
+ ];
24599
25764
  export {
24600
25765
  AUMTypes,
24601
25766
  AutoCompounderSTRK,
@@ -24607,9 +25772,11 @@ export {
24607
25772
  ERC20,
24608
25773
  EkuboCLVault,
24609
25774
  EkuboCLVaultStrategies,
25775
+ EkuboQuoter,
24610
25776
  FatalError,
24611
25777
  FlowChartColors,
24612
25778
  Global,
25779
+ HyperLSTStrategies,
24613
25780
  ILending,
24614
25781
  Initializable,
24615
25782
  MarginType,
@@ -24623,6 +25790,7 @@ export {
24623
25790
  SenseiVault,
24624
25791
  UNIVERSAL_ADAPTERS,
24625
25792
  UNIVERSAL_MANAGE_IDS,
25793
+ UniversalLstMultiplierStrategy,
24626
25794
  UniversalStrategies,
24627
25795
  UniversalStrategy,
24628
25796
  VesuAdapter,
@@ -24633,6 +25801,7 @@ export {
24633
25801
  VesuRebalanceStrategies,
24634
25802
  Web3Number,
24635
25803
  ZkLend,
25804
+ getContractDetails,
24636
25805
  getMainnetConfig,
24637
25806
  getNoRiskTags,
24638
25807
  getRiskColor,