@defisaver/automation-sdk 3.0.1 → 3.0.2-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 (47) hide show
  1. package/esm/automation/private/LegacyAutomation.js +2 -2
  2. package/esm/automation/private/StrategiesAutomation.js +7 -1
  3. package/esm/automation/private/StrategiesAutomation.test.d.ts +1 -1
  4. package/esm/automation/private/StrategiesAutomation.test.js +500 -499
  5. package/esm/constants/index.js +10 -0
  6. package/esm/services/ethereumService.test.d.ts +1 -1
  7. package/esm/services/ethereumService.test.js +1 -0
  8. package/esm/services/strategiesService.js +37 -0
  9. package/esm/services/strategiesService.test.d.ts +1 -1
  10. package/esm/services/strategiesService.test.js +1 -0
  11. package/esm/services/strategySubService.d.ts +3 -0
  12. package/esm/services/strategySubService.js +11 -1
  13. package/esm/services/strategySubService.test.d.ts +1 -1
  14. package/esm/services/strategySubService.test.js +74 -0
  15. package/esm/services/subDataService.d.ts +12 -0
  16. package/esm/services/subDataService.js +33 -1
  17. package/esm/services/subDataService.test.d.ts +1 -1
  18. package/esm/services/subDataService.test.js +89 -0
  19. package/esm/services/triggerService.d.ts +9 -0
  20. package/esm/services/triggerService.js +17 -1
  21. package/esm/services/triggerService.test.d.ts +1 -1
  22. package/esm/services/triggerService.test.js +37 -0
  23. package/esm/services/utils.test.d.ts +1 -1
  24. package/esm/services/utils.test.js +1 -0
  25. package/esm/types/enums.d.ts +5 -2
  26. package/esm/types/enums.js +3 -0
  27. package/package.json +2 -2
  28. package/scripts/generateContractTypes.js +1 -1
  29. package/src/automation/private/LegacyAutomation.ts +2 -2
  30. package/src/automation/private/StrategiesAutomation.test.ts +503 -501
  31. package/src/automation/private/StrategiesAutomation.ts +7 -0
  32. package/src/constants/index.ts +10 -0
  33. package/src/services/ethereumService.test.ts +1 -0
  34. package/src/services/strategiesService.test.ts +1 -0
  35. package/src/services/strategiesService.ts +42 -0
  36. package/src/services/strategySubService.test.ts +90 -1
  37. package/src/services/strategySubService.ts +25 -0
  38. package/src/services/subDataService.test.ts +97 -1
  39. package/src/services/subDataService.ts +43 -0
  40. package/src/services/triggerService.test.ts +40 -0
  41. package/src/services/triggerService.ts +23 -0
  42. package/src/services/utils.test.ts +1 -0
  43. package/src/types/enums.ts +3 -0
  44. package/umd/index.js +126 -3
  45. package/.env +0 -4
  46. package/.yarn/releases/yarn-1.22.1.cjs +0 -147386
  47. package/.yarnrc.yml +0 -3
@@ -46,6 +46,9 @@ export default class StrategiesAutomation extends Automation {
46
46
  }
47
47
 
48
48
  protected async getEventFromSubStorage(event: string, options?: PastEventOptions) {
49
+ if (new Dec(this.subStorageContract.createdBlock.toString()).gt(options?.fromBlock?.toString() || 0)) {
50
+ return [];
51
+ }
49
52
  return getEventsFromContract<SubStorage>(this.subStorageContract, this.subStorageContractFork, event, options);
50
53
  }
51
54
 
@@ -119,6 +122,10 @@ export default class StrategiesAutomation extends Automation {
119
122
  && (
120
123
  s.protocol.id !== ProtocolIdentifiers.StrategiesAutomation.CrvUSD // merge only crvUSD leverage management for the same market
121
124
  || s.strategyData.decoded.subData.controller.toLowerCase() === current.strategyData.decoded.triggerData.controller.toLowerCase()
125
+ )
126
+ && (
127
+ s.protocol.id !== ProtocolIdentifiers.StrategiesAutomation.MorphoBlue // merge morpho blue with the same marketId
128
+ || s.strategyData.decoded.triggerData.marketId.toLowerCase() === current.strategyData.decoded.triggerData.marketId.toLowerCase()
122
129
  );
123
130
  }
