@defisaver/automation-sdk 3.1.4 → 3.1.6-fluid-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 (44) hide show
  1. package/cjs/automation/private/StrategiesAutomation.d.ts +2 -2
  2. package/cjs/automation/public/Strategies.test.d.ts +1 -0
  3. package/cjs/automation/public/Strategies.test.js +61 -0
  4. package/cjs/constants/index.js +45 -0
  5. package/cjs/services/strategiesService.js +155 -0
  6. package/cjs/services/strategySubService.d.ts +10 -1
  7. package/cjs/services/strategySubService.js +35 -1
  8. package/cjs/services/subDataService.d.ts +55 -1
  9. package/cjs/services/subDataService.js +174 -1
  10. package/cjs/services/triggerService.d.ts +43 -0
  11. package/cjs/services/triggerService.js +81 -1
  12. package/cjs/services/utils.d.ts +6 -1
  13. package/cjs/services/utils.js +52 -1
  14. package/cjs/types/enums.d.ts +38 -3
  15. package/cjs/types/enums.js +40 -1
  16. package/cjs/types/index.d.ts +16 -3
  17. package/esm/automation/private/StrategiesAutomation.d.ts +2 -2
  18. package/esm/automation/public/Strategies.test.d.ts +1 -0
  19. package/esm/automation/public/Strategies.test.js +56 -0
  20. package/esm/constants/index.js +45 -0
  21. package/esm/services/strategiesService.js +153 -1
  22. package/esm/services/strategySubService.d.ts +10 -1
  23. package/esm/services/strategySubService.js +36 -2
  24. package/esm/services/subDataService.d.ts +55 -1
  25. package/esm/services/subDataService.js +174 -1
  26. package/esm/services/triggerService.d.ts +43 -0
  27. package/esm/services/triggerService.js +80 -0
  28. package/esm/services/utils.d.ts +6 -1
  29. package/esm/services/utils.js +50 -1
  30. package/esm/types/enums.d.ts +38 -3
  31. package/esm/types/enums.js +39 -0
  32. package/esm/types/index.d.ts +16 -3
  33. package/package.json +3 -3
  34. package/src/automation/private/StrategiesAutomation.ts +2 -2
  35. package/src/automation/public/Strategies.test.ts +49 -0
  36. package/src/constants/index.ts +45 -0
  37. package/src/services/strategiesService.ts +199 -1
  38. package/src/services/strategySubService.ts +97 -1
  39. package/src/services/subDataService.ts +243 -2
  40. package/src/services/triggerService.ts +125 -0
  41. package/src/services/utils.ts +60 -1
  42. package/src/types/enums.ts +39 -0
  43. package/src/types/index.ts +20 -2
  44. package/umd/index.js +34219 -0
@@ -1,6 +1,7 @@
1
1
  import { getAssetInfoByAddress } from '@defisaver/tokens';
2
2
  import { cloneDeep } from 'lodash';
3
3
 
4
+ import Web3 from 'web3';
4
5
  import { BUNDLES_INFO, STRATEGIES_INFO } from '../constants';
