@defisaver/automation-sdk 1.2.31 → 1.2.33

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.
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # SDK for fetching DeFi Saver strategies data from the blockchain.
2
+
3
+ Fetch strategies data from the blockchain, and parse it into a readable format.
4
+ Use one of the following classes to fetch data for strategies: EthereumStrategies, OptimismStrategies, or ArbitrumStrategies.
5
+ Use one of the following classes to fetch data for legacy automation: LegacyMakerAutomation, LegacyAaveAutomation, or LegacyCompoundAutomation.
6
+ Various services and constants also available for use.
7
+
8
+ ## Usage
9
+
10
+ ```js
11
+ const ethereumStrategies = new EthereumStrategies({
12
+ provider: WEB3_PROVIDER_HERE,
13
+ });
14
+
15
+ const subscriptions = await ethereumStrategies.getSubscriptionsFor(
16
+ // Pass one or multiple owner addresses, or use getSubscriptions method to fetch all subscriptions
17
+ ['0x000000000000000000000000000000000000dEaD'],
18
+ {
19
+ fromBlock: 0,
20
+ toBlock: 'latest',
21
+ }
22
+ );
23
+
24
+ // Do what you would like with subscriptions
25
+ ```
26
+
27
+ ## Development - How to add new strategies?
28
+
29
+ - Add strategy/bundle ID to `./src/types/enums.ts`, and create `Identifiers` if needed
30
+ - Add strategy/bundle info to `./src/constants/index.ts`
31
+ - Add encoding/decoding to the following files:
32
+ - `./src/services/strategySubService.ts`
33
+ - `./src/services/subDataService.ts`
34
+ - `./src/services/triggerService.ts`
35
+ - Write parsing for the strategy in `./src/services/strategeiesService.ts` and add assign it to `const parsingMethodsMapping`
36
+ - Test it out!
@@ -222,6 +222,26 @@ export const MAINNET_BUNDLES_INFO = {
222
222
  strategyId: Strategies.Identifiers.CloseToCollateral,
223
223
  protocol: PROTOCOLS.Spark,
224
224
  },
225
+ [Bundles.MainnetIds.AAVE_V2_REPAY]: {
226
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V2_REPAY,
227
+ strategyId: Strategies.Identifiers.Repay,
228
+ protocol: PROTOCOLS.AaveV2,
229
+ },
230
+ [Bundles.MainnetIds.AAVE_V2_BOOST]: {
231
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V2_BOOST,
232
+ strategyId: Strategies.Identifiers.Boost,
233
+ protocol: PROTOCOLS.AaveV2,
234
+ },
235
+ [Bundles.MainnetIds.COMP_V2_REPAY]: {
236
+ strategyOrBundleId: Bundles.MainnetIds.COMP_V2_REPAY,
237
+ strategyId: Strategies.Identifiers.Repay,
238
+ protocol: PROTOCOLS.CompoundV2,
239
+ },
240
+ [Bundles.MainnetIds.COMP_V2_BOOST]: {
241
+ strategyOrBundleId: Bundles.MainnetIds.COMP_V2_BOOST,
242
+ strategyId: Strategies.Identifiers.Boost,
243
+ protocol: PROTOCOLS.CompoundV2,
244
+ },
225
245
  };
