@defisaver/automation-sdk 3.3.6 → 3.3.7-morpho-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/cjs/constants/index.js +20 -10
  2. package/cjs/services/strategiesService.js +41 -14
  3. package/cjs/services/strategySubService.d.ts +2 -11
  4. package/cjs/services/strategySubService.js +12 -5
  5. package/cjs/services/strategySubService.test.js +38 -72
  6. package/cjs/services/subDataService.d.ts +24 -9
  7. package/cjs/services/subDataService.js +63 -20
  8. package/cjs/services/subDataService.test.js +52 -72
  9. package/cjs/services/triggerService.d.ts +19 -9
  10. package/cjs/services/triggerService.js +40 -19
  11. package/cjs/services/triggerService.test.js +48 -46
  12. package/cjs/services/utils.test.js +0 -77
  13. package/cjs/types/enums.d.ts +7 -5
  14. package/cjs/types/enums.js +4 -2
  15. package/esm/constants/index.js +20 -10
  16. package/esm/services/strategiesService.js +41 -14
  17. package/esm/services/strategySubService.d.ts +2 -11
  18. package/esm/services/strategySubService.js +12 -5
  19. package/esm/services/strategySubService.test.js +39 -73
  20. package/esm/services/subDataService.d.ts +24 -9
  21. package/esm/services/subDataService.js +62 -19
  22. package/esm/services/subDataService.test.js +52 -72
  23. package/esm/services/triggerService.d.ts +19 -9
  24. package/esm/services/triggerService.js +39 -18
  25. package/esm/services/triggerService.test.js +49 -47
  26. package/esm/services/utils.test.js +1 -52
  27. package/esm/types/enums.d.ts +7 -5
  28. package/esm/types/enums.js +4 -2
  29. package/package.json +1 -1
  30. package/src/constants/index.ts +20 -12
  31. package/src/services/strategiesService.ts +55 -22
  32. package/src/services/strategySubService.test.ts +59 -94
  33. package/src/services/strategySubService.ts +36 -16
  34. package/src/services/subDataService.test.ts +60 -78
  35. package/src/services/subDataService.ts +92 -31
  36. package/src/services/triggerService.test.ts +53 -51
  37. package/src/services/triggerService.ts +61 -26
  38. package/src/services/utils.test.ts +0 -59
  39. package/src/types/enums.ts +4 -2
@@ -1,11 +1,8 @@
1
1
  import { expect } from 'chai';
2
- import * as web3Utils from 'web3-utils';
3
- import AbiCoder from 'web3-eth-abi';
4
2
  import { getAssetInfo } from '@defisaver/tokens';
5
3
  import { ChainId, ProtocolIdentifiers, RatioState } from '../types/enums';
6
- import { sparkEncode } from './strategySubService';
7
4
  import '../configuration';