124
131
 
@@ -293,6 +293,16 @@ export const MAINNET_BUNDLES_INFO: MainnetBundleInfo = {
293
293
  strategyId: Strategies.Identifiers.Boost,
294
294
  protocol: PROTOCOLS.CrvUSD,
295
295
  },
296
+ [Bundles.MainnetIds.MORPHO_BLUE_REPAY]: {
297
+ strategyOrBundleId: Bundles.MainnetIds.MORPHO_BLUE_REPAY,
298
+ strategyId: Strategies.Identifiers.Repay,
299
+ protocol: PROTOCOLS.MorphoBlue,
300
+ },
301
+ [Bundles.MainnetIds.MORPHO_BLUE_BOOST]: {
302
+ strategyOrBundleId: Bundles.MainnetIds.MORPHO_BLUE_BOOST,
303
+ strategyId: Strategies.Identifiers.Boost,
304
+ protocol: PROTOCOLS.MorphoBlue,
305
+ },
296
306
  };
297
307
 
298
308
  export const OPTIMISM_BUNDLES_INFO: OptimismBundleInfo = {
@@ -8,6 +8,7 @@ import type { BlockNumber, Multicall } from '../types';
8
8
  import { Contract } from '../types';
9
9
  import type { Erc20 } from '../types/contracts/generated';
10
10
 
11
+ import '../configuration';
11
12
  import { getEventsFromContract, multicall, } from './ethereumService';
12
13
 
13
14
  import { makeErc20Contract } from './contractService';
@@ -3,6 +3,7 @@ import { expect } from 'chai';
3
3
  import { ProtocolIdentifiers, Strategies } from '../types/enums';
4
4
  import type { ParseData, Position } from '../types';
5
5
 
6
+ import '../configuration';
6
7
  import { parseStrategiesAutomatedPosition } from './strategiesService';
7
8
 
8
9
  describe('Feature: strategiesService.ts', () => {
@@ -719,6 +719,44 @@ function parseCrvUSDLeverageManagement(position: Position.Automated, parseData:
719
719
  return _position;
720
720
  }
721
721
 
722
+ function parseMorphoBlueLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
723
+ const _position = cloneDeep(position);
724
+
725
+ const { subStruct, subId, subHash } = parseData.subscriptionEventData;
726
+ const { isEnabled } = parseData.strategiesSubsData;
727
+ const triggerData = triggerService.morphoBlueRatioTrigger.decode(subStruct.triggerData);
728
+ const subData = subDataService.morphoBlueLeverageManagementSubData.decode(subStruct.subData);
729
+
730
+ _position.strategyData.decoded.triggerData = triggerData;
731
+ _position.strategyData.decoded.subData = subData;
732
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
733
+
734
+ if (isRepay) {
735
+ _position.specific = {
736
+ triggerRepayRatio: triggerData.ratio,
737
+ targetRepayRatio: subData.targetRatio,
738
+ repayEnabled: isEnabled,
739
+ subId1: Number(subId),
740
+ subHashRepay: subHash,
741
+ mergeWithId: Strategies.Identifiers.Boost,
742
+ };
743
+ } else {
744
+ _position.specific = {
745
+ triggerBoostRatio: triggerData.ratio,
746
+ targetBoostRatio: subData.targetRatio,
747
+ boostEnabled: isEnabled,
748
+ subId2: Number(subId),
749
+ subHashBoost: subHash,
750
+ mergeId: Strategies.Identifiers.Boost,
751
+ };
752
+ }
753
+
754
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, triggerData.marketId);
755
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
756
+
757
+ return _position;
758
+ }
759
+
722
760
  const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
723
761
  [ProtocolIdentifiers.StrategiesAutomation.MakerDAO]: {
724
762
  [Strategies.Identifiers.SavingsLiqProtection]: parseMakerSavingsLiqProtection,
@@ -782,6 +820,10 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
782
820
  [Strategies.Identifiers.Repay]: parseCrvUSDLeverageManagement,
783
821
  [Strategies.Identifiers.Boost]: parseCrvUSDLeverageManagement,
784
822
  },
823
+ [ProtocolIdentifiers.StrategiesAutomation.MorphoBlue]: {
824
+ [Strategies.Identifiers.Repay]: parseMorphoBlueLeverageManagement,
825
+ [Strategies.Identifiers.Boost]: parseMorphoBlueLeverageManagement,
826
+ },
785
827
  };
