@defisaver/automation-sdk 3.3.11 → 3.3.12-strategies-refactor-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 (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 +11 -0
  8. package/cjs/services/strategySubService.js +61 -1
  9. package/cjs/services/strategySubService.test.js +96 -0
  10. package/cjs/services/subDataService.d.ts +333 -137
  11. package/cjs/services/subDataService.js +853 -537
  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 +11 -0
  28. package/esm/services/strategySubService.js +60 -0
  29. package/esm/services/strategySubService.test.js +97 -1
  30. package/esm/services/subDataService.d.ts +333 -137
  31. package/esm/services/subDataService.js +852 -537
  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 +196 -0
  48. package/src/services/subDataService.test.ts +172 -0
  49. package/src/services/subDataService.ts +1100 -764
  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
@@ -23,6 +23,8 @@ import LegacyProtocol from '../automation/private/LegacyProtocol';
23
23
  // General
24
24
  export const ZERO_ADDRESS: EthereumAddress = '0x0000000000000000000000000000000000000000';
25
25
 
26
+ export const EMPTY_SLOT: string = '0x0000000000000000000000000000000000000000000000000000000000000000';
27
+
26
28
  export const AAVE_V3_VARIABLE_BORROW_RATE = 2;
27
29
 
28
30
  export const PROTOCOLS: Record<keyof typeof ProtocolIdentifiers.StrategiesAutomation, Interfaces.Protocol> = (() => {
@@ -123,6 +125,16 @@ export const MAINNET_STRATEGIES_INFO: MainnetStrategiesInfo = {
123
125
  strategyId: Strategies.Identifiers.CollateralSwitch,
124
126
  protocol: PROTOCOLS.AaveV3,
125
127
  },
128
+ [Strategies.MainnetIds.AAVE_V4_COLLATERAL_SWITCH]: {
129
+ strategyOrBundleId: Strategies.MainnetIds.AAVE_V4_COLLATERAL_SWITCH,
130
+ strategyId: Strategies.Identifiers.CollateralSwitch,
131
+ protocol: PROTOCOLS.AaveV4,
132
+ },
133
+ [Strategies.MainnetIds.AAVE_V4_COLLATERAL_SWITCH_EOA]: {
134
+ strategyOrBundleId: Strategies.MainnetIds.AAVE_V4_COLLATERAL_SWITCH_EOA,
135
+ strategyId: Strategies.Identifiers.EoaCollateralSwitch,
136
+ protocol: PROTOCOLS.AaveV4,
137
+ },
126
138
  };
127
139
 
128
140
  export const OPTIMISM_STRATEGIES_INFO: OptimismStrategiesInfo = {
@@ -506,6 +518,56 @@ export const MAINNET_BUNDLES_INFO: MainnetBundleInfo = {
506
518
  strategyId: Strategies.Identifiers.BoostOnPrice,
507
519
  protocol: PROTOCOLS.Spark,
508
520
  },
521
+ [Bundles.MainnetIds.AAVE_V4_REPAY]: {
522
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_REPAY,
523
+ strategyId: Strategies.Identifiers.Repay,
524
+ protocol: PROTOCOLS.AaveV4,
525
+ },
526
+ [Bundles.MainnetIds.AAVE_V4_BOOST]: {
527
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_BOOST,
528
+ strategyId: Strategies.Identifiers.Boost,
529
+ protocol: PROTOCOLS.AaveV4,
530
+ },
531
+ [Bundles.MainnetIds.AAVE_V4_REPAY_ON_PRICE]: {
532
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_REPAY_ON_PRICE,
533
+ strategyId: Strategies.Identifiers.RepayOnPrice,
534
+ protocol: PROTOCOLS.AaveV4,
535
+ },
536
+ [Bundles.MainnetIds.AAVE_V4_BOOST_ON_PRICE]: {
537
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_BOOST_ON_PRICE,
538
+ strategyId: Strategies.Identifiers.BoostOnPrice,
539
+ protocol: PROTOCOLS.AaveV4,
540
+ },
541
+ [Bundles.MainnetIds.AAVE_V4_CLOSE]: {
542
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_CLOSE,
543
+ strategyId: Strategies.Identifiers.CloseOnPrice,
544
+ protocol: PROTOCOLS.AaveV4,
545
+ },
546
+ [Bundles.MainnetIds.AAVE_V4_EOA_REPAY]: {
547
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_EOA_REPAY,
548
+ strategyId: Strategies.Identifiers.EoaRepay,
549
+ protocol: PROTOCOLS.AaveV4,
550
+ },
551
+ [Bundles.MainnetIds.AAVE_V4_EOA_BOOST]: {
552
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_EOA_BOOST,
553
+ strategyId: Strategies.Identifiers.EoaBoost,
554
+ protocol: PROTOCOLS.AaveV4,
555
+ },
556
+ [Bundles.MainnetIds.AAVE_V4_EOA_REPAY_ON_PRICE]: {
557
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_EOA_REPAY_ON_PRICE,
558
+ strategyId: Strategies.Identifiers.EoaRepayOnPrice,
559
+ protocol: PROTOCOLS.AaveV4,
560
+ },
561
+ [Bundles.MainnetIds.AAVE_V4_EOA_BOOST_ON_PRICE]: {
562
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_EOA_BOOST_ON_PRICE,
563
+ strategyId: Strategies.Identifiers.EoaBoostOnPrice,
564
+ protocol: PROTOCOLS.AaveV4,
565
+ },
566
+ [Bundles.MainnetIds.AAVE_V4_EOA_CLOSE]: {
567
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V4_EOA_CLOSE,
568
+ strategyId: Strategies.Identifiers.EoaCloseOnPrice,
569
+ protocol: PROTOCOLS.AaveV4,
570
+ },
509
571
  };
510
572
 
511
573
  export const OPTIMISM_BUNDLES_INFO: OptimismBundleInfo = {
@@ -7,7 +7,9 @@ import type {
7
7
  Position, ParseData, StrategiesToProtocolVersionMapping, BundleOrStrategy, StrategyOrBundleIds,
8
8
  BundleInfoUnion, StrategyInfoUnion,
9
9
  } from '../types';
10
- import { ChainId, ProtocolIdentifiers, Strategies } from '../types/enums';
10
+ import {
11
+ ChainId, ProtocolIdentifiers, RatioState, Strategies,
12
+ } from '../types/enums';
11
13
 
12
14
  import {
13
15
  getPositionId, getRatioStateInfoForAaveCloseStrategy, getStopLossAndTakeProfitTypeByCloseStrategyType, isRatioStateOver, wethToEthByAddress,
@@ -383,6 +385,108 @@ function parseAaveV3CollateralSwitch(position: Position.Automated, parseData: Pa
383
385
  return _position;
384
386
  }
385
387
 
388
+ function parseAaveV4LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
389
+ const _position = cloneDeep(position);
390
+ const { subStruct, subId, subHash } = parseData.subscriptionEventData;
391
+ const { isEnabled } = parseData.strategiesSubsData;
392
+ const triggerData = triggerService.aaveV4RatioTrigger.decode(subStruct.triggerData);
393
+ const subData = subDataService.aaveV4LeverageManagementSubData.decode(subStruct.subData);
394
+ const isEOA = _position.strategy.strategyId.includes('eoa');
395
+ const isRepay = [Strategies.Identifiers.Repay, Strategies.Identifiers.EoaRepay].includes(_position.strategy.strategyId as Strategies.Identifiers);
396
+
397
+ _position.strategyData.decoded.triggerData = triggerData;
398
+ _position.strategyData.decoded.subData = subData;
399
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.spoke);
400
+ _position.strategy.strategyId = isEOA ? Strategies.IdOverrides.EoaLeverageManagement : Strategies.IdOverrides.LeverageManagement;
401
+
402
+ if (isRepay) {
403
+ _position.specific = {
404
+ triggerRepayRatio: triggerData.ratio,
405
+ targetRepayRatio: subData.targetRatio,
406
+ repayEnabled: isEnabled,
407
+ subId1: Number(subId),
408
+ mergeWithId: isEOA ? Strategies.Identifiers.EoaBoost : Strategies.Identifiers.Boost,
409
+ subHashRepay: subHash,
410
+ };
411
+ } else {
412
+ _position.specific = {
413
+ triggerBoostRatio: triggerData.ratio,
414
+ targetBoostRatio: subData.targetRatio,
415
+ boostEnabled: isEnabled,
416
+ subId2: Number(subId),
417
+ mergeId: isEOA ? Strategies.Identifiers.EoaBoost : Strategies.Identifiers.Boost,
418
+ subHashBoost: subHash,
419
+ };
420
+ }
421
+
422
+ return _position;
423
+ }
424
+
425
+ function parseAaveV4LeverageManagementOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
426
+ const _position = cloneDeep(position);
427
+ const { subStruct } = parseData.subscriptionEventData;
428
+ const triggerData = triggerService.aaveV4QuotePriceTrigger.decode(subStruct.triggerData);
429
+ const subData = subDataService.aaveV4LeverageManagementOnPriceSubData.decode(subStruct.subData);
430
+ const isEOA = _position.strategy.strategyId.includes('eoa');
431
+
432
+ _position.strategyData.decoded.triggerData = triggerData;
433
+ _position.strategyData.decoded.subData = subData;
434
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.spoke);
435
+ _position.strategy.strategyId = isEOA ? Strategies.IdOverrides.EoaLeverageManagementOnPrice : Strategies.IdOverrides.LeverageManagementOnPrice;
436
+
437
+ _position.specific = {
438
+ collAsset: subData.collAsset,
439
+ collAssetId: subData.collAssetId,
440
+ debtAsset: subData.debtAsset,
441
+ debtAssetId: subData.debtAssetId,
442
+ price: triggerData.price,
443
+ ratioState: triggerData.ratioState,
444
+ ratio: subData.targetRatio,
445
+ };
446
+
447
+ return _position;
448
+ }
449
+
450
+ function parseAaveV4CloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
451
+ const _position = cloneDeep(position);
452
+ const { subStruct } = parseData.subscriptionEventData;
453
+ const triggerData = triggerService.aaveV4QuotePriceRangeTrigger.decode(subStruct.triggerData);
454
+ const subData = subDataService.aaveV4CloseSubData.decode(subStruct.subData);
455
+ const { takeProfitType, stopLossType } = getStopLossAndTakeProfitTypeByCloseStrategyType(+subData.closeType);
456
+ const isEOA = _position.strategy.strategyId.includes('eoa');
457
+
458
+ _position.strategyData.decoded.triggerData = triggerData;
459
+ _position.strategyData.decoded.subData = subData;
460
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.spoke);
461
+ _position.strategy.strategyId = isEOA ? Strategies.Identifiers.EoaCloseOnPrice : Strategies.Identifiers.CloseOnPrice;
462
+
463
+ _position.specific = {
464
+ collAsset: subData.collAsset,
465
+ collAssetId: subData.collAssetId,
466
+ debtAsset: subData.debtAsset,
467
+ debtAssetId: subData.debtAssetId,
468
+ stopLossPrice: triggerData.lowerPrice,
469
+ takeProfitPrice: triggerData.upperPrice,
470
+ stopLossType,
471
+ takeProfitType,
472
+ };
473
+
474
+ return _position;
475
+ }
476
+
477
+ function parseAaveV4CollateralSwitch(position: Position.Automated, parseData: ParseData): Position.Automated {
478
+ const _position = cloneDeep(position);
479
+ const { subStruct } = parseData.subscriptionEventData;
480
+ const triggerData = triggerService.aaveV4QuotePriceTrigger.decode(subStruct.triggerData);
481
+ const subData = subDataService.aaveV4CollateralSwitchSubData.decode(subStruct.subData);
482
+ const isEOA = _position.strategy.strategyId.includes('eoa');
483
+ _position.strategyData.decoded.triggerData = triggerData;
484
+ _position.strategyData.decoded.subData = subData;
485
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.spoke);
486
+ _position.strategy.strategyId = isEOA ? Strategies.Identifiers.EoaCollateralSwitch : Strategies.Identifiers.CollateralSwitch;
487
+ return _position;
488
+ }
489
+
386
490
  function parseMorphoAaveV2LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
