@defisaver/automation-sdk 1.2.11 → 1.2.13
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/esm/constants/index.d.ts +24 -2
- package/esm/constants/index.js +34 -2
- package/esm/services/strategiesService.js +20 -0
- package/esm/services/strategySubService.d.ts +4 -0
- package/esm/services/strategySubService.js +17 -1
- package/esm/services/subDataService.d.ts +17 -0
- package/esm/services/subDataService.js +42 -9
- package/esm/services/triggerService.d.ts +14 -0
- package/esm/services/triggerService.js +34 -5
- package/esm/types/enums.d.ts +12 -3
- package/esm/types/enums.js +9 -0
- package/package.json +1 -1
- package/src/constants/index.ts +34 -2
- package/src/services/strategiesService.ts +27 -0
- package/src/services/strategySubService.ts +32 -1
- package/src/services/subDataService.ts +47 -9
- package/src/services/triggerService.ts +48 -6
- package/src/types/enums.ts +13 -2
- package/umd/index.js +786 -407
- package/yarn-error.log +6937 -0
package/esm/constants/index.d.ts
CHANGED
|
@@ -4,8 +4,30 @@ export declare const ZERO_ADDRESS: EthereumAddress;
|
|
|
4
4
|
export declare const PROTOCOLS: Record<keyof typeof ProtocolIdentifiers.StrategiesAutomation, Interfaces.Protocol>;
|
|
5
5
|
export declare const LEGACY_PROTOCOLS: Record<keyof typeof ProtocolIdentifiers.LegacyAutomation, Interfaces.LegacyProtocol>;
|
|
6
6
|
export declare const MAINNET_STRATEGIES_INFO: MainnetStrategiesInfo;
|
|
7
|
-
export declare const OPTIMISM_STRATEGIES_INFO: {
|
|
8
|
-
|
|
7
|
+
export declare const OPTIMISM_STRATEGIES_INFO: {
|
|
8
|
+
8: {
|
|
9
|
+
strategyOrBundleId: Strategies.OptimismIds;
|
|
10
|
+
strategyId: Strategies.Identifiers;
|
|
11
|
+
protocol: Interfaces.Protocol;
|
|
12
|
+
};
|
|
13
|
+
9: {
|
|
14
|
+
strategyOrBundleId: Strategies.OptimismIds;
|
|
15
|
+
strategyId: Strategies.Identifiers;
|
|
16
|
+
protocol: Interfaces.Protocol;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export declare const ARBITRUM_STRATEGIES_INFO: {
|
|
20
|
+
8: {
|
|
21
|
+
strategyOrBundleId: Strategies.ArbitrumIds;
|
|
22
|
+
strategyId: Strategies.Identifiers;
|
|
23
|
+
protocol: Interfaces.Protocol;
|
|
24
|
+
};
|
|
25
|
+
9: {
|
|
26
|
+
strategyOrBundleId: Strategies.ArbitrumIds;
|
|
27
|
+
strategyId: Strategies.Identifiers;
|
|
28
|
+
protocol: Interfaces.Protocol;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
9
31
|
export declare const STRATEGIES_INFO: StrategiesInfo;
|
|
10
32
|
export declare const STRATEGY_IDS: {
|
|
11
33
|
1: typeof Strategies.MainnetIds;
|
package/esm/constants/index.js
CHANGED
|
@@ -59,9 +59,41 @@ export const MAINNET_STRATEGIES_INFO = {
|
|
|
59
59
|
strategyId: Strategies.Identifiers.Rebond,
|
|
60
60
|
protocol: PROTOCOLS.ChickenBonds,
|
|
61
61
|
},
|
|
62
|
+
[Strategies.MainnetIds.EXCHANGE_DCA]: {
|
|
63
|
+
strategyOrBundleId: Strategies.MainnetIds.EXCHANGE_DCA,
|
|
64
|
+
strategyId: Strategies.Identifiers.Dca,
|
|
65
|
+
protocol: PROTOCOLS.Exchange,
|
|
66
|
+
},
|
|
67
|
+
[Strategies.MainnetIds.EXCHANGE_LIMIT_ORDER]: {
|
|
68
|
+
strategyOrBundleId: Strategies.MainnetIds.EXCHANGE_LIMIT_ORDER,
|
|
69
|
+
strategyId: Strategies.Identifiers.LimitOrder,
|
|
70
|
+
protocol: PROTOCOLS.Exchange,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
export const OPTIMISM_STRATEGIES_INFO = {
|
|
74
|
+
[Strategies.OptimismIds.EXCHANGE_DCA]: {
|
|
75
|
+
strategyOrBundleId: Strategies.OptimismIds.EXCHANGE_DCA,
|
|
76
|
+
strategyId: Strategies.Identifiers.Dca,
|
|
77
|
+
protocol: PROTOCOLS.Exchange,
|
|
78
|
+
},
|
|
79
|
+
[Strategies.OptimismIds.EXCHANGE_LIMIT_ORDER]: {
|
|
80
|
+
strategyOrBundleId: Strategies.OptimismIds.EXCHANGE_LIMIT_ORDER,
|
|
81
|
+
strategyId: Strategies.Identifiers.LimitOrder,
|
|
82
|
+
protocol: PROTOCOLS.Exchange,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
export const ARBITRUM_STRATEGIES_INFO = {
|
|
86
|
+
[Strategies.ArbitrumIds.EXCHANGE_DCA]: {
|
|
87
|
+
strategyOrBundleId: Strategies.ArbitrumIds.EXCHANGE_DCA,
|
|
88
|
+
strategyId: Strategies.Identifiers.Dca,
|
|
89
|
+
protocol: PROTOCOLS.Exchange,
|
|
90
|
+
},
|
|
91
|
+
[Strategies.ArbitrumIds.EXCHANGE_LIMIT_ORDER]: {
|
|
92
|
+
strategyOrBundleId: Strategies.ArbitrumIds.EXCHANGE_LIMIT_ORDER,
|
|
93
|
+
strategyId: Strategies.Identifiers.LimitOrder,
|
|
94
|
+
protocol: PROTOCOLS.Exchange,
|
|
95
|
+
},
|
|
62
96
|
};
|
|
63
|
-
export const OPTIMISM_STRATEGIES_INFO = {};
|
|
64
|
-
export const ARBITRUM_STRATEGIES_INFO = {};
|
|
65
97
|
export const STRATEGIES_INFO = {
|
|
66
98
|
[ChainId.Ethereum]: MAINNET_STRATEGIES_INFO,
|
|
67
99
|
[ChainId.Optimism]: OPTIMISM_STRATEGIES_INFO,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getAssetInfoByAddress } from '@defisaver/tokens';
|
|
1
2
|
import { cloneDeep } from 'lodash';
|
|
2
3
|
import { BUNDLES_INFO, STRATEGIES_INFO } from '../constants';
|
|
3
4
|
import { ProtocolIdentifiers, Strategies } from '../types/enums';
|
|
@@ -238,6 +239,21 @@ function parseLiquityBondProtection(position, parseData) {
|
|
|
238
239
|
};
|
|
239
240
|
return _position;
|
|
240
241
|
}
|
|
242
|
+
function parseExchangeDca(position, parseData) {
|
|
243
|
+
const _position = cloneDeep(position);
|
|
244
|
+
const { subStruct } = parseData.subscriptionEventData;
|
|
245
|
+
_position.strategyData.decoded.triggerData = triggerService.exchangeTimestampTrigger.decode(subStruct.triggerData);
|
|
246
|
+
_position.strategyData.decoded.subData = subDataService.exchangeDcaSubData.decode(subStruct.subData);
|
|
247
|
+
return _position;
|
|
248
|
+
}
|
|
249
|
+
function parseExchangeLimitOrder(position, parseData) {
|
|
250
|
+
const _position = cloneDeep(position);
|
|
251
|
+
const { subStruct } = parseData.subscriptionEventData;
|
|
252
|
+
_position.strategyData.decoded.subData = subDataService.exchangeLimitOrderSubData.decode(subStruct.subData);
|
|
253
|
+
const fromTokenDecimals = getAssetInfoByAddress(_position.strategyData.decoded.subData.fromToken).decimals;
|
|
254
|
+
_position.strategyData.decoded.triggerData = triggerService.exchangeOffchainPriceTrigger.decode(subStruct.triggerData, fromTokenDecimals);
|
|
255
|
+
return _position;
|
|
256
|
+
}
|
|
241
257
|
const parsingMethodsMapping = {
|
|
242
258
|
[ProtocolIdentifiers.StrategiesAutomation.MakerDAO]: {
|
|
243
259
|
[Strategies.Identifiers.SavingsLiqProtection]: parseMakerSavingsLiqProtection,
|
|
@@ -272,6 +288,10 @@ const parsingMethodsMapping = {
|
|
|
272
288
|
[Strategies.Identifiers.Repay]: parseMorphoAaveV2LeverageManagement,
|
|
273
289
|
[Strategies.Identifiers.Boost]: parseMorphoAaveV2LeverageManagement,
|
|
274
290
|
},
|
|
291
|
+
[ProtocolIdentifiers.StrategiesAutomation.Exchange]: {
|
|
292
|
+
[Strategies.Identifiers.Dca]: parseExchangeDca,
|
|
293
|
+
[Strategies.Identifiers.LimitOrder]: parseExchangeLimitOrder,
|
|
294
|
+
},
|
|
275
295
|
};
|
|
276
296
|
function getParsingMethod(id, strategy) {
|
|
277
297
|
return parsingMethodsMapping[id][strategy.strategyId];
|
|
@@ -34,3 +34,7 @@ export declare const compoundV3Encode: {
|
|
|
34
34
|
export declare const morphoAaveV2Encode: {
|
|
35
35
|
leverageManagement(minRatio: number, maxRatio: number, maxOptimalRatio: number, minOptimalRatio: number, boostEnabled: boolean): string[];
|
|
36
36
|
};
|
|
37
|
+
export declare const exchangeEncode: {
|
|
38
|
+
dca(fromToken: EthereumAddress, toToken: EthereumAddress, amount: string, timestamp: number, interval: number): (boolean | string[] | Strategies.MainnetIds)[];
|
|
39
|
+
limitOrder(fromToken: EthereumAddress, toToken: EthereumAddress, amount: string, targetPrice: string, goodUntil: number): (boolean | string[] | Strategies.MainnetIds)[];
|
|
40
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Dec from 'decimal.js';
|
|
2
|
-
import { getAssetInfo } from '@defisaver/tokens';
|
|
2
|
+
import { getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
|
|
3
3
|
import { Bundles, ChainId, RatioState, Strategies, } from '../types/enums';
|
|
4
4
|
import * as subDataService from './subDataService';
|
|
5
5
|
import * as triggerService from './triggerService';
|
|
@@ -104,3 +104,19 @@ export const morphoAaveV2Encode = {
|
|
|
104
104
|
return subDataService.morphoAaveV2LeverageManagementSubData.encode(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled);
|
|
105
105
|
},
|
|
106
106
|
};
|
|
107
|
+
export const exchangeEncode = {
|
|
108
|
+
dca(fromToken, toToken, amount, timestamp, interval) {
|
|
109
|
+
requireAddresses([fromToken, toToken]);
|
|
110
|
+
const subData = subDataService.exchangeDcaSubData.encode(fromToken, toToken, amount, interval);
|
|
111
|
+
const triggerData = triggerService.exchangeTimestampTrigger.encode(timestamp, interval);
|
|
112
|
+
const strategyId = Strategies.MainnetIds.EXCHANGE_DCA;
|
|
113
|
+
return [strategyId, false, triggerData, subData];
|
|
114
|
+
},
|
|
115
|
+
limitOrder(fromToken, toToken, amount, targetPrice, goodUntil) {
|
|
116
|
+
const strategyId = Strategies.MainnetIds.EXCHANGE_LIMIT_ORDER;
|
|
117
|
+
const subData = subDataService.exchangeLimitOrderSubData.encode(fromToken, toToken, amount);
|
|
118
|
+
const fromTokenDecimals = getAssetInfoByAddress(fromToken).decimals;
|
|
119
|
+
const triggerData = triggerService.exchangeOffchainPriceTrigger.encode(targetPrice, goodUntil, fromTokenDecimals);
|
|
120
|
+
return [strategyId, false, triggerData, subData];
|
|
121
|
+
},
|
|
122
|
+
};
|
|
@@ -73,3 +73,20 @@ export declare const liquityPaybackUsingChickenBondSubData: {
|
|
|
73
73
|
sourceType: string;
|
|
74
74
|
};
|
|
75
75
|
};
|
|
76
|
+
export declare const exchangeDcaSubData: {
|
|
77
|
+
encode: (fromToken: EthereumAddress, toToken: EthereumAddress, amount: string, interval: number) => string[];
|
|
78
|
+
decode: (subData: string[]) => {
|
|
79
|
+
fromToken: string;
|
|
80
|
+
toToken: string;
|
|
81
|
+
amount: string;
|
|
82
|
+
interval: string;
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
export declare const exchangeLimitOrderSubData: {
|
|
86
|
+
encode: (fromToken: EthereumAddress, toToken: EthereumAddress, amount: string) => string[];
|
|
87
|
+
decode: (subData: string[]) => {
|
|
88
|
+
fromToken: string;
|
|
89
|
+
toToken: string;
|
|
90
|
+
amount: string;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
@@ -136,17 +136,15 @@ export const compoundV3LeverageManagementSubData = {
|
|
|
136
136
|
};
|
|
137
137
|
export const morphoAaveV2LeverageManagementSubData = {
|
|
138
138
|
encode(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
boostEnabled,
|
|
146
|
-
];
|
|
139
|
+
const encodedMinRatio = mockedWeb3.eth.abi.encodeParameter('uint128', ratioPercentageToWei(minRatio));
|
|
140
|
+
const encodedMaxRatio = mockedWeb3.eth.abi.encodeParameter('uint128', ratioPercentageToWei(maxRatio));
|
|
141
|
+
const encodedMaxOptimalRatio = mockedWeb3.eth.abi.encodeParameter('uint128', ratioPercentageToWei(maxOptimalRatio));
|
|
142
|
+
const encodedMinOptimalRatio = mockedWeb3.eth.abi.encodeParameter('uint128', ratioPercentageToWei(minOptimalRatio));
|
|
143
|
+
const encodedBoostEnabled = mockedWeb3.eth.abi.encodeParameter('bool', boostEnabled);
|
|
144
|
+
return [encodedMinRatio, encodedMaxRatio, encodedMaxOptimalRatio, encodedMinOptimalRatio, encodedBoostEnabled];
|
|
147
145
|
},
|
|
148
146
|
decode(subData) {
|
|
149
|
-
const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint128', subData[
|
|
147
|
+
const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint128', subData[0]);
|
|
150
148
|
const targetRatio = weiToRatioPercentage(ratioWei);
|
|
151
149
|
return { targetRatio };
|
|
152
150
|
},
|
|
@@ -180,3 +178,38 @@ export const liquityPaybackUsingChickenBondSubData = {
|
|
|
180
178
|
return { sourceId, sourceType };
|
|
181
179
|
},
|
|
182
180
|
};
|
|
181
|
+
export const exchangeDcaSubData = {
|
|
182
|
+
encode: (fromToken, toToken, amount, interval) => {
|
|
183
|
+
const sellTokenEncoded = mockedWeb3.eth.abi.encodeParameter('address', fromToken);
|
|
184
|
+
const buyTokenEncoded = mockedWeb3.eth.abi.encodeParameter('address', toToken);
|
|
185
|
+
const amountEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', amount);
|
|
186
|
+
const intervalEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', interval);
|
|
187
|
+
return [sellTokenEncoded, buyTokenEncoded, amountEncoded, intervalEncoded];
|
|
188
|
+
},
|
|
189
|
+
decode: (subData) => {
|
|
190
|
+
const fromToken = mockedWeb3.eth.abi.decodeParameter('address', subData[0]).toString();
|
|
191
|
+
const toToken = mockedWeb3.eth.abi.decodeParameter('address', subData[1]).toString();
|
|
192
|
+
const amount = mockedWeb3.eth.abi.decodeParameter('uint256', subData[2]).toString();
|
|
193
|
+
const interval = mockedWeb3.eth.abi.decodeParameter('uint256', subData[3]).toString();
|
|
194
|
+
return {
|
|
195
|
+
fromToken,
|
|
196
|
+
toToken,
|
|
197
|
+
amount,
|
|
198
|
+
interval,
|
|
199
|
+
};
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
export const exchangeLimitOrderSubData = {
|
|
203
|
+
encode: (fromToken, toToken, amount) => {
|
|
204
|
+
const fromTokenEncoded = mockedWeb3.eth.abi.encodeParameter('address', fromToken);
|
|
205
|
+
const toTokenEncoded = mockedWeb3.eth.abi.encodeParameter('address', toToken);
|
|
206
|
+
const amountEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', amount);
|
|
207
|
+
return [fromTokenEncoded, toTokenEncoded, amountEncoded];
|
|
208
|
+
},
|
|
209
|
+
decode: (subData) => {
|
|
210
|
+
const fromToken = mockedWeb3.eth.abi.decodeParameter('address', subData[0]).toString();
|
|
211
|
+
const toToken = mockedWeb3.eth.abi.decodeParameter('address', subData[1]).toString();
|
|
212
|
+
const amount = mockedWeb3.eth.abi.decodeParameter('uint256', subData[2]).toString();
|
|
213
|
+
return { fromToken, toToken, amount };
|
|
214
|
+
},
|
|
215
|
+
};
|
|
@@ -97,3 +97,17 @@ export declare const compoundV3RatioTrigger: {
|
|
|
97
97
|
ratio: number;
|
|
98
98
|
};
|
|
99
99
|
};
|
|
100
|
+
export declare const exchangeTimestampTrigger: {
|
|
101
|
+
encode(timestamp: number, interval: number): string[];
|
|
102
|
+
decode(triggerData: string[]): {
|
|
103
|
+
timestamp: number;
|
|
104
|
+
interval: number;
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
export declare const exchangeOffchainPriceTrigger: {
|
|
108
|
+
encode(targetPrice: string, goodUntil: number, fromTokenDecimals: number): string[];
|
|
109
|
+
decode(triggerData: string[], fromTokenDecimals: number): {
|
|
110
|
+
targetPrice: string;
|
|
111
|
+
goodUntil: number;
|
|
112
|
+
};
|
|
113
|
+
};
|
|
@@ -49,15 +49,15 @@ export const aaveV3RatioTrigger = {
|
|
|
49
49
|
};
|
|
50
50
|
export const morphoAaveV2RatioTrigger = {
|
|
51
51
|
encode(owner, ratioPercentage, ratioState) {
|
|
52
|
-
const ratioWei =
|
|
53
|
-
return [mockedWeb3.eth.abi.encodeParameters(['address', '
|
|
52
|
+
const ratioWei = ratioPercentageToWei(ratioPercentage);
|
|
53
|
+
return [mockedWeb3.eth.abi.encodeParameters(['address', 'uint256', 'uint8'], [owner, ratioWei, ratioState])];
|
|
54
54
|
},
|
|
55
55
|
decode(triggerData) {
|
|
56
|
-
const decodedData = mockedWeb3.eth.abi.decodeParameters(['address', '
|
|
56
|
+
const decodedData = mockedWeb3.eth.abi.decodeParameters(['address', 'uint256', 'uint8'], triggerData[0]);
|
|
57
57
|
return {
|
|
58
58
|
owner: decodedData[0],
|
|
59
|
-
ratio: new Dec(decodedData[
|
|
60
|
-
ratioState: Number(decodedData[
|
|
59
|
+
ratio: new Dec(mockedWeb3.utils.fromWei(decodedData[2])).mul(100).toNumber(),
|
|
60
|
+
ratioState: Number(decodedData[3]),
|
|
61
61
|
};
|
|
62
62
|
},
|
|
63
63
|
};
|
|
@@ -158,3 +158,32 @@ export const compoundV3RatioTrigger = {
|
|
|
158
158
|
};
|
|
159
159
|
},
|
|
160
160
|
};
|
|
161
|
+
export const exchangeTimestampTrigger = {
|
|
162
|
+
encode(timestamp, interval) {
|
|
163
|
+
const timestampWei = mockedWeb3.utils.toWei(new Dec(timestamp).toString());
|
|
164
|
+
const intervalWei = mockedWeb3.utils.toWei(new Dec(interval).toString());
|
|
165
|
+
return [mockedWeb3.eth.abi.encodeParameters(['uint256', 'uint256'], [timestampWei, intervalWei])];
|
|
166
|
+
},
|
|
167
|
+
decode(triggerData) {
|
|
168
|
+
const decodedData = mockedWeb3.eth.abi.decodeParameters(['uint256', 'uint256'], triggerData[0]);
|
|
169
|
+
return {
|
|
170
|
+
timestamp: new Dec(mockedWeb3.utils.fromWei(decodedData[0])).toNumber(),
|
|
171
|
+
interval: new Dec(mockedWeb3.utils.fromWei(decodedData[1])).toNumber(),
|
|
172
|
+
};
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
export const exchangeOffchainPriceTrigger = {
|
|
176
|
+
encode(targetPrice, goodUntil, fromTokenDecimals) {
|
|
177
|
+
const price = new Dec(targetPrice.toString()).mul(Math.pow(10, fromTokenDecimals)).floor().toString();
|
|
178
|
+
const goodUntilWei = mockedWeb3.utils.toWei(new Dec(goodUntil).toString());
|
|
179
|
+
return [mockedWeb3.eth.abi.encodeParameters(['uint256', 'uint256'], [price, goodUntilWei])];
|
|
180
|
+
},
|
|
181
|
+
decode(triggerData, fromTokenDecimals) {
|
|
182
|
+
const decodedData = mockedWeb3.eth.abi.decodeParameters(['uint256', 'uint256'], triggerData[0]);
|
|
183
|
+
const price = new Dec(decodedData[0]).div(Math.pow(10, fromTokenDecimals)).toDP(fromTokenDecimals).toString();
|
|
184
|
+
return {
|
|
185
|
+
targetPrice: price,
|
|
186
|
+
goodUntil: new Dec(mockedWeb3.utils.fromWei(decodedData[1])).toNumber(),
|
|
187
|
+
};
|
|
188
|
+
},
|
|
189
|
+
};
|
package/esm/types/enums.d.ts
CHANGED
|
@@ -26,7 +26,8 @@ export declare namespace ProtocolIdentifiers {
|
|
|
26
26
|
ChickenBonds = "Chicken Bonds",
|
|
27
27
|
CompoundV3 = "Compound__V3",
|
|
28
28
|
AaveV3 = "Aave__V3",
|
|
29
|
-
MorphoAaveV2 = "Morpho-Aave__V2"
|
|
29
|
+
MorphoAaveV2 = "Morpho-Aave__V2",
|
|
30
|
+
Exchange = "Exchange"
|
|
30
31
|
}
|
|
31
32
|
enum LegacyAutomation {
|
|
32
33
|
MakerDAO = "MakerDAO",
|
|
@@ -43,11 +44,17 @@ export declare namespace Strategies {
|
|
|
43
44
|
MAKER_TRAILING_STOP_LOSS_TO_DAI = 12,
|
|
44
45
|
LIQUITY_TRAILING_STOP_LOSS_TO_COLL = 13,
|
|
45
46
|
LIQUITY_CLOSE_ON_PRICE_TO_COLL = 14,
|
|
46
|
-
CHICKEN_BONDS_REBOND = 31
|
|
47
|
+
CHICKEN_BONDS_REBOND = 31,
|
|
48
|
+
EXCHANGE_DCA = 46,
|
|
49
|
+
EXCHANGE_LIMIT_ORDER = 51
|
|
47
50
|
}
|
|
48
51
|
enum OptimismIds {
|
|
52
|
+
EXCHANGE_DCA = 8,
|
|
53
|
+
EXCHANGE_LIMIT_ORDER = 9
|
|
49
54
|
}
|
|
50
55
|
enum ArbitrumIds {
|
|
56
|
+
EXCHANGE_DCA = 8,
|
|
57
|
+
EXCHANGE_LIMIT_ORDER = 9
|
|
51
58
|
}
|
|
52
59
|
enum Identifiers {
|
|
53
60
|
SavingsLiqProtection = "smart-savings-liquidation-protection",
|
|
@@ -62,7 +69,9 @@ export declare namespace Strategies {
|
|
|
62
69
|
TrailingStopToColl = "trailing-stop-to-collateral",
|
|
63
70
|
TrailingStopToDebt = "trailing-stop-to-debt",
|
|
64
71
|
Rebond = "rebond",
|
|
65
|
-
BondProtection = "bond-protection"
|
|
72
|
+
BondProtection = "bond-protection",
|
|
73
|
+
Dca = "dca",
|
|
74
|
+
LimitOrder = "limit-order"
|
|
66
75
|
}
|
|
67
76
|
enum IdOverrides {
|
|
68
77
|
TakeProfit = "take-profit",
|
package/esm/types/enums.js
CHANGED
|
@@ -32,6 +32,7 @@ export var ProtocolIdentifiers;
|
|
|
32
32
|
StrategiesAutomation["CompoundV3"] = "Compound__V3";
|
|
33
33
|
StrategiesAutomation["AaveV3"] = "Aave__V3";
|
|
34
34
|
StrategiesAutomation["MorphoAaveV2"] = "Morpho-Aave__V2";
|
|
35
|
+
StrategiesAutomation["Exchange"] = "Exchange";
|
|
35
36
|
})(StrategiesAutomation = ProtocolIdentifiers.StrategiesAutomation || (ProtocolIdentifiers.StrategiesAutomation = {}));
|
|
36
37
|
let LegacyAutomation;
|
|
37
38
|
(function (LegacyAutomation) {
|
|
@@ -52,12 +53,18 @@ export var Strategies;
|
|
|
52
53
|
MainnetIds[MainnetIds["LIQUITY_TRAILING_STOP_LOSS_TO_COLL"] = 13] = "LIQUITY_TRAILING_STOP_LOSS_TO_COLL";
|
|
53
54
|
MainnetIds[MainnetIds["LIQUITY_CLOSE_ON_PRICE_TO_COLL"] = 14] = "LIQUITY_CLOSE_ON_PRICE_TO_COLL";
|
|
54
55
|
MainnetIds[MainnetIds["CHICKEN_BONDS_REBOND"] = 31] = "CHICKEN_BONDS_REBOND";
|
|
56
|
+
MainnetIds[MainnetIds["EXCHANGE_DCA"] = 46] = "EXCHANGE_DCA";
|
|
57
|
+
MainnetIds[MainnetIds["EXCHANGE_LIMIT_ORDER"] = 51] = "EXCHANGE_LIMIT_ORDER";
|
|
55
58
|
})(MainnetIds = Strategies.MainnetIds || (Strategies.MainnetIds = {}));
|
|
56
59
|
let OptimismIds;
|
|
57
60
|
(function (OptimismIds) {
|
|
61
|
+
OptimismIds[OptimismIds["EXCHANGE_DCA"] = 8] = "EXCHANGE_DCA";
|
|
62
|
+
OptimismIds[OptimismIds["EXCHANGE_LIMIT_ORDER"] = 9] = "EXCHANGE_LIMIT_ORDER";
|
|
58
63
|
})(OptimismIds = Strategies.OptimismIds || (Strategies.OptimismIds = {}));
|
|
59
64
|
let ArbitrumIds;
|
|
60
65
|
(function (ArbitrumIds) {
|
|
66
|
+
ArbitrumIds[ArbitrumIds["EXCHANGE_DCA"] = 8] = "EXCHANGE_DCA";
|
|
67
|
+
ArbitrumIds[ArbitrumIds["EXCHANGE_LIMIT_ORDER"] = 9] = "EXCHANGE_LIMIT_ORDER";
|
|
61
68
|
})(ArbitrumIds = Strategies.ArbitrumIds || (Strategies.ArbitrumIds = {}));
|
|
62
69
|
let Identifiers;
|
|
63
70
|
(function (Identifiers) {
|
|
@@ -74,6 +81,8 @@ export var Strategies;
|
|
|
74
81
|
Identifiers["TrailingStopToDebt"] = "trailing-stop-to-debt";
|
|
75
82
|
Identifiers["Rebond"] = "rebond";
|
|
76
83
|
Identifiers["BondProtection"] = "bond-protection";
|
|
84
|
+
Identifiers["Dca"] = "dca";
|
|
85
|
+
Identifiers["LimitOrder"] = "limit-order";
|
|
77
86
|
})(Identifiers = Strategies.Identifiers || (Strategies.Identifiers = {}));
|
|
78
87
|
let IdOverrides;
|
|
79
88
|
(function (IdOverrides) {
|
package/package.json
CHANGED
package/src/constants/index.ts
CHANGED
|
@@ -70,11 +70,43 @@ export const MAINNET_STRATEGIES_INFO: MainnetStrategiesInfo = {
|
|
|
70
70
|
strategyId: Strategies.Identifiers.Rebond,
|
|
71
71
|
protocol: PROTOCOLS.ChickenBonds,
|
|
72
72
|
},
|
|
73
|
+
[Strategies.MainnetIds.EXCHANGE_DCA]: {
|
|
74
|
+
strategyOrBundleId: Strategies.MainnetIds.EXCHANGE_DCA,
|
|
75
|
+
strategyId: Strategies.Identifiers.Dca,
|
|
76
|
+
protocol: PROTOCOLS.Exchange,
|
|
77
|
+
},
|
|
78
|
+
[Strategies.MainnetIds.EXCHANGE_LIMIT_ORDER]: {
|
|
79
|
+
strategyOrBundleId: Strategies.MainnetIds.EXCHANGE_LIMIT_ORDER,
|
|
80
|
+
strategyId: Strategies.Identifiers.LimitOrder,
|
|
81
|
+
protocol: PROTOCOLS.Exchange,
|
|
82
|
+
},
|
|
73
83
|
};
|
|
74
84
|
|
|
75
|
-
export const OPTIMISM_STRATEGIES_INFO = {
|
|
85
|
+
export const OPTIMISM_STRATEGIES_INFO = {
|
|
86
|
+
[Strategies.OptimismIds.EXCHANGE_DCA]: {
|
|
87
|
+
strategyOrBundleId: Strategies.OptimismIds.EXCHANGE_DCA,
|
|
88
|
+
strategyId: Strategies.Identifiers.Dca,
|
|
89
|
+
protocol: PROTOCOLS.Exchange,
|
|
90
|
+
},
|
|
91
|
+
[Strategies.OptimismIds.EXCHANGE_LIMIT_ORDER]: {
|
|
92
|
+
strategyOrBundleId: Strategies.OptimismIds.EXCHANGE_LIMIT_ORDER,
|
|
93
|
+
strategyId: Strategies.Identifiers.LimitOrder,
|
|
94
|
+
protocol: PROTOCOLS.Exchange,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
76
97
|
|
|
77
|
-
export const ARBITRUM_STRATEGIES_INFO = {
|
|
98
|
+
export const ARBITRUM_STRATEGIES_INFO = {
|
|
99
|
+
[Strategies.ArbitrumIds.EXCHANGE_DCA]: {
|
|
100
|
+
strategyOrBundleId: Strategies.ArbitrumIds.EXCHANGE_DCA,
|
|
101
|
+
strategyId: Strategies.Identifiers.Dca,
|
|
102
|
+
protocol: PROTOCOLS.Exchange,
|
|
103
|
+
},
|
|
104
|
+
[Strategies.ArbitrumIds.EXCHANGE_LIMIT_ORDER]: {
|
|
105
|
+
strategyOrBundleId: Strategies.ArbitrumIds.EXCHANGE_LIMIT_ORDER,
|
|
106
|
+
strategyId: Strategies.Identifiers.LimitOrder,
|
|
107
|
+
protocol: PROTOCOLS.Exchange,
|
|
108
|
+
},
|
|
109
|
+
};
|
|
78
110
|
|
|
79
111
|
export const STRATEGIES_INFO: StrategiesInfo = {
|
|
80
112
|
[ChainId.Ethereum]: MAINNET_STRATEGIES_INFO,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getAssetInfoByAddress } from '@defisaver/tokens';
|
|
1
2
|
import { cloneDeep } from 'lodash';
|
|
2
3
|
|
|
3
4
|
import { BUNDLES_INFO, STRATEGIES_INFO } from '../constants';
|
|
@@ -328,6 +329,28 @@ function parseLiquityBondProtection(position: Position.Automated, parseData: Par
|
|
|
328
329
|
return _position;
|
|
329
330
|
}
|
|
330
331
|
|
|
332
|
+
function parseExchangeDca(position: Position.Automated, parseData: ParseData): Position.Automated {
|
|
333
|
+
const _position = cloneDeep(position);
|
|
334
|
+
|
|
335
|
+
const { subStruct } = parseData.subscriptionEventData;
|
|
336
|
+
|
|
337
|
+
_position.strategyData.decoded.triggerData = triggerService.exchangeTimestampTrigger.decode(subStruct.triggerData);
|
|
338
|
+
_position.strategyData.decoded.subData = subDataService.exchangeDcaSubData.decode(subStruct.subData);
|
|
339
|
+
|
|
340
|
+
return _position;
|
|
341
|
+
}
|
|
342
|
+
function parseExchangeLimitOrder(position: Position.Automated, parseData: ParseData): Position.Automated {
|
|
343
|
+
const _position = cloneDeep(position);
|
|
344
|
+
|
|
345
|
+
const { subStruct } = parseData.subscriptionEventData;
|
|
346
|
+
|
|
347
|
+
_position.strategyData.decoded.subData = subDataService.exchangeLimitOrderSubData.decode(subStruct.subData);
|
|
348
|
+
const fromTokenDecimals = getAssetInfoByAddress(_position.strategyData.decoded.subData.fromToken).decimals;
|
|
349
|
+
_position.strategyData.decoded.triggerData = triggerService.exchangeOffchainPriceTrigger.decode(subStruct.triggerData, fromTokenDecimals);
|
|
350
|
+
|
|
351
|
+
return _position;
|
|
352
|
+
}
|
|
353
|
+
|
|
331
354
|
const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
|
|
332
355
|
[ProtocolIdentifiers.StrategiesAutomation.MakerDAO]: {
|
|
333
356
|
[Strategies.Identifiers.SavingsLiqProtection]: parseMakerSavingsLiqProtection,
|
|
@@ -362,6 +385,10 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
|
|
|
362
385
|
[Strategies.Identifiers.Repay]: parseMorphoAaveV2LeverageManagement,
|
|
363
386
|
[Strategies.Identifiers.Boost]: parseMorphoAaveV2LeverageManagement,
|
|
364
387
|
},
|
|
388
|
+
[ProtocolIdentifiers.StrategiesAutomation.Exchange]: {
|
|
389
|
+
[Strategies.Identifiers.Dca]: parseExchangeDca,
|
|
390
|
+
[Strategies.Identifiers.LimitOrder]: parseExchangeLimitOrder,
|
|
391
|
+
},
|
|
365
392
|
};
|
|
366
393
|
|
|
367
394
|
function getParsingMethod(id: ProtocolIdentifiers.StrategiesAutomation, strategy: BundleOrStrategy) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Dec from 'decimal.js';
|
|
2
|
-
import { getAssetInfo } from '@defisaver/tokens';
|
|
2
|
+
import { getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
Bundles, ChainId, RatioState, Strategies,
|
|
@@ -229,3 +229,34 @@ export const morphoAaveV2Encode = {
|
|
|
229
229
|
return subDataService.morphoAaveV2LeverageManagementSubData.encode(minRatio, maxRatio, maxOptimalRatio, minOptimalRatio, boostEnabled);
|
|
230
230
|
},
|
|
231
231
|
};
|
|
232
|
+
|
|
233
|
+
export const exchangeEncode = {
|
|
234
|
+
dca(
|
|
235
|
+
fromToken: EthereumAddress,
|
|
236
|
+
toToken: EthereumAddress,
|
|
237
|
+
amount: string,
|
|
238
|
+
timestamp: number,
|
|
239
|
+
interval: number,
|
|
240
|
+
) {
|
|
241
|
+
requireAddresses([fromToken, toToken]);
|
|
242
|
+
const subData = subDataService.exchangeDcaSubData.encode(fromToken, toToken, amount, interval);
|
|
243
|
+
const triggerData = triggerService.exchangeTimestampTrigger.encode(timestamp, interval);
|
|
244
|
+
const strategyId = Strategies.MainnetIds.EXCHANGE_DCA;
|
|
245
|
+
|
|
246
|
+
return [strategyId, false, triggerData, subData];
|
|
247
|
+
},
|
|
248
|
+
limitOrder(
|
|
249
|
+
fromToken: EthereumAddress,
|
|
250
|
+
toToken: EthereumAddress,
|
|
251
|
+
amount: string,
|
|
252
|
+
targetPrice: string,
|
|
253
|
+
goodUntil: number,
|
|
254
|
+
) {
|
|
255
|
+
const strategyId = Strategies.MainnetIds.EXCHANGE_LIMIT_ORDER;
|
|
256
|
+
const subData = subDataService.exchangeLimitOrderSubData.encode(fromToken, toToken, amount);
|
|
257
|
+
const fromTokenDecimals = getAssetInfoByAddress(fromToken).decimals;
|
|
258
|
+
const triggerData = triggerService.exchangeOffchainPriceTrigger.encode(targetPrice, goodUntil, fromTokenDecimals);
|
|
259
|
+
|
|
260
|
+
return [strategyId, false, triggerData, subData];
|
|
261
|
+
},
|
|
262
|
+
};
|
|
@@ -203,17 +203,16 @@ export const morphoAaveV2LeverageManagementSubData = {
|
|
|
203
203
|
minOptimalRatio: number,
|
|
204
204
|
boostEnabled: boolean,
|
|
205
205
|
): SubData {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
];
|
|
206
|
+
const encodedMinRatio = mockedWeb3.eth.abi.encodeParameter('uint128', ratioPercentageToWei(minRatio));
|
|
207
|
+
const encodedMaxRatio = mockedWeb3.eth.abi.encodeParameter('uint128', ratioPercentageToWei(maxRatio));
|
|
208
|
+
const encodedMaxOptimalRatio = mockedWeb3.eth.abi.encodeParameter('uint128', ratioPercentageToWei(maxOptimalRatio));
|
|
209
|
+
const encodedMinOptimalRatio = mockedWeb3.eth.abi.encodeParameter('uint128', ratioPercentageToWei(minOptimalRatio));
|
|
210
|
+
const encodedBoostEnabled = mockedWeb3.eth.abi.encodeParameter('bool', boostEnabled);
|
|
211
|
+
|
|
212
|
+
return [encodedMinRatio, encodedMaxRatio, encodedMaxOptimalRatio, encodedMinOptimalRatio, encodedBoostEnabled];
|
|
214
213
|
},
|
|
215
214
|
decode(subData: SubData): { targetRatio: number } {
|
|
216
|
-
const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint128', subData[
|
|
215
|
+
const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint128', subData[0]) as any as string;
|
|
217
216
|
const targetRatio = weiToRatioPercentage(ratioWei);
|
|
218
217
|
|
|
219
218
|
return { targetRatio };
|
|
@@ -252,3 +251,42 @@ export const liquityPaybackUsingChickenBondSubData = {
|
|
|
252
251
|
return { sourceId, sourceType };
|
|
253
252
|
},
|
|
254
253
|
};
|
|
254
|
+
|
|
255
|
+
export const exchangeDcaSubData = {
|
|
256
|
+
encode: (fromToken: EthereumAddress, toToken: EthereumAddress, amount: string, interval: number) : SubData => {
|
|
257
|
+
const sellTokenEncoded = mockedWeb3.eth.abi.encodeParameter('address', fromToken);
|
|
258
|
+
const buyTokenEncoded = mockedWeb3.eth.abi.encodeParameter('address', toToken);
|
|
259
|
+
const amountEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', amount);
|
|
260
|
+
const intervalEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', interval);
|
|
261
|
+
|
|
262
|
+
return [sellTokenEncoded, buyTokenEncoded, amountEncoded, intervalEncoded];
|
|
263
|
+
},
|
|
264
|
+
decode: (subData: SubData) => {
|
|
265
|
+
const fromToken = mockedWeb3.eth.abi.decodeParameter('address', subData[0]).toString();
|
|
266
|
+
const toToken = mockedWeb3.eth.abi.decodeParameter('address', subData[1]).toString();
|
|
267
|
+
const amount = mockedWeb3.eth.abi.decodeParameter('uint256', subData[2]).toString();
|
|
268
|
+
const interval = mockedWeb3.eth.abi.decodeParameter('uint256', subData[3]).toString();
|
|
269
|
+
return {
|
|
270
|
+
fromToken,
|
|
271
|
+
toToken,
|
|
272
|
+
amount,
|
|
273
|
+
interval,
|
|
274
|
+
};
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
export const exchangeLimitOrderSubData = {
|
|
279
|
+
encode: (fromToken: EthereumAddress, toToken: EthereumAddress, amount: string) : SubData => {
|
|
280
|
+
const fromTokenEncoded = mockedWeb3.eth.abi.encodeParameter('address', fromToken);
|
|
281
|
+
const toTokenEncoded = mockedWeb3.eth.abi.encodeParameter('address', toToken);
|
|
282
|
+
const amountEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', amount);
|
|
283
|
+
|
|
284
|
+
return [fromTokenEncoded, toTokenEncoded, amountEncoded];
|
|
285
|
+
},
|
|
286
|
+
decode: (subData: SubData) => {
|
|
287
|
+
const fromToken = mockedWeb3.eth.abi.decodeParameter('address', subData[0]).toString();
|
|
288
|
+
const toToken = mockedWeb3.eth.abi.decodeParameter('address', subData[1]).toString();
|
|
289
|
+
const amount = mockedWeb3.eth.abi.decodeParameter('uint256', subData[2]).toString();
|
|
290
|
+
return { fromToken, toToken, amount };
|
|
291
|
+
},
|
|
292
|
+
};
|