@defisaver/automation-sdk 3.3.11-aave-v4-dev → 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.
@@ -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)[]>;
@@ -104,7 +104,16 @@ class StrategiesAutomation extends Automation_1.default {
104
104
  && (s.protocol.id !== enums_1.ProtocolIdentifiers.StrategiesAutomation.CrvUSD // merge only crvUSD leverage management for the same market
105
105
  || s.strategyData.decoded.subData.controller.toLowerCase() === current.strategyData.decoded.triggerData.controller.toLowerCase())
106
106
  && (s.protocol.id !== enums_1.ProtocolIdentifiers.StrategiesAutomation.MorphoBlue // merge morpho blue with the same marketId
107
- || s.strategyData.decoded.triggerData.marketId.toLowerCase() === current.strategyData.decoded.triggerData.marketId.toLowerCase());
107
+ || s.strategyData.decoded.triggerData.marketId.toLowerCase() === current.strategyData.decoded.triggerData.marketId.toLowerCase())
108
+ && (s.protocol.id !== enums_1.ProtocolIdentifiers.StrategiesAutomation.AaveV4
109
+ || this._aaveV4MergeSpokesMatch(s, current));
110
+ }
111
+ /** Repay/boost leverage pairs must not merge across different Aave V4 spokes. */
112
+ _aaveV4MergeSpokesMatch(s, current) {
113
+ var _a, _b, _c, _d, _e, _f;
114
+ 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;
115
+ 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;
116
+ return !!a && !!b && a.toLowerCase() === b.toLowerCase();
108
117
  }
109
118
  mergeSubs(_subscriptions) {
110
119
  const mergeBase = _subscriptions.filter(s => (0, utils_1.isDefined)(s) && (0, utils_1.isDefined)(s.specific.mergeWithId));
@@ -667,5 +667,30 @@ describe('Feature: StrategiesAutomation.ts', () => {
667
667
  (0, chai_1.expect)(JSON.stringify(actual)).to.equal(JSON.stringify(expected));
668
668
  }));
669
669
  });
670
+ it('Aave V4: pairs repay/boost merge only when trigger spoke matches (no cross-spoke merge)', () => {
671
+ var _a, _b, _c;
672
+ const spoke1 = '0x0000000000000000000000000000000000000a01';
673
+ const spoke2 = '0x0000000000000000000000000000000000000a02';
674
+ const base = {
675
+ isEnabled: true,
676
+ chainId: 1,
677
+ owner: '0x0000000000000000000000000000000000000b01',
678
+ protocol: { id: 'Aave__V4' },
679
+ strategy: { strategyId: 'leverage-management' },
680
+ blockNumber: 0,
681
+ subHash: '0x1',
682
+ positionId: 'test',
683
+ };
684
+ const boostSpoke1 = Object.assign(Object.assign({}, base), { subId: 1, strategyData: { decoded: { triggerData: { spoke: spoke1 }, subData: {} } }, specific: { mergeId: 'boost', subId2: 1 } });
685
+ const repaySpoke2 = Object.assign(Object.assign({}, base), { subId: 2, strategyData: { decoded: { triggerData: { spoke: spoke2 }, subData: {} } }, specific: { mergeWithId: 'boost', subId1: 2 } });
686
+ const boostSpoke2 = Object.assign(Object.assign({}, base), { subId: 3, strategyData: { decoded: { triggerData: { spoke: spoke2 }, subData: {} } }, specific: { mergeId: 'boost', subId2: 3 } });
687
+ // @ts-ignore — mergeSubs is protected; exercised here as in examples above
688
+ const merged = exampleStrategiesAutomation.mergeSubs([boostSpoke1, repaySpoke2, boostSpoke2]);
689
+ (0, chai_1.expect)(merged).to.have.length(2);
690
+ const mergedPair = merged.find((m) => { var _a; return ((_a = m.subIds) === null || _a === void 0 ? void 0 : _a.length) === 2; });
691
+ const loneBoost = merged.find((m) => { var _a; return ((_a = m.subIds) === null || _a === void 0 ? void 0 : _a.length) === 1; });
692
+ (0, chai_1.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);
693
+ (0, chai_1.expect)(loneBoost === null || loneBoost === void 0 ? void 0 : loneBoost.subId).to.equal(1);
694
+ });
670
695
  }));
