@defisaver/automation-sdk 2.0.5 → 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 (50) 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/automation/private/StrategiesAutomation.js +1 -1
  9. package/esm/constants/index.js +15 -0
  10. package/esm/services/contractService.d.ts +3 -2
  11. package/esm/services/contractService.js +7 -1
  12. package/esm/services/ethereumService.test.d.ts +1 -0
  13. package/esm/services/ethereumService.test.js +241 -0
  14. package/esm/services/strategiesService.js +40 -0
  15. package/esm/services/strategiesService.test.d.ts +1 -0
  16. package/esm/services/strategiesService.test.js +108 -0
  17. package/esm/services/strategySubService.d.ts +17 -3
  18. package/esm/services/strategySubService.js +17 -6
  19. package/esm/services/strategySubService.test.d.ts +1 -0
  20. package/esm/services/strategySubService.test.js +692 -0
  21. package/esm/services/subDataService.d.ts +8 -1
  22. package/esm/services/subDataService.js +23 -14
  23. package/esm/services/subDataService.test.d.ts +1 -0
  24. package/esm/services/subDataService.test.js +993 -0
  25. package/esm/services/triggerService.d.ts +17 -0
  26. package/esm/services/triggerService.js +42 -1
  27. package/esm/services/triggerService.test.js +119 -17
  28. package/esm/types/enums.d.ts +10 -2
  29. package/esm/types/enums.js +8 -0
  30. package/esm/types/index.d.ts +19 -2
  31. package/package.json +3 -3
  32. package/src/automation/private/LegacyProtocol.test.ts +24 -0
  33. package/src/automation/private/Protocol.test.ts +24 -0
  34. package/src/automation/private/StrategiesAutomation.ts +1 -1
  35. package/src/constants/index.ts +15 -0
  36. package/src/services/contractService.ts +17 -4
  37. package/src/services/ethereumService.test.ts +256 -0
  38. package/src/services/ethereumService.ts +2 -1
  39. package/src/services/strategiesService.test.ts +103 -0
  40. package/src/services/strategiesService.ts +66 -3
  41. package/src/services/strategySubService.test.ts +835 -0
  42. package/src/services/strategySubService.ts +50 -15
  43. package/src/services/subDataService.test.ts +1063 -0
  44. package/src/services/subDataService.ts +29 -14
  45. package/src/services/triggerService.test.ts +133 -20
  46. package/src/services/triggerService.ts +55 -0
  47. package/src/services/utils.test.ts +1 -1
  48. package/src/types/enums.ts +8 -0
  49. package/src/types/index.ts +27 -3
  50. package/umd/index.js +282 -115