387
491
  const _position = cloneDeep(position);
388
492
 
@@ -1235,6 +1339,20 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
1235
1339
  [Strategies.Identifiers.EoaCloseOnPrice]: parseAaveV3CloseOnPrice,
1236
1340
  [Strategies.Identifiers.CollateralSwitch]: parseAaveV3CollateralSwitch,
1237
1341
  },
1342
+ [ProtocolIdentifiers.StrategiesAutomation.AaveV4]: {
1343
+ [Strategies.Identifiers.Repay]: parseAaveV4LeverageManagement,
1344
+ [Strategies.Identifiers.Boost]: parseAaveV4LeverageManagement,
1345
+ [Strategies.Identifiers.RepayOnPrice]: parseAaveV4LeverageManagementOnPrice,
1346
+ [Strategies.Identifiers.BoostOnPrice]: parseAaveV4LeverageManagementOnPrice,
1347
+ [Strategies.Identifiers.CloseOnPrice]: parseAaveV4CloseOnPrice,
1348
+ [Strategies.Identifiers.EoaRepay]: parseAaveV4LeverageManagement,
1349
+ [Strategies.Identifiers.EoaBoost]: parseAaveV4LeverageManagement,
1350
+ [Strategies.Identifiers.EoaRepayOnPrice]: parseAaveV4LeverageManagementOnPrice,
1351
+ [Strategies.Identifiers.EoaBoostOnPrice]: parseAaveV4LeverageManagementOnPrice,
1352
+ [Strategies.Identifiers.EoaCloseOnPrice]: parseAaveV4CloseOnPrice,
1353
+ [Strategies.Identifiers.CollateralSwitch]: parseAaveV4CollateralSwitch,
1354
+ [Strategies.Identifiers.EoaCollateralSwitch]: parseAaveV4CollateralSwitch,
1355
+ },
1238
1356
  [ProtocolIdentifiers.StrategiesAutomation.CompoundV2]: {
1239
1357
  [Strategies.Identifiers.Repay]: parseCompoundV2LeverageManagement,
1240
1358
  [Strategies.Identifiers.Boost]: parseCompoundV2LeverageManagement,
@@ -22,6 +22,7 @@ import {
22
22
  compoundV3L2Encode,
23
23
  morphoBlueEncode,
24
24
  sparkEncode,
25
+ aaveV4Encode,
25
26
  } from './strategySubService';
26
27
 
27
28
  describe('Feature: strategySubService.ts', () => {
@@ -1892,4 +1893,127 @@ describe('Feature: strategySubService.ts', () => {
1892
1893
  });
1893
1894
  });
1894
1895
  });
