@defisaver/automation-sdk 3.3.14 → 3.3.15-liq-prot-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 (41) hide show
  1. package/cjs/constants/index.js +95 -0
  2. package/cjs/index.d.ts +4 -3
  3. package/cjs/index.js +6 -2
  4. package/cjs/services/strategiesService.js +181 -17
  5. package/cjs/services/strategySubService.d.ts +14 -13
  6. package/cjs/services/strategySubService.js +74 -63
  7. package/cjs/services/strategySubService.test.js +0 -234
  8. package/cjs/services/subDataService.d.ts +98 -1
  9. package/cjs/services/subDataService.js +264 -6
  10. package/cjs/services/subDataService.test.js +0 -42
  11. package/cjs/services/utils.d.ts +3 -1
  12. package/cjs/services/utils.js +34 -1
  13. package/cjs/services/utils.test.js +25 -0
  14. package/cjs/types/enums.d.ts +29 -6
  15. package/cjs/types/enums.js +23 -0
  16. package/esm/constants/index.js +95 -0
  17. package/esm/index.d.ts +4 -3
  18. package/esm/index.js +7 -3
  19. package/esm/services/strategiesService.js +181 -17
  20. package/esm/services/strategySubService.d.ts +14 -13
  21. package/esm/services/strategySubService.js +74 -60
  22. package/esm/services/strategySubService.test.js +2 -236
  23. package/esm/services/subDataService.d.ts +98 -1
  24. package/esm/services/subDataService.js +262 -5
  25. package/esm/services/subDataService.test.js +0 -42
  26. package/esm/services/utils.d.ts +3 -1
  27. package/esm/services/utils.js +32 -1
  28. package/esm/services/utils.test.js +27 -2
  29. package/esm/types/enums.d.ts +29 -6
  30. package/esm/types/enums.js +23 -0
  31. package/package.json +1 -1
  32. package/src/constants/index.ts +96 -0
  33. package/src/index.ts +24 -6
  34. package/src/services/strategiesService.ts +246 -17
  35. package/src/services/strategySubService.test.ts +0 -279
  36. package/src/services/strategySubService.ts +196 -110
  37. package/src/services/subDataService.test.ts +0 -48
  38. package/src/services/subDataService.ts +363 -4
  39. package/src/services/utils.test.ts +32 -1
  40. package/src/services/utils.ts +32 -1
  41. package/src/types/enums.ts +23 -0
@@ -164,6 +164,9 @@ export const makerLeverageManagementSubData = {
164
164
  return { vaultId, targetRatio };
165
165
  },
166
166
  };
