@strkfarm/sdk 1.1.8 → 1.1.9

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.
@@ -35,7 +35,7 @@ import { log } from "winston";
35
35
  import { EkuboHarvests } from "@/modules/harvests";
36
36
  import { logger } from "@/utils/logger";
37
37
  import { COMMON_CONTRACTS } from "./constants";
38
- import { ImpermanentLossLevel, MarketRiskLevel, SmartContractRiskLevel } from "@/interfaces/risks";
38
+ import { DepegRiskLevel, ImpermanentLossLevel, MarketRiskLevel, SmartContractRiskLevel } from "@/interfaces/risks";
39
39
 
40
40
  export interface EkuboPoolKey {
41
41
  token0: ContractAddr;
@@ -1591,22 +1591,30 @@ const _protocol: IProtocol = {
1591
1591
  logo: "https://app.ekubo.org/favicon.ico",
1592
1592
  };
1593
1593
  // need to fine tune better
1594
- const _corelatedPoolRiskFactors: RiskFactor[] = [
1594
+ const _lstPoolRiskFactors: RiskFactor[] = [
1595
1595
  { type: RiskType.SMART_CONTRACT_RISK, value: SmartContractRiskLevel.WELL_AUDITED, weight: 34, reason: "Audited smart contracts" },
1596
1596
  { type: RiskType.IMPERMANENT_LOSS, value: ImpermanentLossLevel.HIGHLY_CORRELATED, weight: 33, reason: "Low risk due to co-related assets" },
1597
1597
  { type: RiskType.MARKET_RISK, value: MarketRiskLevel.VERY_LOW_VOLATILITY, weight: 33, reason: "Low risk due to co-related assets" },
1598
+ {type: RiskType.DEPEG_RISK, value: DepegRiskLevel.GENERALLY_STABLE, weight: 33, reason: "Generally stable pegged assets" },
1599
+ ];
1600
+
1601
+ const _stableCoinPoolRiskFactors: RiskFactor[] = [
1602
+ { type: RiskType.SMART_CONTRACT_RISK, value: SmartContractRiskLevel.BATTLE_TESTED, weight: 34, reason: "Audited smart contracts" },
1603
+ { type: RiskType.IMPERMANENT_LOSS, value: ImpermanentLossLevel.HIGHLY_CORRELATED, weight: 33, reason: "Low risk due to co-related assets" },
1604
+ { type: RiskType.MARKET_RISK, value: MarketRiskLevel.VERY_LOW_VOLATILITY, weight: 33, reason: "Low risk due to co-related assets" },
1605
+ {type: RiskType.DEPEG_RISK, value: DepegRiskLevel.HIGHLY_STABLE, weight: 33, reason: "Highly stable assets" },
1598
1606
  ];
1599
1607
 
1600
1608
  const mediumVolatilityPoolRiskFactors: RiskFactor[] = [
1601
1609
  { 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" },
1610
+ { type: RiskType.IMPERMANENT_LOSS, value: ImpermanentLossLevel.NON_CORRELATED, weight: 33, reason: "Assets are not correlated, often volatile" },
1611
+ { type: RiskType.MARKET_RISK, value: MarketRiskLevel.MODERATE_VOLATILITY, weight: 33, reason: "Assets are not correlated, relative volatile can be moderate sometimes" },
1604
1612
  ];
1605
1613
 
1606
1614
  const highVolatilityPoolRiskFactors: RiskFactor[] = [
1607
1615
  { 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" },
1616
+ { type: RiskType.IMPERMANENT_LOSS, value: ImpermanentLossLevel.NON_CORRELATED, weight: 33, reason: "Assets are not correlated, often volatile" },
1617
+ { type: RiskType.MARKET_RISK, value: MarketRiskLevel.HIGH_VOLATILITY, weight: 33, reason: "Assets are not correlated, relative volatile is often high" },
1610
1618
  ];
1611
1619
 
1612
1620
  const mediumRisk = {
@@ -1696,11 +1704,11 @@ const xSTRKSTRK: IStrategyMetadata<CLVaultStrategySettings> = {
1696
1704
  auditUrl: AUDIT_URL,
1697
1705
  maxTVL: Web3Number.fromWei("0", 18),
1698
1706
  risk: {
1699
- riskFactor: _corelatedPoolRiskFactors,
1707
+ riskFactor: _lstPoolRiskFactors,
1700
1708
  netRisk:
1701
- _corelatedPoolRiskFactors.reduce((acc, curr) => acc + curr.value * curr.weight, 0) /
1702
- _corelatedPoolRiskFactors.reduce((acc, curr) => acc + curr.weight, 0),
1703
- notARisks: getNoRiskTags(_corelatedPoolRiskFactors),
1709
+ _lstPoolRiskFactors.reduce((acc, curr) => acc + curr.value * curr.weight, 0) /
1710
+ _lstPoolRiskFactors.reduce((acc, curr) => acc + curr.weight, 0),
1711
+ notARisks: getNoRiskTags(_lstPoolRiskFactors),
1704
1712
  },
1705
1713
  apyMethodology:
1706
1714
  "APY based on 30-day historical performance, including fees and rewards.",
@@ -1858,7 +1866,13 @@ const RE7Strategies: IStrategyMetadata<CLVaultStrategySettings>[] = [
1858
1866
  Global.getDefaultTokens().find((t) => t.symbol === "USDC")!,
1859
1867
  Global.getDefaultTokens().find((t) => t.symbol === "USDT")!
1860
1868
  ],
1861
- risk: xSTRKSTRK.risk,
1869
+ risk: {
1870
+ riskFactor: _stableCoinPoolRiskFactors,
1871
+ netRisk:
1872
+ _stableCoinPoolRiskFactors.reduce((acc, curr) => acc + curr.value * curr.weight, 0) /
1873
+ _stableCoinPoolRiskFactors.reduce((acc, curr) => acc + curr.weight, 0),
1874
+ notARisks: getNoRiskTags(_stableCoinPoolRiskFactors),
1875
+ }
1862
1876
  },
1863
1877
  {
1864
1878
  ...ETHUSDCRe7Strategy,
@@ -4,4 +4,5 @@ export * from './ekubo-cl-vault';
4
4
  export * from './base-strategy';
5
5
  export * from './sensei';
6
6
  export * from './universal-adapters';
7
- export * from './universal-strategy';
7
+ export * from './universal-strategy';
8
+ export * from './universal-lst-muliplier-strategy';
@@ -1,6 +1,9 @@
1
1
  import { ContractAddr } from "@/dataTypes";
2
2
 
3
+ // Zellic audited
3
4
  export const SIMPLE_SANITIZER = ContractAddr.from('0x5a2e3ceb3da368b983a8717898427ab7b6daf04014b70f321e777f9aad940b4');
5
+ // Without flashloan options
6
+ export const SIMPLE_SANITIZER_V2 = ContractAddr.from('0x5643d54da70a471cd2b6fa37f52ea7a13cc3f3910689a839f8490a663d2208a');
4
7
  export const PRICE_ROUTER = ContractAddr.from('0x05e83Fa38D791d2dba8E6f487758A9687FfEe191A6Cf8a6c5761ab0a110DB837');
5
8
  export const AVNU_MIDDLEWARE = ContractAddr.from('0x4a7972ed3f5d1e74a6d6c4a8f467666953d081c8f2270390cc169d50d17cb0d');
6
9
 
@@ -23,14 +23,14 @@ export class BaseAdapter extends CacheClass {
23
23
  id: string,
24
24
  target: ContractAddr,
25
25
  method: string,
26
- packedArguments: bigint[]
27
- }): LeafData {
26
+ packedArguments: bigint[],
27
+ }, sanitizer: ContractAddr = SIMPLE_SANITIZER): LeafData {
28
28
  const { id, target, method, packedArguments } = params;
29
29
  return {
30
30
  id: BigInt(num.getDecimalString(shortString.encodeShortString(id))),
31
31
  readableId: id,
32
32
  data: [
33
- SIMPLE_SANITIZER.toBigInt(), // sanitizer address
33
+ sanitizer.toBigInt(), // sanitizer address
34
34
  target.toBigInt(), // contract
35
35
  toBigInt(hash.getSelectorFromName(method)), // method name
36
36
  BigInt(packedArguments.length),
@@ -1,8 +1,8 @@
1
1
  import { LeafData, logger } from "@/utils"
2
2
  import { CairoCustomEnum, Contract, hash, num, RpcProvider, shortString, uint256, Uint256 } from "starknet";
3
- import { SIMPLE_SANITIZER, toBigInt } from "./adapter-utils";
3
+ import { SIMPLE_SANITIZER, SIMPLE_SANITIZER_V2, toBigInt } from "./adapter-utils";
4
4
  import { ContractAddr, Web3Number } from "@/dataTypes";
5
- import { AdapterLeafType, BaseAdapter, GenerateCallFn, ManageCall } from "./baseAdapter";
5
+ import { AdapterLeafType, BaseAdapter, GenerateCallFn, LeafAdapterFn, ManageCall } from "./baseAdapter";
6
6
  import VesuSingletonAbi from '../../data/vesu-singleton.abi.json';
7
7
  import { IConfig, TokenInfo, VaultPosition } from "@/interfaces";
8
8
  import { PricerBase } from "@/modules/pricerBase";
@@ -11,6 +11,8 @@ import { getAPIUsingHeadlessBrowser } from "@/node/headless";
11
11
  import { Global } from "@/global";
12
12
  import { VESU_REWARDS_CONTRACT } from "@/modules/harvests";
13
13
  import { ENDPOINTS } from "../constants";
14
+ import VesuMultiplyAbi from '@/data/vesu-multiple.abi.json';
15
+ import { EkuboPoolKey } from "../ekubo-cl-vault";
14
16
 
15
17
  interface VesuPoolsInfo { pools: any[]; isErrorPoolsAPI: boolean };
16
18
 
@@ -53,12 +55,169 @@ export interface VesuAdapterConfig {
53
55
  id: string
54
56
  }
55
57
 
58
+ export interface TokenAmount {
59
+ token: ContractAddr,
60
+ amount: Web3Number, // i129
61
+ }
62
+ export interface Swap {
63
+ route: RouteNode[],
64
+ token_amount: TokenAmount,
65
+ }
66
+
67
+ export interface RouteNode {
68
+ pool_key: EkuboPoolKey,
69
+ sqrt_ratio_limit: Web3Number, // u256
70
+ skip_ahead: Web3Number, // u128
71
+ }
72
+
73
+ export interface IncreaseLeverParams {
74
+ pool_id: ContractAddr,
75
+ collateral_asset: ContractAddr,
76
+ debt_asset: ContractAddr,
77
+ user: ContractAddr,
78
+ add_margin: Web3Number,
79
+ margin_swap: Swap[],
80
+ margin_swap_limit_amount: Web3Number,
81
+ lever_swap: Swap[],
82
+ lever_swap_limit_amount: Web3Number,
83
+ }
84
+
85
+ export interface DecreaseLeverParams {
86
+ pool_id: ContractAddr,
87
+ collateral_asset: ContractAddr,
88
+ debt_asset: ContractAddr,
89
+ user: ContractAddr,
90
+ sub_margin: Web3Number,
91
+ recipient: ContractAddr,
92
+ lever_swap: Swap[],
93
+ lever_swap_limit_amount: Web3Number,
94
+ lever_swap_weights: Web3Number[],
95
+ withdraw_swap: Swap[],
96
+ withdraw_swap_limit_amount: Web3Number,
97
+ withdraw_swap_weights: Web3Number[],
98
+ close_position: boolean,
99
+ }
100
+
101
+ export interface VesuMultiplyCallParams {
102
+ increaseParams?: Omit<IncreaseLeverParams, 'user' | 'pool_id' | 'collateral_asset' | 'debt_asset'>,
103
+ decreaseParams?: Omit<DecreaseLeverParams, 'user' | 'pool_id' | 'collateral_asset' | 'debt_asset' | 'recipient'>,
104
+ isIncrease: boolean,
105
+ }
106
+
107
+ export interface VesuModifyDelegationCallParams {
108
+ delegation: boolean, // is on/off
109
+ }
110
+
111
+ function getVesuMultiplyParams(isIncrease: boolean, params: IncreaseLeverParams | DecreaseLeverParams) {
112
+ if (isIncrease) {
113
+ const _params = params as IncreaseLeverParams;
114
+ return {
115
+ action: new CairoCustomEnum({ IncreaseLever: {
116
+ pool_id: _params.pool_id.toBigInt(),
117
+ collateral_asset: _params.collateral_asset.toBigInt(),
118
+ debt_asset: _params.debt_asset.toBigInt(),
119
+ user: _params.user.toBigInt(),
120
+ add_margin: BigInt(_params.add_margin.toWei()),
121
+ margin_swap: _params.margin_swap.map(swap => ({
122
+ route: swap.route.map(route => ({
123
+ pool_key: {
124
+ token0: route.pool_key.token0.toBigInt(),
125
+ token1: route.pool_key.token1.toBigInt(),
126
+ fee: route.pool_key.fee,
127
+ tick_spacing: route.pool_key.tick_spacing,
128
+ extension: BigInt(num.hexToDecimalString(route.pool_key.extension)),
129
+ },
130
+ sqrt_ratio_limit: uint256.bnToUint256(route.sqrt_ratio_limit.toWei()),
131
+ skip_ahead: BigInt(100)
132
+ })),
133
+ token_amount: {
134
+ token: swap.token_amount.token.toBigInt(),
135
+ amount: swap.token_amount.amount.toI129()
136
+ }
137
+ })),
138
+ margin_swap_limit_amount: BigInt(_params.margin_swap_limit_amount.toWei()),
139
+ lever_swap: _params.lever_swap.map(swap => ({
140
+ route: swap.route.map(route => ({
141
+ pool_key: {
142
+ token0: route.pool_key.token0.toBigInt(),
143
+ token1: route.pool_key.token1.toBigInt(),
144
+ fee: route.pool_key.fee,
145
+ tick_spacing: route.pool_key.tick_spacing,
146
+ extension: BigInt(num.hexToDecimalString(route.pool_key.extension)),
147
+ },
148
+ sqrt_ratio_limit: uint256.bnToUint256(route.sqrt_ratio_limit.toWei()),
149
+ skip_ahead: BigInt(100)
150
+ })),
151
+ token_amount: {
152
+ token: swap.token_amount.token.toBigInt(),
153
+ amount: swap.token_amount.amount.toI129()
154
+ }
155
+ })),
156
+ lever_swap_limit_amount: BigInt(_params.lever_swap_limit_amount.toWei()),
157
+ } }),
158
+ }
159
+ }
160
+
161
+ const _params = params as DecreaseLeverParams;
162
+ return {
163
+ action: new CairoCustomEnum({ DecreaseLever: {
164
+ pool_id: _params.pool_id.toBigInt(),
165
+ collateral_asset: _params.collateral_asset.toBigInt(),
166
+ debt_asset: _params.debt_asset.toBigInt(),
167
+ user: _params.user.toBigInt(),
168
+ sub_margin: BigInt(_params.sub_margin.toWei()),
169
+ recipient: _params.recipient.toBigInt(),
170
+ lever_swap: _params.lever_swap.map(swap => ({
171
+ route: swap.route.map(route => ({
172
+ pool_key: {
173
+ token0: route.pool_key.token0.toBigInt(),
174
+ token1: route.pool_key.token1.toBigInt(),
175
+ fee: route.pool_key.fee,
176
+ tick_spacing: route.pool_key.tick_spacing,
177
+ extension: ContractAddr.from(route.pool_key.extension).toBigInt(),
178
+ },
179
+ sqrt_ratio_limit: uint256.bnToUint256(route.sqrt_ratio_limit.toWei()),
180
+ skip_ahead: BigInt(route.skip_ahead.toWei())
181
+ })),
182
+ token_amount: {
183
+ token: swap.token_amount.token.toBigInt(),
184
+ amount: swap.token_amount.amount.toI129()
185
+ }
186
+ })),
187
+ lever_swap_limit_amount: BigInt(_params.lever_swap_limit_amount.toWei()),
188
+ lever_swap_weights: _params.lever_swap_weights.map(weight => BigInt(weight.toWei())),
189
+ withdraw_swap: _params.withdraw_swap.map(swap => ({
190
+ route: swap.route.map(route => ({
191
+ pool_key: {
192
+ token0: route.pool_key.token0.toBigInt(),
193
+ token1: route.pool_key.token1.toBigInt(),
194
+ fee: route.pool_key.fee,
195
+ tick_spacing: route.pool_key.tick_spacing,
196
+ extension: ContractAddr.from(route.pool_key.extension).toBigInt(),
197
+ },
198
+ sqrt_ratio_limit: uint256.bnToUint256(route.sqrt_ratio_limit.toWei()),
199
+ skip_ahead: BigInt(route.skip_ahead.toWei())
200
+ })),
201
+ token_amount: {
202
+ token: swap.token_amount.token.toBigInt(),
203
+ amount: swap.token_amount.amount.toI129()
204
+ }
205
+ })),
206
+ withdraw_swap_limit_amount: BigInt(_params.withdraw_swap_limit_amount.toWei()),
207
+ withdraw_swap_weights: _params.withdraw_swap_weights.map(weight => BigInt(weight.toWei())),
208
+ close_position: _params.close_position,
209
+ }}),
210
+ }
211
+ }
212
+
56
213
  export const VesuPools = {
57
- Genesis: ContractAddr.from('0x4dc4f0ca6ea4961e4c8373265bfd5317678f4fe374d76f3fd7135f57763bf28')
214
+ Genesis: ContractAddr.from('0x4dc4f0ca6ea4961e4c8373265bfd5317678f4fe374d76f3fd7135f57763bf28'),
215
+ Re7xSTRK: ContractAddr.from('0x052fb52363939c3aa848f8f4ac28f0a51379f8d1b971d8444de25fbd77d8f161')
58
216
  }
59
217
 
60
218
  export class VesuAdapter extends BaseAdapter {
61
219
  VESU_SINGLETON = ContractAddr.from("0x000d8d6dfec4d33bfb6895de9f3852143a17c6f92fd2a21da3d6924d34870160");
220
+ VESU_MULTIPLY = ContractAddr.from('0x3630f1f8e5b8f5c4c4ae9b6620f8a570ae55cddebc0276c37550e7c118edf67');
62
221
  config: VesuAdapterConfig;
63
222
  networkConfig: IConfig | undefined;
64
223
  pricer: PricerBase | undefined;
@@ -163,6 +322,88 @@ export class VesuAdapter extends BaseAdapter {
163
322
  }
164
323
  }
165
324
  }
325
+
326
+ getMultiplyAdapter = (): AdapterLeafType<VesuMultiplyCallParams> => {
327
+ const packedArguments: bigint[] = [
328
+ toBigInt(this.config.poolId.toString()), // pool id
329
+ toBigInt(this.config.collateral.address.toString()), // collateral
330
+ toBigInt(this.config.debt.address.toString()), // debt
331
+ toBigInt(this.config.vaultAllocator.toString()), // vault allocator
332
+ ];
333
+ const output = this.constructSimpleLeafData({
334
+ id: this.config.id,
335
+ target: this.VESU_MULTIPLY,
336
+ method: 'modify_lever',
337
+ packedArguments
338
+ }, SIMPLE_SANITIZER_V2);
339
+
340
+ return { leaf: output, callConstructor: this.getMultiplyCall.bind(this) };
341
+ }
342
+
343
+ getMultiplyCall = (params: VesuMultiplyCallParams): ManageCall => {
344
+ const isIncrease = params.isIncrease;
345
+ const multiplyParams = isIncrease ? params.increaseParams : params.decreaseParams;
346
+ if (!multiplyParams) {
347
+ throw new Error('Multiply params are not provided');
348
+ }
349
+ const multiplyContract = new Contract({abi: VesuMultiplyAbi, address: this.VESU_MULTIPLY.toString(), providerOrAccount: new RpcProvider({nodeUrl: ''})});
350
+ const call = multiplyContract.populate('modify_lever', {
351
+ modify_lever_params: getVesuMultiplyParams(isIncrease, {
352
+ ...multiplyParams,
353
+ user: this.config.vaultAllocator,
354
+ pool_id: this.config.poolId,
355
+ collateral_asset: this.config.collateral.address,
356
+ debt_asset: this.config.debt.address,
357
+ recipient: this.config.vaultAllocator
358
+ })
359
+ });
360
+ return {
361
+ sanitizer: SIMPLE_SANITIZER_V2,
362
+ call: {
363
+ contractAddress: this.VESU_MULTIPLY,
364
+ selector: hash.getSelectorFromName('modify_lever'),
365
+ calldata: [
366
+ ...call.calldata as bigint[]
367
+ ]
368
+ }
369
+ }
370
+ }
371
+
372
+ getVesuModifyDelegationAdapter = (id: string): LeafAdapterFn<VesuModifyDelegationCallParams> => {
373
+ return () => {
374
+ const packedArguments: bigint[] = [
375
+ toBigInt(this.config.poolId.toString()), // pool id
376
+ toBigInt(this.VESU_MULTIPLY.toString()), // vault allocator
377
+ ];
378
+ const output = this.constructSimpleLeafData({
379
+ id: id,
380
+ target: this.VESU_SINGLETON,
381
+ method: 'modify_delegation',
382
+ packedArguments
383
+ }, SIMPLE_SANITIZER_V2);
384
+
385
+ return { leaf: output, callConstructor: this.getVesuModifyDelegationCall.bind(this) };
386
+ }
387
+ }
388
+
389
+ getVesuModifyDelegationCall = (params: VesuModifyDelegationCallParams): ManageCall => {
390
+ const singletonContract = new Contract({abi: VesuSingletonAbi, address: this.VESU_SINGLETON.toString(), providerOrAccount: new RpcProvider({nodeUrl: ''})});
391
+ const call = singletonContract.populate('modify_delegation', {
392
+ pool_id: this.config.poolId.toBigInt(),
393
+ delegatee: this.VESU_MULTIPLY.toBigInt(),
394
+ delegation: params.delegation,
395
+ });
396
+ return {
397
+ sanitizer: SIMPLE_SANITIZER_V2,
398
+ call: {
399
+ contractAddress: this.VESU_SINGLETON,
400
+ selector: hash.getSelectorFromName('modify_delegation'),
401
+ calldata: [
402
+ ...call.calldata as bigint[]
403
+ ]
404
+ }
405
+ }
406
+ }
166
407
 
167
408
  getDefispringRewardsAdapter = (id: string): () => AdapterLeafType<VesuDefiSpringRewardsCallParams> => {
168
409
  return () => {