@defisaver/automation-sdk 3.1.5 → 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 +35 -0
- package/cjs/services/strategiesService.js +123 -0
- package/cjs/services/strategySubService.d.ts +9 -1
- package/cjs/services/strategySubService.js +30 -1
- package/cjs/services/subDataService.d.ts +43 -1
- package/cjs/services/subDataService.js +143 -1
- package/cjs/services/triggerService.d.ts +33 -0
- package/cjs/services/triggerService.js +63 -1
- package/cjs/services/utils.d.ts +6 -1
- package/cjs/services/utils.js +52 -1
- package/cjs/types/enums.d.ts +34 -2
- package/cjs/types/enums.js +37 -1
- package/cjs/types/index.d.ts +12 -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 +35 -0
- package/esm/services/strategiesService.js +124 -1
- package/esm/services/strategySubService.d.ts +9 -1
- package/esm/services/strategySubService.js +31 -2
- package/esm/services/subDataService.d.ts +43 -1
- package/esm/services/subDataService.js +143 -1
- package/esm/services/triggerService.d.ts +33 -0
- package/esm/services/triggerService.js +62 -0
- package/esm/services/utils.d.ts +6 -1
- package/esm/services/utils.js +50 -1
- package/esm/types/enums.d.ts +34 -2
- package/esm/types/enums.js +36 -0
- package/esm/types/index.d.ts +12 -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 +35 -0
- package/src/services/strategiesService.ts +159 -1
- package/src/services/strategySubService.ts +80 -1
- package/src/services/subDataService.ts +202 -2
- package/src/services/triggerService.ts +96 -0
- package/src/services/utils.ts +60 -1
- package/src/types/enums.ts +36 -0
- package/src/types/index.ts +13 -1
- package/umd/index.js +34219 -0
|
@@ -19,7 +19,7 @@ import Automation from './Automation';
|
|
|
19
19
|
|
|
20
20
|
interface IStrategiesAutomation extends Interfaces.Automation {
|
|
21
21
|
chainId: ChainId,
|
|
22
|
-
providerFork
|
|
22
|
+
providerFork?: Web3,
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export default class StrategiesAutomation extends Automation {
|
|
@@ -27,7 +27,7 @@ export default class StrategiesAutomation extends Automation {
|
|
|
27
27
|
|
|
28
28
|
protected web3: Web3;
|
|
29
29
|
|
|
30
|
-
protected web3Fork
|
|
30
|
+
protected web3Fork?: Web3;
|
|
31
31
|
|
|
32
32
|
protected subStorageContract: Contract.WithMeta<SubStorage>;
|
|
33
33
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import Web3 from 'web3';
|
|
2
|
+
import { expect } from 'chai';
|
|
3
|
+
|
|
4
|
+
import {ChainId} from '../../types/enums';
|
|
5
|
+
|
|
6
|
+
import '../../configuration';
|
|
7
|
+
import EthereumStrategies from './EthereumStrategies';
|
|
8
|
+
import ArbitrumStrategies from './ArbitrumStrategies';
|
|
9
|
+
import OptimismStrategies from './OptimismStrategies';
|
|
10
|
+
import BaseStrategies from './BaseStrategies';
|
|
11
|
+
|
|
12
|
+
require('dotenv').config({ path: '.env' });
|
|
13
|
+
|
|
14
|
+
const Web3_1 = new Web3(process.env.RPC_1!);
|
|
15
|
+
const Web3_42161 = new Web3(process.env.RPC_42161!);
|
|
16
|
+
const Web3_10 = new Web3(process.env.RPC_10!);
|
|
17
|
+
const Web3_8453 = new Web3(process.env.RPC_8453!);
|
|
18
|
+
|
|
19
|
+
describe('Feature: StrategiesAutomation.ts', () => {
|
|
20
|
+
describe('Fetching subscriptions', () => {
|
|
21
|
+
it('can fetch subscriptions on Mainnet', async function () {
|
|
22
|
+
this.timeout(120000);
|
|
23
|
+
const ethStrategies = new EthereumStrategies({provider: Web3_1});
|
|
24
|
+
const subs = await ethStrategies.getSubscriptions({mergeSubs: true})
|
|
25
|
+
console.log(subs.length);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('can fetch subscriptions on Arbitrum', async function () {
|
|
29
|
+
this.timeout(120000);
|
|
30
|
+
const arbiStrategies = new ArbitrumStrategies({provider: Web3_42161});
|
|
31
|
+
const subs = await arbiStrategies.getSubscriptions({mergeSubs: true})
|
|
32
|
+
console.log(subs.length);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('can fetch subscriptions on Optimism', async function () {
|
|
36
|
+
this.timeout(120000);
|
|
37
|
+
const optimismStrategies = new OptimismStrategies({provider: Web3_10});
|
|
38
|
+
const subs = await optimismStrategies.getSubscriptions({mergeSubs: true})
|
|
39
|
+
console.log(subs.length);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('can fetch subscriptions on Base', async function () {
|
|
43
|
+
this.timeout(120000);
|
|
44
|
+
const baseStrategies = new BaseStrategies({provider: Web3_8453});
|
|
45
|
+
const subs = await baseStrategies.getSubscriptions({mergeSubs: true})
|
|
46
|
+
console.log(subs.length);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
});
|
package/src/constants/index.ts
CHANGED
|
@@ -376,11 +376,46 @@ export const MAINNET_BUNDLES_INFO: MainnetBundleInfo = {
|
|
|
376
376
|
strategyId: Strategies.Identifiers.RepayOnPrice,
|
|
377
377
|
protocol: PROTOCOLS.AaveV3,
|
|
378
378
|
},
|
|
379
|
+
[Bundles.MainnetIds.LIQUITY_V2_REPAY]: {
|
|
380
|
+
strategyOrBundleId: Bundles.MainnetIds.LIQUITY_V2_REPAY,
|
|
381
|
+
strategyId: Strategies.Identifiers.Repay,
|
|
382
|
+
protocol: PROTOCOLS.LiquityV2,
|
|
383
|
+
},
|
|
384
|
+
[Bundles.MainnetIds.LIQUITY_V2_BOOST]: {
|
|
385
|
+
strategyOrBundleId: Bundles.MainnetIds.LIQUITY_V2_BOOST,
|
|
386
|
+
strategyId: Strategies.Identifiers.Boost,
|
|
387
|
+
protocol: PROTOCOLS.LiquityV2,
|
|
388
|
+
},
|
|
389
|
+
[Bundles.MainnetIds.LIQUITY_V2_CLOSE]: {
|
|
390
|
+
strategyOrBundleId: Bundles.MainnetIds.LIQUITY_V2_CLOSE,
|
|
391
|
+
strategyId: Strategies.Identifiers.CloseOnPrice,
|
|
392
|
+
protocol: PROTOCOLS.LiquityV2,
|
|
393
|
+
},
|
|
394
|
+
[Bundles.MainnetIds.LIQUITY_V2_REPAY_ON_PRICE]: {
|
|
395
|
+
strategyOrBundleId: Bundles.MainnetIds.LIQUITY_V2_REPAY_ON_PRICE,
|
|
396
|
+
strategyId: Strategies.Identifiers.OpenOrderFromCollateral,
|
|
397
|
+
protocol: PROTOCOLS.LiquityV2,
|
|
398
|
+
},
|
|
399
|
+
[Bundles.MainnetIds.LIQUITY_V2_BOOST_ON_PRICE]: {
|
|
400
|
+
strategyOrBundleId: Bundles.MainnetIds.LIQUITY_V2_BOOST_ON_PRICE,
|
|
401
|
+
strategyId: Strategies.Identifiers.RepayOnPrice,
|
|
402
|
+
protocol: PROTOCOLS.LiquityV2,
|
|
403
|
+
},
|
|
379
404
|
[Bundles.MainnetIds.MORPHO_BLUE_BOOST_ON_PRICE]: {
|
|
380
405
|
strategyOrBundleId: Bundles.MainnetIds.MORPHO_BLUE_BOOST_ON_PRICE,
|
|
381
406
|
strategyId: Strategies.Identifiers.BoostOnPrice,
|
|
382
407
|
protocol: PROTOCOLS.MorphoBlue,
|
|
383
408
|
},
|
|
409
|
+
[Bundles.MainnetIds.FLUID_T1_REPAY]: {
|
|
410
|
+
strategyOrBundleId: Bundles.MainnetIds.FLUID_T1_REPAY,
|
|
411
|
+
strategyId: Strategies.Identifiers.Repay,
|
|
412
|
+
protocol: PROTOCOLS.FluidT1,
|
|
413
|
+
},
|
|
414
|
+
[Bundles.MainnetIds.FLUID_T2_BOOST]: {
|
|
415
|
+
strategyOrBundleId: Bundles.MainnetIds.FLUID_T2_BOOST,
|
|
416
|
+
strategyId: Strategies.Identifiers.Boost,
|
|
417
|
+
protocol: PROTOCOLS.FluidT1,
|
|
418
|
+
},
|
|
384
419
|
};
|
|
385
420
|
|
|
386
421
|
export const OPTIMISM_BUNDLES_INFO: OptimismBundleInfo = {
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
import { ChainId, ProtocolIdentifiers, Strategies } from '../types/enums';
|
|
11
11
|
|
|
12
12
|
import {
|
|
13
|
-
getPositionId, getRatioStateInfoForAaveCloseStrategy, isRatioStateOver, wethToEthByAddress,
|
|
13
|
+
getPositionId, getRatioStateInfoForAaveCloseStrategy, getStopLossAndTakeProfitTypeByCloseStrategyType, isRatioStateOver, wethToEthByAddress,
|
|
14
14
|
} from './utils';
|
|
15
15
|
import * as subDataService from './subDataService';
|
|
16
16
|
import * as triggerService from './triggerService';
|
|
@@ -566,6 +566,49 @@ function parseLiquityLeverageManagement(position: Position.Automated, parseData:
|
|
|
566
566
|
return _position;
|
|
567
567
|
}
|
|
568
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
|
+
|
|
569
612
|
function parseSparkLeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
|
|
570
613
|
const _position = cloneDeep(position);
|
|
571
614
|
|
|
@@ -845,6 +888,110 @@ function parseAaveV3LeverageManagementOnPrice(position: Position.Automated, pars
|
|
|
845
888
|
return _position;
|
|
846
889
|
}
|
|
847
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
|
+
|
|
848
995
|
const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
|
|
849
996
|
[ProtocolIdentifiers.StrategiesAutomation.MakerDAO]: {
|
|
850
997
|
[Strategies.Identifiers.SavingsLiqProtection]: parseMakerSavingsLiqProtection,
|
|
@@ -865,6 +1012,13 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
|
|
|
865
1012
|
[Strategies.Identifiers.SavingsDsrSupply]: parseLiquitySavingsLiqProtection,
|
|
866
1013
|
[Strategies.Identifiers.DebtInFrontRepay]: parseLiquityDebtInFrontRepay,
|
|
867
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
|
+
},
|
|
868
1022
|
[ProtocolIdentifiers.StrategiesAutomation.AaveV2]: {
|
|
869
1023
|
[Strategies.Identifiers.Repay]: parseAaveV2LeverageManagement,
|
|
870
1024
|
[Strategies.Identifiers.Boost]: parseAaveV2LeverageManagement,
|
|
@@ -918,6 +1072,10 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
|
|
|
918
1072
|
[Strategies.Identifiers.EoaBoost]: parseMorphoBlueLeverageManagement,
|
|
919
1073
|
[Strategies.Identifiers.BoostOnPrice]: parseMorphoBlueLeverageManagementOnPrice,
|
|
920
1074
|
},
|
|
1075
|
+
[ProtocolIdentifiers.StrategiesAutomation.FluidT1]: {
|
|
1076
|
+
[Strategies.Identifiers.Repay]: parseFluidT1LeverageManagement,
|
|
1077
|
+
[Strategies.Identifiers.Boost]: parseFluidT1LeverageManagement,
|
|
1078
|
+
},
|
|
921
1079
|
};
|
|
922
1080
|
|
|
923
1081
|
function getParsingMethod(id: ProtocolIdentifiers.StrategiesAutomation, strategy: BundleOrStrategy) {
|
|
@@ -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(
|
|
@@ -539,3 +542,79 @@ export const morphoBlueEncode = {
|
|
|
539
542
|
return [strategyOrBundleId, isBundle, triggerData, subData];
|
|
540
543
|
},
|
|
541
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
|
+
|
|
618
|
+
return [strategyOrBundleId, isBundle, triggerData, subData];
|
|
619
|
+
},
|
|
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
|
|
|
@@ -644,6 +646,153 @@ export const aaveV3LeverageManagementOnPriceSubData = {
|
|
|
644
646
|
},
|
|
645
647
|
};
|
|
646
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
|
+
};
|
|
647
796
|
export const morphoBlueLeverageManagementOnPriceSubData = {
|
|
648
797
|
encode(
|
|
649
798
|
loanToken: EthereumAddress,
|
|
@@ -684,3 +833,54 @@ export const morphoBlueLeverageManagementOnPriceSubData = {
|
|
|
684
833
|
};
|
|
685
834
|
},
|
|
686
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
|
+
};
|