786
828
 
787
829
  function getParsingMethod(id: ProtocolIdentifiers.StrategiesAutomation, strategy: BundleOrStrategy) {
@@ -7,6 +7,7 @@ import * as web3Utils from 'web3-utils';
7
7
  import { Bundles, ChainId, OrderType, RatioState, Strategies } from '../types/enums';
8
8
  import type { EthereumAddress, StrategyOrBundleIds, SubData, TriggerData } from '../types';
9
9
 
10
+ import '../configuration';
10
11
  import {
11
12
  aaveV2Encode,
12
13
  chickenBondsEncode,
@@ -18,7 +19,7 @@ import {
18
19
  morphoAaveV2Encode,
19
20
  exchangeEncode,
20
21
  sparkEncode,
21
- crvUSDEncode, compoundV3L2Encode,
22
+ crvUSDEncode, compoundV3L2Encode, morphoBlueEncode,
22
23
  } from './strategySubService';
23
24
 
24
25
  describe('Feature: strategySubService.ts', () => {
@@ -899,6 +900,94 @@ describe('Feature: strategySubService.ts', () => {
899
900
  });
900
901
  });
901
902
  });
903
+ describe('When testing strategySubService.morphoBlueEncode', () => {
904
+ describe('leverageManagement()', () => {
905
+ const examples: Array<[
906
+ [StrategyOrBundleIds, boolean, TriggerData, SubData],
907
+ [
908
+ marketId: string,
909
+ loanToken: EthereumAddress,
910
+ collToken: EthereumAddress,
911
+ oracle: EthereumAddress,
912
+ irm: EthereumAddress,
913
+ lltv: string,
914
+ ratioState: RatioState,
915
+ targetRatio: number,
916
+ triggerRatio: number,
917
+ user: EthereumAddress,
918
+ ],
919
+ ]> = [
920
+ [
921
+ [
922
+ Bundles.MainnetIds.MORPHO_BLUE_REPAY,
923
+ true,
924
+ [
925
+ '0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec410000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c00000000000000000000000000000000000000000000000010a741a4627800000000000000000000000000000000000000000000000000000000000000000001',
926
+ ],
927
+ [
928
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
929
+ '0x0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0',
930
+ '0x0000000000000000000000002a01eb9496094da03c4e364def50f5ad1280ad72',
931
+ '0x000000000000000000000000870ac11d48b15db9a138cf899d20f13f79ba00bc',
932
+ '0x0000000000000000000000000000000000000000000000000d1d507e40be8000',
933
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
934
+ '0x000000000000000000000000000000000000000000000000136dcc951d8c0000',
935
+ '0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c',
936
+ ],
937
+ ],
938
+ [
939
+ '0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41',
940
+ web3Utils.toChecksumAddress('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'),
941
+ web3Utils.toChecksumAddress('0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0'),
942
+ web3Utils.toChecksumAddress('0x2a01eb9496094da03c4e364def50f5ad1280ad72'),
943
+ web3Utils.toChecksumAddress('0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC'),
944
+ '945000000000000000',
945
+ RatioState.UNDER,
946
+ 140,
947
+ 120,
948
+ web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c')
949
+ ]
950
+ ],
951
+ [
952
+ [
953
+ Bundles.MainnetIds.MORPHO_BLUE_BOOST,
954
+ true,
955
+ [
956
+ '0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec410000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c0000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000000'
957
+ ],
958
+ [
959
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
960
+ '0x0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0',
961
+ '0x0000000000000000000000002a01eb9496094da03c4e364def50f5ad1280ad72',
962
+ '0x000000000000000000000000870ac11d48b15db9a138cf899d20f13f79ba00bc',
963
+ '0x0000000000000000000000000000000000000000000000000d1d507e40be8000',
964
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
965
+ '0x00000000000000000000000000000000000000000000000016345785d8a00000',
966
+ '0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c',
967
+ ],
968
+ ],
969
+ [
970
+ '0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41',
971
+ web3Utils.toChecksumAddress('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'),
972
+ web3Utils.toChecksumAddress('0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0'),
973
+ web3Utils.toChecksumAddress('0x2a01eb9496094da03c4e364def50f5ad1280ad72'),
974
+ web3Utils.toChecksumAddress('0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC'),
975
+ '945000000000000000',
976
+ RatioState.OVER,
977
+ 160,
978
+ 200,
979
+ web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c')
980
+ ]
981
+ ],
982
+ ];
983
+
984
+ examples.forEach(([expected, actual]) => {
985
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
986
+ expect(morphoBlueEncode.leverageManagement(...actual)).to.eql(expected);
987
+ });
988
+ });
989
+ });
990
+ });
902
991
 