@@ -0,0 +1,835 @@
1
+ import { expect } from 'chai';
2
+ import Dec from 'decimal.js';
3
+ import { otherAddresses } from '@defisaver/sdk';
4
+ import { getAssetInfo } from '@defisaver/tokens';
5
+ import * as web3Utils from 'web3-utils';
6
+
7
+ import { Bundles, ChainId, OrderType, RatioState, Strategies } from '../types/enums';
8
+ import type { EthereumAddress, StrategyOrBundleIds, SubData, TriggerData } from '../types';
9
+
10
+ import {
11
+ aaveV2Encode,
12
+ chickenBondsEncode,
13
+ liquityEncode,
14
+ makerEncode,
15
+ aaveV3Encode,
16
+ compoundV2Encode,
17
+ compoundV3Encode,
18
+ morphoAaveV2Encode,
19
+ exchangeEncode,
20
+ sparkEncode,
21
+ } from './strategySubService';
22
+
23
+ describe('Feature: strategySubService.ts', () => {
24
+ describe('When testing strategySubService.makerEncode', () => {
25
+ // @ts-ignore // TODO - this requires change in @defisaver/tokens
26
+ const mcdCdpManagerAddr = otherAddresses(ChainId.Ethereum).McdCdpManager;
27
+
28
+ describe('repayFromSavings()', () => {
29
+ const examples: Array<[
30
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
31
+ [
32
+ bundleId: StrategyOrBundleIds, vaultId: number, triggerRepayRatio: number, targetRepayRatio: number,
33
+ isBundle?: boolean, chainId?: ChainId, daiAddr?: EthereumAddress, mcdCdpManagerAddr?: EthereumAddress,
34
+ ]
35
+ ]> = [
36
+ [
37
+ [
38
+ Bundles.MainnetIds.MAKER_REPAY_FROM_SMART_SAVINGS_RARI,
39
+ true,
40
+ ['0x00000000000000000000000000000000000000000000000000000000000000de000000000000000000000000000000000000000000000000136dcc951d8c00000000000000000000000000000000000000000000000000000000000000000001'],
41
+ [
42
+ '0x00000000000000000000000000000000000000000000000000000000000000de', '0x00000000000000000000000000000000000000000000000018fae27693b40000',
43
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f', '0x0000000000000000000000005ef30b9986345249bc32d8928b7ee64de9435e39',
44
+ ],
45
+ ],
46
+ [
47
+ Bundles.MainnetIds.MAKER_REPAY_FROM_SMART_SAVINGS_RARI,
48
+ 222,
49
+ 140,
50
+ 180,
51
+ true,
52
+ ChainId.Ethereum,
53
+ getAssetInfo('DAI').address,
54
+ mcdCdpManagerAddr,
55
+ ]
56
+ ]
57
+ ];
58
+
59
+ examples.forEach(([expected, actual]) => {
60
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
61
+ expect(makerEncode.repayFromSavings(...actual)).to.eql(expected);
62
+ });
63
+ });
64
+ });
65
+
66
+ describe('closeOnPrice()', () => {
67
+ const examples: Array<[
68
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
69
+ [
70
+ vaultId: number, ratioState: RatioState, price: string, closeToAssetAddr: EthereumAddress,
71
+ chainlinkCollAddress: EthereumAddress, chainId?: ChainId, daiAddr?: EthereumAddress, mcdCdpManagerAddr?: EthereumAddress,
72
+ ]
73
+ ]> = [
74
+ [
75
+ [
76
+ Strategies.MainnetIds.MAKER_CLOSE_ON_PRICE_TO_DAI,
77
+ false,
78
+ ['0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c5990000000000000000000000000000000000000000000000000000000002cc9e4c0000000000000000000000000000000000000000000000000000000000000000'],
79
+ [
80
+ '0x0000000000000000000000000000000000000000000000000000000000000078', '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f',
81
+ '0x0000000000000000000000005ef30b9986345249bc32d8928b7ee64de9435e39',
82
+ ],
83
+ ],
84
+ [
85
+ 120,
86
+ RatioState.OVER,
87
+ '0.469643',
88
+ getAssetInfo('DAI').address,
89
+ getAssetInfo('WBTC').address,
90
+ ChainId.Ethereum,
91
+ ]
92
+ ]
93
+ ];
94
+
95
+ examples.forEach(([expected, actual]) => {
96
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
97
+ expect(makerEncode.closeOnPrice(...actual)).to.eql(expected);
98
+ });
99
+ });
100
+ });
101
+
102
+ describe('trailingStop()', () => {
103
+ const examples: Array<[
104
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
105
+ [
106
+ vaultId: number, triggerPercentage: number, closeToAssetAddr: EthereumAddress, chainlinkCollAddress: EthereumAddress,
107
+ roundId: number, chainId: ChainId, daiAddr?: EthereumAddress, mcdCdpManagerAddr?: EthereumAddress,
108
+ ]
109
+ ]> = [
110
+ [
111
+ [
112
+ Strategies.MainnetIds.MAKER_TRAILING_STOP_LOSS_TO_COLL,
113
+ false,
114
+ ['0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000000000000000000000000000000000055ae82600000000000000000000000000000000000000000000000000000000000000007b'],
115
+ [
116
+ '0x000000000000000000000000000000000000000000000000000000000000096e', '0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599',
117
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f', '0x0000000000000000000000005ef30b9986345249bc32d8928b7ee64de9435e39',
118
+ ],
119
+ ],
120
+ [
121
+ 2414,
122
+ 230,
123
+ getAssetInfo('WBTC').address,
124
+ getAssetInfo('WBTC').address,
125
+ 123,
126
+ ChainId.Ethereum,
127
+ ]
128
+ ]
129
+ ];
130
+
131
+ examples.forEach(([expected, actual]) => {
132
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
133
+ expect(makerEncode.trailingStop(...actual)).to.eql(expected);
134
+ });
135
+ });
136
+ });
137
+
138
+ describe('leverageManagement()', () => {
139
+ const examples: Array<[
140
+ [
141
+ vaultId: number, triggerRepayRatio: string, triggerBoostRatio: string, targetBoostRatio: string,
142
+ targetRepayRatio: string, boostEnabled: boolean,
143
+ ],
144
+ [
145
+ vaultId: number, triggerRepayRatio: string, triggerBoostRatio: string, targetBoostRatio: string,
146
+ targetRepayRatio: string, boostEnabled: boolean,
147
+ ]
148
+ ]> = [
149
+ [
150
+ [
151
+ 5791,
152
+ new Dec('210').mul(1e16).toString(),
153
+ new Dec('290').mul(1e16).toString(),
154
+ new Dec('240').mul(1e16).toString(),
155
+ new Dec('240').mul(1e16).toString(),
156
+ true,
157
+ ],
158
+ [
159
+ 5791, '210', '290', '240', '240', true,
160
+ ]
161
+ ]
162
+ ];
163
+
164
+ examples.forEach(([expected, actual]) => {
165
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
166
+ expect(makerEncode.leverageManagement(...actual)).to.eql(expected);
167
+ });
168
+ });
169
+ });
170
+ });
171
+
172
+ describe('When testing strategySubService.liquityEncode', () => {
173
+ describe('closeOnPrice()', () => {
174
+ const examples: Array<[
175
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
176
+ [
177
+ priceOverOrUnder: RatioState, price: string, closeToAssetAddr: EthereumAddress, chainlinkCollAddress: EthereumAddress,
178
+ chainId?: ChainId, collAddr?: EthereumAddress, debtAddr?: EthereumAddress,
179
+ ]
180
+ ]> = [
181
+ [
182
+ [
183
+ Strategies.MainnetIds.LIQUITY_CLOSE_ON_PRICE_TO_COLL,
184
+ false,
185
+ ['0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000001c027053000000000000000000000000000000000000000000000000000000000000000000'],
186
+ [
187
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', '0x0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0',
188
+ ],
189
+ ],
190
+ [
191
+ RatioState.OVER,
192
+ '1203',
193
+ getAssetInfo('WETH').address,
194
+ getAssetInfo('WETH').address,
195
+ ]
196
+ ]
197
+ ];
198
+
199
+ examples.forEach(([expected, actual]) => {
200
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
201
+ expect(liquityEncode.closeOnPrice(...actual)).to.eql(expected);
202
+ });
203
+ });
204
+ });
205
+
206
+ describe('trailingStop()', () => {
207
+ const examples: Array<[
208
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
209
+ [
210
+ triggerPercentage: number, closeToAssetAddr: EthereumAddress, chainlinkCollAddress: EthereumAddress, roundId: number,
211
+ chainId?: ChainId, collAddr?: EthereumAddress, debtAddr?: EthereumAddress,
212
+ ]
213
+ ]> = [
214
+ [
215
+ [
216
+ Strategies.MainnetIds.LIQUITY_TRAILING_STOP_LOSS_TO_COLL,
217
+ false,
218
+ ['0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000055ae826000000000000000000000000000000000000000000000000000000000000000c97'],
219
+ [
220
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', '0x0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0',
221
+ ],
222
+ ],
223
+ [
224
+ 230,
225
+ getAssetInfo('WETH').address,
226
+ getAssetInfo('WETH').address,
227
+ 3223,
228
+ ]
229
+ ]
230
+ ];
231
+
232
+ examples.forEach(([expected, actual]) => {
233
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
234
+ expect(liquityEncode.trailingStop(...actual)).to.eql(expected);
235
+ });
236
+ });
237
+ });
238
+
239
+ describe('leverageManagement()', () => {
240
+ const examples: Array<[
241
+ [
242
+ triggerRepayRatio: string, triggerBoostRatio: string, targetBoostRatio: string,
243
+ targetRepayRatio: string, boostEnabled: boolean,
244
+ ],
245
+ [
246
+ triggerRepayRatio: string, triggerBoostRatio: string, targetBoostRatio: string,
247
+ targetRepayRatio: string, boostEnabled: boolean,
248
+ ]
249
+ ]> = [
250
+ [
251
+ [
252
+ new Dec('210').mul(1e16).toString(),
253
+ new Dec('290').mul(1e16).toString(),
254
+ new Dec('240').mul(1e16).toString(),
255
+ new Dec('240').mul(1e16).toString(),
256
+ false,
257
+ ],
258
+ [
259
+ '210', '290', '240', '240', false,
260
+ ]
261
+ ]
262
+ ];
263
+
264
+ examples.forEach(([expected, actual]) => {
265
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
266
+ expect(liquityEncode.leverageManagement(...actual)).to.eql(expected);
267
+ });
268
+ });
269
+ });
270
+
271
+ describe('paybackFromChickenBondStrategySub()', () => {
272
+ const examples: Array<[
273
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
274
+ [
275
+ proxyAddress: EthereumAddress, ratio: number, sourceId: string, sourceType: number, ratioState: RatioState,
276
+ ]
277
+ ]> = [
278
+ [
279
+ [
280
+ Bundles.MainnetIds.LIQUITY_PAYBACK_USING_CHICKEN_BOND,
281
+ true,
282
+ ['0x0000000000000000000000002439d211133afab8f2b819b1066c7e434ad94e9e0000000000000000000000000000000000000000000000002dcbf4840eca00000000000000000000000000000000000000000000000000000000000000000000'],
283
+ [
284
+ '0x000000000000000000000000000000000000000000000000000000000000007b', '0x0000000000000000000000000000000000000000000000000000000000000000',
285
+ '0x0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0', '0x000000000000000000000000b9d7dddca9a4ac480991865efef82e01273f79c3',
286
+ ],
287
+ ],
288
+ [
289
+ web3Utils.toChecksumAddress('0x2439d211133AFaB8F2B819B1066c7E434Ad94E9e'),
290
+ 330,
291
+ '123',
292
+ 0,
293
+ RatioState.OVER
294
+ ]
295
+ ]
296
+ ];
297
+
298
+ examples.forEach(([expected, actual]) => {
299
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
300
+ expect(liquityEncode.paybackFromChickenBondStrategySub(...actual)).to.eql(expected);
301
+ });
302
+ });
303
+ });
304
+
305
+ describe('dsrPayback()', () => {
306
+ const examples: Array<[
307
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
308
+ [proxyAddress: EthereumAddress, triggerRatio: number, targetRatio: number],
309
+ ]> = [
310
+ [
311
+ [
312
+ Strategies.MainnetIds.LIQUITY_DSR_PAYBACK,
313
+ false,
314
+ ['0x0000000000000000000000002439d211133afab8f2b819b1066c7e434ad94e9e000000000000000000000000000000000000000000000000250dbeda8e4b00000000000000000000000000000000000000000000000000000000000000000001'],
315
+ [
316
+ '0x0000000000000000000000000000000000000000000000000000000000000001', '0x00000000000000000000000000000000000000000000000029a2241af62c0000',
317
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f', '0x0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0',
318
+ ],
319
+ ],
320
+ [web3Utils.toChecksumAddress('0x2439d211133AFaB8F2B819B1066c7E434Ad94E9e'), 267, 300]
321
+ ]
322
+ ];
323
+
324
+ examples.forEach(([expected, actual]) => {
325
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
326
+ expect(liquityEncode.dsrPayback(...actual)).to.eql(expected);
327
+ });
328
+ });
329
+ });
330
+
331
+ describe('debtInFrontRepay()', () => {
332
+ const examples: Array<[
333
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
334
+ [proxyAddress: EthereumAddress, debtInFrontMin: string, targetRatioIncrease: number],
335
+ ]> = [
336
+ [
337
+ [
338
+ Strategies.MainnetIds.LIQUITY_DEBT_IN_FRONT_REPAY,
339
+ false,
340
+ ['0x000000000000000000000000235d6a8db3c57c3f7b4eba749e1738db6093732a0000000000000000000000000000000000000000019d971e4fe8401e74000000'],
341
+ [
342
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', '0x0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0',
343
+ '0x000000000000000000000000000000000000000000000000063eb89da4ed0000', '0x0000000000000000000000000000000000000000000000000000000000000001',
344
+ '0x0000000000000000000000000000000000000000000000000000000000000000'
345
+ ],
346
+ ],
347
+ [web3Utils.toChecksumAddress('0x235d6A8DB3C57c3f7b4ebA749E1738Db6093732a'), '500000000', 45]
348
+ ]
349
+ ];
350
+
351
+ examples.forEach(([expected, actual]) => {
352
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
353
+ expect(liquityEncode.debtInFrontRepay(...actual)).to.eql(expected);
354
+ });
355
+ });
356
+ });
357
+ });
358
+
359
+ describe('When testing strategySubService.chickenBondsEncode', () => {
360
+ describe('rebond()', () => {
361
+ const examples: Array<[
362
+ SubData,
363
+ [bondId: number],
364
+ ]> = [
365
+ [
366
+ ["0x00000000000000000000000000000000000000000000000000000000000005e3"],
367
+ [1507]
368
+ ]
369
+ ];
370
+
371
+ examples.forEach(([expected, actual]) => {
372
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
373
+ expect(chickenBondsEncode.rebond(...actual)).to.eql(expected);
374
+ });
375
+ });
376
+ });
377
+ });
378
+
379
+ describe('When testing strategySubService.aaveV2Encode', () => {
380
+ describe('leverageManagement()', () => {
381
+ const examples: Array<[
382
+ [string, string, string, string, boolean],
383
+ [triggerRepayRatio: number, triggerBoostRatio: number, targetBoostRatio: number, targetRepayRatio: number, boostEnabled: boolean],
384
+ ]> = [
385
+ [
386
+ [new Dec(160).mul(1e16).toString(), new Dec(220).mul(1e16).toString(), new Dec(180).mul(1e16).toString(), new Dec(190).mul(1e16).toString(), true],
387
+ [160, 220, 180, 190, true]
388
+ ],
389
+ [
390
+ [new Dec(160).mul(1e16).toString(), new Dec(200).mul(1e16).toString(), new Dec(180).mul(1e16).toString(), new Dec(190).mul(1e16).toString(), false],
391
+ [160, 200, 180, 190, false]
392
+ ],
393
+ ];
394
+
395
+ examples.forEach(([expected, actual]) => {
396
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
397
+ expect(aaveV2Encode.leverageManagement(...actual)).to.eql(expected);
398
+ });
399
+ });
400
+ });
401
+ });
402
+
403
+ describe('When testing strategySubService.aaveV3Encode', () => {
404
+ describe('leverageManagement()', () => {
405
+ const examples: Array<[
406
+ string,
407
+ [triggerRepayRatio: number, triggerBoostRatio: number, targetBoostRatio: number, targetRepayRatio: number, boostEnabled: boolean],
408
+ ]> = [
409
+ [
410
+ '0x000000000000000016345785d8a0000000000000000000001e87f85809dc0000000000000000000018fae27693b4000000000000000000001a5e27eef13e000001',
411
+ [160, 220, 180, 190, true]
412
+ ],
413
+ [
414
+ '0x000000000000000016345785d8a0000000000000000000001bc16d674ec80000000000000000000018fae27693b4000000000000000000001a5e27eef13e000000',
415
+ [160, 200, 180, 190, false]
416
+ ],
417
+ ];
418
+
419
+ examples.forEach(([expected, actual]) => {
420
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
421
+ expect(aaveV3Encode.leverageManagement(...actual)).to.eql(expected);
422
+ });
423
+ });
424
+ });
425
+
426
+ describe('closeToAsset()', () => {
427
+ const examples: Array<[
428
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
429
+ [
430
+ strategyOrBundleId: number,
431
+ isBundle: boolean,
432
+ triggerData: {
433
+ baseTokenAddress: EthereumAddress, quoteTokenAddress: EthereumAddress, price: number, ratioState: RatioState
434
+ },
435
+ subData: {
436
+ collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number,
437
+ },
438
+ ]
439
+ ]> = [
440
+ [
441
+ [
442
+ Bundles.MainnetIds.AAVE_V3_CLOSE_TO_COLLATERAL,
443
+ true,
444
+ ['0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000026e1f9c6000000000000000000000000000000000000000000000000000000000000000000'],
445
+ [
446
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', '0x0000000000000000000000000000000000000000000000000000000000000015',
447
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f', '0x0000000000000000000000000000000000000000000000000000000000000020',
448
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
449
+ ],
450
+ ],
451
+ [
452
+ Bundles.MainnetIds.AAVE_V3_CLOSE_TO_COLLATERAL,
453
+ true,
454
+ {
455
+ baseTokenAddress: getAssetInfo('WETH').address, quoteTokenAddress: getAssetInfo('DAI').address, price: 1670, ratioState: RatioState.OVER
456
+ },
457
+ {
458
+ collAsset: getAssetInfo('WETH').address, collAssetId: 21, debtAsset: getAssetInfo('DAI').address, debtAssetId: 32,
459
+ },
460
+ ]
461
+ ],
462
+ [
463
+ [
464
+ Bundles.MainnetIds.AAVE_V3_CLOSE_TO_DEBT,
465
+ true,
466
+ ['0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000084d000000000000000000000000000000000000000000000000000000000000000001'],
467
+ [
468
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f', '0x0000000000000000000000000000000000000000000000000000000000000015',
469
+ '0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca', '0x0000000000000000000000000000000000000000000000000000000000000020',
470
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
471
+ ],
472
+ ],
473
+ [
474
+ Bundles.MainnetIds.AAVE_V3_CLOSE_TO_DEBT,
475
+ true,
476
+ {
477
+ baseTokenAddress: getAssetInfo('LINK').address, quoteTokenAddress: getAssetInfo('DAI').address, price: 0.00544, ratioState: RatioState.UNDER
478
+ },
479
+ {
480
+ collAsset: getAssetInfo('DAI').address, collAssetId: 21, debtAsset: getAssetInfo('LINK').address, debtAssetId: 32,
481
+ },
482
+ ]
483
+ ]
484
+ ];
485
+
486
+ examples.forEach(([expected, actual]) => {
487
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
488
+ expect(aaveV3Encode.closeToAsset(...actual)).to.eql(expected);
489
+ });
490
+ });
491
+ });
492
+
493
+ describe('closeToAssetWithMaximumGasPrice()', () => {
494
+ const examples: Array<[
495
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
496
+ [
497
+ strategyOrBundleId: number,
498
+ isBundle: boolean,
499
+ triggerData: {
500
+ baseTokenAddress: EthereumAddress, quoteTokenAddress: EthereumAddress, price: number, ratioState: RatioState, maximumGasPrice: number
501
+ },
502
+ subData: {
503
+ collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number,
504
+ },
505
+ ]
506
+ ]> = [
507
+ [
508
+ [
509
+ Bundles.MainnetIds.AAVE_V3_CLOSE_TO_COLLATERAL,
510
+ true,
511
+ [
512
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000026e1f9c6000000000000000000000000000000000000000000000000000000000000000000',
513
+ '0x00000000000000000000000000000000000000000000000000000002cb417800',
514
+ ],
515
+ [
516
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', '0x0000000000000000000000000000000000000000000000000000000000000015',
517
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f', '0x0000000000000000000000000000000000000000000000000000000000000020',
518
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
519
+ ],
520
+ ],
521
+ [
522
+ Bundles.MainnetIds.AAVE_V3_CLOSE_TO_COLLATERAL,
523
+ true,
524
+ {
525
+ baseTokenAddress: getAssetInfo('WETH').address, quoteTokenAddress: getAssetInfo('DAI').address, price: 1670, ratioState: RatioState.OVER, maximumGasPrice: 12,
526
+ },
527
+ {
528
+ collAsset: getAssetInfo('WETH').address, collAssetId: 21, debtAsset: getAssetInfo('DAI').address, debtAssetId: 32,
529
+ },
530
+ ]
531
+ ],
532
+ [
533
+ [
534
+ Bundles.MainnetIds.AAVE_V3_CLOSE_TO_DEBT,
535
+ true,
536
+ [
537
+ '0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000084d000000000000000000000000000000000000000000000000000000000000000001',
538
+ '0x0000000000000000000000000000000000000000000000000000004a817c8000',
539
+ ],
540
+ [
541
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f', '0x0000000000000000000000000000000000000000000000000000000000000015',
542
+ '0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca', '0x0000000000000000000000000000000000000000000000000000000000000020',
543
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
544
+ ],
545
+ ],
546
+ [
547
+ Bundles.MainnetIds.AAVE_V3_CLOSE_TO_DEBT,
548
+ true,
549
+ {
550
+ baseTokenAddress: getAssetInfo('LINK').address, quoteTokenAddress: getAssetInfo('DAI').address, price: 0.00544, ratioState: RatioState.UNDER, maximumGasPrice: 320,
551
+ },
552
+ {
553
+ collAsset: getAssetInfo('DAI').address, collAssetId: 21, debtAsset: getAssetInfo('LINK').address, debtAssetId: 32,
554
+ },
555
+ ]
556
+ ]
557
+ ];
558
+
559
+ examples.forEach(([expected, actual]) => {
560
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
561
+ expect(aaveV3Encode.closeToAssetWithMaximumGasPrice(...actual)).to.eql(expected);
562
+ });
563
+ });
564
+ });
565
+ });
566
+
567
+ describe('When testing strategySubService.compoundV2Encode', () => {
568
+ describe('leverageManagement()', () => {
569
+ const examples: Array<[
570
+ [string, string, string, string, boolean],
571
+ [triggerRepayRatio: number, triggerBoostRatio: number, targetBoostRatio: number, targetRepayRatio: number, boostEnabled: boolean],
572
+ ]> = [
573
+ [
574
+ [new Dec(160).mul(1e16).toString(), new Dec(220).mul(1e16).toString(), new Dec(180).mul(1e16).toString(), new Dec(190).mul(1e16).toString(), true],
575
+ [160, 220, 180, 190, true]
576
+ ],
577
+ [
578
+ [new Dec(160).mul(1e16).toString(), new Dec(200).mul(1e16).toString(), new Dec(180).mul(1e16).toString(), new Dec(190).mul(1e16).toString(), false],
579
+ [160, 200, 180, 190, false]
580
+ ],
581
+ ];
582
+
583
+ examples.forEach(([expected, actual]) => {
584
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
585
+ expect(compoundV2Encode.leverageManagement(...actual)).to.eql(expected);
586
+ });
587
+ });
588
+ });
589
+ });
590
+
591
+ describe('When testing strategySubService.compoundV3Encode', () => {
592
+ describe('leverageManagement()', () => {
593
+ const examples: Array<[[EthereumAddress, EthereumAddress, string, string, string, string, boolean, boolean], [market: EthereumAddress, baseToken: EthereumAddress, triggerRepayRatio: number, triggerBoostRatio: number, targetBoostRatio: number, targetRepayRatio: number, boostEnabled: boolean, isEOA: boolean]]> = [
594
+ [
595
+ [
596
+ web3Utils.toChecksumAddress('0x1C0F620155e85491f8D35440eb17538Ca5c55212'),
597
+ web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
598
+ new Dec(160).mul(1e16).toString(),
599
+ new Dec(220).mul(1e16).toString(),
600
+ new Dec(180).mul(1e16).toString(),
601
+ new Dec(190).mul(1e16).toString(),
602
+ true, false,
603
+ ],
604
+ [
605
+ web3Utils.toChecksumAddress('0x1C0F620155e85491f8D35440eb17538Ca5c55212'),
606
+ web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
607
+ 160, 220, 180, 190,
608
+ true, false,
609
+ ]
610
+ ],
611
+ [
612
+ [
613
+ web3Utils.toChecksumAddress('0xaC0F620155e85491f8D35440eb17538Ca5c55212'),
614
+ web3Utils.toChecksumAddress(getAssetInfo('WETH', ChainId.Ethereum).address),
615
+ new Dec(160).mul(1e16).toString(),
616
+ new Dec(210).mul(1e16).toString(),
617
+ new Dec(180).mul(1e16).toString(),
618
+ new Dec(190).mul(1e16).toString(),
619
+ false, true,
620
+ ],
621
+ [
622
+ web3Utils.toChecksumAddress('0xaC0F620155e85491f8D35440eb17538Ca5c55212'),
623
+ web3Utils.toChecksumAddress(getAssetInfo('WETH', ChainId.Ethereum).address),
624
+ 160, 210, 180, 190,
625
+ false, true,
626
+ ]
627
+ ],
628
+ ];
629
+ examples.forEach(([expected, actual]) => {
630
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
631
+ expect(compoundV3Encode.leverageManagement(...actual)).to.eql(expected);
632
+ });
633
+ });
634
+ });
635
+ });
636
+
637
+ describe('When testing strategySubService.morphoAaveV2Encode', () => {
638
+ describe('leverageManagement()', () => {
639
+ const examples: Array<[[string, string, string, string, boolean], [triggerRepayRatio: number, triggerBoostRatio: number, targetBoostRatio: number, targetRepayRatio: number, boostEnabled: boolean]]> = [
640
+ [
641
+ [new Dec(160).mul(1e16).toString(), new Dec(220).mul(1e16).toString(), new Dec(180).mul(1e16).toString(), new Dec(190).mul(1e16).toString(), true],
642
+ [160, 220, 180, 190, true]
643
+ ],
644
+ [
645
+ [new Dec(160).mul(1e16).toString(), new Dec(200).mul(1e16).toString(), new Dec(180).mul(1e16).toString(), new Dec(190).mul(1e16).toString(), false],
646
+ [160, 200, 180, 190, false]
647
+ ],
648
+ ];
649
+
650
+ examples.forEach(([expected, actual]) => {
651
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
652
+ expect(morphoAaveV2Encode.leverageManagement(...actual)).to.eql(expected);
653
+ });
654
+ });
655
+ });
656
+ });
657
+
658
+ describe('When testing strategySubService.exchangeEncode', () => {
659
+ describe('dca()', () => {
660
+ const examples: Array<[
661
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
662
+ [fromToken: EthereumAddress, toToken: EthereumAddress, amount: string, timestamp: number, interval: number, network: ChainId],
663
+ ]> = [
664
+ [
665
+ [
666
+ Strategies.ArbitrumIds.EXCHANGE_DCA,
667
+ false,
668
+ ['0x0000000000000000000000000000000000000000000000000000018b23bd88cd000000000000000000000000000000000000000000000000000000000012d068'],
669
+ [
670
+ '0x000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1', '0x000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831',
671
+ '0x0000000000000000000000000000000000000000000000000000000000038270', '0x000000000000000000000000000000000000000000000000000000000012d068'
672
+ ],
673
+ ],
674
+ [getAssetInfo('DAI', ChainId.Arbitrum).address, getAssetInfo('USDC', ChainId.Arbitrum).address, '230000', 1697111705805, 1233000, ChainId.Arbitrum]
675
+ ],
676
+ [
677
+ [
678
+ Strategies.MainnetIds.EXCHANGE_DCA,
679
+ false,
680
+ ['0x0000000000000000000000000000000000000000000000000000018b23bd88cd0000000000000000000000000000000000000000000000000000000000067458'],
681
+ [
682
+ '0x0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599', '0x000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
683
+ '0x0000000000000000000000000000000000000000000000000000000000000015', '0x0000000000000000000000000000000000000000000000000000000000067458',
684
+ ],
685
+ ],
686
+ [getAssetInfo('WBTC').address, getAssetInfo('ETH').address, '21', 1697111705805, 423000, ChainId.Ethereum]
687
+ ],
688
+ ];
689
+
690
+ examples.forEach(([expected, actual]) => {
691
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
692
+ expect(exchangeEncode.dca(...actual)).to.eql(expected);
693
+ });
694
+ });
695
+ });
696
+
697
+ describe('limitOrder()', () => {
698
+ const examples: Array<[[EthereumAddress, EthereumAddress, string, string, string, string], [fromToken: EthereumAddress, toToken: EthereumAddress, amount: string, targetPrice: string, goodUntil: string | number, orderType: OrderType]]> = [
699
+ [
700
+ [
701
+ web3Utils.toChecksumAddress(getAssetInfo('WETH', ChainId.Ethereum).address),
702
+ web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
703
+ '2131',
704
+ '0.53123',
705
+ '1696590921159',
706
+ `${OrderType.STOP_LOSS}`
707
+ ],
708
+ [
709
+ web3Utils.toChecksumAddress(getAssetInfo('WETH', ChainId.Ethereum).address),
710
+ web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
711
+ '2131',
712
+ '0.53123',
713
+ 1696590921159,
714
+ OrderType.STOP_LOSS
715
+ ]
716
+ ],
717
+ [
718
+ [
719
+ web3Utils.toChecksumAddress(getAssetInfo('LINK', ChainId.Arbitrum).address),
720
+ web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Arbitrum).address),
721
+ '2131',
722
+ '0.43123',
723
+ '1646590921159',
724
+ `${OrderType.TAKE_PROFIT}`
725
+ ],
726
+ [
727
+ web3Utils.toChecksumAddress(getAssetInfo('LINK', ChainId.Arbitrum).address),
728
+ web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Arbitrum).address),
729
+ '2131',
730
+ '0.43123',
731
+ 1646590921159,
732
+ OrderType.TAKE_PROFIT
733
+ ]
734
+ ],
735
+ ];
736
+
737
+ examples.forEach(([expected, actual]) => {
738
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
739
+ expect(exchangeEncode.limitOrder(...actual)).to.eql(expected);
740
+ });
741
+ });
742
+ });
743
+ });
744
+
745
+ describe('When testing strategySubService.sparkEncode', () => {
746
+ describe('leverageManagement()', () => {
747
+ const examples: Array<[
748
+ string,
749
+ [triggerRepayRatio: number, triggerBoostRatio: number, targetBoostRatio: number, targetRepayRatio: number, boostEnabled: boolean],
750
+ ]> = [
751
+ [
752
+ '0x000000000000000016345785d8a0000000000000000000001e87f85809dc0000000000000000000018fae27693b4000000000000000000001a5e27eef13e000001',
753
+ [160, 220, 180, 190, true]
754
+ ],
755
+ [
756
+ '0x000000000000000016345785d8a0000000000000000000001bc16d674ec80000000000000000000018fae27693b4000000000000000000001a5e27eef13e000000',
757
+ [160, 200, 180, 190, false]
758
+ ],
759
+ ];
760
+
761
+ examples.forEach(([expected, actual]) => {
762
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
763
+ expect(sparkEncode.leverageManagement(...actual)).to.eql(expected);
764
+ });
765
+ });
766
+ });
767
+
768
+ describe('closeToAsset()', () => {
769
+ const examples: Array<[
770
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
771
+ [
772
+ strategyOrBundleId: number,
773
+ isBundle: boolean,
774
+ triggerData: {
775
+ baseTokenAddress: EthereumAddress, quoteTokenAddress: EthereumAddress, price: number, ratioState: RatioState
776
+ },
777
+ subData: {
778
+ collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number,
779
+ },
780
+ ]
781
+ ]> = [
782
+ [
783
+ [
784
+ Bundles.MainnetIds.SPARK_CLOSE_TO_COLLATERAL,
785
+ true,
786
+ ['0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000026e1f9c6000000000000000000000000000000000000000000000000000000000000000000'],
787
+ [
788
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', '0x0000000000000000000000000000000000000000000000000000000000000015',
789
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f', '0x0000000000000000000000000000000000000000000000000000000000000020',
790
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
791
+ ],
792
+ ],
793
+ [
794
+ Bundles.MainnetIds.SPARK_CLOSE_TO_COLLATERAL,
795
+ true,
796
+ {
797
+ baseTokenAddress: getAssetInfo('WETH').address, quoteTokenAddress: getAssetInfo('DAI').address, price: 1670, ratioState: RatioState.OVER
798
+ },
799
+ {
800
+ collAsset: getAssetInfo('WETH').address, collAssetId: 21, debtAsset: getAssetInfo('DAI').address, debtAssetId: 32,
801
+ },
802
+ ]
803
+ ],
804
+ [
805
+ [
806
+ Bundles.MainnetIds.SPARK_CLOSE_TO_DEBT,
807
+ true,
808
+ ['0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000084d000000000000000000000000000000000000000000000000000000000000000001'],
809
+ [
810
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f', '0x0000000000000000000000000000000000000000000000000000000000000015',
811
+ '0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca', '0x0000000000000000000000000000000000000000000000000000000000000020',
812
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
813
+ ],
814
+ ],
815
+ [
816
+ Bundles.MainnetIds.SPARK_CLOSE_TO_DEBT,
817
+ true,
818
+ {
819
+ baseTokenAddress: getAssetInfo('LINK').address, quoteTokenAddress: getAssetInfo('DAI').address, price: 0.00544, ratioState: RatioState.UNDER
820
+ },
821
+ {
822
+ collAsset: getAssetInfo('DAI').address, collAssetId: 21, debtAsset: getAssetInfo('LINK').address, debtAssetId: 32,
823
+ },
824
+ ]
825
+ ]
826
+ ];
827
+
828
+ examples.forEach(([expected, actual]) => {
829
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
830
+ expect(sparkEncode.closeToAsset(...actual)).to.eql(expected);
831
+ });
832
+ });
833
+ });
834
+ });
835
+ });