@strkfarm/sdk 1.0.28 → 1.0.30

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.
@@ -1,3 +1,4 @@
1
1
  export * from './autoCompounderStrk';
2
2
  export * from './vesu-rebalance';
3
- export * from './ekubo-cl-vault';
3
+ export * from './ekubo-cl-vault';
4
+ export * from './base-strategy';
@@ -1,7 +1,7 @@
1
1
  import { ContractAddr, Web3Number } from "@/dataTypes";
2
2
  import { FlowChartColors, getNoRiskTags, IConfig, IInvestmentFlow, IProtocol, IStrategyMetadata, RiskFactor, RiskType } from "@/interfaces";
3
- import { Pricer } from "@/modules";
4
- import { CairoCustomEnum, Contract, num, uint256 } from "starknet";
3
+ import { AvnuWrapper, Pricer, SwapInfo } from "@/modules";
4
+ import { Account, CairoCustomEnum, Contract, num, uint256 } from "starknet";
5
5
  import VesuRebalanceAbi from '@/data/vesu-rebalance.abi.json';
6
6
  import { Global, logger } from "@/global";
7
7
  import { assert } from "@/utils";
@@ -9,6 +9,8 @@ import axios from "axios";
9
9
  import { PricerBase } from "@/modules/pricerBase";
10
10
  import { BaseStrategy, SingleActionAmount, SingleTokenInfo } from "./base-strategy";
11
11
  import { getAPIUsingHeadlessBrowser } from "@/node/headless";
12
+ import { VesuHarvests } from "@/modules/harvests";
13
+ import VesuPoolIDs from "@/data/vesu_pools.json";
12
14
 
