@defisaver/automation-sdk 3.1.1-dev → 3.1.1-dev-2
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/constants/index.js +5 -0
- package/cjs/services/strategiesService.js +22 -2
- package/cjs/services/strategySubService.d.ts +2 -1
- package/cjs/services/strategySubService.js +9 -0
- package/cjs/services/subDataService.d.ts +11 -1
- package/cjs/services/subDataService.js +31 -1
- package/cjs/services/triggerService.d.ts +8 -0
- package/cjs/services/triggerService.js +18 -1
- package/cjs/services/utils.d.ts +2 -1
- package/cjs/services/utils.js +29 -1
- package/cjs/types/enums.d.ts +17 -1
- package/cjs/types/enums.js +19 -1
- package/esm/constants/index.js +5 -0
- package/esm/services/strategiesService.js +22 -2
- package/esm/services/strategySubService.d.ts +2 -1
- package/esm/services/strategySubService.js +11 -2
- package/esm/services/subDataService.d.ts +11 -1
- package/esm/services/subDataService.js +30 -0
- package/esm/services/triggerService.d.ts +8 -0
- package/esm/services/triggerService.js +17 -0
- package/esm/services/utils.d.ts +2 -1
- package/esm/services/utils.js +28 -1
- package/esm/types/enums.d.ts +17 -1
- package/esm/types/enums.js +18 -0
- package/package.json +1 -1
- package/src/constants/index.ts +5 -0
- package/src/services/strategiesService.ts +31 -2
- package/src/services/strategySubService.ts +26 -1
- package/src/services/subDataService.ts +46 -1
- package/src/services/triggerService.ts +30 -0
- package/src/services/utils.ts +35 -1
- package/src/types/enums.ts +18 -0
package/cjs/constants/index.js
CHANGED
|
@@ -373,6 +373,11 @@ exports.MAINNET_BUNDLES_INFO = {
|
|
|
373
373
|
strategyId: enums_1.Strategies.Identifiers.Boost,
|
|
374
374
|
protocol: exports.PROTOCOLS.LiquityV2,
|
|
375
375
|
},
|
|
376
|
+
[enums_1.Bundles.MainnetIds.LIQUITY_V2_CLOSE]: {
|
|
377
|
+
strategyOrBundleId: enums_1.Bundles.MainnetIds.LIQUITY_V2_CLOSE,
|
|
378
|
+
strategyId: enums_1.Strategies.Identifiers.CloseOnPrice,
|
|
379
|
+
protocol: exports.PROTOCOLS.LiquityV2,
|
|
380
|
+
},
|
|
376
381
|
};
|
|
377
382
|
exports.OPTIMISM_BUNDLES_INFO = {
|
|
378
383
|
[enums_1.Bundles.OptimismIds.AAVE_V3_REPAY]: {
|
|
@@ -431,7 +431,7 @@ function parseLiquityLeverageManagement(position, parseData) {
|
|
|
431
431
|
}
|
|
432
432
|
function parseLiquityV2LeverageManagement(position, parseData) {
|
|
433
433
|
const _position = (0, lodash_1.cloneDeep)(position);
|
|
434
|
-
const { subStruct, subId } = parseData.subscriptionEventData;
|
|
434
|
+
const { subStruct, subId, subHash } = parseData.subscriptionEventData;
|
|
435
435
|
const { isEnabled } = parseData.strategiesSubsData;
|
|
436
436
|
const triggerData = triggerService.liquityV2RatioTrigger.decode(subStruct.triggerData);
|
|
437
437
|
const subData = subDataService.liquityV2LeverageManagementSubData.decode(subStruct.subData);
|
|
@@ -443,8 +443,9 @@ function parseLiquityV2LeverageManagement(position, parseData) {
|
|
|
443
443
|
_position.specific = {
|
|
444
444
|
triggerRepayRatio: triggerData.ratio,
|
|
445
445
|
targetRepayRatio: subData.targetRatio,
|
|
446
|
-
repayEnabled:
|
|
446
|
+
repayEnabled: isEnabled,
|
|
447
447
|
subId1: Number(subId),
|
|
448
|
+
subHashRepay: subHash,
|
|
448
449
|
mergeWithId: enums_1.Strategies.Identifiers.Boost,
|
|
449
450
|
};
|
|
450
451
|
}
|
|
@@ -454,6 +455,7 @@ function parseLiquityV2LeverageManagement(position, parseData) {
|
|
|
454
455
|
targetBoostRatio: subData.targetRatio,
|
|
455
456
|
boostEnabled: isEnabled,
|
|
456
457
|
subId2: Number(subId),
|
|
458
|
+
subHashBoost: subHash,
|
|
457
459
|
mergeId: enums_1.Strategies.Identifiers.Boost,
|
|
458
460
|
};
|
|
459
461
|
}
|
|
@@ -642,6 +644,23 @@ function parseAaveV3OpenOrderFromCollateral(position, parseData) {
|
|
|
642
644
|
};
|
|
643
645
|
return _position;
|
|
644
646
|
}
|
|
647
|
+
function parseLiquityV2CloseOnPrice(position, parseData) {
|
|
648
|
+
const _position = (0, lodash_1.cloneDeep)(position);
|
|
649
|
+
const { subStruct } = parseData.subscriptionEventData;
|
|
650
|
+
const triggerData = triggerService.shouldClosePriceTrigger.decode(subStruct.triggerData);
|
|
651
|
+
const subData = subDataService.liquityV2CloseSubData.decode(subStruct.subData);
|
|
652
|
+
_position.strategyData.decoded.triggerData = triggerData;
|
|
653
|
+
_position.strategyData.decoded.subData = subData;
|
|
654
|
+
_position.positionId = (0, utils_1.getPositionId)(_position.chainId, _position.protocol.id, _position.owner, subData.troveId, subData.market);
|
|
655
|
+
// User can have:
|
|
656
|
+
// - Only TakeProfit
|
|
657
|
+
// - Only StopLoss
|
|
658
|
+
// - Both
|
|
659
|
+
// TODO: see on frontend what specific data we need here because stop-loss and take-profit is one bundle now
|
|
660
|
+
_position.strategy.strategyId = enums_1.Strategies.Identifiers.CloseOnPrice;
|
|
661
|
+
_position.specific = {};
|
|
662
|
+
return _position;
|
|
663
|
+
}
|
|
645
664
|
const parsingMethodsMapping = {
|
|
646
665
|
[enums_1.ProtocolIdentifiers.StrategiesAutomation.MakerDAO]: {
|
|
647
666
|
[enums_1.Strategies.Identifiers.SavingsLiqProtection]: parseMakerSavingsLiqProtection,
|
|
@@ -665,6 +684,7 @@ const parsingMethodsMapping = {
|
|
|
665
684
|
[enums_1.ProtocolIdentifiers.StrategiesAutomation.LiquityV2]: {
|
|
666
685
|
[enums_1.Strategies.Identifiers.Repay]: parseLiquityV2LeverageManagement,
|
|
667
686
|
[enums_1.Strategies.Identifiers.Boost]: parseLiquityV2LeverageManagement,
|
|
687
|
+
[enums_1.Strategies.Identifiers.CloseOnPrice]: parseLiquityV2CloseOnPrice,
|
|
668
688
|
},
|
|
669
689
|
[enums_1.ProtocolIdentifiers.StrategiesAutomation.AaveV2]: {
|
|
670
690
|
[enums_1.Strategies.Identifiers.Repay]: parseAaveV2LeverageManagement,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { OrderType } from '../types/enums';
|
|
2
|
-
import { Bundles, ChainId, RatioState, Strategies } from '../types/enums';
|
|
2
|
+
import { CloseToAssetType, Bundles, ChainId, RatioState, Strategies } from '../types/enums';
|
|
3
3
|
import type { EthereumAddress, StrategyOrBundleIds } from '../types';
|
|
4
4
|
export declare const makerEncode: {
|
|
5
5
|
repayFromSavings(bundleId: StrategyOrBundleIds, vaultId: number, triggerRepayRatio: number, targetRepayRatio: number, isBundle?: boolean, chainId?: ChainId, daiAddr?: EthereumAddress, mcdCdpManagerAddr?: EthereumAddress): (boolean | string[] | Strategies.MainnetIds | Strategies.OptimismIds | Strategies.ArbitrumIds | Strategies.BaseIds | Bundles.MainnetIds | Bundles.OptimismIds | Bundles.ArbitrumIds | Bundles.BaseIds)[];
|
|
@@ -100,4 +100,5 @@ export declare const morphoBlueEncode: {
|
|
|
100
100
|
};
|
|
101
101
|
export declare const liquityV2Encode: {
|
|
102
102
|
leverageManagement(market: EthereumAddress, troveId: string, ratioState: RatioState, targetRatio: number, triggerRatio: number, strategyOrBundleId: number): (number | boolean | string[])[];
|
|
103
|
+
closeOnPrice(strategyOrBundleId: number, market: EthereumAddress, troveId: string, collToken: EthereumAddress, boldToken: EthereumAddress, stopLossPrice?: number, stopLossType?: CloseToAssetType, takeProfitPrice?: number, takeProfitType?: CloseToAssetType): (number | boolean | string[])[];
|
|
103
104
|
};
|
|
@@ -274,4 +274,13 @@ exports.liquityV2Encode = {
|
|
|
274
274
|
// : Bundles.MainnetIds.LIQUITY_V2_REPAY;
|
|
275
275
|
return [strategyOrBundleId, isBundle, triggerData, subData];
|
|
276
276
|
},
|
|
277
|
+
closeOnPrice(strategyOrBundleId, market, troveId, collToken, boldToken, stopLossPrice = 0, stopLossType = enums_1.CloseToAssetType.DEBT, takeProfitPrice = 0, takeProfitType = enums_1.CloseToAssetType.COLLATERAL) {
|
|
278
|
+
const isBundle = true;
|
|
279
|
+
const closeType = (0, utils_1.getCloseStrategyType)(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType);
|
|
280
|
+
const subData = subDataService.liquityV2CloseSubData.encode(market, troveId, collToken, boldToken, closeType);
|
|
281
|
+
const triggerData = triggerService.shouldClosePriceTrigger.encode(collToken, stopLossPrice, takeProfitPrice);
|
|
282
|
+
// TODO: we can hardcode bundleID after testing
|
|
283
|
+
// Bundles.MainnetIds.LIQUITY_V2_CLOSE;
|
|
284
|
+
return [strategyOrBundleId, isBundle, triggerData, subData];
|
|
285
|
+
},
|
|
277
286
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EthereumAddress } from '../types';
|
|
2
|
-
import type { OrderType } from '../types/enums';
|
|
2
|
+
import type { CloseStrategyType, OrderType } from '../types/enums';
|
|
3
3
|
import { ChainId, RatioState } from '../types/enums';
|
|
4
4
|
export declare const makerRepayFromSavingsSubData: {
|
|
5
5
|
encode(vaultId: number, targetRatioPercentage: number, chainId: ChainId, daiAddr?: EthereumAddress, mcdCdpManagerAddr?: EthereumAddress): string[];
|
|
@@ -199,3 +199,13 @@ export declare const liquityV2LeverageManagementSubData: {
|
|
|
199
199
|
targetRatio: number;
|
|
200
200
|
};
|
|
201
201
|
};
|
|
202
|
+
export declare const liquityV2CloseSubData: {
|
|
203
|
+
encode(market: EthereumAddress, troveId: string, collToken: EthereumAddress, boldToken: EthereumAddress, closeType: CloseStrategyType): string[];
|
|
204
|
+
decode(subData: string[]): {
|
|
205
|
+
market: EthereumAddress;
|
|
206
|
+
troveId: string;
|
|
207
|
+
collToken: EthereumAddress;
|
|
208
|
+
boldToken: EthereumAddress;
|
|
209
|
+
closeType: CloseStrategyType;
|
|
210
|
+
};
|
|
211
|
+
};
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.liquityV2LeverageManagementSubData = exports.aaveV3OpenOrderSubData = exports.morphoBlueLeverageManagementSubData = exports.crvUSDPaybackSubData = exports.crvUSDLeverageManagementSubData = exports.liquityDebtInFrontRepaySubData = exports.liquityDsrSupplySubData = exports.liquityDsrPaybackSubData = exports.sparkQuotePriceSubData = exports.sparkLeverageManagementSubData = exports.exchangeLimitOrderSubData = exports.exchangeDcaSubData = exports.liquityPaybackUsingChickenBondSubData = exports.cBondsRebondSubData = exports.morphoAaveV2LeverageManagementSubData = exports.compoundV3L2LeverageManagementSubData = exports.compoundV3LeverageManagementSubData = exports.compoundV2LeverageManagementSubData = exports.aaveV3QuotePriceSubData = exports.aaveV3LeverageManagementSubData = exports.aaveV2LeverageManagementSubData = exports.liquityCloseSubData = exports.liquityLeverageManagementSubData = exports.makerLeverageManagementSubData = exports.makerCloseSubData = exports.liquityRepayFromSavingsSubData = exports.makerRepayFromSavingsSubData = void 0;
|
|
6
|
+
exports.liquityV2CloseSubData = exports.liquityV2LeverageManagementSubData = exports.aaveV3OpenOrderSubData = exports.morphoBlueLeverageManagementSubData = exports.crvUSDPaybackSubData = exports.crvUSDLeverageManagementSubData = exports.liquityDebtInFrontRepaySubData = exports.liquityDsrSupplySubData = exports.liquityDsrPaybackSubData = exports.sparkQuotePriceSubData = exports.sparkLeverageManagementSubData = exports.exchangeLimitOrderSubData = exports.exchangeDcaSubData = exports.liquityPaybackUsingChickenBondSubData = exports.cBondsRebondSubData = exports.morphoAaveV2LeverageManagementSubData = exports.compoundV3L2LeverageManagementSubData = exports.compoundV3LeverageManagementSubData = exports.compoundV2LeverageManagementSubData = exports.aaveV3QuotePriceSubData = exports.aaveV3LeverageManagementSubData = exports.aaveV2LeverageManagementSubData = exports.liquityCloseSubData = exports.liquityLeverageManagementSubData = exports.makerLeverageManagementSubData = exports.makerCloseSubData = exports.liquityRepayFromSavingsSubData = exports.makerRepayFromSavingsSubData = void 0;
|
|
7
7
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
8
8
|
const web3_eth_abi_1 = __importDefault(require("web3-eth-abi"));
|
|
9
9
|
const web3_utils_1 = require("web3-utils");
|
|
@@ -497,3 +497,33 @@ exports.liquityV2LeverageManagementSubData = {
|
|
|
497
497
|
};
|
|
498
498
|
},
|
|
499
499
|
};
|
|
500
|
+
exports.liquityV2CloseSubData = {
|
|
501
|
+
encode(market, troveId, collToken, boldToken, closeType) {
|
|
502
|
+
const marketEncoded = web3_eth_abi_1.default.encodeParameter('address', market);
|
|
503
|
+
const troveIdEncoded = web3_eth_abi_1.default.encodeParameter('uint256', troveId);
|
|
504
|
+
const collAddrEncoded = web3_eth_abi_1.default.encodeParameter('address', collToken);
|
|
505
|
+
const boldTokenEncoded = web3_eth_abi_1.default.encodeParameter('address', boldToken);
|
|
506
|
+
const wethAddress = (0, tokens_1.getAssetInfo)('WETH').address;
|
|
507
|
+
const wethAddressEncoded = web3_eth_abi_1.default.encodeParameter('address', wethAddress);
|
|
508
|
+
const closeTypeEncoded = web3_eth_abi_1.default.encodeParameter('uint8', closeType);
|
|
509
|
+
return [
|
|
510
|
+
marketEncoded,
|
|
511
|
+
troveIdEncoded,
|
|
512
|
+
collAddrEncoded,
|
|
513
|
+
boldTokenEncoded,
|
|
514
|
+
wethAddressEncoded,
|
|
515
|
+
closeTypeEncoded,
|
|
516
|
+
];
|
|
517
|
+
},
|
|
518
|
+
decode(subData) {
|
|
519
|
+
const market = web3_eth_abi_1.default.decodeParameter('address', subData[0]);
|
|
520
|
+
const troveId = web3_eth_abi_1.default.decodeParameter('uint256', subData[1]);
|
|
521
|
+
const collToken = web3_eth_abi_1.default.decodeParameter('address', subData[2]);
|
|
522
|
+
const boldToken = web3_eth_abi_1.default.decodeParameter('address', subData[3]);
|
|
523
|
+
// skip wethAddress
|
|
524
|
+
const closeType = web3_eth_abi_1.default.decodeParameter('uint8', subData[5]);
|
|
525
|
+
return {
|
|
526
|
+
market, troveId, collToken, boldToken, closeType,
|
|
527
|
+
};
|
|
528
|
+
},
|
|
529
|
+
};
|
|
@@ -198,3 +198,11 @@ export declare const liquityV2RatioTrigger: {
|
|
|
198
198
|
ratioState: number;
|
|
199
199
|
};
|
|
200
200
|
};
|
|
201
|
+
export declare const shouldClosePriceTrigger: {
|
|
202
|
+
encode(tokenAddr: EthereumAddress, lowerPrice: number, upperPrice: number): string[];
|
|
203
|
+
decode(triggerData: string[]): {
|
|
204
|
+
tokenAddr: EthereumAddress;
|
|
205
|
+
lowerPrice: string;
|
|
206
|
+
upperPrice: string;
|
|
207
|
+
};
|
|
208
|
+
};
|
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.liquityV2RatioTrigger = exports.morphoBlueRatioTrigger = exports.crvUsdHealthRatioTrigger = exports.crvUSDRatioTrigger = exports.curveUsdSoftLiquidationTrigger = exports.curveUsdBorrowRateTrigger = exports.sparkQuotePriceTrigger = exports.sparkRatioTrigger = exports.exchangeOffchainPriceTrigger = exports.exchangeTimestampTrigger = exports.compoundV3RatioTrigger = exports.cBondsRebondTrigger = exports.aaveV2RatioTrigger = exports.liquityDebtInFrontWithLimitTrigger = exports.liquityDebtInFrontTrigger = exports.liquityRatioTrigger = exports.compoundV2RatioTrigger = exports.aaveV3QuotePriceWithMaximumGasPriceTrigger = exports.aaveV3QuotePriceTrigger = exports.morphoAaveV2RatioTrigger = exports.aaveV3RatioTrigger = exports.makerRatioTrigger = exports.trailingStopTrigger = exports.chainlinkPriceTrigger = void 0;
|
|
29
|
+
exports.shouldClosePriceTrigger = exports.liquityV2RatioTrigger = exports.morphoBlueRatioTrigger = exports.crvUsdHealthRatioTrigger = exports.crvUSDRatioTrigger = exports.curveUsdSoftLiquidationTrigger = exports.curveUsdBorrowRateTrigger = exports.sparkQuotePriceTrigger = exports.sparkRatioTrigger = exports.exchangeOffchainPriceTrigger = exports.exchangeTimestampTrigger = exports.compoundV3RatioTrigger = exports.cBondsRebondTrigger = exports.aaveV2RatioTrigger = exports.liquityDebtInFrontWithLimitTrigger = exports.liquityDebtInFrontTrigger = exports.liquityRatioTrigger = exports.compoundV2RatioTrigger = exports.aaveV3QuotePriceWithMaximumGasPriceTrigger = exports.aaveV3QuotePriceTrigger = exports.morphoAaveV2RatioTrigger = exports.aaveV3RatioTrigger = exports.makerRatioTrigger = exports.trailingStopTrigger = exports.chainlinkPriceTrigger = void 0;
|
|
30
30
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
31
31
|
const tokens_1 = require("@defisaver/tokens");
|
|
32
32
|
const web3_eth_abi_1 = __importDefault(require("web3-eth-abi"));
|
|
@@ -380,3 +380,20 @@ exports.liquityV2RatioTrigger = {
|
|
|
380
380
|
};
|
|
381
381
|
},
|
|
382
382
|
};
|
|
383
|
+
exports.shouldClosePriceTrigger = {
|
|
384
|
+
encode(tokenAddr, lowerPrice, upperPrice) {
|
|
385
|
+
const lowerPriceFormatted = new decimal_js_1.default(lowerPrice).mul(1e8).floor().toString();
|
|
386
|
+
const upperPriceFormatted = new decimal_js_1.default(upperPrice).mul(1e8).floor().toString();
|
|
387
|
+
return [
|
|
388
|
+
web3_eth_abi_1.default.encodeParameters(['address', 'uint256', 'uint256'], [tokenAddr, lowerPriceFormatted, upperPriceFormatted]),
|
|
389
|
+
];
|
|
390
|
+
},
|
|
391
|
+
decode(triggerData) {
|
|
392
|
+
const decodedData = web3_eth_abi_1.default.decodeParameters(['address', 'uint256', 'uint256'], triggerData[0]);
|
|
393
|
+
return {
|
|
394
|
+
tokenAddr: decodedData[0],
|
|
395
|
+
lowerPrice: new decimal_js_1.default(decodedData[1]).div(1e8).toString(),
|
|
396
|
+
upperPrice: new decimal_js_1.default(decodedData[2]).div(1e8).toString(),
|
|
397
|
+
};
|
|
398
|
+
},
|
|
399
|
+
};
|
package/cjs/services/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EthereumAddress } from '../types';
|
|
2
|
-
import { ChainId, RatioState } from '../types/enums';
|
|
2
|
+
import { ChainId, CloseStrategyType, CloseToAssetType, RatioState } from '../types/enums';
|
|
3
3
|
export declare function isDefined<T>(value: T): value is NonNullable<T>;
|
|
4
4
|
export declare function isUndefined(value: unknown): boolean;
|
|
5
5
|
export declare function compareAddresses(firstAddress: EthereumAddress, secondAddress: EthereumAddress): boolean;
|
|
@@ -23,3 +23,4 @@ export declare function getRatioStateInfoForAaveCloseStrategy(currentRatioState:
|
|
|
23
23
|
ratioState: RatioState;
|
|
24
24
|
};
|
|
25
25
|
export declare function getPositionId(...args: (number | string)[]): string;
|
|
26
|
+
export declare function getCloseStrategyType(stopLossPrice: number, stopLossType: CloseToAssetType, takeProfitPrice: number, takeProfitType: CloseToAssetType): CloseStrategyType;
|
package/cjs/services/utils.js
CHANGED
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.getPositionId = exports.getRatioStateInfoForAaveCloseStrategy = exports.requireAddresses = exports.requireAddress = exports.isEmptyBytes = exports.isRatioStateUnder = exports.isRatioStateOver = exports.weiToRatioPercentage = exports.ratioPercentageToWei = exports.encodeSubId = exports.compareSubHashes = exports.wethToEthByAddress = exports.wethToEth = exports.ethToWeth = exports.addToObjectIf = exports.addToArrayIf = exports.isAddress = exports.compareAddresses = exports.isUndefined = exports.isDefined = void 0;
|
|
29
|
+
exports.getCloseStrategyType = exports.getPositionId = exports.getRatioStateInfoForAaveCloseStrategy = exports.requireAddresses = exports.requireAddress = exports.isEmptyBytes = exports.isRatioStateUnder = exports.isRatioStateOver = exports.weiToRatioPercentage = exports.ratioPercentageToWei = exports.encodeSubId = exports.compareSubHashes = exports.wethToEthByAddress = exports.wethToEth = exports.ethToWeth = exports.addToObjectIf = exports.addToArrayIf = exports.isAddress = exports.compareAddresses = exports.isUndefined = exports.isDefined = void 0;
|
|
30
30
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
31
31
|
const web3Utils = __importStar(require("web3-utils"));
|
|
32
32
|
const web3_eth_abi_1 = __importDefault(require("web3-eth-abi"));
|
|
@@ -129,3 +129,31 @@ function getPositionId(...args) {
|
|
|
129
129
|
return args.map(arg => arg.toString().toLowerCase().split(' ').join('_')).join('-');
|
|
130
130
|
}
|
|
131
131
|
exports.getPositionId = getPositionId;
|
|
132
|
+
function getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType) {
|
|
133
|
+
const isStopLoss = stopLossPrice > 0;
|
|
134
|
+
const isTakeProfit = takeProfitPrice > 0;
|
|
135
|
+
if (!isStopLoss && !isTakeProfit) {
|
|
136
|
+
throw new Error('CloseOnPrice: At least one price must be defined');
|
|
137
|
+
}
|
|
138
|
+
if (isStopLoss && isTakeProfit) {
|
|
139
|
+
if (stopLossType === enums_1.CloseToAssetType.COLLATERAL && takeProfitType === enums_1.CloseToAssetType.COLLATERAL) {
|
|
140
|
+
return enums_1.CloseStrategyType.TAKE_PROFIT_AND_STOP_LOSS_IN_COLLATERAL;
|
|
141
|
+
}
|
|
142
|
+
if (stopLossType === enums_1.CloseToAssetType.COLLATERAL) {
|
|
143
|
+
return enums_1.CloseStrategyType.TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL;
|
|
144
|
+
}
|
|
145
|
+
if (takeProfitType === enums_1.CloseToAssetType.COLLATERAL) {
|
|
146
|
+
return enums_1.CloseStrategyType.TAKE_PROFIT_IN_COLLATERAL_AND_STOP_LOSS_IN_DEBT;
|
|
147
|
+
}
|
|
148
|
+
return enums_1.CloseStrategyType.TAKE_PROFIT_AND_STOP_LOSS_IN_DEBT;
|
|
149
|
+
}
|
|
150
|
+
if (isStopLoss) {
|
|
151
|
+
return stopLossType === enums_1.CloseToAssetType.COLLATERAL
|
|
152
|
+
? enums_1.CloseStrategyType.STOP_LOSS_IN_COLLATERAL
|
|
153
|
+
: enums_1.CloseStrategyType.STOP_LOSS_IN_DEBT;
|
|
154
|
+
}
|
|
155
|
+
return takeProfitType === enums_1.CloseToAssetType.COLLATERAL
|
|
156
|
+
? enums_1.CloseStrategyType.TAKE_PROFIT_IN_COLLATERAL
|
|
157
|
+
: enums_1.CloseStrategyType.TAKE_PROFIT_IN_DEBT;
|
|
158
|
+
}
|
|
159
|
+
exports.getCloseStrategyType = getCloseStrategyType;
|
package/cjs/types/enums.d.ts
CHANGED
|
@@ -25,6 +25,20 @@ export declare enum DebtActionType {
|
|
|
25
25
|
PAYBACK = 0,
|
|
26
26
|
BORROW = 1
|
|
27
27
|
}
|
|
28
|
+
export declare enum CloseStrategyType {
|
|
29
|
+
TAKE_PROFIT_IN_COLLATERAL = 0,
|
|
30
|
+
STOP_LOSS_IN_COLLATERAL = 1,
|
|
31
|
+
TAKE_PROFIT_IN_DEBT = 2,
|
|
32
|
+
STOP_LOSS_IN_DEBT = 3,
|
|
33
|
+
TAKE_PROFIT_AND_STOP_LOSS_IN_COLLATERAL = 4,
|
|
34
|
+
TAKE_PROFIT_IN_COLLATERAL_AND_STOP_LOSS_IN_DEBT = 5,
|
|
35
|
+
TAKE_PROFIT_AND_STOP_LOSS_IN_DEBT = 6,
|
|
36
|
+
TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL = 7
|
|
37
|
+
}
|
|
38
|
+
export declare enum CloseToAssetType {
|
|
39
|
+
COLLATERAL = 0,
|
|
40
|
+
DEBT = 1
|
|
41
|
+
}
|
|
28
42
|
/**
|
|
29
43
|
* @dev Follow the naming convention:
|
|
30
44
|
* - Enum name consists of two parts, name and version
|
|
@@ -100,6 +114,7 @@ export declare namespace Strategies {
|
|
|
100
114
|
CloseToCollateralWithGasPrice = "close-to-collateral-with-gas-price",
|
|
101
115
|
CloseOnPriceToDebt = "close-on-price-to-debt",
|
|
102
116
|
CloseOnPriceToColl = "close-on-price-to-collateral",
|
|
117
|
+
CloseOnPrice = "close-on-price",
|
|
103
118
|
TrailingStopToColl = "trailing-stop-to-collateral",
|
|
104
119
|
TrailingStopToDebt = "trailing-stop-to-debt",
|
|
105
120
|
Rebond = "rebond",
|
|
@@ -163,7 +178,8 @@ export declare namespace Bundles {
|
|
|
163
178
|
MORPHO_BLUE_EOA_BOOST = 35,
|
|
164
179
|
AAVE_V3_OPEN_ORDER_FROM_COLLATERAL = 36,
|
|
165
180
|
LIQUITY_V2_REPAY = 37,
|
|
166
|
-
LIQUITY_V2_BOOST = 38
|
|
181
|
+
LIQUITY_V2_BOOST = 38,
|
|
182
|
+
LIQUITY_V2_CLOSE = 39
|
|
167
183
|
}
|
|
168
184
|
enum OptimismIds {
|
|
169
185
|
AAVE_V3_REPAY = 0,
|
package/cjs/types/enums.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Bundles = exports.Strategies = exports.ProtocolIdentifiers = exports.DebtActionType = exports.CollActionType = exports.BundleProtocols = exports.OrderType = exports.RatioState = exports.ChainId = void 0;
|
|
3
|
+
exports.Bundles = exports.Strategies = exports.ProtocolIdentifiers = exports.CloseToAssetType = exports.CloseStrategyType = exports.DebtActionType = exports.CollActionType = exports.BundleProtocols = exports.OrderType = exports.RatioState = exports.ChainId = void 0;
|
|
4
4
|
var ChainId;
|
|
5
5
|
(function (ChainId) {
|
|
6
6
|
ChainId[ChainId["Ethereum"] = 1] = "Ethereum";
|
|
@@ -34,6 +34,22 @@ var DebtActionType;
|
|
|
34
34
|
DebtActionType[DebtActionType["PAYBACK"] = 0] = "PAYBACK";
|
|
35
35
|
DebtActionType[DebtActionType["BORROW"] = 1] = "BORROW";
|
|
36
36
|
})(DebtActionType = exports.DebtActionType || (exports.DebtActionType = {}));
|
|
37
|
+
var CloseStrategyType;
|
|
38
|
+
(function (CloseStrategyType) {
|
|
39
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_IN_COLLATERAL"] = 0] = "TAKE_PROFIT_IN_COLLATERAL";
|
|
40
|
+
CloseStrategyType[CloseStrategyType["STOP_LOSS_IN_COLLATERAL"] = 1] = "STOP_LOSS_IN_COLLATERAL";
|
|
41
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_IN_DEBT"] = 2] = "TAKE_PROFIT_IN_DEBT";
|
|
42
|
+
CloseStrategyType[CloseStrategyType["STOP_LOSS_IN_DEBT"] = 3] = "STOP_LOSS_IN_DEBT";
|
|
43
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_AND_STOP_LOSS_IN_COLLATERAL"] = 4] = "TAKE_PROFIT_AND_STOP_LOSS_IN_COLLATERAL";
|
|
44
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_IN_COLLATERAL_AND_STOP_LOSS_IN_DEBT"] = 5] = "TAKE_PROFIT_IN_COLLATERAL_AND_STOP_LOSS_IN_DEBT";
|
|
45
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_AND_STOP_LOSS_IN_DEBT"] = 6] = "TAKE_PROFIT_AND_STOP_LOSS_IN_DEBT";
|
|
46
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL"] = 7] = "TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL";
|
|
47
|
+
})(CloseStrategyType = exports.CloseStrategyType || (exports.CloseStrategyType = {}));
|
|
48
|
+
var CloseToAssetType;
|
|
49
|
+
(function (CloseToAssetType) {
|
|
50
|
+
CloseToAssetType[CloseToAssetType["COLLATERAL"] = 0] = "COLLATERAL";
|
|
51
|
+
CloseToAssetType[CloseToAssetType["DEBT"] = 1] = "DEBT";
|
|
52
|
+
})(CloseToAssetType = exports.CloseToAssetType || (exports.CloseToAssetType = {}));
|
|
37
53
|
/**
|
|
38
54
|
* @dev Follow the naming convention:
|
|
39
55
|
* - Enum name consists of two parts, name and version
|
|
@@ -118,6 +134,7 @@ var Strategies;
|
|
|
118
134
|
Identifiers["CloseToCollateralWithGasPrice"] = "close-to-collateral-with-gas-price";
|
|
119
135
|
Identifiers["CloseOnPriceToDebt"] = "close-on-price-to-debt";
|
|
120
136
|
Identifiers["CloseOnPriceToColl"] = "close-on-price-to-collateral";
|
|
137
|
+
Identifiers["CloseOnPrice"] = "close-on-price";
|
|
121
138
|
Identifiers["TrailingStopToColl"] = "trailing-stop-to-collateral";
|
|
122
139
|
Identifiers["TrailingStopToDebt"] = "trailing-stop-to-debt";
|
|
123
140
|
Identifiers["Rebond"] = "rebond";
|
|
@@ -185,6 +202,7 @@ var Bundles;
|
|
|
185
202
|
MainnetIds[MainnetIds["AAVE_V3_OPEN_ORDER_FROM_COLLATERAL"] = 36] = "AAVE_V3_OPEN_ORDER_FROM_COLLATERAL";
|
|
186
203
|
MainnetIds[MainnetIds["LIQUITY_V2_REPAY"] = 37] = "LIQUITY_V2_REPAY";
|
|
187
204
|
MainnetIds[MainnetIds["LIQUITY_V2_BOOST"] = 38] = "LIQUITY_V2_BOOST";
|
|
205
|
+
MainnetIds[MainnetIds["LIQUITY_V2_CLOSE"] = 39] = "LIQUITY_V2_CLOSE";
|
|
188
206
|
})(MainnetIds = Bundles.MainnetIds || (Bundles.MainnetIds = {}));
|
|
189
207
|
let OptimismIds;
|
|
190
208
|
(function (OptimismIds) {
|
package/esm/constants/index.js
CHANGED
|
@@ -367,6 +367,11 @@ export const MAINNET_BUNDLES_INFO = {
|
|
|
367
367
|
strategyId: Strategies.Identifiers.Boost,
|
|
368
368
|
protocol: PROTOCOLS.LiquityV2,
|
|
369
369
|
},
|
|
370
|
+
[Bundles.MainnetIds.LIQUITY_V2_CLOSE]: {
|
|
371
|
+
strategyOrBundleId: Bundles.MainnetIds.LIQUITY_V2_CLOSE,
|
|
372
|
+
strategyId: Strategies.Identifiers.CloseOnPrice,
|
|
373
|
+
protocol: PROTOCOLS.LiquityV2,
|
|
374
|
+
},
|
|
370
375
|
};
|
|
371
376
|
export const OPTIMISM_BUNDLES_INFO = {
|
|
372
377
|
[Bundles.OptimismIds.AAVE_V3_REPAY]: {
|
|
@@ -405,7 +405,7 @@ function parseLiquityLeverageManagement(position, parseData) {
|
|
|
405
405
|
}
|
|
406
406
|
function parseLiquityV2LeverageManagement(position, parseData) {
|
|
407
407
|
const _position = cloneDeep(position);
|
|
408
|
-
const { subStruct, subId } = parseData.subscriptionEventData;
|
|
408
|
+
const { subStruct, subId, subHash } = parseData.subscriptionEventData;
|
|
409
409
|
const { isEnabled } = parseData.strategiesSubsData;
|
|
410
410
|
const triggerData = triggerService.liquityV2RatioTrigger.decode(subStruct.triggerData);
|
|
411
411
|
const subData = subDataService.liquityV2LeverageManagementSubData.decode(subStruct.subData);
|
|
@@ -417,8 +417,9 @@ function parseLiquityV2LeverageManagement(position, parseData) {
|
|
|
417
417
|
_position.specific = {
|
|
418
418
|
triggerRepayRatio: triggerData.ratio,
|
|
419
419
|
targetRepayRatio: subData.targetRatio,
|
|
420
|
-
repayEnabled:
|
|
420
|
+
repayEnabled: isEnabled,
|
|
421
421
|
subId1: Number(subId),
|
|
422
|
+
subHashRepay: subHash,
|
|
422
423
|
mergeWithId: Strategies.Identifiers.Boost,
|
|
423
424
|
};
|
|
424
425
|
}
|
|
@@ -428,6 +429,7 @@ function parseLiquityV2LeverageManagement(position, parseData) {
|
|
|
428
429
|
targetBoostRatio: subData.targetRatio,
|
|
429
430
|
boostEnabled: isEnabled,
|
|
430
431
|
subId2: Number(subId),
|
|
432
|
+
subHashBoost: subHash,
|
|
431
433
|
mergeId: Strategies.Identifiers.Boost,
|
|
432
434
|
};
|
|
433
435
|
}
|
|
@@ -616,6 +618,23 @@ function parseAaveV3OpenOrderFromCollateral(position, parseData) {
|
|
|
616
618
|
};
|
|
617
619
|
return _position;
|
|
618
620
|
}
|
|
621
|
+
function parseLiquityV2CloseOnPrice(position, parseData) {
|
|
622
|
+
const _position = cloneDeep(position);
|
|
623
|
+
const { subStruct } = parseData.subscriptionEventData;
|
|
624
|
+
const triggerData = triggerService.shouldClosePriceTrigger.decode(subStruct.triggerData);
|
|
625
|
+
const subData = subDataService.liquityV2CloseSubData.decode(subStruct.subData);
|
|
626
|
+
_position.strategyData.decoded.triggerData = triggerData;
|
|
627
|
+
_position.strategyData.decoded.subData = subData;
|
|
628
|
+
_position.positionId = getPositionId(_position.chainId, _position.protocol.id, _position.owner, subData.troveId, subData.market);
|
|
629
|
+
// User can have:
|
|
630
|
+
// - Only TakeProfit
|
|
631
|
+
// - Only StopLoss
|
|
632
|
+
// - Both
|
|
633
|
+
// TODO: see on frontend what specific data we need here because stop-loss and take-profit is one bundle now
|
|
634
|
+
_position.strategy.strategyId = Strategies.Identifiers.CloseOnPrice;
|
|
635
|
+
_position.specific = {};
|
|
636
|
+
return _position;
|
|
637
|
+
}
|
|
619
638
|
const parsingMethodsMapping = {
|
|
620
639
|
[ProtocolIdentifiers.StrategiesAutomation.MakerDAO]: {
|
|
621
640
|
[Strategies.Identifiers.SavingsLiqProtection]: parseMakerSavingsLiqProtection,
|
|
@@ -639,6 +658,7 @@ const parsingMethodsMapping = {
|
|
|
639
658
|
[ProtocolIdentifiers.StrategiesAutomation.LiquityV2]: {
|
|
640
659
|
[Strategies.Identifiers.Repay]: parseLiquityV2LeverageManagement,
|
|
641
660
|
[Strategies.Identifiers.Boost]: parseLiquityV2LeverageManagement,
|
|
661
|
+
[Strategies.Identifiers.CloseOnPrice]: parseLiquityV2CloseOnPrice,
|
|
642
662
|
},
|
|
643
663
|
[ProtocolIdentifiers.StrategiesAutomation.AaveV2]: {
|
|
644
664
|
[Strategies.Identifiers.Repay]: parseAaveV2LeverageManagement,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { OrderType } from '../types/enums';
|
|
2
|
-
import { Bundles, ChainId, RatioState, Strategies } from '../types/enums';
|
|
2
|
+
import { CloseToAssetType, Bundles, ChainId, RatioState, Strategies } from '../types/enums';
|
|
3
3
|
import type { EthereumAddress, StrategyOrBundleIds } from '../types';
|
|
4
4
|
export declare const makerEncode: {
|
|
5
5
|
repayFromSavings(bundleId: StrategyOrBundleIds, vaultId: number, triggerRepayRatio: number, targetRepayRatio: number, isBundle?: boolean, chainId?: ChainId, daiAddr?: EthereumAddress, mcdCdpManagerAddr?: EthereumAddress): (boolean | string[] | Strategies.MainnetIds | Strategies.OptimismIds | Strategies.ArbitrumIds | Strategies.BaseIds | Bundles.MainnetIds | Bundles.OptimismIds | Bundles.ArbitrumIds | Bundles.BaseIds)[];
|
|
@@ -100,4 +100,5 @@ export declare const morphoBlueEncode: {
|
|
|
100
100
|
};
|
|
101
101
|
export declare const liquityV2Encode: {
|
|
102
102
|
leverageManagement(market: EthereumAddress, troveId: string, ratioState: RatioState, targetRatio: number, triggerRatio: number, strategyOrBundleId: number): (number | boolean | string[])[];
|
|
103
|
+
closeOnPrice(strategyOrBundleId: number, market: EthereumAddress, troveId: string, collToken: EthereumAddress, boldToken: EthereumAddress, stopLossPrice?: number, stopLossType?: CloseToAssetType, takeProfitPrice?: number, takeProfitType?: CloseToAssetType): (number | boolean | string[])[];
|
|
103
104
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import Dec from 'decimal.js';
|
|
2
2
|
import { getAssetInfo } from '@defisaver/tokens';
|
|
3
|
-
import { Bundles, ChainId, RatioState, Strategies, } from '../types/enums';
|
|
3
|
+
import { CloseToAssetType, Bundles, ChainId, RatioState, Strategies, } from '../types/enums';
|
|
4
4
|
import { STRATEGY_IDS } from '../constants';
|
|
5
5
|
import * as subDataService from './subDataService';
|
|
6
6
|
import * as triggerService from './triggerService';
|
|
7
|
-
import { compareAddresses, requireAddress, requireAddresses } from './utils';
|
|
7
|
+
import { compareAddresses, getCloseStrategyType, requireAddress, requireAddresses, } from './utils';
|
|
8
8
|
export const makerEncode = {
|
|
9
9
|
repayFromSavings(bundleId, vaultId, triggerRepayRatio, targetRepayRatio, isBundle = true, chainId = ChainId.Ethereum, daiAddr, mcdCdpManagerAddr) {
|
|
10
10
|
const subData = subDataService.makerRepayFromSavingsSubData.encode(vaultId, targetRepayRatio, chainId, daiAddr, mcdCdpManagerAddr);
|
|
@@ -245,4 +245,13 @@ export const liquityV2Encode = {
|
|
|
245
245
|
// : Bundles.MainnetIds.LIQUITY_V2_REPAY;
|
|
246
246
|
return [strategyOrBundleId, isBundle, triggerData, subData];
|
|
247
247
|
},
|
|
248
|
+
closeOnPrice(strategyOrBundleId, market, troveId, collToken, boldToken, stopLossPrice = 0, stopLossType = CloseToAssetType.DEBT, takeProfitPrice = 0, takeProfitType = CloseToAssetType.COLLATERAL) {
|
|
249
|
+
const isBundle = true;
|
|
250
|
+
const closeType = getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType);
|
|
251
|
+
const subData = subDataService.liquityV2CloseSubData.encode(market, troveId, collToken, boldToken, closeType);
|
|
252
|
+
const triggerData = triggerService.shouldClosePriceTrigger.encode(collToken, stopLossPrice, takeProfitPrice);
|
|
253
|
+
// TODO: we can hardcode bundleID after testing
|
|
254
|
+
// Bundles.MainnetIds.LIQUITY_V2_CLOSE;
|
|
255
|
+
return [strategyOrBundleId, isBundle, triggerData, subData];
|
|
256
|
+
},
|
|
248
257
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EthereumAddress } from '../types';
|
|
2
|
-
import type { OrderType } from '../types/enums';
|
|
2
|
+
import type { CloseStrategyType, OrderType } from '../types/enums';
|
|
3
3
|
import { ChainId, RatioState } from '../types/enums';
|
|
4
4
|
export declare const makerRepayFromSavingsSubData: {
|
|
5
5
|
encode(vaultId: number, targetRatioPercentage: number, chainId: ChainId, daiAddr?: EthereumAddress, mcdCdpManagerAddr?: EthereumAddress): string[];
|
|
@@ -199,3 +199,13 @@ export declare const liquityV2LeverageManagementSubData: {
|
|
|
199
199
|
targetRatio: number;
|
|
200
200
|
};
|
|
201
201
|
};
|
|
202
|
+
export declare const liquityV2CloseSubData: {
|
|
203
|
+
encode(market: EthereumAddress, troveId: string, collToken: EthereumAddress, boldToken: EthereumAddress, closeType: CloseStrategyType): string[];
|
|
204
|
+
decode(subData: string[]): {
|
|
205
|
+
market: EthereumAddress;
|
|
206
|
+
troveId: string;
|
|
207
|
+
collToken: EthereumAddress;
|
|
208
|
+
boldToken: EthereumAddress;
|
|
209
|
+
closeType: CloseStrategyType;
|
|
210
|
+
};
|
|
211
|
+
};
|
|
@@ -491,3 +491,33 @@ export const liquityV2LeverageManagementSubData = {
|
|
|
491
491
|
};
|
|
492
492
|
},
|
|
493
493
|
};
|
|
494
|
+
export const liquityV2CloseSubData = {
|
|
495
|
+
encode(market, troveId, collToken, boldToken, closeType) {
|
|
496
|
+
const marketEncoded = AbiCoder.encodeParameter('address', market);
|
|
497
|
+
const troveIdEncoded = AbiCoder.encodeParameter('uint256', troveId);
|
|
498
|
+
const collAddrEncoded = AbiCoder.encodeParameter('address', collToken);
|
|
499
|
+
const boldTokenEncoded = AbiCoder.encodeParameter('address', boldToken);
|
|
500
|
+
const wethAddress = getAssetInfo('WETH').address;
|
|
501
|
+
const wethAddressEncoded = AbiCoder.encodeParameter('address', wethAddress);
|
|
502
|
+
const closeTypeEncoded = AbiCoder.encodeParameter('uint8', closeType);
|
|
503
|
+
return [
|
|
504
|
+
marketEncoded,
|
|
505
|
+
troveIdEncoded,
|
|
506
|
+
collAddrEncoded,
|
|
507
|
+
boldTokenEncoded,
|
|
508
|
+
wethAddressEncoded,
|
|
509
|
+
closeTypeEncoded,
|
|
510
|
+
];
|
|
511
|
+
},
|
|
512
|
+
decode(subData) {
|
|
513
|
+
const market = AbiCoder.decodeParameter('address', subData[0]);
|
|
514
|
+
const troveId = AbiCoder.decodeParameter('uint256', subData[1]);
|
|
515
|
+
const collToken = AbiCoder.decodeParameter('address', subData[2]);
|
|
516
|
+
const boldToken = AbiCoder.decodeParameter('address', subData[3]);
|
|
517
|
+
// skip wethAddress
|
|
518
|
+
const closeType = AbiCoder.decodeParameter('uint8', subData[5]);
|
|
519
|
+
return {
|
|
520
|
+
market, troveId, collToken, boldToken, closeType,
|
|
521
|
+
};
|
|
522
|
+
},
|
|
523
|
+
};
|
|
@@ -198,3 +198,11 @@ export declare const liquityV2RatioTrigger: {
|
|
|
198
198
|
ratioState: number;
|
|
199
199
|
};
|
|
200
200
|
};
|
|
201
|
+
export declare const shouldClosePriceTrigger: {
|
|
202
|
+
encode(tokenAddr: EthereumAddress, lowerPrice: number, upperPrice: number): string[];
|
|
203
|
+
decode(triggerData: string[]): {
|
|
204
|
+
tokenAddr: EthereumAddress;
|
|
205
|
+
lowerPrice: string;
|
|
206
|
+
upperPrice: string;
|
|
207
|
+
};
|
|
208
|
+
};
|
|
@@ -351,3 +351,20 @@ export const liquityV2RatioTrigger = {
|
|
|
351
351
|
};
|
|
352
352
|
},
|
|
353
353
|
};
|
|
354
|
+
export const shouldClosePriceTrigger = {
|
|
355
|
+
encode(tokenAddr, lowerPrice, upperPrice) {
|
|
356
|
+
const lowerPriceFormatted = new Dec(lowerPrice).mul(1e8).floor().toString();
|
|
357
|
+
const upperPriceFormatted = new Dec(upperPrice).mul(1e8).floor().toString();
|
|
358
|
+
return [
|
|
359
|
+
AbiCoder.encodeParameters(['address', 'uint256', 'uint256'], [tokenAddr, lowerPriceFormatted, upperPriceFormatted]),
|
|
360
|
+
];
|
|
361
|
+
},
|
|
362
|
+
decode(triggerData) {
|
|
363
|
+
const decodedData = AbiCoder.decodeParameters(['address', 'uint256', 'uint256'], triggerData[0]);
|
|
364
|
+
return {
|
|
365
|
+
tokenAddr: decodedData[0],
|
|
366
|
+
lowerPrice: new Dec(decodedData[1]).div(1e8).toString(),
|
|
367
|
+
upperPrice: new Dec(decodedData[2]).div(1e8).toString(),
|
|
368
|
+
};
|
|
369
|
+
},
|
|
370
|
+
};
|
package/esm/services/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EthereumAddress } from '../types';
|
|
2
|
-
import { ChainId, RatioState } from '../types/enums';
|
|
2
|
+
import { ChainId, CloseStrategyType, CloseToAssetType, RatioState } from '../types/enums';
|
|
3
3
|
export declare function isDefined<T>(value: T): value is NonNullable<T>;
|
|
4
4
|
export declare function isUndefined(value: unknown): boolean;
|
|
5
5
|
export declare function compareAddresses(firstAddress: EthereumAddress, secondAddress: EthereumAddress): boolean;
|
|
@@ -23,3 +23,4 @@ export declare function getRatioStateInfoForAaveCloseStrategy(currentRatioState:
|
|
|
23
23
|
ratioState: RatioState;
|
|
24
24
|
};
|
|
25
25
|
export declare function getPositionId(...args: (number | string)[]): string;
|
|
26
|
+
export declare function getCloseStrategyType(stopLossPrice: number, stopLossType: CloseToAssetType, takeProfitPrice: number, takeProfitType: CloseToAssetType): CloseStrategyType;
|
package/esm/services/utils.js
CHANGED
|
@@ -2,7 +2,7 @@ import Dec from 'decimal.js';
|
|
|
2
2
|
import * as web3Utils from 'web3-utils';
|
|
3
3
|
import AbiCoder from 'web3-eth-abi';
|
|
4
4
|
import { getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
|
|
5
|
-
import { ChainId, RatioState } from '../types/enums';
|
|
5
|
+
import { ChainId, CloseStrategyType, CloseToAssetType, RatioState, } from '../types/enums';
|
|
6
6
|
export function isDefined(value) {
|
|
7
7
|
return value !== undefined && value !== null;
|
|
8
8
|
}
|
|
@@ -80,3 +80,30 @@ export function getRatioStateInfoForAaveCloseStrategy(currentRatioState, collAss
|
|
|
80
80
|
export function getPositionId(...args) {
|
|
81
81
|
return args.map(arg => arg.toString().toLowerCase().split(' ').join('_')).join('-');
|
|
82
82
|
}
|
|
83
|
+
export function getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType) {
|
|
84
|
+
const isStopLoss = stopLossPrice > 0;
|
|
85
|
+
const isTakeProfit = takeProfitPrice > 0;
|
|
86
|
+
if (!isStopLoss && !isTakeProfit) {
|
|
87
|
+
throw new Error('CloseOnPrice: At least one price must be defined');
|
|
88
|
+
}
|
|
89
|
+
if (isStopLoss && isTakeProfit) {
|
|
90
|
+
if (stopLossType === CloseToAssetType.COLLATERAL && takeProfitType === CloseToAssetType.COLLATERAL) {
|
|
91
|
+
return CloseStrategyType.TAKE_PROFIT_AND_STOP_LOSS_IN_COLLATERAL;
|
|
92
|
+
}
|
|
93
|
+
if (stopLossType === CloseToAssetType.COLLATERAL) {
|
|
94
|
+
return CloseStrategyType.TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL;
|
|
95
|
+
}
|
|
96
|
+
if (takeProfitType === CloseToAssetType.COLLATERAL) {
|
|
97
|
+
return CloseStrategyType.TAKE_PROFIT_IN_COLLATERAL_AND_STOP_LOSS_IN_DEBT;
|
|
98
|
+
}
|
|
99
|
+
return CloseStrategyType.TAKE_PROFIT_AND_STOP_LOSS_IN_DEBT;
|
|
100
|
+
}
|
|
101
|
+
if (isStopLoss) {
|
|
102
|
+
return stopLossType === CloseToAssetType.COLLATERAL
|
|
103
|
+
? CloseStrategyType.STOP_LOSS_IN_COLLATERAL
|
|
104
|
+
: CloseStrategyType.STOP_LOSS_IN_DEBT;
|
|
105
|
+
}
|
|
106
|
+
return takeProfitType === CloseToAssetType.COLLATERAL
|
|
107
|
+
? CloseStrategyType.TAKE_PROFIT_IN_COLLATERAL
|
|
108
|
+
: CloseStrategyType.TAKE_PROFIT_IN_DEBT;
|
|
109
|
+
}
|
package/esm/types/enums.d.ts
CHANGED
|
@@ -25,6 +25,20 @@ export declare enum DebtActionType {
|
|
|
25
25
|
PAYBACK = 0,
|
|
26
26
|
BORROW = 1
|
|
27
27
|
}
|
|
28
|
+
export declare enum CloseStrategyType {
|
|
29
|
+
TAKE_PROFIT_IN_COLLATERAL = 0,
|
|
30
|
+
STOP_LOSS_IN_COLLATERAL = 1,
|
|
31
|
+
TAKE_PROFIT_IN_DEBT = 2,
|
|
32
|
+
STOP_LOSS_IN_DEBT = 3,
|
|
33
|
+
TAKE_PROFIT_AND_STOP_LOSS_IN_COLLATERAL = 4,
|
|
34
|
+
TAKE_PROFIT_IN_COLLATERAL_AND_STOP_LOSS_IN_DEBT = 5,
|
|
35
|
+
TAKE_PROFIT_AND_STOP_LOSS_IN_DEBT = 6,
|
|
36
|
+
TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL = 7
|
|
37
|
+
}
|
|
38
|
+
export declare enum CloseToAssetType {
|
|
39
|
+
COLLATERAL = 0,
|
|
40
|
+
DEBT = 1
|
|
41
|
+
}
|
|
28
42
|
/**
|
|
29
43
|
* @dev Follow the naming convention:
|
|
30
44
|
* - Enum name consists of two parts, name and version
|
|
@@ -100,6 +114,7 @@ export declare namespace Strategies {
|
|
|
100
114
|
CloseToCollateralWithGasPrice = "close-to-collateral-with-gas-price",
|
|
101
115
|
CloseOnPriceToDebt = "close-on-price-to-debt",
|
|
102
116
|
CloseOnPriceToColl = "close-on-price-to-collateral",
|
|
117
|
+
CloseOnPrice = "close-on-price",
|
|
103
118
|
TrailingStopToColl = "trailing-stop-to-collateral",
|
|
104
119
|
TrailingStopToDebt = "trailing-stop-to-debt",
|
|
105
120
|
Rebond = "rebond",
|
|
@@ -163,7 +178,8 @@ export declare namespace Bundles {
|
|
|
163
178
|
MORPHO_BLUE_EOA_BOOST = 35,
|
|
164
179
|
AAVE_V3_OPEN_ORDER_FROM_COLLATERAL = 36,
|
|
165
180
|
LIQUITY_V2_REPAY = 37,
|
|
166
|
-
LIQUITY_V2_BOOST = 38
|
|
181
|
+
LIQUITY_V2_BOOST = 38,
|
|
182
|
+
LIQUITY_V2_CLOSE = 39
|
|
167
183
|
}
|
|
168
184
|
enum OptimismIds {
|
|
169
185
|
AAVE_V3_REPAY = 0,
|
package/esm/types/enums.js
CHANGED
|
@@ -31,6 +31,22 @@ export var DebtActionType;
|
|
|
31
31
|
DebtActionType[DebtActionType["PAYBACK"] = 0] = "PAYBACK";
|
|
32
32
|
DebtActionType[DebtActionType["BORROW"] = 1] = "BORROW";
|
|
33
33
|
})(DebtActionType || (DebtActionType = {}));
|
|
34
|
+
export var CloseStrategyType;
|
|
35
|
+
(function (CloseStrategyType) {
|
|
36
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_IN_COLLATERAL"] = 0] = "TAKE_PROFIT_IN_COLLATERAL";
|
|
37
|
+
CloseStrategyType[CloseStrategyType["STOP_LOSS_IN_COLLATERAL"] = 1] = "STOP_LOSS_IN_COLLATERAL";
|
|
38
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_IN_DEBT"] = 2] = "TAKE_PROFIT_IN_DEBT";
|
|
39
|
+
CloseStrategyType[CloseStrategyType["STOP_LOSS_IN_DEBT"] = 3] = "STOP_LOSS_IN_DEBT";
|
|
40
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_AND_STOP_LOSS_IN_COLLATERAL"] = 4] = "TAKE_PROFIT_AND_STOP_LOSS_IN_COLLATERAL";
|
|
41
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_IN_COLLATERAL_AND_STOP_LOSS_IN_DEBT"] = 5] = "TAKE_PROFIT_IN_COLLATERAL_AND_STOP_LOSS_IN_DEBT";
|
|
42
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_AND_STOP_LOSS_IN_DEBT"] = 6] = "TAKE_PROFIT_AND_STOP_LOSS_IN_DEBT";
|
|
43
|
+
CloseStrategyType[CloseStrategyType["TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL"] = 7] = "TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL";
|
|
44
|
+
})(CloseStrategyType || (CloseStrategyType = {}));
|
|
45
|
+
export var CloseToAssetType;
|
|
46
|
+
(function (CloseToAssetType) {
|
|
47
|
+
CloseToAssetType[CloseToAssetType["COLLATERAL"] = 0] = "COLLATERAL";
|
|
48
|
+
CloseToAssetType[CloseToAssetType["DEBT"] = 1] = "DEBT";
|
|
49
|
+
})(CloseToAssetType || (CloseToAssetType = {}));
|
|
34
50
|
/**
|
|
35
51
|
* @dev Follow the naming convention:
|
|
36
52
|
* - Enum name consists of two parts, name and version
|
|
@@ -115,6 +131,7 @@ export var Strategies;
|
|
|
115
131
|
Identifiers["CloseToCollateralWithGasPrice"] = "close-to-collateral-with-gas-price";
|
|
116
132
|
Identifiers["CloseOnPriceToDebt"] = "close-on-price-to-debt";
|
|
117
133
|
Identifiers["CloseOnPriceToColl"] = "close-on-price-to-collateral";
|
|
134
|
+
Identifiers["CloseOnPrice"] = "close-on-price";
|
|
118
135
|
Identifiers["TrailingStopToColl"] = "trailing-stop-to-collateral";
|
|
119
136
|
Identifiers["TrailingStopToDebt"] = "trailing-stop-to-debt";
|
|
120
137
|
Identifiers["Rebond"] = "rebond";
|
|
@@ -182,6 +199,7 @@ export var Bundles;
|
|
|
182
199
|
MainnetIds[MainnetIds["AAVE_V3_OPEN_ORDER_FROM_COLLATERAL"] = 36] = "AAVE_V3_OPEN_ORDER_FROM_COLLATERAL";
|
|
183
200
|
MainnetIds[MainnetIds["LIQUITY_V2_REPAY"] = 37] = "LIQUITY_V2_REPAY";
|
|
184
201
|
MainnetIds[MainnetIds["LIQUITY_V2_BOOST"] = 38] = "LIQUITY_V2_BOOST";
|
|
202
|
+
MainnetIds[MainnetIds["LIQUITY_V2_CLOSE"] = 39] = "LIQUITY_V2_CLOSE";
|
|
185
203
|
})(MainnetIds = Bundles.MainnetIds || (Bundles.MainnetIds = {}));
|
|
186
204
|
let OptimismIds;
|
|
187
205
|
(function (OptimismIds) {
|
package/package.json
CHANGED
package/src/constants/index.ts
CHANGED
|
@@ -385,6 +385,11 @@ export const MAINNET_BUNDLES_INFO: MainnetBundleInfo = {
|
|
|
385
385
|
strategyId: Strategies.Identifiers.Boost,
|
|
386
386
|
protocol: PROTOCOLS.LiquityV2,
|
|
387
387
|
},
|
|
388
|
+
[Bundles.MainnetIds.LIQUITY_V2_CLOSE]: {
|
|
389
|
+
strategyOrBundleId: Bundles.MainnetIds.LIQUITY_V2_CLOSE,
|
|
390
|
+
strategyId: Strategies.Identifiers.CloseOnPrice,
|
|
391
|
+
protocol: PROTOCOLS.LiquityV2,
|
|
392
|
+
},
|
|
388
393
|
};
|
|
389
394
|
|
|
390
395
|
export const OPTIMISM_BUNDLES_INFO: OptimismBundleInfo = {
|
|
@@ -566,7 +566,7 @@ function parseLiquityLeverageManagement(position: Position.Automated, parseData:
|
|
|
566
566
|
function parseLiquityV2LeverageManagement(position: Position.Automated, parseData: ParseData): Position.Automated {
|
|
567
567
|
const _position = cloneDeep(position);
|
|
568
568
|
|
|
569
|
-
const { subStruct, subId } = parseData.subscriptionEventData;
|
|
569
|
+
const { subStruct, subId, subHash } = parseData.subscriptionEventData;
|
|
570
570
|
const { isEnabled } = parseData.strategiesSubsData;
|
|
571
571
|
|
|
572
572
|
const triggerData = triggerService.liquityV2RatioTrigger.decode(subStruct.triggerData);
|
|
@@ -585,8 +585,9 @@ function parseLiquityV2LeverageManagement(position: Position.Automated, parseDat
|
|
|
585
585
|
_position.specific = {
|
|
586
586
|
triggerRepayRatio: triggerData.ratio,
|
|
587
587
|
targetRepayRatio: subData.targetRatio,
|
|
588
|
-
repayEnabled:
|
|
588
|
+
repayEnabled: isEnabled,
|
|
589
589
|
subId1: Number(subId),
|
|
590
|
+
subHashRepay: subHash,
|
|
590
591
|
mergeWithId: Strategies.Identifiers.Boost,
|
|
591
592
|
};
|
|
592
593
|
} else {
|
|
@@ -595,6 +596,7 @@ function parseLiquityV2LeverageManagement(position: Position.Automated, parseDat
|
|
|
595
596
|
targetBoostRatio: subData.targetRatio,
|
|
596
597
|
boostEnabled: isEnabled,
|
|
597
598
|
subId2: Number(subId),
|
|
599
|
+
subHashBoost: subHash,
|
|
598
600
|
mergeId: Strategies.Identifiers.Boost,
|
|
599
601
|
};
|
|
600
602
|
}
|
|
@@ -847,6 +849,32 @@ function parseAaveV3OpenOrderFromCollateral(position: Position.Automated, parseD
|
|
|
847
849
|
return _position;
|
|
848
850
|
}
|
|
849
851
|
|
|
852
|
+
function parseLiquityV2CloseOnPrice(position: Position.Automated, parseData: ParseData): Position.Automated {
|
|
853
|
+
const _position = cloneDeep(position);
|
|
854
|
+
|
|
855
|
+
const { subStruct } = parseData.subscriptionEventData;
|
|
856
|
+
|
|
857
|
+
const triggerData = triggerService.shouldClosePriceTrigger.decode(subStruct.triggerData);
|
|
858
|
+
const subData = subDataService.liquityV2CloseSubData.decode(subStruct.subData);
|
|
859
|
+
|
|
860
|
+
_position.strategyData.decoded.triggerData = triggerData;
|
|
861
|
+
_position.strategyData.decoded.subData = subData;
|
|
862
|
+
|
|
863
|
+
_position.positionId = getPositionId(
|
|
864
|
+
_position.chainId, _position.protocol.id, _position.owner, subData.troveId, subData.market,
|
|
865
|
+
);
|
|
866
|
+
|
|
867
|
+
// User can have:
|
|
868
|
+
// - Only TakeProfit
|
|
869
|
+
// - Only StopLoss
|
|
870
|
+
// - Both
|
|
871
|
+
// TODO: see on frontend what specific data we need here because stop-loss and take-profit is one bundle now
|
|
872
|
+
_position.strategy.strategyId = Strategies.Identifiers.CloseOnPrice;
|
|
873
|
+
_position.specific = {};
|
|
874
|
+
|
|
875
|
+
return _position;
|
|
876
|
+
}
|
|
877
|
+
|
|
850
878
|
const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
|
|
851
879
|
[ProtocolIdentifiers.StrategiesAutomation.MakerDAO]: {
|
|
852
880
|
[Strategies.Identifiers.SavingsLiqProtection]: parseMakerSavingsLiqProtection,
|
|
@@ -870,6 +898,7 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
|
|
|
870
898
|
[ProtocolIdentifiers.StrategiesAutomation.LiquityV2]: {
|
|
871
899
|
[Strategies.Identifiers.Repay]: parseLiquityV2LeverageManagement,
|
|
872
900
|
[Strategies.Identifiers.Boost]: parseLiquityV2LeverageManagement,
|
|
901
|
+
[Strategies.Identifiers.CloseOnPrice]: parseLiquityV2CloseOnPrice,
|
|
873
902
|
},
|
|
874
903
|
[ProtocolIdentifiers.StrategiesAutomation.AaveV2]: {
|
|
875
904
|
[Strategies.Identifiers.Repay]: parseAaveV2LeverageManagement,
|
|
@@ -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(
|
|
@@ -537,6 +540,28 @@ export const liquityV2Encode = {
|
|
|
537
540
|
// ? Bundles.MainnetIds.LIQUITY_V2_BOOST
|
|
538
541
|
// : Bundles.MainnetIds.LIQUITY_V2_REPAY;
|
|
539
542
|
|
|
543
|
+
return [strategyOrBundleId, isBundle, triggerData, subData];
|
|
544
|
+
},
|
|
545
|
+
closeOnPrice(
|
|
546
|
+
strategyOrBundleId: number,
|
|
547
|
+
market: EthereumAddress,
|
|
548
|
+
troveId: string,
|
|
549
|
+
collToken: EthereumAddress,
|
|
550
|
+
boldToken: EthereumAddress,
|
|
551
|
+
stopLossPrice: number = 0,
|
|
552
|
+
stopLossType: CloseToAssetType = CloseToAssetType.DEBT,
|
|
553
|
+
takeProfitPrice: number = 0,
|
|
554
|
+
takeProfitType: CloseToAssetType = CloseToAssetType.COLLATERAL,
|
|
555
|
+
) {
|
|
556
|
+
const isBundle = true;
|
|
557
|
+
const closeType = getCloseStrategyType(stopLossPrice, stopLossType, takeProfitPrice, takeProfitType);
|
|
558
|
+
|
|
559
|
+
const subData = subDataService.liquityV2CloseSubData.encode(market, troveId, collToken, boldToken, closeType);
|
|
560
|
+
const triggerData = triggerService.shouldClosePriceTrigger.encode(collToken, stopLossPrice, takeProfitPrice);
|
|
561
|
+
|
|
562
|
+
// TODO: we can hardcode bundleID after testing
|
|
563
|
+
// Bundles.MainnetIds.LIQUITY_V2_CLOSE;
|
|
564
|
+
|
|
540
565
|
return [strategyOrBundleId, isBundle, triggerData, subData];
|
|
541
566
|
},
|
|
542
567
|
};
|
|
@@ -6,7 +6,7 @@ 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';
|
|
9
|
+
import type { CloseStrategyType, OrderType } from '../types/enums';
|
|
10
10
|
import {
|
|
11
11
|
ChainId, CollActionType, DebtActionType, RatioState,
|
|
12
12
|
} from '../types/enums';
|
|
@@ -679,3 +679,48 @@ export const liquityV2LeverageManagementSubData = {
|
|
|
679
679
|
};
|
|
680
680
|
},
|
|
681
681
|
};
|
|
682
|
+
|
|
683
|
+
export const liquityV2CloseSubData = {
|
|
684
|
+
encode(
|
|
685
|
+
market: EthereumAddress,
|
|
686
|
+
troveId: string,
|
|
687
|
+
collToken: EthereumAddress,
|
|
688
|
+
boldToken: EthereumAddress,
|
|
689
|
+
closeType: CloseStrategyType,
|
|
690
|
+
): SubData {
|
|
691
|
+
const marketEncoded = AbiCoder.encodeParameter('address', market);
|
|
692
|
+
const troveIdEncoded = AbiCoder.encodeParameter('uint256', troveId);
|
|
693
|
+
const collAddrEncoded = AbiCoder.encodeParameter('address', collToken);
|
|
694
|
+
const boldTokenEncoded = AbiCoder.encodeParameter('address', boldToken);
|
|
695
|
+
const wethAddress = getAssetInfo('WETH').address;
|
|
696
|
+
const wethAddressEncoded = AbiCoder.encodeParameter('address', wethAddress);
|
|
697
|
+
const closeTypeEncoded = AbiCoder.encodeParameter('uint8', closeType);
|
|
698
|
+
|
|
699
|
+
return [
|
|
700
|
+
marketEncoded,
|
|
701
|
+
troveIdEncoded,
|
|
702
|
+
collAddrEncoded,
|
|
703
|
+
boldTokenEncoded,
|
|
704
|
+
wethAddressEncoded,
|
|
705
|
+
closeTypeEncoded,
|
|
706
|
+
];
|
|
707
|
+
},
|
|
708
|
+
decode(subData: SubData): {
|
|
709
|
+
market: EthereumAddress,
|
|
710
|
+
troveId: string,
|
|
711
|
+
collToken: EthereumAddress,
|
|
712
|
+
boldToken: EthereumAddress,
|
|
713
|
+
closeType: CloseStrategyType,
|
|
714
|
+
} {
|
|
715
|
+
const market = AbiCoder.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
|
|
716
|
+
const troveId = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
|
|
717
|
+
const collToken = AbiCoder.decodeParameter('address', subData[2]) as any as EthereumAddress;
|
|
718
|
+
const boldToken = AbiCoder.decodeParameter('address', subData[3]) as any as EthereumAddress;
|
|
719
|
+
// skip wethAddress
|
|
720
|
+
const closeType = AbiCoder.decodeParameter('uint8', subData[5]) as any as CloseStrategyType;
|
|
721
|
+
|
|
722
|
+
return {
|
|
723
|
+
market, troveId, collToken, boldToken, closeType,
|
|
724
|
+
};
|
|
725
|
+
},
|
|
726
|
+
};
|
|
@@ -470,3 +470,33 @@ export const liquityV2RatioTrigger = {
|
|
|
470
470
|
};
|
|
471
471
|
},
|
|
472
472
|
};
|
|
473
|
+
|
|
474
|
+
export const shouldClosePriceTrigger = {
|
|
475
|
+
encode(
|
|
476
|
+
tokenAddr: EthereumAddress,
|
|
477
|
+
lowerPrice: number,
|
|
478
|
+
upperPrice: number,
|
|
479
|
+
) {
|
|
480
|
+
const lowerPriceFormatted = new Dec(lowerPrice).mul(1e8).floor().toString();
|
|
481
|
+
const upperPriceFormatted = new Dec(upperPrice).mul(1e8).floor().toString();
|
|
482
|
+
|
|
483
|
+
return [
|
|
484
|
+
AbiCoder.encodeParameters(
|
|
485
|
+
['address', 'uint256', 'uint256'],
|
|
486
|
+
[tokenAddr, lowerPriceFormatted, upperPriceFormatted],
|
|
487
|
+
),
|
|
488
|
+
];
|
|
489
|
+
},
|
|
490
|
+
decode(triggerData: TriggerData): {
|
|
491
|
+
tokenAddr: EthereumAddress,
|
|
492
|
+
lowerPrice: string,
|
|
493
|
+
upperPrice: string,
|
|
494
|
+
} {
|
|
495
|
+
const decodedData = AbiCoder.decodeParameters(['address', 'uint256', 'uint256'], triggerData[0]);
|
|
496
|
+
return {
|
|
497
|
+
tokenAddr: decodedData[0] as EthereumAddress,
|
|
498
|
+
lowerPrice: new Dec(decodedData[1] as string).div(1e8).toString(),
|
|
499
|
+
upperPrice: new Dec(decodedData[2] as string).div(1e8).toString(),
|
|
500
|
+
};
|
|
501
|
+
},
|
|
502
|
+
};
|
package/src/services/utils.ts
CHANGED
|
@@ -4,7 +4,9 @@ import AbiCoder from 'web3-eth-abi';
|
|
|
4
4
|
import { getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
|
|
5
5
|
|
|
6
6
|
import type { EthereumAddress } from '../types';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
ChainId, CloseStrategyType, CloseToAssetType, RatioState,
|
|
9
|
+
} from '../types/enums';
|
|
8
10
|
|
|
9
11
|
export function isDefined<T>(value: T): value is NonNullable<T> {
|
|
10
12
|
return value !== undefined && value !== null;
|
|
@@ -101,4 +103,36 @@ export function getRatioStateInfoForAaveCloseStrategy(
|
|
|
101
103
|
|
|
102
104
|
export function getPositionId(...args: (number | string)[]) {
|
|
103
105
|
return args.map(arg => arg.toString().toLowerCase().split(' ').join('_')).join('-');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function getCloseStrategyType(
|
|
109
|
+
stopLossPrice: number,
|
|
110
|
+
stopLossType: CloseToAssetType,
|
|
111
|
+
takeProfitPrice: number,
|
|
112
|
+
takeProfitType: CloseToAssetType,
|
|
113
|
+
): CloseStrategyType {
|
|
114
|
+
const isStopLoss = stopLossPrice > 0;
|
|
115
|
+
const isTakeProfit = takeProfitPrice > 0;
|
|
116
|
+
|
|
117
|
+
if (!isStopLoss && !isTakeProfit) {
|
|
118
|
+
throw new Error('CloseOnPrice: At least one price must be defined');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (isStopLoss && isTakeProfit) {
|
|
122
|
+
if (stopLossType === CloseToAssetType.COLLATERAL && takeProfitType === CloseToAssetType.COLLATERAL) {
|
|
123
|
+
return CloseStrategyType.TAKE_PROFIT_AND_STOP_LOSS_IN_COLLATERAL;
|
|
124
|
+
} if (stopLossType === CloseToAssetType.COLLATERAL) {
|
|
125
|
+
return CloseStrategyType.TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL;
|
|
126
|
+
} if (takeProfitType === CloseToAssetType.COLLATERAL) {
|
|
127
|
+
return CloseStrategyType.TAKE_PROFIT_IN_COLLATERAL_AND_STOP_LOSS_IN_DEBT;
|
|
128
|
+
}
|
|
129
|
+
return CloseStrategyType.TAKE_PROFIT_AND_STOP_LOSS_IN_DEBT;
|
|
130
|
+
} if (isStopLoss) {
|
|
131
|
+
return stopLossType === CloseToAssetType.COLLATERAL
|
|
132
|
+
? CloseStrategyType.STOP_LOSS_IN_COLLATERAL
|
|
133
|
+
: CloseStrategyType.STOP_LOSS_IN_DEBT;
|
|
134
|
+
}
|
|
135
|
+
return takeProfitType === CloseToAssetType.COLLATERAL
|
|
136
|
+
? CloseStrategyType.TAKE_PROFIT_IN_COLLATERAL
|
|
137
|
+
: CloseStrategyType.TAKE_PROFIT_IN_DEBT;
|
|
104
138
|
}
|
package/src/types/enums.ts
CHANGED
|
@@ -31,6 +31,22 @@ export enum DebtActionType {
|
|
|
31
31
|
BORROW = 1,
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
export enum CloseStrategyType {
|
|
35
|
+
TAKE_PROFIT_IN_COLLATERAL = 0,
|
|
36
|
+
STOP_LOSS_IN_COLLATERAL = 1,
|
|
37
|
+
TAKE_PROFIT_IN_DEBT = 2,
|
|
38
|
+
STOP_LOSS_IN_DEBT = 3,
|
|
39
|
+
TAKE_PROFIT_AND_STOP_LOSS_IN_COLLATERAL = 4,
|
|
40
|
+
TAKE_PROFIT_IN_COLLATERAL_AND_STOP_LOSS_IN_DEBT = 5,
|
|
41
|
+
TAKE_PROFIT_AND_STOP_LOSS_IN_DEBT = 6,
|
|
42
|
+
TAKE_PROFIT_IN_DEBT_AND_STOP_LOSS_IN_COLLATERAL = 7,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export enum CloseToAssetType {
|
|
46
|
+
COLLATERAL = 0,
|
|
47
|
+
DEBT = 1,
|
|
48
|
+
}
|
|
49
|
+
|
|
34
50
|
/**
|
|
35
51
|
* @dev Follow the naming convention:
|
|
36
52
|
* - Enum name consists of two parts, name and version
|
|
@@ -112,6 +128,7 @@ export namespace Strategies {
|
|
|
112
128
|
CloseToCollateralWithGasPrice = 'close-to-collateral-with-gas-price',
|
|
113
129
|
CloseOnPriceToDebt = 'close-on-price-to-debt',
|
|
114
130
|
CloseOnPriceToColl = 'close-on-price-to-collateral',
|
|
131
|
+
CloseOnPrice = 'close-on-price',
|
|
115
132
|
TrailingStopToColl = 'trailing-stop-to-collateral',
|
|
116
133
|
TrailingStopToDebt = 'trailing-stop-to-debt',
|
|
117
134
|
Rebond = 'rebond',
|
|
@@ -177,6 +194,7 @@ export namespace Bundles {
|
|
|
177
194
|
AAVE_V3_OPEN_ORDER_FROM_COLLATERAL = 36,
|
|
178
195
|
LIQUITY_V2_REPAY = 37,
|
|
179
196
|
LIQUITY_V2_BOOST = 38,
|
|
197
|
+
LIQUITY_V2_CLOSE = 39,
|
|
180
198
|
}
|
|
181
199
|
|
|
182
200
|
export enum OptimismIds {
|