903
992
  describe('When testing strategySubService.compoundV3L2Encode', () => {
904
993
  describe('leverageManagement()', () => {
@@ -448,3 +448,28 @@ export const crvUSDEncode = {
448
448
  return [strategyOrBundleId, isBundle, triggerData, subData];
449
449
  },
450
450
  };
451
+
452
+ export const morphoBlueEncode = {
453
+ leverageManagement(
454
+ marketId: string,
455
+ loanToken: EthereumAddress,
456
+ collToken: EthereumAddress,
457
+ oracle: EthereumAddress,
458
+ irm: EthereumAddress,
459
+ lltv: string,
460
+ ratioState: RatioState,
461
+ targetRatio: number,
462
+ triggerRatio: number,
463
+ user: EthereumAddress,
464
+ ) {
465
+ const subData = subDataService.morphoBlueLeverageManagementSubData.encode(loanToken, collToken, oracle, irm, lltv, ratioState, targetRatio, user);
466
+
467
+ const triggerData = triggerService.morphoBlueRatioTrigger.encode(marketId, user, triggerRatio, ratioState);
468
+
469
+ // over is boost, under is repay
470
+ const strategyOrBundleId = ratioState === RatioState.OVER ? Bundles.MainnetIds.MORPHO_BLUE_BOOST : Bundles.MainnetIds.MORPHO_BLUE_REPAY;
471
+ const isBundle = true;
472
+
473
+ return [strategyOrBundleId, isBundle, triggerData, subData];
474
+ },
475
+ };
@@ -6,6 +6,7 @@ import * as web3Utils from 'web3-utils';
6
6
  import { ChainId, OrderType, RatioState } from '../types/enums';
7
7
  import type { EthereumAddress, SubData } from '../types';
8
8
 
9
+ import '../configuration';
9
10
  import {
10
11
  aaveV2LeverageManagementSubData,
11
12
  aaveV3LeverageManagementSubData,
@@ -29,7 +30,7 @@ import {
29
30
  sparkLeverageManagementSubData,
30
31
  sparkQuotePriceSubData,
31
32
  crvUSDLeverageManagementSubData,
32
- compoundV3L2LeverageManagementSubData,
33
+ compoundV3L2LeverageManagementSubData, morphoBlueLeverageManagementSubData,
33
34
  } from './subDataService';
34
35
 
35
36
  describe('Feature: subDataService.ts', () => {
@@ -1172,5 +1173,100 @@ describe('Feature: subDataService.ts', () => {
1172
1173
  });
1173
1174
  });
1174
1175
 
1176
+ describe('When testing subDataService.morphoBlueLeverageManagementSubData', () => {
1177
+ describe('encode()', () => {
1178
+ const examples: Array<[
1179
+ SubData,
1180
+ [loanToken: EthereumAddress, collToken: EthereumAddress, oracle: EthereumAddress, irm: EthereumAddress, lltv: string, ratioState: RatioState, targetRatio: number, user: EthereumAddress],
1181
+ ]> = [
1182
+ [
1183
+ [
1184
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
1185
+ '0x0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0',
1186
+ '0x0000000000000000000000002a01eb9496094da03c4e364def50f5ad1280ad72',
1187
+ '0x000000000000000000000000870ac11d48b15db9a138cf899d20f13f79ba00bc',
1188
+ '0x0000000000000000000000000000000000000000000000000d1d507e40be8000',
1189
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
1190
+ '0x00000000000000000000000000000000000000000000000010a741a462780000',
1191
+ '0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c',
1192
+ ],
1193
+ [web3Utils.toChecksumAddress('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'), web3Utils.toChecksumAddress('0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0'), web3Utils.toChecksumAddress('0x2a01eb9496094da03c4e364def50f5ad1280ad72'), web3Utils.toChecksumAddress('0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC'), '945000000000000000', RatioState.UNDER, 120, web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c')]
1194
+ ],
1195
+ [
1196
+ [
1197
+ '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
1198
+ '0x0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0',
1199
+ '0x00000000000000000000000048f7e36eb6b826b2df4b2e630b62cd25e89e40e2',
1200
+ '0x000000000000000000000000870ac11d48b15db9a138cf899d20f13f79ba00bc',
1201
+ '0x0000000000000000000000000000000000000000000000000bef55718ad60000',
1202
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
1203
+ '0x0000000000000000000000000000000000000000000000001bc16d674ec80000',
1204
+ '0x0000000000000000000000000043d218133afab8f2b829b106633e434ad94e2c',
1205
+ ],
1206
+ [web3Utils.toChecksumAddress('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'), web3Utils.toChecksumAddress('0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0'), web3Utils.toChecksumAddress('0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2'), web3Utils.toChecksumAddress('0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC'), '860000000000000000', RatioState.OVER, 200, web3Utils.toChecksumAddress('0x0043d218133AFaB8F2B829B106633E434Ad94E2c')]
1207
+ ],
1208
+ ];
1209
+
1210
+ examples.forEach(([expected, actual]) => {
1211
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
1212
+ expect(morphoBlueLeverageManagementSubData.encode(...actual)).to.eql(expected);
1213
+ });
1214
+ });
1215
+ });
1216
+
1217
+ describe('decode()', () => {
1218
+ const examples: Array<[{ collToken: EthereumAddress, loanToken: EthereumAddress, oracle: EthereumAddress, irm: EthereumAddress, lltv: string, targetRatio: number, user: EthereumAddress }, SubData]> = [
1219
+ [
1220
+ {
1221
+ 'collToken': '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0',
1222
+ 'irm': '0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC',
1223
+ 'lltv': '945000000000000000',
1224
+ 'loanToken': '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
1225
+ 'oracle': '0x2a01EB9496094dA03c4E364Def50f5aD1280AD72',
1226
+ 'targetRatio': 120,
1227
+ 'user': '0x1031d218133AFaB8C2B819B1366c7e434Ad91e9c',
1228
+ },
1229
+ [
1230
+ '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
1231
+ '0x0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0',
1232
+ '0x0000000000000000000000002a01eb9496094da03c4e364def50f5ad1280ad72',
1233
+ '0x000000000000000000000000870ac11d48b15db9a138cf899d20f13f79ba00bc',
1234
+ '0x0000000000000000000000000000000000000000000000000d1d507e40be8000',
1235
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
1236
+ '0x00000000000000000000000000000000000000000000000010a741a462780000',
1237
+ '0x0000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c',
1238
+ ],
1239
+ ],
1240
+ [
1241
+ {
1242
+ 'collToken': '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0',
1243
+ 'irm': '0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC',
1244
+ 'lltv': '860000000000000000',
1245
+ 'loanToken': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
1246
+ 'oracle': '0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2',
1247
+ 'targetRatio': 200,
1248
+ 'user': '0x0043d218133aFaB8F2b829B106633E434aD94e2C',
1249
+ },
1250
+ [
1251
+ '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
1252
+ '0x0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0',
1253
+ '0x00000000000000000000000048f7e36eb6b826b2df4b2e630b62cd25e89e40e2',
1254
+ '0x000000000000000000000000870ac11d48b15db9a138cf899d20f13f79ba00bc',
1255
+ '0x0000000000000000000000000000000000000000000000000bef55718ad60000',
1256
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
1257
+ '0x0000000000000000000000000000000000000000000000001bc16d674ec80000',
1258
+ '0x0000000000000000000000000043d218133afab8f2b829b106633e434ad94e2c',
1259
+ ],
1260
+ ],
1261
+ ];
1262
+
1263
+ examples.forEach(([expected, actual]) => {
1264
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
1265
+ expect(morphoBlueLeverageManagementSubData.decode(actual)).to.eql(expected);
1266
+ });
1267
+ });
1268
+ });
1269
+ });
1270
+
1175
1271
 
1176
1272
  });
