@defisaver/automation-sdk 3.3.11 → 3.3.12

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 (54) 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 +62 -1
  6. package/cjs/services/strategiesService.js +104 -0
  7. package/cjs/services/strategySubService.d.ts +6 -0
  8. package/cjs/services/strategySubService.js +30 -1
  9. package/cjs/services/strategySubService.test.js +96 -0
  10. package/cjs/services/subDataService.d.ts +295 -137
  11. package/cjs/services/subDataService.js +639 -393
  12. package/cjs/services/subDataService.test.js +157 -0
  13. package/cjs/services/triggerService.d.ts +29 -0
  14. package/cjs/services/triggerService.js +53 -1
  15. package/cjs/services/triggerService.test.js +84 -0
  16. package/cjs/services/utils.d.ts +1 -1
  17. package/cjs/services/utils.js +10 -2
  18. package/cjs/types/enums.d.ts +17 -3
  19. package/cjs/types/enums.js +14 -0
  20. package/cjs/types/index.d.ts +22 -1
  21. package/esm/automation/private/StrategiesAutomation.d.ts +2 -0
  22. package/esm/automation/private/StrategiesAutomation.js +10 -1
  23. package/esm/automation/private/StrategiesAutomation.test.js +25 -0
  24. package/esm/constants/index.d.ts +1 -0
  25. package/esm/constants/index.js +61 -0
  26. package/esm/services/strategiesService.js +105 -1
  27. package/esm/services/strategySubService.d.ts +6 -0
  28. package/esm/services/strategySubService.js +29 -0
  29. package/esm/services/strategySubService.test.js +97 -1
  30. package/esm/services/subDataService.d.ts +295 -137
  31. package/esm/services/subDataService.js +639 -393
  32. package/esm/services/subDataService.test.js +157 -0
  33. package/esm/services/triggerService.d.ts +29 -0
  34. package/esm/services/triggerService.js +52 -0
  35. package/esm/services/triggerService.test.js +85 -1
  36. package/esm/services/utils.d.ts +1 -1
  37. package/esm/services/utils.js +10 -2
  38. package/esm/types/enums.d.ts +17 -3
  39. package/esm/types/enums.js +14 -0
  40. package/esm/types/index.d.ts +22 -1
  41. package/package.json +2 -2
  42. package/src/automation/private/StrategiesAutomation.test.ts +40 -0
  43. package/src/automation/private/StrategiesAutomation.ts +11 -0
  44. package/src/constants/index.ts +62 -0
  45. package/src/services/strategiesService.ts +119 -1
  46. package/src/services/strategySubService.test.ts +124 -0
  47. package/src/services/strategySubService.ts +118 -0
  48. package/src/services/subDataService.test.ts +172 -0
  49. package/src/services/subDataService.ts +1031 -782
  50. package/src/services/triggerService.test.ts +97 -0
  51. package/src/services/triggerService.ts +74 -1
  52. package/src/services/utils.ts +15 -4
  53. package/src/types/enums.ts +14 -0
  54. package/src/types/index.ts +26 -0
@@ -2146,4 +2146,161 @@ describe('Feature: subDataService.ts', () => {
2146
2146
  });
2147
2147
  });
2148
2148
  });
