@defisaver/automation-sdk 3.3.10 → 3.3.11-aave-v4-1-dev

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.
Files changed (57) hide show
  1. package/cjs/automation/private/StrategiesAutomation.d.ts +2 -0
  2. package/cjs/automation/private/StrategiesAutomation.js +10 -1
  3. package/cjs/automation/private/StrategiesAutomation.test.js +25 -0
  4. package/cjs/constants/index.d.ts +1 -0
  5. package/cjs/constants/index.js +72 -1
  6. package/cjs/services/ethereumService.test.js +2 -0
  7. package/cjs/services/strategiesService.js +129 -0
  8. package/cjs/services/strategySubService.d.ts +19 -0
  9. package/cjs/services/strategySubService.js +37 -1
  10. package/cjs/services/strategySubService.test.js +229 -0
  11. package/cjs/services/subDataService.d.ts +298 -129
  12. package/cjs/services/subDataService.js +639 -369
  13. package/cjs/services/subDataService.test.js +214 -0
  14. package/cjs/services/triggerService.d.ts +38 -0
  15. package/cjs/services/triggerService.js +68 -1
  16. package/cjs/services/triggerService.test.js +130 -0
  17. package/cjs/services/utils.d.ts +1 -1
  18. package/cjs/services/utils.js +10 -2
  19. package/cjs/types/enums.d.ts +19 -3
  20. package/cjs/types/enums.js +16 -0
  21. package/cjs/types/index.d.ts +33 -1
  22. package/esm/automation/private/StrategiesAutomation.d.ts +2 -0
  23. package/esm/automation/private/StrategiesAutomation.js +10 -1
  24. package/esm/automation/private/StrategiesAutomation.test.js +25 -0
  25. package/esm/constants/index.d.ts +1 -0
  26. package/esm/constants/index.js +71 -0
  27. package/esm/services/ethereumService.test.js +2 -0
  28. package/esm/services/strategiesService.js +130 -1
  29. package/esm/services/strategySubService.d.ts +19 -0
  30. package/esm/services/strategySubService.js +36 -0
  31. package/esm/services/strategySubService.test.js +230 -1
  32. package/esm/services/subDataService.d.ts +298 -129
  33. package/esm/services/subDataService.js +639 -369
  34. package/esm/services/subDataService.test.js +214 -0
  35. package/esm/services/triggerService.d.ts +38 -0
  36. package/esm/services/triggerService.js +67 -0
  37. package/esm/services/triggerService.test.js +131 -1
  38. package/esm/services/utils.d.ts +1 -1
  39. package/esm/services/utils.js +10 -2
  40. package/esm/types/enums.d.ts +19 -3
  41. package/esm/types/enums.js +16 -0
  42. package/esm/types/index.d.ts +33 -1
  43. package/package.json +2 -2
  44. package/src/automation/private/StrategiesAutomation.test.ts +40 -0
  45. package/src/automation/private/StrategiesAutomation.ts +11 -0
  46. package/src/constants/index.ts +72 -0
  47. package/src/services/ethereumService.test.ts +2 -0
  48. package/src/services/strategiesService.ts +150 -2
  49. package/src/services/strategySubService.test.ts +286 -0
  50. package/src/services/strategySubService.ts +140 -0
  51. package/src/services/subDataService.test.ts +239 -0
  52. package/src/services/subDataService.ts +1072 -784
  53. package/src/services/triggerService.test.ts +148 -0
  54. package/src/services/triggerService.ts +97 -1
  55. package/src/services/utils.ts +15 -4
  56. package/src/types/enums.ts +16 -0
  57. package/src/types/index.ts +40 -1
@@ -197,8 +197,40 @@ export declare namespace Position {
197
197
  stopLossType: CloseToAssetType | undefined;
198
198
  takeProfitType: CloseToAssetType | undefined;
199
199
  }
200
+ interface SparkOnPrice extends Base {
201
+ collAsset: EthereumAddress;
202
+ collAssetId: number;
203
+ debtAsset: EthereumAddress;
204
+ debtAssetId: number;
205
+ baseToken: EthereumAddress;
206
+ quoteToken: EthereumAddress;
207
+ price: string;
208
+ ratioState: RatioState;
209
+ ratio: number;
210
+ }
211
+ interface CloseBase extends Base {
212
+ stopLossPrice: string;
213
+ takeProfitPrice: string;
214
+ stopLossType: CloseToAssetType | undefined;
215
+ takeProfitType: CloseToAssetType | undefined;
216
+ }
217
+ interface AaveV4LeverageManagementOnPrice extends Base {
218
+ collAsset: EthereumAddress;
219
+ collAssetId: number;
220
+ debtAsset: EthereumAddress;
221
+ debtAssetId: number;
222
+ price: string;
223
+ ratioState: number;
224
+ ratio: number;
225
+ }
226
+ interface AaveV4CloseOnPrice extends CloseBase {
227
+ collAsset: EthereumAddress;
228
+ collAssetId: number;
229
+ debtAsset: EthereumAddress;
230
+ debtAssetId: number;
231
+ }
200
232
  }
