@defisaver/automation-sdk 3.3.19 → 3.3.21-coll-switch-generic-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.
@@ -510,6 +510,145 @@ describe('Feature: subDataService.ts', () => {
510
510
  });
511
511
  });
512
512
  });
513
+ describe('When testing subDataService.aaveV3DebtSwitchSubData', () => {
514
+ describe('encode()', () => {
515
+ const examples = [
516
+ // USDC -> DAI
517
+ [
518
+ [
519
+ '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
520
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
521
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f',
522
+ '0x0000000000000000000000000000000000000000000000000000000000000003',
523
+ '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
524
+ '0x0000000000000000000000000000000000000000000000008ac7230489e80000',
525
+ '0x000000000000000000000000dd6ecd6c9b9f7e29e0f14bb9d5f0d0a3c6cb6c6a',
526
+ ],
527
+ [
528
+ web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
529
+ 1,
530
+ web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
531
+ 3,
532
+ web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39'),
533
+ '10000000000000000000',
534
+ web3Utils.toChecksumAddress('0xDd6ecD6c9b9F7e29E0f14bb9D5F0D0A3C6cB6c6A'),
535
+ ]
536
+ ],
537
+ // DAI -> USDC (MaxUint256)
538
+ [
539
+ [
540
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f',
541
+ '0x0000000000000000000000000000000000000000000000000000000000000003',
542
+ '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
543
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
544
+ '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
545
+ '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
546
+ '0x000000000000000000000000dd6ecd6c9b9f7e29e0f14bb9d5f0d0a3c6cb6c6a',
547
+ ],
548
+ [
549
+ web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
550
+ 3,
551
+ web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
552
+ 1,
553
+ web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39'),
554
+ MAXUINT,
555
+ web3Utils.toChecksumAddress('0xDd6ecD6c9b9F7e29E0f14bb9D5F0D0A3C6cB6c6A'),
556
+ ]
557
+ ],
558
+ ];
559
+ examples.forEach(([expected, actual]) => {
560
+ it(`Given ${JSON.stringify(actual)} should return expected value: ${JSON.stringify(expected)}`, () => {
561
+ expect(subDataService.aaveV3DebtSwitchSubData.encode(...actual)).to.eql(expected);
562
+ });
563
+ });
564
+ });
565
+ describe('decode()', () => {
566
+ const examples = [
567
+ // USDC -> DAI
568
+ [
569
+ {
570
+ fromAsset: web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
571
+ fromAssetId: 1,
572
+ toAsset: web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
573
+ toAssetId: 3,
574
+ marketAddr: web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39'),
575
+ amountToSwitch: '10000000000000000000',
576
+ user: web3Utils.toChecksumAddress('0xDd6ecD6c9b9F7e29E0f14bb9D5F0D0A3C6cB6c6A'),
577
+ },
578
+ [
579
+ '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
580
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
581
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f',
582
+ '0x0000000000000000000000000000000000000000000000000000000000000003',
583
+ '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
584
+ '0x0000000000000000000000000000000000000000000000008ac7230489e80000',
585
+ '0x000000000000000000000000dd6ecd6c9b9f7e29e0f14bb9d5f0d0a3c6cb6c6a',
586
+ ],
587
+ ],
588
+ // DAI -> USDC (MaxUint256)
589
+ [
590
+ {
591
+ fromAsset: web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
592
+ fromAssetId: 3,
593
+ toAsset: web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
594
+ toAssetId: 1,
595
+ marketAddr: web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39'),
596
+ amountToSwitch: MAXUINT,
597
+ user: web3Utils.toChecksumAddress('0xDd6ecD6c9b9F7e29E0f14bb9D5F0D0A3C6cB6c6A'),
598
+ },
599
+ [
600
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f',
601
+ '0x0000000000000000000000000000000000000000000000000000000000000003',
602
+ '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
603
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
604
+ '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
605
+ '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
606
+ '0x000000000000000000000000dd6ecd6c9b9f7e29e0f14bb9d5f0d0a3c6cb6c6a',
607
+ ],
608
+ ],
609
+ ];
610
+ examples.forEach(([expected, actual]) => {
611
+ it(`Given ${JSON.stringify(actual)} should return expected value: ${JSON.stringify(expected)}`, () => {
612
+ expect(subDataService.aaveV3DebtSwitchSubData.decode(actual)).to.eql(expected);
613
+ });
614
+ });
615
+ });
616
+ });
617
+ describe('When testing subDataService.aaveV3GenericFLCollateralSwitchSubData', () => {
618
+ const fromAsset = web3Utils.toChecksumAddress(getAssetInfo('WETH', ChainId.Ethereum).address);
619
+ const toAsset = web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address);
620
+ const marketAddr = web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39');
621
+ const user = web3Utils.toChecksumAddress('0x1234567890abcdef1234567890abcdef12345678');
622
+ const examples = [
623
+ ['10000000000000000000', '0x0000000000000000000000000000000000000000000000008ac7230489e80000'],
624
+ [MAXUINT, '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'],
625
+ ];
626
+ examples.forEach(([amountToSwitch, encodedAmount]) => {
627
+ const subData = [
628
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
629
+ '0x0000000000000000000000000000000000000000000000000000000000000100',
630
+ '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
631
+ '0x000000000000000000000000000000000000000000000000000000000000ffff',
632
+ '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
633
+ encodedAmount,
634
+ '0x0000000000000000000000001234567890abcdef1234567890abcdef12345678',
635
+ ];
636
+ it(`encode() preserves uint16 asset IDs and user when switching ${amountToSwitch}`, () => {
637
+ expect(subDataService.aaveV3GenericFLCollateralSwitchSubData.encode(fromAsset, 256, toAsset, 65535, marketAddr, amountToSwitch, user)).to.eql(subData);
638
+ });
639
+ it(`decode() preserves uint16 asset IDs and user when switching ${amountToSwitch}`, () => {
640
+ expect(subDataService.aaveV3GenericFLCollateralSwitchSubData.decode(subData)).to.eql({
641
+ fromAsset,
642
+ fromAssetId: 256,
643
+ toAsset,
644
+ toAssetId: 65535,
645
+ marketAddr,
646
+ amountToSwitch,
647
+ user,
648
+ });
649
+ });
650
+ });
651
+ });
513
652
  describe('When testing subDataService.sparkCollateralSwitchSubData', () => {
514
653
  describe('encode()', () => {
515
654
  const examples = [
@@ -91,22 +91,30 @@ export declare namespace Strategies {
91
91
  AAVE_V4_COLLATERAL_SWITCH = 154,
92
92
  AAVE_V4_COLLATERAL_SWITCH_EOA = 155,
93
93
  SPARK_COLLATERAL_SWITCH = 156,
94
- SPARK_GENERIC_FL_COLLATERAL_SWITCH = 167
94
+ SPARK_GENERIC_FL_COLLATERAL_SWITCH = 167,
95
+ AAVE_V3_DEBT_SWITCH = 168,
96
+ AAVE_V3_DEBT_SWITCH_EOA = 169
95
97
  }
96
98
  enum OptimismIds {
97
99
  EXCHANGE_DCA = 8,
98
100
  EXCHANGE_LIMIT_ORDER = 9,
99
- AAVE_V3_COLLATERAL_SWITCH = 24
101
+ AAVE_V3_COLLATERAL_SWITCH = 24,
102
+ AAVE_V3_DEBT_SWITCH = 25,
103
+ AAVE_V3_DEBT_SWITCH_EOA = 26
100
104
  }
101
105
  enum BaseIds {
102
106
  EXCHANGE_DCA = 8,
103
107
  EXCHANGE_LIMIT_ORDER = 9,
104
- AAVE_V3_COLLATERAL_SWITCH = 56
108
+ AAVE_V3_COLLATERAL_SWITCH = 56,
109
+ AAVE_V3_DEBT_SWITCH = 61,
110
+ AAVE_V3_DEBT_SWITCH_EOA = 62
105
111
  }
106
112
  enum ArbitrumIds {
107
113
  EXCHANGE_DCA = 8,
108
114
  EXCHANGE_LIMIT_ORDER = 9,
109
- AAVE_V3_COLLATERAL_SWITCH = 50
115
+ AAVE_V3_COLLATERAL_SWITCH = 50,
116
+ AAVE_V3_DEBT_SWITCH = 55,
117
+ AAVE_V3_DEBT_SWITCH_EOA = 56
110
118
  }
111
119
  enum Identifiers {
112
120
  SavingsLiqProtection = "smart-savings-liquidation-protection",
@@ -140,6 +148,8 @@ export declare namespace Strategies {
140
148
  EoaRepayOnPrice = "eoa-repay-on-price",
141
149
  CollateralSwitch = "collateral-switch",
142
150
  EoaCollateralSwitch = "eoa-collateral-switch",
151
+ DebtSwitch = "debt-switch",
152
+ EoaDebtSwitch = "eoa-debt-switch",
143
153
  LiquidationProtection = "liquidation-protection",
144
154
  EoaLiquidationProtection = "liquidation-protection-eoa"
145
155
  }
@@ -105,24 +105,32 @@ export var Strategies;
105
105
  MainnetIds[MainnetIds["AAVE_V4_COLLATERAL_SWITCH_EOA"] = 155] = "AAVE_V4_COLLATERAL_SWITCH_EOA";
106
106
  MainnetIds[MainnetIds["SPARK_COLLATERAL_SWITCH"] = 156] = "SPARK_COLLATERAL_SWITCH";
107
107
  MainnetIds[MainnetIds["SPARK_GENERIC_FL_COLLATERAL_SWITCH"] = 167] = "SPARK_GENERIC_FL_COLLATERAL_SWITCH";
108
+ MainnetIds[MainnetIds["AAVE_V3_DEBT_SWITCH"] = 168] = "AAVE_V3_DEBT_SWITCH";
109
+ MainnetIds[MainnetIds["AAVE_V3_DEBT_SWITCH_EOA"] = 169] = "AAVE_V3_DEBT_SWITCH_EOA";
108
110
  })(MainnetIds = Strategies.MainnetIds || (Strategies.MainnetIds = {}));
109
111
  let OptimismIds;
110
112
  (function (OptimismIds) {
111
113
  OptimismIds[OptimismIds["EXCHANGE_DCA"] = 8] = "EXCHANGE_DCA";
112
114
  OptimismIds[OptimismIds["EXCHANGE_LIMIT_ORDER"] = 9] = "EXCHANGE_LIMIT_ORDER";
113
115
  OptimismIds[OptimismIds["AAVE_V3_COLLATERAL_SWITCH"] = 24] = "AAVE_V3_COLLATERAL_SWITCH";
116
+ OptimismIds[OptimismIds["AAVE_V3_DEBT_SWITCH"] = 25] = "AAVE_V3_DEBT_SWITCH";
117
+ OptimismIds[OptimismIds["AAVE_V3_DEBT_SWITCH_EOA"] = 26] = "AAVE_V3_DEBT_SWITCH_EOA";
114
118
  })(OptimismIds = Strategies.OptimismIds || (Strategies.OptimismIds = {}));
115
119
  let BaseIds;
116
120
  (function (BaseIds) {
117
121
  BaseIds[BaseIds["EXCHANGE_DCA"] = 8] = "EXCHANGE_DCA";
118
122
  BaseIds[BaseIds["EXCHANGE_LIMIT_ORDER"] = 9] = "EXCHANGE_LIMIT_ORDER";
119
123
  BaseIds[BaseIds["AAVE_V3_COLLATERAL_SWITCH"] = 56] = "AAVE_V3_COLLATERAL_SWITCH";
124
+ BaseIds[BaseIds["AAVE_V3_DEBT_SWITCH"] = 61] = "AAVE_V3_DEBT_SWITCH";
125
+ BaseIds[BaseIds["AAVE_V3_DEBT_SWITCH_EOA"] = 62] = "AAVE_V3_DEBT_SWITCH_EOA";
120
126
  })(BaseIds = Strategies.BaseIds || (Strategies.BaseIds = {}));
121
127
  let ArbitrumIds;
122
128
  (function (ArbitrumIds) {
123
129
  ArbitrumIds[ArbitrumIds["EXCHANGE_DCA"] = 8] = "EXCHANGE_DCA";
124
130
  ArbitrumIds[ArbitrumIds["EXCHANGE_LIMIT_ORDER"] = 9] = "EXCHANGE_LIMIT_ORDER";
125
131
  ArbitrumIds[ArbitrumIds["AAVE_V3_COLLATERAL_SWITCH"] = 50] = "AAVE_V3_COLLATERAL_SWITCH";
132
+ ArbitrumIds[ArbitrumIds["AAVE_V3_DEBT_SWITCH"] = 55] = "AAVE_V3_DEBT_SWITCH";
133
+ ArbitrumIds[ArbitrumIds["AAVE_V3_DEBT_SWITCH_EOA"] = 56] = "AAVE_V3_DEBT_SWITCH_EOA";
126
134
  })(ArbitrumIds = Strategies.ArbitrumIds || (Strategies.ArbitrumIds = {}));
127
135
  let Identifiers;
128
136
  (function (Identifiers) {
@@ -157,6 +165,8 @@ export var Strategies;
157
165
  Identifiers["EoaRepayOnPrice"] = "eoa-repay-on-price";
158
166
  Identifiers["CollateralSwitch"] = "collateral-switch";
159
167
  Identifiers["EoaCollateralSwitch"] = "eoa-collateral-switch";
168
+ Identifiers["DebtSwitch"] = "debt-switch";
169
+ Identifiers["EoaDebtSwitch"] = "eoa-debt-switch";
160
170
  Identifiers["LiquidationProtection"] = "liquidation-protection";
161
171
  Identifiers["EoaLiquidationProtection"] = "liquidation-protection-eoa";
162
172
  })(Identifiers = Strategies.Identifiers || (Strategies.Identifiers = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/automation-sdk",
3
- "version": "3.3.19",
3
+ "version": "3.3.21-coll-switch-generic-dev",
4
4
  "description": "",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./esm/index.js",
@@ -22,6 +22,17 @@
22
22
  "author": "DeFi Saver",
23
23
  "repository": "https://github.com/defisaver/automation-sdk",
24
24
  "license": "ISC",
25
+ "overrides": {
26
+ "axios": "^1.19.0",
27
+ "tar": "^7.5.21",
28
+ "ws": "^8.18.3",
29
+ "form-data": "^4.0.4",
30
+ "tough-cookie": "^4.1.3",
31
+ "qs": "^6.16.0",
32
+ "serialize-javascript": "^7.1.0",
33
+ "fast-uri": "^3.1.8",
34
+ "js-yaml": "^4.3.2"
35
+ },
25
36
  "dependencies": {
26
37
  "@defisaver/sdk": "^1.3.22",
27
38
  "@defisaver/tokens": "^1.6.19",
@@ -44,7 +55,6 @@
44
55
  "dotenv": "^16.3.1",
45
56
  "eslint": "^8.49.0",
46
57
  "husky": "^8.0.0",
47
- "jsdoc-to-markdown": "^6.0.1",
48
58
  "mocha": "^10.2.0",
49
59
  "ts-node": "^10.9.1",
50
60
  "typechain": "^8.1.0",
@@ -145,6 +145,16 @@ export const MAINNET_STRATEGIES_INFO: MainnetStrategiesInfo = {
145
145
  strategyId: Strategies.Identifiers.EoaCollateralSwitch,
146
146
  protocol: PROTOCOLS.Spark,
147
147
  },
148
+ [Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH]: {
149
+ strategyOrBundleId: Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH,
150
+ strategyId: Strategies.Identifiers.DebtSwitch,
151
+ protocol: PROTOCOLS.AaveV3,
152
+ },
153
+ [Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH_EOA]: {
154
+ strategyOrBundleId: Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH_EOA,
155
+ strategyId: Strategies.Identifiers.EoaDebtSwitch,
156
+ protocol: PROTOCOLS.AaveV3,
157
+ },
148
158
  };
149
159
 
150
160
  export const OPTIMISM_STRATEGIES_INFO: OptimismStrategiesInfo = {
@@ -163,6 +173,16 @@ export const OPTIMISM_STRATEGIES_INFO: OptimismStrategiesInfo = {
163
173
  strategyId: Strategies.Identifiers.CollateralSwitch,
164
174
  protocol: PROTOCOLS.AaveV3,
165
175
  },
176
+ [Strategies.OptimismIds.AAVE_V3_DEBT_SWITCH]: {
177
+ strategyOrBundleId: Strategies.OptimismIds.AAVE_V3_DEBT_SWITCH,
178
+ strategyId: Strategies.Identifiers.DebtSwitch,
179
+ protocol: PROTOCOLS.AaveV3,
180
+ },
181
+ [Strategies.OptimismIds.AAVE_V3_DEBT_SWITCH_EOA]: {
182
+ strategyOrBundleId: Strategies.OptimismIds.AAVE_V3_DEBT_SWITCH_EOA,
183
+ strategyId: Strategies.Identifiers.EoaDebtSwitch,
184
+ protocol: PROTOCOLS.AaveV3,
185
+ },
166
186
  };
167
187
 
168
188
  export const BASE_STRATEGIES_INFO: BaseStrategiesInfo = {
@@ -181,6 +201,16 @@ export const BASE_STRATEGIES_INFO: BaseStrategiesInfo = {
181
201
  strategyId: Strategies.Identifiers.CollateralSwitch,
182
202
  protocol: PROTOCOLS.AaveV3,
183
203
  },
204
+ [Strategies.BaseIds.AAVE_V3_DEBT_SWITCH]: {
205
+ strategyOrBundleId: Strategies.BaseIds.AAVE_V3_DEBT_SWITCH,
206
+ strategyId: Strategies.Identifiers.DebtSwitch,
207
+ protocol: PROTOCOLS.AaveV3,
208
+ },
209
+ [Strategies.BaseIds.AAVE_V3_DEBT_SWITCH_EOA]: {
210
+ strategyOrBundleId: Strategies.BaseIds.AAVE_V3_DEBT_SWITCH_EOA,
211
+ strategyId: Strategies.Identifiers.EoaDebtSwitch,
212
+ protocol: PROTOCOLS.AaveV3,
213
+ },
184
214
  };
185
215
 
186
216
  export const ARBITRUM_STRATEGIES_INFO: ArbitrumStrategiesInfo = {
@@ -199,6 +229,16 @@ export const ARBITRUM_STRATEGIES_INFO: ArbitrumStrategiesInfo = {
199
229
  strategyId: Strategies.Identifiers.CollateralSwitch,
200
230
  protocol: PROTOCOLS.AaveV3,
201
231
  },
232
+ [Strategies.ArbitrumIds.AAVE_V3_DEBT_SWITCH]: {
233
+ strategyOrBundleId: Strategies.ArbitrumIds.AAVE_V3_DEBT_SWITCH,
234
+ strategyId: Strategies.Identifiers.DebtSwitch,
235
+ protocol: PROTOCOLS.AaveV3,
236
+ },
237
+ [Strategies.ArbitrumIds.AAVE_V3_DEBT_SWITCH_EOA]: {
238
+ strategyOrBundleId: Strategies.ArbitrumIds.AAVE_V3_DEBT_SWITCH_EOA,
239
+ strategyId: Strategies.Identifiers.EoaDebtSwitch,
240
+ protocol: PROTOCOLS.AaveV3,
241
+ },
202
242
  };
203
243
 
204
244
  export const STRATEGIES_INFO: StrategiesInfo = {
@@ -1,12 +1,117 @@
1
1
  import { expect } from 'chai';
2
2
 
3
- import { ProtocolIdentifiers, Strategies } from '../types/enums';
3
+ import { ChainId, ProtocolIdentifiers, RatioState, Strategies } from '../types/enums';
4
4
  import type { ParseData, Position } from '../types';
5
+ import { MAINNET_STRATEGIES_INFO } from '../constants';
5
6
 
6
7
  import '../configuration';
7
8
  import { parseStrategiesAutomatedPosition } from './strategiesService';
8
9
 
9
10
  describe('Feature: strategiesService.ts', () => {
11
+ describe('When parsing Aave V3 collateral switch subscriptions', () => {
12
+ const proxy = '0x9cB7E19861665366011899d74E75d4F2A419aEeD';
13
+ const user = '0x1234567890123456789012345678901234567890';
14
+ const fromAsset = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2';
15
+ const toAsset = '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf';
16
+ const marketAddr = '0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e';
17
+ const amountToSwitch = '115792089237316195423570985008687907853269984665640564039457584007913129639935';
18
+ const subHash = `0x${'ab'.repeat(32)}`;
19
+ const triggerData = [
20
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'
21
+ + '000000000000000000000000cbb7c0000ab88b473b1f5afd9ef808440eed33bf'
22
+ + '0000000000000000000000000000000000000000000000000000000000989680'
23
+ + '0000000000000000000000000000000000000000000000000000000000000001',
24
+ ];
25
+
26
+ function getParseData(strategyId: number, isGeneric: boolean, chainId = ChainId.Ethereum): ParseData {
27
+ const subData = [
28
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
29
+ isGeneric
30
+ ? '0x0000000000000000000000000000000000000000000000000000000000000100'
31
+ : '0x0000000000000000000000000000000000000000000000000000000000000000',
32
+ '0x000000000000000000000000cbb7c0000ab88b473b1f5afd9ef808440eed33bf',
33
+ isGeneric
34
+ ? '0x000000000000000000000000000000000000000000000000000000000000ffff'
35
+ : '0x0000000000000000000000000000000000000000000000000000000000000007',
36
+ '0x0000000000000000000000002f39d218133afab8f2b819b1066c7e434ad94e9e',
37
+ '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
38
+ isGeneric
39
+ ? '0x0000000000000000000000001234567890123456789012345678901234567890'
40
+ : '0x0000000000000000000000000000000000000000000000000000000000000000',
41
+ ];
42
+ const subStruct = Object.assign(
43
+ [String(strategyId), false, triggerData, subData] as [string, boolean, string[], string[]],
44
+ { strategyOrBundleId: String(strategyId), isBundle: false, triggerData, subData },
45
+ );
46
+ return {
47
+ chainId,
48
+ blockNumber: 18015756,
49
+ subscriptionEventData: {
50
+ subId: '379', proxy, subHash, subStruct,
51
+ 0: '379', 1: proxy, 2: subHash, 3: subStruct,
52
+ },
53
+ strategiesSubsData: {
54
+ userProxy: proxy, isEnabled: true, strategySubHash: subHash,
55
+ },
56
+ };
57
+ }
58
+
59
+ it('decodes generic collateral switches with the user and uint16 reserve IDs', () => {
60
+ const strategyId = Strategies.MainnetIds.AAVE_V3_COLLATERAL_SWITCH;
61
+ const originalInfo = MAINNET_STRATEGIES_INFO[strategyId];
62
+ const parseData = getParseData(strategyId, true);
63
+ let position: Position.Automated;
64
+ MAINNET_STRATEGIES_INFO[strategyId] = {
65
+ ...originalInfo,
66
+ strategyId: Strategies.Identifiers.EoaCollateralSwitch,
67
+ };
68
+ try {
69
+ position = parseStrategiesAutomatedPosition(parseData)!;
70
+ } finally {
71
+ MAINNET_STRATEGIES_INFO[strategyId] = originalInfo;
72
+ }
73
+
74
+ expect(position).not.to.equal(null);
75
+ expect(position.protocol.id).to.equal(ProtocolIdentifiers.StrategiesAutomation.AaveV3);
76
+ expect(position.strategy.strategyId).to.equal(Strategies.Identifiers.EoaCollateralSwitch);
77
+ expect(position.strategy.isBundle).to.equal(false);
78
+ expect(position.strategyData.encoded).to.eql({
79
+ triggerData,
80
+ subData: parseData.subscriptionEventData.subStruct.subData,
81
+ });
82
+ expect(position.strategyData.decoded.triggerData).to.eql({
83
+ baseTokenAddress: fromAsset,
84
+ quoteTokenAddress: toAsset,
85
+ price: '0.1',
86
+ ratioState: RatioState.UNDER,
87
+ });
88
+ expect(position.strategyData.decoded.subData).to.eql({
89
+ fromAsset, fromAssetId: 256, toAsset, toAssetId: 65535, marketAddr, amountToSwitch, user,
90
+ });
91
+ expect(position.owner).to.equal(proxy.toLowerCase());
92
+ expect(position.positionId).to.equal(`1-aave__v3-${proxy.toLowerCase()}-${marketAddr.toLowerCase()}`);
93
+ });
94
+
95
+ const legacyStrategies: Array<[ChainId, number]> = [
96
+ [ChainId.Ethereum, Strategies.MainnetIds.AAVE_V3_COLLATERAL_SWITCH],
97
+ [ChainId.Optimism, Strategies.OptimismIds.AAVE_V3_COLLATERAL_SWITCH],
98
+ [ChainId.Arbitrum, Strategies.ArbitrumIds.AAVE_V3_COLLATERAL_SWITCH],
99
+ [ChainId.Base, Strategies.BaseIds.AAVE_V3_COLLATERAL_SWITCH],
100
+ ];
101
+ legacyStrategies.forEach(([chainId, strategyId]) => {
102
+ it(`continues to decode legacy collateral switches on chain ${chainId}`, () => {
103
+ const position = parseStrategiesAutomatedPosition(getParseData(strategyId, false, chainId))!;
104
+
105
+ expect(position).not.to.equal(null);
106
+ expect(position.strategy.strategyId).to.equal(Strategies.Identifiers.CollateralSwitch);
107
+ expect(position.strategyData.decoded.subData).to.eql({
108
+ fromAsset, fromAssetId: 0, toAsset, toAssetId: 7, marketAddr, amountToSwitch,
109
+ });
110
+ expect(position.positionId).to.equal(`${chainId}-aave__v3-${proxy.toLowerCase()}-${marketAddr.toLowerCase()}`);
111
+ });
112
+ });
113
+ });
114
+
10
115
  describe('When testing strategiesService.parseStrategiesAutomatedPosition', async () => {
11
116
  // TODO: we should probably write this for every strategy?
12
117
  const examples: Array<[Position.Automated | null, ParseData]> = [
@@ -434,12 +434,31 @@ function parseAaveV3CloseOnPrice(position: Position.Automated, parseData: ParseD
434
434
  }
435
435
 
436
436
  function parseAaveV3CollateralSwitch(position: Position.Automated, parseData: ParseData): Position.Automated {
437
+ const _position = cloneDeep(position);
438
+ const { subStruct } = parseData.subscriptionEventData;
439
+ const isEOA = _position.strategy.strategyId.includes('eoa');
440
+ const triggerData = triggerService.aaveV3QuotePriceTrigger.decode(subStruct.triggerData);
441
+ const subData = isEOA
442
+ ? subDataService.aaveV3GenericFLCollateralSwitchSubData.decode(subStruct.subData)
443
+ : subDataService.aaveV3CollateralSwitchSubData.decode(subStruct.subData);
444
+ _position.strategyData.decoded.triggerData = triggerData;
445
+ _position.strategyData.decoded.subData = subData;
446
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, subData.marketAddr);
447
+ _position.strategy.strategyId = isEOA
448
+ ? Strategies.Identifiers.EoaCollateralSwitch
449
+ : Strategies.Identifiers.CollateralSwitch;
450
+
451
+ return _position;
452
+ }
453
+
454
+ function parseAaveV3DebtSwitch(position: Position.Automated, parseData: ParseData): Position.Automated {
437
455
  const _position = cloneDeep(position);
438
456
  const { subStruct } = parseData.subscriptionEventData;
439
457
  const triggerData = triggerService.aaveV3QuotePriceTrigger.decode(subStruct.triggerData);
440
- const subData = subDataService.aaveV3CollateralSwitchSubData.decode(subStruct.subData);
458
+ const subData = subDataService.aaveV3DebtSwitchSubData.decode(subStruct.subData);
441
459
  _position.strategyData.decoded.triggerData = triggerData;
442
460
  _position.strategyData.decoded.subData = subData;
461
+ // TODO -> This isn't enough for ID
443
462
  _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, subData.marketAddr);
444
463
 
445
464
  return _position;
@@ -1597,6 +1616,9 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
1597
1616
  [Strategies.Identifiers.EoaBoostOnPrice]: parseAaveV3LeverageManagementOnPrice,
1598
1617
  [Strategies.Identifiers.EoaCloseOnPrice]: parseAaveV3CloseOnPrice,
1599
1618
  [Strategies.Identifiers.CollateralSwitch]: parseAaveV3CollateralSwitch,
1619
+ [Strategies.Identifiers.EoaCollateralSwitch]: parseAaveV3CollateralSwitch,
1620
+ [Strategies.Identifiers.DebtSwitch]: parseAaveV3DebtSwitch,
1621
+ [Strategies.Identifiers.EoaDebtSwitch]: parseAaveV3DebtSwitch,
1600
1622
  [Strategies.Identifiers.LiquidationProtection]: parseAaveV3LiquidationProtection,
1601
1623
  [Strategies.Identifiers.EoaLiquidationProtection]: parseAaveV3LiquidationProtection,
1602
1624
  },
@@ -1002,6 +1002,137 @@ describe('Feature: strategySubService.ts', () => {
1002
1002
  });
1003
1003
  });
1004
1004
  });
1005
+
1006
+ describe('collateralSwitchGeneric()', () => {
1007
+ const strategyId = 12345;
1008
+ const fromAsset = web3Utils.toChecksumAddress(getAssetInfo('WETH', ChainId.Ethereum).address);
1009
+ const toAsset = web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address);
1010
+ const marketAddr = web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39');
1011
+ const user = web3Utils.toChecksumAddress('0x1234567890abcdef1234567890abcdef12345678');
1012
+ const examples: Array<[RatioState, string, string, string]> = [
1013
+ [
1014
+ RatioState.UNDER,
1015
+ '10000000000000000000',
1016
+ '0x0000000000000000000000000000000000000000000000008ac7230489e80000',
1017
+ '0000000000000000000000000000000000000000000000000000000000000001',
1018
+ ],
1019
+ [
1020
+ RatioState.OVER,
1021
+ MAXUINT,
1022
+ '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
1023
+ '0000000000000000000000000000000000000000000000000000000000000000',
1024
+ ],
1025
+ ];
1026
+
1027
+ examples.forEach(([state, amountToSwitch, encodedAmount, encodedState]) => {
1028
+ it(`encodes a generic collateral switch with the supplied quote pair and state ${state}`, () => {
1029
+ const expectedTrigger = `0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000003e8${encodedState}`;
1030
+ const expectedSubData: SubData = [
1031
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
1032
+ '0x0000000000000000000000000000000000000000000000000000000000000100',
1033
+ '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
1034
+ '0x000000000000000000000000000000000000000000000000000000000000ffff',
1035
+ '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
1036
+ encodedAmount,
1037
+ '0x0000000000000000000000001234567890abcdef1234567890abcdef12345678',
1038
+ ];
1039
+
1040
+ expect(aaveV3Encode.collateralSwitchGeneric(
1041
+ strategyId, fromAsset, 256, toAsset, 65535, marketAddr, amountToSwitch, user,
1042
+ toAsset, fromAsset, 0.00001, state,
1043
+ )).to.eql([strategyId, false, [expectedTrigger], expectedSubData]);
1044
+ });
1045
+ });
1046
+ });
1047
+
1048
+ describe('debtSwitch()', () => {
1049
+ const examples: Array<[
1050
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
1051
+ [
1052
+ strategyOrBundleId: number,
1053
+ fromAsset: EthereumAddress,
1054
+ fromAssetId: number,
1055
+ toAsset: EthereumAddress,
1056
+ toAssetId: number,
1057
+ marketAddr: EthereumAddress,
1058
+ amountToSwitch: string,
1059
+ user: EthereumAddress,
1060
+ baseTokenAddress: EthereumAddress,
1061
+ quoteTokenAddress: EthereumAddress,
1062
+ price: number,
1063
+ state: RatioState,
1064
+ ]
1065
+ ]> = [
1066
+ // USDC -> DAI, price 100000, state UNDER
1067
+ [
1068
+ [
1069
+ Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH,
1070
+ false,
1071
+ ['0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000000000009184e72a0000000000000000000000000000000000000000000000000000000000000000001'],
1072
+ [
1073
+ '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
1074
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
1075
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f',
1076
+ '0x0000000000000000000000000000000000000000000000000000000000000003',
1077
+ '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
1078
+ '0x0000000000000000000000000000000000000000000000008ac7230489e80000',
1079
+ '0x000000000000000000000000dd6ecd6c9b9f7e29e0f14bb9d5f0d0a3c6cb6c6a',
1080
+ ],
1081
+ ],
1082
+ [
1083
+ Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH,
1084
+ web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
1085
+ 1,
1086
+ web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
1087
+ 3,
1088
+ web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39'),
1089
+ '10000000000000000000', // 10 tokens
1090
+ web3Utils.toChecksumAddress('0xDd6ecD6c9b9F7e29E0f14bb9D5F0D0A3C6cB6c6A'),
1091
+ web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
1092
+ web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
1093
+ 100000,
1094
+ RatioState.UNDER,
1095
+ ]
1096
+ ],
1097
+ // DAI -> USDC (MaxUint256), price 1, state OVER
1098
+ [
1099
+ [
1100
+ Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH,
1101
+ false,
1102
+ ['0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000000000000'],
1103
+ [
1104
+ '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f',
1105
+ '0x0000000000000000000000000000000000000000000000000000000000000003',
1106
+ '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
1107
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
1108
+ '0x00000000000000000000000087870bca3f3fd6335c3f4ce8392d69d0b4161d39',
1109
+ '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
1110
+ '0x000000000000000000000000dd6ecd6c9b9f7e29e0f14bb9d5f0d0a3c6cb6c6a',
1111
+ ],
1112
+ ],
1113
+ [
1114
+ Strategies.MainnetIds.AAVE_V3_DEBT_SWITCH,
1115
+ web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
1116
+ 3,
1117
+ web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
1118
+ 1,
1119
+ web3Utils.toChecksumAddress('0x87870Bca3F3fD6335C3F4ce8392D69d0B4161d39'),
1120
+ MAXUINT, // MaxUint256
1121
+ web3Utils.toChecksumAddress('0xDd6ecD6c9b9F7e29E0f14bb9D5F0D0A3C6cB6c6A'),
1122
+ web3Utils.toChecksumAddress(getAssetInfo('DAI', ChainId.Ethereum).address),
1123
+ web3Utils.toChecksumAddress(getAssetInfo('USDC', ChainId.Ethereum).address),
1124
+ 1,
1125
+ RatioState.OVER,
1126
+ ]
1127
+ ],
1128
+ ];
1129
+
1130
+ examples.forEach(([expected, actual]) => {
1131
+ it(`Given ${JSON.stringify(actual)} should return expected value: ${JSON.stringify(expected)}`, () => {
1132
+ expect(aaveV3Encode.debtSwitch(...actual)).to.eql(expected);
1133
+ });
1134
+ });
1135
+ });
1005
1136
  });
1006
1137
 
1007
1138
  describe('When testing strategySubService.compoundV3Encode', () => {