167
+
168
+ // ! Any change here will PROBABLY require a change in makerLiquidationProtectionSubData as well, since it is copy paste
169
+ // ! Double check before changing
167
170
  export const makerLeverageManagementWithoutSubProxy = {
168
171
  encode(
169
172
  vaultId: number,
@@ -184,6 +187,28 @@ export const makerLeverageManagementWithoutSubProxy = {
184
187
  },
185
188
  };
186
189
 
190
+ export const makerLiquidationProtectionSubData = {
191
+ encode(
192
+ vaultId: number,
193
+ targetRatio: number,
194
+ daiAddr?: EthereumAddress,
195
+ ): SubData {
196
+ const encodedVaultId = AbiCoder.encodeParameter('uint256', vaultId);
197
+ const encodedTargetRatio = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
198
+ const encodedDaiAddr = AbiCoder.encodeParameter('address', daiAddr || getAssetInfo('DAI', 1).address);
199
+
200
+ return [encodedVaultId, encodedTargetRatio, encodedDaiAddr];
201
+ },
202
+ decode(subData: SubData): { vaultId: number, targetRatio: number, daiAddr: string } {
203
+ const vaultId = +AbiCoder.decodeParameter('uint256', subData[0])!.toString();
204
+ const targetRatio = weiToRatioPercentage(AbiCoder.decodeParameter('uint256', subData[1]) as any as string);
205
+ const daiAddr = AbiCoder.decodeParameter('address', subData[2])!.toString();
206
+
207
+ return { vaultId, targetRatio, daiAddr };
208
+ },
209
+ };
210
+
211
+
187
212
  /**
188
213
  __ __ ______ __ __ __ .___________.____ ____ ____ ____ __
189
214
  | | | | / __ \ | | | | | | | |\ \ / / \ \ / / /_ |
@@ -207,6 +232,30 @@ export const liquityLeverageManagementSubData = {
207
232
  return { targetRatio };
208
233
  },
209
234
  };
235
+ export const liquityLeverageManagementSubDataWithoutSubProxy = {
236
+ encode(
237
+ targetRatio: number,
238
+ ratioState: RatioState,
239
+ ): SubData {
240
+ const encodedRatioState = AbiCoder.encodeParameter('uint8', ratioState);
241
+ const encodedTargetRatio = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
242
+
243
+ const isRepay = ratioState === RatioState.UNDER;
244
+ const collActionType = isRepay ? CollActionType.WITHDRAW : CollActionType.SUPPLY;
245
+ const debtActionType = isRepay ? DebtActionType.PAYBACK : DebtActionType.BORROW;
246
+
247
+ const collActionTypeEncoded = AbiCoder.encodeParameter('uint8', collActionType);
248
+ const debtActionTypeEncoded = AbiCoder.encodeParameter('uint8', debtActionType);
249
+
250
+ return [encodedRatioState, encodedTargetRatio, collActionTypeEncoded, debtActionTypeEncoded];
251
+ },
252
+ decode(subData: SubData): { targetRatio: number, ratioState: RatioState } {
253
+ const ratioState = AbiCoder.decodeParameter('uint8', subData[0]) as any as RatioState;
254
+ const targetRatio = weiToRatioPercentage(AbiCoder.decodeParameter('uint256', subData[1]) as any as string);
255
+
256
+ return { targetRatio, ratioState };
257
+ },
258
+ };
210
259
  export const liquityCloseSubData = {
211
260
  encode(
212
261
  closeToAssetAddr: EthereumAddress,
@@ -510,6 +559,33 @@ export const aaveV2LeverageManagementSubData = {
510
559
  return { targetRatio };
511
560
  },
512
561
  };
562
+ export const aaveV2LeverageManagementSubDataWithoutSubProxy = {
563
+ encode(
564
+ market: EthereumAddress,
565
+ targetRatio: number,
566
+ ratioState: RatioState,
567
+ ): SubData {
568
+ const encodedMarket = AbiCoder.encodeParameter('address', market);
569
+ const encodedTargetRatio = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
570
+ const encodedRatioState = AbiCoder.encodeParameter('uint8', ratioState);
571
+
572
+ const isBoost = ratioState === RatioState.OVER;
573
+
574
+ if (isBoost) {
575
+ const enableAsCollEncoded = AbiCoder.encodeParameter('uint256', 1);
576
+ return [encodedMarket, encodedTargetRatio, encodedRatioState, enableAsCollEncoded];
577
+ }
578
+
579
+ return [encodedMarket, encodedTargetRatio, encodedRatioState];
580
+ },
581
+ decode(subData: SubData): { market: EthereumAddress, targetRatio: number, ratioState: RatioState } {
582
+ const market = AbiCoder.decodeParameter('address', subData[0]) as any as EthereumAddress;
583
+ const targetRatio = weiToRatioPercentage(AbiCoder.decodeParameter('uint256', subData[1]) as any as string);
584
+ const ratioState = AbiCoder.decodeParameter('uint8', subData[2]) as any as RatioState;
585
+
586
+ return { market, targetRatio, ratioState };
587
+ },
588
+ };
513
589
 
514
590
  /**
515
591
  ___ ___ ____ ____ _______ ____ ____ ____
@@ -527,6 +603,9 @@ export const aaveV3LeverageManagementSubData = {
527
603
  return { targetRatio };
528
604
  },
529
605
  };
606
+
607
+ // ! Any change here will PROBABLY require a change in aaveV3LiquidationProtectionSubData as well
608
+ // ! Double check before changing. Liquidation protection is using Generic encoding for both - EOA and SW
530
609
  export const aaveV3LeverageManagementSubDataWithoutSubProxy = {
531
610
  encode(
532
611
  targetRatio: number,
@@ -554,6 +633,30 @@ export const aaveV3LeverageManagementSubDataWithoutSubProxy = {
554
633
  return { targetRatio, ratioState };
555
634
  },
556
635
  };
636
+
637
+ export const aaveV3LiquidationProtectionSubData = {
638
+ encode(
639
+ targetRatio: number,
640
+ ratioState: RatioState,
641
+ market: EthereumAddress,
642
+ user: EthereumAddress,
643
+ ): SubData {
644
+ const encodedTargetRatio = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
645
+ const encodedRatioState = AbiCoder.encodeParameter('uint8', ratioState);
646
+ const encodedMarket = AbiCoder.encodeParameter('address', market);
647
+ const encodedUser = AbiCoder.encodeParameter('address', user);
648
+
649
+ return [encodedTargetRatio, encodedRatioState, encodedMarket, encodedUser];
650
+ },
651
+ decode(subData: SubData): { targetRatio: number, ratioState: RatioState } {
652
+ const targetRatio = weiToRatioPercentage(AbiCoder.decodeParameter('uint256', subData[0]) as any as string);
653
+ const ratioState = AbiCoder.decodeParameter('uint8', subData[1]) as any as RatioState;
654
+
655
+ return { targetRatio, ratioState };
656
+ },
657
+ };
658
+
659
+
557
660
  export const aaveV3LeverageManagementOnPriceGeneric = {
558
661
  encode(
559
662
  collAsset: EthereumAddress,
@@ -800,6 +903,9 @@ export const aaveV3LeverageManagementOnPriceSubData = {
800
903
  / _____ \ / _____ \ \ / | |____ \ / | |
801
904
  /__/ \__\ /__/ \__\ \__/ |_______| \__/ |_|
802
905
  */
906
+
907
+ // ! Any change here will PROBABLY require a change in aaveV4LiquidationProtectionSubData as well, since it is copy paste
908
+ // ! Double check before changing
803
909
  export const aaveV4LeverageManagementSubData = {
804
910
  encode: (
805
911
  spoke: EthereumAddress,
@@ -831,6 +937,39 @@ export const aaveV4LeverageManagementSubData = {
831
937
  };
832
938
  },
833
939
  };
940
+
941
+ export const aaveV4LiquidationProtectionSubData = {
942
+ encode: (
943
+ spoke: EthereumAddress,
944
+ owner: EthereumAddress,
945
+ ratioState: RatioState,
946
+ targetRatio: number,
947
+ ) => {
948
+ const spokeEncoded = AbiCoder.encodeParameter('address', spoke);
949
+ const ownerEncoded = AbiCoder.encodeParameter('address', owner);
950
+ const ratioStateEncoded = AbiCoder.encodeParameter('uint8', ratioState);
951
+ const targetRatioEncoded = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
952
+ // Add two empty slots for future addons (e.g tsi or slippage settings)
953
+ return [
954
+ spokeEncoded,
955
+ ownerEncoded,
956
+ ratioStateEncoded,
957
+ targetRatioEncoded,
958
+ EMPTY_SLOT,
959
+ EMPTY_SLOT,
960
+ ];
961
+ },
962
+ decode: (subData: SubData) => {
963
+ const spoke = AbiCoder.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
964
+ const owner = AbiCoder.decodeParameter('address', subData[1]) as unknown as EthereumAddress;
965
+ const ratioState = Number(AbiCoder.decodeParameter('uint8', subData[2])) as RatioState;
966
+ const targetRatio = weiToRatioPercentage(AbiCoder.decodeParameter('uint256', subData[3]) as any as string);
967
+ return {
968
+ spoke, owner, ratioState, targetRatio,
969
+ };
970
+ },
971
+ };
972
+
834
973
  export const aaveV4LeverageManagementOnPriceSubData = {
835
974
  encode: (
836
975
  spoke: EthereumAddress,
@@ -997,6 +1136,30 @@ export const compoundV2LeverageManagementSubData = {
997
1136
  return { targetRatio };
998
1137
  },
999
1138
  };
1139
+ export const compoundV2LeverageManagementSubDataWithoutSubProxy = {
1140
+ encode(
1141
+ targetRatio: number,
1142
+ ratioState: RatioState,
1143
+ ): SubData {
1144
+ const encodedTargetRatio = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
1145
+ const encodedRatioState = AbiCoder.encodeParameter('uint8', ratioState);
1146
+
1147
+ const isBoost = ratioState === RatioState.OVER;
1148
+
1149
+ if (isBoost) {
1150
+ const enableAsCollEncoded = AbiCoder.encodeParameter('uint256', 1);
1151
+ return [encodedTargetRatio, encodedRatioState, enableAsCollEncoded];
1152
+ }
1153
+
1154
+ return [encodedTargetRatio, encodedRatioState];
1155
+ },
1156
+ decode(subData: SubData): { targetRatio: number, ratioState: RatioState } {
1157
+ const targetRatio = weiToRatioPercentage(AbiCoder.decodeParameter('uint256', subData[0]) as any as string);
1158
+ const ratioState = AbiCoder.decodeParameter('uint8', subData[1]) as any as RatioState;
1159
+
1160
+ return { targetRatio, ratioState };
1161
+ },
1162
+ };
1000
1163
 
1001
1164
  /**
1002
1165
  ______ ______ .___ ___. .______ ____ ____ ____
@@ -1006,6 +1169,9 @@ export const compoundV2LeverageManagementSubData = {
1006
1169
  | `----.| `--' | | | | | | | \ / ___) |
1007
1170
  \______| \______/ |__| |__| | _| \__/ |____/
1008
1171
  */
1172
+
1173
+ // ! Any change here will PROBABLY require a change in compoundV3LiquidationProtectionSubData as well, since it is copy paste
1174
+ // ! Double check before changing
1009
1175
  export const compoundV3LeverageManagementSubData = {
1010
1176
  encode(
1011
1177
  market: EthereumAddress,
@@ -1035,11 +1201,70 @@ export const compoundV3LeverageManagementSubData = {
1035
1201
  return { targetRatio };
1036
1202
  },
1037
1203
  };
1038
- export const compoundV3L2LeverageManagementSubData = {
1204
+
1205
+ // ! Any change here will PROBABLY require a change in compoundV3L2LiquidationProtectionSubData as well, since it is copy paste
1206
+ // ! Double check before changing
1207
+ export const compoundV3LeverageManagementSubDataWithoutSubProxy = {
1208
+ encode(
1209
+ market: EthereumAddress,
1210
+ baseToken: EthereumAddress,
1211
+ targetRatio: number,
1212
+ ratioState: RatioState,
1213
+ ): SubData {
1214
+ const encodedMarket = AbiCoder.encodeParameter('address', market);
1215
+ const encodedBaseToken = AbiCoder.encodeParameter('address', baseToken);
1216
+ const encodedRatioState = AbiCoder.encodeParameter('uint8', ratioState);
1217
+ const encodedTargetRatio = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
1218
+ return [encodedMarket, encodedBaseToken, encodedRatioState, encodedTargetRatio];
1219
+ },
1220
+ decode(subData: SubData): { market: EthereumAddress, baseToken: EthereumAddress, targetRatio: number, ratioState: RatioState } {
1221
+ const market = AbiCoder.decodeParameter('address', subData[0]) as any as EthereumAddress;
1222
+ const baseToken = AbiCoder.decodeParameter('address', subData[1]) as any as EthereumAddress;
1223
+ const ratioState = AbiCoder.decodeParameter('uint8', subData[2]) as any as RatioState;
1224
+ const targetRatio = weiToRatioPercentage(AbiCoder.decodeParameter('uint256', subData[3]) as any as string);
1225
+
1226
+ return {
1227
+ market, baseToken, targetRatio, ratioState,
1228
+ };
1229
+ },
1230
+ };
1231
+
1232
+ export const compoundV3LiquidationProtectionSubData = {
1233
+ encode(
1234
+ market: EthereumAddress,
1235
+ baseToken: EthereumAddress,
1236
+ triggerRepayRatio: number,
1237
+ // TODO -> can remove boost stuff ? Not sure if want it to be compatible or not.
1238
+ triggerBoostRatio: number,
1239
+ targetBoostRatio: number,
1240
+ targetRepayRatio: number,
1241
+ boostEnabled: boolean,
1242
+ isEOA: boolean,
1243
+ ): SubData {
1244
+ return [
1245
+ market,
1246
+ baseToken,
1247
+ new Dec(triggerRepayRatio).mul(1e16).toString(),
1248
+ new Dec(triggerBoostRatio).mul(1e16).toString(),
1249
+ new Dec(targetBoostRatio).mul(1e16).toString(),
1250
+ new Dec(targetRepayRatio).mul(1e16).toString(),
1251
+ // @ts-ignore // TODO
1252
+ boostEnabled, isEOA,
1253
+ ];
1254
+ },
1255
+ decode(subData: SubData): { targetRatio: number } {
1256
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[3]) as any as string;
1257
+ const targetRatio = weiToRatioPercentage(weiRatio);
1258
+
1259
+ return { targetRatio };
1260
+ },
1261
+ };
1262
+ export const compoundV3L2LiquidationProtectionSubData = {
1039
1263
  encode(
1040
1264
  market: EthereumAddress,
1041
1265
  baseToken: EthereumAddress,
1042
1266
  triggerRepayRatio: number,
1267
+ // TODO -> can remove boost stuff ? Not sure if want it to be compatible or not.
1043
1268
  triggerBoostRatio: number,
1044
1269
  targetBoostRatio: number,
1045
1270
  targetRepayRatio: number,
@@ -1070,6 +1295,7 @@ export const compoundV3L2LeverageManagementSubData = {
1070
1295
  return { targetRatio };
1071
1296
  },
1072
1297
  };
1298
+
1073
1299
  export const compoundV3LeverageManagementOnPriceSubData = {
1074
1300
  encode(
1075
1301
  market: EthereumAddress,
@@ -1205,6 +1431,21 @@ export const exchangeLimitOrderSubData = {
1205
1431
  return { fromToken, toToken, amount };
1206
1432
  },
1207
1433
  };
1434
+ export const exchangeLimitOrderSubDataWithoutSubProxy = {
1435
+ encode(fromToken: EthereumAddress, toToken: EthereumAddress, amount: string): SubData {
1436
+ return [
1437
+ AbiCoder.encodeParameter('address', fromToken),
1438
+ AbiCoder.encodeParameter('address', toToken),
1439
+ AbiCoder.encodeParameter('uint256', amount),
1440
+ ];
1441
+ },
1442
+ decode: (subData: SubData, chainId: ChainId) => {
1443
+ const fromToken = AbiCoder.decodeParameter('address', subData[0])!.toString();
1444
+ const toToken = AbiCoder.decodeParameter('address', subData[1])!.toString();
1445
+ const amount = assetAmountInEth(AbiCoder.decodeParameter('uint256', subData[2])!.toString(), getAssetInfoByAddress(fromToken, chainId).symbol);
1446
+ return { fromToken, toToken, amount };
1447
+ },
1448
+ };
1208
1449
 
1209
1450
  /**
1210
1451
  _______..______ ___ .______ __ ___
@@ -1222,6 +1463,9 @@ export const sparkLeverageManagementSubData = {
1222
1463
  return { targetRatio };
1223
1464
  },
1224
1465
  };
1466
+
1467
+ // ! Any change here will PROBABLY require a change in sparkLiquidationProtectionSubData as well, since it is copy paste
1468
+ // ! Double check before changing
1225
1469
  export const sparkLeverageManagementSubDataWithoutSubProxy = {
1226
1470
  encode(
1227
1471
  targetRatio: number,
@@ -1241,6 +1485,28 @@ export const sparkLeverageManagementSubDataWithoutSubProxy = {
1241
1485
  return { targetRatio, ratioState };
1242
1486
  },
1243
1487
  };
1488
+
1489
+ export const sparkLiquidationProtectionSubData = {
1490
+ encode(
1491
+ targetRatio: number,
1492
+ ratioState: RatioState,
1493
+ ): SubData {
1494
+ const encodedTargetRatio = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
1495
+ const encodedRatioState = AbiCoder.encodeParameter('uint8', ratioState);
1496
+ const encodedUseDefaultMarket = AbiCoder.encodeParameter('bool', true);
1497
+ const encodedUseOnBehalf = AbiCoder.encodeParameter('bool', false);
1498
+
1499
+ return [encodedTargetRatio, encodedRatioState, encodedUseDefaultMarket, encodedUseOnBehalf];
1500
+ },
1501
+ decode(subData: SubData): { targetRatio: number, ratioState: RatioState } {
1502
+ const targetRatio = weiToRatioPercentage(AbiCoder.decodeParameter('uint256', subData[0]) as any as string);
1503
+ const ratioState = AbiCoder.decodeParameter('uint8', subData[1]) as any as RatioState;
1504
+
1505
+ return { targetRatio, ratioState };
1506
+ },
1507
+ };
1508
+
1509
+
1244
1510
  export const sparkCloseGenericSubData = {
1245
1511
  encode(
1246
1512
  collAsset: EthereumAddress,
@@ -1455,6 +1721,9 @@ export const crvUSDPaybackSubData = {
1455
1721
  | | | | | `--' | | |\ \----.| | | | | | | `--' |
1456
1722
  |__| |__| \______/ | _| `._____|| _| |__| |__| \______/
1457
1723
  */
1724
+
1725
+ // ! Any change here will PROBABLY require a change in morphoBlueLiquidationProtectionSubData as well, since it is copy paste
1726
+ // ! Double check before changing
1458
1727
  export const morphoBlueLeverageManagementSubData = {
1459
1728
  encode: (
1460
1729
  loanToken: EthereumAddress,
@@ -1499,6 +1768,53 @@ export const morphoBlueLeverageManagementSubData = {
1499
1768
  };
1500
1769
  },
1501
1770
  };
1771
+
1772
+ export const morphoBlueLiquidationProtectionSubData = {
1773
+ encode: (
1774
+ loanToken: EthereumAddress,
1775
+ collToken: EthereumAddress,
1776
+ oracle: EthereumAddress,
1777
+ irm: EthereumAddress,
1778
+ lltv: string,
1779
+ ratioState: RatioState,
1780
+ targetRatio: number,
1781
+ user: EthereumAddress,
1782
+ isEOA: boolean,
1783
+ ) => {
1784
+ const loanTokenEncoded = AbiCoder.encodeParameter('address', loanToken);
1785
+ const collTokenEncoded = AbiCoder.encodeParameter('address', collToken);
1786
+ const oracleEncoded = AbiCoder.encodeParameter('address', oracle);
1787
+ const irmEncoded = AbiCoder.encodeParameter('address', irm);
1788
+ const lltvEncoded = AbiCoder.encodeParameter('uint256', lltv);
1789
+ const ratioStateEncoded = AbiCoder.encodeParameter('uint8', ratioState);
1790
+ const targetRatioEncoded = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
1791
+ const userEncoded = AbiCoder.encodeParameter('address', user);
1792
+ const isEOAEncoded = AbiCoder.encodeParameter('bool', isEOA);
1793
+ return [loanTokenEncoded, collTokenEncoded, oracleEncoded, irmEncoded, lltvEncoded, ratioStateEncoded, targetRatioEncoded, userEncoded, isEOAEncoded];
1794
+ },
1795
+ decode: (subData: SubData) => {
1796
+ const loanToken = AbiCoder.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
1797
+ const collToken = AbiCoder.decodeParameter('address', subData[1]) as any as EthereumAddress;
1798
+ const oracle = AbiCoder.decodeParameter('address', subData[2]) as any as EthereumAddress;
1799
+ const irm = AbiCoder.decodeParameter('address', subData[3]) as any as EthereumAddress;
1800
+ const lltv = AbiCoder.decodeParameter('uint256', subData[4]) as any as EthereumAddress;
1801
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[6]) as any as EthereumAddress;
1802
+ const user = AbiCoder.decodeParameter('address', subData[7]) as any as EthereumAddress;
1803
+ const targetRatio = weiToRatioPercentage(weiRatio);
1804
+
1805
+ return {
1806
+ loanToken,
1807
+ collToken,
1808
+ oracle,
1809
+ irm,
1810
+ lltv,
1811
+ user,
1812
+ targetRatio,
1813
+ };
1814
+ },
1815
+ };
1816
+
1817
+
1502
1818
  export const morphoBlueLeverageManagementOnPriceSubData = {
1503
1819
  encode(
1504
1820
  loanToken: EthereumAddress,
@@ -1587,6 +1903,8 @@ _______ __ __ __ __ _______
1587
1903
  | | | `----.| `--' | | | | '--' |
1588
1904
  |__| |_______| \______/ |__| |_______/
1589
1905
  */
1906
+ // ! Any change here will PROBABLY require a change in fluidLeverageManagementSubData as well, since it is copy paste
1907
+ // ! Double check before changing
1590
1908
  export const fluidLeverageManagementSubData = {
1591
1909
  encode: (
1592
1910
  nftId: string,
@@ -1600,9 +1918,50 @@ export const fluidLeverageManagementSubData = {
1600
1918
  const targetRatioEncoded = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
1601
1919
  const wrapEthEncoded = AbiCoder.encodeParameter('bool', true);
1602
1920
 
1603
- const isRepay = ratioState === RatioState.UNDER;
1604
- const collActionType = isRepay ? CollActionType.WITHDRAW : CollActionType.SUPPLY;
1605
- const debtActionType = isRepay ? DebtActionType.PAYBACK : DebtActionType.BORROW;
1921
+ const collActionType = CollActionType.WITHDRAW;
1922
+ const debtActionType = DebtActionType.PAYBACK;
1923
+
1924
+ const collActionTypeEncoded = AbiCoder.encodeParameter('uint8', collActionType);
1925
+ const debtActionTypeEncoded = AbiCoder.encodeParameter('uint8', debtActionType);
1926
+
1927
+ return [
1928
+ nftIdEncoded,
1929
+ vaultEncoded,
1930
+ ratioStateEncoded,
1931
+ targetRatioEncoded,
1932
+ wrapEthEncoded,
1933
+ collActionTypeEncoded,
1934
+ debtActionTypeEncoded,
1935
+ ];
1936
+ },
1937
+ decode: (subData: SubData) => {
1938
+ const nftId = AbiCoder.decodeParameter('uint256', subData[0]) as any as string;
1939
+ const vault = AbiCoder.decodeParameter('address', subData[1]) as unknown as EthereumAddress;
1940
+ const ratioState = AbiCoder.decodeParameter('uint8', subData[2]) as any as RatioState;
1941
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[3]) as any as string;
1942
+ const targetRatio = weiToRatioPercentage(weiRatio);
1943
+
1944
+ return {
1945
+ nftId, vault, ratioState, targetRatio,
1946
+ };
1947
+ },
1948
+ };
1949
+
1950
+ export const fluidLiquidationProtectionSubData = {
1951
+ encode: (
1952
+ nftId: string,
1953
+ vault: EthereumAddress,
1954
+ ratioState: RatioState,
1955
+ targetRatio: number,
1956
+ ) => {
1957
+ const nftIdEncoded = AbiCoder.encodeParameter('uint256', nftId);
1958
+ const vaultEncoded = AbiCoder.encodeParameter('address', vault);
1959
+ const ratioStateEncoded = AbiCoder.encodeParameter('uint8', ratioState);
1960
+ const targetRatioEncoded = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
1961
+ const wrapEthEncoded = AbiCoder.encodeParameter('bool', true);
1962
+
1963
+ const collActionType = CollActionType.WITHDRAW;
1964
+ const debtActionType = DebtActionType.PAYBACK;
1606
1965
 
1607
1966
  const collActionTypeEncoded = AbiCoder.encodeParameter('uint8', collActionType);
1608
1967
  const debtActionTypeEncoded = AbiCoder.encodeParameter('uint8', debtActionType);
@@ -2,7 +2,7 @@ import { expect } from 'chai';
2
2
  import { getAssetInfo } from '@defisaver/tokens';
3
3
 
4
4
  import type { EthereumAddress } from '../types';
5
- import { ChainId, ProtocolIdentifiers, RatioState } from '../types/enums';
5
+ import { Bundles, ChainId, ProtocolIdentifiers, RatioState } from '../types/enums';
6
6
 
7
7
  import '../configuration';
8
8
  import {
@@ -11,6 +11,7 @@ import {
11
11
  compareAddresses,
12
12
  encodeSubId,
13
13
  ethToWeth,
14
+ getCompoundV3LeverageManagementBundleId,
14
15
  getRatioStateInfoForAaveCloseStrategy,
15
16
  isAddress,
16
17
  isDefined,
@@ -369,4 +370,34 @@ describe('Feature: utils.ts', () => {
369
370
  });
370
371
  });
371
372
  });
373
+
374
+ describe('When testing utils.getCompoundV3LeverageManagementBundleId()', () => {
375
+ // Mainnet uses the V2 bundle ids; L2s use the original bundle ids.
376
+ const examples: Array<[number, [network: ChainId, isEOA: boolean, isBoost: boolean]]> = [
377
+ [Bundles.MainnetIds.COMP_V3_SW_REPAY_V2_BUNDLE, [ChainId.Ethereum, false, false]],
378
+ [Bundles.MainnetIds.COMP_V3_SW_BOOST_V2_BUNDLE, [ChainId.Ethereum, false, true]],
379
+ [Bundles.MainnetIds.COMP_V3_EOA_REPAY_V2_BUNDLE, [ChainId.Ethereum, true, false]],
380
+ [Bundles.MainnetIds.COMP_V3_EOA_BOOST_V2_BUNDLE, [ChainId.Ethereum, true, true]],
381
+
382
+ [Bundles.BaseIds.COMP_V3_SW_REPAY_BUNDLE, [ChainId.Base, false, false]],
383
+ [Bundles.BaseIds.COMP_V3_SW_BOOST_BUNDLE, [ChainId.Base, false, true]],
384
+ [Bundles.BaseIds.COMP_V3_EOA_REPAY, [ChainId.Base, true, false]],
385
+ [Bundles.BaseIds.COMP_V3_EOA_BOOST, [ChainId.Base, true, true]],
386
+
387
+ [Bundles.ArbitrumIds.COMP_V3_SW_REPAY_BUNDLE, [ChainId.Arbitrum, false, false]],
388
+ [Bundles.ArbitrumIds.COMP_V3_SW_BOOST_BUNDLE, [ChainId.Arbitrum, false, true]],
389
+ [Bundles.ArbitrumIds.COMP_V3_EOA_REPAY, [ChainId.Arbitrum, true, false]],
390
+ [Bundles.ArbitrumIds.COMP_V3_EOA_BOOST, [ChainId.Arbitrum, true, true]],
391
+ ];
392
+
393
+ examples.forEach(([expected, actual]) => {
394
+ it(`Given ${actual} should return expected value: ${expected}`, () => {
395
+ expect(getCompoundV3LeverageManagementBundleId(...actual)).to.equal(expected);
396
+ });
397
+ });
398
+
399
+ it(`Given ${ChainId.Optimism} (unsupported) should throw an error`, () => {
400
+ expect(() => getCompoundV3LeverageManagementBundleId(ChainId.Optimism, false, false)).to.throw(Error);
401
+ });
402
+ });
372
403
  });
@@ -5,6 +5,7 @@ import { getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
5
5
 
6
6
  import type { EthereumAddress } from '../types';
7
7
  import {
8
+ Bundles,
8
9
  ChainId, CloseStrategyType, CloseToAssetType, RatioState,
9
10
  } from '../types/enums';
10
11
 
@@ -171,4 +172,34 @@ export function getStopLossAndTakeProfitTypeByCloseStrategyType(
171
172
  default:
172
173
  throw new Error('CloseStrategyType not supported');
173
174
  }
174
- }
175
+ }
176
+
177
+ export function getBundleIdsByNetwork(network: ChainId) {
178
+ switch (network) {
179
+ case ChainId.Arbitrum:
180
+ return Bundles.ArbitrumIds;
181
+ case ChainId.Base:
182
+ return Bundles.BaseIds;
183
+ case ChainId.Optimism:
184
+ return Bundles.OptimismIds;
185
+ default:
186
+ return Bundles.MainnetIds;
187
+ }
188
+ }
189
+
190
+ // Mainnet uses the V2 bundle ids; L2s use the original bundle ids.
191
+ export function getCompoundV3LeverageManagementBundleId(network: ChainId, isEOA: boolean, isBoost: boolean): number {
192
+ switch (Number(network)) {
193
+ case ChainId.Ethereum:
194
+ if (isEOA) return isBoost ? Bundles.MainnetIds.COMP_V3_EOA_BOOST_V2_BUNDLE : Bundles.MainnetIds.COMP_V3_EOA_REPAY_V2_BUNDLE;
195
+ return isBoost ? Bundles.MainnetIds.COMP_V3_SW_BOOST_V2_BUNDLE : Bundles.MainnetIds.COMP_V3_SW_REPAY_V2_BUNDLE;
196
+ case ChainId.Base:
197
+ if (isEOA) return isBoost ? Bundles.BaseIds.COMP_V3_EOA_BOOST : Bundles.BaseIds.COMP_V3_EOA_REPAY;
198
+ return isBoost ? Bundles.BaseIds.COMP_V3_SW_BOOST_BUNDLE : Bundles.BaseIds.COMP_V3_SW_REPAY_BUNDLE;
199
+ case ChainId.Arbitrum:
200
+ if (isEOA) return isBoost ? Bundles.ArbitrumIds.COMP_V3_EOA_BOOST : Bundles.ArbitrumIds.COMP_V3_EOA_REPAY;
201
+ return isBoost ? Bundles.ArbitrumIds.COMP_V3_SW_BOOST_BUNDLE : Bundles.ArbitrumIds.COMP_V3_SW_REPAY_BUNDLE;
202
+ default:
203
+ throw new Error(`Compound V3 leverage management is not supported on network ${network}`);
204
+ }
205
+ }
@@ -153,6 +153,8 @@ export namespace Strategies {
153
153
  EoaRepayOnPrice = 'eoa-repay-on-price',
154
154
  CollateralSwitch = 'collateral-switch',
155
155
  EoaCollateralSwitch = 'eoa-collateral-switch',
156
+ LiquidationProtection = 'liquidation-protection',
157
+ EoaLiquidationProtection = 'eoa-liquidation-protection',
156
158
  }
157
159
  export enum IdOverrides {
158
160
  TakeProfit = 'take-profit',
@@ -164,6 +166,8 @@ export namespace Strategies {
164
166
  EoaLeverageManagement = 'leverage-management-eoa',
165
167
  LeverageManagementOnPrice = 'leverage-management-on-price',
166
168
  EoaLeverageManagementOnPrice = 'leverage-management-on-price-eoa',
169
+ LiquidationProtection = 'liquidation-protection',
170
+ EoaLiquidationProtection = 'liquidation-protection-eoa',
167
171
  }
168
172
  }
169
173
 
@@ -240,6 +244,14 @@ export namespace Bundles {
240
244
  AAVE_V4_EOA_REPAY_ON_PRICE = 68,
241
245
  AAVE_V4_EOA_BOOST_ON_PRICE = 69,
242
246
  AAVE_V4_EOA_CLOSE = 70,
247
+ AAVE_V3_LIQUIDATION_PROTECTION = 71,
248
+ SPARK_LIQUIDATION_PROTECTION = 72,
249
+ COMP_V3_SW_LIQUIDATION_PROTECTION = 73,
250
+ COMP_V3_EOA_LIQUIDATION_PROTECTION = 74,
251
+ MAKER_LIQUIDATION_PROTECTION = 75,
252
+ FLUID_T1_LIQUIDATION_PROTECTION = 76,
253
+ AAVE_V4_LIQUIDATION_PROTECTION = 77,
254
+ MORPHO_BLUE_LIQUIDATION_PROTECTION = 78,
243
255
  }
244
256
 
245
257
  export enum OptimismIds {
@@ -254,6 +266,7 @@ export namespace Bundles {
254
266
  AAVE_V3_EOA_REPAY_ON_PRICE = 8,
255
267
  AAVE_V3_EOA_BOOST_ON_PRICE = 9,
256
268
  AAVE_V3_EOA_CLOSE = 10,
269
+ AAVE_V3_LIQUIDATION_PROTECTION = 11,
257
270
  }
258
271
 
259
272
  export enum BaseIds {
@@ -284,6 +297,11 @@ export namespace Bundles {
284
297
  AAVE_V3_EOA_BOOST_ON_PRICE = 26,
285
298
  AAVE_V3_EOA_CLOSE = 27,
286
299
  MORPHO_BLUE_CLOSE = 28,
300
+ AAVE_V3_LIQUIDATION_PROTECTION = 29,
301
+ FLUID_T1_LIQUIDATION_PROTECTION = 30,
302
+ MORPHO_BLUE_LIQUIDATION_PROTECTION = 31,
303
+ COMP_V3_SW_LIQUIDATION_PROTECTION = 32,
304
+ COMP_V3_EOA_LIQUIDATION_PROTECTION = 33,
287
305
  }
288
306
 
289
307
  export enum ArbitrumIds {
@@ -316,6 +334,11 @@ export namespace Bundles {
316
334
  MORPHO_BLUE_EOA_REPAY = 26,
317
335
  MORPHO_BLUE_EOA_BOOST = 27,
318
336
  MORPHO_BLUE_CLOSE = 28,
337
+ AAVE_V3_LIQUIDATION_PROTECTION = 29,
338
+ FLUID_T1_LIQUIDATION_PROTECTION = 30,
339
+ MORPHO_BLUE_LIQUIDATION_PROTECTION = 31,
340
+ COMP_V3_SW_LIQUIDATION_PROTECTION = 32,
341
+ COMP_V3_EOA_LIQUIDATION_PROTECTION = 33,
319
342
  }
320
343
  }
321
344