2149
+ describe('When testing subDataService.aaveV4LeverageManagementSubData', () => {
2150
+ describe('encode()', () => {
2151
+ const examples = [
2152
+ [
2153
+ ["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e", "0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x00000000000000000000000000000000000000000000000014d1120d7b160000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"],
2154
+ [web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'), enums_1.RatioState.UNDER, 150]
2155
+ ],
2156
+ ];
2157
+ examples.forEach(([expected, actual]) => {
2158
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
2159
+ (0, chai_1.expect)(subDataService.aaveV4LeverageManagementSubData.encode(...actual)).to.eql(expected);
2160
+ });
2161
+ });
2162
+ });
2163
+ describe('decode()', () => {
2164
+ const examples = [
2165
+ [
2166
+ {
2167
+ spoke: web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'),
2168
+ owner: web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
2169
+ ratioState: enums_1.RatioState.UNDER,
2170
+ targetRatio: 150,
2171
+ },
2172
+ ["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e", "0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x00000000000000000000000000000000000000000000000014d1120d7b160000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"],
2173
+ ],
2174
+ ];
2175
+ examples.forEach(([expected, actual]) => {
2176
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
2177
+ (0, chai_1.expect)(subDataService.aaveV4LeverageManagementSubData.decode(actual)).to.eql(expected);
2178
+ });
2179
+ });
2180
+ });
2181
+ });
2182
+ describe('When testing subDataService.aaveV4LeverageManagementOnPriceSubData', () => {
2183
+ describe('encode()', () => {
2184
+ const examples = [
2185
+ [
2186
+ ["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e", "0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c", "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "0x0000000000000000000000000000000000000000000000000000000000000014", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000000000000000000000000000016345785d8a00000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"],
2187
+ [
2188
+ web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
2189
+ web3Utils.toChecksumAddress('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'), 10,
2190
+ web3Utils.toChecksumAddress('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'), 20,
2191
+ enums_1.RatioState.OVER, 160
2192
+ ]
2193
+ ],
2194
+ ];
2195
+ examples.forEach(([expected, actual]) => {
2196
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
2197
+ (0, chai_1.expect)(subDataService.aaveV4LeverageManagementOnPriceSubData.encode(...actual)).to.eql(expected);
2198
+ });
2199
+ });
2200
+ });
2201
+ describe('decode()', () => {
2202
+ const examples = [
2203
+ [
2204
+ {
2205
+ spoke: web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'),
2206
+ owner: web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
2207
+ collAsset: web3Utils.toChecksumAddress('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'),
2208
+ collAssetId: 10,
2209
+ debtAsset: web3Utils.toChecksumAddress('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
2210
+ debtAssetId: 20,
2211
+ ratioState: enums_1.RatioState.OVER,
2212
+ targetRatio: 160,
2213
+ },
2214
+ ["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e", "0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c", "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "0x0000000000000000000000000000000000000000000000000000000000000014", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000000000000000000000000000016345785d8a00000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"],
2215
+ ],
2216
+ ];
2217
+ examples.forEach(([expected, actual]) => {
2218
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
2219
+ (0, chai_1.expect)(subDataService.aaveV4LeverageManagementOnPriceSubData.decode(actual)).to.eql(expected);
2220
+ });
2221
+ });
2222
+ });
2223
+ });
2224
+ describe('When testing subDataService.aaveV4CloseSubData', () => {
2225
+ describe('encode()', () => {
2226
+ const examples = [
2227
+ [
2228
+ ["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e", "0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c", "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "0x0000000000000000000000000000000000000000000000000000000000000014", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"],
2229
+ [
2230
+ web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
2231
+ web3Utils.toChecksumAddress('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'), 10,
2232
+ web3Utils.toChecksumAddress('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'), 20,
2233
+ enums_1.CloseStrategyType.STOP_LOSS_IN_COLLATERAL
2234
+ ]
2235
+ ],
2236
+ ];
2237
+ examples.forEach(([expected, actual]) => {
2238
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
2239
+ (0, chai_1.expect)(subDataService.aaveV4CloseSubData.encode(...actual)).to.eql(expected);
2240
+ });
2241
+ });
2242
+ });
2243
+ describe('decode()', () => {
2244
+ const examples = [
2245
+ [
2246
+ {
2247
+ spoke: web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'),
2248
+ owner: web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
2249
+ collAsset: web3Utils.toChecksumAddress('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'),
2250
+ collAssetId: 10,
2251
+ debtAsset: web3Utils.toChecksumAddress('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
2252
+ debtAssetId: 20,
2253
+ closeType: enums_1.CloseStrategyType.STOP_LOSS_IN_COLLATERAL,
2254
+ },
2255
+ ["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e", "0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c", "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "0x0000000000000000000000000000000000000000000000000000000000000014", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"],
2256
+ ],
2257
+ ];
2258
+ examples.forEach(([expected, actual]) => {
2259
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
2260
+ (0, chai_1.expect)(subDataService.aaveV4CloseSubData.decode(actual)).to.eql(expected);
2261
+ });
2262
+ });
2263
+ });
2264
+ });
2265
+ describe('When testing subDataService.aaveV4CollateralSwitchSubData', () => {
2266
+ describe('encode()', () => {
2267
+ const examples = [
2268
+ [
2269
+ ["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e", "0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c", "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "0x0000000000000000000000000000000000000000000000000000000000000014", "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"],
2270
+ [
2271
+ web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
2272
+ web3Utils.toChecksumAddress('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'), 10,
2273
+ web3Utils.toChecksumAddress('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'), 20,
2274
+ '1000000000000000000'
2275
+ ]
2276
+ ],
2277
+ ];
2278
+ examples.forEach(([expected, actual]) => {
2279
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
2280
+ (0, chai_1.expect)(subDataService.aaveV4CollateralSwitchSubData.encode(...actual)).to.eql(expected);
2281
+ });
2282
+ });
2283
+ });
2284
+ describe('decode()', () => {
2285
+ const examples = [
2286
+ [
2287
+ {
2288
+ spoke: web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'),
2289
+ owner: web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
2290
+ fromAsset: web3Utils.toChecksumAddress('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'),
2291
+ fromAssetId: 10,
2292
+ toAsset: web3Utils.toChecksumAddress('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
2293
+ toAssetId: 20,
2294
+ amountToSwitch: '1000000000000000000'
2295
+ },
2296
+ ["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e", "0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c", "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "0x0000000000000000000000000000000000000000000000000000000000000014", "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"],
2297
+ ],
2298
+ ];
2299
+ examples.forEach(([expected, actual]) => {
2300
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
2301
+ (0, chai_1.expect)(subDataService.aaveV4CollateralSwitchSubData.decode(actual)).to.eql(expected);
2302
+ });
2303
+ });
2304
+ });
2305
+ });
2149
2306
  });