5
6
  import type {
6
7
  Position, ParseData, StrategiesToProtocolVersionMapping, BundleOrStrategy, StrategyOrBundleIds,
@@ -9,11 +10,13 @@ import type {
9
10
  import { ChainId, ProtocolIdentifiers, Strategies } from '../types/enums';
10
11
 
11
12
  import {
12
- getPositionId, getRatioStateInfoForAaveCloseStrategy, isRatioStateOver, wethToEthByAddress,
13
+ getPositionId, getRatioStateInfoForAaveCloseStrategy, getStopLossAndTakeProfitTypeByCloseStrategyType, isRatioStateOver, wethToEthByAddress,
13
14
  } from './utils';
14
15
  import * as subDataService from './subDataService';
15
16
  import * as triggerService from './triggerService';
16
17
 
18
+ const web3 = new Web3();
19
+
17
20
  const SPARK_MARKET_ADDRESSES = {
18
21
  [ChainId.Ethereum]: '0x02C3eA4e34C0cBd694D2adFa2c690EECbC1793eE',
19
22
  };
@@ -563,6 +566,49 @@ function parseLiquityLeverageManagement(position: Position.Automated, parseData:
563
566
  return _position;
564
567
  }
565
568
 
569
+ function parseLiquityV2LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
570
+ const _position = cloneDeep(position);
571
+
572
+ const { subStruct, subId, subHash } = parseData.subscriptionEventData;
573
+ const { isEnabled } = parseData.strategiesSubsData;
574
+
575
+ const triggerData = triggerService.liquityV2RatioTrigger.decode(subStruct.triggerData);
576
+ const subData = subDataService.liquityV2LeverageManagementSubData.decode(subStruct.subData);
577
+
578
+ _position.strategyData.decoded.triggerData = triggerData;
579
+ _position.strategyData.decoded.subData = subData;
580
+
581
+ _position.positionId = getPositionId(
582
+ _position.chainId, _position.protocol.id, _position.owner, triggerData.troveId, triggerData.market,
583
+ );
584
+
585
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
586
+
587
+ if (isRepay) {
588
+ _position.specific = {
589
+ triggerRepayRatio: triggerData.ratio,
590
+ targetRepayRatio: subData.targetRatio,
591
+ repayEnabled: isEnabled,
592
+ subId1: Number(subId),
593
+ subHashRepay: subHash,
594
+ mergeWithId: Strategies.Identifiers.Boost,
595
+ };
596
+ } else {
597
+ _position.specific = {
598
+ triggerBoostRatio: triggerData.ratio,
599
+ targetBoostRatio: subData.targetRatio,
600
+ boostEnabled: isEnabled,
601
+ subId2: Number(subId),
602
+ subHashBoost: subHash,
603
+ mergeId: Strategies.Identifiers.Boost,
604
+ };
605
+ }
606
+
607
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
608
+
609
+ return _position;
610
+ }
611
+
566
612
  function parseSparkLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
567
613
  const _position = cloneDeep(position);
568
614
 
@@ -779,6 +825,42 @@ function parseMorphoBlueLeverageManagement(position: Position.Automated, parseDa
779
825
  return _position;
780
826
  }
781
827
 
828
+ function parseMorphoBlueLeverageManagementOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
829
+ const _position = cloneDeep(position);
830
+
831
+ const { subStruct } = parseData.subscriptionEventData;
832
+ const triggerData = triggerService.morphoBluePriceTrigger.decode(subStruct.triggerData);
833
+ const subData = subDataService.morphoBlueLeverageManagementOnPriceSubData.decode(subStruct.subData);
834
+
835
+ _position.strategyData.decoded.triggerData = triggerData;
836
+ _position.strategyData.decoded.subData = subData;
837
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, Math.random());
838
+
839
+ const marketIdEncodedData = web3.eth.abi.encodeParameters(
840
+ ['address', 'address', 'address', 'address', 'uint256'],
841
+ [
842
+ subData.loanToken,
843
+ subData.collToken,
844
+ subData.oracle,
845
+ subData.irm,
846
+ subData.lltv,
847
+ ],
848
+ );
849
+
850
+ const marketId = web3.utils.keccak256(marketIdEncodedData);
851
+
852
+ _position.specific = {
853
+ subHash: _position.subHash,
854
+ marketId,
855
+ collAsset: subData.collToken,
856
+ debtAsset: subData.loanToken,
857
+ price: triggerData.price,
858
+ ratio: subData.targetRatio,
859
+ };
860
+
861
+ return _position;
862
+ }
863
+
782
864
  function parseAaveV3LeverageManagementOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
783
865
  const _position = cloneDeep(position);
784
866
 
@@ -806,6 +888,110 @@ function parseAaveV3LeverageManagementOnPrice(position: Position.Automated, pars
806
888
  return _position;
807
889
  }
808
890
 
