@strkfarm/sdk 1.0.62 → 1.0.64
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.browser.global.js +660 -372
- package/dist/index.browser.mjs +357 -69
- package/dist/index.d.ts +27 -3
- package/dist/index.js +358 -72
- package/dist/index.mjs +360 -74
- package/package.json +1 -1
- package/src/global.ts +19 -1
- package/src/interfaces/common.tsx +1 -0
- package/src/interfaces/risks.ts +175 -0
- package/src/modules/harvests.ts +4 -2
- package/src/notifs/telegram.ts +3 -3
- package/src/strategies/ekubo-cl-vault.tsx +201 -71
- package/src/strategies/universal-adapters/adapter-utils.ts +3 -1
- package/src/strategies/universal-adapters/common-adapter.ts +57 -1
- package/src/strategies/universal-adapters/vesu-adapter.ts +39 -0
- package/src/strategies/universal-strategy.tsx +78 -5
package/src/global.ts
CHANGED
|
@@ -58,7 +58,7 @@ const defaultTokens: TokenInfo[] = [{
|
|
|
58
58
|
name: 'WBTC',
|
|
59
59
|
symbol: 'WBTC',
|
|
60
60
|
logo: 'https://assets.troves.fi/integrations/tokens/wbtc.svg',
|
|
61
|
-
address: ContractAddr.from('
|
|
61
|
+
address: ContractAddr.from('0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac'),
|
|
62
62
|
decimals: 8,
|
|
63
63
|
coingeckId: undefined,
|
|
64
64
|
displayDecimals: 6,
|
|
@@ -72,6 +72,24 @@ const defaultTokens: TokenInfo[] = [{
|
|
|
72
72
|
coingeckId: undefined,
|
|
73
73
|
displayDecimals: 6,
|
|
74
74
|
priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
|
|
75
|
+
}, {
|
|
76
|
+
name: 'solvBTC',
|
|
77
|
+
symbol: 'solvBTC',
|
|
78
|
+
logo: 'https://assets.strkfarm.com/integrations/tokens/solvbtc.svg',
|
|
79
|
+
address: ContractAddr.from('0x0593e034dda23eea82d2ba9a30960ed42cf4a01502cc2351dc9b9881f9931a68'),
|
|
80
|
+
decimals: 18,
|
|
81
|
+
coingeckId: undefined,
|
|
82
|
+
displayDecimals: 6,
|
|
83
|
+
priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
|
|
84
|
+
}, {
|
|
85
|
+
name: 'LBTC',
|
|
86
|
+
symbol: 'LBTC',
|
|
87
|
+
logo: 'https://assets.strkfarm.com/integrations/tokens/lbtc.svg',
|
|
88
|
+
address: ContractAddr.from('0x036834a40984312f7f7de8d31e3f6305b325389eaeea5b1c0664b2fb936461a4'),
|
|
89
|
+
decimals: 8,
|
|
90
|
+
coingeckId: undefined,
|
|
91
|
+
displayDecimals: 6,
|
|
92
|
+
priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
|
|
75
93
|
}]
|
|
76
94
|
const tokens: TokenInfo[] = defaultTokens;
|
|
77
95
|
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { RiskType } from "./common";
|
|
2
|
+
|
|
3
|
+
export enum MarketRiskLevel {
|
|
4
|
+
NO_RISK = 0,
|
|
5
|
+
VERY_LOW_VOLATILITY = 1,
|
|
6
|
+
LOW_VOLATILITY = 2,
|
|
7
|
+
MODERATE_VOLATILITY = 3,
|
|
8
|
+
HIGH_VOLATILITY = 4,
|
|
9
|
+
VERY_HIGH_VOLATILITY = 5
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export enum ImpermanentLossLevel {
|
|
13
|
+
NO_RISK = 0,
|
|
14
|
+
HIGHLY_CORRELATED = 1, // e.g. xSTRK/STRK
|
|
15
|
+
CORRELATED = 2, // e.g. BTC/SOL
|
|
16
|
+
NON_CORRELATED = 3, // e.g. STRK/USDC
|
|
17
|
+
LEVERAGED_CORRELATED = 4, // Added leverage on correlated pairs
|
|
18
|
+
LEVERAGED_NON_CORRELATED = 5 // Added leverage on non-correlated pairs
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export enum LiquidationRiskLevel {
|
|
22
|
+
NO_RISK = 0,
|
|
23
|
+
VERY_LOW_PROBABILITY = 1,
|
|
24
|
+
LOW_PROBABILITY = 2,
|
|
25
|
+
MODERATE_PROBABILITY = 3,
|
|
26
|
+
HIGH_PROBABILITY = 4,
|
|
27
|
+
CRITICAL_PROBABILITY = 5
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export enum LowLiquidityRiskLevel {
|
|
31
|
+
HIGH_LIQUIDITY = 0,
|
|
32
|
+
GOOD_LIQUIDITY = 1,
|
|
33
|
+
ADEQUATE_LIQUIDITY = 2,
|
|
34
|
+
MODERATE_CONCERNS = 3,
|
|
35
|
+
LOW_LIQUIDITY = 4,
|
|
36
|
+
SEVERE_CONSTRAINTS = 5
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export enum SmartContractRiskLevel {
|
|
40
|
+
NO_RISK = 0,
|
|
41
|
+
BATTLE_TESTED = 1, // Well-audited, battle-tested contracts
|
|
42
|
+
WELL_AUDITED = 2, // Audited contracts with good track record
|
|
43
|
+
RECENTLY_AUDITED = 3, // Recently audited or some complexity
|
|
44
|
+
UNAUDITED = 4, // Unaudited or complex logic
|
|
45
|
+
EXPERIMENTAL = 5 // Experimental or known vulnerabilities
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export enum OracleRiskLevel {
|
|
49
|
+
NO_DEPENDENCY = 0,
|
|
50
|
+
MULTIPLE_RELIABLE = 1, // Multiple reliable oracles (Chainlink, etc.)
|
|
51
|
+
SINGLE_RELIABLE = 2, // Single reliable oracle
|
|
52
|
+
LESS_ESTABLISHED = 3, // Less established oracle
|
|
53
|
+
UNPROVEN = 4, // Custom or unproven oracle
|
|
54
|
+
UNRELIABLE = 5 // No oracle or highly unreliable
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export enum TechnicalRiskLevel {
|
|
58
|
+
NO_RISK = 0,
|
|
59
|
+
STABLE_INFRASTRUCTURE = 1, // Stable, well-tested infrastructure
|
|
60
|
+
ESTABLISHED_PROTOCOLS = 2, // Established protocols
|
|
61
|
+
SOME_COMPLEXITY = 3, // Some technical complexity
|
|
62
|
+
NEW_IMPLEMENTATION = 4, // New or complex technical implementation
|
|
63
|
+
EXPERIMENTAL_TECHNOLOGY = 5 // Experimental or untested technology
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export enum CounterpartyRiskLevel {
|
|
67
|
+
NO_RISK = 0,
|
|
68
|
+
FULLY_DECENTRALIZED = 1, // Decentralized, no counterparty
|
|
69
|
+
REPUTABLE_COUNTERPARTY = 2, // Established, reputable counterparty
|
|
70
|
+
SOME_EXPOSURE = 3, // Some counterparty exposure
|
|
71
|
+
SIGNIFICANT_RISK = 4, // Significant counterparty risk
|
|
72
|
+
BAD_DEBT_ISSUES = 5 // Bad debt or known issues
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export enum DepegRiskLevel {
|
|
76
|
+
NO_RISK = 0,
|
|
77
|
+
HIGHLY_STABLE = 1, // Highly stable assets (e.g., major stablecoins)
|
|
78
|
+
GENERALLY_STABLE = 2, // Generally stable with minor fluctuations
|
|
79
|
+
OCCASIONAL_DEPEG = 3, // Occasional depeg events
|
|
80
|
+
FREQUENT_DEPEG = 4, // Frequent or significant depeg risk
|
|
81
|
+
HIGH_DEPEG_PROBABILITY = 5 // High probability of severe depeg (e.g., USDC depeg scenarios)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Helper type to map risk types to their corresponding level enums
|
|
85
|
+
export type RiskLevelMap = {
|
|
86
|
+
[RiskType.MARKET_RISK]: MarketRiskLevel;
|
|
87
|
+
[RiskType.IMPERMANENT_LOSS]: ImpermanentLossLevel;
|
|
88
|
+
[RiskType.LIQUIDATION_RISK]: LiquidationRiskLevel;
|
|
89
|
+
[RiskType.LOW_LIQUIDITY_RISK]: LowLiquidityRiskLevel;
|
|
90
|
+
[RiskType.SMART_CONTRACT_RISK]: SmartContractRiskLevel;
|
|
91
|
+
[RiskType.ORACLE_RISK]: OracleRiskLevel;
|
|
92
|
+
[RiskType.TECHNICAL_RISK]: TechnicalRiskLevel;
|
|
93
|
+
[RiskType.COUNTERPARTY_RISK]: CounterpartyRiskLevel;
|
|
94
|
+
[RiskType.DEPEG_RISK]: DepegRiskLevel;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// Utility function to get risk level description
|
|
98
|
+
export function getRiskLevelDescription(riskType: RiskType, level: number): string {
|
|
99
|
+
const descriptions: Record<RiskType, Record<number, string>> = {
|
|
100
|
+
[RiskType.MARKET_RISK]: {
|
|
101
|
+
0: "No market risk",
|
|
102
|
+
1: "Very low market volatility",
|
|
103
|
+
2: "Low market volatility",
|
|
104
|
+
3: "Moderate market volatility",
|
|
105
|
+
4: "High market volatility",
|
|
106
|
+
5: "Very high market volatility"
|
|
107
|
+
},
|
|
108
|
+
[RiskType.IMPERMANENT_LOSS]: {
|
|
109
|
+
0: "No impermanent loss risk",
|
|
110
|
+
1: "Highly correlated pairs (minimal IL)",
|
|
111
|
+
2: "Correlated pairs (low IL)",
|
|
112
|
+
3: "Non-correlated pairs (moderate IL)",
|
|
113
|
+
4: "Leveraged correlated pairs",
|
|
114
|
+
5: "Leveraged non-correlated pairs"
|
|
115
|
+
},
|
|
116
|
+
[RiskType.LIQUIDATION_RISK]: {
|
|
117
|
+
0: "No liquidation risk",
|
|
118
|
+
1: "Very low liquidation probability",
|
|
119
|
+
2: "Low liquidation probability",
|
|
120
|
+
3: "Moderate liquidation risk",
|
|
121
|
+
4: "High liquidation risk",
|
|
122
|
+
5: "Critical liquidation risk"
|
|
123
|
+
},
|
|
124
|
+
[RiskType.LOW_LIQUIDITY_RISK]: {
|
|
125
|
+
0: "High liquidity",
|
|
126
|
+
1: "Good liquidity",
|
|
127
|
+
2: "Adequate liquidity",
|
|
128
|
+
3: "Moderate liquidity concerns",
|
|
129
|
+
4: "Low liquidity",
|
|
130
|
+
5: "Severe liquidity constraints"
|
|
131
|
+
},
|
|
132
|
+
[RiskType.SMART_CONTRACT_RISK]: {
|
|
133
|
+
0: "No smart contract risk",
|
|
134
|
+
1: "Battle-tested contracts",
|
|
135
|
+
2: "Well-audited contracts",
|
|
136
|
+
3: "Recently audited contracts",
|
|
137
|
+
4: "Unaudited contracts",
|
|
138
|
+
5: "Experimental or vulnerable contracts"
|
|
139
|
+
},
|
|
140
|
+
[RiskType.ORACLE_RISK]: {
|
|
141
|
+
0: "No oracle dependency",
|
|
142
|
+
1: "Multiple reliable oracles",
|
|
143
|
+
2: "Single reliable oracle",
|
|
144
|
+
3: "Less established oracle",
|
|
145
|
+
4: "Unproven oracle",
|
|
146
|
+
5: "Unreliable or no oracle"
|
|
147
|
+
},
|
|
148
|
+
[RiskType.TECHNICAL_RISK]: {
|
|
149
|
+
0: "No technical risk",
|
|
150
|
+
1: "Stable infrastructure",
|
|
151
|
+
2: "Established protocols",
|
|
152
|
+
3: "Some complexity",
|
|
153
|
+
4: "New implementation",
|
|
154
|
+
5: "Experimental technology"
|
|
155
|
+
},
|
|
156
|
+
[RiskType.COUNTERPARTY_RISK]: {
|
|
157
|
+
0: "No counterparty risk",
|
|
158
|
+
1: "Fully decentralized",
|
|
159
|
+
2: "Reputable counterparty",
|
|
160
|
+
3: "Some counterparty exposure",
|
|
161
|
+
4: "Significant counterparty risk",
|
|
162
|
+
5: "Bad debt or known issues"
|
|
163
|
+
},
|
|
164
|
+
[RiskType.DEPEG_RISK]: {
|
|
165
|
+
0: "No depeg risk",
|
|
166
|
+
1: "Highly stable asset",
|
|
167
|
+
2: "Generally stable",
|
|
168
|
+
3: "Occasional depeg events",
|
|
169
|
+
4: "Frequent depeg risk",
|
|
170
|
+
5: "High depeg probability"
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
return descriptions[riskType][level] || "Unknown risk level";
|
|
175
|
+
}
|
package/src/modules/harvests.ts
CHANGED
|
@@ -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 =
|
|
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);
|
package/src/notifs/telegram.ts
CHANGED
|
@@ -4,9 +4,9 @@ import { logger } from "@/utils/logger";
|
|
|
4
4
|
export class TelegramNotif {
|
|
5
5
|
private subscribers: string[] = [
|
|
6
6
|
// '6820228303',
|
|
7
|
-
'1505578076',
|
|
8
|
-
'1356705582', // langs
|
|
9
|
-
'1388729514', // hwashere
|
|
7
|
+
// '1505578076',
|
|
8
|
+
// '1356705582', // langs
|
|
9
|
+
// '1388729514', // hwashere
|
|
10
10
|
'985902592'
|
|
11
11
|
];
|
|
12
12
|
readonly bot: TelegramBot;
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
IStrategyMetadata,
|
|
11
11
|
RiskFactor,
|
|
12
12
|
RiskType,
|
|
13
|
+
TokenInfo,
|
|
13
14
|
} from "@/interfaces";
|
|
14
15
|
import { PricerBase } from "@/modules/pricerBase";
|
|
15
16
|
import { assert } from "@/utils";
|
|
@@ -34,6 +35,7 @@ import { log } from "winston";
|
|
|
34
35
|
import { EkuboHarvests } from "@/modules/harvests";
|
|
35
36
|
import { logger } from "@/utils/logger";
|
|
36
37
|
import { COMMON_CONTRACTS } from "./constants";
|
|
38
|
+
import { ImpermanentLossLevel, MarketRiskLevel, SmartContractRiskLevel } from "@/interfaces/risks";
|
|
37
39
|
|
|
38
40
|
export interface EkuboPoolKey {
|
|
39
41
|
token0: ContractAddr;
|
|
@@ -69,6 +71,7 @@ export interface CLVaultStrategySettings {
|
|
|
69
71
|
direction: "any" | "uponly"; // any for pools like USDC/USDT, uponly for pools like xSTRK/STRK
|
|
70
72
|
customShouldRebalance: (currentPoolPrice: number) => Promise<boolean>; // any additional logic for deciding factor to rebalance or not based on pools
|
|
71
73
|
};
|
|
74
|
+
quoteAsset: TokenInfo
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
export class EkuboCLVault extends BaseStrategy<
|
|
@@ -1588,15 +1591,41 @@ const _protocol: IProtocol = {
|
|
|
1588
1591
|
logo: "https://app.ekubo.org/favicon.ico",
|
|
1589
1592
|
};
|
|
1590
1593
|
// need to fine tune better
|
|
1591
|
-
const
|
|
1592
|
-
{ type: RiskType.SMART_CONTRACT_RISK, value:
|
|
1593
|
-
{ type: RiskType.IMPERMANENT_LOSS, value:
|
|
1594
|
-
{ type: RiskType.MARKET_RISK, value:
|
|
1594
|
+
const _corelatedPoolRiskFactors: RiskFactor[] = [
|
|
1595
|
+
{ type: RiskType.SMART_CONTRACT_RISK, value: SmartContractRiskLevel.WELL_AUDITED, weight: 34, reason: "Audited smart contracts" },
|
|
1596
|
+
{ type: RiskType.IMPERMANENT_LOSS, value: ImpermanentLossLevel.HIGHLY_CORRELATED, weight: 33, reason: "Low risk due to co-related assets" },
|
|
1597
|
+
{ type: RiskType.MARKET_RISK, value: MarketRiskLevel.VERY_LOW_VOLATILITY, weight: 33, reason: "Low risk due to co-related assets" },
|
|
1595
1598
|
];
|
|
1596
1599
|
|
|
1597
|
-
const
|
|
1598
|
-
{ type: RiskType.SMART_CONTRACT_RISK, value:
|
|
1600
|
+
const mediumVolatilityPoolRiskFactors: RiskFactor[] = [
|
|
1601
|
+
{ type: RiskType.SMART_CONTRACT_RISK, value: SmartContractRiskLevel.WELL_AUDITED, weight: 34, reason: "Audited smart contracts" },
|
|
1602
|
+
{ type: RiskType.IMPERMANENT_LOSS, value: ImpermanentLossLevel.NON_CORRELATED, weight: 33, reason: "Low risk due to co-related assets" },
|
|
1603
|
+
{ type: RiskType.MARKET_RISK, value: MarketRiskLevel.MODERATE_VOLATILITY, weight: 33, reason: "Low risk due to co-related assets" },
|
|
1599
1604
|
];
|
|
1605
|
+
|
|
1606
|
+
const highVolatilityPoolRiskFactors: RiskFactor[] = [
|
|
1607
|
+
{ type: RiskType.SMART_CONTRACT_RISK, value: SmartContractRiskLevel.WELL_AUDITED, weight: 34, reason: "Audited smart contracts" },
|
|
1608
|
+
{ type: RiskType.IMPERMANENT_LOSS, value: ImpermanentLossLevel.NON_CORRELATED, weight: 33, reason: "Low risk due to co-related assets" },
|
|
1609
|
+
{ type: RiskType.MARKET_RISK, value: MarketRiskLevel.HIGH_VOLATILITY, weight: 33, reason: "Low risk due to co-related assets" },
|
|
1610
|
+
];
|
|
1611
|
+
|
|
1612
|
+
const mediumRisk = {
|
|
1613
|
+
riskFactor: mediumVolatilityPoolRiskFactors,
|
|
1614
|
+
netRisk:
|
|
1615
|
+
mediumVolatilityPoolRiskFactors.reduce((acc, curr) => acc + curr.value * curr.weight, 0) /
|
|
1616
|
+
mediumVolatilityPoolRiskFactors.reduce((acc, curr) => acc + curr.weight, 0),
|
|
1617
|
+
notARisks: getNoRiskTags(mediumVolatilityPoolRiskFactors),
|
|
1618
|
+
};
|
|
1619
|
+
|
|
1620
|
+
const highRisk = {
|
|
1621
|
+
riskFactor: highVolatilityPoolRiskFactors,
|
|
1622
|
+
netRisk:
|
|
1623
|
+
highVolatilityPoolRiskFactors.reduce((acc, curr) => acc + curr.value * curr.weight, 0) /
|
|
1624
|
+
highVolatilityPoolRiskFactors.reduce((acc, curr) => acc + curr.weight, 0),
|
|
1625
|
+
notARisks: getNoRiskTags(highVolatilityPoolRiskFactors),
|
|
1626
|
+
};
|
|
1627
|
+
|
|
1628
|
+
|
|
1600
1629
|
const AUDIT_URL =
|
|
1601
1630
|
"https://assets.troves.fi/strkfarm/audit_report_vesu_and_ekubo_strats.pdf";
|
|
1602
1631
|
|
|
@@ -1616,6 +1645,11 @@ const faqs: FAQ[] = [
|
|
|
1616
1645
|
answer:
|
|
1617
1646
|
"During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices.",
|
|
1618
1647
|
},
|
|
1648
|
+
{
|
|
1649
|
+
question: "Are there any deposit/withdrawal fees?",
|
|
1650
|
+
answer:
|
|
1651
|
+
"No, there are no deposit/withdrawal fees. However, there is a performance fee varying between 10-20% of the fees and rewards generated. The exact fee is determined by the strategy and the APY shown is net of this fee.",
|
|
1652
|
+
},
|
|
1619
1653
|
{
|
|
1620
1654
|
question: "Is the strategy audited?",
|
|
1621
1655
|
answer: (
|
|
@@ -1651,11 +1685,11 @@ const xSTRKSTRK: IStrategyMetadata<CLVaultStrategySettings> = {
|
|
|
1651
1685
|
auditUrl: AUDIT_URL,
|
|
1652
1686
|
maxTVL: Web3Number.fromWei("0", 18),
|
|
1653
1687
|
risk: {
|
|
1654
|
-
riskFactor:
|
|
1688
|
+
riskFactor: _corelatedPoolRiskFactors,
|
|
1655
1689
|
netRisk:
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
notARisks: getNoRiskTags(
|
|
1690
|
+
_corelatedPoolRiskFactors.reduce((acc, curr) => acc + curr.value * curr.weight, 0) /
|
|
1691
|
+
_corelatedPoolRiskFactors.reduce((acc, curr) => acc + curr.weight, 0),
|
|
1692
|
+
notARisks: getNoRiskTags(_corelatedPoolRiskFactors),
|
|
1659
1693
|
},
|
|
1660
1694
|
apyMethodology:
|
|
1661
1695
|
"APY based on 7-day historical performance, including fees and rewards.",
|
|
@@ -1673,6 +1707,7 @@ const xSTRKSTRK: IStrategyMetadata<CLVaultStrategySettings> = {
|
|
|
1673
1707
|
minWaitHours: 24,
|
|
1674
1708
|
direction: "uponly",
|
|
1675
1709
|
},
|
|
1710
|
+
quoteAsset: Global.getDefaultTokens().find((t) => t.symbol === "STRK")!,
|
|
1676
1711
|
},
|
|
1677
1712
|
faqs: [
|
|
1678
1713
|
...faqs,
|
|
@@ -1691,76 +1726,171 @@ const xSTRKSTRK: IStrategyMetadata<CLVaultStrategySettings> = {
|
|
|
1691
1726
|
investmentSteps: []
|
|
1692
1727
|
};
|
|
1693
1728
|
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
upper: 1,
|
|
1717
|
-
},
|
|
1718
|
-
truePrice: 1,
|
|
1719
|
-
feeBps: 1000,
|
|
1720
|
-
rebalanceConditions: {
|
|
1721
|
-
customShouldRebalance: async (currentPrice: number) =>
|
|
1722
|
-
currentPrice > 0.99 && currentPrice < 1.01,
|
|
1723
|
-
minWaitHours: 6,
|
|
1724
|
-
direction: "any",
|
|
1725
|
-
},
|
|
1726
|
-
},
|
|
1729
|
+
const ETHUSDCRe7Strategy: IStrategyMetadata<CLVaultStrategySettings> = {
|
|
1730
|
+
...xSTRKSTRK,
|
|
1731
|
+
name: "Ekubo ETH/USDC",
|
|
1732
|
+
description: <></>,
|
|
1733
|
+
address: ContractAddr.from(
|
|
1734
|
+
"0x160d8fa4569ef6a12e6bf47cb943d7b5ebba8a41a69a14c1d943050ba5ff947"
|
|
1735
|
+
),
|
|
1736
|
+
launchBlock: 1501761,
|
|
1737
|
+
// must be same order as poolKey token0 and token1
|
|
1738
|
+
depositTokens: [
|
|
1739
|
+
Global.getDefaultTokens().find((t) => t.symbol === "ETH")!,
|
|
1740
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDC")!
|
|
1741
|
+
],
|
|
1742
|
+
additionalInfo: {
|
|
1743
|
+
newBounds: "Managed by Re7",
|
|
1744
|
+
truePrice: 1,
|
|
1745
|
+
feeBps: 1000,
|
|
1746
|
+
rebalanceConditions: {
|
|
1747
|
+
customShouldRebalance: async (currentPrice: number) =>
|
|
1748
|
+
currentPrice > 0.99 && currentPrice < 1.01,
|
|
1749
|
+
minWaitHours: 6,
|
|
1750
|
+
direction: "any"
|
|
1727
1751
|
},
|
|
1752
|
+
quoteAsset: Global.getDefaultTokens().find((t) => t.symbol === "USDC")!,
|
|
1753
|
+
},
|
|
1754
|
+
faqs: [
|
|
1755
|
+
...faqs,
|
|
1728
1756
|
{
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
address: ContractAddr.from(
|
|
1733
|
-
"0xb7bd37121041261446d8eedec618955a4490641034942da688e8cbddea7b23"
|
|
1734
|
-
),
|
|
1735
|
-
launchBlock: 1492136,
|
|
1736
|
-
// must be same order as poolKey token0 and token1
|
|
1737
|
-
depositTokens: [
|
|
1738
|
-
Global.getDefaultTokens().find((t) => t.symbol === "STRK")!,
|
|
1739
|
-
Global.getDefaultTokens().find((t) => t.symbol === "USDC")!,
|
|
1740
|
-
],
|
|
1741
|
-
maxTVL: Web3Number.fromWei("0", 6),
|
|
1742
|
-
additionalInfo: {
|
|
1743
|
-
newBounds: "Managed by Re7",
|
|
1744
|
-
feeBps: 1000,
|
|
1745
|
-
rebalanceConditions: {
|
|
1746
|
-
customShouldRebalance: async (currentPrice: number) =>
|
|
1747
|
-
true,
|
|
1748
|
-
minWaitHours: 6,
|
|
1749
|
-
direction: "any",
|
|
1750
|
-
},
|
|
1751
|
-
},
|
|
1757
|
+
question: "Who is the curator of this strategy?",
|
|
1758
|
+
answer:
|
|
1759
|
+
<div>Re7 Labs is the curator of this strategy. Re7 Labs is a well-known Web3 asset management firm. This strategy is completely managed by them, including ownership of the vault. Troves is developer of the smart contracts and maintains infrastructure to help users access these strategies. You can find more information about them on their website <a href='https://www.re7labs.xyz' style={{textDecoration: "underline", marginLeft: "2px"}} target="_blank">here</a>.</div>
|
|
1752
1760
|
},
|
|
1761
|
+
],
|
|
1762
|
+
risk: highRisk,
|
|
1763
|
+
points: [],
|
|
1764
|
+
curator: { name: "Re7 Labs", logo: "https://www.re7labs.xyz/favicon.ico" }
|
|
1765
|
+
};
|
|
1766
|
+
|
|
1767
|
+
const RE7Strategies: IStrategyMetadata<CLVaultStrategySettings>[] = [
|
|
1768
|
+
ETHUSDCRe7Strategy,
|
|
1769
|
+
{
|
|
1770
|
+
...ETHUSDCRe7Strategy,
|
|
1771
|
+
name: "Ekubo USDC/USDT",
|
|
1772
|
+
description: <></>,
|
|
1773
|
+
address: ContractAddr.from(
|
|
1774
|
+
"0x3a4f8debaf12af97bb911099bc011d63d6c208d4c5ba8e15d7f437785b0aaa2"
|
|
1775
|
+
),
|
|
1776
|
+
launchBlock: 1501761,
|
|
1777
|
+
// must be same order as poolKey token0 and token1
|
|
1778
|
+
depositTokens: [
|
|
1779
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDC")!,
|
|
1780
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDT")!
|
|
1781
|
+
],
|
|
1782
|
+
risk: xSTRKSTRK.risk,
|
|
1783
|
+
},
|
|
1784
|
+
{
|
|
1785
|
+
...ETHUSDCRe7Strategy,
|
|
1786
|
+
name: "Ekubo STRK/USDC",
|
|
1787
|
+
description: <></>,
|
|
1788
|
+
address: ContractAddr.from(
|
|
1789
|
+
"0x351b36d0d9d8b40010658825adeeddb1397436cd41acd0ff6c6e23aaa8b5b30"
|
|
1790
|
+
),
|
|
1791
|
+
launchBlock: 1501762,
|
|
1792
|
+
// must be same order as poolKey token0 and token1
|
|
1793
|
+
depositTokens: [
|
|
1794
|
+
Global.getDefaultTokens().find((t) => t.symbol === "STRK")!,
|
|
1795
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDC")!
|
|
1796
|
+
],
|
|
1797
|
+
risk: highRisk,
|
|
1798
|
+
},
|
|
1799
|
+
{
|
|
1800
|
+
...ETHUSDCRe7Strategy,
|
|
1801
|
+
name: "Ekubo STRK/ETH",
|
|
1802
|
+
description: <></>,
|
|
1803
|
+
address: ContractAddr.from(
|
|
1804
|
+
"0x4ce3024b0ee879009112d7b0e073f8a87153dd35b029347d4247ffe48d28f51"
|
|
1805
|
+
),
|
|
1806
|
+
launchBlock: 1501763,
|
|
1807
|
+
// must be same order as poolKey token0 and token1
|
|
1808
|
+
depositTokens: [
|
|
1809
|
+
Global.getDefaultTokens().find((t) => t.symbol === "STRK")!,
|
|
1810
|
+
Global.getDefaultTokens().find((t) => t.symbol === "ETH")!
|
|
1811
|
+
],
|
|
1812
|
+
risk: highRisk,
|
|
1813
|
+
},
|
|
1814
|
+
{
|
|
1815
|
+
...ETHUSDCRe7Strategy,
|
|
1816
|
+
name: "Ekubo WBTC/USDC",
|
|
1817
|
+
description: <></>,
|
|
1818
|
+
address: ContractAddr.from(
|
|
1819
|
+
"0x2bcaef2eb7706875a5fdc6853dd961a0590f850bc3a031c59887189b5e84ba1"
|
|
1820
|
+
),
|
|
1821
|
+
launchBlock: 1501764,
|
|
1822
|
+
// must be same order as poolKey token0 and token1
|
|
1823
|
+
depositTokens: [
|
|
1824
|
+
Global.getDefaultTokens().find((t) => t.symbol === "WBTC")!,
|
|
1825
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDC")!
|
|
1826
|
+
],
|
|
1827
|
+
risk: mediumRisk,
|
|
1828
|
+
},
|
|
1829
|
+
{
|
|
1830
|
+
...ETHUSDCRe7Strategy,
|
|
1831
|
+
name: "Ekubo tBTC/USDC",
|
|
1832
|
+
description: <></>,
|
|
1833
|
+
address: ContractAddr.from(
|
|
1834
|
+
"0x4aad891a2d4432fba06b6558631bb13f6bbd7f6f33ab8c3111e344889ea4456"
|
|
1835
|
+
),
|
|
1836
|
+
launchBlock: 1501764,
|
|
1837
|
+
// must be same order as poolKey token0 and token1
|
|
1838
|
+
depositTokens: [
|
|
1839
|
+
Global.getDefaultTokens().find((t) => t.symbol === "tBTC")!,
|
|
1840
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDC")!
|
|
1841
|
+
],
|
|
1842
|
+
risk: mediumRisk,
|
|
1843
|
+
},
|
|
1844
|
+
{
|
|
1845
|
+
...ETHUSDCRe7Strategy,
|
|
1846
|
+
name: "Ekubo WBTC/ETH",
|
|
1847
|
+
description: <></>,
|
|
1848
|
+
address: ContractAddr.from(
|
|
1849
|
+
"0x1c9232b8186d9317652f05055615f18a120c2ad9e5ee96c39e031c257fb945b"
|
|
1850
|
+
),
|
|
1851
|
+
launchBlock: 1501765,
|
|
1852
|
+
// must be same order as poolKey token0 and token1
|
|
1853
|
+
depositTokens: [
|
|
1854
|
+
Global.getDefaultTokens().find((t) => t.symbol === "WBTC")!,
|
|
1855
|
+
Global.getDefaultTokens().find((t) => t.symbol === "ETH")!
|
|
1856
|
+
],
|
|
1857
|
+
risk: mediumRisk,
|
|
1858
|
+
},
|
|
1859
|
+
{
|
|
1860
|
+
...ETHUSDCRe7Strategy,
|
|
1861
|
+
name: "Ekubo WBTC/STRK",
|
|
1862
|
+
description: <></>,
|
|
1863
|
+
address: ContractAddr.from(
|
|
1864
|
+
"0x1248e385c23a929a015ec298a26560fa7745bbd6e41a886550e337b02714b1b"
|
|
1865
|
+
),
|
|
1866
|
+
launchBlock: 1501766,
|
|
1867
|
+
// must be same order as poolKey token0 and token1
|
|
1868
|
+
depositTokens: [
|
|
1869
|
+
Global.getDefaultTokens().find((t) => t.symbol === "WBTC")!,
|
|
1870
|
+
Global.getDefaultTokens().find((t) => t.symbol === "STRK")!
|
|
1871
|
+
],
|
|
1872
|
+
risk: highRisk,
|
|
1873
|
+
}
|
|
1874
|
+
];
|
|
1875
|
+
|
|
1876
|
+
/**
|
|
1877
|
+
* Represents the Ekubo CL Vault Strategies.
|
|
1878
|
+
*/
|
|
1879
|
+
export const EkuboCLVaultStrategies: IStrategyMetadata<CLVaultStrategySettings>[] = [
|
|
1880
|
+
xSTRKSTRK,
|
|
1881
|
+
...RE7Strategies,
|
|
1753
1882
|
];
|
|
1754
1883
|
|
|
1755
1884
|
// auto assign contract details to each strategy
|
|
1756
1885
|
EkuboCLVaultStrategies.forEach((s) => {
|
|
1757
1886
|
// set contract details
|
|
1758
1887
|
s.contractDetails = [{
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1888
|
+
address: s.address,
|
|
1889
|
+
name: "Vault",
|
|
1890
|
+
sourceCodeUrl: "https://github.com/strkfarm/strkfarm-contracts/tree/main/src/strategies/cl_vault"
|
|
1891
|
+
},
|
|
1892
|
+
// ...COMMON_CONTRACTS
|
|
1893
|
+
];
|
|
1764
1894
|
// set docs link
|
|
1765
1895
|
s.docs = "https://docs.troves.fi/p/ekubo-cl-vaults"
|
|
1766
1896
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ContractAddr } from "@/dataTypes";
|
|
2
2
|
|
|
3
|
-
export const SIMPLE_SANITIZER = ContractAddr.from('
|
|
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
|
}
|