@@ -294,3 +294,32 @@ export declare const sparkQuotePriceTrigger: {
294
294
  ratioState: number;
295
295
  };
296
296
  };
297
+ export declare const aaveV4RatioTrigger: {
298
+ encode(owner: EthereumAddress, spoke: EthereumAddress, ratioPercentage: number, ratioState: RatioState): string[];
299
+ decode(triggerData: string[]): {
300
+ owner: string;
301
+ spoke: string;
302
+ ratio: number;
303
+ ratioState: number;
304
+ };
305
+ };
306
+ export declare const aaveV4QuotePriceTrigger: {
307
+ encode(spoke: EthereumAddress, baseTokenId: number, quoteTokenId: number, price: string, ratioState: RatioState): string[];
308
+ decode(triggerData: string[]): {
309
+ spoke: string;
310
+ baseTokenId: number;
311
+ quoteTokenId: number;
312
+ price: string;
313
+ ratioState: number;
314
+ };
315
+ };
316
+ export declare const aaveV4QuotePriceRangeTrigger: {
317
+ encode(spoke: EthereumAddress, baseTokenId: number, quoteTokenId: number, lowerPrice: string, upperPrice: string): string[];
318
+ decode(triggerData: string[]): {
319
+ spoke: string;
320
+ baseTokenId: number;
321
+ quoteTokenId: number;
322
+ lowerPrice: string;
323
+ upperPrice: string;
324
+ };
325
+ };
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.sparkQuotePriceTrigger = exports.morphoBluePriceRangeTrigger = exports.sparkQuotePriceRangeTrigger = exports.aaveV3QuotePriceRangeTrigger = exports.compoundV3PriceRangeTrigger = exports.compoundV3PriceTrigger = exports.fluidRatioTrigger = exports.morphoBluePriceTrigger = exports.closePriceTrigger = exports.liquityV2QuotePriceTrigger = exports.liquityV2RatioTrigger = exports.morphoBlueRatioTrigger = exports.crvUsdHealthRatioTrigger = exports.crvUSDRatioTrigger = exports.curveUsdSoftLiquidationTrigger = exports.curveUsdBorrowRateTrigger = exports.sparkRatioTrigger = exports.exchangeOffchainPriceTrigger = exports.exchangeTimestampTrigger = exports.compoundV3RatioTrigger = exports.cBondsRebondTrigger = exports.aaveV2RatioTrigger = exports.liquityV2AdjustTimeTrigger = exports.liquityV2DebtInFrontTrigger = exports.liquityDebtInFrontWithLimitTrigger = exports.liquityDebtInFrontTrigger = exports.liquityRatioTrigger = exports.compoundV2RatioTrigger = exports.aaveV3QuotePriceWithMaximumGasPriceTrigger = exports.aaveV3QuotePriceTrigger = exports.morphoAaveV2RatioTrigger = exports.aaveV3RatioTrigger = exports.makerRatioTrigger = exports.trailingStopTrigger = exports.chainlinkPriceTrigger = void 0;
29
+ exports.aaveV4QuotePriceRangeTrigger = exports.aaveV4QuotePriceTrigger = exports.aaveV4RatioTrigger = exports.sparkQuotePriceTrigger = exports.morphoBluePriceRangeTrigger = exports.sparkQuotePriceRangeTrigger = exports.aaveV3QuotePriceRangeTrigger = exports.compoundV3PriceRangeTrigger = exports.compoundV3PriceTrigger = exports.fluidRatioTrigger = exports.morphoBluePriceTrigger = exports.closePriceTrigger = exports.liquityV2QuotePriceTrigger = exports.liquityV2RatioTrigger = exports.morphoBlueRatioTrigger = exports.crvUsdHealthRatioTrigger = exports.crvUSDRatioTrigger = exports.curveUsdSoftLiquidationTrigger = exports.curveUsdBorrowRateTrigger = exports.sparkRatioTrigger = exports.exchangeOffchainPriceTrigger = exports.exchangeTimestampTrigger = exports.compoundV3RatioTrigger = exports.cBondsRebondTrigger = exports.aaveV2RatioTrigger = exports.liquityV2AdjustTimeTrigger = exports.liquityV2DebtInFrontTrigger = exports.liquityDebtInFrontWithLimitTrigger = exports.liquityDebtInFrontTrigger = exports.liquityRatioTrigger = exports.compoundV2RatioTrigger = exports.aaveV3QuotePriceWithMaximumGasPriceTrigger = exports.aaveV3QuotePriceTrigger = exports.morphoAaveV2RatioTrigger = exports.aaveV3RatioTrigger = exports.makerRatioTrigger = exports.trailingStopTrigger = exports.chainlinkPriceTrigger = void 0;
30
30
  const decimal_js_1 = __importDefault(require("decimal.js"));
