@strkfarm/sdk 2.0.0-staging.4 → 2.0.0-staging.41
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 +10 -6
- package/dist/cli.mjs +10 -6
- package/dist/index.browser.global.js +29277 -26655
- package/dist/index.browser.mjs +4037 -1224
- package/dist/index.d.ts +287 -45
- package/dist/index.js +4316 -1489
- package/dist/index.mjs +4256 -1437
- package/package.json +4 -4
- package/src/data/yoloVault.abi.json +1109 -0
- package/src/dataTypes/_bignumber.ts +5 -0
- package/src/dataTypes/bignumber.browser.ts +5 -0
- package/src/dataTypes/bignumber.node.ts +5 -0
- package/src/global.ts +27 -0
- package/src/interfaces/common.tsx +68 -25
- package/src/modules/avnu.ts +1 -1
- package/src/modules/erc20.ts +18 -2
- package/src/strategies/base-strategy.ts +216 -6
- package/src/strategies/constants.ts +2 -2
- package/src/strategies/ekubo-cl-vault.tsx +210 -105
- package/src/strategies/factory.ts +21 -1
- package/src/strategies/index.ts +2 -0
- package/src/strategies/registry.ts +15 -30
- package/src/strategies/sensei.ts +156 -11
- package/src/strategies/types.ts +4 -0
- package/src/strategies/universal-adapters/vesu-adapter.ts +48 -27
- package/src/strategies/universal-lst-muliplier-strategy.tsx +1473 -574
- package/src/strategies/universal-strategy.tsx +141 -69
- package/src/strategies/vesu-rebalance.tsx +27 -11
- package/src/strategies/yoloVault.ts +747 -0
- package/src/utils/logger.node.ts +11 -4
- package/src/utils/strategy-utils.ts +6 -2
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
UniversalLstMultiplierStrategy,
|
|
10
10
|
HyperLSTStrategySettings
|
|
11
11
|
} from "./universal-lst-muliplier-strategy";
|
|
12
|
+
import { YoLoVault, YoloVaultSettings } from "./yoloVault";
|
|
12
13
|
import { VesuRebalance, VesuRebalanceSettings } from "./vesu-rebalance";
|
|
13
14
|
import { SenseiVault, SenseiVaultSettings } from "./sensei";
|
|
14
15
|
|
|
@@ -17,7 +18,8 @@ export enum FactoryStrategyType {
|
|
|
17
18
|
EKUBO_CL = "EKUBO_CL",
|
|
18
19
|
HYPER_LST = "HYPER_LST",
|
|
19
20
|
VESU_REBALANCE = "VESU_REBALANCE",
|
|
20
|
-
SENSEI = "SENSEI"
|
|
21
|
+
SENSEI = "SENSEI",
|
|
22
|
+
YOLO_VAULT = "YOLO_VAULT"
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export function createUniversalStrategy(
|
|
@@ -36,6 +38,14 @@ export function createEkuboCLStrategy(
|
|
|
36
38
|
return new EkuboCLVault(config, pricer, metadata);
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
export function createYoloVaultStrategy(
|
|
42
|
+
config: IConfig,
|
|
43
|
+
pricer: PricerBase,
|
|
44
|
+
metadata: IStrategyMetadata<YoloVaultSettings>
|
|
45
|
+
): YoLoVault {
|
|
46
|
+
return new YoLoVault(config, pricer, metadata);
|
|
47
|
+
}
|
|
48
|
+
|
|
39
49
|
export function createHyperLSTStrategy(
|
|
40
50
|
config: IConfig,
|
|
41
51
|
pricer: PricerBase,
|
|
@@ -67,6 +77,10 @@ export function getStrategyTypeFromMetadata(
|
|
|
67
77
|
metadata: IStrategyMetadata<any>
|
|
68
78
|
): FactoryStrategyType {
|
|
69
79
|
const info = metadata.additionalInfo;
|
|
80
|
+
|
|
81
|
+
if (info && "mainToken" in info && "secondaryToken" in info && "minEpochDurationSeconds" in info && "feeBps" in info) {
|
|
82
|
+
return FactoryStrategyType.YOLO_VAULT;
|
|
83
|
+
}
|
|
70
84
|
|
|
71
85
|
// Check for HyperLST (extends UniversalStrategySettings with borrowable_assets and underlyingToken)
|
|
72
86
|
if (info && "borrowable_assets" in info && "underlyingToken" in info) {
|
|
@@ -153,6 +167,12 @@ export function createStrategy(
|
|
|
153
167
|
pricer,
|
|
154
168
|
metadata as IStrategyMetadata<SenseiVaultSettings>
|
|
155
169
|
);
|
|
170
|
+
case FactoryStrategyType.YOLO_VAULT:
|
|
171
|
+
return createYoloVaultStrategy(
|
|
172
|
+
config,
|
|
173
|
+
pricer,
|
|
174
|
+
metadata as IStrategyMetadata<YoloVaultSettings>
|
|
175
|
+
);
|
|
156
176
|
default:
|
|
157
177
|
throw new Error(`Unknown strategy type: ${type}`);
|
|
158
178
|
}
|
package/src/strategies/index.ts
CHANGED
|
@@ -3,8 +3,10 @@ export * from './vesu-rebalance';
|
|
|
3
3
|
export * from './ekubo-cl-vault';
|
|
4
4
|
export * from './base-strategy';
|
|
5
5
|
export * from './sensei';
|
|
6
|
+
export * from './yoloVault';
|
|
6
7
|
export * from './universal-adapters';
|
|
7
8
|
export * from './universal-strategy';
|
|
8
9
|
export * from './universal-lst-muliplier-strategy';
|
|
9
10
|
export * from "./registry";
|
|
10
11
|
export * from "./factory";
|
|
12
|
+
export * from "./types";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IStrategyMetadata } from "@/interfaces";
|
|
1
|
+
import { getAllStrategyTags, IStrategyMetadata } from "@/interfaces";
|
|
2
2
|
import {
|
|
3
3
|
EkuboCLVaultStrategies,
|
|
4
4
|
CLVaultStrategySettings,
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
import { UniversalStrategies } from "./universal-strategy";
|
|
11
11
|
import { VesuRebalanceStrategies } from "./vesu-rebalance";
|
|
12
12
|
import { SenseiStrategies } from "./sensei";
|
|
13
|
+
import { YoloVaultStrategies } from "./yoloVault";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Filter option definition
|
|
@@ -26,7 +27,6 @@ export interface FilterOption {
|
|
|
26
27
|
export interface StrategyFilterMetadata {
|
|
27
28
|
assets: FilterOption[];
|
|
28
29
|
protocols: FilterOption[];
|
|
29
|
-
categories: FilterOption[];
|
|
30
30
|
quickFilters: FilterOption[];
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -39,6 +39,7 @@ export enum StrategyType {
|
|
|
39
39
|
HYPER_LST = "hyper-lst",
|
|
40
40
|
VESU_REBALANCE = "vesu-rebalance",
|
|
41
41
|
SENSEI = "sensei",
|
|
42
|
+
YOLO_VAULT = "yolo-vault",
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
/**
|
|
@@ -50,7 +51,6 @@ export interface StrategyMetadata {
|
|
|
50
51
|
type: StrategyType;
|
|
51
52
|
assets: string[]; // Token symbols (e.g., ["STRK", "USDC"])
|
|
52
53
|
protocols: string[]; // Protocol names (e.g., ["Ekubo"])
|
|
53
|
-
category: string; // Category (e.g., "BTC", "Meta Vaults")
|
|
54
54
|
tags: string[];
|
|
55
55
|
curator?: { name: string; logo: string };
|
|
56
56
|
isRetired: boolean;
|
|
@@ -145,6 +145,16 @@ export function buildStrategyRegistry(): StrategyRegistryEntry[] {
|
|
|
145
145
|
});
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
// Register Yolo Vault strategies
|
|
149
|
+
if (YoloVaultStrategies && Array.isArray(YoloVaultStrategies)) {
|
|
150
|
+
YoloVaultStrategies.forEach((metadata) => {
|
|
151
|
+
registry.push({
|
|
152
|
+
metadata: metadata as any,
|
|
153
|
+
type: StrategyType.YOLO_VAULT,
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
148
158
|
return registry;
|
|
149
159
|
}
|
|
150
160
|
|
|
@@ -161,7 +171,6 @@ export function getAllStrategyMetadata(): StrategyMetadata[] {
|
|
|
161
171
|
type: entry.type,
|
|
162
172
|
assets: extractAssets(entry.metadata),
|
|
163
173
|
protocols: entry.metadata.protocols.map(p => p.name.toLowerCase()),
|
|
164
|
-
category: entry.metadata.category,
|
|
165
174
|
tags: entry.metadata.tags || [],
|
|
166
175
|
curator: entry.metadata.curator,
|
|
167
176
|
isRetired: isRetired(entry.metadata),
|
|
@@ -208,41 +217,17 @@ export function getFilterMetadata(): StrategyFilterMetadata {
|
|
|
208
217
|
.sort()
|
|
209
218
|
.map((id) => ({
|
|
210
219
|
id,
|
|
211
|
-
label:
|
|
212
|
-
id === "meta-vaults"
|
|
213
|
-
? "Meta Vaults"
|
|
214
|
-
: id.charAt(0).toUpperCase() + id.slice(1)
|
|
215
|
-
}));
|
|
216
|
-
|
|
217
|
-
// Extract unique categories
|
|
218
|
-
const categorySet = new Set<string>();
|
|
219
|
-
allMetadata.forEach((meta) => {
|
|
220
|
-
if (meta.category) categorySet.add(meta.category);
|
|
221
|
-
});
|
|
222
|
-
const categories: FilterOption[] = Array.from(categorySet)
|
|
223
|
-
.sort()
|
|
224
|
-
.map((id) => ({
|
|
225
|
-
id,
|
|
226
|
-
label:
|
|
227
|
-
id === "btc"
|
|
228
|
-
? "BTC"
|
|
229
|
-
: id === "meta-vaults"
|
|
230
|
-
? "Meta Vaults"
|
|
231
|
-
: "All"
|
|
220
|
+
label: id.charAt(0).toUpperCase() + id.slice(1)
|
|
232
221
|
}));
|
|
233
222
|
|
|
234
223
|
const quickFilters: FilterOption[] = [
|
|
235
224
|
{ id: "all", label: "All Strategies" },
|
|
236
|
-
{ id: "
|
|
237
|
-
{ id: "ekubo", label: "Ekubo" },
|
|
238
|
-
{ id: "endur", label: "Endur" },
|
|
239
|
-
{ id: "meta-vaults", label: "Meta Vaults" }
|
|
225
|
+
...getAllStrategyTags().map((tag) => ({ id: tag.toLowerCase().replaceAll(" ", "-"), label: tag })),
|
|
240
226
|
];
|
|
241
227
|
|
|
242
228
|
return {
|
|
243
229
|
assets,
|
|
244
230
|
protocols,
|
|
245
|
-
categories,
|
|
246
231
|
quickFilters
|
|
247
232
|
};
|
|
248
233
|
}
|
package/src/strategies/sensei.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import { getNoRiskTags, highlightTextWithLinks, IConfig, IProtocol, IStrategyMetadata, RiskFactor, RiskType,
|
|
2
|
-
import {
|
|
1
|
+
import { getNoRiskTags, highlightTextWithLinks, IConfig, IProtocol, IStrategyMetadata, RiskFactor, RiskType, StrategyTag, TokenInfo, AuditStatus, SourceCodeType, AccessControlType, InstantWithdrawalVault, StrategyLiveStatus, VaultType, UnwrapLabsCurator } from "@/interfaces";
|
|
2
|
+
import {
|
|
3
|
+
BaseStrategy,
|
|
4
|
+
SingleActionAmount,
|
|
5
|
+
SingleTokenInfo,
|
|
6
|
+
UserPositionCard,
|
|
7
|
+
UserPositionCardsInput,
|
|
8
|
+
} from "./base-strategy";
|
|
3
9
|
import { ContractAddr, Web3Number } from "@/dataTypes";
|
|
4
|
-
import { Call, Contract, uint256, BlockIdentifier } from "starknet";
|
|
10
|
+
import { Call, Contract, num, uint256, BlockIdentifier } from "starknet";
|
|
5
11
|
import SenseiABI from "@/data/sensei.abi.json";
|
|
6
12
|
import { getTrovesEndpoint, logger } from "@/utils";
|
|
7
13
|
import { Global } from "@/global";
|
|
@@ -11,6 +17,8 @@ import ERC20ABI from "@/data/erc20.abi.json";
|
|
|
11
17
|
import { AvnuWrapper } from "@/modules";
|
|
12
18
|
import { gql } from "@apollo/client";
|
|
13
19
|
import apolloClient from "@/modules/apollo-client";
|
|
20
|
+
import { VesuAdapter, VesuPools } from "./universal-adapters/vesu-adapter";
|
|
21
|
+
import { LSTAPRService } from "@/modules/lst-apr";
|
|
14
22
|
|
|
15
23
|
export interface SenseiVaultSettings {
|
|
16
24
|
mainToken: TokenInfo;
|
|
@@ -92,7 +100,7 @@ export class SenseiVault extends BaseStrategy<
|
|
|
92
100
|
tokenInfo: this.metadata.depositTokens[0],
|
|
93
101
|
};
|
|
94
102
|
} catch (error) {
|
|
95
|
-
console.error(
|
|
103
|
+
console.error(`[SDK] Error fetching TVL for ${this.metadata.id}:`, error);
|
|
96
104
|
return {
|
|
97
105
|
usdValue: 0,
|
|
98
106
|
amount: new Web3Number('0', this.metadata.depositTokens[0].decimals),
|
|
@@ -236,12 +244,122 @@ export class SenseiVault extends BaseStrategy<
|
|
|
236
244
|
return settings;
|
|
237
245
|
};
|
|
238
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Calculate lifetime earnings for a user
|
|
249
|
+
* Not yet implemented for Sensei Vault strategy
|
|
250
|
+
*/
|
|
251
|
+
getLifetimeEarnings(
|
|
252
|
+
userTVL: SingleTokenInfo,
|
|
253
|
+
investmentFlows: Array<{ amount: string; type: string; timestamp: number; tx_hash: string }>
|
|
254
|
+
): any {
|
|
255
|
+
throw new Error("getLifetimeEarnings is not implemented yet for this strategy");
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async netAPY(): Promise<number> {
|
|
259
|
+
try {
|
|
260
|
+
// Fetch Vesu pools and select the Re7 xSTRK pool
|
|
261
|
+
const { pools } = await VesuAdapter.getVesuPools();
|
|
262
|
+
const re7PoolId = VesuPools.Re7xSTRK;
|
|
263
|
+
const pool = pools.find((p: any) =>
|
|
264
|
+
ContractAddr.from(num.getHexString(p.id)).eq(re7PoolId),
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
if (!pool) {
|
|
268
|
+
logger.warn(`${SenseiVault.name}::netAPY - Re7 xSTRK pool not found`);
|
|
269
|
+
return 0;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const mainSymbol = this.metadata.additionalInfo.mainToken.symbol.toLowerCase(); // STRK
|
|
273
|
+
const secondarySymbol =
|
|
274
|
+
this.metadata.additionalInfo.secondaryToken.symbol.toLowerCase(); // xSTRK
|
|
275
|
+
|
|
276
|
+
const collateralAssetStats = pool.assets.find(
|
|
277
|
+
(a: any) => String(a.symbol).toLowerCase() === secondarySymbol,
|
|
278
|
+
)?.stats;
|
|
279
|
+
const debtAssetStats = pool.assets.find(
|
|
280
|
+
(a: any) => String(a.symbol).toLowerCase() === mainSymbol,
|
|
281
|
+
)?.stats;
|
|
282
|
+
|
|
283
|
+
if (!collateralAssetStats || !debtAssetStats) {
|
|
284
|
+
logger.warn(
|
|
285
|
+
`${SenseiVault.name}::netAPY - Missing collateral/debt stats on Vesu pool`,
|
|
286
|
+
);
|
|
287
|
+
return 0;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Base xSTRK lending APY from Vesu
|
|
291
|
+
const xstrkSupplyAPY =
|
|
292
|
+
Number(collateralAssetStats.supplyApy?.value || 0) / 1e18;
|
|
293
|
+
|
|
294
|
+
// STRK rewards APR on xSTRK collateral from Vesu
|
|
295
|
+
const strkRewardsAPR = collateralAssetStats.defiSpringSupplyApr
|
|
296
|
+
? Number(collateralAssetStats.defiSpringSupplyApr.value || 0) / 1e18
|
|
297
|
+
: 0;
|
|
298
|
+
|
|
299
|
+
// STRK borrow APY from Vesu
|
|
300
|
+
const borrowAPY =
|
|
301
|
+
Number(debtAssetStats.borrowApr?.value || 0) / 1e18;
|
|
302
|
+
|
|
303
|
+
// LST APR for xSTRK from Endur (based on underlying STRK asset)
|
|
304
|
+
const lstAPY = await LSTAPRService.getLSTAPR(
|
|
305
|
+
this.metadata.additionalInfo.mainToken.address,
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
// Collateral APY = Vesu xSTRK supply + Endur xSTRK APR + STRK rewards
|
|
309
|
+
const collateralAPY = xstrkSupplyAPY + lstAPY + strkRewardsAPR;
|
|
310
|
+
|
|
311
|
+
const feeFactor = this.metadata.additionalInfo.feeBps / 10000; // convert bps to decimal
|
|
312
|
+
const feeAdjustedColAPY =
|
|
313
|
+
collateralAPY - strkRewardsAPR * feeFactor;
|
|
314
|
+
|
|
315
|
+
// Position info (collateral & debt in USD terms)
|
|
316
|
+
const { collateralUSDValue, debtUSDValue } =
|
|
317
|
+
await this.getPositionInfo();
|
|
318
|
+
|
|
319
|
+
const collateralUSD = Number(collateralUSDValue.toFixed(6));
|
|
320
|
+
const debtUSD = Number(debtUSDValue.toFixed(6));
|
|
321
|
+
|
|
322
|
+
// Compute expected leverage using the same math as app-side strategy
|
|
323
|
+
const targetHf = this.metadata.additionalInfo.targetHfBps / 10000;
|
|
324
|
+
const xSTRKPrice = await this.getSecondaryTokenPriceRelativeToMain();
|
|
325
|
+
const denominator = targetHf * xSTRKPrice - 0.87;
|
|
326
|
+
if (denominator <= 0) {
|
|
327
|
+
logger.warn(
|
|
328
|
+
`${SenseiVault.name}::netAPY - Invalid denominator in leverage calc`,
|
|
329
|
+
);
|
|
330
|
+
return 0;
|
|
331
|
+
}
|
|
332
|
+
const borrowedSTRK = (0.87 * xSTRKPrice) / denominator;
|
|
333
|
+
const expectedLeverage = 1 + borrowedSTRK;
|
|
334
|
+
if (!Number.isFinite(expectedLeverage) || expectedLeverage <= 0) {
|
|
335
|
+
logger.warn(
|
|
336
|
+
`${SenseiVault.name}::netAPY - Non-positive or invalid expectedLeverage`,
|
|
337
|
+
);
|
|
338
|
+
return 0;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const payoff =
|
|
342
|
+
collateralUSD * feeAdjustedColAPY - debtUSD * borrowAPY;
|
|
343
|
+
const investment = collateralUSD - debtUSD;
|
|
344
|
+
|
|
345
|
+
if (investment === 0) {
|
|
346
|
+
return 0;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const netAPY = payoff / investment;
|
|
350
|
+
return Number.isFinite(netAPY) ? netAPY : 0;
|
|
351
|
+
} catch (error) {
|
|
352
|
+
logger.error(`${SenseiVault.name}::netAPY - Error`, error);
|
|
353
|
+
return 0;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
239
357
|
/**
|
|
240
358
|
* Calculates user realized APY based on position growth accounting for deposits and withdrawals.
|
|
241
359
|
* Returns the APY as a number.
|
|
360
|
+
* Not implemented for Sensei Strategy yet.
|
|
242
361
|
*/
|
|
243
362
|
async getUserRealizedAPY(
|
|
244
|
-
userAddress: ContractAddr,
|
|
245
363
|
blockIdentifier: BlockIdentifier = "latest",
|
|
246
364
|
sinceBlocks = 600000
|
|
247
365
|
): Promise<number> {
|
|
@@ -387,7 +505,10 @@ export class SenseiVault extends BaseStrategy<
|
|
|
387
505
|
return apy;
|
|
388
506
|
*/
|
|
389
507
|
}
|
|
390
|
-
|
|
508
|
+
|
|
509
|
+
async getUserPositionCards(input: UserPositionCardsInput): Promise<UserPositionCard[]> {
|
|
510
|
+
return [await this.createApyCard(input)];
|
|
511
|
+
}
|
|
391
512
|
}
|
|
392
513
|
|
|
393
514
|
const senseiDescription = `Deposit your {{token1}} to automatically loop your funds via Endur ({{token2}}) and Vesu to create a delta neutral position. This strategy is designed to maximize your yield on {{token1}}. Your position is automatically adjusted periodically to maintain a healthy health factor. You receive a NFT as representation for your stake on Troves. You can withdraw anytime by redeeming your NFT for {{token1}}.`;
|
|
@@ -473,6 +594,11 @@ export const SenseiStrategies: IStrategyMetadata<SenseiVaultSettings>[] =
|
|
|
473
594
|
),
|
|
474
595
|
launchBlock: 1053811,
|
|
475
596
|
type: "Other",
|
|
597
|
+
curator: UnwrapLabsCurator,
|
|
598
|
+
vaultType: {
|
|
599
|
+
type: VaultType.LOOPING,
|
|
600
|
+
description: "Creates leveraged looping position on xSTRK by borrowing STRK to increase yield"
|
|
601
|
+
},
|
|
476
602
|
depositTokens: [
|
|
477
603
|
Global.getDefaultTokens().find((t) => t.symbol === "STRK")!
|
|
478
604
|
],
|
|
@@ -486,7 +612,7 @@ export const SenseiStrategies: IStrategyMetadata<SenseiVaultSettings>[] =
|
|
|
486
612
|
tab: "all"
|
|
487
613
|
}
|
|
488
614
|
],
|
|
489
|
-
liveStatus: StrategyLiveStatus.
|
|
615
|
+
liveStatus: StrategyLiveStatus.RETIRED,
|
|
490
616
|
isPaused: false,
|
|
491
617
|
isInMaintenance: false,
|
|
492
618
|
isAudited: false,
|
|
@@ -519,8 +645,7 @@ export const SenseiStrategies: IStrategyMetadata<SenseiVaultSettings>[] =
|
|
|
519
645
|
"Repeat the process to loop your position",
|
|
520
646
|
"Claim DeFi spring (STRK) rewards weekly and reinvest",
|
|
521
647
|
],
|
|
522
|
-
|
|
523
|
-
tags: [StrategyTag.SENSEI],
|
|
648
|
+
tags: [StrategyTag.LEVERED],
|
|
524
649
|
security: {
|
|
525
650
|
auditStatus: AuditStatus.AUDITED,
|
|
526
651
|
sourceCode: {
|
|
@@ -528,13 +653,33 @@ export const SenseiStrategies: IStrategyMetadata<SenseiVaultSettings>[] =
|
|
|
528
653
|
contractLink: "https://github.com/trovesfi/troves-contracts",
|
|
529
654
|
},
|
|
530
655
|
accessControl: {
|
|
531
|
-
type: AccessControlType.
|
|
656
|
+
type: AccessControlType.ROLE_BASED_ACCESS,
|
|
532
657
|
addresses: [ContractAddr.from("0x0")],
|
|
533
658
|
timeLock: "2 Days",
|
|
534
659
|
},
|
|
535
660
|
},
|
|
536
661
|
redemptionInfo: {
|
|
537
662
|
instantWithdrawalVault: InstantWithdrawalVault.YES,
|
|
663
|
+
redemptionsInfo: [],
|
|
664
|
+
alerts: [],
|
|
665
|
+
},
|
|
666
|
+
usualTimeToEarnings: "2 weeks",
|
|
667
|
+
usualTimeToEarningsDescription: "Strategy returns depend on LST price on DEXes. Even though the true price of LST on Endur increases continuously, the DEX price may lag sometimes, and historically is seen to rebase at least once every 2 hours. This is when you realise your earnings.",
|
|
668
|
+
points: [{
|
|
669
|
+
multiplier: 4,
|
|
670
|
+
logo: 'https://endur.fi/favicon.ico',
|
|
671
|
+
toolTip: "This strategy holds xSTRK. Earn 3-4x Endur points on your xSTRK due to the leverage. Points can be found on endur.fi.",
|
|
672
|
+
}],
|
|
673
|
+
discontinuationInfo: {
|
|
674
|
+
info: highlightTextWithLinks(
|
|
675
|
+
"This strategy is retired. All funds have been moved to Hyper xSTRK.",
|
|
676
|
+
[
|
|
677
|
+
{
|
|
678
|
+
highlight: "Hyper xSTRK",
|
|
679
|
+
link: "/strategy/hyper_xstrk",
|
|
680
|
+
},
|
|
681
|
+
]
|
|
682
|
+
),
|
|
538
683
|
},
|
|
539
684
|
},
|
|
540
|
-
];
|
|
685
|
+
];
|
|
@@ -234,6 +234,25 @@ export const VesuPools = {
|
|
|
234
234
|
Re7xSTRK: ContractAddr.from('0x052fb52363939c3aa848f8f4ac28f0a51379f8d1b971d8444de25fbd77d8f161'),
|
|
235
235
|
Re7xBTC: ContractAddr.from('0x3a8416bf20d036df5b1cf3447630a2e1cb04685f6b0c3a70ed7fb1473548ecf'),
|
|
236
236
|
Prime: ContractAddr.from('0x451fe483d5921a2919ddd81d0de6696669bccdacd859f72a4fba7656b97c3b5'),
|
|
237
|
+
Re7STRK: ContractAddr.from('0x01fcdacc1d8184eca7b472b5acbaf1500cec9d5683ca95fede8128b46c8f9cc2'),
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export const VesuPoolMetadata = {
|
|
241
|
+
[VesuPools.Genesis.address]: {
|
|
242
|
+
name: 'Genesis',
|
|
243
|
+
},
|
|
244
|
+
[VesuPools.Re7xSTRK.address]: {
|
|
245
|
+
name: 'Re7 xSTRK',
|
|
246
|
+
},
|
|
247
|
+
[VesuPools.Re7xBTC.address]: {
|
|
248
|
+
name: 'Re7 xBTC',
|
|
249
|
+
},
|
|
250
|
+
[VesuPools.Prime.address]: {
|
|
251
|
+
name: 'Prime',
|
|
252
|
+
},
|
|
253
|
+
[VesuPools.Re7STRK.address]: {
|
|
254
|
+
name: 'Re7 STRK',
|
|
255
|
+
},
|
|
237
256
|
}
|
|
238
257
|
|
|
239
258
|
export const extensionMap: {[key: string]: ContractAddr} = {};
|
|
@@ -418,14 +437,14 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
418
437
|
}
|
|
419
438
|
}
|
|
420
439
|
|
|
421
|
-
getVesuModifyDelegationAdapter = (id: string): LeafAdapterFn<VesuModifyDelegationCallParams> => {
|
|
440
|
+
getVesuModifyDelegationAdapter = (id: string, delegatee: ContractAddr): LeafAdapterFn<VesuModifyDelegationCallParams> => {
|
|
422
441
|
return () => {
|
|
423
442
|
const { addr: VESU_SINGLETON, isV2 } = getVesuSingletonAddress(this.config.poolId);
|
|
424
443
|
const packedArguments: bigint[] = isV2 ? [
|
|
425
|
-
toBigInt(
|
|
444
|
+
toBigInt(delegatee.toString()), // v2
|
|
426
445
|
] : [
|
|
427
446
|
this.config.poolId.toBigInt(),
|
|
428
|
-
toBigInt(
|
|
447
|
+
toBigInt(delegatee.toString()), // v1
|
|
429
448
|
];
|
|
430
449
|
const output = this.constructSimpleLeafData({
|
|
431
450
|
id: id,
|
|
@@ -434,29 +453,31 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
434
453
|
packedArguments
|
|
435
454
|
}, isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER_VESU_V1_DELEGATIONS);
|
|
436
455
|
|
|
437
|
-
return { leaf: output, callConstructor: this.getVesuModifyDelegationCall.bind(this) };
|
|
456
|
+
return { leaf: output, callConstructor: this.getVesuModifyDelegationCall(delegatee).bind(this) };
|
|
438
457
|
}
|
|
439
458
|
}
|
|
440
459
|
|
|
441
|
-
getVesuModifyDelegationCall = (
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
+
getVesuModifyDelegationCall = (delegatee: ContractAddr) => {
|
|
461
|
+
return (params: VesuModifyDelegationCallParams) => {
|
|
462
|
+
const VESU_SINGLETON = getVesuSingletonAddress(this.config.poolId).addr;
|
|
463
|
+
const { contract, isV2 } = this.getVesuSingletonContract(getMainnetConfig(), this.config.poolId);
|
|
464
|
+
const call = contract.populate('modify_delegation', isV2 ? {
|
|
465
|
+
delegatee: delegatee.toBigInt(),
|
|
466
|
+
delegation: params.delegation,
|
|
467
|
+
} : {
|
|
468
|
+
pool_id: this.config.poolId.toBigInt(),
|
|
469
|
+
delegatee: delegatee.toBigInt(),
|
|
470
|
+
delegation: params.delegation,
|
|
471
|
+
});
|
|
472
|
+
return {
|
|
473
|
+
sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER_VESU_V1_DELEGATIONS,
|
|
474
|
+
call: {
|
|
475
|
+
contractAddress: VESU_SINGLETON,
|
|
476
|
+
selector: hash.getSelectorFromName('modify_delegation'),
|
|
477
|
+
calldata: [
|
|
478
|
+
...call.calldata as bigint[]
|
|
479
|
+
]
|
|
480
|
+
}
|
|
460
481
|
}
|
|
461
482
|
}
|
|
462
483
|
}
|
|
@@ -654,12 +675,12 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
654
675
|
amount: collateralAmount,
|
|
655
676
|
token: this.config.collateral,
|
|
656
677
|
usdValue: collateralAmount.multipliedBy(token1Price.price).toNumber(),
|
|
657
|
-
remarks:
|
|
678
|
+
remarks: `Collateral - ${VesuPoolMetadata[this.config.poolId.address].name} pool`
|
|
658
679
|
}, {
|
|
659
680
|
amount: debtAmount,
|
|
660
681
|
token: this.config.debt,
|
|
661
682
|
usdValue: debtAmount.multipliedBy(token2Price.price).toNumber(),
|
|
662
|
-
remarks:
|
|
683
|
+
remarks: `Debt - ${VesuPoolMetadata[this.config.poolId.address].name} pool`
|
|
663
684
|
}];
|
|
664
685
|
this.setCache(CACHE_KEY, value, 60000); // ttl: 1min
|
|
665
686
|
return value;
|
|
@@ -747,7 +768,7 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
747
768
|
let pools: any[] = [];
|
|
748
769
|
try {
|
|
749
770
|
const data = await getAPIUsingHeadlessBrowser(
|
|
750
|
-
`${ENDPOINTS.
|
|
771
|
+
`${ENDPOINTS.VESU_BASE}/pools`
|
|
751
772
|
);
|
|
752
773
|
pools = data.data;
|
|
753
774
|
|
|
@@ -893,4 +914,4 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
893
914
|
}
|
|
894
915
|
throw new Error('Max utilization not found');
|
|
895
916
|
}
|
|
896
|
-
}
|
|
917
|
+
}
|