891
+ function parseLiquityV2CloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
892
+ const _position = cloneDeep(position);
893
+
894
+ const { subStruct } = parseData.subscriptionEventData;
895
+
896
+ const triggerData = triggerService.closePriceTrigger.decode(subStruct.triggerData);
897
+ const subData = subDataService.liquityV2CloseSubData.decode(subStruct.subData);
898
+
899
+ _position.strategyData.decoded.triggerData = triggerData;
900
+ _position.strategyData.decoded.subData = subData;
901
+
902
+ _position.positionId = getPositionId(
903
+ _position.chainId, _position.protocol.id, _position.owner, subData.troveId, subData.market,
904
+ );
905
+
906
+ const { takeProfitType, stopLossType } = getStopLossAndTakeProfitTypeByCloseStrategyType(+subData.closeType);
907
+
908
+ // User can have:
909
+ // - Only TakeProfit
910
+ // - Only StopLoss
911
+ // - Both
912
+ // TODO: see on frontend what specific data we need here because stop-loss and take-profit is one bundle now
913
+ _position.strategy.strategyId = Strategies.Identifiers.CloseOnPrice;
914
+ _position.specific = {
915
+ market: subData.market,
916
+ troveId: subData.troveId,
917
+ stopLossPrice: triggerData.lowerPrice,
918
+ takeProfitPrice: triggerData.upperPrice,
919
+ closeToAssetAddr: triggerData.tokenAddr,
920
+ takeProfitType,
921
+ stopLossType,
922
+ };
923
+
924
+ return _position;
925
+ }
926
+
927
+ function parseLiquityV2LeverageManagementOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
928
+ const _position = cloneDeep(position);
929
+
930
+ const { subStruct } = parseData.subscriptionEventData;
931
+
932
+ const triggerData = triggerService.liquityV2QuotePriceTrigger.decode(subStruct.triggerData);
933
+ const subData = subDataService.liquityV2LeverageManagementOnPriceSubData.decode(subStruct.subData);
934
+
935
+ _position.strategyData.decoded.triggerData = triggerData;
936
+ _position.strategyData.decoded.subData = subData;
937
+ _position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, Math.random());
938
+ /// @TODO: what does even go here
939
+ /*
940
+ _position.specific = {
941
+ market: subData.market,
942
+ troveId: subData.troveId,
943
+ ratio: subData.targetRatio,
944
+ price: triggerData.price,
945
+ ratioState: triggerData.ratioState,
946
+ };
947
+ */
948
+
949
+ return _position;
950
+ }
951
+
952
+ function parseFluidT1LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
953
+ const _position = cloneDeep(position);
954
+
955
+ const { subStruct, subId, subHash } = parseData.subscriptionEventData;
956
+ const { isEnabled } = parseData.strategiesSubsData;
957
+
958
+ const triggerData = triggerService.fluidRatioTrigger.decode(subStruct.triggerData);
959
+ const subData = subDataService.fluidLeverageManagementSubData.decode(subStruct.subData);
960
+
961
+ _position.strategyData.decoded.triggerData = triggerData;
962
+ _position.strategyData.decoded.subData = subData;
963
+
964
+ _position.positionId = getPositionId(
965
+ _position.chainId, _position.protocol.id, _position.owner, triggerData.nftId, subData.vault,
966
+ );
967
+
968
+ const isRepay = _position.strategy.strategyId === Strategies.Identifiers.Repay;
969
+
970
+ if (isRepay) {
971
+ _position.specific = {
972
+ triggerRepayRatio: triggerData.ratio,
973
+ targetRepayRatio: subData.targetRatio,
974
+ repayEnabled: isEnabled,
975
+ subId1: Number(subId),
976
+ subHashRepay: subHash,
977
+ mergeWithId: Strategies.Identifiers.Boost,
978
+ };
979
+ } else {
980
+ _position.specific = {
981
+ triggerBoostRatio: triggerData.ratio,
982
+ targetBoostRatio: subData.targetRatio,
983
+ boostEnabled: isEnabled,
984
+ subId2: Number(subId),
985
+ subHashBoost: subHash,
986
+ mergeId: Strategies.Identifiers.Boost,
987
+ };
988
+ }
989
+
990
+ _position.strategy.strategyId = Strategies.IdOverrides.LeverageManagement;
991
+
992
+ return _position;
993
+ }
994
+
809
995
  const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
