@strkfarm/sdk 1.0.62 → 1.0.63

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.mjs CHANGED
@@ -3890,11 +3890,12 @@ var EkuboHarvests = class extends Harvests {
3890
3890
  return rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime());
3891
3891
  }
3892
3892
  };
3893
+ var VESU_REWARDS_CONTRACT = ContractAddr.from("0x0387f3eb1d98632fbe3440a9f1385Aec9d87b6172491d3Dd81f1c35A7c61048F");
3893
3894
  var VesuHarvests = class _VesuHarvests extends Harvests {
3894
3895
  async getHarvests(addr) {
3895
3896
  const result = await fetch(`https://api.vesu.xyz/users/${addr.address}/strk-rewards/calldata`);
3896
3897
  const data = await result.json();
3897
- const rewardsContract = ContractAddr.from("0x0387f3eb1d98632fbe3440a9f1385Aec9d87b6172491d3Dd81f1c35A7c61048F");
3898
+ const rewardsContract = VESU_REWARDS_CONTRACT;
3898
3899
  const cls = await this.config.provider.getClassAt(rewardsContract.address);
3899
3900
  const contract = new Contract4(cls.abi, rewardsContract.address, this.config.provider);
3900
3901
  const _claimed_amount = await contract.call("amount_already_claimed", [addr.address]);
@@ -18486,7 +18487,9 @@ var SenseiStrategies = [
18486
18487
  import { hash, num as num6, shortString } from "starknet";
18487
18488
 
18488
18489
  // src/strategies/universal-adapters/adapter-utils.ts
18489
- var SIMPLE_SANITIZER = ContractAddr.from("0x3798dc4f83fdfad199e5236e3656cf2fb79bc50c00504d0dd41522e0f042072");
18490
+ var SIMPLE_SANITIZER = ContractAddr.from("0x5a2e3ceb3da368b983a8717898427ab7b6daf04014b70f321e777f9aad940b4");
18491
+ var PRICE_ROUTER = ContractAddr.from("0x05e83Fa38D791d2dba8E6f487758A9687FfEe191A6Cf8a6c5761ab0a110DB837");
18492
+ var AVNU_MIDDLEWARE = ContractAddr.from("0x4a7972ed3f5d1e74a6d6c4a8f467666953d081c8f2270390cc169d50d17cb0d");
18490
18493
  function toBigInt(value) {
18491
18494
  if (typeof value === "string") {
18492
18495
  return BigInt(value);
@@ -18519,7 +18522,7 @@ var BaseAdapter = class extends CacheClass {
18519
18522
  };
18520
18523
 
18521
18524
  // src/strategies/universal-adapters/common-adapter.ts
18522
- import { hash as hash2, uint256 as uint2566 } from "starknet";
18525
+ import { hash as hash2, num as num7, uint256 as uint2566 } from "starknet";
18523
18526
  var CommonAdapter = class extends BaseAdapter {
18524
18527
  constructor(config) {
18525
18528
  super();
@@ -18630,10 +18633,70 @@ var CommonAdapter = class extends BaseAdapter {
18630
18633
  };
18631
18634
  };
18632
18635
  }
18636
+ getAvnuAdapter(fromToken, toToken, id) {
18637
+ return () => ({
18638
+ leaf: this.constructSimpleLeafData({
18639
+ id,
18640
+ target: AVNU_MIDDLEWARE,
18641
+ method: "multi_route_swap",
18642
+ packedArguments: [
18643
+ fromToken.toBigInt(),
18644
+ toToken.toBigInt(),
18645
+ this.config.vaultAllocator.toBigInt()
18646
+ ]
18647
+ }),
18648
+ callConstructor: this.getAvnuCall(fromToken, toToken).bind(this)
18649
+ });
18650
+ }
18651
+ getAvnuCall(fromToken, toToken) {
18652
+ return (params) => {
18653
+ return {
18654
+ sanitizer: SIMPLE_SANITIZER,
18655
+ call: {
18656
+ contractAddress: AVNU_MIDDLEWARE,
18657
+ selector: hash2.getSelectorFromName("multi_route_swap"),
18658
+ calldata: [
18659
+ fromToken.toBigInt(),
18660
+ // sell_token_address
18661
+ toBigInt(params.props.token_from_amount.low.toString()),
18662
+ // sell_token_amount low
18663
+ toBigInt(params.props.token_from_amount.high.toString()),
18664
+ // sell_token_amount high
18665
+ toToken.toBigInt(),
18666
+ // buy_token_address
18667
+ toBigInt(params.props.token_to_amount.low.toString()),
18668
+ // buy_token_amount low
18669
+ toBigInt(params.props.token_to_amount.high.toString()),
18670
+ // buy_token_amount high
18671
+ toBigInt(params.props.token_to_min_amount.low.toString()),
18672
+ // buy_token_min_amount low
18673
+ toBigInt(params.props.token_to_min_amount.high.toString()),
18674
+ // buy_token_min_amount high
18675
+ this.config.vaultAllocator.toBigInt(),
18676
+ // beneficiary
18677
+ toBigInt(0),
18678
+ // integrator_fee_amount_bps
18679
+ this.config.vaultAllocator.toBigInt(),
18680
+ // integrator_fee_recipient
18681
+ // unpack routes
18682
+ BigInt(params.props.routes.length),
18683
+ ...params.props.routes.map((r) => [
18684
+ BigInt(num7.hexToDecimalString(r.token_from)),
18685
+ BigInt(num7.hexToDecimalString(r.token_to)),
18686
+ BigInt(num7.hexToDecimalString(r.exchange_address)),
18687
+ BigInt(r.percent),
18688
+ BigInt(r.additional_swap_params.length),
18689
+ ...r.additional_swap_params.map((p) => BigInt(num7.hexToDecimalString(p)))
18690
+ ]).flat()
18691
+ ]
18692
+ }
18693
+ };
18694
+ };
18695
+ }
18633
18696
  };
18634
18697
 
18635
18698
  // src/strategies/universal-adapters/vesu-adapter.ts
18636
- import { CairoCustomEnum as CairoCustomEnum2, Contract as Contract8, hash as hash3, RpcProvider as RpcProvider4, uint256 as uint2567 } from "starknet";
18699
+ import { CairoCustomEnum as CairoCustomEnum2, Contract as Contract8, hash as hash3, num as num8, RpcProvider as RpcProvider4, shortString as shortString3, uint256 as uint2567 } from "starknet";
18637
18700
 
18638
18701
  // src/data/vesu-singleton.abi.json
18639
18702
  var vesu_singleton_abi_default = [
@@ -20966,6 +21029,40 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
20966
21029
  }
20967
21030
  };
20968
21031
  };
21032
+ this.getDefispringRewardsAdapter = (id) => {
21033
+ return () => {
21034
+ const packedArguments = [];
21035
+ const output = {
21036
+ id: BigInt(num8.getDecimalString(shortString3.encodeShortString(id))),
21037
+ readableId: id,
21038
+ data: [
21039
+ SIMPLE_SANITIZER.toBigInt(),
21040
+ // sanitizer address
21041
+ VESU_REWARDS_CONTRACT.toBigInt(),
21042
+ // contract
21043
+ toBigInt(hash3.getSelectorFromName("claim")),
21044
+ // method name
21045
+ BigInt(packedArguments.length),
21046
+ ...packedArguments
21047
+ ]
21048
+ };
21049
+ return { leaf: output, callConstructor: this.getDefiSpringClaimCall().bind(this) };
21050
+ };
21051
+ };
21052
+ this.getDefiSpringClaimCall = () => {
21053
+ return (params) => ({
21054
+ sanitizer: SIMPLE_SANITIZER,
21055
+ call: {
21056
+ contractAddress: VESU_REWARDS_CONTRACT,
21057
+ selector: hash3.getSelectorFromName("claim"),
21058
+ calldata: [
21059
+ BigInt(params.amount.toWei()),
21060
+ BigInt(params.proofs.length),
21061
+ ...params.proofs.map((proof) => BigInt(num8.hexToDecimalString(proof)))
21062
+ ]
21063
+ }
21064
+ });
21065
+ };
20969
21066
  this.config = config;
20970
21067
  }
20971
21068
  static getDefaultModifyPositionCallParams(params) {
@@ -23595,7 +23692,7 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
23595
23692
  const aumToken = vesuAum.plus(balance.amount);
23596
23693
  logger.verbose(`${this.getTag()} Actual AUM: ${aumToken}`);
23597
23694
  const netAPY = await this.netAPY();
23598
- const defispringAPY = netAPY.splits.find((s) => s.id === "defispring")?.apy || 0;
23695
+ const defispringAPY = (netAPY.splits.find((s) => s.id === "defispring")?.apy || 0) * 0.8;
23599
23696
  if (!defispringAPY) throw new Error("DefiSpring APY not found");
23600
23697
  const timeDiff = Math.round(Date.now() / 1e3) - Number(lastReportTime);
23601
23698
  const growthRate = timeDiff * defispringAPY / (365 * 24 * 60 * 60);
@@ -23838,6 +23935,51 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
23838
23935
  const manageCall = this.getManageCall(["approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */, "bring_liquidity" /* BRING_LIQUIDITY */], [manageCall1, manageCall2]);
23839
23936
  return manageCall;
23840
23937
  }
23938
+ async getHarvestCall() {
23939
+ const vesuHarvest = new VesuHarvests(this.config);
23940
+ const harvestInfo = await vesuHarvest.getUnHarvestedRewards(this.metadata.additionalInfo.vaultAllocator);
23941
+ if (harvestInfo.length != 1) {
23942
+ throw new Error(`Expected 1 harvest info, got ${harvestInfo.length}`);
23943
+ }
23944
+ const amount = harvestInfo[0].claim.amount;
23945
+ const actualReward = harvestInfo[0].actualReward;
23946
+ const proofs = harvestInfo[0].proof;
23947
+ if (actualReward.isZero()) {
23948
+ throw new Error(`Expected non-zero actual reward, got ${harvestInfo[0].actualReward}`);
23949
+ }
23950
+ const manage1Info = this.getProofs("defispring_rewards" /* DEFISPRING_REWARDS */);
23951
+ const manageCall1 = manage1Info.callConstructor({
23952
+ amount,
23953
+ proofs
23954
+ });
23955
+ const proofIds = ["defispring_rewards" /* DEFISPRING_REWARDS */];
23956
+ const manageCalls = [manageCall1];
23957
+ const STRK2 = Global.getDefaultTokens().find((t) => t.symbol === "STRK");
23958
+ if (this.asset().symbol != "STRK") {
23959
+ const manage2Info = this.getProofs("approve_swap_token1" /* APPROVE_SWAP_TOKEN1 */);
23960
+ const manageCall2 = manage2Info.callConstructor({
23961
+ amount: actualReward
23962
+ });
23963
+ const avnuModule = new AvnuWrapper();
23964
+ const quote = await avnuModule.getQuotes(
23965
+ STRK2.address.address,
23966
+ this.asset().address.address,
23967
+ actualReward.toWei(),
23968
+ this.address.address
23969
+ );
23970
+ const swapInfo = await avnuModule.getSwapInfo(quote, this.address.address, 0, this.address.address);
23971
+ const manage3Info = this.getProofs("avnu_swap_rewards" /* AVNU_SWAP_REWARDS */);
23972
+ const manageCall3 = manage3Info.callConstructor({
23973
+ props: swapInfo
23974
+ });
23975
+ proofIds.push("approve_swap_token1" /* APPROVE_SWAP_TOKEN1 */);
23976
+ proofIds.push("avnu_swap_rewards" /* AVNU_SWAP_REWARDS */);
23977
+ manageCalls.push(manageCall2);
23978
+ manageCalls.push(manageCall3);
23979
+ }
23980
+ const manageCall = this.getManageCall(proofIds, manageCalls);
23981
+ return { call: manageCall, reward: actualReward, tokenInfo: STRK2 };
23982
+ }
23841
23983
  async getRebalanceCall(params) {
23842
23984
  let callSet1 = this.getVesuModifyPositionCalls({
23843
23985
  isLeg1: true,
@@ -23874,6 +24016,9 @@ var UNIVERSAL_MANAGE_IDS = /* @__PURE__ */ ((UNIVERSAL_MANAGE_IDS2) => {
23874
24016
  UNIVERSAL_MANAGE_IDS2["APPROVE_TOKEN2"] = "approve_token2";
23875
24017
  UNIVERSAL_MANAGE_IDS2["APPROVE_BRING_LIQUIDITY"] = "approve_bring_liquidity";
23876
24018
  UNIVERSAL_MANAGE_IDS2["BRING_LIQUIDITY"] = "bring_liquidity";
24019
+ UNIVERSAL_MANAGE_IDS2["DEFISPRING_REWARDS"] = "defispring_rewards";
24020
+ UNIVERSAL_MANAGE_IDS2["APPROVE_SWAP_TOKEN1"] = "approve_swap_token1";
24021
+ UNIVERSAL_MANAGE_IDS2["AVNU_SWAP_REWARDS"] = "avnu_swap_rewards";
23877
24022
  return UNIVERSAL_MANAGE_IDS2;
23878
24023
  })(UNIVERSAL_MANAGE_IDS || {});
23879
24024
  var UNIVERSAL_ADAPTERS = /* @__PURE__ */ ((UNIVERSAL_ADAPTERS2) => {
@@ -23923,6 +24068,10 @@ function getLooperSettings(token1Symbol, token2Symbol, vaultSettings, pool1, poo
23923
24068
  vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(ETHToken.address, vesuAdapterETHUSDC.VESU_SINGLETON, "approve_token2" /* APPROVE_TOKEN2 */).bind(commonAdapter));
23924
24069
  vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(USDCToken.address, vaultSettings.vaultAddress, "approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */).bind(commonAdapter));
23925
24070
  vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter("bring_liquidity" /* BRING_LIQUIDITY */).bind(commonAdapter));
24071
+ vaultSettings.leafAdapters.push(vesuAdapterUSDCETH.getDefispringRewardsAdapter("defispring_rewards" /* DEFISPRING_REWARDS */).bind(vesuAdapterUSDCETH));
24072
+ const STRKToken = Global.getDefaultTokens().find((token) => token.symbol === "STRK");
24073
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(STRKToken.address, AVNU_MIDDLEWARE, "approve_swap_token1" /* APPROVE_SWAP_TOKEN1 */).bind(commonAdapter));
24074
+ vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(STRKToken.address, USDCToken.address, "avnu_swap_rewards" /* AVNU_SWAP_REWARDS */).bind(commonAdapter));
23926
24075
  return vaultSettings;
23927
24076
  }
23928
24077
  var _riskFactor4 = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strkfarm/sdk",
3
- "version": "1.0.62",
3
+ "version": "1.0.63",
4
4
  "description": "STRKFarm TS SDK (Meant for our internal use, but feel free to use it)",
5
5
  "typings": "dist/index.d.ts",
6
6
  "types": "dist/index.d.ts",
@@ -83,12 +83,14 @@ export class EkuboHarvests extends Harvests {
83
83
  }
84
84
  }
85
85
 
86
+ export const VESU_REWARDS_CONTRACT = ContractAddr.from('0x0387f3eb1d98632fbe3440a9f1385Aec9d87b6172491d3Dd81f1c35A7c61048F');
87
+
86
88
  export class VesuHarvests extends Harvests {
87
89
  async getHarvests(addr: ContractAddr): Promise<HarvestInfo[]> {
88
90
  const result = await fetch(`https://api.vesu.xyz/users/${addr.address}/strk-rewards/calldata`);
89
91
  const data = await result.json();
90
- const rewardsContract = ContractAddr.from('0x0387f3eb1d98632fbe3440a9f1385Aec9d87b6172491d3Dd81f1c35A7c61048F');
91
-
92
+ const rewardsContract = VESU_REWARDS_CONTRACT;
93
+
92
94
  // get already claimed amount
93
95
  const cls = await this.config.provider.getClassAt(rewardsContract.address);
94
96
  const contract = new Contract(cls.abi, rewardsContract.address, this.config.provider);
@@ -1,6 +1,8 @@
1
1
  import { ContractAddr } from "@/dataTypes";
2
2
 
3
- export const SIMPLE_SANITIZER = ContractAddr.from('0x3798dc4f83fdfad199e5236e3656cf2fb79bc50c00504d0dd41522e0f042072');
3
+ export const SIMPLE_SANITIZER = ContractAddr.from('0x5a2e3ceb3da368b983a8717898427ab7b6daf04014b70f321e777f9aad940b4');
4
+ export const PRICE_ROUTER = ContractAddr.from('0x05e83Fa38D791d2dba8E6f487758A9687FfEe191A6Cf8a6c5761ab0a110DB837');
5
+ export const AVNU_MIDDLEWARE = ContractAddr.from('0x4a7972ed3f5d1e74a6d6c4a8f467666953d081c8f2270390cc169d50d17cb0d');
4
6
 
5
7
  export function toBigInt(value: string | number): bigint {
6
8
  if (typeof value === 'string') {
@@ -1,8 +1,9 @@
1
1
  import { ContractAddr, Web3Number } from "@/dataTypes";
2
2
  import { LeafData } from "@/utils";
3
3
  import { Call, hash, num, shortString, uint256 } from "starknet";
4
- import { SIMPLE_SANITIZER, toBigInt } from "./adapter-utils";
4
+ import { AVNU_MIDDLEWARE, SIMPLE_SANITIZER, toBigInt } from "./adapter-utils";
5
5
  import { AdapterLeafType, BaseAdapter, GenerateCallFn, LeafAdapterFn, ManageCall } from "./baseAdapter";
6
+ import { SwapInfo } from "@/modules";
6
7
 
7
8
  export interface FlashloanCallParams {
8
9
  amount: Web3Number,
@@ -11,6 +12,9 @@ export interface FlashloanCallParams {
11
12
  export interface ApproveCallParams {
12
13
  amount: Web3Number,
13
14
  }
15
+ export interface AvnuSwapCallParams {
16
+ props: SwapInfo
17
+ }
14
18
 
15
19
  export interface CommonAdapterConfig {
16
20
  id: string,
@@ -124,4 +128,56 @@ export class CommonAdapter extends BaseAdapter {
124
128
  }
125
129
  }
126
130
  }
131
+
132
+ getAvnuAdapter(fromToken: ContractAddr, toToken: ContractAddr, id: string): () => AdapterLeafType<AvnuSwapCallParams> {
133
+ return () => ({
134
+ leaf: this.constructSimpleLeafData({
135
+ id: id,
136
+ target: AVNU_MIDDLEWARE,
137
+ method: 'multi_route_swap',
138
+ packedArguments: [
139
+ fromToken.toBigInt(),
140
+ toToken.toBigInt(),
141
+ this.config.vaultAllocator.toBigInt(),
142
+ ]
143
+ }),
144
+ callConstructor: this.getAvnuCall(fromToken, toToken).bind(this)
145
+ });
146
+ }
147
+
148
+ getAvnuCall(fromToken: ContractAddr, toToken: ContractAddr): GenerateCallFn<AvnuSwapCallParams> {
149
+ return (params: AvnuSwapCallParams): ManageCall => {
150
+ return {
151
+ sanitizer: SIMPLE_SANITIZER,
152
+ call: {
153
+ contractAddress: AVNU_MIDDLEWARE,
154
+ selector: hash.getSelectorFromName('multi_route_swap'),
155
+ calldata: [
156
+ fromToken.toBigInt(), // sell_token_address
157
+ toBigInt(params.props.token_from_amount.low.toString()), // sell_token_amount low
158
+ toBigInt(params.props.token_from_amount.high.toString()), // sell_token_amount high
159
+ toToken.toBigInt(), // buy_token_address
160
+ toBigInt(params.props.token_to_amount.low.toString()), // buy_token_amount low
161
+ toBigInt(params.props.token_to_amount.high.toString()), // buy_token_amount high
162
+ toBigInt(params.props.token_to_min_amount.low.toString()), // buy_token_min_amount low
163
+ toBigInt(params.props.token_to_min_amount.high.toString()), // buy_token_min_amount high
164
+ this.config.vaultAllocator.toBigInt(), // beneficiary
165
+ toBigInt(0), // integrator_fee_amount_bps
166
+ this.config.vaultAllocator.toBigInt(), // integrator_fee_recipient
167
+
168
+ // unpack routes
169
+ BigInt(params.props.routes.length),
170
+ ...params.props.routes.map(r => ([
171
+ BigInt(num.hexToDecimalString(r.token_from)),
172
+ BigInt(num.hexToDecimalString(r.token_to)),
173
+ BigInt(num.hexToDecimalString(r.exchange_address)),
174
+ BigInt(r.percent),
175
+ BigInt(r.additional_swap_params.length),
176
+ ...r.additional_swap_params.map(p => BigInt(num.hexToDecimalString(p)))
177
+ ])).flat()
178
+ ]
179
+ }
180
+ }
181
+ }
182
+ }
127
183
  }
@@ -9,6 +9,7 @@ import { PricerBase } from "@/modules/pricerBase";
9
9
  import VesuPoolIDs from "@/data/vesu_pools.json";
10
10
  import { getAPIUsingHeadlessBrowser } from "@/node/headless";
11
11
  import { Global } from "@/global";
12
+ import { VESU_REWARDS_CONTRACT } from "@/modules/harvests";
12
13
 
13
14
  interface VesuPoolsInfo { pools: any[]; isErrorPoolsAPI: boolean };
14
15
 
@@ -38,6 +39,11 @@ export interface VesuModifyPositionCallParams {
38
39
  debtAmount: VesuAmount
39
40
  }
40
41
 
42
+ export interface VesuDefiSpringRewardsCallParams {
43
+ amount: Web3Number,
44
+ proofs: string[],
45
+ }
46
+
41
47
  export interface VesuAdapterConfig {
42
48
  poolId: ContractAddr,
43
49
  collateral: TokenInfo,
@@ -156,6 +162,39 @@ export class VesuAdapter extends BaseAdapter {
156
162
  }
157
163
  }
158
164
  }
165
+
166
+ getDefispringRewardsAdapter = (id: string): () => AdapterLeafType<VesuDefiSpringRewardsCallParams> => {
167
+ return () => {
168
+ const packedArguments: bigint[] = [];
169
+ const output = {
170
+ id: BigInt(num.getDecimalString(shortString.encodeShortString(id))),
171
+ readableId: id,
172
+ data: [
173
+ SIMPLE_SANITIZER.toBigInt(), // sanitizer address
174
+ VESU_REWARDS_CONTRACT.toBigInt(), // contract
175
+ toBigInt(hash.getSelectorFromName("claim")), // method name
176
+ BigInt(packedArguments.length),
177
+ ...packedArguments
178
+ ]
179
+ };
180
+ return { leaf: output, callConstructor: this.getDefiSpringClaimCall().bind(this) };
181
+ }
182
+ }
183
+
184
+ getDefiSpringClaimCall = (): GenerateCallFn<VesuDefiSpringRewardsCallParams> => {
185
+ return (params: VesuDefiSpringRewardsCallParams) => ({
186
+ sanitizer: SIMPLE_SANITIZER,
187
+ call: {
188
+ contractAddress: VESU_REWARDS_CONTRACT,
189
+ selector: hash.getSelectorFromName('claim'),
190
+ calldata: [
191
+ BigInt(params.amount.toWei()),
192
+ BigInt(params.proofs.length),
193
+ ...params.proofs.map(proof => BigInt(num.hexToDecimalString(proof)))
194
+ ]
195
+ }
196
+ })
197
+ }
159
198
 
160
199
  formatAmountTypeEnum(amountType: VesuAmountType) {
161
200
  switch(amountType) {
@@ -7,9 +7,11 @@ import { VesuRebalanceSettings } from "./vesu-rebalance";
7
7
  import { assert, LeafData, logger, StandardMerkleTree } from "@/utils";
8
8
  import UniversalVaultAbi from '../data/universal-vault.abi.json';
9
9
  import ManagerAbi from '../data/vault-manager.abi.json';
10
- import { ApproveCallParams, BaseAdapter, CommonAdapter, FlashloanCallParams, GenerateCallFn, LeafAdapterFn, ManageCall, VesuAdapter, VesuModifyPositionCallParams, VesuPools } from "./universal-adapters";
10
+ import { ApproveCallParams, AvnuSwapCallParams, BaseAdapter, CommonAdapter, FlashloanCallParams, GenerateCallFn, LeafAdapterFn, ManageCall, VesuAdapter, VesuDefiSpringRewardsCallParams, VesuModifyPositionCallParams, VesuPools } from "./universal-adapters";
11
11
  import { Global } from "@/global";
12
- import { ERC20 } from "@/modules";
12
+ import { AvnuWrapper, ERC20 } from "@/modules";
13
+ import { AVNU_MIDDLEWARE } from "./universal-adapters/adapter-utils";
14
+ import { VesuHarvests } from "@/modules/harvests";
13
15
 
14
16
  export interface UniversalStrategySettings {
15
17
  vaultAddress: ContractAddr,
@@ -312,7 +314,8 @@ export class UniversalStrategy<
312
314
 
313
315
  // calculate estimated growth from strk rewards
314
316
  const netAPY = await this.netAPY();
315
- const defispringAPY = netAPY.splits.find(s => s.id === 'defispring')?.apy || 0;
317
+ // account only 80% of value
318
+ const defispringAPY = (netAPY.splits.find(s => s.id === 'defispring')?.apy || 0) * 0.8;
316
319
  if (!defispringAPY) throw new Error('DefiSpring APY not found');
317
320
 
318
321
  const timeDiff = (Math.round(Date.now() / 1000) - Number(lastReportTime));
@@ -605,6 +608,61 @@ export class UniversalStrategy<
605
608
  return manageCall;
606
609
  }
607
610
 
611
+ async getHarvestCall() {
612
+ const vesuHarvest = new VesuHarvests(this.config);
613
+ const harvestInfo = await vesuHarvest.getUnHarvestedRewards(this.metadata.additionalInfo.vaultAllocator);
614
+ if (harvestInfo.length != 1) {
615
+ throw new Error(`Expected 1 harvest info, got ${harvestInfo.length}`);
616
+ }
617
+
618
+ const amount = harvestInfo[0].claim.amount;
619
+ const actualReward = harvestInfo[0].actualReward;
620
+ const proofs = harvestInfo[0].proof;
621
+ if (actualReward.isZero()) {
622
+ throw new Error(`Expected non-zero actual reward, got ${harvestInfo[0].actualReward}`);
623
+ }
624
+
625
+ const manage1Info = this.getProofs<VesuDefiSpringRewardsCallParams>(UNIVERSAL_MANAGE_IDS.DEFISPRING_REWARDS);
626
+ const manageCall1 = manage1Info.callConstructor({
627
+ amount,
628
+ proofs
629
+ });
630
+ const proofIds: string[] = [UNIVERSAL_MANAGE_IDS.DEFISPRING_REWARDS];
631
+ const manageCalls: ManageCall[] = [manageCall1];
632
+
633
+ // swap rewards for underlying
634
+ const STRK = Global.getDefaultTokens().find(t => t.symbol === 'STRK')!;
635
+ if (this.asset().symbol != 'STRK') {
636
+ // approve
637
+ const manage2Info = this.getProofs<ApproveCallParams>(UNIVERSAL_MANAGE_IDS.APPROVE_SWAP_TOKEN1);
638
+ const manageCall2 = manage2Info.callConstructor({
639
+ amount: actualReward
640
+ });
641
+
642
+ // swap
643
+ const avnuModule = new AvnuWrapper();
644
+ const quote = await avnuModule.getQuotes(
645
+ STRK.address.address,
646
+ this.asset().address.address,
647
+ actualReward.toWei(),
648
+ this.address.address
649
+ );
650
+ const swapInfo = await avnuModule.getSwapInfo(quote, this.address.address, 0, this.address.address);
651
+ const manage3Info = this.getProofs<AvnuSwapCallParams>(UNIVERSAL_MANAGE_IDS.AVNU_SWAP_REWARDS);
652
+ const manageCall3 = manage3Info.callConstructor({
653
+ props: swapInfo
654
+ });
655
+ proofIds.push(UNIVERSAL_MANAGE_IDS.APPROVE_SWAP_TOKEN1);
656
+ proofIds.push(UNIVERSAL_MANAGE_IDS.AVNU_SWAP_REWARDS);
657
+
658
+ manageCalls.push(manageCall2);
659
+ manageCalls.push(manageCall3);
660
+ }
661
+
662
+ const manageCall = this.getManageCall(proofIds, manageCalls);
663
+ return { call: manageCall, reward: actualReward, tokenInfo: STRK };
664
+ }
665
+
608
666
  async getRebalanceCall(params: {
609
667
  isLeg1toLeg2: boolean,
610
668
  amount: Web3Number
@@ -646,7 +704,14 @@ export enum UNIVERSAL_MANAGE_IDS {
646
704
  APPROVE_TOKEN1 = 'approve_token1',
647
705
  APPROVE_TOKEN2 = 'approve_token2',
648
706
  APPROVE_BRING_LIQUIDITY = 'approve_bring_liquidity',
649
- BRING_LIQUIDITY = 'bring_liquidity'
707
+ BRING_LIQUIDITY = 'bring_liquidity',
708
+
709
+ // defi spring claim
710
+ DEFISPRING_REWARDS = 'defispring_rewards',
711
+
712
+ // avnu swaps
713
+ APPROVE_SWAP_TOKEN1 = 'approve_swap_token1',
714
+ AVNU_SWAP_REWARDS = 'avnu_swap_rewards'
650
715
  }
651
716
 
652
717
  export enum UNIVERSAL_ADAPTERS {
@@ -707,7 +772,15 @@ function getLooperSettings(
707
772
  // to bridge liquidity back to vault (used by bring_liquidity)
708
773
  vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(USDCToken.address, vaultSettings.vaultAddress, UNIVERSAL_MANAGE_IDS.APPROVE_BRING_LIQUIDITY).bind(commonAdapter));
709
774
  vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter(UNIVERSAL_MANAGE_IDS.BRING_LIQUIDITY).bind(commonAdapter));
710
- return vaultSettings;
775
+
776
+ // claim rewards
777
+ vaultSettings.leafAdapters.push(vesuAdapterUSDCETH.getDefispringRewardsAdapter(UNIVERSAL_MANAGE_IDS.DEFISPRING_REWARDS).bind(vesuAdapterUSDCETH));
778
+
779
+ // avnu swap
780
+ const STRKToken = Global.getDefaultTokens().find(token => token.symbol === 'STRK')!;
781
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(STRKToken.address, AVNU_MIDDLEWARE, UNIVERSAL_MANAGE_IDS.APPROVE_SWAP_TOKEN1).bind(commonAdapter));
782
+ vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(STRKToken.address, USDCToken.address, UNIVERSAL_MANAGE_IDS.AVNU_SWAP_REWARDS).bind(commonAdapter));
783
+ return vaultSettings;
711
784
  }
712
785
 
713
786
  const _riskFactor: RiskFactor[] = [