31
31
  const tokens_1 = require("@defisaver/tokens");
32
32
  const web3_eth_abi_1 = __importDefault(require("web3-eth-abi"));
@@ -562,3 +562,55 @@ exports.sparkQuotePriceTrigger = {
562
562
  };
563
563
  },
564
564
  };
565
+ exports.aaveV4RatioTrigger = {
566
+ encode(owner, spoke, ratioPercentage, ratioState) {
567
+ const ratioWei = (0, utils_1.ratioPercentageToWei)(ratioPercentage);
568
+ return [web3_eth_abi_1.default.encodeParameters(['address', 'address', 'uint256', 'uint8'], [owner, spoke, ratioWei, ratioState])];
569
+ },
570
+ decode(triggerData) {
571
+ const decodedData = web3_eth_abi_1.default.decodeParameters(['address', 'address', 'uint256', 'uint8'], triggerData[0]);
572
+ return {
573
+ owner: decodedData[0],
574
+ spoke: decodedData[1],
575
+ ratio: (0, utils_1.weiToRatioPercentage)(decodedData[2]),
576
+ ratioState: Number(decodedData[3]),
577
+ };
578
+ },
579
+ };
580
+ exports.aaveV4QuotePriceTrigger = {
581
+ encode(spoke, baseTokenId, quoteTokenId, price, ratioState) {
582
+ // Price is intentionally scaled to 1e18 for higher precision.
583
+ const _price = new decimal_js_1.default(price).mul(1e18).floor().toString();
584
+ return [web3_eth_abi_1.default.encodeParameters(['address', 'uint256', 'uint256', 'uint256', 'uint8'], [spoke, baseTokenId, quoteTokenId, _price, ratioState])];
585
+ },
586
+ decode(triggerData) {
587
+ const decodedData = web3_eth_abi_1.default.decodeParameters(['address', 'uint256', 'uint256', 'uint256', 'uint8'], triggerData[0]);
588
+ return {
589
+ spoke: decodedData[0],
590
+ baseTokenId: Number(decodedData[1]),
591
+ quoteTokenId: Number(decodedData[2]),
592
+ price: new decimal_js_1.default(decodedData[3]).div(1e18).toString(),
593
+ ratioState: Number(decodedData[4]),
594
+ };
595
+ },
596
+ };
597
+ exports.aaveV4QuotePriceRangeTrigger = {
598
+ encode(spoke, baseTokenId, quoteTokenId, lowerPrice, upperPrice) {
599
+ // Price is intentionally scaled to 1e18 for higher precision.
600
+ const lowerPriceFormatted = new decimal_js_1.default(lowerPrice).mul(1e18).floor().toString();
601
+ const upperPriceFormatted = new decimal_js_1.default(upperPrice).mul(1e18).floor().toString();
602
+ return [
603
+ web3_eth_abi_1.default.encodeParameters(['address', 'uint256', 'uint256', 'uint256', 'uint256'], [spoke, baseTokenId, quoteTokenId, lowerPriceFormatted, upperPriceFormatted]),
604
+ ];
605
+ },
606
+ decode(triggerData) {
607
+ const decodedData = web3_eth_abi_1.default.decodeParameters(['address', 'uint256', 'uint256', 'uint256', 'uint256'], triggerData[0]);
608
+ return {
609
+ spoke: decodedData[0],
610
+ baseTokenId: Number(decodedData[1]),
611
+ quoteTokenId: Number(decodedData[2]),
612
+ lowerPrice: new decimal_js_1.default(decodedData[3]).div(1e18).toString(),
613
+ upperPrice: new decimal_js_1.default(decodedData[4]).div(1e18).toString(),
614
+ };
615
+ },
616
+ };
@@ -1184,6 +1184,90 @@ describe('Feature: triggerService.ts', () => {
1184
1184
  });