201
- type SpecificAny = Specific.CloseOnPrice | Specific.TrailingStop | Specific.RatioProtection | Specific.CloseOnPriceAave | Specific.BoostOnPriceAave | Specific.CloseOnPriceWithMaximumGasPriceAave | Specific.DebtInFrontRepay | Specific.LeverageManagementCrvUSD | Specific.CloseOnPriceLiquityV2 | Specific.BoostOnPriceMorpho | Specific.BoostOnPriceLiquityV2 | Specific.PaybackLiquityV2 | Specific.CompoundV3LeverageManagementOnPrice | Specific.CompoundV3CloseOnPrice | Specific.AaveV3CloseOnPriceGeneric;
233
+ type SpecificAny = Specific.CloseOnPrice | Specific.TrailingStop | Specific.RatioProtection | Specific.CloseOnPriceAave | Specific.BoostOnPriceAave | Specific.CloseOnPriceWithMaximumGasPriceAave | Specific.DebtInFrontRepay | Specific.LeverageManagementCrvUSD | Specific.CloseOnPriceLiquityV2 | Specific.BoostOnPriceMorpho | Specific.BoostOnPriceLiquityV2 | Specific.PaybackLiquityV2 | Specific.CompoundV3LeverageManagementOnPrice | Specific.CompoundV3CloseOnPrice | Specific.AaveV3CloseOnPriceGeneric | Specific.AaveV4LeverageManagementOnPrice | Specific.AaveV4CloseOnPrice | Specific.SparkOnPrice;
202
234
  interface Automated {
203
235
  chainId: ChainId;
204
236
  positionId: string;
@@ -25,6 +25,8 @@ export default class StrategiesAutomation extends Automation {
25
25
  */
26
26
  protected removeExpiredSubscriptions(subscriptions: (Position.Automated | null)[]): (Position.Automated | null)[];
27
27
  private _mergeCheck;
28
+ /** Repay/boost leverage pairs must not merge across different Aave V4 spokes. */
29
+ private _aaveV4MergeSpokesMatch;
28
30
  protected mergeSubs(_subscriptions: (Position.Automated | null)[]): Position.Automated[];
29
31
  protected _getSubscriptions(addresses?: EthereumAddress[], options?: SubscriptionOptions): Promise<(Position.Automated | null)[]>;
30
32
  getSubscriptions(options?: SubscriptionOptions): Promise<(Position.Automated | null)[]>;
@@ -99,7 +99,16 @@ export default class StrategiesAutomation extends Automation {
99
99
  && (s.protocol.id !== ProtocolIdentifiers.StrategiesAutomation.CrvUSD // merge only crvUSD leverage management for the same market
100
100
  || s.strategyData.decoded.subData.controller.toLowerCase() === current.strategyData.decoded.triggerData.controller.toLowerCase())
101
101
  && (s.protocol.id !== ProtocolIdentifiers.StrategiesAutomation.MorphoBlue // merge morpho blue with the same marketId
102
- || s.strategyData.decoded.triggerData.marketId.toLowerCase() === current.strategyData.decoded.triggerData.marketId.toLowerCase());
102
+ || s.strategyData.decoded.triggerData.marketId.toLowerCase() === current.strategyData.decoded.triggerData.marketId.toLowerCase())
103
+ && (s.protocol.id !== ProtocolIdentifiers.StrategiesAutomation.AaveV4
104
+ || this._aaveV4MergeSpokesMatch(s, current));
105
+ }
106
+ /** Repay/boost leverage pairs must not merge across different Aave V4 spokes. */
107
+ _aaveV4MergeSpokesMatch(s, current) {
108
+ var _a, _b, _c, _d, _e, _f;
109
+ const a = (_c = (_b = (_a = s.strategyData) === null || _a === void 0 ? void 0 : _a.decoded) === null || _b === void 0 ? void 0 : _b.triggerData) === null || _c === void 0 ? void 0 : _c.spoke;
110
+ const b = (_f = (_e = (_d = current.strategyData) === null || _d === void 0 ? void 0 : _d.decoded) === null || _e === void 0 ? void 0 : _e.triggerData) === null || _f === void 0 ? void 0 : _f.spoke;
111
+ return !!a && !!b && a.toLowerCase() === b.toLowerCase();
103
112
  }
104
113
  mergeSubs(_subscriptions) {
105
114
  const mergeBase = _subscriptions.filter(s => isDefined(s) && isDefined(s.specific.mergeWithId));
@@ -662,5 +662,30 @@ describe('Feature: StrategiesAutomation.ts', () => {
662
662
  expect(JSON.stringify(actual)).to.equal(JSON.stringify(expected));
663
663
  }));
664
664
  });
