@defisaver/automation-sdk 2.0.6 → 2.0.8

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 (48) hide show
  1. package/.env.dev +5 -0
  2. package/.tests.sh +3 -0
  3. package/README.md +3 -1
  4. package/esm/automation/private/LegacyProtocol.test.d.ts +1 -0
  5. package/esm/automation/private/LegacyProtocol.test.js +25 -0
  6. package/esm/automation/private/Protocol.test.d.ts +1 -0
  7. package/esm/automation/private/Protocol.test.js +25 -0
  8. package/esm/constants/index.js +5 -0
  9. package/esm/services/contractService.d.ts +3 -2
  10. package/esm/services/contractService.js +7 -1
  11. package/esm/services/ethereumService.test.d.ts +1 -0
  12. package/esm/services/ethereumService.test.js +241 -0
  13. package/esm/services/strategiesService.js +14 -0
  14. package/esm/services/strategiesService.test.d.ts +1 -0
  15. package/esm/services/strategiesService.test.js +108 -0
  16. package/esm/services/strategySubService.d.ts +5 -3
  17. package/esm/services/strategySubService.js +10 -6
  18. package/esm/services/strategySubService.test.d.ts +1 -0
  19. package/esm/services/strategySubService.test.js +692 -0
  20. package/esm/services/subDataService.d.ts +8 -1
  21. package/esm/services/subDataService.js +23 -14
  22. package/esm/services/subDataService.test.d.ts +1 -0
  23. package/esm/services/subDataService.test.js +993 -0
  24. package/esm/services/triggerService.d.ts +7 -0
  25. package/esm/services/triggerService.js +14 -1
  26. package/esm/services/triggerService.test.js +119 -17
  27. package/esm/types/enums.d.ts +4 -2
  28. package/esm/types/enums.js +2 -0
  29. package/esm/types/index.d.ts +8 -2
  30. package/package.json +3 -3
  31. package/src/automation/private/LegacyProtocol.test.ts +24 -0
  32. package/src/automation/private/Protocol.test.ts +24 -0
  33. package/src/constants/index.ts +5 -0
  34. package/src/services/contractService.ts +17 -4
  35. package/src/services/ethereumService.test.ts +256 -0
  36. package/src/services/ethereumService.ts +2 -1
  37. package/src/services/strategiesService.test.ts +103 -0
  38. package/src/services/strategiesService.ts +27 -3
  39. package/src/services/strategySubService.test.ts +835 -0
  40. package/src/services/strategySubService.ts +28 -15
  41. package/src/services/subDataService.test.ts +1063 -0
  42. package/src/services/subDataService.ts +29 -14
  43. package/src/services/triggerService.test.ts +131 -19
  44. package/src/services/triggerService.ts +14 -0
  45. package/src/services/utils.test.ts +1 -1
  46. package/src/types/enums.ts +2 -0
  47. package/src/types/index.ts +14 -3
  48. package/umd/index.js +148 -74
@@ -4,6 +4,7 @@ import { assetAmountInEth, getAssetInfo, getAssetInfoByAddress } from '@defisave
4
4
  import { otherAddresses } from '@defisaver/sdk';
5
5
 
6
6
  import type { EthereumAddress, SubData } from '../types';
7
+ import type { OrderType } from '../types/enums';
7
8
  import { ChainId, RatioState } from '../types/enums';
8
9
 
9
10
  import { ZERO_ADDRESS } from '../constants';