@@ -510,3 +510,46 @@ export const crvUSDLeverageManagementSubData = {
510
510
  return { controller, targetRatio };
511
511
  },
512
512
  };
513
+
514
+ export const morphoBlueLeverageManagementSubData = {
515
+ encode: (
516
+ loanToken: EthereumAddress,
517
+ collToken: EthereumAddress,
518
+ oracle: EthereumAddress,
519
+ irm: EthereumAddress,
520
+ lltv: string,
521
+ ratioState: RatioState,
522
+ targetRatio: number,
523
+ user: EthereumAddress,
524
+ ) => {
525
+ const loanTokenEncoded = AbiCoder.encodeParameter('address', loanToken);
526
+ const collTokenEncoded = AbiCoder.encodeParameter('address', collToken);
527
+ const oracleEncoded = AbiCoder.encodeParameter('address', oracle);
528
+ const irmEncoded = AbiCoder.encodeParameter('address', irm);
529
+ const lltvEncoded = AbiCoder.encodeParameter('uint256', lltv);
530
+ const ratioStateEncoded = AbiCoder.encodeParameter('uint8', ratioState);
531
+ const targetRatioEncoded = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
532
+ const userEncoded = AbiCoder.encodeParameter('address', user);
533
+ return [loanTokenEncoded, collTokenEncoded, oracleEncoded, irmEncoded, lltvEncoded, ratioStateEncoded, targetRatioEncoded, userEncoded];
534
+ },
535
+ decode: (subData: SubData) => {
536
+ const loanToken = AbiCoder.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
537
+ const collToken = AbiCoder.decodeParameter('address', subData[1]) as any as EthereumAddress;
538
+ const oracle = AbiCoder.decodeParameter('address', subData[2]) as any as EthereumAddress;
539
+ const irm = AbiCoder.decodeParameter('address', subData[3]) as any as EthereumAddress;
540
+ const lltv = AbiCoder.decodeParameter('uint256', subData[4]) as any as EthereumAddress;
541
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[6]) as any as EthereumAddress;
542
+ const user = AbiCoder.decodeParameter('address', subData[7]) as any as EthereumAddress;
543
+ const targetRatio = weiToRatioPercentage(weiRatio);
544
+
545
+ return {
546
+ loanToken,
547
+ collToken,
548
+ oracle,
549
+ irm,
550
+ lltv,
551
+ user,
552
+ targetRatio,
553
+ };
554
+ },
555
+ };
@@ -5,6 +5,7 @@ import * as web3Utils from 'web3-utils';
5
5
  import { ChainId, OrderType, RatioState } from '../types/enums';
