@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.
- package/cjs/automation/private/StrategiesAutomation.d.ts +2 -2
- package/cjs/automation/public/Strategies.test.d.ts +1 -0
- package/cjs/automation/public/Strategies.test.js +61 -0
- package/cjs/constants/index.js +45 -0
- package/cjs/services/strategiesService.js +155 -0
- package/cjs/services/strategySubService.d.ts +10 -1
- package/cjs/services/strategySubService.js +35 -1
- package/cjs/services/subDataService.d.ts +55 -1
- package/cjs/services/subDataService.js +174 -1
- package/cjs/services/triggerService.d.ts +43 -0
- package/cjs/services/triggerService.js +81 -1
- package/cjs/services/utils.d.ts +6 -1
- package/cjs/services/utils.js +52 -1
- package/cjs/types/enums.d.ts +38 -3
- package/cjs/types/enums.js +40 -1
- package/cjs/types/index.d.ts +16 -3
- package/esm/automation/private/StrategiesAutomation.d.ts +2 -2
- package/esm/automation/public/Strategies.test.d.ts +1 -0
- package/esm/automation/public/Strategies.test.js +56 -0
- package/esm/constants/index.js +45 -0
- package/esm/services/strategiesService.js +153 -1
- package/esm/services/strategySubService.d.ts +10 -1
- package/esm/services/strategySubService.js +36 -2
- package/esm/services/subDataService.d.ts +55 -1
- package/esm/services/subDataService.js +174 -1
- package/esm/services/triggerService.d.ts +43 -0
- package/esm/services/triggerService.js +80 -0
- package/esm/services/utils.d.ts +6 -1
- package/esm/services/utils.js +50 -1
- package/esm/types/enums.d.ts +38 -3
- package/esm/types/enums.js +39 -0
- package/esm/types/index.d.ts +16 -3
- package/package.json +3 -3
- package/src/automation/private/StrategiesAutomation.ts +2 -2
- package/src/automation/public/Strategies.test.ts +49 -0
- package/src/constants/index.ts +45 -0
- package/src/services/strategiesService.ts +199 -1
- package/src/services/strategySubService.ts +97 -1
- package/src/services/subDataService.ts +243 -2
- package/src/services/triggerService.ts +125 -0
- package/src/services/utils.ts +60 -1
- package/src/types/enums.ts +39 -0
- package/src/types/index.ts +20 -2
- 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 {
|
|
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 {
|
|
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
|
+
};
|