665
+ it('Aave V4: pairs repay/boost merge only when trigger spoke matches (no cross-spoke merge)', () => {
666
+ var _a, _b, _c;
667
+ const spoke1 = '0x0000000000000000000000000000000000000a01';
668
+ const spoke2 = '0x0000000000000000000000000000000000000a02';
669
+ const base = {
670
+ isEnabled: true,
671
+ chainId: 1,
672
+ owner: '0x0000000000000000000000000000000000000b01',
673
+ protocol: { id: 'Aave__V4' },
674
+ strategy: { strategyId: 'leverage-management' },
675
+ blockNumber: 0,
676
+ subHash: '0x1',
677
+ positionId: 'test',
678
+ };
679
+ const boostSpoke1 = Object.assign(Object.assign({}, base), { subId: 1, strategyData: { decoded: { triggerData: { spoke: spoke1 }, subData: {} } }, specific: { mergeId: 'boost', subId2: 1 } });
680
+ const repaySpoke2 = Object.assign(Object.assign({}, base), { subId: 2, strategyData: { decoded: { triggerData: { spoke: spoke2 }, subData: {} } }, specific: { mergeWithId: 'boost', subId1: 2 } });
681
+ const boostSpoke2 = Object.assign(Object.assign({}, base), { subId: 3, strategyData: { decoded: { triggerData: { spoke: spoke2 }, subData: {} } }, specific: { mergeId: 'boost', subId2: 3 } });
682
+ // @ts-ignore — mergeSubs is protected; exercised here as in examples above
683
+ const merged = exampleStrategiesAutomation.mergeSubs([boostSpoke1, repaySpoke2, boostSpoke2]);
684
+ expect(merged).to.have.length(2);
685
+ const mergedPair = merged.find((m) => { var _a; return ((_a = m.subIds) === null || _a === void 0 ? void 0 : _a.length) === 2; });
686
+ const loneBoost = merged.find((m) => { var _a; return ((_a = m.subIds) === null || _a === void 0 ? void 0 : _a.length) === 1; });
687
+ expect((_c = (_b = (_a = mergedPair === null || mergedPair === void 0 ? void 0 : mergedPair.strategyData) === null || _a === void 0 ? void 0 : _a.decoded) === null || _b === void 0 ? void 0 : _b.triggerData) === null || _c === void 0 ? void 0 : _c.spoke).to.equal(spoke2);
688
+ expect(loneBoost === null || loneBoost === void 0 ? void 0 : loneBoost.subId).to.equal(1);
689
+ });
665
690
  }));
666
691
  });
@@ -1,6 +1,7 @@
1
1
  import type { ArbitrumBundleInfo, ArbitrumStrategiesInfo, BundlesInfo, EthereumAddress, Interfaces, MainnetBundleInfo, MainnetStrategiesInfo, OptimismBundleInfo, OptimismStrategiesInfo, BaseBundleInfo, BaseStrategiesInfo, StrategiesInfo } from '../types';
2
2
  import { ProtocolIdentifiers, Strategies, Bundles } from '../types/enums';
3
3
  export declare const ZERO_ADDRESS: EthereumAddress;
4
+ export declare const EMPTY_SLOT: string;
4
5
  export declare const AAVE_V3_VARIABLE_BORROW_RATE = 2;
5
6
  export declare const PROTOCOLS: Record<keyof typeof ProtocolIdentifiers.StrategiesAutomation, Interfaces.Protocol>;
6
7
  export declare const LEGACY_PROTOCOLS: Record<keyof typeof ProtocolIdentifiers.LegacyAutomation, Interfaces.LegacyProtocol>;
@@ -3,6 +3,7 @@ import Protocol from '../automation/private/Protocol';
3
3
  import LegacyProtocol from '../automation/private/LegacyProtocol';
4
4
  // General
5
5
  export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
6
+ export const EMPTY_SLOT = '0x0000000000000000000000000000000000000000000000000000000000000000';
6
7
  export const AAVE_V3_VARIABLE_BORROW_RATE = 2;