810
996
  [ProtocolIdentifiers.StrategiesAutomation.MakerDAO]: {
811
997
  [Strategies.Identifiers.SavingsLiqProtection]: parseMakerSavingsLiqProtection,
@@ -826,6 +1012,13 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
826
1012
  [Strategies.Identifiers.SavingsDsrSupply]: parseLiquitySavingsLiqProtection,
827
1013
  [Strategies.Identifiers.DebtInFrontRepay]: parseLiquityDebtInFrontRepay,
828
1014
  },
1015
+ [ProtocolIdentifiers.StrategiesAutomation.LiquityV2]: {
1016
+ [Strategies.Identifiers.Repay]: parseLiquityV2LeverageManagement,
1017
+ [Strategies.Identifiers.Boost]: parseLiquityV2LeverageManagement,
1018
+ [Strategies.Identifiers.CloseOnPrice]: parseLiquityV2CloseOnPrice,
1019
+ [Strategies.Identifiers.OpenOrderFromCollateral]: parseLiquityV2LeverageManagementOnPrice,
1020
+ [Strategies.Identifiers.RepayOnPrice]: parseLiquityV2LeverageManagementOnPrice,
1021
+ },
829
1022
  [ProtocolIdentifiers.StrategiesAutomation.AaveV2]: {
830
1023
  [Strategies.Identifiers.Repay]: parseAaveV2LeverageManagement,
831
1024
  [Strategies.Identifiers.Boost]: parseAaveV2LeverageManagement,
@@ -877,6 +1070,11 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
877
1070
  [Strategies.Identifiers.Boost]: parseMorphoBlueLeverageManagement,
878
1071
  [Strategies.Identifiers.EoaRepay]: parseMorphoBlueLeverageManagement,
879
1072
  [Strategies.Identifiers.EoaBoost]: parseMorphoBlueLeverageManagement,
1073
+ [Strategies.Identifiers.BoostOnPrice]: parseMorphoBlueLeverageManagementOnPrice,
1074
+ },
1075
+ [ProtocolIdentifiers.StrategiesAutomation.FluidT1]: {
1076
+ [Strategies.Identifiers.Repay]: parseFluidT1LeverageManagement,
1077
+ [Strategies.Identifiers.Boost]: parseFluidT1LeverageManagement,
880
1078
  },
881
1079
  };
882
1080
 
@@ -3,6 +3,7 @@ import { getAssetInfo } from '@defisaver/tokens';
3
3
 
4
4
  import type { OrderType } from '../types/enums';
5
5
  import {
6
+ CloseStrategyType, CloseToAssetType,
6
7
  Bundles, ChainId, RatioState, Strategies,
7
8
  } from '../types/enums';
8
9
  import type { EthereumAddress, StrategyOrBundleIds } from '../types';
@@ -11,7 +12,9 @@ import { STRATEGY_IDS } from '../constants';
11
12
 
12
13
  import * as subDataService from './subDataService';
13
14
  import * as triggerService from './triggerService';
14
- import { compareAddresses, requireAddress, requireAddresses } from './utils';
15
+ import {
16
+ compareAddresses, getCloseStrategyType, requireAddress, requireAddresses,
17
+ } from './utils';
15
18
 