@@ -82,7 +83,7 @@ export const makerCloseSubData = {
82
83
  const vaultId = +AbiCoder.decodeParameter('uint256', subData[0])!;
83
84
  // if closing to collateral, asset addr will be 2nd param out of 4
84
85
  // if closing to DAI, will return 2nd param out of 3, which will be DAI addr
85
- const closeToAssetAddr = AbiCoder.decodeParameter('address', subData[1])!.toString().toLowerCase();
86
+ const closeToAssetAddr = AbiCoder.decodeParameter('address', subData[1])!.toString();
86
87
 
87
88
  return {
88
89
  vaultId, closeToAssetAddr,
@@ -91,14 +92,6 @@ export const makerCloseSubData = {
91
92
  };
92
93
 
93
94
  export const makerLeverageManagementSubData = {
94
- // encode: (vaultId:number, repayFrom, boostFrom, boostTo, repayTo, boostEnabled) => [
95
- // vaultId,
96
- // new Dec(repayFrom).mul(1e16).toString(),
97
- // new Dec(boostFrom).mul(1e16).toString(),
98
- // new Dec(boostTo).mul(1e16).toString(),
99
- // new Dec(repayTo).mul(1e16).toString(),
100
- // boostEnabled,
101
- // ],
102
95
  decode: (subData:SubData) => {
103
96
  const vaultId = +AbiCoder.decodeParameter('uint256', subData[0])!.toString();
104
97
  const weiRatio = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
@@ -106,6 +99,7 @@ export const makerLeverageManagementSubData = {
106
99
  return { vaultId, targetRatio };
107
100
  },
108
101
  };
102
+
109
103
  export const liquityLeverageManagementSubData = {
110
104
  decode: (subData:SubData) => {
111
105
  const weiRatio = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
@@ -113,6 +107,7 @@ export const liquityLeverageManagementSubData = {
113
107
  return { targetRatio };
114
108
  },
115
109
  };
110
+
116
111
  export const liquityCloseSubData = {
117
112
  encode(
118
113
  closeToAssetAddr: EthereumAddress,
@@ -125,16 +120,16 @@ export const liquityCloseSubData = {
125
120
 
126
121
  const collAddrEncoded = AbiCoder.encodeParameter('address', _collAddr);
127
122
  const debtAddrEncoded = AbiCoder.encodeParameter('address', _debtAddr);
128
- // if (compareAddresses(closeToAssetAddr, daiAddr)) { // TODO - Uhm, wth?
123
+ // if (compareAddresses(closeToAssetAddr, _debtAddr)) { // Closing to debt strategy was not implemented, but it should be in the future
129
124
  // // close to LUSD strategy
130
- // return [daiAddrEncoded, mcdManagerAddrEncoded];
125
+ // return [debtAddrEncoded, collAddrEncoded];
131
126
  // }
132
127
  // close to collateral strategy
133
128
  return [collAddrEncoded, debtAddrEncoded];
134
129
  },
135
130
  decode(subData: SubData): { closeToAssetAddr: EthereumAddress, debtAddr: string } {
136
- const closeToAssetAddr = AbiCoder.decodeParameter('address', subData[0])!.toString().toLowerCase();
137
- const debtAddr = AbiCoder.decodeParameter('address', subData[1])!.toString().toLowerCase();
131
+ const closeToAssetAddr = AbiCoder.decodeParameter('address', subData[0])!.toString();
132
+ const debtAddr = AbiCoder.decodeParameter('address', subData[1])!.toString();
138
133
 
139
134
  return { closeToAssetAddr, debtAddr };
140
135
  },
@@ -342,7 +337,7 @@ export const exchangeDcaSubData = {
342
337
  };
343
338
 
344
339
  export const exchangeLimitOrderSubData = {
345
- encode(fromToken: EthereumAddress, toToken: EthereumAddress, amount: string, targetPrice: string, goodUntil: string | number, orderType: number) : SubData {
340
+ encode(fromToken: EthereumAddress, toToken: EthereumAddress, amount: string, targetPrice: string, goodUntil: string | number, orderType: OrderType) : SubData {
346
341
  return [
347
342
  fromToken,
348
343
  toToken,
@@ -437,3 +432,23 @@ export const liquityDsrSupplySubData = {
437
432
  return { targetRatio };
438
433
  },
439
434
  };
435
+
436
+ export const liquityDebtInFrontRepaySubData = {
437
+ encode: (targetRatioIncrease: number) => {
438
+ const wethAddress = getAssetInfo('WETH').address;
439
+ const lusdAddress = getAssetInfo('LUSD').address;
440
+
441
+ const wethAddressEncoded = AbiCoder.encodeParameter('address', wethAddress);
442
+ const lusdAddressEncoded = AbiCoder.encodeParameter('address', lusdAddress);
443
+ const targetRatioIncreaseEncoded = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatioIncrease));
444
+ const withdrawIdEncoded = AbiCoder.encodeParameter('uint8', 1); // withdraw - 1
445
+ const paybackIdEncoded = AbiCoder.encodeParameter('uint8', 0); // payback - 0
446
+
447
+ return [wethAddressEncoded, lusdAddressEncoded, targetRatioIncreaseEncoded, withdrawIdEncoded, paybackIdEncoded];
448
+ },
449
+ decode: (subData: SubData) => {
450
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[2]) as any as string;
451
+ const targetRatioIncrease = weiToRatioPercentage(weiRatio);
452
+ return { targetRatioIncrease };
453
+ },
454
+ };
@@ -1,13 +1,14 @@
1
1
  import { expect } from 'chai';
2
- import { getAssetInfo } from '@defisaver/tokens';
2
+ import { getAssetInfo, MAXUINT } from '@defisaver/tokens';
3
3
  import * as web3Utils from 'web3-utils';
4
4
 
5
5
  import { ChainId, OrderType, RatioState } from '../types/enums';
6
- import { EthereumAddress, TriggerData } from '../types';
6
+ import type { EthereumAddress, TriggerData } from '../types';
7
7
 
8
8
  import {
9
9
  aaveV2RatioTrigger,
10
10
  aaveV3QuotePriceTrigger,
11
+ aaveV3QuotePriceWithMaximumGasPriceTrigger,
11
12
  aaveV3RatioTrigger,
12
13
  cBondsRebondTrigger,
13
14
  chainlinkPriceTrigger,
@@ -23,6 +24,7 @@ import {
23
24
  sparkQuotePriceTrigger,
24
25
  sparkRatioTrigger,
25
26
  trailingStopTrigger,
27
+ liquityDebtInFrontWithLimitTrigger,
26
28
  } from './triggerService';
27
29
 
28
30
  describe('Feature: triggerService.ts', () => {
@@ -60,7 +62,7 @@ describe('Feature: triggerService.ts', () => {
60
62
  ];
61
63
 
62
64
  examples.forEach(([expected, actual]) => {
63
- it(`Given ${actual} should return expected value: ${expected}`, () => {
65
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
64
66
  expect(chainlinkPriceTrigger.decode(actual)).to.eql(expected);
65
67
  });
66
68
  });
@@ -100,7 +102,7 @@ describe('Feature: triggerService.ts', () => {
100
102
  ];
101
103
 
102
104
  examples.forEach(([expected, actual]) => {
103
- it(`Given ${actual} should return expected value: ${expected}`, () => {
105
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
104
106
  expect(trailingStopTrigger.decode(actual)).to.eql(expected);
105
107
  });
106
108
  });
@@ -140,7 +142,7 @@ describe('Feature: triggerService.ts', () => {
140
142
  ];
141
143
 
142
144
  examples.forEach(([expected, actual]) => {
143
- it(`Given ${actual} should return expected value: ${expected}`, () => {
145
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
144
146
  expect(makerRatioTrigger.decode(actual)).to.eql(expected);
145
147
  });
146
148
  });
@@ -180,7 +182,7 @@ describe('Feature: triggerService.ts', () => {
180
182
  ];
181
183
 
182
184
  examples.forEach(([expected, actual]) => {
183
- it(`Given ${actual} should return expected value: ${expected}`, () => {
185
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
184
186
  expect(aaveV3RatioTrigger.decode(actual)).to.eql(expected);
185
187
  });
186
188
  });
@@ -220,7 +222,7 @@ describe('Feature: triggerService.ts', () => {
220
222
  ];
221
223
 
222
224
  examples.forEach(([expected, actual]) => {
223
- it(`Given ${actual} should return expected value: ${expected}`, () => {
225
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
224
226
  expect(morphoAaveV2RatioTrigger.decode(actual)).to.eql(expected);
225
227
  });
226
228
  });
@@ -270,13 +272,77 @@ describe('Feature: triggerService.ts', () => {
270
272
  ];
271
273
 
272
274
  examples.forEach(([expected, actual]) => {
273
- it(`Given ${actual} should return expected value: ${expected}`, () => {
275
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
274
276
  expect(aaveV3QuotePriceTrigger.decode(actual)).to.eql(expected);
275
277
  });
276
278
  });
277
279
  });
278
280
  });
279
281
 
282
+ describe('When testing triggerService.aaveV3QuotePriceWithMaximumGasPriceTrigger', () => {
283
+ describe('encode()', () => {
284
+ const examples: Array<[TriggerData, [baseTokenAddress: EthereumAddress, quoteTokenAddress: EthereumAddress, price: number, ratioState: RatioState, maximumGasPriceInGwei?: number]]> = [
285
+ [
286
+ [
287
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000009c400000000000000000000000000000000000000000000000000000000000000001',
288
+ '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
289
+ ],
290
+ [getAssetInfo('DAI', ChainId.Ethereum).address, getAssetInfo('WETH', ChainId.Ethereum).address, 0.0004, RatioState.UNDER]
291
+ ],
292
+ [
293
+ [
294
+ '0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000000',
295
+ '0x00000000000000000000000000000000000000000000000000000002cb417800',
296
+ ],
297
+ [getAssetInfo('WBTC', ChainId.Ethereum).address, getAssetInfo('USDT', ChainId.Ethereum).address, 0.00000023, RatioState.OVER, 12]
298
+ ],
299
+ ];
300
+
301
+ examples.forEach(([expected, actual]) => {
302
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
303
+ expect(aaveV3QuotePriceWithMaximumGasPriceTrigger.encode(...actual)).to.eql(expected);
304
+ });
305
+ });
306
+ });
307
+
308
+ describe('decode()', () => {
309
+ const examples: Array<[{ baseTokenAddress: EthereumAddress, quoteTokenAddress: EthereumAddress, price: string, ratioState: RatioState, maximumGasPrice: string }, TriggerData]> = [
310
+ [
311
+ {
312
+ baseTokenAddress: web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
313
+ quoteTokenAddress: web3Utils.toChecksumAddress(getAssetInfo('WETH', ChainId.Ethereum).address),
314
+ price: '0.0004',
315
+ ratioState: RatioState.UNDER,
316
+ maximumGasPrice: web3Utils.fromWei(MAXUINT, 'gwei')
317
+ },
318
+ [
319
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000009c400000000000000000000000000000000000000000000000000000000000000001',
320
+ '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
321
+ ],
322
+ ],
323
+ [
324
+ {
325
+ baseTokenAddress: web3Utils.toChecksumAddress(getAssetInfo('WBTC', ChainId.Ethereum).address),
326
+ quoteTokenAddress: web3Utils.toChecksumAddress(getAssetInfo('USDT', ChainId.Ethereum).address),
327
+ price: '0.00000023',
328
+ ratioState: RatioState.OVER,
329
+ maximumGasPrice: '12',
330
+ },
331
+ [
332
+ '0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000000',
333
+ '0x00000000000000000000000000000000000000000000000000000002cb417800',
334
+ ],
335
+ ]
336
+ ];
337
+
338
+ examples.forEach(([expected, actual]) => {
339
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
340
+ expect(aaveV3QuotePriceWithMaximumGasPriceTrigger.decode(actual)).to.eql(expected);
341
+ });
342
+ });
343
+ });
344
+ });
345
+
280
346
  describe('When testing triggerService.liquityRatioTrigger', () => {
281
347
  describe('encode()', () => {
282
348
  const examples: Array<[[string], [owner: EthereumAddress, ratioPercentage: number, ratioState: RatioState]]> = [
@@ -318,7 +384,7 @@ describe('Feature: triggerService.ts', () => {
318
384
  ];
319
385
 
320
386
  examples.forEach(([expected, actual]) => {
321
- it(`Given ${actual} should return expected value: ${expected}`, () => {
387
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
322
388
  expect(compoundV2RatioTrigger.decode(actual)).to.eql(expected);
323
389
  });
324
390
  });
@@ -364,7 +430,7 @@ describe('Feature: triggerService.ts', () => {
364
430
  ];
365
431
 
366
432
  examples.forEach(([expected, actual]) => {
367
- it(`Given ${actual} should return expected value: ${expected}`, () => {
433
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
368
434
  expect(liquityDebtInFrontTrigger.decode(actual)).to.eql(expected);
369
435
  });
370
436
  });
@@ -401,7 +467,7 @@ describe('Feature: triggerService.ts', () => {
401
467
  ];
402
468
 
403
469
  examples.forEach(([expected, actual]) => {
404
- it(`Given ${actual} should return expected value: ${expected}`, () => {
470
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
405
471
  expect(aaveV2RatioTrigger.decode(actual)).to.eql(expected);
406
472
  });
407
473
  });
@@ -441,7 +507,7 @@ describe('Feature: triggerService.ts', () => {
441
507
  ];
442
508
 
443
509
  examples.forEach(([expected, actual]) => {
444
- it(`Given ${actual} should return expected value: ${expected}`, () => {
510
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
445
511
  expect(cBondsRebondTrigger.decode(actual)).to.eql(expected);
446
512
  });
447
513
  });
@@ -491,7 +557,7 @@ describe('Feature: triggerService.ts', () => {
491
557
  ];
492
558
 
493
559
  examples.forEach(([expected, actual]) => {
494
- it(`Given ${actual} should return expected value: ${expected}`, () => {
560
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
495
561
  expect(compoundV3RatioTrigger.decode(actual)).to.eql(expected);
496
562
  });
497
563
  });
@@ -535,7 +601,7 @@ describe('Feature: triggerService.ts', () => {
535
601
  ];
536
602
 
537
603
  examples.forEach(([expected, actual]) => {
538
- it(`Given ${actual} should return expected value: ${expected}`, () => {
604
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
539
605
  expect(exchangeTimestampTrigger.decode(actual)).to.eql(expected);
540
606
  });
541
607
  });
@@ -587,7 +653,7 @@ describe('Feature: triggerService.ts', () => {
587
653
  ];
588
654
 
589
655
  examples.forEach(([expected, actual]) => {
590
- it(`Given ${actual} should return expected value: ${expected}`, () => {
656
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
591
657
  expect(exchangeOffchainPriceTrigger.decode(...actual)).to.eql(expected);
592
658
  });
593
659
  });
@@ -627,7 +693,7 @@ describe('Feature: triggerService.ts', () => {
627
693
  ];
628
694
 
629
695
  examples.forEach(([expected, actual]) => {
630
- it(`Given ${actual} should return expected value: ${expected}`, () => {
696
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
631
697
  expect(sparkRatioTrigger.decode(actual)).to.eql(expected);
632
698
  });
633
699
  });
@@ -677,7 +743,7 @@ describe('Feature: triggerService.ts', () => {
677
743
  ];
678
744
 
679
745
  examples.forEach(([expected, actual]) => {
680
- it(`Given ${actual} should return expected value: ${expected}`, () => {
746
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
681
747
  expect(sparkQuotePriceTrigger.decode(actual)).to.eql(expected);
682
748
  });
683
749
  });
@@ -727,7 +793,7 @@ describe('Feature: triggerService.ts', () => {
727
793
  ];
728
794
 
729
795
  examples.forEach(([expected, actual]) => {
730
- it(`Given ${actual} should return expected value: ${expected}`, () => {
796
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
731
797
  expect(curveUsdBorrowRateTrigger.decode(actual)).to.eql(expected);
732
798
  });
733
799
  });
@@ -775,11 +841,57 @@ describe('Feature: triggerService.ts', () => {
775
841
  ];
776
842
 
777
843
  examples.forEach(([expected, actual]) => {
778
- it(`Given ${actual} should return expected value: ${expected}`, () => {
844
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
779
845
  expect(curveUsdSoftLiquidationTrigger.decode(actual)).to.eql(expected);
780
846
  });
781
847
  });
782
848
  });
783
849
  });
784
850
 
851
+ describe('When testing triggerService.liquityDebtInFrontWithLimitTrigger', () => {
852
+ describe('encode()', () => {
853
+ const examples: Array<[[string], [owner: EthereumAddress, debtInFrontMin: string]]> = [
854
+ [
855
+ ['0x000000000000000000000000235d6a8db3c57c3f7b4eba749e1738db6093732a0000000000000000000000000000000000000000019d971e4fe8401e74000000'],
856
+ [web3Utils.toChecksumAddress('0x235d6A8DB3C57c3f7b4ebA749E1738Db6093732a'), '500000000']
857
+ ],
858
+ [
859
+ ['0x000000000000000000000000235d6a8db3c57c3f7b4eba749e1738db6093732a00000000000000000000000000000000000000000001a784379d99db42000000'],
860
+ [web3Utils.toChecksumAddress('0x235d6A8DB3C57c3f7b4ebA749E1738Db6093732a'), '2000000']
861
+ ],
862
+ ];
863
+
864
+ examples.forEach(([expected, actual]) => {
865
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
866
+ expect(liquityDebtInFrontWithLimitTrigger.encode(...actual)).to.eql(expected);
867
+ });
868
+ });
869
+ });
870
+
871
+ describe('decode()', () => {
872
+ const examples: Array<[{ owner: EthereumAddress, debtInFrontMin: string }, TriggerData]> = [
873
+ [
874
+ {
875
+ owner: web3Utils.toChecksumAddress('0x235d6A8DB3C57c3f7b4ebA749E1738Db6093732a'),
876
+ debtInFrontMin: '500000000',
877
+ },
878
+ ['0x000000000000000000000000235d6a8db3c57c3f7b4eba749e1738db6093732a0000000000000000000000000000000000000000019d971e4fe8401e74000000'],
879
+ ],
880
+ [
881
+ {
882
+ owner: web3Utils.toChecksumAddress('0x235d6A8DB3C57c3f7b4ebA749E1738Db6093732a'),
883
+ debtInFrontMin: '2000000',
884
+ },
885
+ ['0x000000000000000000000000235d6a8db3c57c3f7b4eba749e1738db6093732a00000000000000000000000000000000000000000001a784379d99db42000000'],
886
+ ],
887
+ ];
888
+
889
+ examples.forEach(([expected, actual]) => {
890
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
891
+ expect(liquityDebtInFrontWithLimitTrigger.decode(actual)).to.eql(expected);
892
+ });
893
+ });
894
+ });
895
+ });
896
+
785
897
  });
@@ -184,6 +184,20 @@ export const liquityDebtInFrontTrigger = {
184
184
  },
185
185
  };
186
186
 
187
+ export const liquityDebtInFrontWithLimitTrigger = {
188
+ encode(owner: EthereumAddress, debtInFrontMin: string) {
189
+ const debtInFrontMinWei = web3Utils.toWei(new Dec(debtInFrontMin).toString(), 'ether');
190
+ return [AbiCoder.encodeParameters(['address', 'uint256'], [owner, debtInFrontMinWei])];
191
+ },
192
+ decode(triggerData: TriggerData): { owner: EthereumAddress, debtInFrontMin: string } {
193
+ const decodedData = AbiCoder.decodeParameters(['address', 'uint256'], triggerData[0]);
194
+ return {
195
+ owner: decodedData[0] as EthereumAddress,
196
+ debtInFrontMin: new Dec(decodedData[1] as string).div(10 ** 18).toString(),
197
+ };
198
+ },
199
+ };
200
+
187
201
  export const aaveV2RatioTrigger = {
188
202
  encode(owner: EthereumAddress, market: EthereumAddress, ratioPercentage: number, ratioState: RatioState) {
189
203
  const ratioWei = ratioPercentageToWei(ratioPercentage);
@@ -3,7 +3,7 @@ import * as web3Utils from 'web3-utils';
3
3
  import AbiCoder from 'web3-eth-abi';
4
4
  import { getAssetInfo } from '@defisaver/tokens';
5
5
 
6
- import { EthereumAddress } from '../types';
6
+ import type { EthereumAddress } from '../types';
7
7
  import { ChainId, RatioState } from '../types/enums';
8
8
 
9
9
  import { sparkEncode } from './strategySubService';
@@ -62,6 +62,7 @@ export namespace Strategies {
62
62
  EXCHANGE_LIMIT_ORDER = 51,
63
63
  LIQUITY_DSR_PAYBACK = 69,
64
64
  LIQUITY_DSR_SUPPLY = 70,
65
+ LIQUITY_DEBT_IN_FRONT_REPAY = 75,
65
66
  }
66
67
 
67
68
  export enum OptimismIds {
@@ -94,6 +95,7 @@ export namespace Strategies {
94
95
  BondProtection = 'bond-protection',
95
96
  Dca = 'dca',
96
97
  LimitOrder = 'limit-order',
98
+ DebtInFrontRepay = 'debt-in-front-repay',
97
99
  }
98
100
  export enum IdOverrides {
99
101
  TakeProfit = 'take-profit',
@@ -158,9 +158,14 @@ export declare namespace Position {
158
158
  triggerPercentage: number,
159
159
  closeToAssetAddr: EthereumAddress,
160
160
  }
161
+
162
+ interface DebtInFrontRepay extends Base {
163
+ debtInFrontMin: string,
164
+ targetRepayRatioIncrease: number,
165
+ }
161
166
  }
162
167
 
163
- type SpecificAny = Specific.CloseOnPrice | Specific.TrailingStop | Specific.RatioProtection | Specific.CloseOnPriceAave | Specific.CloseOnPriceWithMaximumGasPriceAave;
168
+ type SpecificAny = Specific.CloseOnPrice | Specific.TrailingStop | Specific.RatioProtection | Specific.CloseOnPriceAave | Specific.CloseOnPriceWithMaximumGasPriceAave | Specific.DebtInFrontRepay;
164
169
 
165
170
  export interface Automated {
166
171
  chainId: ChainId,
@@ -202,11 +207,13 @@ type StrategyInfo<T extends number> = Record<T, Strategy<T>>;
202
207
  export type MainnetStrategiesInfo = StrategyInfo<Strategies.MainnetIds>;
203
208
  export type OptimismStrategiesInfo = StrategyInfo<Strategies.OptimismIds>;
204
209
  export type ArbitrumStrategiesInfo = StrategyInfo<Strategies.ArbitrumIds>;
210
+ export type StrategyInfoUnion = MainnetStrategiesInfo | OptimismStrategiesInfo | ArbitrumStrategiesInfo;
205
211
 
206
212
  type BundleInfo<T extends number> = Record<T, BundleOrStrategy<T>>;
207
213
  export type MainnetBundleInfo = BundleInfo<Bundles.MainnetIds>;
208
214
  export type OptimismBundleInfo = BundleInfo<Bundles.OptimismIds>;
209
215
  export type ArbitrumBundleInfo = BundleInfo<Bundles.ArbitrumIds>;
216
+ export type BundleInfoUnion = MainnetBundleInfo | OptimismBundleInfo | ArbitrumBundleInfo;
210
217
 
211
218
  export interface StrategiesInfo {
212
219
  [ChainId.Ethereum]: MainnetStrategiesInfo,
@@ -221,8 +228,12 @@ export interface BundlesInfo {
221
228
  }
222
229
 
223
230
  export type StrategyOrBundleIds =
224
- Strategies.MainnetIds & Strategies.OptimismIds & Strategies.ArbitrumIds
225
- & Bundles.MainnetIds & Bundles.OptimismIds & Bundles.ArbitrumIds;
231
+ typeof Strategies.MainnetIds[keyof typeof Strategies.MainnetIds]
232
+ | typeof Strategies.OptimismIds[keyof typeof Strategies.OptimismIds]
233
+ | typeof Strategies.ArbitrumIds[keyof typeof Strategies.ArbitrumIds]
234
+ | typeof Bundles.MainnetIds[keyof typeof Bundles.MainnetIds]
235
+ | typeof Bundles.OptimismIds[keyof typeof Bundles.OptimismIds]
236
+ | typeof Bundles.ArbitrumIds[keyof typeof Bundles.ArbitrumIds];
226
237
 
227
238
  export interface ParseData {
228
239
  chainId: ChainId,