7
8
  export const PROTOCOLS = (() => {
8
9
  const protocolsMapping = {};
@@ -100,6 +101,16 @@ export const MAINNET_STRATEGIES_INFO = {
100
101
  strategyId: Strategies.Identifiers.CollateralSwitch,
101
102
  protocol: PROTOCOLS.AaveV3,
102
103
  },
104
+ [Strategies.MainnetIds.AAVE_V4_COLLATERAL_SWITCH]: {
105
+ strategyOrBundleId: Strategies.MainnetIds.AAVE_V4_COLLATERAL_SWITCH,
106
+ strategyId: Strategies.Identifiers.CollateralSwitch,
107
+ protocol: PROTOCOLS.AaveV4,
108
+ },
109
+ [Strategies.MainnetIds.AAVE_V4_COLLATERAL_SWITCH_EOA]: {
110
+ strategyOrBundleId: Strategies.MainnetIds.AAVE_V4_COLLATERAL_SWITCH_EOA,
111
+ strategyId: Strategies.Identifiers.EoaCollateralSwitch,
112
+ protocol: PROTOCOLS.AaveV4,
113
+ },
103
114
  };
104
115
  export const OPTIMISM_STRATEGIES_INFO = {
105
116
  [Strategies.OptimismIds.EXCHANGE_DCA]: {
@@ -467,6 +478,66 @@ export const MAINNET_BUNDLES_INFO = {
467
478
  strategyId: Strategies.Identifiers.CloseOnPrice,
468
479
  protocol: PROTOCOLS.MorphoBlue,
469
480
  },
481
+ [Bundles.MainnetIds.SPARK_REPAY_ON_PRICE]: {
482
+ strategyOrBundleId: Bundles.MainnetIds.SPARK_REPAY_ON_PRICE,
483
+ strategyId: Strategies.Identifiers.RepayOnPrice,
484
+ protocol: PROTOCOLS.Spark,
485
+ },
486
+ [Bundles.MainnetIds.SPARK_BOOST_ON_PRICE]: {
487
+ strategyOrBundleId: Bundles.MainnetIds.SPARK_BOOST_ON_PRICE,
488
+ strategyId: Strategies.Identifiers.BoostOnPrice,
489
+ protocol: PROTOCOLS.Spark,
490
+ },
491
+ [Bundles.MainnetIds.AAVE_V4_REPAY]: {
492
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_REPAY,
493
+ strategyId: Strategies.Identifiers.Repay,
494
+ protocol: PROTOCOLS.AaveV4,
495
+ },
496
+ [Bundles.MainnetIds.AAVE_V4_BOOST]: {
497
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_BOOST,
498
+ strategyId: Strategies.Identifiers.Boost,
499
+ protocol: PROTOCOLS.AaveV4,
500
+ },
501
+ [Bundles.MainnetIds.AAVE_V4_REPAY_ON_PRICE]: {
502
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_REPAY_ON_PRICE,
503
+ strategyId: Strategies.Identifiers.RepayOnPrice,
504
+ protocol: PROTOCOLS.AaveV4,
505
+ },
506
+ [Bundles.MainnetIds.AAVE_V4_BOOST_ON_PRICE]: {
507
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_BOOST_ON_PRICE,
508
+ strategyId: Strategies.Identifiers.BoostOnPrice,
509
+ protocol: PROTOCOLS.AaveV4,
510
+ },
511
+ [Bundles.MainnetIds.AAVE_V4_CLOSE]: {
512
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_CLOSE,
513
+ strategyId: Strategies.Identifiers.CloseOnPrice,
514
+ protocol: PROTOCOLS.AaveV4,
515
+ },
516
+ [Bundles.MainnetIds.AAVE_V4_EOA_REPAY]: {
517
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_EOA_REPAY,
518
+ strategyId: Strategies.Identifiers.EoaRepay,
519
+ protocol: PROTOCOLS.AaveV4,
520
+ },
521
+ [Bundles.MainnetIds.AAVE_V4_EOA_BOOST]: {
522
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_EOA_BOOST,
523
+ strategyId: Strategies.Identifiers.EoaBoost,
524
+ protocol: PROTOCOLS.AaveV4,
525
+ },
526
+ [Bundles.MainnetIds.AAVE_V4_EOA_REPAY_ON_PRICE]: {
527
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_EOA_REPAY_ON_PRICE,
528
+ strategyId: Strategies.Identifiers.EoaRepayOnPrice,
529
+ protocol: PROTOCOLS.AaveV4,
530
+ },
531
+ [Bundles.MainnetIds.AAVE_V4_EOA_BOOST_ON_PRICE]: {
532
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_EOA_BOOST_ON_PRICE,
533
+ strategyId: Strategies.Identifiers.EoaBoostOnPrice,
534
+ protocol: PROTOCOLS.AaveV4,
535
+ },
536
+ [Bundles.MainnetIds.AAVE_V4_EOA_CLOSE]: {
537
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_EOA_CLOSE,
538
+ strategyId: Strategies.Identifiers.EoaCloseOnPrice,
539
+ protocol: PROTOCOLS.AaveV4,
540
+ },
470
541
  };
471
542
  export const OPTIMISM_BUNDLES_INFO = {
472
543
  [Bundles.OptimismIds.AAVE_V3_REPAY]: {
@@ -142,6 +142,7 @@ describe('Feature: ethereumService.ts', () => {
142
142
  'address': '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
143
143
  'blockHash': '0xacb0213af63b4c17c436f084a96d1ac385641a59a9a4cf014ae3337cbe545aa7',
144
144
  'blockNumber': 5353002,
145
+ 'blockTimestamp': '0x624c1a5b',
145
146
  'event': 'Transfer',
146
147
  'id': 'log_f49645b8',
147
148
  'logIndex': 1,
@@ -187,6 +188,7 @@ describe('Feature: ethereumService.ts', () => {
187
188
  'address': '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
188
189
  'blockHash': '0xacb0213af63b4c17c436f084a96d1ac385641a59a9a4cf014ae3337cbe545aa7',
189
190
  'blockNumber': 5353002,
191
+ 'blockTimestamp': '0x624c1a5b',
190
192
  'event': 'Transfer',
191
193
  'id': 'log_f49645b8',
192
194
  'logIndex': 1,
@@ -2,7 +2,7 @@ import { getAssetInfoByAddress } from '@defisaver/tokens';
2
2
  import { cloneDeep } from 'lodash';
3
3
  import Web3 from 'web3';
4
4
  import { BUNDLES_INFO, STRATEGIES_INFO } from '../constants';
5
- import { ChainId, ProtocolIdentifiers, Strategies } from '../types/enums';
5
+ import { ChainId, ProtocolIdentifiers, Strategies, } from '../types/enums';
6
6
  import { getPositionId, getRatioStateInfoForAaveCloseStrategy, getStopLossAndTakeProfitTypeByCloseStrategyType, isRatioStateOver, wethToEthByAddress, } from './utils';
7
7
  import * as subDataService from './subDataService';
8
8
  import * as triggerService from './triggerService';
@@ -285,6 +285,96 @@ function parseAaveV3CollateralSwitch(position, parseData) {
285
285
  _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, subData.marketAddr);
286
286
  return _position;
287
287
  }
288
+ function parseAaveV4LeverageManagement(position, parseData) {
289
+ const _position = cloneDeep(position);
290
+ const { subStruct, subId, subHash } = parseData.subscriptionEventData;
291
+ const { isEnabled } = parseData.strategiesSubsData;
292
+ const triggerData = triggerService.aaveV4RatioTrigger.decode(subStruct.triggerData);
293
+ const subData = subDataService.aaveV4LeverageManagementSubData.decode(subStruct.subData);
294
+ const isEOA = _position.strategy.strategyId.includes('eoa');
295
+ const isRepay = [Strategies.Identifiers.Repay, Strategies.Identifiers.EoaRepay].includes(_position.strategy.strategyId);
296
+ _position.strategyData.decoded.triggerData = triggerData;
297
+ _position.strategyData.decoded.subData = subData;
298
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.spoke);
299
+ _position.strategy.strategyId = isEOA ? Strategies.IdOverrides.EoaLeverageManagement : Strategies.IdOverrides.LeverageManagement;
300
+ if (isRepay) {
301
+ _position.specific = {
302
+ triggerRepayRatio: triggerData.ratio,
303
+ targetRepayRatio: subData.targetRatio,
304
+ repayEnabled: isEnabled,
305
+ subId1: Number(subId),
306
+ mergeWithId: isEOA ? Strategies.Identifiers.EoaBoost : Strategies.Identifiers.Boost,
307
+ subHashRepay: subHash,
308
+ };
309
+ }
310
+ else {
311
+ _position.specific = {
312
+ triggerBoostRatio: triggerData.ratio,
313
+ targetBoostRatio: subData.targetRatio,
314
+ boostEnabled: isEnabled,
315
+ subId2: Number(subId),
316
+ mergeId: isEOA ? Strategies.Identifiers.EoaBoost : Strategies.Identifiers.Boost,
317
+ subHashBoost: subHash,
318
+ };
319
+ }
320
+ return _position;
321
+ }
322
+ function parseAaveV4LeverageManagementOnPrice(position, parseData) {
323
+ const _position = cloneDeep(position);
324
+ const { subStruct } = parseData.subscriptionEventData;
325
+ const triggerData = triggerService.aaveV4QuotePriceTrigger.decode(subStruct.triggerData);
326
+ const subData = subDataService.aaveV4LeverageManagementOnPriceSubData.decode(subStruct.subData);
327
+ const isEOA = _position.strategy.strategyId.includes('eoa');
328
+ _position.strategyData.decoded.triggerData = triggerData;
329
+ _position.strategyData.decoded.subData = subData;
330
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.spoke);
331
+ _position.strategy.strategyId = isEOA ? Strategies.IdOverrides.EoaLeverageManagementOnPrice : Strategies.IdOverrides.LeverageManagementOnPrice;
332
+ _position.specific = {
333
+ collAsset: subData.collAsset,
334
+ collAssetId: subData.collAssetId,
335
+ debtAsset: subData.debtAsset,
336
+ debtAssetId: subData.debtAssetId,
337
+ price: triggerData.price,
338
+ ratioState: triggerData.ratioState,
339
+ ratio: subData.targetRatio,
340
+ };
341
+ return _position;
342
+ }
343
+ function parseAaveV4CloseOnPrice(position, parseData) {
344
+ const _position = cloneDeep(position);
345
+ const { subStruct } = parseData.subscriptionEventData;
346
+ const triggerData = triggerService.aaveV4QuotePriceRangeTrigger.decode(subStruct.triggerData);
347
+ const subData = subDataService.aaveV4CloseSubData.decode(subStruct.subData);
348
+ const { takeProfitType, stopLossType } = getStopLossAndTakeProfitTypeByCloseStrategyType(+subData.closeType);
349
+ const isEOA = _position.strategy.strategyId.includes('eoa');
350
+ _position.strategyData.decoded.triggerData = triggerData;
351
+ _position.strategyData.decoded.subData = subData;
352
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.spoke);
353
+ _position.strategy.strategyId = isEOA ? Strategies.Identifiers.EoaCloseOnPrice : Strategies.Identifiers.CloseOnPrice;
354
+ _position.specific = {
355
+ collAsset: subData.collAsset,
356
+ collAssetId: subData.collAssetId,
357
+ debtAsset: subData.debtAsset,
358
+ debtAssetId: subData.debtAssetId,
359
+ stopLossPrice: triggerData.lowerPrice,
360
+ takeProfitPrice: triggerData.upperPrice,
361
+ stopLossType,
362
+ takeProfitType,
363
+ };
364
+ return _position;
365
+ }
366
+ function parseAaveV4CollateralSwitch(position, parseData) {
367
+ const _position = cloneDeep(position);
368
+ const { subStruct } = parseData.subscriptionEventData;
369
+ const triggerData = triggerService.aaveV4QuotePriceTrigger.decode(subStruct.triggerData);
370
+ const subData = subDataService.aaveV4CollateralSwitchSubData.decode(subStruct.subData);
371
+ const isEOA = _position.strategy.strategyId.includes('eoa');
372
+ _position.strategyData.decoded.triggerData = triggerData;
373
+ _position.strategyData.decoded.subData = subData;
374
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.spoke);
375
+ _position.strategy.strategyId = isEOA ? Strategies.Identifiers.EoaCollateralSwitch : Strategies.Identifiers.CollateralSwitch;
376
+ return _position;
377
+ }
288
378
  function parseMorphoAaveV2LeverageManagement(position, parseData) {
289
379
  const _position = cloneDeep(position);
290
380
  const { subStruct, subId } = parseData.subscriptionEventData;
@@ -584,6 +674,29 @@ function parseSparkLeverageManagement(position, parseData) {
584
674
  _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
585
675
  return _position;
586
676
  }
677
+ function parseSparkLeverageManagementOnPrice(position, parseData) {
678
+ const _position = cloneDeep(position);
679
+ const { subStruct } = parseData.subscriptionEventData;
680
+ const triggerData = triggerService.sparkQuotePriceTrigger.decode(subStruct.triggerData);
681
+ const subData = subDataService.sparkLeverageManagementOnPriceSubData.decode(subStruct.subData);
682
+ _position.strategyData.decoded.triggerData = triggerData;
683
+ _position.strategyData.decoded.subData = subData;
684
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, subData.marketAddr);
685
+ _position.specific = {
686
+ // subData
687
+ collAsset: subData.collAsset,
688
+ collAssetId: subData.collAssetId,
689
+ debtAsset: subData.debtAsset,
690
+ debtAssetId: subData.debtAssetId,
691
+ ratio: subData.targetRatio,
692
+ // triggerData
693
+ baseToken: triggerData.baseTokenAddr,
694
+ quoteToken: triggerData.quoteTokenAddr,
695
+ price: triggerData.price,
696
+ ratioState: triggerData.ratioState,
697
+ };
698
+ return _position;
699
+ }
587
700
  function parseSparkCloseOnPrice(position, parseData) {
588
701
  const _position = cloneDeep(position);
589
702
  const { subStruct } = parseData.subscriptionEventData;
@@ -914,6 +1027,20 @@ const parsingMethodsMapping = {
914
1027
  [Strategies.Identifiers.EoaCloseOnPrice]: parseAaveV3CloseOnPrice,
915
1028
  [Strategies.Identifiers.CollateralSwitch]: parseAaveV3CollateralSwitch,
916
1029
  },
1030
+ [ProtocolIdentifiers.StrategiesAutomation.AaveV4]: {
1031
+ [Strategies.Identifiers.Repay]: parseAaveV4LeverageManagement,
1032
+ [Strategies.Identifiers.Boost]: parseAaveV4LeverageManagement,
1033
+ [Strategies.Identifiers.RepayOnPrice]: parseAaveV4LeverageManagementOnPrice,
1034
+ [Strategies.Identifiers.BoostOnPrice]: parseAaveV4LeverageManagementOnPrice,
1035
+ [Strategies.Identifiers.CloseOnPrice]: parseAaveV4CloseOnPrice,
1036
+ [Strategies.Identifiers.EoaRepay]: parseAaveV4LeverageManagement,
1037
+ [Strategies.Identifiers.EoaBoost]: parseAaveV4LeverageManagement,
1038
+ [Strategies.Identifiers.EoaRepayOnPrice]: parseAaveV4LeverageManagementOnPrice,
1039
+ [Strategies.Identifiers.EoaBoostOnPrice]: parseAaveV4LeverageManagementOnPrice,
1040
+ [Strategies.Identifiers.EoaCloseOnPrice]: parseAaveV4CloseOnPrice,
1041
+ [Strategies.Identifiers.CollateralSwitch]: parseAaveV4CollateralSwitch,
1042
+ [Strategies.Identifiers.EoaCollateralSwitch]: parseAaveV4CollateralSwitch,
1043
+ },
917
1044
  [ProtocolIdentifiers.StrategiesAutomation.CompoundV2]: {
918
1045
  [Strategies.Identifiers.Repay]: parseCompoundV2LeverageManagement,
919
1046
  [Strategies.Identifiers.Boost]: parseCompoundV2LeverageManagement,
@@ -944,6 +1071,8 @@ const parsingMethodsMapping = {
944
1071
  [ProtocolIdentifiers.StrategiesAutomation.Spark]: {
945
1072
  [Strategies.Identifiers.Repay]: parseSparkLeverageManagement,
946
1073
  [Strategies.Identifiers.Boost]: parseSparkLeverageManagement,
1074
+ [Strategies.Identifiers.RepayOnPrice]: parseSparkLeverageManagementOnPrice,
1075
+ [Strategies.Identifiers.BoostOnPrice]: parseSparkLeverageManagementOnPrice,
947
1076
  [Strategies.Identifiers.CloseOnPrice]: parseSparkCloseOnPrice,
948
1077
  },
949
1078
  [ProtocolIdentifiers.StrategiesAutomation.CrvUSD]: {
@@ -86,6 +86,19 @@ export declare const exchangeEncode: {
86
86
  };
87
87
  export declare const sparkEncode: {
88
88
  leverageManagement(triggerRepayRatio: number, triggerBoostRatio: number, targetBoostRatio: number, targetRepayRatio: number, boostEnabled: boolean): string;
89
+ leverageManagementOnPrice(strategyOrBundleId: number, isBundle: boolean | undefined, triggerData: {
90
+ baseTokenAddr: EthereumAddress;
91
+ quoteTokenAddr: EthereumAddress;
92
+ price: number;
93
+ ratioState: RatioState;
94
+ }, subData: {
95
+ collAsset: EthereumAddress;
96
+ collAssetId: number;
97
+ debtAsset: EthereumAddress;
98
+ debtAssetId: number;
99
+ marketAddr: EthereumAddress;
100
+ targetRatio: number;
101
+ }): (number | boolean | string[])[];
89
102
  closeOnPriceGeneric(strategyOrBundleId: number, collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number, marketAddr: EthereumAddress, user: EthereumAddress, stopLossPrice?: number, stopLossType?: CloseToAssetType, takeProfitPrice?: number, takeProfitType?: CloseToAssetType): (number | boolean | string[])[];
90
103
  leverageManagementWithoutSubProxy(strategyOrBundleId: number, market: EthereumAddress, user: EthereumAddress, ratioState: RatioState, targetRatio: number, triggerRatio: number): (number | boolean | string[])[];
91
104
  };
@@ -107,3 +120,9 @@ export declare const liquityV2Encode: {
107
120
  export declare const fluidEncode: {
108
121
  leverageManagement(nftId: string, vault: EthereumAddress, ratioState: RatioState, targetRatio: number, triggerRatio: number, strategyOrBundleId: number): (number | boolean | string[])[];
109
122
  };
123
+ export declare const aaveV4Encode: {
124
+ leverageManagement(strategyOrBundleId: number, owner: EthereumAddress, spoke: EthereumAddress, ratioState: RatioState, targetRatio: number, triggerRatio: number): (number | boolean | string[])[];
125
+ leverageManagementOnPrice(strategyOrBundleId: number, owner: EthereumAddress, spoke: EthereumAddress, collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number, targetRatio: number, price: string, priceState: RatioState, ratioState: RatioState): (number | boolean | string[])[];
126
+ closeOnPrice(strategyOrBundleId: number, owner: EthereumAddress, spoke: EthereumAddress, collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number, stopLossPrice?: string, stopLossType?: CloseToAssetType, takeProfitPrice?: string, takeProfitType?: CloseToAssetType): (number | boolean | string[])[];
127
+ collateralSwitch(strategyOrBundleId: number, owner: EthereumAddress, spoke: EthereumAddress, fromAsset: EthereumAddress, fromAssetId: number, toAsset: EthereumAddress, toAssetId: number, amountToSwitch: string, price: string, ratioState: RatioState): (number | boolean | string[])[];
128
+ };
@@ -243,6 +243,13 @@ export const sparkEncode = {
243
243
  subInput = subInput.concat(boostEnabled ? '01' : '00');
244
244
  return subInput;
245
245
  },
246
+ leverageManagementOnPrice(strategyOrBundleId, isBundle = true, triggerData, subData) {
247
+ const { collAsset, collAssetId, debtAsset, debtAssetId, marketAddr, targetRatio, } = subData;
248
+ const subDataEncoded = subDataService.sparkLeverageManagementOnPriceSubData.encode(collAsset, collAssetId, debtAsset, debtAssetId, marketAddr, targetRatio);
249
+ const { baseTokenAddr, quoteTokenAddr, price, ratioState, } = triggerData;
250
+ const triggerDataEncoded = triggerService.sparkQuotePriceTrigger.encode(baseTokenAddr, quoteTokenAddr, price, ratioState);
251
+ return [strategyOrBundleId, isBundle, triggerDataEncoded, subDataEncoded];
252
+ },
246
253
  closeOnPriceGeneric(strategyOrBundleId, collAsset, collAssetId, debtAsset, debtAssetId, marketAddr, user, stopLossPrice = 0, stopLossType = CloseToAssetType.DEBT, takeProfitPrice = 0, takeProfitType = CloseToAssetType.COLLATERAL) {
247
254
  const isBundle = true;
248
255
  const closeType = getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType);
@@ -341,3 +348,32 @@ export const fluidEncode = {
341
348
  return [strategyOrBundleId, isBundle, triggerData, subData];
342
349
  },
343
350
  };
351
+ export const aaveV4Encode = {
352
+ leverageManagement(strategyOrBundleId, owner, spoke, ratioState, targetRatio, triggerRatio) {
353
+ const isBundle = true;
354
+ const subData = subDataService.aaveV4LeverageManagementSubData.encode(spoke, owner, ratioState, targetRatio);
355
+ const triggerData = triggerService.aaveV4RatioTrigger.encode(owner, spoke, triggerRatio, ratioState);
356
+ return [strategyOrBundleId, isBundle, triggerData, subData];
357
+ },
358
+ leverageManagementOnPrice(strategyOrBundleId, owner, spoke, collAsset, collAssetId, debtAsset, debtAssetId, targetRatio, price, priceState, ratioState) {
359
+ const isBundle = true;
360
+ const subData = subDataService.aaveV4LeverageManagementOnPriceSubData.encode(spoke, owner, collAsset, collAssetId, debtAsset, debtAssetId, ratioState, targetRatio);
361
+ const triggerData = triggerService.aaveV4QuotePriceTrigger.encode(spoke, collAssetId, debtAssetId, price, priceState);
362
+ return [strategyOrBundleId, isBundle, triggerData, subData];
363
+ },
364
+ closeOnPrice(strategyOrBundleId, owner, spoke, collAsset, collAssetId, debtAsset, debtAssetId, stopLossPrice = '0', stopLossType = CloseToAssetType.DEBT, takeProfitPrice = '0', takeProfitType = CloseToAssetType.COLLATERAL) {
365
+ const isBundle = true;
366
+ const closeType = getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType);
367
+ const subData = subDataService.aaveV4CloseSubData.encode(spoke, owner, collAsset, collAssetId, debtAsset, debtAssetId, closeType);
368
+ const triggerData = triggerService.aaveV4QuotePriceRangeTrigger.encode(spoke, collAssetId, debtAssetId, stopLossPrice, takeProfitPrice);
369
+ return [strategyOrBundleId, isBundle, triggerData, subData];
370
+ },
371
+ collateralSwitch(strategyOrBundleId, owner, spoke, fromAsset, fromAssetId, toAsset, toAssetId, amountToSwitch, price, ratioState) {
372
+ const isBundle = false;
373
+ const subData = subDataService.aaveV4CollateralSwitchSubData.encode(spoke, owner, fromAsset, fromAssetId, toAsset, toAssetId, amountToSwitch);
374
+ const triggerData = triggerService.aaveV4QuotePriceTrigger.encode(spoke, fromAssetId, // baseTokenId
375
+ toAssetId, // quoteTokenId
376
+ price, ratioState);
377
+ return [strategyOrBundleId, isBundle, triggerData, subData];
378
+ },
379
+ };