1896
+ describe('When testing strategySubService.aaveV4Encode', () => {
1897
+ describe('leverageManagement()', () => {
1898
+ const examples: Array<[
1899
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
1900
+ [
1901
+ strategyOrBundleId: number, owner: EthereumAddress, spoke: EthereumAddress, ratioState: RatioState, targetRatio: number, triggerRatio: number
1902
+ ]
1903
+ ]> = [
1904
+ [
1905
+ [1,true,["0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000010a741a4627800000000000000000000000000000000000000000000000000000000000000000001"],["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e","0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c","0x0000000000000000000000000000000000000000000000000000000000000001","0x00000000000000000000000000000000000000000000000014d1120d7b160000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"]],
1906
+ [
1907
+ 1,
1908
+ web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
1909
+ web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'),
1910
+ RatioState.UNDER,
1911
+ 150,
1912
+ 120,
1913
+ ]
1914
+ ]
1915
+ ];
1916
+
1917
+ examples.forEach(([expected, actual]) => {
1918
+ it(`Given ${JSON.stringify(actual)} should return expected value: ${JSON.stringify(expected)}`, () => {
1919
+ expect(aaveV4Encode.leverageManagement(...actual)).to.eql(expected);
1920
+ });
1921
+ });
1922
+ });
1923
+
1924
+ describe('leverageManagementOnPrice()', () => {
1925
+ const examples: Array<[
1926
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
1927
+ [
1928
+ strategyOrBundleId: number, owner: EthereumAddress, spoke: EthereumAddress, collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number, targetRatio: number, price: string, priceState: RatioState, ratioState: RatioState
1929
+ ]
1930
+ ]> = [
1931
+ [
1932
+ [2,true,["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e","0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c","0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0x000000000000000000000000000000000000000000000000000000000000000a","0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","0x0000000000000000000000000000000000000000000000000000000000000014","0x0000000000000000000000000000000000000000000000000000000000000000","0x00000000000000000000000000000000000000000000000016345785d8a00000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"]],
1933
+ [
1934
+ 2,
1935
+ web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
1936
+ web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'),
1937
+ web3Utils.toChecksumAddress('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'),
1938
+ 10,
1939
+ web3Utils.toChecksumAddress('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
1940
+ 20,
1941
+ 160,
1942
+ '1500',
1943
+ RatioState.OVER, // priceState - goes to trigger
1944
+ RatioState.OVER, // ratioState - UNDER for repay, OVER for boost
1945
+ ]
1946
+ ]
1947
+ ];
1948
+
1949
+ examples.forEach(([expected, actual]) => {
1950
+ it(`Given ${JSON.stringify(actual)} should return expected value: ${JSON.stringify(expected)}`, () => {
1951
+ expect(aaveV4Encode.leverageManagementOnPrice(...actual)).to.eql(expected);
1952
+ });
1953
+ });
1954
+ });
1955
+
1956
+ describe('closeOnPrice()', () => {
1957
+ const examples: Array<[
1958
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
1959
+ [
1960
+ strategyOrBundleId: number, owner: EthereumAddress, spoke: EthereumAddress, collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number, stopLossPrice: string, stopLossType: CloseToAssetType, takeProfitPrice: string, takeProfitType: CloseToAssetType
1961
+ ]
1962
+ ]> = [
1963
+ [
1964
+ [3,true,["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000004be4e7267b6ae000000000000000000000000000000000000000000000000000000000000000000000"],["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e","0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c","0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0x000000000000000000000000000000000000000000000000000000000000000a","0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","0x0000000000000000000000000000000000000000000000000000000000000014","0x0000000000000000000000000000000000000000000000000000000000000003","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"]],
1965
+ [
1966
+ 3,
1967
+ web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
1968
+ web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'),
1969
+ web3Utils.toChecksumAddress('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'),
1970
+ 10,
1971
+ web3Utils.toChecksumAddress('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
1972
+ 20,
1973
+ '1400',
1974
+ CloseToAssetType.DEBT,
1975
+ '0',
1976
+ CloseToAssetType.COLLATERAL
1977
+ ]
1978
+ ]
1979
+ ];
1980
+
1981
+ examples.forEach(([expected, actual]) => {
1982
+ it(`Given ${JSON.stringify(actual)} should return expected value: ${JSON.stringify(expected)}`, () => {
1983
+ expect(aaveV4Encode.closeOnPrice(...actual)).to.eql(expected);
1984
+ });
1985
+ });
1986
+ });
1987
+
1988
+ describe('collateralSwitch()', () => {
1989
+ const examples: Array<[
1990
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
1991
+ [
1992
+ strategyOrBundleId: number, owner: EthereumAddress, spoke: EthereumAddress, fromAsset: EthereumAddress, fromAssetId: number, toAsset: EthereumAddress, toAssetId: number, amountToSwitch: string, price: string, ratioState: RatioState
1993
+ ]
1994
+ ]> = [
1995
+ [
1996
+ [4,false,["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000000000000000000000000000000000000000000001"],["0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e","0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c","0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","0x000000000000000000000000000000000000000000000000000000000000000a","0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","0x0000000000000000000000000000000000000000000000000000000000000014","0x0000000000000000000000000000000000000000000000000de0b6b3a7640000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"]],
1997
+ [
1998
+ 4,
1999
+ web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
2000
+ web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'),
2001
+ web3Utils.toChecksumAddress('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'),
2002
+ 10,
2003
+ web3Utils.toChecksumAddress('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
2004
+ 20,
2005
+ '1000000000000000000',
2006
+ '1500',
2007
+ RatioState.UNDER,
2008
+ ]
2009
+ ]
2010
+ ];
2011
+
2012
+ examples.forEach(([expected, actual]) => {
2013
+ it(`Given ${JSON.stringify(actual)} should return expected value: ${JSON.stringify(expected)}`, () => {
2014
+ expect(aaveV4Encode.collateralSwitch(...actual)).to.eql(expected);
2015
+ });
2016
+ });
2017
+ });
2018
+ });
1895
2019
  });
@@ -194,6 +194,20 @@ export const liquityEncode = {
194
194
  boostEnabled,
195
195
  ];
196
196
  },