671
696
  });
@@ -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
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/automation-sdk",
3
- "version": "3.3.11-aave-v4-dev",
3
+ "version": "3.3.11-aave-v4-1-dev",
4
4
  "description": "",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./esm/index.js",
@@ -659,5 +659,45 @@ describe('Feature: StrategiesAutomation.ts', () => {
659
659
  expect(JSON.stringify(actual)).to.equal(JSON.stringify(expected));
660
660
  });
661
661
  });
662
+
663
+ it('Aave V4: pairs repay/boost merge only when trigger spoke matches (no cross-spoke merge)', () => {
664
+ const spoke1 = '0x0000000000000000000000000000000000000a01';
665
+ const spoke2 = '0x0000000000000000000000000000000000000a02';
666
+ const base = {
667
+ isEnabled: true,
668
+ chainId: 1,
669
+ owner: '0x0000000000000000000000000000000000000b01',
670
+ protocol: { id: 'Aave__V4' },
671
+ strategy: { strategyId: 'leverage-management' },
672
+ blockNumber: 0,
673
+ subHash: '0x1',
674
+ positionId: 'test',
675
+ };
676
+ const boostSpoke1 = {
677
+ ...base,
678
+ subId: 1,
679
+ strategyData: { decoded: { triggerData: { spoke: spoke1 }, subData: {} } },
680
+ specific: { mergeId: 'boost', subId2: 1 },
681
+ };
682
+ const repaySpoke2 = {
683
+ ...base,
684
+ subId: 2,
685
+ strategyData: { decoded: { triggerData: { spoke: spoke2 }, subData: {} } },
686
+ specific: { mergeWithId: 'boost', subId1: 2 },
687
+ };
688
+ const boostSpoke2 = {
689
+ ...base,
690
+ subId: 3,
691
+ strategyData: { decoded: { triggerData: { spoke: spoke2 }, subData: {} } },
692
+ specific: { mergeId: 'boost', subId2: 3 },
693
+ };
694
+ // @ts-ignore — mergeSubs is protected; exercised here as in examples above
695
+ const merged = exampleStrategiesAutomation.mergeSubs([boostSpoke1, repaySpoke2, boostSpoke2]);
696
+ expect(merged).to.have.length(2);
697
+ const mergedPair = merged.find((m: { subIds?: number[] }) => m.subIds?.length === 2);
698
+ const loneBoost = merged.find((m: { subIds?: number[] }) => m.subIds?.length === 1);
699
+ expect(mergedPair?.strategyData?.decoded?.triggerData?.spoke).to.equal(spoke2);
700
+ expect(loneBoost?.subId).to.equal(1);
701
+ });
662
702
  });
663
703
  });
@@ -129,9 +129,20 @@ export default class StrategiesAutomation extends Automation {
129
129
  && (
130
130
  s.protocol.id !== ProtocolIdentifiers.StrategiesAutomation.MorphoBlue // merge morpho blue with the same marketId
131
131
  || s.strategyData.decoded.triggerData.marketId.toLowerCase() === current.strategyData.decoded.triggerData.marketId.toLowerCase()
132
+ )
133
+ && (
134
+ s.protocol.id !== ProtocolIdentifiers.StrategiesAutomation.AaveV4
135
+ || this._aaveV4MergeSpokesMatch(s, current)
132
136
  );
133
137
  }
134
138
 
139
+ /** Repay/boost leverage pairs must not merge across different Aave V4 spokes. */
140
+ private _aaveV4MergeSpokesMatch(s: Position.Automated, current: Position.Automated): boolean {
141
+ const a = s.strategyData?.decoded?.triggerData?.spoke as EthereumAddress | undefined;
142
+ const b = current.strategyData?.decoded?.triggerData?.spoke as EthereumAddress | undefined;
143
+ return !!a && !!b && a.toLowerCase() === b.toLowerCase();
144
+ }
145
+
135
146
  protected mergeSubs(_subscriptions:(Position.Automated | null)[]) {
136
147
  const mergeBase = _subscriptions.filter(s => isDefined(s) && isDefined(s.specific.mergeWithId)) as Position.Automated[];
137
148
  const mergeExtension = _subscriptions.filter(s => isDefined(s) && isDefined(s.specific.mergeId)) as Position.Automated[];