@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
@@ -33,6 +33,9 @@ import {
33
33
  aaveV3QuotePriceRangeTrigger,
34
34
  morphoBluePriceRangeTrigger,
35
35
  sparkQuotePriceTrigger,
36
+ aaveV4RatioTrigger,
37
+ aaveV4QuotePriceTrigger,
38
+ aaveV4QuotePriceRangeTrigger,
36
39
  } from './triggerService';
37
40
 
38
41
  describe('Feature: triggerService.ts', () => {
@@ -1284,7 +1287,101 @@ describe('Feature: triggerService.ts', () => {
1284
1287
  });
1285
1288
  });
1286
1289
  });
1290
+ describe('When testing triggerService.aaveV4RatioTrigger', () => {
1291
+ describe('encode()', () => {
1292
+ const examples: Array<[[string], [owner: EthereumAddress, spoke: EthereumAddress, ratioPercentage: number, ratioState: RatioState]]> = [
1293
+ [
1294
+ ['0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000010a741a4627800000000000000000000000000000000000000000000000000000000000000000001'],
1295
+ [web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'), web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), 120, RatioState.UNDER]
1296
+ ],
1297
+ ];
1298
+
1299
+ examples.forEach(([expected, actual]) => {
1300
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
1301
+ expect(aaveV4RatioTrigger.encode(...actual)).to.eql(expected);
1302
+ });
1303
+ });
1304
+ });
1305
+
1306
+ describe('decode()', () => {
1307
+ const examples: Array<[{ owner: EthereumAddress, spoke: EthereumAddress, ratio: number, ratioState: RatioState }, TriggerData]> = [
1308
+ [
1309
+ { owner: web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'), spoke: web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), ratio: 120, ratioState: RatioState.UNDER },
1310
+ ['0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e00000000000000000000000000000000000000000000000010a741a4627800000000000000000000000000000000000000000000000000000000000000000001'],
1311
+ ],
1312
+ ];
1313
+
1314
+ examples.forEach(([expected, actual]) => {
1315
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
1316
+ expect(aaveV4RatioTrigger.decode(actual)).to.eql(expected);
1317
+ });
1318
+ });
1319
+ });
1320
+ });
1287
1321
 