197
+ leverageManagementWithoutSubProxy(
198
+ strategyOrBundleId: number,
199
+ user: EthereumAddress,
200
+ ratioState: RatioState,
201
+ targetRatio: number,
202
+ triggerRatio: number,
203
+ ) {
204
+ const isBundle = true;
205
+
206
+ const subData = subDataService.liquityLeverageManagementSubDataWithoutSubProxy.encode(targetRatio, ratioState);
207
+ const triggerData = triggerService.liquityRatioTrigger.encode(user, triggerRatio, ratioState);
208
+
209
+ return [strategyOrBundleId, isBundle, triggerData, subData];
210
+ },
197
211
  dsrPayback(
198
212
  proxyAddress: EthereumAddress,
199
213
  triggerRatio: number,
@@ -257,6 +271,21 @@ export const aaveV2Encode = {
257
271
  ) {
258
272
  return subDataService.aaveV2LeverageManagementSubData.encode(triggerRepayRatio, triggerBoostRatio, targetBoostRatio, targetRepayRatio, boostEnabled);
259
273
  },
274
+ leverageManagementWithoutSubProxy(
275
+ strategyOrBundleId: number,
276
+ market: EthereumAddress,
277
+ user: EthereumAddress,
278
+ ratioState: RatioState,
279
+ targetRatio: number,
280
+ triggerRatio: number,
281
+ ) {
282
+ const isBundle = true;
283
+
284
+ const subData = subDataService.aaveV2LeverageManagementSubDataWithoutSubProxy.encode(targetRatio, ratioState);
285
+ const triggerData = triggerService.aaveV2RatioTrigger.encode(user, market, triggerRatio, ratioState);
286
+
287
+ return [strategyOrBundleId, isBundle, triggerData, subData];
288
+ },
260
289
  };