1185
1185
  });
1186
1186
  });
1187
+ describe('When testing triggerService.aaveV4RatioTrigger', () => {
1188
+ describe('encode()', () => {
1189
+ const examples = [
1190
+ [
1191
+ ['0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000010a741a4627800000000000000000000000000000000000000000000000000000000000000000001'],
1192
+ [web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'), web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), 120, enums_1.RatioState.UNDER]
1193
+ ],
1194
+ ];
1195
+ examples.forEach(([expected, actual]) => {
1196
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
1197
+ (0, chai_1.expect)(triggerService_1.aaveV4RatioTrigger.encode(...actual)).to.eql(expected);
1198
+ });
1199
+ });
1200
+ });
1201
+ describe('decode()', () => {
1202
+ const examples = [
1203
+ [
1204
+ { owner: web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'), spoke: web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), ratio: 120, ratioState: enums_1.RatioState.UNDER },
1205
+ ['0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000010a741a4627800000000000000000000000000000000000000000000000000000000000000000001'],
1206
+ ],
1207
+ ];
1208
+ examples.forEach(([expected, actual]) => {
1209
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
1210
+ (0, chai_1.expect)(triggerService_1.aaveV4RatioTrigger.decode(actual)).to.eql(expected);
1211
+ });
1212
+ });
1213
+ });
1214
+ });
1215
+ describe('When testing triggerService.aaveV4QuotePriceTrigger', () => {
1216
+ describe('encode()', () => {
1217
+ const examples = [
1218
+ [
1219
+ ['0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000000000000000000000000000000000000000000000'],
1220
+ [web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), 10, 20, '1500', enums_1.RatioState.OVER]
1221
+ ],
1222
+ ];
1223
+ examples.forEach(([expected, actual]) => {
1224
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
1225
+ (0, chai_1.expect)(triggerService_1.aaveV4QuotePriceTrigger.encode(...actual)).to.eql(expected);
1226
+ });
1227
+ });
1228
+ });
1229
+ describe('decode()', () => {
1230
+ const examples = [
1231
+ [
1232
+ { spoke: web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), baseTokenId: 10, quoteTokenId: 20, price: '1500', ratioState: enums_1.RatioState.OVER },
1233
+ ['0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000000000000000000000000000000000000000000000'],
1234
+ ],
1235
+ ];
1236
+ examples.forEach(([expected, actual]) => {
1237
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
1238
+ (0, chai_1.expect)(triggerService_1.aaveV4QuotePriceTrigger.decode(actual)).to.eql(expected);
1239
+ });
1240
+ });
1241
+ });
1242
+ });
1243
+ describe('When testing triggerService.aaveV4QuotePriceRangeTrigger', () => {
1244
+ describe('encode()', () => {
1245
+ const examples = [
1246
+ [
1247
+ ['0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000004be4e7267b6ae00000000000000000000000000000000000000000000000000056bc75e2d631000000'],
1248
+ [web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), 10, 20, '1400', '1600']
1249
+ ],
1250
+ ];
1251
+ examples.forEach(([expected, actual]) => {
1252
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
1253
+ (0, chai_1.expect)(triggerService_1.aaveV4QuotePriceRangeTrigger.encode(...actual)).to.eql(expected);
1254
+ });
1255
+ });
1256
+ });
1257
+ describe('decode()', () => {
1258
+ const examples = [
1259
+ [
1260
+ { spoke: web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), baseTokenId: 10, quoteTokenId: 20, lowerPrice: '1400', upperPrice: '1600' },
1261
+ ['0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000004be4e7267b6ae00000000000000000000000000000000000000000000000000056bc75e2d631000000'],
1262
+ ],
1263
+ ];
1264
+ examples.forEach(([expected, actual]) => {
1265
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
1266
+ (0, chai_1.expect)(triggerService_1.aaveV4QuotePriceRangeTrigger.decode(actual)).to.eql(expected);
1267
+ });
1268
+ });
1269
+ });
1270
+ });
1187
1271
  describe('When testing triggerService.sparkQuotePriceTrigger', () => {
1188
1272
  describe('encode()', () => {
1189
1273
  const examples = [
@@ -23,7 +23,7 @@ export declare function getRatioStateInfoForAaveCloseStrategy(currentRatioState:
23
23
  ratioState: RatioState;
24
24
  };
25
25
  export declare function getPositionId(...args: (number | string)[]): string;
26
- export declare function getCloseStrategyType(stopLossPrice: number, stopLossType: CloseToAssetType, takeProfitPrice: number, takeProfitType: CloseToAssetType): CloseStrategyType;
26
+ export declare function getCloseStrategyType(stopLossPrice: number | string, stopLossType: CloseToAssetType, takeProfitPrice: number | string, takeProfitType: CloseToAssetType): CloseStrategyType;
27
27
  export declare function getStopLossAndTakeProfitTypeByCloseStrategyType(closeStrategyType: CloseStrategyType): {
28
28
  stopLossType: CloseToAssetType | undefined;
29
29
  takeProfitType: CloseToAssetType | undefined;
@@ -130,8 +130,16 @@ function getPositionId(...args) {
130
130
  }
131
131
  exports.getPositionId = getPositionId;
132
132
  function getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType) {
133
- const isStopLoss = stopLossPrice > 0;
134
- const isTakeProfit = takeProfitPrice > 0;
133
+ const stopLossPriceDec = new decimal_js_1.default(stopLossPrice);
134
+ const takeProfitPriceDec = new decimal_js_1.default(takeProfitPrice);
135
+ if (!stopLossPriceDec.isFinite() || stopLossPriceDec.isNegative()) {
136
+ throw new Error('CloseOnPrice: stopLossPrice must be a finite non-negative number');
137
+ }
138
+ if (!takeProfitPriceDec.isFinite() || takeProfitPriceDec.isNegative()) {
139
+ throw new Error('CloseOnPrice: takeProfitPrice must be a finite non-negative number');
140
+ }
141
+ const isStopLoss = stopLossPriceDec.gt(0);
142
+ const isTakeProfit = takeProfitPriceDec.gt(0);
135
143
  if (!isStopLoss && !isTakeProfit) {
136
144
  throw new Error('CloseOnPrice: At least one price must be defined');
137
145
  }
@@ -56,6 +56,7 @@ export declare namespace ProtocolIdentifiers {
56
56
  CompoundV3 = "Compound__V3",
57
57
  AaveV2 = "Aave__V2",
58
58
  AaveV3 = "Aave__V3",
59
+ AaveV4 = "Aave__V4",
59
60
  MorphoAaveV2 = "Morpho-Aave__V2",
60
61
  Exchange = "Exchange",
61
62
  Spark = "Spark",
@@ -86,7 +87,9 @@ export declare namespace Strategies {
86
87
  LIQUITY_DEBT_IN_FRONT_REPAY = 75,
87
88
  CURVEUSD_PAYBACK = 92,
88
89
  LIQUITY_V2_PAYBACK = 113,
89
- AAVE_V3_COLLATERAL_SWITCH = 135
90
+ AAVE_V3_COLLATERAL_SWITCH = 135,
91
+ AAVE_V4_COLLATERAL_SWITCH = 154,
92
+ AAVE_V4_COLLATERAL_SWITCH_EOA = 155
90
93
  }
91
94
  enum OptimismIds {
92
95
  EXCHANGE_DCA = 8,
@@ -133,7 +136,8 @@ export declare namespace Strategies {
133
136
  RepayOnPrice = "repay-on-price",
134
137
  EoaBoostOnPrice = "eoa-boost-on-price",
135
138
  EoaRepayOnPrice = "eoa-repay-on-price",
136
- CollateralSwitch = "collateral-switch"
139
+ CollateralSwitch = "collateral-switch",
140
+ EoaCollateralSwitch = "eoa-collateral-switch"
137
141
  }
138
142
  enum IdOverrides {
139
143
  TakeProfit = "take-profit",
@@ -209,7 +213,17 @@ export declare namespace Bundles {
209
213
  SPARK_CLOSE = 57,
210
214
  MORPHO_BLUE_CLOSE = 58,
211
215
  SPARK_REPAY_ON_PRICE = 59,
212
- SPARK_BOOST_ON_PRICE = 60
216
+ SPARK_BOOST_ON_PRICE = 60,
217
+ AAVE_V4_REPAY = 61,
218
+ AAVE_V4_BOOST = 62,
219
+ AAVE_V4_REPAY_ON_PRICE = 63,
220
+ AAVE_V4_BOOST_ON_PRICE = 64,
221
+ AAVE_V4_CLOSE = 65,
222
+ AAVE_V4_EOA_REPAY = 66,
223
+ AAVE_V4_EOA_BOOST = 67,
224
+ AAVE_V4_EOA_REPAY_ON_PRICE = 68,
225
+ AAVE_V4_EOA_BOOST_ON_PRICE = 69,
226
+ AAVE_V4_EOA_CLOSE = 70
213
227
  }
214
228
  enum OptimismIds {
215
229
  AAVE_V3_REPAY = 0,
@@ -69,6 +69,7 @@ var ProtocolIdentifiers;
69
69
  StrategiesAutomation["CompoundV3"] = "Compound__V3";
70
70
  StrategiesAutomation["AaveV2"] = "Aave__V2";
71
71
  StrategiesAutomation["AaveV3"] = "Aave__V3";
72
+ StrategiesAutomation["AaveV4"] = "Aave__V4";
72
73
  StrategiesAutomation["MorphoAaveV2"] = "Morpho-Aave__V2";
73
74
  StrategiesAutomation["Exchange"] = "Exchange";
74
75
  StrategiesAutomation["Spark"] = "Spark";
@@ -103,6 +104,8 @@ var Strategies;
103
104
  MainnetIds[MainnetIds["CURVEUSD_PAYBACK"] = 92] = "CURVEUSD_PAYBACK";
104
105
  MainnetIds[MainnetIds["LIQUITY_V2_PAYBACK"] = 113] = "LIQUITY_V2_PAYBACK";
105
106
  MainnetIds[MainnetIds["AAVE_V3_COLLATERAL_SWITCH"] = 135] = "AAVE_V3_COLLATERAL_SWITCH";
107
+ MainnetIds[MainnetIds["AAVE_V4_COLLATERAL_SWITCH"] = 154] = "AAVE_V4_COLLATERAL_SWITCH";
108
+ MainnetIds[MainnetIds["AAVE_V4_COLLATERAL_SWITCH_EOA"] = 155] = "AAVE_V4_COLLATERAL_SWITCH_EOA";
106
109
  })(MainnetIds = Strategies.MainnetIds || (Strategies.MainnetIds = {}));
107
110
  let OptimismIds;
108
111
  (function (OptimismIds) {
@@ -154,6 +157,7 @@ var Strategies;
154
157
  Identifiers["EoaBoostOnPrice"] = "eoa-boost-on-price";
155
158
  Identifiers["EoaRepayOnPrice"] = "eoa-repay-on-price";
156
159
  Identifiers["CollateralSwitch"] = "collateral-switch";
160
+ Identifiers["EoaCollateralSwitch"] = "eoa-collateral-switch";
157
161
  })(Identifiers = Strategies.Identifiers || (Strategies.Identifiers = {}));
158
162
  let IdOverrides;
159
163
  (function (IdOverrides) {
@@ -233,6 +237,16 @@ var Bundles;
233
237
  MainnetIds[MainnetIds["MORPHO_BLUE_CLOSE"] = 58] = "MORPHO_BLUE_CLOSE";
234
238
  MainnetIds[MainnetIds["SPARK_REPAY_ON_PRICE"] = 59] = "SPARK_REPAY_ON_PRICE";
235
239
  MainnetIds[MainnetIds["SPARK_BOOST_ON_PRICE"] = 60] = "SPARK_BOOST_ON_PRICE";
240
+ MainnetIds[MainnetIds["AAVE_V4_REPAY"] = 61] = "AAVE_V4_REPAY";
241
+ MainnetIds[MainnetIds["AAVE_V4_BOOST"] = 62] = "AAVE_V4_BOOST";
242
+ MainnetIds[MainnetIds["AAVE_V4_REPAY_ON_PRICE"] = 63] = "AAVE_V4_REPAY_ON_PRICE";
243
+ MainnetIds[MainnetIds["AAVE_V4_BOOST_ON_PRICE"] = 64] = "AAVE_V4_BOOST_ON_PRICE";
244
+ MainnetIds[MainnetIds["AAVE_V4_CLOSE"] = 65] = "AAVE_V4_CLOSE";
245
+ MainnetIds[MainnetIds["AAVE_V4_EOA_REPAY"] = 66] = "AAVE_V4_EOA_REPAY";
246
+ MainnetIds[MainnetIds["AAVE_V4_EOA_BOOST"] = 67] = "AAVE_V4_EOA_BOOST";
247
+ MainnetIds[MainnetIds["AAVE_V4_EOA_REPAY_ON_PRICE"] = 68] = "AAVE_V4_EOA_REPAY_ON_PRICE";
248
+ MainnetIds[MainnetIds["AAVE_V4_EOA_BOOST_ON_PRICE"] = 69] = "AAVE_V4_EOA_BOOST_ON_PRICE";
249
+ MainnetIds[MainnetIds["AAVE_V4_EOA_CLOSE"] = 70] = "AAVE_V4_EOA_CLOSE";
236
250
  })(MainnetIds = Bundles.MainnetIds || (Bundles.MainnetIds = {}));
237
251
  let OptimismIds;
238
252
  (function (OptimismIds) {
@@ -208,8 +208,29 @@ export declare namespace Position {
208
208
  ratioState: RatioState;
209
209
  ratio: number;
210
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
+ }
211
232
  }
212
- 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.SparkOnPrice;
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;
213
234
  interface Automated {
214
235
  chainId: ChainId;
215
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>;