6
6
  import type { EthereumAddress, TriggerData } from '../types';
7
7
 
8
+ import '../configuration';
8
9
  import {
9
10
  aaveV2RatioTrigger,
10
11
  aaveV3QuotePriceTrigger,
@@ -26,6 +27,7 @@ import {
26
27
  trailingStopTrigger,
27
28
  liquityDebtInFrontWithLimitTrigger,
28
29
  crvUSDRatioTrigger,
30
+ morphoBlueRatioTrigger,
29
31
  } from './triggerService';
30
32
 
31
33
  describe('Feature: triggerService.ts', () => {
@@ -931,4 +933,42 @@ describe('Feature: triggerService.ts', () => {
931
933
  });
932
934
  });
933
935
  });
936
+
937
+ describe('When testing triggerService.morphoBlueRatioTrigger', () => {
938
+ describe('encode()', () => {
939
+ const examples: Array<[[string], [marketId: string, owner: EthereumAddress, ratioPercentage: number, ratioState: RatioState]]> = [
940
+ [
941
+ ['0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec410000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c00000000000000000000000000000000000000000000000010a741a4627800000000000000000000000000000000000000000000000000000000000000000001'],
942
+ ['0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41', web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'), 120, RatioState.UNDER]
943
+ ],
944
+ [
945
+ ['0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc0000000000000000000000000043d218133afab8f2b829b106633e434ad94e2c0000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000000'],
946
+ ['0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc', web3Utils.toChecksumAddress('0x0043d218133AFaB8F2B829B106633E434Ad94E2c'), 200, RatioState.OVER]
947
+ ],
948
+ ];
949
+ examples.forEach(([expected, actual]) => {
950
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
951
+ expect(morphoBlueRatioTrigger.encode(...actual)).to.eql(expected);
952
+ });
953
+ });
954
+ });
955
+ describe('decode()', () => {
956
+ const examples: Array<[{ marketId: string, owner: EthereumAddress, ratio: number, ratioState: RatioState }, TriggerData]> = [
957
+ [
958
+ { marketId: '0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41', owner: web3Utils.toChecksumAddress('0x1031d218133AFaB8c2B819B1366c7E434Ad91E9c'), ratio: 120, ratioState: RatioState.UNDER },
959
+ ['0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec410000000000000000000000001031d218133afab8c2b819b1366c7e434ad91e9c00000000000000000000000000000000000000000000000010a741a4627800000000000000000000000000000000000000000000000000000000000000000001'],
960
+ ],
961
+ [
962
+ { marketId: '0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc', owner: web3Utils.toChecksumAddress('0x0043d218133AFaB8F2B829B106633E434Ad94E2c'), ratio: 200, ratioState: RatioState.OVER },
963
+ ['0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc0000000000000000000000000043d218133afab8f2b829b106633e434ad94e2c0000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000000'],
964
+ ],
965
+ ];
966
+
967
+ examples.forEach(([expected, actual]) => {
968
+ it(`Given ${actual} should return expected value: ${JSON.stringify(expected)}`, () => {
969
+ expect(morphoBlueRatioTrigger.decode(actual)).to.eql(expected);
970
+ });
971
+ });
972
+ });
973
+ });
934
974
  });