8
- import { addToArrayIf, addToObjectIf, compareAddresses, compareSubHashes, encodeSubId, ethToWeth, getRatioStateInfoForAaveCloseStrategy, isAddress, isDefined, isEmptyBytes, isRatioStateOver, isRatioStateUnder, isUndefined, ratioPercentageToWei, requireAddress, requireAddresses, weiToRatioPercentage, wethToEth, wethToEthByAddress, getPositionId, } from './utils';
5
+ import { addToArrayIf, addToObjectIf, compareAddresses, encodeSubId, ethToWeth, getRatioStateInfoForAaveCloseStrategy, isAddress, isDefined, isEmptyBytes, isRatioStateOver, isRatioStateUnder, isUndefined, ratioPercentageToWei, requireAddress, requireAddresses, weiToRatioPercentage, wethToEth, wethToEthByAddress, getPositionId, } from './utils';
9
6
  describe('Feature: utils.ts', () => {
10
7
  describe('When testing utils.isDefined()', () => {
11
8
  const examples = [
@@ -139,54 +136,6 @@ describe('Feature: utils.ts', () => {
139
136
  });
140
137
  });
141
138
  });
142
- describe('When testing utils.compareSubHashes()', () => {
143
- const subDataToEncodeOne = [
144
- 12,
145
- false,
146
- {
147
- baseTokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
148
- quoteTokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
149
- price: 100,
150
- ratioState: 1,
151
- },
152
- {
153
- collAsset: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
154
- collAssetId: 2,
155
- debtAsset: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
156
- debtAssetId: 3,
157
- },
158
- ];
159
- const subDataToEncodeTwo = [
160
- 13,
161
- true,
162
- {
163
- baseTokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
164
- quoteTokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
165
- price: 100,
166
- ratioState: 2,
167
- },
168
- {
169
- collAsset: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
170
- collAssetId: 2,
171
- debtAsset: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
172
- debtAssetId: 3,
173
- },
174
- ];
175
- // @ts-ignore
176
- const encodedSubDataOne = sparkEncode.closeToAsset(...subDataToEncodeOne);
177
- // @ts-ignore
178
- const encodedSubDataTwo = sparkEncode.closeToAsset(...subDataToEncodeTwo);
179
- const encodedParams = web3Utils.keccak256(AbiCoder.encodeParameter('(uint64,bool,bytes[],bytes32[])', encodedSubDataOne));
180
- const examples = [
181
- [true, [encodedParams, encodedSubDataOne]],
182
- [false, [encodedParams, encodedSubDataTwo]],
183
- ];
184
- examples.forEach(([expected, actual]) => {
185
- it(`Given ${actual} should return expected value: ${expected}`, () => {
186
- expect(compareSubHashes(...actual)).to.equal(expected);
187
- });
188
- });
189
- });
190
139
  describe('When testing utils.encodeSubId()', () => {
191
140
  const examples = [
192
141
  ['00000001', '1'],
@@ -171,8 +171,6 @@ export declare namespace Bundles {
171
171
  LIQUITY_BOOST = 17,
172
172
  SPARK_REPAY = 18,
173
173
  SPARK_BOOST = 19,
174
- SPARK_CLOSE_TO_DEBT = -21231230,
175
- SPARK_CLOSE_TO_COLLATERAL = -21231231,
176
174
  AAVE_V2_REPAY = 22,
177
175
  AAVE_V2_BOOST = 23,
178
176
  COMP_V2_REPAY = 20,
@@ -207,7 +205,9 @@ export declare namespace Bundles {
207
205
  AAVE_V3_EOA_BOOST = 53,
208
206
  AAVE_V3_EOA_REPAY_ON_PRICE = 54,
209
207
  AAVE_V3_EOA_BOOST_ON_PRICE = 55,
210
- AAVE_V3_EOA_CLOSE = 56
208
+ AAVE_V3_EOA_CLOSE = 56,
209
+ SPARK_CLOSE = 57,
210
+ MORPHO_BLUE_CLOSE = 58
211
211
  }
212
212
  enum OptimismIds {
213
213
  AAVE_V3_REPAY = 0,
@@ -248,7 +248,8 @@ export declare namespace Bundles {
248
248
  AAVE_V3_EOA_BOOST = 24,
249
249
  AAVE_V3_EOA_REPAY_ON_PRICE = 25,
250
250
  AAVE_V3_EOA_BOOST_ON_PRICE = 26,
251
- AAVE_V3_EOA_CLOSE = 27
251
+ AAVE_V3_EOA_CLOSE = 27,
252
+ MORPHO_BLUE_CLOSE = 28
252
253
  }
253
254
  enum ArbitrumIds {
254
255
  AAVE_V3_REPAY = 0,
@@ -278,6 +279,7 @@ export declare namespace Bundles {
278
279
  MORPHO_BLUE_BOOST = 24,
279
280
  MORPHO_BLUE_BOOST_ON_PRICE = 25,
280
281
  MORPHO_BLUE_EOA_REPAY = 26,
281
- MORPHO_BLUE_EOA_BOOST = 27
282
+ MORPHO_BLUE_EOA_BOOST = 27,
283
+ MORPHO_BLUE_CLOSE = 28
282
284
  }
283
285
  }
@@ -191,8 +191,6 @@ export var Bundles;
191
191
  MainnetIds[MainnetIds["LIQUITY_BOOST"] = 17] = "LIQUITY_BOOST";
192
192
  MainnetIds[MainnetIds["SPARK_REPAY"] = 18] = "SPARK_REPAY";
193
193
  MainnetIds[MainnetIds["SPARK_BOOST"] = 19] = "SPARK_BOOST";
194
- MainnetIds[MainnetIds["SPARK_CLOSE_TO_DEBT"] = -21231230] = "SPARK_CLOSE_TO_DEBT";
195
- MainnetIds[MainnetIds["SPARK_CLOSE_TO_COLLATERAL"] = -21231231] = "SPARK_CLOSE_TO_COLLATERAL";
196
194
  MainnetIds[MainnetIds["AAVE_V2_REPAY"] = 22] = "AAVE_V2_REPAY";
197
195
  MainnetIds[MainnetIds["AAVE_V2_BOOST"] = 23] = "AAVE_V2_BOOST";
198
196
  MainnetIds[MainnetIds["COMP_V2_REPAY"] = 20] = "COMP_V2_REPAY";
@@ -228,6 +226,8 @@ export var Bundles;
228
226
  MainnetIds[MainnetIds["AAVE_V3_EOA_REPAY_ON_PRICE"] = 54] = "AAVE_V3_EOA_REPAY_ON_PRICE";
229
227
  MainnetIds[MainnetIds["AAVE_V3_EOA_BOOST_ON_PRICE"] = 55] = "AAVE_V3_EOA_BOOST_ON_PRICE";
230
228
  MainnetIds[MainnetIds["AAVE_V3_EOA_CLOSE"] = 56] = "AAVE_V3_EOA_CLOSE";
229
+ MainnetIds[MainnetIds["SPARK_CLOSE"] = 57] = "SPARK_CLOSE";
230
+ MainnetIds[MainnetIds["MORPHO_BLUE_CLOSE"] = 58] = "MORPHO_BLUE_CLOSE";
231
231
  })(MainnetIds = Bundles.MainnetIds || (Bundles.MainnetIds = {}));
232
232
  let OptimismIds;
233
233
  (function (OptimismIds) {
@@ -271,6 +271,7 @@ export var Bundles;
271
271
  BaseIds[BaseIds["AAVE_V3_EOA_REPAY_ON_PRICE"] = 25] = "AAVE_V3_EOA_REPAY_ON_PRICE";
272
272
  BaseIds[BaseIds["AAVE_V3_EOA_BOOST_ON_PRICE"] = 26] = "AAVE_V3_EOA_BOOST_ON_PRICE";
273
273
  BaseIds[BaseIds["AAVE_V3_EOA_CLOSE"] = 27] = "AAVE_V3_EOA_CLOSE";
274
+ BaseIds[BaseIds["MORPHO_BLUE_CLOSE"] = 28] = "MORPHO_BLUE_CLOSE";
274
275
  })(BaseIds = Bundles.BaseIds || (Bundles.BaseIds = {}));
275
276
  let ArbitrumIds;
276
277
  (function (ArbitrumIds) {
@@ -302,5 +303,6 @@ export var Bundles;
302
303
  ArbitrumIds[ArbitrumIds["MORPHO_BLUE_BOOST_ON_PRICE"] = 25] = "MORPHO_BLUE_BOOST_ON_PRICE";
303
304
  ArbitrumIds[ArbitrumIds["MORPHO_BLUE_EOA_REPAY"] = 26] = "MORPHO_BLUE_EOA_REPAY";
304
305
  ArbitrumIds[ArbitrumIds["MORPHO_BLUE_EOA_BOOST"] = 27] = "MORPHO_BLUE_EOA_BOOST";
306
+ ArbitrumIds[ArbitrumIds["MORPHO_BLUE_CLOSE"] = 28] = "MORPHO_BLUE_CLOSE";
305
307
  })(ArbitrumIds = Bundles.ArbitrumIds || (Bundles.ArbitrumIds = {}));
306
308
  })(Bundles || (Bundles = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/automation-sdk",
3
- "version": "3.3.6",
3
+ "version": "3.3.7-morpho-dev",
4
4
  "description": "",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./esm/index.js",
@@ -331,16 +331,6 @@ export const MAINNET_BUNDLES_INFO: MainnetBundleInfo = {
331
331
  strategyId: Strategies.Identifiers.Boost,
332
332
  protocol: PROTOCOLS.Spark,
333
333
  },
334
- [Bundles.MainnetIds.SPARK_CLOSE_TO_DEBT]: {
335
- strategyOrBundleId: Bundles.MainnetIds.SPARK_CLOSE_TO_DEBT,
336
- strategyId: Strategies.Identifiers.CloseToDebt,
337
- protocol: PROTOCOLS.Spark,
338
- },
339
- [Bundles.MainnetIds.SPARK_CLOSE_TO_COLLATERAL]: {
340
- strategyOrBundleId: Bundles.MainnetIds.SPARK_CLOSE_TO_COLLATERAL,
341
- strategyId: Strategies.Identifiers.CloseToCollateral,
342
- protocol: PROTOCOLS.Spark,
343
- },
344
334
  [Bundles.MainnetIds.AAVE_V2_REPAY]: {
345
335
  strategyOrBundleId: Bundles.MainnetIds.AAVE_V2_REPAY,
346
336
  strategyId: Strategies.Identifiers.Repay,
@@ -496,7 +486,16 @@ export const MAINNET_BUNDLES_INFO: MainnetBundleInfo = {
496
486
  strategyId: Strategies.Identifiers.EoaCloseOnPrice,
497
487
  protocol: PROTOCOLS.AaveV3,
498
488
  },
499
-
489
+ [Bundles.MainnetIds.SPARK_CLOSE]: {
490
+ strategyOrBundleId: Bundles.MainnetIds.SPARK_CLOSE,
491
+ strategyId: Strategies.Identifiers.CloseOnPrice,
492
+ protocol: PROTOCOLS.Spark,
493
+ },
494
+ [Bundles.MainnetIds.MORPHO_BLUE_CLOSE]: {
495
+ strategyOrBundleId: Bundles.MainnetIds.MORPHO_BLUE_CLOSE,
496
+ strategyId: Strategies.Identifiers.CloseOnPrice,
497
+ protocol: PROTOCOLS.MorphoBlue,
498
+ },
500
499
  };
501
500
 
502
501
  export const OPTIMISM_BUNDLES_INFO: OptimismBundleInfo = {
@@ -689,7 +688,11 @@ export const BASE_BUNDLES_INFO: BaseBundleInfo = {
689
688
  strategyId: Strategies.Identifiers.EoaCloseOnPrice,
690
689
  protocol: PROTOCOLS.AaveV3,
691
690
  },
692
-
691
+ [Bundles.BaseIds.MORPHO_BLUE_CLOSE]: {
692
+ strategyOrBundleId: Bundles.BaseIds.MORPHO_BLUE_CLOSE,
693
+ strategyId: Strategies.Identifiers.CloseOnPrice,
694
+ protocol: PROTOCOLS.MorphoBlue,
695
+ },
693
696
  };
694
697
 
695
698
  export const ARBITRUM_BUNDLES_INFO: ArbitrumBundleInfo = {
@@ -833,6 +836,11 @@ export const ARBITRUM_BUNDLES_INFO: ArbitrumBundleInfo = {
833
836
  strategyId: Strategies.Identifiers.EoaBoost,
834
837
  protocol: PROTOCOLS.MorphoBlue,
835
838
  },
839
+ [Bundles.ArbitrumIds.MORPHO_BLUE_CLOSE]: {
840
+ strategyOrBundleId: Bundles.ArbitrumIds.MORPHO_BLUE_CLOSE,
841
+ strategyId: Strategies.Identifiers.CloseOnPrice,
842
+ protocol: PROTOCOLS.MorphoBlue,
843
+ },
836
844
  };
837
845
 
838
846
  export const BUNDLES_INFO: BundlesInfo = {
@@ -17,10 +17,6 @@ import * as triggerService from './triggerService';
17
17
 
18
18
  const web3 = new Web3();
19
19
 
20
- const SPARK_MARKET_ADDRESSES = {
21
- [ChainId.Ethereum]: '0x02C3eA4e34C0cBd694D2adFa2c690EECbC1793eE',
22
- };
23
-
24
20
  const AAVE_V3_MARKET_ADDRESSES = {
25
21
  [ChainId.Ethereum]: '0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e',
26
22
  [ChainId.Optimism]: '0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb',
@@ -791,34 +787,29 @@ function parseSparkCloseOnPrice(position: Position.Automated, parseData: ParseDa
791
787
 
792
788
  const { subStruct } = parseData.subscriptionEventData;
793
789
 
794
- const triggerData = triggerService.sparkQuotePriceTrigger.decode(subStruct.triggerData);
795
- const subData = subDataService.sparkQuotePriceSubData.decode(subStruct.subData);
790
+ const triggerData = triggerService.sparkQuotePriceRangeTrigger.decode(subStruct.triggerData);
791
+ const subData = subDataService.sparkCloseGenericSubData.decode(subStruct.subData);
796
792
 
797
793
  _position.strategyData.decoded.triggerData = triggerData;
798
794
  _position.strategyData.decoded.subData = subData;
799
795
 
800
- _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, SPARK_MARKET_ADDRESSES[_position.chainId as ChainId.Ethereum]);
796
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, subData.marketAddr);
797
+
798
+ const { takeProfitType, stopLossType } = getStopLossAndTakeProfitTypeByCloseStrategyType(+subData.closeType);
801
799
 
802
800
  _position.specific = {
803
801
  collAsset: subData.collAsset,
804
802
  collAssetId: subData.collAssetId,
805
803
  debtAsset: subData.debtAsset,
806
804
  debtAssetId: subData.debtAssetId,
807
- baseToken: triggerData.baseTokenAddress,
808
- quoteToken: triggerData.quoteTokenAddress,
809
- price: triggerData.price,
810
- ratioState: triggerData.ratioState,
805
+ baseToken: triggerData.collToken,
806
+ quoteToken: triggerData.debtToken,
807
+ stopLossPrice: triggerData.lowerPrice,
808
+ takeProfitPrice: triggerData.upperPrice,
809
+ stopLossType,
810
+ takeProfitType,
811
811
  };
812
812
 
813
- const { ratioState } = getRatioStateInfoForAaveCloseStrategy(
814
- _position.specific.ratioState,
815
- wethToEthByAddress(_position.specific.collAsset, parseData.chainId),
816
- wethToEthByAddress(_position.specific.debtAsset, parseData.chainId),
817
- parseData.chainId,
818
- );
819
-
820
- _position.strategy.strategyId = isRatioStateOver(ratioState) ? Strategies.IdOverrides.TakeProfit : Strategies.IdOverrides.StopLoss;
821
-
822
813
  return _position;
823
814
  }
824
815
 
@@ -999,6 +990,48 @@ function parseMorphoBlueLeverageManagementOnPrice(position: Position.Automated,
999
990
  return _position;
1000
991
  }
1001
992
 
993
+ function parseMorphoBlueCloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
994
+ const _position = cloneDeep(position);
995
+
996
+ const { subStruct } = parseData.subscriptionEventData;
997
+
998
+ const triggerData = triggerService.morphoBluePriceRangeTrigger.decode(subStruct.triggerData);
999
+ const subData = subDataService.morphoBlueCloseOnPriceSubData.decode(subStruct.subData);
1000
+
1001
+ _position.strategyData.decoded.triggerData = triggerData;
1002
+ _position.strategyData.decoded.subData = subData;
1003
+
1004
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, Math.random());
1005
+
1006
+ const marketIdEncodedData = web3.eth.abi.encodeParameters(
1007
+ ['address', 'address', 'address', 'address', 'uint256'],
1008
+ [
1009
+ subData.loanToken,
1010
+ subData.collToken,
1011
+ subData.oracle,
1012
+ subData.irm,
1013
+ subData.lltv,
1014
+ ],
1015
+ );
1016
+
1017
+ const marketId = web3.utils.keccak256(marketIdEncodedData);
1018
+
1019
+ const { takeProfitType, stopLossType } = getStopLossAndTakeProfitTypeByCloseStrategyType(+subData.closeType);
1020
+
1021
+ _position.specific = {
1022
+ subHash: _position.subHash,
1023
+ marketId,
1024
+ collAsset: subData.collToken,
1025
+ debtAsset: subData.loanToken,
1026
+ stopLossPrice: triggerData.lowerPrice,
1027
+ takeProfitPrice: triggerData.upperPrice,
1028
+ stopLossType,
1029
+ takeProfitType,
1030
+ };
1031
+
1032
+ return _position;
1033
+ }
1034
+
1002
1035
  function parseLiquityV2CloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
1003
1036
  const _position = cloneDeep(position);
1004
1037
 
@@ -1204,8 +1237,7 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
1204
1237
  [ProtocolIdentifiers.StrategiesAutomation.Spark]: {
1205
1238
  [Strategies.Identifiers.Repay]: parseSparkLeverageManagement,
1206
1239
  [Strategies.Identifiers.Boost]: parseSparkLeverageManagement,
1207
- [Strategies.Identifiers.CloseToDebt]: parseSparkCloseOnPrice,
1208
- [Strategies.Identifiers.CloseToCollateral]: parseSparkCloseOnPrice,
1240
+ [Strategies.Identifiers.CloseOnPrice]: parseSparkCloseOnPrice,
1209
1241
  },
1210
1242
  [ProtocolIdentifiers.StrategiesAutomation.CrvUSD]: {
1211
1243
  [Strategies.Identifiers.Repay]: parseCrvUSDLeverageManagement,
@@ -1218,6 +1250,7 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
1218
1250
  [Strategies.Identifiers.EoaRepay]: parseMorphoBlueLeverageManagement,
1219
1251
  [Strategies.Identifiers.EoaBoost]: parseMorphoBlueLeverageManagement,
1220
1252
  [Strategies.Identifiers.BoostOnPrice]: parseMorphoBlueLeverageManagementOnPrice,
1253
+ [Strategies.Identifiers.CloseOnPrice]: parseMorphoBlueCloseOnPrice,
1221
1254
  },
1222
1255
  [ProtocolIdentifiers.StrategiesAutomation.FluidT1]: {
1223
1256
  [Strategies.Identifiers.Repay]: parseFluidT1LeverageManagement,
@@ -18,8 +18,9 @@ import {
18
18
  compoundV3Encode,
19
19
  morphoAaveV2Encode,
20
20
  exchangeEncode,
21
- sparkEncode,
22
- crvUSDEncode, compoundV3L2Encode, morphoBlueEncode,
21
+ crvUSDEncode,
22
+ compoundV3L2Encode,
23
+ morphoBlueEncode,
23
24
  } from './strategySubService';
24
25
 
25
26
  describe('Feature: strategySubService.ts', () => {
@@ -1387,97 +1388,6 @@ describe('Feature: strategySubService.ts', () => {
1387
1388
  });
1388
1389
  });
1389
1390
 
1390
- describe('When testing strategySubService.sparkEncode', () => {
1391
- describe('leverageManagement()', () => {
1392
- const examples: Array<[
1393
- string,
1394
- [triggerRepayRatio: number, triggerBoostRatio: number, targetBoostRatio: number, targetRepayRatio: number, boostEnabled: boolean],
1395
- ]> = [
1396
- [
1397
- '0x000000000000000016345785d8a0000000000000000000001e87f85809dc0000000000000000000018fae27693b4000000000000000000001a5e27eef13e000001',
1398
- [160, 220, 180, 190, true]
1399
- ],
1400
- [
1401
- '0x000000000000000016345785d8a0000000000000000000001bc16d674ec80000000000000000000018fae27693b4000000000000000000001a5e27eef13e000000',
1402
- [160, 200, 180, 190, false]
1403
- ],
1404
- ];
1405
-
1406
- examples.forEach(([expected, actual]) => {
1407
- it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
1408
- expect(sparkEncode.leverageManagement(...actual)).to.eql(expected);
1409
- });
1410
- });
1411
- });
1412
-
1413
- describe('closeToAsset()', () => {
1414
- const examples: Array<[
1415
- [StrategyOrBundleIds, boolean, TriggerData, SubData],
1416
- [
1417
- strategyOrBundleId: number,
1418
- isBundle: boolean,
1419
- triggerData: {
1420
- baseTokenAddress: EthereumAddress, quoteTokenAddress: EthereumAddress, price: number, ratioState: RatioState
1421
- },
1422
- subData: {
1423
- collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number,
1424
- },
1425
- ]
1426
- ]> = [
1427
- [
1428
- [
1429
- Bundles.MainnetIds.SPARK_CLOSE_TO_COLLATERAL,
1430
- true,
1431
- ['0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000026e1f9c6000000000000000000000000000000000000000000000000000000000000000000'],
1432
- [
1433
- '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', '0x0000000000000000000000000000000000000000000000000000000000000015',
1434
- '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f', '0x0000000000000000000000000000000000000000000000000000000000000020',
1435
- '0x0000000000000000000000000000000000000000000000000000000000000000',
1436
- ],
1437
- ],
1438
- [
1439
- Bundles.MainnetIds.SPARK_CLOSE_TO_COLLATERAL,
1440
- true,
1441
- {
1442
- baseTokenAddress: getAssetInfo('WETH').address, quoteTokenAddress: getAssetInfo('DAI').address, price: 1670, ratioState: RatioState.OVER
1443
- },
1444
- {
1445
- collAsset: getAssetInfo('WETH').address, collAssetId: 21, debtAsset: getAssetInfo('DAI').address, debtAssetId: 32,
1446
- },
1447
- ]
1448
- ],
1449
- [
1450
- [
1451
- Bundles.MainnetIds.SPARK_CLOSE_TO_DEBT,
1452
- true,
1453
- ['0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000084d000000000000000000000000000000000000000000000000000000000000000001'],
1454
- [
1455
- '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f', '0x0000000000000000000000000000000000000000000000000000000000000015',
1456
- '0x000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca', '0x0000000000000000000000000000000000000000000000000000000000000020',
1457
- '0x0000000000000000000000000000000000000000000000000000000000000000',
1458
- ],
1459
- ],
1460
- [
1461
- Bundles.MainnetIds.SPARK_CLOSE_TO_DEBT,
1462
- true,
1463
- {
1464
- baseTokenAddress: getAssetInfo('LINK').address, quoteTokenAddress: getAssetInfo('DAI').address, price: 0.00544, ratioState: RatioState.UNDER
1465
- },
1466
- {
1467
- collAsset: getAssetInfo('DAI').address, collAssetId: 21, debtAsset: getAssetInfo('LINK').address, debtAssetId: 32,
1468
- },
1469
- ]
1470
- ]
1471
- ];
1472
-
1473
- examples.forEach(([expected, actual]) => {
1474
- it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
1475
- expect(sparkEncode.closeToAsset(...actual)).to.eql(expected);
1476
- });
1477
- });
1478
- });
1479
- });
1480
-
1481
1391
  describe('When testing strategySubService.crvUSDEncode', () => {
1482
1392
  describe('leverageManagement()', () => {
1483
1393
  const examples: Array<[
@@ -1581,6 +1491,7 @@ describe('Feature: strategySubService.ts', () => {
1581
1491
  });
1582
1492
  });
1583
1493
  });
1494
+
1584
1495
  describe('When testing strategySubService.morphoBlueEncode', () => {
1585
1496
  describe('leverageManagement()', () => {
1586
1497
  const examples: Array<[
@@ -1676,6 +1587,61 @@ describe('Feature: strategySubService.ts', () => {
1676
1587
  });
1677
1588
  });
1678
1589
  });
1590
+
1591
+ describe('closeOnPrice()', () => {
1592
+ const examples: Array<[
1593
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
1594
+ [
1595
+ strategyOrBundleId: number,
1596
+ loanToken: EthereumAddress,
1597
+ collToken: EthereumAddress,
1598
+ oracle: EthereumAddress,
1599
+ irm: EthereumAddress,
1600
+ lltv: string,
1601
+ user: EthereumAddress,
1602
+ stopLossPrice: number,
1603
+ stopLossType: CloseToAssetType,
1604
+ takeProfitPrice: number,
1605
+ takeProfitType: CloseToAssetType,
1606
+ ]
1607
+ ]> = [
1608
+ [
1609
+ [
1610
+ Bundles.MainnetIds.MORPHO_BLUE_CLOSE,
1611
+ true,
1612
+ ['0x000000000000000000000000870ac11d48b15db9a138cf899d20f13f79ba00bc0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000022ecb25c000000000000000000000000000000000000000000000000000000005d21dba000'],
1613
+ [
1614
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
1615
+ '0x0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0',
1616
+ '0x000000000000000000000000870ac11d48b15db9a138cf899d20f13f79ba00bc',
1617
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
1618
+ '0x0000000000000000000000000000000000000000000000000d1d507e40be8000',
1619
+ '0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c',
1620
+ '0x0000000000000000000000000000000000000000000000000000000000000005',
1621
+ ],
1622
+ ],
1623
+ [
1624
+ Bundles.MainnetIds.MORPHO_BLUE_CLOSE,
1625
+ web3Utils.toChecksumAddress('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'),
1626
+ web3Utils.toChecksumAddress('0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0'),
1627
+ web3Utils.toChecksumAddress('0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC'),
1628
+ web3Utils.toChecksumAddress('0x0000000000000000000000000000000000000000'),
1629
+ '945000000000000000',
1630
+ web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'),
1631
+ 1500,
1632
+ CloseToAssetType.DEBT,
1633
+ 4000,
1634
+ CloseToAssetType.COLLATERAL
1635
+ ]
1636
+ ],
1637
+ ];
1638
+
1639
+ examples.forEach(([expected, actual]) => {
1640
+ it(`Given ${JSON.stringify(actual)} should return expected value: ${JSON.stringify(expected)}`, () => {
1641
+ expect(morphoBlueEncode.closeOnPrice(...actual)).to.eql(expected);
1642
+ });
1643
+ });
1644
+ });
1679
1645
  });
