@defisaver/automation-sdk 3.0.3 → 3.0.5

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 (143) hide show
  1. package/.babelrc +3 -3
  2. package/.editorconfig +9 -9
  3. package/.env.dev +4 -4
  4. package/.eslintignore +6 -6
  5. package/.eslintrc.js +41 -41
  6. package/.tests.sh +2 -2
  7. package/README.md +41 -41
  8. package/esm/abis/Erc20.json +223 -223
  9. package/esm/abis/SubStorage.json +17 -17
  10. package/esm/abis/UniMulticall.json +14 -14
  11. package/esm/abis/index.d.ts +9 -9
  12. package/esm/abis/index.js +30 -30
  13. package/esm/abis/legacy_AaveV2Subscriptions.json +8 -8
  14. package/esm/abis/legacy_AuthCheck.json +8 -8
  15. package/esm/abis/legacy_CompoundV2Subscriptions.json +9 -9
  16. package/esm/abis/legacy_MakerSubscriptions.json +9 -9
  17. package/esm/automation/private/Automation.d.ts +12 -12
  18. package/esm/automation/private/Automation.js +42 -42
  19. package/esm/automation/private/LegacyAutomation.d.ts +25 -25
  20. package/esm/automation/private/LegacyAutomation.js +118 -118
  21. package/esm/automation/private/LegacyProtocol.d.ts +22 -22
  22. package/esm/automation/private/LegacyProtocol.js +41 -41
  23. package/esm/automation/private/LegacyProtocol.test.d.ts +1 -1
  24. package/esm/automation/private/LegacyProtocol.test.js +25 -25
  25. package/esm/automation/private/Protocol.d.ts +22 -22
  26. package/esm/automation/private/Protocol.js +41 -41
  27. package/esm/automation/private/Protocol.test.d.ts +1 -1
  28. package/esm/automation/private/Protocol.test.js +25 -25
  29. package/esm/automation/private/StrategiesAutomation.d.ts +33 -33
  30. package/esm/automation/private/StrategiesAutomation.js +181 -181
  31. package/esm/automation/private/StrategiesAutomation.test.d.ts +1 -1
  32. package/esm/automation/private/StrategiesAutomation.test.js +671 -671
  33. package/esm/automation/public/ArbitrumStrategies.d.ts +5 -5
  34. package/esm/automation/public/ArbitrumStrategies.js +13 -13
  35. package/esm/automation/public/EthereumStrategies.d.ts +5 -5
  36. package/esm/automation/public/EthereumStrategies.js +13 -13
  37. package/esm/automation/public/OptimismStrategies.d.ts +5 -5
  38. package/esm/automation/public/OptimismStrategies.js +13 -13
  39. package/esm/automation/public/legacy/LegacyAaveAutomation.d.ts +6 -6
  40. package/esm/automation/public/legacy/LegacyAaveAutomation.js +20 -20
  41. package/esm/automation/public/legacy/LegacyCompoundAutomation.d.ts +6 -6
  42. package/esm/automation/public/legacy/LegacyCompoundAutomation.js +20 -20
  43. package/esm/automation/public/legacy/LegacyMakerAutomation.d.ts +6 -6
  44. package/esm/automation/public/legacy/LegacyMakerAutomation.js +20 -20
  45. package/esm/configuration.d.ts +1 -1
  46. package/esm/configuration.js +12 -12
  47. package/esm/constants/index.d.ts +45 -45
  48. package/esm/constants/index.js +395 -365
  49. package/esm/index.d.ts +22 -22
  50. package/esm/index.js +63 -63
  51. package/esm/services/contractService.d.ts +12 -12
  52. package/esm/services/contractService.js +54 -54
  53. package/esm/services/ethereumService.d.ts +7 -7
  54. package/esm/services/ethereumService.js +49 -49
  55. package/esm/services/ethereumService.test.d.ts +1 -1
  56. package/esm/services/ethereumService.test.js +242 -242
  57. package/esm/services/strategiesService.d.ts +2 -2
  58. package/esm/services/strategiesService.js +701 -698
  59. package/esm/services/strategiesService.test.d.ts +1 -1
  60. package/esm/services/strategiesService.test.js +110 -110
  61. package/esm/services/strategySubService.d.ts +87 -87
  62. package/esm/services/strategySubService.js +257 -252
  63. package/esm/services/strategySubService.test.d.ts +1 -1
  64. package/esm/services/strategySubService.test.js +892 -890
  65. package/esm/services/subDataService.d.ts +181 -181
  66. package/esm/services/subDataService.js +442 -442
  67. package/esm/services/subDataService.test.d.ts +1 -1
  68. package/esm/services/subDataService.test.js +1223 -1223
  69. package/esm/services/triggerService.d.ts +191 -191
  70. package/esm/services/triggerService.js +367 -367
  71. package/esm/services/triggerService.test.d.ts +1 -1
  72. package/esm/services/triggerService.test.js +926 -926
  73. package/esm/services/utils.d.ts +25 -25
  74. package/esm/services/utils.js +131 -131
  75. package/esm/services/utils.test.d.ts +1 -1
  76. package/esm/services/utils.test.js +376 -376
  77. package/esm/types/contracts/generated/Erc20.d.ts +53 -53
  78. package/esm/types/contracts/generated/Erc20.js +5 -5
  79. package/esm/types/contracts/generated/Legacy_AaveV2Subscriptions.d.ts +129 -129
  80. package/esm/types/contracts/generated/Legacy_AaveV2Subscriptions.js +5 -5
  81. package/esm/types/contracts/generated/Legacy_AuthCheck.d.ts +20 -20
  82. package/esm/types/contracts/generated/Legacy_AuthCheck.js +5 -5
  83. package/esm/types/contracts/generated/Legacy_CompoundV2Subscriptions.d.ts +128 -128
  84. package/esm/types/contracts/generated/Legacy_CompoundV2Subscriptions.js +5 -5
  85. package/esm/types/contracts/generated/Legacy_MakerSubscriptions.d.ts +246 -246
  86. package/esm/types/contracts/generated/Legacy_MakerSubscriptions.js +5 -5
  87. package/esm/types/contracts/generated/SubStorage.d.ts +114 -114
  88. package/esm/types/contracts/generated/SubStorage.js +5 -5
  89. package/esm/types/contracts/generated/UniMulticall.d.ts +55 -55
  90. package/esm/types/contracts/generated/UniMulticall.js +5 -5
  91. package/esm/types/contracts/generated/index.d.ts +7 -7
  92. package/esm/types/contracts/generated/index.js +2 -2
  93. package/esm/types/contracts/generated/types.d.ts +54 -54
  94. package/esm/types/contracts/generated/types.js +2 -2
  95. package/esm/types/enums.d.ts +160 -154
  96. package/esm/types/enums.js +180 -174
  97. package/esm/types/index.d.ts +217 -217
  98. package/esm/types/index.js +2 -2
  99. package/package.json +71 -71
  100. package/scripts/generateContractTypes.js +39 -39
  101. package/src/abis/Erc20.json +222 -222
  102. package/src/abis/SubStorage.json +17 -17
  103. package/src/abis/UniMulticall.json +14 -14
  104. package/src/abis/index.ts +28 -28
  105. package/src/abis/legacy_AaveV2Subscriptions.json +7 -7
  106. package/src/abis/legacy_AuthCheck.json +7 -7
  107. package/src/abis/legacy_CompoundV2Subscriptions.json +8 -8
  108. package/src/abis/legacy_MakerSubscriptions.json +8 -8
  109. package/src/automation/private/Automation.ts +44 -44
  110. package/src/automation/private/LegacyAutomation.ts +135 -135
  111. package/src/automation/private/LegacyProtocol.test.ts +23 -23
  112. package/src/automation/private/LegacyProtocol.ts +51 -51
  113. package/src/automation/private/Protocol.test.ts +23 -23
  114. package/src/automation/private/Protocol.ts +51 -51
  115. package/src/automation/private/StrategiesAutomation.test.ts +663 -663
  116. package/src/automation/private/StrategiesAutomation.ts +242 -242
  117. package/src/automation/public/ArbitrumStrategies.ts +10 -10
  118. package/src/automation/public/EthereumStrategies.ts +10 -10
  119. package/src/automation/public/OptimismStrategies.ts +10 -10
  120. package/src/automation/public/legacy/LegacyAaveAutomation.ts +20 -20
  121. package/src/automation/public/legacy/LegacyCompoundAutomation.ts +20 -20
  122. package/src/automation/public/legacy/LegacyMakerAutomation.ts +20 -20
  123. package/src/configuration.ts +8 -8
  124. package/src/constants/index.ts +409 -379
  125. package/src/index.ts +38 -38
  126. package/src/services/contractService.ts +77 -77
  127. package/src/services/ethereumService.test.ts +257 -257
  128. package/src/services/ethereumService.ts +69 -69
  129. package/src/services/strategiesService.test.ts +105 -105
  130. package/src/services/strategiesService.ts +905 -901
  131. package/src/services/strategySubService.test.ts +1063 -1060
  132. package/src/services/strategySubService.ts +496 -492
  133. package/src/services/subDataService.test.ts +1324 -1324
  134. package/src/services/subDataService.ts +594 -593
  135. package/src/services/triggerService.test.ts +1004 -1004
  136. package/src/services/triggerService.ts +449 -449
  137. package/src/services/utils.test.ts +430 -430
  138. package/src/services/utils.ts +103 -103
  139. package/src/types/enums.ts +174 -168
  140. package/src/types/index.ts +262 -262
  141. package/tsconfig.json +79 -79
  142. package/umd/index.js +65 -24
  143. package/webpack.umd.js +52 -52