261
290
 
262
291
  export const aaveV3Encode = {
@@ -450,6 +479,20 @@ export const compoundV2Encode = {
450
479
  ) {
451
480
  return subDataService.compoundV2LeverageManagementSubData.encode(triggerRepayRatio, triggerBoostRatio, targetBoostRatio, targetRepayRatio, boostEnabled);
452
481
  },
482
+ leverageManagementWithoutSubProxy(
483
+ strategyOrBundleId: number,
484
+ user: EthereumAddress,
485
+ ratioState: RatioState,
486
+ targetRatio: number,
487
+ triggerRatio: number,
488
+ ) {
489
+ const isBundle = true;
490
+
491
+ const subData = subDataService.compoundV2LeverageManagementSubDataWithoutSubProxy.encode(targetRatio, ratioState);
492
+ const triggerData = triggerService.compoundV2RatioTrigger.encode(user, triggerRatio, ratioState);
493
+
494
+ return [strategyOrBundleId, isBundle, triggerData, subData];
495
+ },
453
496
  };
454
497
 
455
498
  export const compoundV3Encode = {
@@ -465,6 +508,22 @@ export const compoundV3Encode = {
465
508
  ) {
466
509
  return subDataService.compoundV3LeverageManagementSubData.encode(market, baseToken, triggerRepayRatio, triggerBoostRatio, targetBoostRatio, targetRepayRatio, boostEnabled, isEOA);
467
510
  },
511
+ leverageManagementWithoutSubProxy(
512
+ strategyOrBundleId: number,
513
+ market: EthereumAddress,
514
+ baseToken: EthereumAddress,
515
+ user: EthereumAddress,
516
+ ratioState: RatioState,
517
+ targetRatio: number,
518
+ triggerRatio: number,
519
+ ) {
520
+ const isBundle = true;
521
+
522
+ const subData = subDataService.compoundV3LeverageManagementSubDataWithoutSubProxy.encode(market, baseToken, targetRatio, ratioState);
523
+ const triggerData = triggerService.compoundV3RatioTrigger.encode(user, market, triggerRatio, ratioState);
524
+
525
+ return [strategyOrBundleId, isBundle, triggerData, subData];
526
+ },
468
527
  leverageManagementOnPrice(
469
528
  strategyOrBundleId: number,
470
529
  market: EthereumAddress,
@@ -557,6 +616,25 @@ export const exchangeEncode = {
557
616
  ) {
558
617
  return subDataService.exchangeLimitOrderSubData.encode(fromToken, toToken, amount, targetPrice, goodUntil, orderType);
559
618
  },
619
+ limitOrderWithoutSubProxy(
620
+ fromToken: EthereumAddress,
621
+ toToken: EthereumAddress,
622
+ amount: string,
623
+ targetPrice: string,
624
+ goodUntil: string | number,
625
+ orderType: OrderType,
626
+ fromTokenDecimals: number,
627
+ toTokenDecimals: number,
628
+ network: ChainId,
629
+ ) {
630
+ requireAddresses([fromToken, toToken]);
631
+ const subData = subDataService.exchangeLimitOrderSubDataWithoutSubProxy.encode(fromToken, toToken, amount);
632
+ const triggerData = triggerService.exchangeOffchainPriceTrigger.encode(targetPrice, Number(goodUntil), orderType, fromTokenDecimals, toTokenDecimals);
633
+
634
+ const strategyId = STRATEGY_IDS[network].EXCHANGE_LIMIT_ORDER;
635
+
636
+ return [strategyId, false, triggerData, subData];
637
+ },
560
638
  };
561
639
 
562
640
  export const sparkEncode = {
@@ -846,3 +924,121 @@ export const fluidEncode = {
846
924
  return [strategyOrBundleId, isBundle, triggerData, subData];
847
925
  },
848
926
  };
927
+
928
+ export const aaveV4Encode = {
929
+ leverageManagement(
930
+ strategyOrBundleId: number,
931
+ owner: EthereumAddress,
932
+ spoke: EthereumAddress,
933
+ ratioState: RatioState,
934
+ targetRatio: number,
935
+ triggerRatio: number,
936
+ ) {
937
+ const isBundle = true;
938
+ const subData = subDataService.aaveV4LeverageManagementSubData.encode(spoke, owner, ratioState, targetRatio);
939
+ const triggerData = triggerService.aaveV4RatioTrigger.encode(owner, spoke, triggerRatio, ratioState);
940
+
941
+ return [strategyOrBundleId, isBundle, triggerData, subData];
942
+ },
943
+ leverageManagementOnPrice(
944
+ strategyOrBundleId: number,
945
+ owner: EthereumAddress,
946
+ spoke: EthereumAddress,
947
+ collAsset: EthereumAddress,
948
+ collAssetId: number,
949
+ debtAsset: EthereumAddress,
950
+ debtAssetId: number,
951
+ targetRatio: number,
952
+ price: string,
953
+ priceState: RatioState,
954
+ ratioState: RatioState, // UNDER for repay, OVER for boost
955
+ ) {
956
+ const isBundle = true;
957
+ const subData = subDataService.aaveV4LeverageManagementOnPriceSubData.encode(
958
+ spoke,
959
+ owner,
960
+ collAsset,
961
+ collAssetId,
962
+ debtAsset,
963
+ debtAssetId,
964
+ ratioState,
965
+ targetRatio,
966
+ );
967
+ const triggerData = triggerService.aaveV4QuotePriceTrigger.encode(
968
+ spoke,
969
+ collAssetId,
970
+ debtAssetId,
971
+ price,
972
+ priceState,
973
+ );
974
+
975
+ return [strategyOrBundleId, isBundle, triggerData, subData];
976
+ },
977
+ closeOnPrice(
978
+ strategyOrBundleId: number,
979
+ owner: EthereumAddress,
980
+ spoke: EthereumAddress,
981
+ collAsset: EthereumAddress,
982
+ collAssetId: number,
983
+ debtAsset: EthereumAddress,
984
+ debtAssetId: number,
985
+ stopLossPrice: string = '0',
986
+ stopLossType: CloseToAssetType = CloseToAssetType.DEBT,
987
+ takeProfitPrice: string = '0',
988
+ takeProfitType: CloseToAssetType = CloseToAssetType.COLLATERAL,
989
+ ) {
990
+ const isBundle = true;
991
+ const closeType = getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType);
992
+
993
+ const subData = subDataService.aaveV4CloseSubData.encode(
994
+ spoke,
995
+ owner,
996
+ collAsset,
997
+ collAssetId,
998
+ debtAsset,
999
+ debtAssetId,
1000
+ closeType,
1001
+ );
1002
+ const triggerData = triggerService.aaveV4QuotePriceRangeTrigger.encode(
1003
+ spoke,
1004
+ collAssetId,
1005
+ debtAssetId,
1006
+ stopLossPrice,
1007
+ takeProfitPrice,
1008
+ );
1009
+
1010
+ return [strategyOrBundleId, isBundle, triggerData, subData];
1011
+ },
1012
+ collateralSwitch(
1013
+ strategyOrBundleId: number,
1014
+ owner: EthereumAddress,
1015
+ spoke: EthereumAddress,
1016
+ fromAsset: EthereumAddress,
1017
+ fromAssetId: number,
1018
+ toAsset: EthereumAddress,
1019
+ toAssetId: number,
1020
+ amountToSwitch: string,
1021
+ price: string,
1022
+ ratioState: RatioState,
1023
+ ) {
1024
+ const isBundle = false;
1025
+ const subData = subDataService.aaveV4CollateralSwitchSubData.encode(
1026
+ spoke,
1027
+ owner,
1028
+ fromAsset,
1029
+ fromAssetId,
1030
+ toAsset,
1031
+ toAssetId,
1032
+ amountToSwitch,
1033
+ );
1034
+ const triggerData = triggerService.aaveV4QuotePriceTrigger.encode(
1035
+ spoke,
1036
+ fromAssetId, // baseTokenId
1037
+ toAssetId, // quoteTokenId
1038
+ price,
1039
+ ratioState,
1040
+ );
1041
+
1042
+ return [strategyOrBundleId, isBundle, triggerData, subData];
1043
+ },
1044
+ };