1322
+ describe('When testing triggerService.aaveV4QuotePriceTrigger', () => {
1323
+ describe('encode()', () => {
1324
+ const examples: Array<[[string], [spoke: EthereumAddress, baseTokenId: number, quoteTokenId: number, price: string, ratioState: RatioState]]> = [
1325
+ [
1326
+ ['0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000000000000000000000000000000000000000000000'],
1327
+ [web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), 10, 20, '1500', RatioState.OVER]
1328
+ ],
1329
+ ];
1330
+
1331
+ examples.forEach(([expected, actual]) => {
1332
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
1333
+ expect(aaveV4QuotePriceTrigger.encode(...actual)).to.eql(expected);
1334
+ });
1335
+ });
1336
+ });
1337
+
1338
+ describe('decode()', () => {
1339
+ const examples: Array<[{ spoke: EthereumAddress, baseTokenId: number, quoteTokenId: number, price: string, ratioState: RatioState }, TriggerData]> = [
1340
+ [
1341
+ { spoke: web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), baseTokenId: 10, quoteTokenId: 20, price: '1500', ratioState: RatioState.OVER },
1342
+ ['0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000000000000000000000000000000000000000000000'],
1343
+ ],
1344
+ ];
1345
+
1346
+ examples.forEach(([expected, actual]) => {
1347
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
1348
+ expect(aaveV4QuotePriceTrigger.decode(actual)).to.eql(expected);
1349
+ });
1350
+ });
1351
+ });
1352
+ });
1353
+
1354
+ describe('When testing triggerService.aaveV4QuotePriceRangeTrigger', () => {
1355
+ describe('encode()', () => {
1356
+ const examples: Array<[[string], [spoke: EthereumAddress, baseTokenId: number, quoteTokenId: number, lowerPrice: string, upperPrice: string]]> = [
1357
+ [
1358
+ ['0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000004be4e7267b6ae00000000000000000000000000000000000000000000000000056bc75e2d631000000'],
1359
+ [web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), 10, 20, '1400', '1600']
1360
+ ],
1361
+ ];
1362
+
1363
+ examples.forEach(([expected, actual]) => {
1364
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
1365
+ expect(aaveV4QuotePriceRangeTrigger.encode(...actual)).to.eql(expected);
1366
+ });
1367
+ });
1368
+ });
1369
+
1370
+ describe('decode()', () => {
1371
+ const examples: Array<[{ spoke: EthereumAddress, baseTokenId: number, quoteTokenId: number, lowerPrice: string, upperPrice: string }, TriggerData]> = [
1372
+ [
1373
+ { spoke: web3Utils.toChecksumAddress('0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e'), baseTokenId: 10, quoteTokenId: 20, lowerPrice: '1400', upperPrice: '1600' },
1374
+ ['0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000004be4e7267b6ae00000000000000000000000000000000000000000000000000056bc75e2d631000000'],
1375
+ ],
1376
+ ];
1377
+
1378
+ examples.forEach(([expected, actual]) => {
1379
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
1380
+ expect(aaveV4QuotePriceRangeTrigger.decode(actual)).to.eql(expected);
1381
+ });
1382
+ });
1383
+ });
1384
+ });
1288
1385
  describe('When testing triggerService.sparkQuotePriceTrigger', () => {
1289
1386
  describe('encode()', () => {
1290
1387
  const examples: Array<[[string], [baseTokenAddr: EthereumAddress, quoteTokenAddr: EthereumAddress, price: number, ratioState: RatioState]]> = [
@@ -743,4 +743,77 @@ export const sparkQuotePriceTrigger = {
743
743
  ratioState: Number(decodedData[3]),
744
744
  };
745
745
  },
746
- };
746
+ };
747
+
748
+ export const aaveV4RatioTrigger = {
749
+ encode(owner: EthereumAddress, spoke: EthereumAddress, ratioPercentage: number, ratioState: RatioState) {
750
+ const ratioWei = ratioPercentageToWei(ratioPercentage);
751
+ return [AbiCoder.encodeParameters(['address', 'address', 'uint256', 'uint8'], [owner, spoke, ratioWei, ratioState])];
752
+ },
753
+ decode(triggerData: TriggerData) {
754
+ const decodedData = AbiCoder.decodeParameters(['address', 'address', 'uint256', 'uint8'], triggerData[0]);
755
+ return {
756
+ owner: decodedData[0] as EthereumAddress,
757
+ spoke: decodedData[1] as EthereumAddress,
758
+ ratio: weiToRatioPercentage(decodedData[2] as string),
759
+ ratioState: Number(decodedData[3]),
760
+ };
761
+ },
762
+ };
763
+
764
+ export const aaveV4QuotePriceTrigger = {
765
+ encode(
766
+ spoke: EthereumAddress,
767
+ baseTokenId: number,
768
+ quoteTokenId: number,
769
+ price: string,
770
+ ratioState: RatioState,
771
+ ) {
772
+ // Price is intentionally scaled to 1e18 for higher precision.
773
+ const _price = new Dec(price).mul(1e18).floor().toString();
774
+ return [AbiCoder.encodeParameters(['address', 'uint256', 'uint256', 'uint256', 'uint8'], [spoke, baseTokenId, quoteTokenId, _price, ratioState])];
775
+ },
776
+ decode(
777
+ triggerData: TriggerData,
778
+ ) {
779
+ const decodedData = AbiCoder.decodeParameters(['address', 'uint256', 'uint256', 'uint256', 'uint8'], triggerData[0]);
780
+ return {
781
+ spoke: decodedData[0] as EthereumAddress,
782
+ baseTokenId: Number(decodedData[1]),
783
+ quoteTokenId: Number(decodedData[2]),
784
+ price: new Dec(decodedData[3] as string).div(1e18).toString(),
785
+ ratioState: Number(decodedData[4]),
786
+ };
787
+ },
788
+ };
789
+
790
+ export const aaveV4QuotePriceRangeTrigger = {
791
+ encode(
792
+ spoke: EthereumAddress,
793
+ baseTokenId: number,
794
+ quoteTokenId: number,
795
+ lowerPrice: string,
796
+ upperPrice: string,
797
+ ) {
798
+ // Price is intentionally scaled to 1e18 for higher precision.
799
+ const lowerPriceFormatted = new Dec(lowerPrice).mul(1e18).floor().toString();
800
+ const upperPriceFormatted = new Dec(upperPrice).mul(1e18).floor().toString();
801
+ return [
802
+ AbiCoder.encodeParameters(
803
+ ['address', 'uint256', 'uint256', 'uint256', 'uint256'],
804
+ [spoke, baseTokenId, quoteTokenId, lowerPriceFormatted, upperPriceFormatted]),
805
+ ];
806
+ },
807
+ decode(
808
+ triggerData: TriggerData,
809
+ ) {
810
+ const decodedData = AbiCoder.decodeParameters(['address', 'uint256', 'uint256', 'uint256', 'uint256'], triggerData[0]);
811
+ return {
812
+ spoke: decodedData[0] as EthereumAddress,
813
+ baseTokenId: Number(decodedData[1]),
814
+ quoteTokenId: Number(decodedData[2]),
815
+ lowerPrice: new Dec(decodedData[3] as string).div(1e18).toString(),
816
+ upperPrice: new Dec(decodedData[4] as string).div(1e18).toString(),
817
+ };
818
+ },
819
+ };
@@ -106,13 +106,24 @@ export function getPositionId(...args: (number | string)[]) {
106
106
  }
107
107
 
108
108
  export function getCloseStrategyType(
109
- stopLossPrice: number,
109
+ stopLossPrice: number | string,
110
110
  stopLossType: CloseToAssetType,
111
- takeProfitPrice: number,
111
+ takeProfitPrice: number | string,
112
112
  takeProfitType: CloseToAssetType,
113
113
  ): CloseStrategyType {
114
- const isStopLoss = stopLossPrice > 0;
115
- const isTakeProfit = takeProfitPrice > 0;
114
+ const stopLossPriceDec = new Dec(stopLossPrice);
115
+ const takeProfitPriceDec = new Dec(takeProfitPrice);
116
+
117
+ if (!stopLossPriceDec.isFinite() || stopLossPriceDec.isNegative()) {
118
+ throw new Error('CloseOnPrice: stopLossPrice must be a finite non-negative number');
119
+ }
120
+
121
+ if (!takeProfitPriceDec.isFinite() || takeProfitPriceDec.isNegative()) {
122
+ throw new Error('CloseOnPrice: takeProfitPrice must be a finite non-negative number');
123
+ }
124
+
125
+ const isStopLoss = stopLossPriceDec.gt(0);
126
+ const isTakeProfit = takeProfitPriceDec.gt(0);
116
127
 
117
128
  if (!isStopLoss && !isTakeProfit) {
118
129
  throw new Error('CloseOnPrice: At least one price must be defined');
@@ -64,6 +64,7 @@ export namespace ProtocolIdentifiers {
64
64
  CompoundV3 = 'Compound__V3',
65
65
  AaveV2 = 'Aave__V2',
66
66
  AaveV3 = 'Aave__V3',
67
+ AaveV4 = 'Aave__V4',
67
68
  MorphoAaveV2 = 'Morpho-Aave__V2',
68
69
  Exchange = 'Exchange',
69
70
  Spark = 'Spark',
@@ -97,6 +98,8 @@ export namespace Strategies {
97
98
  CURVEUSD_PAYBACK = 92,
98
99
  LIQUITY_V2_PAYBACK = 113,
99
100
  AAVE_V3_COLLATERAL_SWITCH = 135,
101
+ AAVE_V4_COLLATERAL_SWITCH = 154,
102
+ AAVE_V4_COLLATERAL_SWITCH_EOA = 155,
100
103
  }
101
104
 
102
105
  export enum OptimismIds {
@@ -148,6 +151,7 @@ export namespace Strategies {
148
151
  EoaBoostOnPrice = 'eoa-boost-on-price',
149
152
  EoaRepayOnPrice = 'eoa-repay-on-price',
150
153
  CollateralSwitch = 'collateral-switch',
154
+ EoaCollateralSwitch = 'eoa-collateral-switch',
151
155
  }
152
156
  export enum IdOverrides {
153
157
  TakeProfit = 'take-profit',
@@ -225,6 +229,16 @@ export namespace Bundles {
225
229
  MORPHO_BLUE_CLOSE = 58,
226
230
  SPARK_REPAY_ON_PRICE = 59,
227
231
  SPARK_BOOST_ON_PRICE = 60,
232
+ AAVE_V4_REPAY = 61,
233
+ AAVE_V4_BOOST = 62,
234
+ AAVE_V4_REPAY_ON_PRICE = 63,
235
+ AAVE_V4_BOOST_ON_PRICE = 64,
236
+ AAVE_V4_CLOSE = 65,
237
+ AAVE_V4_EOA_REPAY = 66,
238
+ AAVE_V4_EOA_BOOST = 67,
239
+ AAVE_V4_EOA_REPAY_ON_PRICE = 68,
240
+ AAVE_V4_EOA_BOOST_ON_PRICE = 69,
241
+ AAVE_V4_EOA_CLOSE = 70,
228
242
  }
229
243
 
230
244
  export enum OptimismIds {
@@ -248,6 +248,30 @@ export declare namespace Position {
248
248
  ratioState: RatioState,
249
249
  ratio: number,
250
250
  }
251
+
252
+ interface CloseBase extends Base {
253
+ stopLossPrice: string,
254
+ takeProfitPrice: string,
255
+ stopLossType: CloseToAssetType | undefined,
256
+ takeProfitType: CloseToAssetType | undefined,
257
+ }
258
+
259
+ interface AaveV4LeverageManagementOnPrice extends Base {
260
+ collAsset: EthereumAddress,
261
+ collAssetId: number,
262
+ debtAsset: EthereumAddress,
263
+ debtAssetId: number,
264
+ price: string,
265
+ ratioState: number,
266
+ ratio: number,
267
+ }
268
+
269
+ interface AaveV4CloseOnPrice extends CloseBase {
270
+ collAsset: EthereumAddress,
271
+ collAssetId: number,
272
+ debtAsset: EthereumAddress,
273
+ debtAssetId: number,
274
+ }
251
275
  }
252
276
 
253
277
  type SpecificAny =
@@ -266,6 +290,8 @@ export declare namespace Position {
266
290
  | Specific.CompoundV3LeverageManagementOnPrice
267
291
  | Specific.CompoundV3CloseOnPrice
268
292
  | Specific.AaveV3CloseOnPriceGeneric
293
+ | Specific.AaveV4LeverageManagementOnPrice
294
+ | Specific.AaveV4CloseOnPrice
269
295
  | Specific.SparkOnPrice;
270
296
 
271
297
  export interface Automated {