@@ -1,901 +1,905 @@
1
- import { getAssetInfoByAddress } from '@defisaver/tokens';
2
- import { cloneDeep } from 'lodash';
3
-
4
- import { BUNDLES_INFO, STRATEGIES_INFO } from '../constants';
5
- import type {
6
- Position, ParseData, StrategiesToProtocolVersionMapping, BundleOrStrategy, StrategyOrBundleIds,
7
- BundleInfoUnion, StrategyInfoUnion,
8
- } from '../types';
9
- import { ChainId, ProtocolIdentifiers, Strategies } from '../types/enums';
10
-
11
- import {
12
- getPositionId, getRatioStateInfoForAaveCloseStrategy, isRatioStateOver, wethToEthByAddress,
13
- } from './utils';
14
- import * as subDataService from './subDataService';
15
- import * as triggerService from './triggerService';
16
-
17
- const SPARK_MARKET_ADDRESSES = {
18
- [ChainId.Ethereum]: '0x02C3eA4e34C0cBd694D2adFa2c690EECbC1793eE',
19
- };
20
-
21
- const AAVE_V3_MARKET_ADDRESSES = {
22
- [ChainId.Ethereum]: '0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e',
23
- [ChainId.Optimism]: '0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb',
24
- [ChainId.Arbitrum]: '0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb',
25
- };
26
-
27
- function parseMakerSavingsLiqProtection(position: Position.Automated, parseData: ParseData): Position.Automated {
28
- const _position = cloneDeep(position);
29
-
30
- const { subStruct } = parseData.subscriptionEventData;
31
-
32
- const triggerData = triggerService.makerRatioTrigger.decode(subStruct.triggerData);
33
- const subData = subDataService.makerRepayFromSavingsSubData.decode(subStruct.subData);
34
-
35
- _position.strategyData.decoded.triggerData = triggerData;
36
- _position.strategyData.decoded.subData = subData;
37
-
38
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, subData.vaultId);
39
-
40
- _position.specific = {
41
- triggerRepayRatio: Number(triggerData.ratio),
42
- targetRepayRatio: Number(subData.targetRatio),
43
- repayEnabled: true,
44
- boostEnabled: false,
45
- };
46
-
47
- return _position;
48
- }
49
-
50
- function parseMakerCloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
51
- const _position = cloneDeep(position);
52
-
53
- const { subStruct } = parseData.subscriptionEventData;
54
-
55
- const triggerData = triggerService.chainlinkPriceTrigger.decode(subStruct.triggerData);
56
- const subData = subDataService.makerCloseSubData.decode(subStruct.subData);
57
-
58
- _position.strategyData.decoded.triggerData = triggerData;
59
- _position.strategyData.decoded.subData = subData;
60
-
61
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, subData.vaultId);
62
-
63
- const isTakeProfit = isRatioStateOver(Number(triggerData.state));
64
-
65
- _position.strategy.strategyId = isTakeProfit ? Strategies.IdOverrides.TakeProfit : Strategies.IdOverrides.StopLoss;
66
-
67
- _position.specific = {
68
- price: triggerData.price,
69
- closeToAssetAddr: subData.closeToAssetAddr,
70
- };
71
-
72
- return _position;
73
- }
74
-
75
- function parseMakerTrailingStop(position: Position.Automated, parseData: ParseData): Position.Automated {
76
- const _position = cloneDeep(position);
77
-
78
- const { subStruct } = parseData.subscriptionEventData;
79
-
80
- const triggerData = triggerService.trailingStopTrigger.decode(subStruct.triggerData);
81
- const subData = subDataService.makerCloseSubData.decode(subStruct.subData);
82
-
83
- _position.strategyData.decoded.triggerData = triggerData;
84
- _position.strategyData.decoded.subData = subData;
85
-
86
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, subData.vaultId);
87
-
88
- _position.strategy.strategyId = Strategies.IdOverrides.TrailingStop;
89
-
90
- _position.specific = {
91
- triggerPercentage: Number(triggerData.triggerPercentage),
92
- roundId: Number(triggerData.roundId),
93
- closeToAssetAddr: subData.closeToAssetAddr,
94
- };
95
-
96
- return _position;
97
- }
98
-
99
- function parseMakerLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
100
- const _position = cloneDeep(position);
101
-
102
- const { subStruct, subId } = parseData.subscriptionEventData;
103
- const { isEnabled } = parseData.strategiesSubsData;
104
-
105
- const triggerData = triggerService.makerRatioTrigger.decode(subStruct.triggerData);
106
- const subData = subDataService.makerLeverageManagementSubData.decode(subStruct.subData);
107
-
108
- _position.strategyData.decoded.triggerData = triggerData;
109
- _position.strategyData.decoded.subData = subData;
110
-
111
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, subData.vaultId);
112
-
113
- const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
114
-
115
- if (isRepay) {
116
- _position.specific = {
117
- triggerRepayRatio: triggerData.ratio,
118
- targetRepayRatio: subData.targetRatio,
119
- repayEnabled: true,
120
- subId1: Number(subId),
121
- mergeWithId: Strategies.Identifiers.Boost,
122
- };
123
- } else {
124
- _position.specific = {
125
- triggerBoostRatio: triggerData.ratio,
126
- targetBoostRatio: subData.targetRatio,
127
- boostEnabled: isEnabled,
128
- subId2: Number(subId),
129
- mergeId: Strategies.Identifiers.Boost,
130
- };
131
- }
132
-
133
- _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
134
-
135
- return _position;
136
- }
137
-
138
- function parseLiquityCloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
139
- const _position = cloneDeep(position);
140
-
141
- const { subStruct } = parseData.subscriptionEventData;
142
-
143
- const triggerData = triggerService.chainlinkPriceTrigger.decode(subStruct.triggerData);
144
- const subData = subDataService.liquityCloseSubData.decode(subStruct.subData);
145
-
146
- _position.strategyData.decoded.triggerData = triggerData;
147
- _position.strategyData.decoded.subData = subData;
148
-
149
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
150
-
151
- const isTakeProfit = isRatioStateOver(Number(triggerData.state));
152
-
153
- _position.strategy.strategyId = isTakeProfit ? Strategies.IdOverrides.TakeProfit : Strategies.IdOverrides.StopLoss;
154
-
155
- _position.specific = {
156
- price: triggerData.price,
157
- closeToAssetAddr: subData.closeToAssetAddr,
158
- };
159
-
160
- return _position;
161
- }
162
-
163
- function parseLiquityTrailingStop(position: Position.Automated, parseData: ParseData): Position.Automated {
164
- const _position = cloneDeep(position);
165
-
166
- const { subStruct } = parseData.subscriptionEventData;
167
-
168
- const triggerData = triggerService.trailingStopTrigger.decode(subStruct.triggerData);
169
- const subData = subDataService.liquityCloseSubData.decode(subStruct.subData);
170
-
171
- _position.strategyData.decoded.triggerData = triggerData;
172
- _position.strategyData.decoded.subData = subData;
173
-
174
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
175
-
176
- _position.strategy.strategyId = Strategies.IdOverrides.TrailingStop;
177
-
178
- _position.specific = {
179
- triggerPercentage: Number(triggerData.triggerPercentage),
180
- roundId: Number(triggerData.roundId),
181
- closeToAssetAddr: subData.closeToAssetAddr,
182
- };
183
-
184
- return _position;
185
- }
186
-
187
- function parseAaveV2LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
188
- const _position = cloneDeep(position);
189
-
190
- const { subStruct, subId } = parseData.subscriptionEventData;
191
- const { isEnabled } = parseData.strategiesSubsData;
192
-
193
- const triggerData = triggerService.aaveV2RatioTrigger.decode(subStruct.triggerData);
194
- const subData = subDataService.aaveV2LeverageManagementSubData.decode(subStruct.subData);
195
-
196
- _position.strategyData.decoded.triggerData = triggerData;
197
- _position.strategyData.decoded.subData = subData;
198
-
199
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
200
-
201
- const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
202
-
203
- if (isRepay) {
204
- _position.specific = {
205
- triggerRepayRatio: triggerData.ratio,
206
- targetRepayRatio: subData.targetRatio,
207
- repayEnabled: true,
208
- subId1: Number(subId),
209
- mergeWithId: Strategies.Identifiers.Boost,
210
- };
211
- } else {
212
- _position.specific = {
213
- triggerBoostRatio: triggerData.ratio,
214
- targetBoostRatio: subData.targetRatio,
215
- boostEnabled: isEnabled,
216
- subId2: Number(subId),
217
- mergeId: Strategies.Identifiers.Boost,
218
- };
219
- }
220
-
221
- _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
222
-
223
- return _position;
224
- }
225
-
226
- function parseAaveV3LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
227
- const _position = cloneDeep(position);
228
-
229
- const { subStruct, subId } = parseData.subscriptionEventData;
230
- const { isEnabled } = parseData.strategiesSubsData;
231
-
232
- const triggerData = triggerService.aaveV3RatioTrigger.decode(subStruct.triggerData);
233
- const subData = subDataService.aaveV3LeverageManagementSubData.decode(subStruct.subData);
234
-
235
- _position.strategyData.decoded.triggerData = triggerData;
236
- _position.strategyData.decoded.subData = subData;
237
-
238
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
239
-
240
- const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
241
-
242
- if (isRepay) {
243
- _position.specific = {
244
- triggerRepayRatio: triggerData.ratio,
245
- targetRepayRatio: subData.targetRatio,
246
- repayEnabled: true,
247
- subId1: Number(subId),
248
- mergeWithId: Strategies.Identifiers.Boost,
249
- };
250
- } else {
251
- _position.specific = {
252
- triggerBoostRatio: triggerData.ratio,
253
- targetBoostRatio: subData.targetRatio,
254
- boostEnabled: isEnabled,
255
- subId2: Number(subId),
256
- mergeId: Strategies.Identifiers.Boost,
257
- };
258
- }
259
-
260
- _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
261
-
262
- return _position;
263
- }
264
-
265
- function parseMorphoAaveV2LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
266
- const _position = cloneDeep(position);
267
-
268
- const { subStruct, subId } = parseData.subscriptionEventData;
269
- const { isEnabled } = parseData.strategiesSubsData;
270
-
271
- const triggerData = triggerService.morphoAaveV2RatioTrigger.decode(subStruct.triggerData);
272
- const subData = subDataService.morphoAaveV2LeverageManagementSubData.decode(subStruct.subData);
273
-
274
- _position.strategyData.decoded.triggerData = triggerData;
275
- _position.strategyData.decoded.subData = subData;
276
-
277
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
278
-
279
- const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
280
-
281
- if (isRepay) {
282
- _position.specific = {
283
- triggerRepayRatio: triggerData.ratio,
284
- targetRepayRatio: subData.targetRatio,
285
- repayEnabled: true,
286
- subId1: Number(subId),
287
- mergeWithId: Strategies.Identifiers.Boost,
288
- };
289
- } else {
290
- _position.specific = {
291
- triggerBoostRatio: triggerData.ratio,
292
- targetBoostRatio: subData.targetRatio,
293
- boostEnabled: isEnabled,
294
- subId2: Number(subId),
295
- mergeId: Strategies.Identifiers.Boost,
296
- };
297
- }
298
-
299
- _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
300
-
301
- return _position;
302
- }
303
-
304
- function parseAaveV3CloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
305
- const _position = cloneDeep(position);
306
-
307
- const { subStruct } = parseData.subscriptionEventData;
308
-
309
- const triggerData = triggerService.aaveV3QuotePriceTrigger.decode(subStruct.triggerData);
310
- const subData = subDataService.aaveV3QuotePriceSubData.decode(subStruct.subData);
311
-
312
- _position.strategyData.decoded.triggerData = triggerData;
313
- _position.strategyData.decoded.subData = subData;
314
-
315
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, AAVE_V3_MARKET_ADDRESSES[_position.chainId]);
316
-
317
- _position.specific = {
318
- collAsset: subData.collAsset,
319
- collAssetId: subData.collAssetId,
320
- debtAsset: subData.debtAsset,
321
- debtAssetId: subData.debtAssetId,
322
- baseToken: triggerData.baseTokenAddress,
323
- quoteToken: triggerData.quoteTokenAddress,
324
- price: triggerData.price,
325
- ratioState: triggerData.ratioState,
326
- };
327
-
328
- const { ratioState } = getRatioStateInfoForAaveCloseStrategy(
329
- _position.specific.ratioState,
330
- wethToEthByAddress(_position.specific.collAsset, parseData.chainId),
331
- wethToEthByAddress(_position.specific.debtAsset, parseData.chainId),
332
- parseData.chainId,
333
- );
334
-
335
- _position.strategy.strategyId = isRatioStateOver(ratioState) ? Strategies.IdOverrides.TakeProfit : Strategies.IdOverrides.StopLoss;
336
-
337
- return _position;
338
- }
339
-
340
- function parseAaveV3CloseOnPriceWithMaximumGasPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
341
- const _position = cloneDeep(position);
342
-
343
- const { subStruct } = parseData.subscriptionEventData;
344
-
345
- const triggerData = triggerService.aaveV3QuotePriceWithMaximumGasPriceTrigger.decode(subStruct.triggerData);
346
- const subData = subDataService.aaveV3QuotePriceSubData.decode(subStruct.subData);
347
-
348
- _position.strategyData.decoded.triggerData = triggerData;
349
- _position.strategyData.decoded.subData = subData;
350
-
351
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, AAVE_V3_MARKET_ADDRESSES[_position.chainId]);
352
-
353
- _position.specific = {
354
- collAsset: subData.collAsset,
355
- collAssetId: subData.collAssetId,
356
- debtAsset: subData.debtAsset,
357
- debtAssetId: subData.debtAssetId,
358
- baseToken: triggerData.baseTokenAddress,
359
- quoteToken: triggerData.quoteTokenAddress,
360
- price: triggerData.price,
361
- maximumGasPrice: triggerData.maximumGasPrice,
362
- ratioState: triggerData.ratioState,
363
- };
364
-
365
- const { ratioState } = getRatioStateInfoForAaveCloseStrategy(
366
- _position.specific.ratioState,
367
- wethToEthByAddress(_position.specific.collAsset, parseData.chainId),
368
- wethToEthByAddress(_position.specific.debtAsset, parseData.chainId),
369
- parseData.chainId,
370
- );
371
-
372
- _position.strategy.strategyId = isRatioStateOver(ratioState)
373
- ? Strategies.IdOverrides.TakeProfitWithGasPrice
374
- : Strategies.IdOverrides.StopLossWithGasPrice;
375
-
376
- return _position;
377
- }
378
-
379
- function parseCompoundV2LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
380
- const _position = cloneDeep(position);
381
-
382
- const { subStruct, subId } = parseData.subscriptionEventData;
383
- const { isEnabled } = parseData.strategiesSubsData;
384
-
385
- const triggerData = triggerService.compoundV2RatioTrigger.decode(subStruct.triggerData);
386
- const subData = subDataService.compoundV2LeverageManagementSubData.decode(subStruct.subData);
387
-
388
- _position.strategyData.decoded.triggerData = triggerData;
389
- _position.strategyData.decoded.subData = subData;
390
- _position.owner = triggerData.owner.toLowerCase();
391
-
392
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
393
-
394
- const isRepay = [Strategies.Identifiers.Repay, Strategies.Identifiers.EoaRepay].includes(_position.strategy.strategyId as Strategies.Identifiers);
395
-
396
- if (isRepay) {
397
- _position.specific = {
398
- triggerRepayRatio: triggerData.ratio,
399
- targetRepayRatio: subData.targetRatio,
400
- repayEnabled: true,
401
- subId1: Number(subId),
402
- mergeWithId: Strategies.Identifiers.Boost,
403
- };
404
- } else {
405
- _position.specific = {
406
- triggerBoostRatio: triggerData.ratio,
407
- targetBoostRatio: subData.targetRatio,
408
- boostEnabled: isEnabled,
409
- subId2: Number(subId),
410
- mergeId: Strategies.Identifiers.Boost,
411
- };
412
- }
413
-
414
- _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
415
-
416
- return _position;
417
- }
418
-
419
- function parseCompoundV3LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
420
- const _position = cloneDeep(position);
421
-
422
- const { subStruct, subId } = parseData.subscriptionEventData;
423
- const { isEnabled } = parseData.strategiesSubsData;
424
-
425
- const subDataDecoder = position.chainId !== 1
426
- ? subDataService.compoundV3L2LeverageManagementSubData
427
- : subDataService.compoundV3LeverageManagementSubData;
428
-
429
- const triggerData = triggerService.compoundV3RatioTrigger.decode(subStruct.triggerData);
430
- const subData = subDataDecoder.decode(subStruct.subData);
431
-
432
- _position.strategyData.decoded.triggerData = triggerData;
433
- _position.strategyData.decoded.subData = subData;
434
- _position.owner = triggerData.owner.toLowerCase();
435
-
436
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
437
-
438
- const isRepay = [Strategies.Identifiers.Repay, Strategies.Identifiers.EoaRepay].includes(_position.strategy.strategyId as Strategies.Identifiers);
439
-
440
- if (isRepay) {
441
- _position.specific = {
442
- triggerRepayRatio: triggerData.ratio,
443
- targetRepayRatio: subData.targetRatio,
444
- repayEnabled: true,
445
- subId1: Number(subId),
446
- mergeWithId: Strategies.Identifiers.Boost,
447
- };
448
- } else {
449
- _position.specific = {
450
- triggerBoostRatio: triggerData.ratio,
451
- targetBoostRatio: subData.targetRatio,
452
- boostEnabled: isEnabled,
453
- subId2: Number(subId),
454
- mergeId: Strategies.Identifiers.Boost,
455
- };
456
- }
457
-
458
- const isEOA = _position.strategy.strategyId.includes('eoa');
459
- _position.strategy.strategyId = isEOA ? Strategies.IdOverrides.EoaLeverageManagement : Strategies.IdOverrides.LeverageManagement;
460
-
461
-
462
- return _position;
463
- }
464
-
465
- function parseChickenBondsRebond(position: Position.Automated, parseData: ParseData): Position.Automated {
466
- const _position = cloneDeep(position);
467
-
468
- const { subStruct } = parseData.subscriptionEventData;
469
-
470
- _position.strategyData.decoded.triggerData = triggerService.cBondsRebondTrigger.decode(subStruct.triggerData);
471
- _position.strategyData.decoded.subData = subDataService.cBondsRebondSubData.decode(subStruct.subData);
472
-
473
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.strategyData.decoded.triggerData.bondId);
474
-
475
- return _position;
476
- }
477
-
478
- function parseLiquityBondProtection(position: Position.Automated, parseData: ParseData): Position.Automated {
479
- const _position = cloneDeep(position);
480
-
481
- const { subStruct } = parseData.subscriptionEventData;
482
-
483
- const triggerData = triggerService.liquityRatioTrigger.decode(subStruct.triggerData);
484
-
485
- _position.strategyData.decoded.triggerData = triggerData;
486
- _position.strategyData.decoded.subData = subDataService.liquityPaybackUsingChickenBondSubData.decode(subStruct.subData);
487
-
488
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
489
-
490
- _position.specific = {
491
- triggerRepayRatio: Number(triggerData.ratio),
492
- targetRepayRatio: Infinity, // Unknown targetRepayRatio, uses all assets from chicken bond until trove min debt (2000LUSD)
493
- repayEnabled: true,
494
- };
495
- return _position;
496
- }
497
-
498
- function parseExchangeDca(position: Position.Automated, parseData: ParseData, chainId: ChainId): Position.Automated {
499
- const _position = cloneDeep(position);
500
-
501
- const { subStruct } = parseData.subscriptionEventData;
502
-
503
- _position.strategyData.decoded.triggerData = triggerService.exchangeTimestampTrigger.decode(subStruct.triggerData);
504
- _position.strategyData.decoded.subData = subDataService.exchangeDcaSubData.decode(subStruct.subData, chainId);
505
-
506
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, Math.random());
507
-
508
- return _position;
509
- }
510
-
511
- function parseExchangeLimitOrder(position: Position.Automated, parseData: ParseData, chainId: ChainId): Position.Automated {
512
- const _position = cloneDeep(position);
513
-
514
- const { subStruct } = parseData.subscriptionEventData;
515
-
516
- _position.strategyData.decoded.subData = subDataService.exchangeLimitOrderSubData.decode(subStruct.subData, chainId);
517
- const fromTokenDecimals = getAssetInfoByAddress(_position.strategyData.decoded.subData.fromToken, chainId).decimals;
518
- const toTokenDecimals = getAssetInfoByAddress(_position.strategyData.decoded.subData.toToken, chainId).decimals;
519
- _position.strategyData.decoded.triggerData = triggerService.exchangeOffchainPriceTrigger.decode(subStruct.triggerData, fromTokenDecimals, toTokenDecimals);
520
-
521
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, Math.random());
522
-
523
- return _position;
524
- }
525
-
526
- function parseLiquityLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
527
- const _position = cloneDeep(position);
528
-
529
- const { subStruct, subId } = parseData.subscriptionEventData;
530
- const { isEnabled } = parseData.strategiesSubsData;
531
-
532
- const triggerData = triggerService.liquityRatioTrigger.decode(subStruct.triggerData);
533
- const subData = subDataService.liquityLeverageManagementSubData.decode(subStruct.subData);
534
-
535
- _position.strategyData.decoded.triggerData = triggerData;
536
- _position.strategyData.decoded.subData = subData;
537
-
538
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
539
-
540
- const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
541
-
542
- if (isRepay) {
543
- _position.specific = {
544
- triggerRepayRatio: triggerData.ratio,
545
- targetRepayRatio: subData.targetRatio,
546
- repayEnabled: true,
547
- subId1: Number(subId),
548
- mergeWithId: Strategies.Identifiers.Boost,
549
- };
550
- } else {
551
- _position.specific = {
552
- triggerBoostRatio: triggerData.ratio,
553
- targetBoostRatio: subData.targetRatio,
554
- boostEnabled: isEnabled,
555
- subId2: Number(subId),
556
- mergeId: Strategies.Identifiers.Boost,
557
- };
558
- }
559
-
560
- _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
561
-
562
- return _position;
563
- }
564
-
565
- function parseSparkLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
566
- const _position = cloneDeep(position);
567
-
568
- const { subStruct, subId } = parseData.subscriptionEventData;
569
- const { isEnabled } = parseData.strategiesSubsData;
570
-
571
- const triggerData = triggerService.sparkRatioTrigger.decode(subStruct.triggerData);
572
- const subData = subDataService.sparkLeverageManagementSubData.decode(subStruct.subData);
573
-
574
- _position.strategyData.decoded.triggerData = triggerData;
575
- _position.strategyData.decoded.subData = subData;
576
-
577
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
578
-
579
- const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
580
-
581
- if (isRepay) {
582
- _position.specific = {
583
- triggerRepayRatio: triggerData.ratio,
584
- targetRepayRatio: subData.targetRatio,
585
- repayEnabled: true,
586
- subId1: Number(subId),
587
- mergeWithId: Strategies.Identifiers.Boost,
588
- };
589
- } else {
590
- _position.specific = {
591
- triggerBoostRatio: triggerData.ratio,
592
- targetBoostRatio: subData.targetRatio,
593
- boostEnabled: isEnabled,
594
- subId2: Number(subId),
595
- mergeId: Strategies.Identifiers.Boost,
596
- };
597
- }
598
-
599
- _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
600
-
601
- return _position;
602
- }
603
-
604
- function parseSparkCloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
605
- const _position = cloneDeep(position);
606
-
607
- const { subStruct } = parseData.subscriptionEventData;
608
-
609
- const triggerData = triggerService.sparkQuotePriceTrigger.decode(subStruct.triggerData);
610
- const subData = subDataService.sparkQuotePriceSubData.decode(subStruct.subData);
611
-
612
- _position.strategyData.decoded.triggerData = triggerData;
613
- _position.strategyData.decoded.subData = subData;
614
-
615
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, SPARK_MARKET_ADDRESSES[_position.chainId as ChainId.Ethereum]);
616
-
617
- _position.specific = {
618
- collAsset: subData.collAsset,
619
- collAssetId: subData.collAssetId,
620
- debtAsset: subData.debtAsset,
621
- debtAssetId: subData.debtAssetId,
622
- baseToken: triggerData.baseTokenAddress,
623
- quoteToken: triggerData.quoteTokenAddress,
624
- price: triggerData.price,
625
- ratioState: triggerData.ratioState,
626
- };
627
-
628
- const { ratioState } = getRatioStateInfoForAaveCloseStrategy(
629
- _position.specific.ratioState,
630
- wethToEthByAddress(_position.specific.collAsset, parseData.chainId),
631
- wethToEthByAddress(_position.specific.debtAsset, parseData.chainId),
632
- parseData.chainId,
633
- );
634
-
635
- _position.strategy.strategyId = isRatioStateOver(ratioState) ? Strategies.IdOverrides.TakeProfit : Strategies.IdOverrides.StopLoss;
636
-
637
- return _position;
638
- }
639
-
640
- function parseLiquitySavingsLiqProtection(position: Position.Automated, parseData: ParseData): Position.Automated {
641
- const _position = cloneDeep(position);
642
-
643
- const { subStruct } = parseData.subscriptionEventData;
644
-
645
- const triggerData = triggerService.liquityRatioTrigger.decode(subStruct.triggerData);
646
- const subData = subDataService.liquityRepayFromSavingsSubData.decode(subStruct.subData);
647
-
648
- _position.strategyData.decoded.triggerData = triggerData;
649
- _position.strategyData.decoded.subData = subData;
650
-
651
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
652
-
653
- _position.specific = {
654
- triggerRepayRatio: triggerData.ratio,
655
- targetRepayRatio: subData.targetRatio,
656
- repayEnabled: true,
657
- boostEnabled: false,
658
- };
659
-
660
- return _position;
661
- }
662
-
663
- function parseLiquityDebtInFrontRepay(position: Position.Automated, parseData: ParseData): Position.Automated {
664
- const _position = cloneDeep(position);
665
-
666
- const { subStruct } = parseData.subscriptionEventData;
667
-
668
- const triggerData = triggerService.liquityDebtInFrontWithLimitTrigger.decode(subStruct.triggerData);
669
- const subData = subDataService.liquityDebtInFrontRepaySubData.decode(subStruct.subData);
670
-
671
- _position.strategyData.decoded.triggerData = triggerData;
672
- _position.strategyData.decoded.subData = subData;
673
-
674
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
675
-
676
- _position.specific = {
677
- debtInFrontMin: triggerData.debtInFrontMin,
678
- targetRepayRatioIncrease: subData.targetRatioIncrease,
679
- };
680
-
681
- return _position;
682
- }
683
-
684
- function parseCrvUSDLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
685
- const _position = cloneDeep(position);
686
-
687
- const { subStruct, subId, subHash } = parseData.subscriptionEventData;
688
- const { isEnabled } = parseData.strategiesSubsData;
689
- const triggerData = triggerService.crvUSDRatioTrigger.decode(subStruct.triggerData);
690
- const subData = subDataService.crvUSDLeverageManagementSubData.decode(subStruct.subData);
691
-
692
- _position.strategyData.decoded.triggerData = triggerData;
693
- _position.strategyData.decoded.subData = subData;
694
-
695
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.controller);
696
-
697
- const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
698
-
699
- if (isRepay) {
700
- _position.specific = {
701
- triggerRepayRatio: triggerData.ratio,
702
- targetRepayRatio: subData.targetRatio,
703
- repayEnabled: isEnabled,
704
- subId1: Number(subId),
705
- subHashRepay: subHash,
706
- mergeWithId: Strategies.Identifiers.Boost,
707
- };
708
- } else {
709
- _position.specific = {
710
- triggerBoostRatio: triggerData.ratio,
711
- targetBoostRatio: subData.targetRatio,
712
- boostEnabled: isEnabled,
713
- subId2: Number(subId),
714
- subHashBoost: subHash,
715
- mergeId: Strategies.Identifiers.Boost,
716
- };
717
- }
718
-
719
- _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
720
-
721
- return _position;
722
- }
723
-
724
- function parseCrvUSDPayback(position: Position.Automated, parseData: ParseData): Position.Automated {
725
- const _position = cloneDeep(position);
726
-
727
- const { subStruct } = parseData.subscriptionEventData;
728
- const triggerData = triggerService.crvUsdHealthRatioTrigger.decode(subStruct.triggerData);
729
- const subData = subDataService.crvUSDPaybackSubData.decode(subStruct.subData);
730
-
731
- _position.strategyData.decoded.triggerData = triggerData;
732
- _position.strategyData.decoded.subData = subData;
733
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.controller, Math.random());
734
- _position.strategy.strategyId = Strategies.Identifiers.Payback;
735
-
736
- return _position;
737
- }
738
-
739
- function parseMorphoBlueLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
740
- const _position = cloneDeep(position);
741
-
742
- const { subStruct, subId, subHash } = parseData.subscriptionEventData;
743
- const { isEnabled } = parseData.strategiesSubsData;
744
- const triggerData = triggerService.morphoBlueRatioTrigger.decode(subStruct.triggerData);
745
- const subData = subDataService.morphoBlueLeverageManagementSubData.decode(subStruct.subData);
746
-
747
- _position.strategyData.decoded.triggerData = triggerData;
748
- _position.strategyData.decoded.subData = subData;
749
-
750
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.marketId);
751
-
752
- const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
753
-
754
- if (isRepay) {
755
- _position.specific = {
756
- triggerRepayRatio: triggerData.ratio,
757
- targetRepayRatio: subData.targetRatio,
758
- repayEnabled: isEnabled,
759
- subId1: Number(subId),
760
- subHashRepay: subHash,
761
- mergeWithId: Strategies.Identifiers.Boost,
762
- };
763
- } else {
764
- _position.specific = {
765
- triggerBoostRatio: triggerData.ratio,
766
- targetBoostRatio: subData.targetRatio,
767
- boostEnabled: isEnabled,
768
- subId2: Number(subId),
769
- subHashBoost: subHash,
770
- mergeId: Strategies.Identifiers.Boost,
771
- };
772
- }
773
-
774
- _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
775
-
776
- return _position;
777
- }
778
-
779
- const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
780
- [ProtocolIdentifiers.StrategiesAutomation.MakerDAO]: {
781
- [Strategies.Identifiers.SavingsLiqProtection]: parseMakerSavingsLiqProtection,
782
- [Strategies.Identifiers.CloseOnPriceToDebt]: parseMakerCloseOnPrice,
783
- [Strategies.Identifiers.CloseOnPriceToColl]: parseMakerCloseOnPrice,
784
- [Strategies.Identifiers.TrailingStopToColl]: parseMakerTrailingStop,
785
- [Strategies.Identifiers.TrailingStopToDebt]: parseMakerTrailingStop,
786
- [Strategies.Identifiers.Repay]: parseMakerLeverageManagement,
787
- [Strategies.Identifiers.Boost]: parseMakerLeverageManagement,
788
- },
789
- [ProtocolIdentifiers.StrategiesAutomation.Liquity]: {
790
- [Strategies.Identifiers.CloseOnPriceToColl]: parseLiquityCloseOnPrice,
791
- [Strategies.Identifiers.TrailingStopToColl]: parseLiquityTrailingStop,
792
- [Strategies.Identifiers.BondProtection]: parseLiquityBondProtection,
793
- [Strategies.Identifiers.Repay]: parseLiquityLeverageManagement,
794
- [Strategies.Identifiers.Boost]: parseLiquityLeverageManagement,
795
- [Strategies.Identifiers.SavingsDsrPayback]: parseLiquitySavingsLiqProtection,
796
- [Strategies.Identifiers.SavingsDsrSupply]: parseLiquitySavingsLiqProtection,
797
- [Strategies.Identifiers.DebtInFrontRepay]: parseLiquityDebtInFrontRepay,
798
- },
799
- [ProtocolIdentifiers.StrategiesAutomation.AaveV2]: {
800
- [Strategies.Identifiers.Repay]: parseAaveV2LeverageManagement,
801
- [Strategies.Identifiers.Boost]: parseAaveV2LeverageManagement,
802
- },
803
- [ProtocolIdentifiers.StrategiesAutomation.AaveV3]: {
804
- [Strategies.Identifiers.Repay]: parseAaveV3LeverageManagement,
805
- [Strategies.Identifiers.Boost]: parseAaveV3LeverageManagement,
806
- [Strategies.Identifiers.CloseToDebt]: parseAaveV3CloseOnPrice,
807
- [Strategies.Identifiers.CloseToDebtWithGasPrice]: parseAaveV3CloseOnPriceWithMaximumGasPrice,
808
- [Strategies.Identifiers.CloseToCollateral]: parseAaveV3CloseOnPrice,
809
- [Strategies.Identifiers.CloseToCollateralWithGasPrice]: parseAaveV3CloseOnPriceWithMaximumGasPrice,
810
- },
811
- [ProtocolIdentifiers.StrategiesAutomation.CompoundV2]: {
812
- [Strategies.Identifiers.Repay]: parseCompoundV2LeverageManagement,
813
- [Strategies.Identifiers.Boost]: parseCompoundV2LeverageManagement,
814
- },
815
- [ProtocolIdentifiers.StrategiesAutomation.CompoundV3]: {
816
- [Strategies.Identifiers.Repay]: parseCompoundV3LeverageManagement,
817
- [Strategies.Identifiers.Boost]: parseCompoundV3LeverageManagement,
818
- [Strategies.Identifiers.EoaRepay]: parseCompoundV3LeverageManagement,
819
- [Strategies.Identifiers.EoaBoost]: parseCompoundV3LeverageManagement,
820
- },
821
- [ProtocolIdentifiers.StrategiesAutomation.ChickenBonds]: {
822
- [Strategies.Identifiers.Rebond]: parseChickenBondsRebond,
823
- },
824
- [ProtocolIdentifiers.StrategiesAutomation.MorphoAaveV2]: {
825
- [Strategies.Identifiers.Repay]: parseMorphoAaveV2LeverageManagement,
826
- [Strategies.Identifiers.Boost]: parseMorphoAaveV2LeverageManagement,
827
- },
828
- [ProtocolIdentifiers.StrategiesAutomation.Exchange]: {
829
- [Strategies.Identifiers.Dca]: parseExchangeDca,
830
- [Strategies.Identifiers.LimitOrder]: parseExchangeLimitOrder,
831
- },
832
- [ProtocolIdentifiers.StrategiesAutomation.Spark]: {
833
- [Strategies.Identifiers.Repay]: parseSparkLeverageManagement,
834
- [Strategies.Identifiers.Boost]: parseSparkLeverageManagement,
835
- [Strategies.Identifiers.CloseToDebt]: parseSparkCloseOnPrice,
836
- [Strategies.Identifiers.CloseToCollateral]: parseSparkCloseOnPrice,
837
- },
838
- [ProtocolIdentifiers.StrategiesAutomation.CrvUSD]: {
839
- [Strategies.Identifiers.Repay]: parseCrvUSDLeverageManagement,
840
- [Strategies.Identifiers.Boost]: parseCrvUSDLeverageManagement,
841
- [Strategies.Identifiers.Payback]: parseCrvUSDPayback,
842
- },
843
- [ProtocolIdentifiers.StrategiesAutomation.MorphoBlue]: {
844
- [Strategies.Identifiers.Repay]: parseMorphoBlueLeverageManagement,
845
- [Strategies.Identifiers.Boost]: parseMorphoBlueLeverageManagement,
846
- },
847
- };
848
-
849
- function getParsingMethod(id: ProtocolIdentifiers.StrategiesAutomation, strategy: BundleOrStrategy) {
850
- return parsingMethodsMapping[id][strategy.strategyId];
851
- }
852
-
853
- export function parseStrategiesAutomatedPosition(parseData: ParseData): Position.Automated | null {
854
- const {
855
- chainId, blockNumber, subscriptionEventData, strategiesSubsData,
856
- } = parseData;
857
- const {
858
- subStruct, proxy, subId, subHash,
859
- } = subscriptionEventData;
860
- const { isEnabled } = strategiesSubsData;
861
-
862
- const id = subStruct.strategyOrBundleId as unknown as StrategyOrBundleIds;
863
-
864
- const strategyOrBundleInfo = (
865
- subStruct.isBundle
866
- ? BUNDLES_INFO[chainId][id as keyof BundleInfoUnion]
867
- : STRATEGIES_INFO[chainId][id as keyof StrategyInfoUnion]
868
- ) as BundleOrStrategy;
869
-
870
- if (!strategyOrBundleInfo) return null;
871
-
872
- const position: Position.Automated = {
873
- isEnabled,
874
- chainId,
875
- subHash,
876
- blockNumber,
877
- positionId: 'positionId parsing not implemented.',
878
- subId: Number(subId),
879
- owner: proxy.toLowerCase(),
880
- protocol: {
881
- ...strategyOrBundleInfo.protocol,
882
- },
883
- strategy: {
884
- isBundle: subStruct.isBundle,
885
- ...strategyOrBundleInfo,
886
- },
887
- strategyData: {
888
- encoded: {
889
- triggerData: subStruct.triggerData,
890
- subData: subStruct.subData,
891
- },
892
- decoded: {
893
- triggerData: null,
894
- subData: null,
895
- },
896
- },
897
- specific: {},
898
- };
899
-
900
- return getParsingMethod(position.protocol.id, position.strategy)(position, parseData, chainId);
901
- }
1
+ import { getAssetInfoByAddress } from '@defisaver/tokens';
2
+ import { cloneDeep } from 'lodash';
3
+
4
+ import { BUNDLES_INFO, STRATEGIES_INFO } from '../constants';
5
+ import type {
6
+ Position, ParseData, StrategiesToProtocolVersionMapping, BundleOrStrategy, StrategyOrBundleIds,
7
+ BundleInfoUnion, StrategyInfoUnion,
8
+ } from '../types';
9
+ import { ChainId, ProtocolIdentifiers, Strategies } from '../types/enums';
10
+
11
+ import {
12
+ getPositionId, getRatioStateInfoForAaveCloseStrategy, isRatioStateOver, wethToEthByAddress,
13
+ } from './utils';
14
+ import * as subDataService from './subDataService';
15
+ import * as triggerService from './triggerService';
16
+
17
+ const SPARK_MARKET_ADDRESSES = {
18
+ [ChainId.Ethereum]: '0x02C3eA4e34C0cBd694D2adFa2c690EECbC1793eE',
19
+ };
20
+
21
+ const AAVE_V3_MARKET_ADDRESSES = {
22
+ [ChainId.Ethereum]: '0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e',
23
+ [ChainId.Optimism]: '0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb',
24
+ [ChainId.Arbitrum]: '0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb',
25
+ };
26
+
27
+ function parseMakerSavingsLiqProtection(position: Position.Automated, parseData: ParseData): Position.Automated {
28
+ const _position = cloneDeep(position);
29
+
30
+ const { subStruct } = parseData.subscriptionEventData;
31
+
32
+ const triggerData = triggerService.makerRatioTrigger.decode(subStruct.triggerData);
33
+ const subData = subDataService.makerRepayFromSavingsSubData.decode(subStruct.subData);
34
+
35
+ _position.strategyData.decoded.triggerData = triggerData;
36
+ _position.strategyData.decoded.subData = subData;
37
+
38
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, subData.vaultId);
39
+
40
+ _position.specific = {
41
+ triggerRepayRatio: Number(triggerData.ratio),
42
+ targetRepayRatio: Number(subData.targetRatio),
43
+ repayEnabled: true,
44
+ boostEnabled: false,
45
+ };
46
+
47
+ return _position;
48
+ }
49
+
50
+ function parseMakerCloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
51
+ const _position = cloneDeep(position);
52
+
53
+ const { subStruct } = parseData.subscriptionEventData;
54
+
55
+ const triggerData = triggerService.chainlinkPriceTrigger.decode(subStruct.triggerData);
56
+ const subData = subDataService.makerCloseSubData.decode(subStruct.subData);
57
+
58
+ _position.strategyData.decoded.triggerData = triggerData;
59
+ _position.strategyData.decoded.subData = subData;
60
+
61
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, subData.vaultId);
62
+
63
+ const isTakeProfit = isRatioStateOver(Number(triggerData.state));
64
+
65
+ _position.strategy.strategyId = isTakeProfit ? Strategies.IdOverrides.TakeProfit : Strategies.IdOverrides.StopLoss;
66
+
67
+ _position.specific = {
68
+ price: triggerData.price,
69
+ closeToAssetAddr: subData.closeToAssetAddr,
70
+ };
71
+
72
+ return _position;
73
+ }
74
+
75
+ function parseMakerTrailingStop(position: Position.Automated, parseData: ParseData): Position.Automated {
76
+ const _position = cloneDeep(position);
77
+
78
+ const { subStruct } = parseData.subscriptionEventData;
79
+
80
+ const triggerData = triggerService.trailingStopTrigger.decode(subStruct.triggerData);
81
+ const subData = subDataService.makerCloseSubData.decode(subStruct.subData);
82
+
83
+ _position.strategyData.decoded.triggerData = triggerData;
84
+ _position.strategyData.decoded.subData = subData;
85
+
86
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, subData.vaultId);
87
+
88
+ _position.strategy.strategyId = Strategies.IdOverrides.TrailingStop;
89
+
90
+ _position.specific = {
91
+ triggerPercentage: Number(triggerData.triggerPercentage),
92
+ roundId: Number(triggerData.roundId),
93
+ closeToAssetAddr: subData.closeToAssetAddr,
94
+ };
95
+
96
+ return _position;
97
+ }
98
+
99
+ function parseMakerLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
100
+ const _position = cloneDeep(position);
101
+
102
+ const { subStruct, subId } = parseData.subscriptionEventData;
103
+ const { isEnabled } = parseData.strategiesSubsData;
104
+
105
+ const triggerData = triggerService.makerRatioTrigger.decode(subStruct.triggerData);
106
+ const subData = subDataService.makerLeverageManagementSubData.decode(subStruct.subData);
107
+
108
+ _position.strategyData.decoded.triggerData = triggerData;
109
+ _position.strategyData.decoded.subData = subData;
110
+
111
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, subData.vaultId);
112
+
113
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
114
+
115
+ if (isRepay) {
116
+ _position.specific = {
117
+ triggerRepayRatio: triggerData.ratio,
118
+ targetRepayRatio: subData.targetRatio,
119
+ repayEnabled: true,
120
+ subId1: Number(subId),
121
+ mergeWithId: Strategies.Identifiers.Boost,
122
+ };
123
+ } else {
124
+ _position.specific = {
125
+ triggerBoostRatio: triggerData.ratio,
126
+ targetBoostRatio: subData.targetRatio,
127
+ boostEnabled: isEnabled,
128
+ subId2: Number(subId),
129
+ mergeId: Strategies.Identifiers.Boost,
130
+ };
131
+ }
132
+
133
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
134
+
135
+ return _position;
136
+ }
137
+
138
+ function parseLiquityCloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
139
+ const _position = cloneDeep(position);
140
+
141
+ const { subStruct } = parseData.subscriptionEventData;
142
+
143
+ const triggerData = triggerService.chainlinkPriceTrigger.decode(subStruct.triggerData);
144
+ const subData = subDataService.liquityCloseSubData.decode(subStruct.subData);
145
+
146
+ _position.strategyData.decoded.triggerData = triggerData;
147
+ _position.strategyData.decoded.subData = subData;
148
+
149
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
150
+
151
+ const isTakeProfit = isRatioStateOver(Number(triggerData.state));
152
+
153
+ _position.strategy.strategyId = isTakeProfit ? Strategies.IdOverrides.TakeProfit : Strategies.IdOverrides.StopLoss;
154
+
155
+ _position.specific = {
156
+ price: triggerData.price,
157
+ closeToAssetAddr: subData.closeToAssetAddr,
158
+ };
159
+
160
+ return _position;
161
+ }
162
+
163
+ function parseLiquityTrailingStop(position: Position.Automated, parseData: ParseData): Position.Automated {
164
+ const _position = cloneDeep(position);
165
+
166
+ const { subStruct } = parseData.subscriptionEventData;
167
+
168
+ const triggerData = triggerService.trailingStopTrigger.decode(subStruct.triggerData);
169
+ const subData = subDataService.liquityCloseSubData.decode(subStruct.subData);
170
+
171
+ _position.strategyData.decoded.triggerData = triggerData;
172
+ _position.strategyData.decoded.subData = subData;
173
+
174
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
175
+
176
+ _position.strategy.strategyId = Strategies.IdOverrides.TrailingStop;
177
+
178
+ _position.specific = {
179
+ triggerPercentage: Number(triggerData.triggerPercentage),
180
+ roundId: Number(triggerData.roundId),
181
+ closeToAssetAddr: subData.closeToAssetAddr,
182
+ };
183
+
184
+ return _position;
185
+ }
186
+
187
+ function parseAaveV2LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
188
+ const _position = cloneDeep(position);
189
+
190
+ const { subStruct, subId } = parseData.subscriptionEventData;
191
+ const { isEnabled } = parseData.strategiesSubsData;
192
+
193
+ const triggerData = triggerService.aaveV2RatioTrigger.decode(subStruct.triggerData);
194
+ const subData = subDataService.aaveV2LeverageManagementSubData.decode(subStruct.subData);
195
+
196
+ _position.strategyData.decoded.triggerData = triggerData;
197
+ _position.strategyData.decoded.subData = subData;
198
+
199
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
200
+
201
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
202
+
203
+ if (isRepay) {
204
+ _position.specific = {
205
+ triggerRepayRatio: triggerData.ratio,
206
+ targetRepayRatio: subData.targetRatio,
207
+ repayEnabled: true,
208
+ subId1: Number(subId),
209
+ mergeWithId: Strategies.Identifiers.Boost,
210
+ };
211
+ } else {
212
+ _position.specific = {
213
+ triggerBoostRatio: triggerData.ratio,
214
+ targetBoostRatio: subData.targetRatio,
215
+ boostEnabled: isEnabled,
216
+ subId2: Number(subId),
217
+ mergeId: Strategies.Identifiers.Boost,
218
+ };
219
+ }
220
+
221
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
222
+
223
+ return _position;
224
+ }
225
+
226
+ function parseAaveV3LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
227
+ const _position = cloneDeep(position);
228
+
229
+ const { subStruct, subId } = parseData.subscriptionEventData;
230
+ const { isEnabled } = parseData.strategiesSubsData;
231
+
232
+ const triggerData = triggerService.aaveV3RatioTrigger.decode(subStruct.triggerData);
233
+ const subData = subDataService.aaveV3LeverageManagementSubData.decode(subStruct.subData);
234
+
235
+ _position.strategyData.decoded.triggerData = triggerData;
236
+ _position.strategyData.decoded.subData = subData;
237
+
238
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
239
+
240
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
241
+
242
+ if (isRepay) {
243
+ _position.specific = {
244
+ triggerRepayRatio: triggerData.ratio,
245
+ targetRepayRatio: subData.targetRatio,
246
+ repayEnabled: true,
247
+ subId1: Number(subId),
248
+ mergeWithId: Strategies.Identifiers.Boost,
249
+ };
250
+ } else {
251
+ _position.specific = {
252
+ triggerBoostRatio: triggerData.ratio,
253
+ targetBoostRatio: subData.targetRatio,
254
+ boostEnabled: isEnabled,
255
+ subId2: Number(subId),
256
+ mergeId: Strategies.Identifiers.Boost,
257
+ };
258
+ }
259
+
260
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
261
+
262
+ return _position;
263
+ }
264
+
265
+ function parseMorphoAaveV2LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
266
+ const _position = cloneDeep(position);
267
+
268
+ const { subStruct, subId } = parseData.subscriptionEventData;
269
+ const { isEnabled } = parseData.strategiesSubsData;
270
+
271
+ const triggerData = triggerService.morphoAaveV2RatioTrigger.decode(subStruct.triggerData);
272
+ const subData = subDataService.morphoAaveV2LeverageManagementSubData.decode(subStruct.subData);
273
+
274
+ _position.strategyData.decoded.triggerData = triggerData;
275
+ _position.strategyData.decoded.subData = subData;
276
+
277
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
278
+
279
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
280
+
281
+ if (isRepay) {
282
+ _position.specific = {
283
+ triggerRepayRatio: triggerData.ratio,
284
+ targetRepayRatio: subData.targetRatio,
285
+ repayEnabled: true,
286
+ subId1: Number(subId),
287
+ mergeWithId: Strategies.Identifiers.Boost,
288
+ };
289
+ } else {
290
+ _position.specific = {
291
+ triggerBoostRatio: triggerData.ratio,
292
+ targetBoostRatio: subData.targetRatio,
293
+ boostEnabled: isEnabled,
294
+ subId2: Number(subId),
295
+ mergeId: Strategies.Identifiers.Boost,
296
+ };
297
+ }
298
+
299
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
300
+
301
+ return _position;
302
+ }
303
+
304
+ function parseAaveV3CloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
305
+ const _position = cloneDeep(position);
306
+
307
+ const { subStruct } = parseData.subscriptionEventData;
308
+
309
+ const triggerData = triggerService.aaveV3QuotePriceTrigger.decode(subStruct.triggerData);
310
+ const subData = subDataService.aaveV3QuotePriceSubData.decode(subStruct.subData);
311
+
312
+ _position.strategyData.decoded.triggerData = triggerData;
313
+ _position.strategyData.decoded.subData = subData;
314
+
315
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, AAVE_V3_MARKET_ADDRESSES[_position.chainId]);
316
+
317
+ _position.specific = {
318
+ collAsset: subData.collAsset,
319
+ collAssetId: subData.collAssetId,
320
+ debtAsset: subData.debtAsset,
321
+ debtAssetId: subData.debtAssetId,
322
+ baseToken: triggerData.baseTokenAddress,
323
+ quoteToken: triggerData.quoteTokenAddress,
324
+ price: triggerData.price,
325
+ ratioState: triggerData.ratioState,
326
+ };
327
+
328
+ const { ratioState } = getRatioStateInfoForAaveCloseStrategy(
329
+ _position.specific.ratioState,
330
+ wethToEthByAddress(_position.specific.collAsset, parseData.chainId),
331
+ wethToEthByAddress(_position.specific.debtAsset, parseData.chainId),
332
+ parseData.chainId,
333
+ );
334
+
335
+ _position.strategy.strategyId = isRatioStateOver(ratioState) ? Strategies.IdOverrides.TakeProfit : Strategies.IdOverrides.StopLoss;
336
+
337
+ return _position;
338
+ }
339
+
340
+ function parseAaveV3CloseOnPriceWithMaximumGasPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
341
+ const _position = cloneDeep(position);
342
+
343
+ const { subStruct } = parseData.subscriptionEventData;
344
+
345
+ const triggerData = triggerService.aaveV3QuotePriceWithMaximumGasPriceTrigger.decode(subStruct.triggerData);
346
+ const subData = subDataService.aaveV3QuotePriceSubData.decode(subStruct.subData);
347
+
348
+ _position.strategyData.decoded.triggerData = triggerData;
349
+ _position.strategyData.decoded.subData = subData;
350
+
351
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, AAVE_V3_MARKET_ADDRESSES[_position.chainId]);
352
+
353
+ _position.specific = {
354
+ collAsset: subData.collAsset,
355
+ collAssetId: subData.collAssetId,
356
+ debtAsset: subData.debtAsset,
357
+ debtAssetId: subData.debtAssetId,
358
+ baseToken: triggerData.baseTokenAddress,
359
+ quoteToken: triggerData.quoteTokenAddress,
360
+ price: triggerData.price,
361
+ maximumGasPrice: triggerData.maximumGasPrice,
362
+ ratioState: triggerData.ratioState,
363
+ };
364
+
365
+ const { ratioState } = getRatioStateInfoForAaveCloseStrategy(
366
+ _position.specific.ratioState,
367
+ wethToEthByAddress(_position.specific.collAsset, parseData.chainId),
368
+ wethToEthByAddress(_position.specific.debtAsset, parseData.chainId),
369
+ parseData.chainId,
370
+ );
371
+
372
+ _position.strategy.strategyId = isRatioStateOver(ratioState)
373
+ ? Strategies.IdOverrides.TakeProfitWithGasPrice
374
+ : Strategies.IdOverrides.StopLossWithGasPrice;
375
+
376
+ return _position;
377
+ }
378
+
379
+ function parseCompoundV2LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
380
+ const _position = cloneDeep(position);
381
+
382
+ const { subStruct, subId } = parseData.subscriptionEventData;
383
+ const { isEnabled } = parseData.strategiesSubsData;
384
+
385
+ const triggerData = triggerService.compoundV2RatioTrigger.decode(subStruct.triggerData);
386
+ const subData = subDataService.compoundV2LeverageManagementSubData.decode(subStruct.subData);
387
+
388
+ _position.strategyData.decoded.triggerData = triggerData;
389
+ _position.strategyData.decoded.subData = subData;
390
+ _position.owner = triggerData.owner.toLowerCase();
391
+
392
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
393
+
394
+ const isRepay = [Strategies.Identifiers.Repay, Strategies.Identifiers.EoaRepay].includes(_position.strategy.strategyId as Strategies.Identifiers);
395
+
396
+ if (isRepay) {
397
+ _position.specific = {
398
+ triggerRepayRatio: triggerData.ratio,
399
+ targetRepayRatio: subData.targetRatio,
400
+ repayEnabled: true,
401
+ subId1: Number(subId),
402
+ mergeWithId: Strategies.Identifiers.Boost,
403
+ };
404
+ } else {
405
+ _position.specific = {
406
+ triggerBoostRatio: triggerData.ratio,
407
+ targetBoostRatio: subData.targetRatio,
408
+ boostEnabled: isEnabled,
409
+ subId2: Number(subId),
410
+ mergeId: Strategies.Identifiers.Boost,
411
+ };
412
+ }
413
+
414
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
415
+
416
+ return _position;
417
+ }
418
+
419
+ function parseCompoundV3LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
420
+ const _position = cloneDeep(position);
421
+
422
+ const { subStruct, subId } = parseData.subscriptionEventData;
423
+ const { isEnabled } = parseData.strategiesSubsData;
424
+
425
+ const subDataDecoder = position.chainId !== 1
426
+ ? subDataService.compoundV3L2LeverageManagementSubData
427
+ : subDataService.compoundV3LeverageManagementSubData;
428
+
429
+ const triggerData = triggerService.compoundV3RatioTrigger.decode(subStruct.triggerData);
430
+ const subData = subDataDecoder.decode(subStruct.subData);
431
+
432
+ _position.strategyData.decoded.triggerData = triggerData;
433
+ _position.strategyData.decoded.subData = subData;
434
+ _position.owner = triggerData.owner.toLowerCase();
435
+
436
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
437
+
438
+ const isRepay = [Strategies.Identifiers.Repay, Strategies.Identifiers.EoaRepay].includes(_position.strategy.strategyId as Strategies.Identifiers);
439
+
440
+ if (isRepay) {
441
+ _position.specific = {
442
+ triggerRepayRatio: triggerData.ratio,
443
+ targetRepayRatio: subData.targetRatio,
444
+ repayEnabled: true,
445
+ subId1: Number(subId),
446
+ mergeWithId: Strategies.Identifiers.Boost,
447
+ };
448
+ } else {
449
+ _position.specific = {
450
+ triggerBoostRatio: triggerData.ratio,
451
+ targetBoostRatio: subData.targetRatio,
452
+ boostEnabled: isEnabled,
453
+ subId2: Number(subId),
454
+ mergeId: Strategies.Identifiers.Boost,
455
+ };
456
+ }
457
+
458
+ const isEOA = _position.strategy.strategyId.includes('eoa');
459
+ _position.strategy.strategyId = isEOA ? Strategies.IdOverrides.EoaLeverageManagement : Strategies.IdOverrides.LeverageManagement;
460
+
461
+
462
+ return _position;
463
+ }
464
+
465
+ function parseChickenBondsRebond(position: Position.Automated, parseData: ParseData): Position.Automated {
466
+ const _position = cloneDeep(position);
467
+
468
+ const { subStruct } = parseData.subscriptionEventData;
469
+
470
+ _position.strategyData.decoded.triggerData = triggerService.cBondsRebondTrigger.decode(subStruct.triggerData);
471
+ _position.strategyData.decoded.subData = subDataService.cBondsRebondSubData.decode(subStruct.subData);
472
+
473
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.strategyData.decoded.triggerData.bondId);
474
+
475
+ return _position;
476
+ }
477
+
478
+ function parseLiquityBondProtection(position: Position.Automated, parseData: ParseData): Position.Automated {
479
+ const _position = cloneDeep(position);
480
+
481
+ const { subStruct } = parseData.subscriptionEventData;
482
+
483
+ const triggerData = triggerService.liquityRatioTrigger.decode(subStruct.triggerData);
484
+
485
+ _position.strategyData.decoded.triggerData = triggerData;
486
+ _position.strategyData.decoded.subData = subDataService.liquityPaybackUsingChickenBondSubData.decode(subStruct.subData);
487
+
488
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
489
+
490
+ _position.specific = {
491
+ triggerRepayRatio: Number(triggerData.ratio),
492
+ targetRepayRatio: Infinity, // Unknown targetRepayRatio, uses all assets from chicken bond until trove min debt (2000LUSD)
493
+ repayEnabled: true,
494
+ };
495
+ return _position;
496
+ }
497
+
498
+ function parseExchangeDca(position: Position.Automated, parseData: ParseData, chainId: ChainId): Position.Automated {
499
+ const _position = cloneDeep(position);
500
+
501
+ const { subStruct } = parseData.subscriptionEventData;
502
+
503
+ _position.strategyData.decoded.triggerData = triggerService.exchangeTimestampTrigger.decode(subStruct.triggerData);
504
+ _position.strategyData.decoded.subData = subDataService.exchangeDcaSubData.decode(subStruct.subData, chainId);
505
+
506
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, Math.random());
507
+
508
+ return _position;
509
+ }
510
+
511
+ function parseExchangeLimitOrder(position: Position.Automated, parseData: ParseData, chainId: ChainId): Position.Automated {
512
+ const _position = cloneDeep(position);
513
+
514
+ const { subStruct } = parseData.subscriptionEventData;
515
+
516
+ _position.strategyData.decoded.subData = subDataService.exchangeLimitOrderSubData.decode(subStruct.subData, chainId);
517
+ const fromTokenDecimals = getAssetInfoByAddress(_position.strategyData.decoded.subData.fromToken, chainId).decimals;
518
+ const toTokenDecimals = getAssetInfoByAddress(_position.strategyData.decoded.subData.toToken, chainId).decimals;
519
+ _position.strategyData.decoded.triggerData = triggerService.exchangeOffchainPriceTrigger.decode(subStruct.triggerData, fromTokenDecimals, toTokenDecimals);
520
+
521
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, Math.random());
522
+
523
+ return _position;
524
+ }
525
+
526
+ function parseLiquityLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
527
+ const _position = cloneDeep(position);
528
+
529
+ const { subStruct, subId } = parseData.subscriptionEventData;
530
+ const { isEnabled } = parseData.strategiesSubsData;
531
+
532
+ const triggerData = triggerService.liquityRatioTrigger.decode(subStruct.triggerData);
533
+ const subData = subDataService.liquityLeverageManagementSubData.decode(subStruct.subData);
534
+
535
+ _position.strategyData.decoded.triggerData = triggerData;
536
+ _position.strategyData.decoded.subData = subData;
537
+
538
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
539
+
540
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
541
+
542
+ if (isRepay) {
543
+ _position.specific = {
544
+ triggerRepayRatio: triggerData.ratio,
545
+ targetRepayRatio: subData.targetRatio,
546
+ repayEnabled: true,
547
+ subId1: Number(subId),
548
+ mergeWithId: Strategies.Identifiers.Boost,
549
+ };
550
+ } else {
551
+ _position.specific = {
552
+ triggerBoostRatio: triggerData.ratio,
553
+ targetBoostRatio: subData.targetRatio,
554
+ boostEnabled: isEnabled,
555
+ subId2: Number(subId),
556
+ mergeId: Strategies.Identifiers.Boost,
557
+ };
558
+ }
559
+
560
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
561
+
562
+ return _position;
563
+ }
564
+
565
+ function parseSparkLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
566
+ const _position = cloneDeep(position);
567
+
568
+ const { subStruct, subId } = parseData.subscriptionEventData;
569
+ const { isEnabled } = parseData.strategiesSubsData;
570
+
571
+ const triggerData = triggerService.sparkRatioTrigger.decode(subStruct.triggerData);
572
+ const subData = subDataService.sparkLeverageManagementSubData.decode(subStruct.subData);
573
+
574
+ _position.strategyData.decoded.triggerData = triggerData;
575
+ _position.strategyData.decoded.subData = subData;
576
+
577
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.market);
578
+
579
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
580
+
581
+ if (isRepay) {
582
+ _position.specific = {
583
+ triggerRepayRatio: triggerData.ratio,
584
+ targetRepayRatio: subData.targetRatio,
585
+ repayEnabled: true,
586
+ subId1: Number(subId),
587
+ mergeWithId: Strategies.Identifiers.Boost,
588
+ };
589
+ } else {
590
+ _position.specific = {
591
+ triggerBoostRatio: triggerData.ratio,
592
+ targetBoostRatio: subData.targetRatio,
593
+ boostEnabled: isEnabled,
594
+ subId2: Number(subId),
595
+ mergeId: Strategies.Identifiers.Boost,
596
+ };
597
+ }
598
+
599
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
600
+
601
+ return _position;
602
+ }
603
+
604
+ function parseSparkCloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
605
+ const _position = cloneDeep(position);
606
+
607
+ const { subStruct } = parseData.subscriptionEventData;
608
+
609
+ const triggerData = triggerService.sparkQuotePriceTrigger.decode(subStruct.triggerData);
610
+ const subData = subDataService.sparkQuotePriceSubData.decode(subStruct.subData);
611
+
612
+ _position.strategyData.decoded.triggerData = triggerData;
613
+ _position.strategyData.decoded.subData = subData;
614
+
615
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, SPARK_MARKET_ADDRESSES[_position.chainId as ChainId.Ethereum]);
616
+
617
+ _position.specific = {
618
+ collAsset: subData.collAsset,
619
+ collAssetId: subData.collAssetId,
620
+ debtAsset: subData.debtAsset,
621
+ debtAssetId: subData.debtAssetId,
622
+ baseToken: triggerData.baseTokenAddress,
623
+ quoteToken: triggerData.quoteTokenAddress,
624
+ price: triggerData.price,
625
+ ratioState: triggerData.ratioState,
626
+ };
627
+
628
+ const { ratioState } = getRatioStateInfoForAaveCloseStrategy(
629
+ _position.specific.ratioState,
630
+ wethToEthByAddress(_position.specific.collAsset, parseData.chainId),
631
+ wethToEthByAddress(_position.specific.debtAsset, parseData.chainId),
632
+ parseData.chainId,
633
+ );
634
+
635
+ _position.strategy.strategyId = isRatioStateOver(ratioState) ? Strategies.IdOverrides.TakeProfit : Strategies.IdOverrides.StopLoss;
636
+
637
+ return _position;
638
+ }
639
+
640
+ function parseLiquitySavingsLiqProtection(position: Position.Automated, parseData: ParseData): Position.Automated {
641
+ const _position = cloneDeep(position);
642
+
643
+ const { subStruct } = parseData.subscriptionEventData;
644
+
645
+ const triggerData = triggerService.liquityRatioTrigger.decode(subStruct.triggerData);
646
+ const subData = subDataService.liquityRepayFromSavingsSubData.decode(subStruct.subData);
647
+
648
+ _position.strategyData.decoded.triggerData = triggerData;
649
+ _position.strategyData.decoded.subData = subData;
650
+
651
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
652
+
653
+ _position.specific = {
654
+ triggerRepayRatio: triggerData.ratio,
655
+ targetRepayRatio: subData.targetRatio,
656
+ repayEnabled: true,
657
+ boostEnabled: false,
658
+ };
659
+
660
+ return _position;
661
+ }
662
+
663
+ function parseLiquityDebtInFrontRepay(position: Position.Automated, parseData: ParseData): Position.Automated {
664
+ const _position = cloneDeep(position);
665
+
666
+ const { subStruct } = parseData.subscriptionEventData;
667
+
668
+ const triggerData = triggerService.liquityDebtInFrontWithLimitTrigger.decode(subStruct.triggerData);
669
+ const subData = subDataService.liquityDebtInFrontRepaySubData.decode(subStruct.subData);
670
+
671
+ _position.strategyData.decoded.triggerData = triggerData;
672
+ _position.strategyData.decoded.subData = subData;
673
+
674
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner);
675
+
676
+ _position.specific = {
677
+ debtInFrontMin: triggerData.debtInFrontMin,
678
+ targetRepayRatioIncrease: subData.targetRatioIncrease,
679
+ };
680
+
681
+ return _position;
682
+ }
683
+
684
+ function parseCrvUSDLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
685
+ const _position = cloneDeep(position);
686
+
687
+ const { subStruct, subId, subHash } = parseData.subscriptionEventData;
688
+ const { isEnabled } = parseData.strategiesSubsData;
689
+ const triggerData = triggerService.crvUSDRatioTrigger.decode(subStruct.triggerData);
690
+ const subData = subDataService.crvUSDLeverageManagementSubData.decode(subStruct.subData);
691
+
692
+ _position.strategyData.decoded.triggerData = triggerData;
693
+ _position.strategyData.decoded.subData = subData;
694
+
695
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.controller);
696
+
697
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
698
+
699
+ if (isRepay) {
700
+ _position.specific = {
701
+ triggerRepayRatio: triggerData.ratio,
702
+ targetRepayRatio: subData.targetRatio,
703
+ repayEnabled: isEnabled,
704
+ subId1: Number(subId),
705
+ subHashRepay: subHash,
706
+ mergeWithId: Strategies.Identifiers.Boost,
707
+ };
708
+ } else {
709
+ _position.specific = {
710
+ triggerBoostRatio: triggerData.ratio,
711
+ targetBoostRatio: subData.targetRatio,
712
+ boostEnabled: isEnabled,
713
+ subId2: Number(subId),
714
+ subHashBoost: subHash,
715
+ mergeId: Strategies.Identifiers.Boost,
716
+ };
717
+ }
718
+
719
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
720
+
721
+ return _position;
722
+ }
723
+
724
+ function parseCrvUSDPayback(position: Position.Automated, parseData: ParseData): Position.Automated {
725
+ const _position = cloneDeep(position);
726
+
727
+ const { subStruct } = parseData.subscriptionEventData;
728
+ const triggerData = triggerService.crvUsdHealthRatioTrigger.decode(subStruct.triggerData);
729
+ const subData = subDataService.crvUSDPaybackSubData.decode(subStruct.subData);
730
+
731
+ _position.strategyData.decoded.triggerData = triggerData;
732
+ _position.strategyData.decoded.subData = subData;
733
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.controller, Math.random());
734
+ _position.strategy.strategyId = Strategies.Identifiers.Payback;
735
+
736
+ return _position;
737
+ }
738
+
739
+ function parseMorphoBlueLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
740
+ const _position = cloneDeep(position);
741
+
742
+ const { subStruct, subId, subHash } = parseData.subscriptionEventData;
743
+ const { isEnabled } = parseData.strategiesSubsData;
744
+ const triggerData = triggerService.morphoBlueRatioTrigger.decode(subStruct.triggerData);
745
+ const subData = subDataService.morphoBlueLeverageManagementSubData.decode(subStruct.subData);
746
+
747
+ _position.strategyData.decoded.triggerData = triggerData;
748
+ _position.strategyData.decoded.subData = subData;
749
+
750
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.marketId);
751
+
752
+ const isRepay = [Strategies.Identifiers.Repay, Strategies.Identifiers.EoaRepay].includes(_position.strategy.strategyId as Strategies.Identifiers);
753
+
754
+ if (isRepay) {
755
+ _position.specific = {
756
+ triggerRepayRatio: triggerData.ratio,
757
+ targetRepayRatio: subData.targetRatio,
758
+ repayEnabled: isEnabled,
759
+ subId1: Number(subId),
760
+ subHashRepay: subHash,
761
+ mergeWithId: Strategies.Identifiers.Boost,
762
+ };
763
+ } else {
764
+ _position.specific = {
765
+ triggerBoostRatio: triggerData.ratio,
766
+ targetBoostRatio: subData.targetRatio,
767
+ boostEnabled: isEnabled,
768
+ subId2: Number(subId),
769
+ subHashBoost: subHash,
770
+ mergeId: Strategies.Identifiers.Boost,
771
+ };
772
+ }
773
+
774
+ const isEOA = _position.strategy.strategyId.includes('eoa');
775
+ _position.strategy.strategyId = isEOA ? Strategies.IdOverrides.EoaLeverageManagement : Strategies.IdOverrides.LeverageManagement;
776
+
777
+
778
+ return _position;
779
+ }
780
+
781
+ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
782
+ [ProtocolIdentifiers.StrategiesAutomation.MakerDAO]: {
783
+ [Strategies.Identifiers.SavingsLiqProtection]: parseMakerSavingsLiqProtection,
784
+ [Strategies.Identifiers.CloseOnPriceToDebt]: parseMakerCloseOnPrice,
785
+ [Strategies.Identifiers.CloseOnPriceToColl]: parseMakerCloseOnPrice,
786
+ [Strategies.Identifiers.TrailingStopToColl]: parseMakerTrailingStop,
787
+ [Strategies.Identifiers.TrailingStopToDebt]: parseMakerTrailingStop,
788
+ [Strategies.Identifiers.Repay]: parseMakerLeverageManagement,
789
+ [Strategies.Identifiers.Boost]: parseMakerLeverageManagement,
790
+ },
791
+ [ProtocolIdentifiers.StrategiesAutomation.Liquity]: {
792
+ [Strategies.Identifiers.CloseOnPriceToColl]: parseLiquityCloseOnPrice,
793
+ [Strategies.Identifiers.TrailingStopToColl]: parseLiquityTrailingStop,
794
+ [Strategies.Identifiers.BondProtection]: parseLiquityBondProtection,
795
+ [Strategies.Identifiers.Repay]: parseLiquityLeverageManagement,
796
+ [Strategies.Identifiers.Boost]: parseLiquityLeverageManagement,
797
+ [Strategies.Identifiers.SavingsDsrPayback]: parseLiquitySavingsLiqProtection,
798
+ [Strategies.Identifiers.SavingsDsrSupply]: parseLiquitySavingsLiqProtection,
799
+ [Strategies.Identifiers.DebtInFrontRepay]: parseLiquityDebtInFrontRepay,
800
+ },
801
+ [ProtocolIdentifiers.StrategiesAutomation.AaveV2]: {
802
+ [Strategies.Identifiers.Repay]: parseAaveV2LeverageManagement,
803
+ [Strategies.Identifiers.Boost]: parseAaveV2LeverageManagement,
804
+ },
805
+ [ProtocolIdentifiers.StrategiesAutomation.AaveV3]: {
806
+ [Strategies.Identifiers.Repay]: parseAaveV3LeverageManagement,
807
+ [Strategies.Identifiers.Boost]: parseAaveV3LeverageManagement,
808
+ [Strategies.Identifiers.CloseToDebt]: parseAaveV3CloseOnPrice,
809
+ [Strategies.Identifiers.CloseToDebtWithGasPrice]: parseAaveV3CloseOnPriceWithMaximumGasPrice,
810
+ [Strategies.Identifiers.CloseToCollateral]: parseAaveV3CloseOnPrice,
811
+ [Strategies.Identifiers.CloseToCollateralWithGasPrice]: parseAaveV3CloseOnPriceWithMaximumGasPrice,
812
+ },
813
+ [ProtocolIdentifiers.StrategiesAutomation.CompoundV2]: {
814
+ [Strategies.Identifiers.Repay]: parseCompoundV2LeverageManagement,
815
+ [Strategies.Identifiers.Boost]: parseCompoundV2LeverageManagement,
816
+ },
817
+ [ProtocolIdentifiers.StrategiesAutomation.CompoundV3]: {
818
+ [Strategies.Identifiers.Repay]: parseCompoundV3LeverageManagement,
819
+ [Strategies.Identifiers.Boost]: parseCompoundV3LeverageManagement,
820
+ [Strategies.Identifiers.EoaRepay]: parseCompoundV3LeverageManagement,
821
+ [Strategies.Identifiers.EoaBoost]: parseCompoundV3LeverageManagement,
822
+ },
823
+ [ProtocolIdentifiers.StrategiesAutomation.ChickenBonds]: {
824
+ [Strategies.Identifiers.Rebond]: parseChickenBondsRebond,
825
+ },
826
+ [ProtocolIdentifiers.StrategiesAutomation.MorphoAaveV2]: {
827
+ [Strategies.Identifiers.Repay]: parseMorphoAaveV2LeverageManagement,
828
+ [Strategies.Identifiers.Boost]: parseMorphoAaveV2LeverageManagement,
829
+ },
830
+ [ProtocolIdentifiers.StrategiesAutomation.Exchange]: {
831
+ [Strategies.Identifiers.Dca]: parseExchangeDca,
832
+ [Strategies.Identifiers.LimitOrder]: parseExchangeLimitOrder,
833
+ },
834
+ [ProtocolIdentifiers.StrategiesAutomation.Spark]: {
835
+ [Strategies.Identifiers.Repay]: parseSparkLeverageManagement,
836
+ [Strategies.Identifiers.Boost]: parseSparkLeverageManagement,
837
+ [Strategies.Identifiers.CloseToDebt]: parseSparkCloseOnPrice,
838
+ [Strategies.Identifiers.CloseToCollateral]: parseSparkCloseOnPrice,
839
+ },
840
+ [ProtocolIdentifiers.StrategiesAutomation.CrvUSD]: {
841
+ [Strategies.Identifiers.Repay]: parseCrvUSDLeverageManagement,
842
+ [Strategies.Identifiers.Boost]: parseCrvUSDLeverageManagement,
843
+ [Strategies.Identifiers.Payback]: parseCrvUSDPayback,
844
+ },
845
+ [ProtocolIdentifiers.StrategiesAutomation.MorphoBlue]: {
846
+ [Strategies.Identifiers.Repay]: parseMorphoBlueLeverageManagement,
847
+ [Strategies.Identifiers.Boost]: parseMorphoBlueLeverageManagement,
848
+ [Strategies.Identifiers.EoaRepay]: parseMorphoBlueLeverageManagement,
849
+ [Strategies.Identifiers.EoaBoost]: parseMorphoBlueLeverageManagement,
850
+ },
851
+ };
852
+
853
+ function getParsingMethod(id: ProtocolIdentifiers.StrategiesAutomation, strategy: BundleOrStrategy) {
854
+ return parsingMethodsMapping[id][strategy.strategyId];
855
+ }
856
+
857
+ export function parseStrategiesAutomatedPosition(parseData: ParseData): Position.Automated | null {
858
+ const {
859
+ chainId, blockNumber, subscriptionEventData, strategiesSubsData,
860
+ } = parseData;
861
+ const {
862
+ subStruct, proxy, subId, subHash,
863
+ } = subscriptionEventData;
864
+ const { isEnabled } = strategiesSubsData;
865
+
866
+ const id = subStruct.strategyOrBundleId as unknown as StrategyOrBundleIds;
867
+
868
+ const strategyOrBundleInfo = (
869
+ subStruct.isBundle
870
+ ? BUNDLES_INFO[chainId][id as keyof BundleInfoUnion]
871
+ : STRATEGIES_INFO[chainId][id as keyof StrategyInfoUnion]
872
+ ) as BundleOrStrategy;
873
+
874
+ if (!strategyOrBundleInfo) return null;
875
+
876
+ const position: Position.Automated = {
877
+ isEnabled,
878
+ chainId,
879
+ subHash,
880
+ blockNumber,
881
+ positionId: 'positionId parsing not implemented.',
882
+ subId: Number(subId),
883
+ owner: proxy.toLowerCase(),
884
+ protocol: {
885
+ ...strategyOrBundleInfo.protocol,
886
+ },
887
+ strategy: {
888
+ isBundle: subStruct.isBundle,
889
+ ...strategyOrBundleInfo,
890
+ },
891
+ strategyData: {
892
+ encoded: {
893
+ triggerData: subStruct.triggerData,
894
+ subData: subStruct.subData,
895
+ },
896
+ decoded: {
897
+ triggerData: null,
898
+ subData: null,
899
+ },
900
+ },
901
+ specific: {},
902
+ };
903
+
904
+ return getParsingMethod(position.protocol.id, position.strategy)(position, parseData, chainId);
905
+ }