13
15
  interface PoolProps {
14
16
  pool_id: ContractAddr;
@@ -83,7 +85,7 @@ export class VesuRebalance extends BaseStrategy<SingleTokenInfo, SingleActionAmo
83
85
  * @param receiver - Address that will receive the strategy tokens
84
86
  * @returns Populated contract call for deposit
85
87
  */
86
- depositCall(amountInfo: SingleActionAmount, receiver: ContractAddr) {
88
+ async depositCall(amountInfo: SingleActionAmount, receiver: ContractAddr) {
87
89
  // Technically its not erc4626 abi, but we just need approve call
88
90
  // so, its ok to use it
89
91
  assert(amountInfo.tokenInfo.address.eq(this.asset().address), 'Deposit token mismatch');
@@ -100,7 +102,7 @@ export class VesuRebalance extends BaseStrategy<SingleTokenInfo, SingleActionAmo
100
102
  * @param owner - Address that owns the strategy tokens
101
103
  * @returns Populated contract call for withdrawal
102
104
  */
103
- withdrawCall(amountInfo: SingleActionAmount, receiver: ContractAddr, owner: ContractAddr) {
105
+ async withdrawCall(amountInfo: SingleActionAmount, receiver: ContractAddr, owner: ContractAddr) {
104
106
  return [this.contract.populate('withdraw', [uint256.bnToUint256(amountInfo.amount.toWei()), receiver.address, owner.address])];
105
107
  }
106
108
 
@@ -189,9 +191,10 @@ export class VesuRebalance extends BaseStrategy<SingleTokenInfo, SingleActionAmo
189
191
  logger.verbose(typeof _pool);
190
192
  logger.verbose(`name: ${_pool?.name}`);
191
193
  const name = _pool?.name;
192
- logger.verbose(`name2: ${name}`);
194
+ logger.verbose(`name2: ${name}, ${!name ? true : false}, ${name?.length}, ${typeof name}`);
193
195
  const assetInfo = _pool?.assets.find((d: any) => this.asset().address.eqString(d.address));
194
196
  if (!name) {
197
+ logger.verbose(`Pool not found`);
195
198
  throw new Error(`Pool name ${p.pool_id.address.toString()} not found`);
196
199
  }
197
200
  if (!assetInfo) {
@@ -302,15 +305,7 @@ export class VesuRebalance extends BaseStrategy<SingleTokenInfo, SingleActionAmo
302
305
  }
303
306
 
304
307
 
305
- let isErrorPoolsAPI = false;
306
- let pools: any[] = [];
307
- try {
308
- const data = await getAPIUsingHeadlessBrowser('https://api.vesu.xyz/pools');
309
- pools = data.data;
310
- } catch (e) {
311
- console.error(`${VesuRebalance.name}: Error fetching pools for ${this.address.address}`, e);
312
- isErrorPoolsAPI = true;
313
- }
308
+ let { pools, isErrorPoolsAPI } = await this.getVesuPools();
314
309
 
315
310
  const totalAssets = (await this.getTVL()).amount;
316
311
 
@@ -324,6 +319,34 @@ export class VesuRebalance extends BaseStrategy<SingleTokenInfo, SingleActionAmo
324
319
  }
325
320
  }
326
321
 
322
+ async getVesuPools(retry = 0): Promise<{pools: any[], isErrorPoolsAPI: boolean}> {
323
+ let isErrorPoolsAPI = false;
324
+ let pools: any[] = [];
325
+ try {
326
+ const data = await getAPIUsingHeadlessBrowser('https://api.vesu.xyz/pools');
327
+ pools = data.data;
328
+
329
+ // Vesu API is unstable sometimes, some Pools may be missing sometimes
330
+ for (const pool of VesuPoolIDs.data) {
331
+ const found = pools.find((d: any) => d.id === pool.id);
332
+ if (!found) {
333
+ logger.verbose(`VesuRebalance: pools: ${JSON.stringify(pools)}`);
334
+ logger.verbose(`VesuRebalance: Pool ${pool.id} not found in Vesu API, using hardcoded data`);
335
+ throw new Error('pool not found [sanity check]')
336
+ }
337
+ }
338
+ } catch (e) {
339
+ logger.error(`${VesuRebalance.name}: Error fetching pools for ${this.address.address}, retry ${retry}`, e);
340
+ isErrorPoolsAPI = true;
341
+ if (retry < 10) {
342
+ await new Promise((resolve) => setTimeout(resolve, 5000 * (retry + 1)));
343
+ return await this.getVesuPools(retry + 1);
344
+ }
345
+ }
346
+
347
+ return { pools, isErrorPoolsAPI };
348
+ }
349
+
327
350
  /**
328
351
  * Calculates the weighted average APY across all pools based on USD value.
329
352
  * @returns {Promise<number>} The weighted average APY across all pools
@@ -497,6 +520,46 @@ export class VesuRebalance extends BaseStrategy<SingleTokenInfo, SingleActionAmo
497
520
  });
498
521
  return [baseFlow];
499
522
  }
523
+
524
+ async harvest(acc: Account) {
525
+ const vesuHarvest = new VesuHarvests(this.config);
526
+ const harvests = await vesuHarvest.getUnHarvestedRewards(this.address);
527
+ const harvest = harvests[0];
528
+ const avnu = new AvnuWrapper();
529
+ let swapInfo: SwapInfo = {
530
+ token_from_address: harvest.token.address,
531
+ token_from_amount: uint256.bnToUint256(harvest.actualReward.toWei()),
532
+ token_to_address: this.asset().address.address,
533
+ token_to_amount: uint256.bnToUint256(0),
534
+ token_to_min_amount: uint256.bnToUint256(0),
535
+ beneficiary: this.address.address,
536
+ integrator_fee_amount_bps: 0,
537
+ integrator_fee_recipient: this.address.address,
538
+ routes: []
539
+ }
540
+ if (!this.asset().address.eqString(harvest.token.address)) {
541
+ const quote = await avnu.getQuotes(
542
+ harvest.token.address,
543
+ this.asset().address.address,
544
+ harvest.actualReward.toWei(),
545
+ this.address.address
546
+ );
547
+ swapInfo = await avnu.getSwapInfo(quote, this.address.address, 0, this.address.address);
548
+ }
549
+
550
+ return [
551
+ this.contract.populate('harvest', [
552
+ harvest.rewardsContract.address,
553
+ {
554
+ id: harvest.claim.id,
555
+ amount: harvest.claim.amount.toWei(),
556
+ claimee: harvest.claim.claimee.address
557
+ },
558
+ harvest.proof,
559
+ swapInfo
560
+ ])
561
+ ]
562
+ }
500
563
  }
501
564
 
502
565
  const _description = 'Automatically diversify {{TOKEN}} holdings into different Vesu pools while reducing risk and maximizing yield. Defi spring STRK Rewards are auto-compounded as well.'