@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.
- package/dist/cli.js +48 -26
- package/dist/cli.mjs +45 -23
- package/dist/index.browser.global.js +9857 -326
- package/dist/index.browser.mjs +9640 -108
- package/dist/index.d.ts +65 -16
- package/dist/index.js +9654 -121
- package/dist/index.mjs +9642 -110
- package/package.json +1 -1
- package/src/data/vesu_pools.json +9019 -0
- package/src/dataTypes/_bignumber.ts +15 -7
- package/src/global.ts +13 -6
- package/src/interfaces/common.ts +3 -0
- package/src/modules/avnu.ts +78 -59
- package/src/modules/harvests.ts +111 -0
- package/src/modules/pricer-from-api.ts +9 -8
- package/src/modules/zkLend.ts +2 -1
- package/src/strategies/base-strategy.ts +3 -3
- package/src/strategies/ekubo-cl-vault.ts +477 -55
- package/src/strategies/index.ts +2 -1
- package/src/strategies/vesu-rebalance.ts +77 -14
package/src/strategies/index.ts
CHANGED
|
@@ -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 =
|
|
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.'
|