16
19
  export const makerEncode = {
17
20
  repayFromSavings(
@@ -519,6 +522,99 @@ export const morphoBlueEncode = {
519
522
  else strategyOrBundleId = isEOA ? Bundles.MainnetIds.MORPHO_BLUE_EOA_REPAY : Bundles.MainnetIds.MORPHO_BLUE_REPAY;
520
523
  const isBundle = true;
521
524
 
525
+ return [strategyOrBundleId, isBundle, triggerData, subData];
526
+ },
527
+ leverageManagementOnPrice(
528
+ strategyOrBundleId: number,
529
+ isBundle: boolean = true,
530
+ loanToken: EthereumAddress,
531
+ collToken: EthereumAddress,
532
+ oracle: EthereumAddress,
533
+ irm: EthereumAddress,
534
+ lltv: string,
535
+ user: EthereumAddress,
536
+ targetRatio: number,
537
+ price: number,
538
+ priceState: RatioState,
539
+ ) {
540
+ const subData = subDataService.morphoBlueLeverageManagementOnPriceSubData.encode(loanToken, collToken, oracle, irm, lltv, targetRatio, user);
541
+ const triggerData = triggerService.morphoBluePriceTrigger.encode(oracle, collToken, loanToken, price, priceState);
542
+ return [strategyOrBundleId, isBundle, triggerData, subData];
543
+ },
544
+ };
545
+
546
+ export const liquityV2Encode = {
547
+ leverageManagement(
548
+ market: EthereumAddress,
549
+ troveId: string,
550
+ collToken: EthereumAddress,
551
+ boldToken: EthereumAddress,
552
+ ratioState: RatioState,
553
+ targetRatio: number,
554
+ triggerRatio: number,
555
+ strategyOrBundleId: number,
556
+ ) {
557
+ const isBundle = true;
558
+ const subData = subDataService.liquityV2LeverageManagementSubData.encode(market, troveId, collToken, boldToken, ratioState, targetRatio);
559
+ const triggerData = triggerService.liquityV2RatioTrigger.encode(market, troveId, triggerRatio, ratioState);
560
+
561
+ return [strategyOrBundleId, isBundle, triggerData, subData];
562
+ },
563
+ closeOnPrice(
564
+ strategyOrBundleId: number,
565
+ market: EthereumAddress,
566
+ troveId: string,
567
+ collToken: EthereumAddress,
568
+ boldToken: EthereumAddress,
569
+ stopLossPrice: number = 0,
570
+ stopLossType: CloseToAssetType = CloseToAssetType.DEBT,
571
+ takeProfitPrice: number = 0,
572
+ takeProfitType: CloseToAssetType = CloseToAssetType.COLLATERAL,
573
+ ) {
574
+ const isBundle = true;
575
+ const closeType = getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType);
576
+
577
+ const subData = subDataService.liquityV2CloseSubData.encode(market, troveId, collToken, boldToken, closeType);
578
+ const triggerData = triggerService.closePriceTrigger.encode(collToken, stopLossPrice, takeProfitPrice);
579
+
580
+ return [strategyOrBundleId, isBundle, triggerData, subData];
581
+ },
582
+ leverageManagementOnPrice(
583
+ strategyOrBundleId: number,
584
+ market: EthereumAddress,
585
+ price: number,
586
+ state: RatioState,
587
+ troveId: string,
588
+ collToken: EthereumAddress,
589
+ boldToken: EthereumAddress,
590
+ targetRatio: number,
591
+ isRepayOnPrice: boolean,
592
+ ) {
593
+ const subDataEncoded = subDataService.liquityV2LeverageManagementOnPriceSubData.encode(
594
+ market, troveId, collToken, boldToken, targetRatio, isRepayOnPrice,
595
+ );
596
+
597
+ const triggerDataEncoded = triggerService.liquityV2QuotePriceTrigger.encode(market, price, state);
598
+ const isBundle = true;
599
+ return [strategyOrBundleId, isBundle, triggerDataEncoded, subDataEncoded];
600
+ },
601
+ };
602
+
603
+ export const fluidEncode = {
604
+ leverageManagement(
605
+ nftId: string,
606
+ vault: EthereumAddress,
607
+ collToken: EthereumAddress,
608
+ debtToken: EthereumAddress,
609
+ ratioState: RatioState,
610
+ targetRatio: number,
611
+ triggerRatio: number,
612
+ strategyOrBundleId: number,
613
+ ) {
614
+ const isBundle = true;
615
+ const subData = subDataService.fluidLeverageManagementSubData.encode(nftId, vault, collToken, debtToken, ratioState, targetRatio);
616
+ const triggerData = triggerService.fluidRatioTrigger.encode(nftId, triggerRatio, ratioState);
617
+
522
618
  return [strategyOrBundleId, isBundle, triggerData, subData];
523
619
  },
524
620
  };
@@ -6,8 +6,10 @@ import { assetAmountInEth, getAssetInfo, getAssetInfoByAddress } from '@defisave
6
6
  import { otherAddresses } from '@defisaver/sdk';
7
7
 
8
8
  import type { SubData, EthereumAddress } from '../types';