226
246
  export const OPTIMISM_BUNDLES_INFO = {
227
247
  [Bundles.OptimismIds.AAVE_V3_REPAY]: {
@@ -109,12 +109,41 @@ function parseLiquityTrailingStop(position, parseData) {
109
109
  };
110
110
  return _position;
111
111
  }
112
+ function parseAaveV2LeverageManagement(position, parseData) {
113
+ const _position = cloneDeep(position);
114
+ const { subStruct, subId } = parseData.subscriptionEventData;
115
+ const { isEnabled } = parseData.strategiesSubsData;
116
+ const triggerData = triggerService.aaveV2RatioTrigger.decode(subStruct.triggerData);
117
+ const subData = subDataService.aaveV2LeverageManagementSubData.decode(subStruct.subData);
118
+ _position.strategyData.decoded.triggerData = triggerData;
119
+ _position.strategyData.decoded.subData = subData;
120
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
121
+ if (isRepay) {
122
+ _position.specific = {
123
+ minRatio: triggerData.ratio,
124
+ minOptimalRatio: subData.targetRatio,
125
+ repayEnabled: true,
126
+ subId1: Number(subId),
127
+ };
128
+ }
129
+ else {
130
+ _position.specific = {
131
+ maxRatio: triggerData.ratio,
132
+ maxOptimalRatio: subData.targetRatio,
133
+ boostEnabled: isEnabled,
134
+ subId2: Number(subId),
135
+ };
136
+ }
137
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
138
+ _position.specific.mergeWithSameId = true;
139
+ return _position;
140
+ }
112
141
  function parseAaveV3LeverageManagement(position, parseData) {
113
142
  const _position = cloneDeep(position);
114
143
  const { subStruct, subId } = parseData.subscriptionEventData;
115
144
  const { isEnabled } = parseData.strategiesSubsData;
116
145
  const triggerData = triggerService.aaveV3RatioTrigger.decode(subStruct.triggerData);
117
- const subData = subDataService.aaveLeverageManagementSubData.decode(subStruct.subData);
146
+ const subData = subDataService.aaveV3LeverageManagementSubData.decode(subStruct.subData);
118
147
  _position.strategyData.decoded.triggerData = triggerData;
119
148
  _position.strategyData.decoded.subData = subData;
120
149
  const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
@@ -188,6 +217,36 @@ function parseAaveV3CloseOnPrice(position, parseData) {
188
217
  _position.strategy.strategyId = isRatioStateOver(ratioState) ? Strategies.IdOverrides.TakeProfit : Strategies.IdOverrides.StopLoss;
189
218
  return _position;
190
219
  }
220
+ function parseCompoundV2LeverageManagement(position, parseData) {
221
+ const _position = cloneDeep(position);
222
+ const { subStruct, subId } = parseData.subscriptionEventData;
223
+ const { isEnabled } = parseData.strategiesSubsData;
224
+ const triggerData = triggerService.compoundV2RatioTrigger.decode(subStruct.triggerData);
225
+ const subData = subDataService.compoundV2LeverageManagementSubData.decode(subStruct.subData);
226
+ _position.strategyData.decoded.triggerData = triggerData;
227
+ _position.strategyData.decoded.subData = subData;
228
+ _position.owner = triggerData.owner;
229
+ const isRepay = [Strategies.Identifiers.Repay, Strategies.Identifiers.EoaRepay].includes(_position.strategy.strategyId);
230
+ if (isRepay) {
231
+ _position.specific = {
232
+ minRatio: triggerData.ratio,
233
+ minOptimalRatio: subData.targetRatio,
234
+ repayEnabled: true,
235
+ subId1: Number(subId),
236
+ };
237
+ }
238
+ else {
239
+ _position.specific = {
240
+ maxRatio: triggerData.ratio,
241
+ maxOptimalRatio: subData.targetRatio,
242
+ boostEnabled: isEnabled,
243
+ subId2: Number(subId),
244
+ };
245
+ }
246
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
247
+ _position.specific.mergeWithSameId = true;
248
+ return _position;
249
+ }
191
250
  function parseCompoundV3LeverageManagement(position, parseData) {
192
251
  const _position = cloneDeep(position);
193
252
  const { subStruct, subId } = parseData.subscriptionEventData;
@@ -351,12 +410,20 @@ const parsingMethodsMapping = {
351
410
  [Strategies.Identifiers.Repay]: parseLiquityLeverageManagement,
352
411
  [Strategies.Identifiers.Boost]: parseLiquityLeverageManagement,
353
412
  },
413
+ [ProtocolIdentifiers.StrategiesAutomation.AaveV2]: {
414
+ [Strategies.Identifiers.Repay]: parseAaveV2LeverageManagement,
415
+ [Strategies.Identifiers.Boost]: parseAaveV2LeverageManagement,
416
+ },
354
417
  [ProtocolIdentifiers.StrategiesAutomation.AaveV3]: {
355
418
  [Strategies.Identifiers.Repay]: parseAaveV3LeverageManagement,
356
419
  [Strategies.Identifiers.Boost]: parseAaveV3LeverageManagement,
357
420
  [Strategies.Identifiers.CloseToDebt]: parseAaveV3CloseOnPrice,
358
421
  [Strategies.Identifiers.CloseToCollateral]: parseAaveV3CloseOnPrice,
359
422
  },
423
+ [ProtocolIdentifiers.StrategiesAutomation.CompoundV2]: {
424
+ [Strategies.Identifiers.Repay]: parseCompoundV2LeverageManagement,
425
+ [Strategies.Identifiers.Boost]: parseCompoundV2LeverageManagement,
426
+ },
360
427
  [ProtocolIdentifiers.StrategiesAutomation.CompoundV3]: {
361
428
  [Strategies.Identifiers.Repay]: parseCompoundV3LeverageManagement,
362
429
  [Strategies.Identifiers.Boost]: parseCompoundV3LeverageManagement,
@@ -15,6 +15,9 @@ export declare const liquityEncode: {
15
15
  export declare const chickenBondsEncode: {
16
16
  rebond(bondId: number): string[];
17
17
  };
18
+ export declare const aaveV2Encode: {
19
+ leverageManagement(minRatio: number, maxRatio: number, maxOptimalRatio: number, minOptimalRatio: number, boostEnabled: boolean): string[];
20
+ };
18
21
  export declare const aaveV3Encode: {
19
22
  leverageManagement(minRatio: number, maxRatio: number, maxOptimalRatio: number, minOptimalRatio: number, boostEnabled: boolean): string;
20
23
  closeToAsset(strategyOrBundleId: number, isBundle: boolean | undefined, triggerData: {
@@ -29,6 +32,9 @@ export declare const aaveV3Encode: {
29
32
  debtAssetId: number;
30
33
  }): (number | boolean | string[])[];
31
34
  };
35
+ export declare const compoundV2Encode: {
36
+ leverageManagement(minRatio: number, maxRatio: number, maxOptimalRatio: number, minOptimalRatio: number, boostEnabled: boolean): string[];
37
+ };
32
38
  export declare const compoundV3Encode: {
33
39
  leverageManagement(market: EthereumAddress, baseToken: EthereumAddress, minRatio: number, maxRatio: number, maxOptimalRatio: number, minOptimalRatio: number, boostEnabled: boolean, isEOA: boolean): string[];
34
40
  };
@@ -81,6 +81,11 @@ export const chickenBondsEncode = {
81
81
  return subDataService.cBondsRebondSubData.encode(bondId);
82
82
  },
83
83
  };
84
+ export const aaveV2Encode = {
85
+ leverageManagement(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled) {
86
+ return subDataService.aaveV2LeverageManagementSubData.encode(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled);
87
+ },
88
+ };
84
89
  export const aaveV3Encode = {
85
90
  leverageManagement(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled) {
86
91
  let subInput = '0x';
@@ -103,6 +108,11 @@ export const aaveV3Encode = {
103
108
  return [strategyOrBundleId, isBundle, triggerDataEncoded, subDataEncoded];
104
109
  },
105
110
  };
111
+ export const compoundV2Encode = {
112
+ leverageManagement(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled) {
113
+ return subDataService.compoundV2LeverageManagementSubData.encode(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled);
114
+ },
115
+ };
106
116
  export const compoundV3Encode = {
107
117
  leverageManagement(market, baseToken, minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled, isEOA) {
108
118
  return subDataService.compoundV3LeverageManagementSubData.encode(market, baseToken, minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled, isEOA);
@@ -34,7 +34,13 @@ export declare const liquityCloseSubData: {
34
34
  debtAddr: string;
35
35
  };
36
36
  };
37
- export declare const aaveLeverageManagementSubData: {
37
+ export declare const aaveV2LeverageManagementSubData: {
38
+ encode(minRatio: number, maxRatio: number, maxOptimalRatio: number, minOptimalRatio: number, boostEnabled: boolean): string[];
39
+ decode(subData: string[]): {
40
+ targetRatio: number;
41
+ };
42
+ };
43
+ export declare const aaveV3LeverageManagementSubData: {
38
44
  decode(subData: string[]): {
39
45
  targetRatio: number;
40
46
  };
@@ -48,6 +54,12 @@ export declare const aaveV3QuotePriceSubData: {
48
54
  debtAssetId: number;
49
55
  };
50
56
  };
57
+ export declare const compoundV2LeverageManagementSubData: {
58
+ encode(minRatio: number, maxRatio: number, maxOptimalRatio: number, minOptimalRatio: number, boostEnabled: boolean): string[];
59
+ decode(subData: string[]): {
60
+ targetRatio: number;
61
+ };
62
+ };
51
63
  export declare const compoundV3LeverageManagementSubData: {
52
64
  encode(market: EthereumAddress, baseToken: EthereumAddress, minRatio: number, maxRatio: number, maxOptimalRatio: number, minOptimalRatio: number, boostEnabled: boolean, isEOA: boolean): string[];
53
65
  decode(subData: string[]): {
@@ -96,7 +96,24 @@ export const liquityCloseSubData = {
96
96
  return { closeToAssetAddr, debtAddr };
97
97
  },
98
98
  };
99
- export const aaveLeverageManagementSubData = {
99
+ export const aaveV2LeverageManagementSubData = {
100
+ encode(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled) {
101
+ return [
102
+ new Dec(minRatio).mul(1e16).toString(),
103
+ new Dec(maxRatio).mul(1e16).toString(),
104
+ new Dec(maxOptimalRatio).mul(1e16).toString(),
105
+ new Dec(minOptimalRatio).mul(1e16).toString(),
106
+ // @ts-ignore // TODO
107
+ boostEnabled,
108
+ ];
109
+ },
110
+ decode(subData) {
111
+ const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint256', subData[1]);
112
+ const targetRatio = weiToRatioPercentage(ratioWei);
113
+ return { targetRatio };
114
+ },
115
+ };
116
+ export const aaveV3LeverageManagementSubData = {
100
117
  decode(subData) {
101
118
  const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint256', subData[0]);
102
119
  const targetRatio = weiToRatioPercentage(ratioWei);
@@ -122,6 +139,23 @@ export const aaveV3QuotePriceSubData = {
122
139
  };
123
140
  },
124
141
  };
142
+ export const compoundV2LeverageManagementSubData = {
143
+ encode(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled) {
144
+ return [
145
+ new Dec(minRatio).mul(1e16).toString(),
146
+ new Dec(maxRatio).mul(1e16).toString(),
147
+ new Dec(maxOptimalRatio).mul(1e16).toString(),
148
+ new Dec(minOptimalRatio).mul(1e16).toString(),
149
+ // @ts-ignore // TODO
150
+ boostEnabled,
151
+ ];
152
+ },
153
+ decode(subData) {
154
+ const weiRatio = mockedWeb3.eth.abi.decodeParameter('uint256', subData[0]);
155
+ const targetRatio = weiToRatioPercentage(weiRatio);
156
+ return { targetRatio };
157
+ },
158
+ };
125
159
  export const compoundV3LeverageManagementSubData = {
126
160
  encode(market, baseToken, minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled, isEOA) {
127
161
  return [
@@ -55,7 +55,7 @@ export declare const compoundV2RatioTrigger: {
55
55
  decode(triggerData: string[]): {
56
56
  owner: EthereumAddress;
57
57
  ratioState: RatioState;
58
- ratio: string;
58
+ ratio: number;
59
59
  };
60
60
  };
61
61
  export declare const liquityRatioTrigger: {
@@ -79,7 +79,7 @@ export declare const aaveV2RatioTrigger: {
79
79
  owner: EthereumAddress;
80
80
  market: EthereumAddress;
81
81
  ratioState: RatioState;
82
- ratio: string;
82
+ ratio: number;
83
83
  };
84
84
  };
85
85
  export declare const cBondsRebondTrigger: {
@@ -88,7 +88,7 @@ export const compoundV2RatioTrigger = {
88
88
  const decodedData = mockedWeb3.eth.abi.decodeParameters(['address', 'uint256', 'uint8'], triggerData[0]);
89
89
  return {
90
90
  owner: decodedData[0],
91
- ratio: new Dec(mockedWeb3.utils.fromWei(decodedData[1])).mul(100).toString(),
91
+ ratio: new Dec(mockedWeb3.utils.fromWei(decodedData[1])).mul(100).toNumber(),
92
92
  ratioState: +decodedData[2],
93
93
  };
94
94
  },
@@ -129,7 +129,7 @@ export const aaveV2RatioTrigger = {
129
129
  return {
130
130
  owner: decodedData[0],
131
131
  market: decodedData[1],
132
- ratio: new Dec(mockedWeb3.utils.fromWei(decodedData[2])).mul(100).toString(),
132
+ ratio: new Dec(mockedWeb3.utils.fromWei(decodedData[2])).mul(100).toNumber(),
133
133
  ratioState: +decodedData[3],
134
134
  };
135
135
  },
@@ -24,7 +24,9 @@ export declare namespace ProtocolIdentifiers {
24
24
  MakerDAO = "MakerDAO",
25
25
  Liquity = "Liquity",
26
26
  ChickenBonds = "Chicken Bonds",
27
+ CompoundV2 = "Compound__V2",
27
28
  CompoundV3 = "Compound__V3",
29
+ AaveV2 = "Aave__V2",
28
30
  AaveV3 = "Aave__V3",
29
31
  MorphoAaveV2 = "Morpho-Aave__V2",
30
32
  Exchange = "Exchange",
@@ -104,8 +106,12 @@ export declare namespace Bundles {
104
106
  LIQUITY_BOOST = 17,
105
107
  SPARK_REPAY = 18,
106
108
  SPARK_BOOST = 19,
107
- SPARK_CLOSE_TO_DEBT = 20,
108
- SPARK_CLOSE_TO_COLLATERAL = 21
109
+ SPARK_CLOSE_TO_DEBT = -21231230,
110
+ SPARK_CLOSE_TO_COLLATERAL = -21231231,
111
+ AAVE_V2_REPAY = 22,
112
+ AAVE_V2_BOOST = 23,
113
+ COMP_V2_REPAY = 20,
114
+ COMP_V2_BOOST = 21
109
115
  }
110
116
  enum OptimismIds {
111
117
  AAVE_V3_REPAY = 0,
@@ -29,7 +29,9 @@ export var ProtocolIdentifiers;
29
29
  StrategiesAutomation["MakerDAO"] = "MakerDAO";
30
30
  StrategiesAutomation["Liquity"] = "Liquity";
31
31
  StrategiesAutomation["ChickenBonds"] = "Chicken Bonds";
32
+ StrategiesAutomation["CompoundV2"] = "Compound__V2";
32
33
  StrategiesAutomation["CompoundV3"] = "Compound__V3";
34
+ StrategiesAutomation["AaveV2"] = "Aave__V2";
33
35
  StrategiesAutomation["AaveV3"] = "Aave__V3";
34
36
  StrategiesAutomation["MorphoAaveV2"] = "Morpho-Aave__V2";
35
37
  StrategiesAutomation["Exchange"] = "Exchange";
@@ -118,8 +120,12 @@ export var Bundles;
118
120
  MainnetIds[MainnetIds["LIQUITY_BOOST"] = 17] = "LIQUITY_BOOST";
119
121
  MainnetIds[MainnetIds["SPARK_REPAY"] = 18] = "SPARK_REPAY";
120
122
  MainnetIds[MainnetIds["SPARK_BOOST"] = 19] = "SPARK_BOOST";
121
- MainnetIds[MainnetIds["SPARK_CLOSE_TO_DEBT"] = 20] = "SPARK_CLOSE_TO_DEBT";
122
- MainnetIds[MainnetIds["SPARK_CLOSE_TO_COLLATERAL"] = 21] = "SPARK_CLOSE_TO_COLLATERAL";
123
+ MainnetIds[MainnetIds["SPARK_CLOSE_TO_DEBT"] = -21231230] = "SPARK_CLOSE_TO_DEBT";
124
+ MainnetIds[MainnetIds["SPARK_CLOSE_TO_COLLATERAL"] = -21231231] = "SPARK_CLOSE_TO_COLLATERAL";
125
+ MainnetIds[MainnetIds["AAVE_V2_REPAY"] = 22] = "AAVE_V2_REPAY";
126
+ MainnetIds[MainnetIds["AAVE_V2_BOOST"] = 23] = "AAVE_V2_BOOST";
127
+ MainnetIds[MainnetIds["COMP_V2_REPAY"] = 20] = "COMP_V2_REPAY";
128
+ MainnetIds[MainnetIds["COMP_V2_BOOST"] = 21] = "COMP_V2_BOOST";
123
129
  })(MainnetIds = Bundles.MainnetIds || (Bundles.MainnetIds = {}));
124
130
  let OptimismIds;
125
131
  (function (OptimismIds) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/automation-sdk",
3
- "version": "1.2.31",
3
+ "version": "1.2.33",
4
4
  "description": "",
5
5
  "main": "./umd/index.js",
6
6
  "module": "./esm/index.js",
@@ -238,6 +238,26 @@ export const MAINNET_BUNDLES_INFO: MainnetBundleInfo = {
238
238
  strategyId: Strategies.Identifiers.CloseToCollateral,
239
239
  protocol: PROTOCOLS.Spark,
240
240
  },
241
+ [Bundles.MainnetIds.AAVE_V2_REPAY]: {
242
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V2_REPAY,
243
+ strategyId: Strategies.Identifiers.Repay,
244
+ protocol: PROTOCOLS.AaveV2,
245
+ },
246
+ [Bundles.MainnetIds.AAVE_V2_BOOST]: {
247
+ strategyOrBundleId: Bundles.MainnetIds.AAVE_V2_BOOST,
248
+ strategyId: Strategies.Identifiers.Boost,
249
+ protocol: PROTOCOLS.AaveV2,
250
+ },
251
+ [Bundles.MainnetIds.COMP_V2_REPAY]: {
252
+ strategyOrBundleId: Bundles.MainnetIds.COMP_V2_REPAY,
253
+ strategyId: Strategies.Identifiers.Repay,
254
+ protocol: PROTOCOLS.CompoundV2,
255
+ },
256
+ [Bundles.MainnetIds.COMP_V2_BOOST]: {
257
+ strategyOrBundleId: Bundles.MainnetIds.COMP_V2_BOOST,
258
+ strategyId: Strategies.Identifiers.Boost,
259
+ protocol: PROTOCOLS.CompoundV2,
260
+ },
241
261
  };
242
262
 
243
263
  export const OPTIMISM_BUNDLES_INFO: OptimismBundleInfo = {
@@ -157,6 +157,42 @@ function parseLiquityTrailingStop(position: Position.Automated, parseData: Parse
157
157
  return _position;
158
158
  }
159
159
 
160
+ function parseAaveV2LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
161
+ const _position = cloneDeep(position);
162
+
163
+ const { subStruct, subId } = parseData.subscriptionEventData;
164
+ const { isEnabled } = parseData.strategiesSubsData;
165
+
166
+ const triggerData = triggerService.aaveV2RatioTrigger.decode(subStruct.triggerData);
167
+ const subData = subDataService.aaveV2LeverageManagementSubData.decode(subStruct.subData);
168
+
169
+ _position.strategyData.decoded.triggerData = triggerData;
170
+ _position.strategyData.decoded.subData = subData;
171
+
172
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
173
+
174
+ if (isRepay) {
175
+ _position.specific = {
176
+ minRatio: triggerData.ratio,
177
+ minOptimalRatio: subData.targetRatio,
178
+ repayEnabled: true,
179
+ subId1: Number(subId),
180
+ };
181
+ } else {
182
+ _position.specific = {
183
+ maxRatio: triggerData.ratio,
184
+ maxOptimalRatio: subData.targetRatio,
185
+ boostEnabled: isEnabled,
186
+ subId2: Number(subId),
187
+ };
188
+ }
189
+
190
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
191
+ _position.specific.mergeWithSameId = true;
192
+
193
+ return _position;
194
+ }
195
+
160
196
  function parseAaveV3LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
161
197
  const _position = cloneDeep(position);
162
198
 
@@ -164,7 +200,7 @@ function parseAaveV3LeverageManagement(position: Position.Automated, parseData:
164
200
  const { isEnabled } = parseData.strategiesSubsData;
165
201
 
166
202
  const triggerData = triggerService.aaveV3RatioTrigger.decode(subStruct.triggerData);
167
- const subData = subDataService.aaveLeverageManagementSubData.decode(subStruct.subData);
203
+ const subData = subDataService.aaveV3LeverageManagementSubData.decode(subStruct.subData);
168
204
 
169
205
  _position.strategyData.decoded.triggerData = triggerData;
170
206
  _position.strategyData.decoded.subData = subData;
@@ -263,6 +299,42 @@ function parseAaveV3CloseOnPrice(position: Position.Automated, parseData: ParseD
263
299
  return _position;
264
300
  }
265
301
 
302
+ function parseCompoundV2LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
303
+ const _position = cloneDeep(position);
304
+
305
+ const { subStruct, subId } = parseData.subscriptionEventData;
306
+ const { isEnabled } = parseData.strategiesSubsData;
307
+
308
+ const triggerData = triggerService.compoundV2RatioTrigger.decode(subStruct.triggerData);
309
+ const subData = subDataService.compoundV2LeverageManagementSubData.decode(subStruct.subData);
310
+
311
+ _position.strategyData.decoded.triggerData = triggerData;
312
+ _position.strategyData.decoded.subData = subData;
313
+ _position.owner = triggerData.owner;
314
+ const isRepay = [Strategies.Identifiers.Repay, Strategies.Identifiers.EoaRepay].includes(_position.strategy.strategyId as Strategies.Identifiers);
315
+
316
+ if (isRepay) {
317
+ _position.specific = {
318
+ minRatio: triggerData.ratio,
319
+ minOptimalRatio: subData.targetRatio,
320
+ repayEnabled: true,
321
+ subId1: Number(subId),
322
+ };
323
+ } else {
324
+ _position.specific = {
325
+ maxRatio: triggerData.ratio,
326
+ maxOptimalRatio: subData.targetRatio,
327
+ boostEnabled: isEnabled,
328
+ subId2: Number(subId),
329
+ };
330
+ }
331
+
332
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
333
+ _position.specific.mergeWithSameId = true;
334
+
335
+ return _position;
336
+ }
337
+
266
338
  function parseCompoundV3LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
267
339
  const _position = cloneDeep(position);
268
340
 
@@ -475,12 +547,20 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
475
547
  [Strategies.Identifiers.Repay]: parseLiquityLeverageManagement,
476
548
  [Strategies.Identifiers.Boost]: parseLiquityLeverageManagement,
477
549
  },
550
+ [ProtocolIdentifiers.StrategiesAutomation.AaveV2]: {
551
+ [Strategies.Identifiers.Repay]: parseAaveV2LeverageManagement,
552
+ [Strategies.Identifiers.Boost]: parseAaveV2LeverageManagement,
553
+ },
478
554
  [ProtocolIdentifiers.StrategiesAutomation.AaveV3]: {
479
555
  [Strategies.Identifiers.Repay]: parseAaveV3LeverageManagement,
480
556
  [Strategies.Identifiers.Boost]: parseAaveV3LeverageManagement,
481
557
  [Strategies.Identifiers.CloseToDebt]: parseAaveV3CloseOnPrice,
482
558
  [Strategies.Identifiers.CloseToCollateral]: parseAaveV3CloseOnPrice,
483
559
  },
560
+ [ProtocolIdentifiers.StrategiesAutomation.CompoundV2]: {
561
+ [Strategies.Identifiers.Repay]: parseCompoundV2LeverageManagement,
562
+ [Strategies.Identifiers.Boost]: parseCompoundV2LeverageManagement,
563
+ },
484
564
  [ProtocolIdentifiers.StrategiesAutomation.CompoundV3]: {
485
565
  [Strategies.Identifiers.Repay]: parseCompoundV3LeverageManagement,
486
566
  [Strategies.Identifiers.Boost]: parseCompoundV3LeverageManagement,
@@ -172,6 +172,18 @@ export const chickenBondsEncode = {
172
172
  },
173
173
  };
174
174
 
175
+ export const aaveV2Encode = {
176
+ leverageManagement(
177
+ minRatio: number,
178
+ maxRatio: number,
179
+ maxOptimalRatio: number,
180
+ minOptimalRatio: number,
181
+ boostEnabled: boolean,
182
+ ) {
183
+ return subDataService.aaveV2LeverageManagementSubData.encode(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled);
184
+ },
185
+ };
186
+
175
187
  export const aaveV3Encode = {
176
188
  leverageManagement(
177
189
  minRatio: number,
@@ -218,6 +230,18 @@ export const aaveV3Encode = {
218
230
  },
219
231
  };
220
232
 
233
+ export const compoundV2Encode = {
234
+ leverageManagement(
235
+ minRatio: number,
236
+ maxRatio: number,
237
+ maxOptimalRatio: number,
238
+ minOptimalRatio: number,
239
+ boostEnabled: boolean,
240
+ ) {
241
+ return subDataService.compoundV2LeverageManagementSubData.encode(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled);
242
+ },
243
+ };
244
+
221
245
  export const compoundV3Encode = {
222
246
  leverageManagement(
223
247
  market: EthereumAddress,
@@ -132,7 +132,32 @@ export const liquityCloseSubData = {
132
132
  },
133
133
  };
134
134
 
135
- export const aaveLeverageManagementSubData = { // TODO encode?
135
+ export const aaveV2LeverageManagementSubData = {
136
+ encode(
137
+ minRatio: number,
138
+ maxRatio: number,
139
+ maxOptimalRatio: number,
140
+ minOptimalRatio: number,
141
+ boostEnabled: boolean,
142
+ ): SubData {
143
+ return [
144
+ new Dec(minRatio).mul(1e16).toString(),
145
+ new Dec(maxRatio).mul(1e16).toString(),
146
+ new Dec(maxOptimalRatio).mul(1e16).toString(),
147
+ new Dec(minOptimalRatio).mul(1e16).toString(),
148
+ // @ts-ignore // TODO
149
+ boostEnabled,
150
+ ];
151
+ },
152
+ decode(subData: SubData): { targetRatio: number } {
153
+ const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint256', subData[1]) as any as string;
154
+ const targetRatio = weiToRatioPercentage(ratioWei);
155
+
156
+ return { targetRatio };
157
+ },
158
+ };
159
+
160
+ export const aaveV3LeverageManagementSubData = { // TODO encode?
136
161
  decode(subData: SubData): { targetRatio: number } {
137
162
  const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint256', subData[0]) as any as string;
138
163
  const targetRatio = weiToRatioPercentage(ratioWei);
@@ -172,6 +197,31 @@ export const aaveV3QuotePriceSubData = {
172
197
  },
173
198
  };
174
199
 
200
+ export const compoundV2LeverageManagementSubData = {
201
+ encode(
202
+ minRatio: number,
203
+ maxRatio: number,
204
+ maxOptimalRatio: number,
205
+ minOptimalRatio: number,
206
+ boostEnabled: boolean,
207
+ ): SubData {
208
+ return [
209
+ new Dec(minRatio).mul(1e16).toString(),
210
+ new Dec(maxRatio).mul(1e16).toString(),
211
+ new Dec(maxOptimalRatio).mul(1e16).toString(),
212
+ new Dec(minOptimalRatio).mul(1e16).toString(),
213
+ // @ts-ignore // TODO
214
+ boostEnabled,
215
+ ];
216
+ },
217
+ decode(subData: SubData): { targetRatio: number } {
218
+ const weiRatio = mockedWeb3.eth.abi.decodeParameter('uint256', subData[0]) as any as string;
219
+ const targetRatio = weiToRatioPercentage(weiRatio);
220
+
221
+ return { targetRatio };
222
+ },
223
+ };
224
+
175
225
  export const compoundV3LeverageManagementSubData = {
176
226
  encode(
177
227
  market: EthereumAddress,
@@ -105,11 +105,11 @@ export const compoundV2RatioTrigger = {
105
105
  const ratioWei = ratioPercentageToWei(ratioPercentage);
106
106
  return [mockedWeb3.eth.abi.encodeParameters(['address', 'uint256', 'uint8'], [owner, ratioWei, ratioState])];
107
107
  },
108
- decode(triggerData: TriggerData): { owner: EthereumAddress, ratioState: RatioState, ratio: string } {
108
+ decode(triggerData: TriggerData): { owner: EthereumAddress, ratioState: RatioState, ratio: number } {
109
109
  const decodedData = mockedWeb3.eth.abi.decodeParameters(['address', 'uint256', 'uint8'], triggerData[0]);
110
110
  return {
111
111
  owner: decodedData[0],
112
- ratio: new Dec(mockedWeb3.utils.fromWei(decodedData[1])).mul(100).toString(),
112
+ ratio: new Dec(mockedWeb3.utils.fromWei(decodedData[1])).mul(100).toNumber(),
113
113
  ratioState: +decodedData[2],
114
114
  };
115
115
  },
@@ -148,12 +148,12 @@ export const aaveV2RatioTrigger = {
148
148
  const ratioWei = ratioPercentageToWei(ratioPercentage);
149
149
  return [mockedWeb3.eth.abi.encodeParameters(['address', 'address', 'uint256', 'uint8'], [owner, market, ratioWei, ratioState])];
150
150
  },
151
- decode(triggerData: TriggerData): { owner: EthereumAddress, market:EthereumAddress, ratioState: RatioState, ratio: string } {
151
+ decode(triggerData: TriggerData): { owner: EthereumAddress, market:EthereumAddress, ratioState: RatioState, ratio: number } {
152
152
  const decodedData = mockedWeb3.eth.abi.decodeParameters(['address', 'address', 'uint256', 'uint8'], triggerData[0]);
153
153
  return {
154
154
  owner: decodedData[0],
155
155
  market: decodedData[1],
156
- ratio: new Dec(mockedWeb3.utils.fromWei(decodedData[2])).mul(100).toString(),
156
+ ratio: new Dec(mockedWeb3.utils.fromWei(decodedData[2])).mul(100).toNumber(),
157
157
  ratioState: +decodedData[3],
158
158
  };
159
159
  },