1680
1646
 
1681
1647
  describe('When testing strategySubService.compoundV3L2Encode', () => {
@@ -1709,5 +1675,4 @@ describe('Feature: strategySubService.ts', () => {
1709
1675
  });
1710
1676
  });
1711
1677
  });
1712
-
1713
1678
  });
@@ -557,25 +557,24 @@ export const sparkEncode = {
557
557
 
558
558
  return subInput;
559
559
  },
560
- closeToAsset(
560
+ closeOnPriceGeneric(
561
561
  strategyOrBundleId: number,
562
- isBundle: boolean = true,
563
- triggerData: {
564
- baseTokenAddress: EthereumAddress, quoteTokenAddress: EthereumAddress, price: number, ratioState: RatioState
565
- },
566
- subData: {
567
- collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number,
568
- },
562
+ collAsset: EthereumAddress,
563
+ collAssetId: number,
564
+ debtAsset: EthereumAddress,
565
+ debtAssetId: number,
566
+ marketAddr: EthereumAddress,
567
+ user: EthereumAddress,
568
+ stopLossPrice: number = 0,
569
+ stopLossType: CloseToAssetType = CloseToAssetType.DEBT,
570
+ takeProfitPrice: number = 0,
571
+ takeProfitType: CloseToAssetType = CloseToAssetType.COLLATERAL,
569
572
  ) {
570
- const {
571
- collAsset, collAssetId, debtAsset, debtAssetId,
572
- } = subData;
573
- const subDataEncoded = subDataService.sparkQuotePriceSubData.encode(collAsset, collAssetId, debtAsset, debtAssetId);
573
+ const isBundle = true;
574
+ const closeType = getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType);
574
575
 
575
- const {
576
- baseTokenAddress, quoteTokenAddress, price, ratioState,
577
- } = triggerData;
578
- const triggerDataEncoded = triggerService.sparkQuotePriceTrigger.encode(baseTokenAddress, quoteTokenAddress, price, ratioState);
576
+ const subDataEncoded = subDataService.sparkCloseGenericSubData.encode(collAsset, collAssetId, debtAsset, debtAssetId, closeType, marketAddr, user);
577
+ const triggerDataEncoded = triggerService.sparkQuotePriceRangeTrigger.encode(collAsset, debtAsset, stopLossPrice, takeProfitPrice);
579
578
 
580
579
  return [strategyOrBundleId, isBundle, triggerDataEncoded, subDataEncoded];
581
580
  },