9
- import type { OrderType } from '../types/enums';
10
- import { ChainId, RatioState } from '../types/enums';
9
+ import type { CloseStrategyType, OrderType } from '../types/enums';
10
+ import {
11
+ ChainId, CollActionType, DebtActionType, RatioState,
12
+ } from '../types/enums';
11
13
 
12
14
  import { AAVE_V3_VARIABLE_BORROW_RATE, ZERO_ADDRESS } from '../constants';
13
15
 
@@ -643,3 +645,242 @@ export const aaveV3LeverageManagementOnPriceSubData = {
643
645
  };
644
646
  },
645
647
  };
648
+
649
+ export const liquityV2LeverageManagementSubData = {
650
+ encode: (
651
+ market: EthereumAddress,
652
+ troveId: string,
653
+ collToken: EthereumAddress,
654
+ boldToken: EthereumAddress,
655
+ ratioState: RatioState,
656
+ targetRatio: number,
657
+ ) => {
658
+ const marketEncoded = AbiCoder.encodeParameter('address', market);
659
+ const troveIdEncoded = AbiCoder.encodeParameter('uint256', troveId);
660
+ const collTokenEncoded = AbiCoder.encodeParameter('address', collToken);
661
+ const boldTokenEncoded = AbiCoder.encodeParameter('address', boldToken);
662
+ const ratioStateEncoded = AbiCoder.encodeParameter('uint8', ratioState);
663
+ const targetRatioEncoded = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
664
+
665
+ const isRepay = ratioState === RatioState.UNDER;
666
+ const collActionType = isRepay ? CollActionType.WITHDRAW : CollActionType.SUPPLY;
667
+ const debtActionType = isRepay ? DebtActionType.PAYBACK : DebtActionType.BORROW;
668
+
669
+ const collActionTypeEncoded = AbiCoder.encodeParameter('uint8', collActionType);
670
+ const debtActionTypeEncoded = AbiCoder.encodeParameter('uint8', debtActionType);
671
+
672
+ return [
673
+ marketEncoded,
674
+ troveIdEncoded,
675
+ collTokenEncoded,
676
+ boldTokenEncoded,
677
+ ratioStateEncoded,
678
+ targetRatioEncoded,
679
+ collActionTypeEncoded,
680
+ debtActionTypeEncoded,
681
+ ];
682
+ },
683
+ decode: (subData: SubData) => {
684
+ const market = AbiCoder.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
685
+ const troveId = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
686
+ const collToken = AbiCoder.decodeParameter('address', subData[2]) as any as EthereumAddress;
687
+ const boldToken = AbiCoder.decodeParameter('address', subData[3]) as any as EthereumAddress;
688
+ const ratioState = AbiCoder.decodeParameter('uint8', subData[4]) as any as RatioState;
689
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[5]) as any as string;
690
+ const targetRatio = weiToRatioPercentage(weiRatio);
691
+
692
+ return {
693
+ market, troveId, collToken, boldToken, ratioState, targetRatio,
694
+ };
695
+ },
696
+ };
697
+
698
+ export const liquityV2CloseSubData = {
699
+ encode(
700
+ market: EthereumAddress,
701
+ troveId: string,
702
+ collToken: EthereumAddress,
703
+ boldToken: EthereumAddress,
704
+ closeType: CloseStrategyType,
705
+ ): SubData {
706
+ const marketEncoded = AbiCoder.encodeParameter('address', market);
707
+ const troveIdEncoded = AbiCoder.encodeParameter('uint256', troveId);
708
+ const collAddrEncoded = AbiCoder.encodeParameter('address', collToken);
709
+ const boldTokenEncoded = AbiCoder.encodeParameter('address', boldToken);
710
+ const wethAddress = getAssetInfo('WETH').address;
711
+ const wethAddressEncoded = AbiCoder.encodeParameter('address', wethAddress);
712
+ const gasCompensation = new Dec('0.0375').mul(1e18).toString();
713
+ const gasCompensationEncoded = AbiCoder.encodeParameter('uint256', gasCompensation);
714
+ const closeTypeEncoded = AbiCoder.encodeParameter('uint8', closeType);
715
+
716
+ return [
717
+ marketEncoded,
718
+ troveIdEncoded,
719
+ collAddrEncoded,
720
+ boldTokenEncoded,
721
+ wethAddressEncoded,
722
+ gasCompensationEncoded,
723
+ closeTypeEncoded,
724
+ ];
725
+ },
726
+ decode(subData: SubData): {
727
+ market: EthereumAddress,
728
+ troveId: string,
729
+ collToken: EthereumAddress,
730
+ boldToken: EthereumAddress,
731
+ closeType: CloseStrategyType,
732
+ } {
733
+ const market = AbiCoder.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
734
+ const troveId = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
735
+ const collToken = AbiCoder.decodeParameter('address', subData[2]) as any as EthereumAddress;
736
+ const boldToken = AbiCoder.decodeParameter('address', subData[3]) as any as EthereumAddress;
737
+ // skip wethAddress and gasCompensation
738
+ const closeType = AbiCoder.decodeParameter('uint8', subData[6]) as any as CloseStrategyType;
739
+
740
+ return {
741
+ market, troveId, collToken, boldToken, closeType,
742
+ };
743
+ },
744
+ };
745
+
746
+ export const liquityV2LeverageManagementOnPriceSubData = {
747
+ encode(
748
+ market: EthereumAddress,
749
+ troveId: string,
750
+ collToken: EthereumAddress,
751
+ boldToken: EthereumAddress,
752
+ targetRatio: number,
753
+ isRepayOnPrice: boolean,
754
+ ): SubData {
755
+ const encodedMarket = AbiCoder.encodeParameter('address', market);
756
+ const encodedTroveId = AbiCoder.encodeParameter('uint256', troveId);
757
+ const encodedCollToken = AbiCoder.encodeParameter('address', collToken);
758
+ const encodedBoldToken = AbiCoder.encodeParameter('address', boldToken);
759
+ const encodedTargetRatio = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
760
+
761
+ const collActionType = isRepayOnPrice ? CollActionType.WITHDRAW : CollActionType.SUPPLY;
762
+ const debtActionType = isRepayOnPrice ? DebtActionType.PAYBACK : DebtActionType.BORROW;
763
+
764
+ const encodedCollActionType = AbiCoder.encodeParameter('uint8', collActionType);
765
+ const encodedDebtActionType = AbiCoder.encodeParameter('uint8', debtActionType);
766
+
767
+ return [
768
+ encodedMarket,
769
+ encodedTroveId,
770
+ encodedCollToken,
771
+ encodedBoldToken,
772
+ encodedTargetRatio,
773
+ encodedCollActionType,
774
+ encodedDebtActionType,
775
+ ];
776
+ },
777
+ decode(subData: SubData): {
778
+ market: EthereumAddress,
779
+ troveId: string,
780
+ collToken: EthereumAddress,
781
+ boldToken: EthereumAddress,
782
+ targetRatio: number,
783
+ } {
784
+ const market = AbiCoder.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
785
+ const troveId = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
786
+ const collToken = AbiCoder.decodeParameter('address', subData[2]) as unknown as EthereumAddress;
787
+ const boldToken = AbiCoder.decodeParameter('address', subData[3]) as unknown as EthereumAddress;
788
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[4]) as any as string;
789
+ const targetRatio = weiToRatioPercentage(weiRatio);
790
+
791
+ return {
792
+ market, troveId, collToken, boldToken, targetRatio,
793
+ };
794
+ },
795
+ };
796
+ export const morphoBlueLeverageManagementOnPriceSubData = {
797
+ encode(
798
+ loanToken: EthereumAddress,
799
+ collToken: EthereumAddress,
800
+ oracle: EthereumAddress,
801
+ irm: EthereumAddress,
802
+ lltv: string,
803
+ targetRatio: number,
804
+ user: EthereumAddress,
805
+ ): SubData {
806
+ const loanTokenEncoded = AbiCoder.encodeParameter('address', loanToken);
807
+ const collTokenEncoded = AbiCoder.encodeParameter('address', collToken);
808
+ const oracleEncoded = AbiCoder.encodeParameter('address', oracle);
809
+ const irmEncoded = AbiCoder.encodeParameter('address', irm);
810
+ const lltvEncoded = AbiCoder.encodeParameter('uint256', lltv);
811
+ const targetRatioEncoded = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
812
+ const userEncoded = AbiCoder.encodeParameter('address', user);
813
+ return [loanTokenEncoded, collTokenEncoded, oracleEncoded, irmEncoded, lltvEncoded, targetRatioEncoded, userEncoded];
814
+ },
815
+ decode(subData: SubData) {
816
+ const loanToken = AbiCoder.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
817
+ const collToken = AbiCoder.decodeParameter('address', subData[1]) as any as EthereumAddress;
818
+ const oracle = AbiCoder.decodeParameter('address', subData[2]) as any as EthereumAddress;
819
+ const irm = AbiCoder.decodeParameter('address', subData[3]) as any as EthereumAddress;
820
+ const lltv = AbiCoder.decodeParameter('uint256', subData[4]) as any as EthereumAddress;
821
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[5]) as any as EthereumAddress;
822
+ const targetRatio = weiToRatioPercentage(weiRatio);
823
+ const user = AbiCoder.decodeParameter('address', subData[6]) as any as EthereumAddress;
824
+
825
+ return {
826
+ loanToken,
827
+ collToken,
828
+ oracle,
829
+ irm,
830
+ lltv,
831
+ targetRatio,
832
+ user,
833
+ };
834
+ },
835
+ };
836
+
837
+ export const fluidLeverageManagementSubData = {
838
+ encode: (
839
+ nftId: string,
840
+ vault: EthereumAddress,
841
+ collToken: EthereumAddress,
842
+ debtToken: EthereumAddress,
843
+ ratioState: RatioState,
844
+ targetRatio: number,
845
+ ) => {
846
+ const nftIdEncoded = AbiCoder.encodeParameter('uint256', nftId);
847
+ const vaultEncoded = AbiCoder.encodeParameter('address', vault);
848
+ const collTokenEncoded = AbiCoder.encodeParameter('address', collToken);
849
+ const debtTokenEncoded = AbiCoder.encodeParameter('address', debtToken);
850
+ const ratioStateEncoded = AbiCoder.encodeParameter('uint8', ratioState);
851
+ const targetRatioEncoded = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
852
+ const wrapEthEncoded = AbiCoder.encodeParameter('bool', true);
853
+
854
+ const isRepay = ratioState === RatioState.UNDER;
855
+ const collActionType = isRepay ? CollActionType.WITHDRAW : CollActionType.SUPPLY;
856
+ const debtActionType = isRepay ? DebtActionType.PAYBACK : DebtActionType.BORROW;
857
+
858
+ const collActionTypeEncoded = AbiCoder.encodeParameter('uint8', collActionType);
859
+ const debtActionTypeEncoded = AbiCoder.encodeParameter('uint8', debtActionType);
860
+
861
+ return [
862
+ nftIdEncoded,
863
+ vaultEncoded,
864
+ collTokenEncoded,
865
+ debtTokenEncoded,
866
+ ratioStateEncoded,
867
+ targetRatioEncoded,
868
+ wrapEthEncoded,
869
+ collActionTypeEncoded,
870
+ debtActionTypeEncoded,
871
+ ];
872
+ },
873
+ decode: (subData: SubData) => {
874
+ const nftId = AbiCoder.decodeParameter('uint256', subData[0]) as any as string;
875
+ const vault = AbiCoder.decodeParameter('address', subData[1]) as unknown as EthereumAddress;
876
+ const collToken = AbiCoder.decodeParameter('address', subData[2]) as any as EthereumAddress;
877
+ const debtToken = AbiCoder.decodeParameter('address', subData[3]) as any as EthereumAddress;
878
+ const ratioState = AbiCoder.decodeParameter('uint8', subData[4]) as any as RatioState;
879
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[5]) as any as string;
880
+ const targetRatio = weiToRatioPercentage(weiRatio);
881
+
882
+ return {
883
+ nftId, vault, collToken, debtToken, ratioState, targetRatio,
884
+ };
885
+ },
886
+ };