@@ -404,3 +404,26 @@ export const crvUSDRatioTrigger = {
404
404
  };
405
405
  },
406
406
  };
407
+
408
+ export const morphoBlueRatioTrigger = {
409
+ encode(
410
+ marketId: string, // bytes32
411
+ owner: EthereumAddress,
412
+ ratioPercentage: number,
413
+ ratioState: RatioState,
414
+ ) {
415
+ const ratioWei = ratioPercentageToWei(ratioPercentage);
416
+ return [AbiCoder.encodeParameters(['bytes32', 'address', 'uint256', 'uint8'], [marketId, owner, ratioWei, ratioState])];
417
+ },
418
+ decode(
419
+ triggerData: TriggerData,
420
+ ) {
421
+ const decodedData = AbiCoder.decodeParameters(['bytes32', 'address', 'uint256', 'uint8'], triggerData[0]);
422
+ return {
423
+ marketId: decodedData[0] as string,
424
+ owner: decodedData[1] as EthereumAddress,
425
+ ratio: weiToRatioPercentage(decodedData[2] as string),
426
+ ratioState: Number(decodedData[3]),
427
+ };
428
+ },
429
+ };
@@ -8,6 +8,7 @@ import { ChainId, ProtocolIdentifiers, RatioState } from '../types/enums';
8
8
 
9
9
  import { sparkEncode } from './strategySubService';
10
10
 
11
+ import '../configuration';
11
12
  import {
12
13
  addToArrayIf,
13
14
  addToObjectIf,
@@ -40,6 +40,7 @@ export namespace ProtocolIdentifiers {
40
40
  Exchange = 'Exchange',
41
41
  Spark = 'Spark',
42
42
  CrvUSD = 'CurveUSD',
43
+ MorphoBlue = 'MorphoBlue',
43
44
  }
44
45
 
45
46
  export enum LegacyAutomation {
@@ -141,6 +142,8 @@ export namespace Bundles {
141
142
  COMP_V2_BOOST = 21,
142
143
  CRVUSD_REPAY = 26,
143
144
  CRVUSD_BOOST = 27,
145
+ MORPHO_BLUE_REPAY = 32,
146
+ MORPHO_BLUE_BOOST = 33,
144
147
  }
145
148
 
146
149
  export enum OptimismIds {