@@ -671,6 +670,27 @@ export const morphoBlueEncode = {
671
670
  const triggerData = triggerService.morphoBluePriceTrigger.encode(oracle, collToken, loanToken, price, priceState);
672
671
  return [strategyOrBundleId, isBundle, triggerData, subData];
673
672
  },
673
+ closeOnPrice(
674
+ strategyOrBundleId: number,
675
+ loanToken: EthereumAddress,
676
+ collToken: EthereumAddress,
677
+ oracle: EthereumAddress,
678
+ irm: EthereumAddress,
679
+ lltv: string,
680
+ user: EthereumAddress,
681
+ stopLossPrice: number = 0,
682
+ stopLossType: CloseToAssetType = CloseToAssetType.DEBT,
683
+ takeProfitPrice: number = 0,
684
+ takeProfitType: CloseToAssetType = CloseToAssetType.COLLATERAL,
685
+ ) {
686
+ const isBundle = true;
687
+ const closeType = getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType);
688
+
689
+ const subDataEncoded = subDataService.morphoBlueCloseOnPriceSubData.encode(loanToken, collToken, oracle, irm, lltv, user, closeType);
690
+ const triggerDataEncoded = triggerService.morphoBluePriceRangeTrigger.encode(oracle, collToken, loanToken, stopLossPrice, takeProfitPrice);
691
+
692
+ return [strategyOrBundleId, isBundle, triggerDataEncoded, subDataEncoded];
693
+ },
674
694
  };
675
695
 
676
696
  export const liquityV2Encode = {