@defisaver/automation-sdk 2.0.1 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/.eslintrc.js +1 -0
  2. package/esm/abis/index.js +27 -15
  3. package/esm/automation/private/Automation.js +9 -6
  4. package/esm/automation/private/LegacyAutomation.d.ts +5 -5
  5. package/esm/automation/private/LegacyAutomation.js +30 -23
  6. package/esm/automation/private/LegacyProtocol.js +4 -1
  7. package/esm/automation/private/Protocol.js +4 -1
  8. package/esm/automation/private/StrategiesAutomation.d.ts +2 -2
  9. package/esm/automation/private/StrategiesAutomation.js +27 -21
  10. package/esm/automation/public/ArbitrumStrategies.js +10 -4
  11. package/esm/automation/public/EthereumStrategies.js +10 -4
  12. package/esm/automation/public/OptimismStrategies.js +10 -4
  13. package/esm/automation/public/legacy/LegacyAaveAutomation.js +13 -7
  14. package/esm/automation/public/legacy/LegacyCompoundAutomation.js +13 -7
  15. package/esm/automation/public/legacy/LegacyMakerAutomation.js +13 -7
  16. package/esm/configuration.js +8 -5
  17. package/esm/constants/index.js +281 -265
  18. package/esm/index.js +57 -17
  19. package/esm/services/contractService.js +22 -14
  20. package/esm/services/ethereumService.js +18 -10
  21. package/esm/services/strategiesService.js +144 -100
  22. package/esm/services/strategySubService.d.ts +2 -0
  23. package/esm/services/strategySubService.js +100 -55
  24. package/esm/services/subDataService.d.ts +12 -0
  25. package/esm/services/subDataService.js +165 -127
  26. package/esm/services/triggerService.d.ts +8 -8
  27. package/esm/services/triggerService.js +125 -95
  28. package/esm/services/utils.js +82 -33
  29. package/esm/services/utils.test.d.ts +1 -0
  30. package/esm/services/utils.test.js +362 -0
  31. package/esm/types/contracts/generated/Erc20.js +2 -1
  32. package/esm/types/contracts/generated/Legacy_AaveV2Subscriptions.js +2 -1
  33. package/esm/types/contracts/generated/Legacy_AuthCheck.js +2 -1
  34. package/esm/types/contracts/generated/Legacy_CompoundV2Subscriptions.js +2 -1
  35. package/esm/types/contracts/generated/Legacy_MakerSubscriptions.js +2 -1
  36. package/esm/types/contracts/generated/SubStorage.js +2 -1
  37. package/esm/types/contracts/generated/UniMulticall.js +2 -1
  38. package/esm/types/contracts/generated/index.js +2 -1
  39. package/esm/types/contracts/generated/types.js +2 -1
  40. package/esm/types/enums.d.ts +9 -1
  41. package/esm/types/enums.js +24 -12
  42. package/esm/types/index.js +2 -1
  43. package/package.json +12 -8
  44. package/src/automation/private/LegacyAutomation.ts +11 -10
  45. package/src/automation/private/StrategiesAutomation.ts +5 -6
  46. package/src/configuration.ts +0 -3
  47. package/src/constants/index.ts +10 -0
  48. package/src/index.ts +0 -1
  49. package/src/services/ethereumService.ts +6 -6
  50. package/src/services/strategiesService.ts +24 -0
  51. package/src/services/strategySubService.ts +30 -0
  52. package/src/services/subDataService.ts +104 -67
  53. package/src/services/triggerService.ts +86 -85
  54. package/src/services/utils.test.ts +414 -0
  55. package/src/services/utils.ts +6 -7
  56. package/src/types/enums.ts +9 -0
  57. package/tsconfig.json +1 -1
  58. package/umd/index.js +7142 -4138
  59. package/src/types/typings/process.d.ts +0 -9
  60. package/yarn-error.log +0 -7233
@@ -1,6 +1,6 @@
1
1
  import type Web3 from 'web3';
2
2
  import type {
3
- EthereumAddress, Position, Interfaces, Contract, PlaceholderType,
3
+ EthereumAddress, Position, Interfaces, Contract, PlaceholderType, SubscriptionOptions,
4
4
  } from '../../types';
5
5
  import type {
6
6
  Legacy_AaveV2Subscriptions, Legacy_CompoundV2Subscriptions, Legacy_MakerSubscriptions, Legacy_AuthCheck,
@@ -85,8 +85,8 @@ export default class LegacyAutomation extends Automation {
85
85
  return this.protocol.id === ProtocolIdentifiers.LegacyAutomation.MakerDAO ? 'owner' : 'user';
86
86
  }
87
87
 
88
- protected async _getSubscriptions(addresses?: EthereumAddress[]): Promise<PlaceholderType> { // TODO PlaceholderType
89
- let subscriptions = await this.subscriptionsContract.contract.methods.getSubscribers().call();
88
+ protected async _getSubscriptions(addresses?: EthereumAddress[], options?: SubscriptionOptions): Promise<PlaceholderType> { // TODO PlaceholderType
89
+ let subscriptions = await this.subscriptionsContract.contract.methods.getSubscribers().call({}, options?.fromBlock || 'latest');
90
90
 
91
91
  if (addresses) {
92
92
  const _addresses = addresses.map(a => a.toLowerCase());
@@ -98,14 +98,15 @@ export default class LegacyAutomation extends Automation {
98
98
  return subscriptions;
99
99
  }
100
100
 
101
- protected async getParsedSubscriptions(addresses?: EthereumAddress[]): Promise<Position.LegacyAutomated[]> {
102
- const subscriptions = await this._getSubscriptions(addresses);
101
+ protected async getParsedSubscriptions(addresses?: EthereumAddress[], options?: SubscriptionOptions): Promise<Position.LegacyAutomated[]> {
102
+ const subscriptions = await this._getSubscriptions(addresses, options);
103
103
 
104
104
  // @ts-ignore
105
105
  return subscriptions.map((sub) => ({
106
106
  chainId: this.chainId,
107
107
  owner: sub[this.getOwnerPropName()],
108
- isEnabled: true,
108
+ isEnabled: (options?.fromBlock && options?.fromBlock !== 'latest')
109
+ ? options?.fromBlock > 18213086 : false, // Legacy automation was disabled on block 18213086
109
110
  protocol: this.protocol,
110
111
  specific: { ...sub },
111
112
  strategy: {
@@ -115,11 +116,11 @@ export default class LegacyAutomation extends Automation {
115
116
  }));
116
117
  }
117
118
 
118
- public async getSubscriptions(): Promise<Position.LegacyAutomated[]> {
119
- return this.getParsedSubscriptions();
119
+ public async getSubscriptions(options?: SubscriptionOptions): Promise<Position.LegacyAutomated[]> {
120
+ return this.getParsedSubscriptions(undefined, options);
120
121
  }
121
122
 
122
- public async getSubscriptionsFor(addresses: EthereumAddress[]): Promise<Position.LegacyAutomated[]> {
123
- return this.getParsedSubscriptions(addresses);
123
+ public async getSubscriptionsFor(addresses: EthereumAddress[], options?: SubscriptionOptions): Promise<Position.LegacyAutomated[]> {
124
+ return this.getParsedSubscriptions(addresses, options);
124
125
  }
125
126
  }
@@ -2,11 +2,10 @@ import Dec from 'decimal.js';
2
2
  import type Web3 from 'web3';
3
3
  import type { PastEventOptions } from 'web3-eth-contract';
4
4
  import type {
5
- Position, Interfaces, EthereumAddress,
6
- SubscriptionOptions, Contract, ParseData, PlaceholderType,
5
+ Position, Interfaces, EthereumAddress, SubscriptionOptions, Contract, ParseData, PlaceholderType, BlockNumber,
7
6
  } from '../../types';
8
7
  import type {
9
- Subscribe, StrategyModel, SubStorage, UpdateData,
8
+ StrategyModel, SubStorage,
10
9
  } from '../../types/contracts/generated/SubStorage';
11
10
  import type { ChainId } from '../../types/enums';
12
11
 
@@ -49,7 +48,7 @@ export default class StrategiesAutomation extends Automation {
49
48
  return getEventsFromContract<SubStorage>(this.subStorageContract, this.subStorageContractFork, event, options);
50
49
  }
51
50
 
52
- protected async getStrategiesSubs(subIds: number[]): Promise<StrategyModel.StoredSubDataStructOutputStruct[]> {
51
+ protected async getStrategiesSubs(subIds: number[], fromBlock: BlockNumber = 'latest'): Promise<StrategyModel.StoredSubDataStructOutputStruct[]> {
53
52
  let options : any;
54
53
  let web3: Web3;
55
54
 
@@ -68,7 +67,7 @@ export default class StrategiesAutomation extends Automation {
68
67
  }
69
68
 
70
69
  const multicallCalls = subIds.map((subId) => ({ ...options, params: [subId] }));
71
- return multicall(web3, this.chainId, multicallCalls);
70
+ return multicall(web3, this.chainId, multicallCalls, fromBlock);
72
71
  }
73
72
 
74
73
  protected async getSubscriptionEventsFromSubStorage(options?: PastEventOptions) {
@@ -98,7 +97,7 @@ export default class StrategiesAutomation extends Automation {
98
97
 
99
98
  if (subscriptionEvents) {
100
99
  // @ts-ignore
101
- const strategiesSubs = await this.getStrategiesSubs(subscriptionEvents.map((e) => e.returnValues.subId));
100
+ const strategiesSubs = await this.getStrategiesSubs(subscriptionEvents.map((e) => e.returnValues.subId), _options.fromBlock);
102
101
 
103
102
  subscriptions = await Promise.all(strategiesSubs.map(async (sub, index: number) => {
104
103
  let latestUpdate = subscriptionEvents[index].returnValues;
@@ -1,8 +1,5 @@
1
- import Web3 from 'web3';
2
1
  import Dec from 'decimal.js';
3
2
 
4
- process.mockedWeb3 = new Web3('');
5
-
6
3
  Dec.set({
7
4
  rounding: Dec.ROUND_DOWN,
8
5
  toExpPos: 9e15,
@@ -80,6 +80,16 @@ export const MAINNET_STRATEGIES_INFO: MainnetStrategiesInfo = {
80
80
  strategyId: Strategies.Identifiers.LimitOrder,
81
81
  protocol: PROTOCOLS.Exchange,
82
82
  },
83
+ [Strategies.MainnetIds.LIQUITY_DSR_PAYBACK]: {
84
+ strategyOrBundleId: Strategies.MainnetIds.LIQUITY_DSR_PAYBACK,
85
+ strategyId: Strategies.Identifiers.SavingsDsrPayback,
86
+ protocol: PROTOCOLS.Liquity,
87
+ },
88
+ [Strategies.MainnetIds.LIQUITY_DSR_SUPPLY]: {
89
+ strategyOrBundleId: Strategies.MainnetIds.LIQUITY_DSR_SUPPLY,
90
+ strategyId: Strategies.Identifiers.SavingsDsrSupply,
91
+ protocol: PROTOCOLS.Liquity,
92
+ },
83
93
  };
84
94
 
85
95
  export const OPTIMISM_STRATEGIES_INFO = {
package/src/index.ts CHANGED
@@ -2,7 +2,6 @@
2
2
  // [] Check @ts-ignores and PlaceholderType
3
3
  // [] Improve typing for subData, trigger and strategySub services
4
4
  // [] Make possible to use any provider not only web3 (This requires changes throughout the package)
5
- // [] Write unit tests
6
5
 
7
6
  import './configuration';
8
7
 
@@ -1,3 +1,5 @@
1
+ import AbiCoder from 'web3-eth-abi';
2
+
1
3
  import type Web3 from 'web3';
2
4
  import type { PastEventOptions } from 'web3-eth-contract';
3
5
  import type {
@@ -9,8 +11,6 @@ import { addToObjectIf, isDefined } from './utils';
9
11
  import type { BaseContract } from '../types/contracts/generated/types';
10
12
  import type { ChainId } from '../types/enums';
11
13
 
12
- const { mockedWeb3 } = process;
13
-
14
14
  export async function multicall(
15
15
  web3: Web3,
16
16
  chainId: ChainId,
@@ -20,7 +20,7 @@ export async function multicall(
20
20
  const multicallContract = makeUniMulticallContract(web3, chainId).contract;
21
21
 
22
22
  const formattedCalls: Multicall.FormattedCalls[] = calls.map((call) => ({
23
- callData: mockedWeb3.eth.abi.encodeFunctionCall(call.abiItem, call.params),
23
+ callData: AbiCoder.encodeFunctionCall(call.abiItem, call.params),
24
24
  target: call.target || '0x0',
25
25
  gasLimit: call.gasLimit || 1e6,
26
26
  }));
@@ -33,12 +33,12 @@ export async function multicall(
33
33
 
34
34
  callResult.returnData.forEach(([success, gasUsed, result], i) => {
35
35
  const formattedRes = (result !== '0x'
36
- ? mockedWeb3.eth.abi.decodeParameters(calls[i].abiItem.outputs!, result)
37
- : undefined) as Multicall.Payload;
36
+ ? AbiCoder.decodeParameters(calls[i].abiItem.outputs!, result)
37
+ : undefined);
38
38
  formattedResult = [...formattedResult, formattedRes];
39
39
  });
40
40
 
41
- return formattedResult;
41
+ return formattedResult as Multicall.Payload;
42
42
  }
43
43
 
44
44
  export async function getEventsFromContract<T extends BaseContract>(
@@ -530,6 +530,28 @@ function parseSparkCloseOnPrice(position: Position.Automated, parseData: ParseDa
530
530
  return _position;
531
531
  }
532
532
 
533
+ function parseLiquitySavingsLiqProtection(position: Position.Automated, parseData: ParseData): Position.Automated {
534
+ const _position = cloneDeep(position);
535
+
536
+ const { subStruct } = parseData.subscriptionEventData;
537
+
538
+ const triggerData = triggerService.makerRatioTrigger.decode(subStruct.triggerData);
539
+ const subData = subDataService.makerRepayFromSavingsSubData.decode(subStruct.subData);
540
+
541
+ _position.strategyData.decoded.triggerData = triggerData;
542
+ _position.strategyData.decoded.subData = subData;
543
+
544
+ _position.specific = {
545
+ triggerRepayRatio: triggerData.ratio,
546
+ targetRepayRatio: subData.targetRatio,
547
+ repayEnabled: true,
548
+ boostEnabled: false,
549
+ };
550
+
551
+ return _position;
552
+ }
553
+
554
+
533
555
  const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
534
556
  [ProtocolIdentifiers.StrategiesAutomation.MakerDAO]: {
535
557
  [Strategies.Identifiers.SavingsLiqProtection]: parseMakerSavingsLiqProtection,
@@ -546,6 +568,8 @@ const parsingMethodsMapping: StrategiesToProtocolVersionMapping = {
546
568
  [Strategies.Identifiers.BondProtection]: parseLiquityBondProtection,
547
569
  [Strategies.Identifiers.Repay]: parseLiquityLeverageManagement,
548
570
  [Strategies.Identifiers.Boost]: parseLiquityLeverageManagement,
571
+ [Strategies.Identifiers.SavingsDsrPayback]: parseLiquitySavingsLiqProtection,
572
+ [Strategies.Identifiers.SavingsDsrSupply]: parseLiquitySavingsLiqProtection,
549
573
  },
550
574
  [ProtocolIdentifiers.StrategiesAutomation.AaveV2]: {
551
575
  [Strategies.Identifiers.Repay]: parseAaveV2LeverageManagement,
@@ -164,6 +164,36 @@ export const liquityEncode = {
164
164
  boostEnabled,
165
165
  ];
166
166
  },
167
+ dsrPayback(
168
+ proxyAddress: EthereumAddress,
169
+ triggerRatio: number,
170
+ targetRatio: number,
171
+ ) {
172
+ requireAddress(proxyAddress);
173
+ const subData = subDataService.liquityDsrPaybackSubData.encode(targetRatio);
174
+ const triggerData = triggerService.liquityRatioTrigger.encode(proxyAddress, triggerRatio, RatioState.UNDER);
175
+
176
+ const strategyOrBundleId = Strategies.MainnetIds.LIQUITY_DSR_PAYBACK;
177
+
178
+ const isBundle = false;
179
+
180
+ return [strategyOrBundleId, isBundle, triggerData, subData];
181
+ },
182
+ dsrSupply(
183
+ proxyAddress: EthereumAddress,
184
+ triggerRatio: number,
185
+ targetRatio: number,
186
+ ) {
187
+ requireAddress(proxyAddress);
188
+ const subData = subDataService.liquityDsrSupplySubData.encode(targetRatio);
189
+ const triggerData = triggerService.liquityRatioTrigger.encode(proxyAddress, triggerRatio, RatioState.UNDER);
190
+
191
+ const strategyOrBundleId = Strategies.MainnetIds.LIQUITY_DSR_SUPPLY;
192
+
193
+ const isBundle = false;
194
+
195
+ return [strategyOrBundleId, isBundle, triggerData, subData];
196
+ },
167
197
  };
168
198
 
169
199
  export const chickenBondsEncode = {
@@ -1,16 +1,15 @@
1
1
  import Dec from 'decimal.js';
2
+ import AbiCoder from 'web3-eth-abi';
2
3
  import { assetAmountInEth, getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
3
4
  import { otherAddresses } from '@defisaver/sdk';
4
5
 
5
6
  import type { EthereumAddress, SubData } from '../types';
6
- import { ChainId } from '../types/enums';
7
+ import { ChainId, RatioState } from '../types/enums';
7
8
 
8
9
  import { ZERO_ADDRESS } from '../constants';
9
10
 
10
11
  import { compareAddresses, ratioPercentageToWei, weiToRatioPercentage } from './utils';
11
12
 
12
- const { mockedWeb3 } = process;
13
-
14
13
  export const makerRepayFromSavingsSubData = {
15
14
  encode(
16
15
  vaultId: number,
@@ -23,22 +22,22 @@ export const makerRepayFromSavingsSubData = {
23
22
  // @ts-ignore // TODO - this requires change in @defisaver/tokens
24
23
  const _mcdCdpManagerAddr = mcdCdpManagerAddr || otherAddresses(chainId).McdCdpManager;
25
24
 
26
- const vaultIdEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', vaultId.toString());
25
+ const vaultIdEncoded = AbiCoder.encodeParameter('uint256', vaultId.toString());
27
26
  const targetRatioWei = ratioPercentageToWei(targetRatioPercentage);
28
- const targetRatioEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', targetRatioWei);
29
- const daiAddrEncoded = mockedWeb3.eth.abi.encodeParameter('address', _daiAddr);
30
- const mcdManagerAddrEncoded = mockedWeb3.eth.abi.encodeParameter('address', _mcdCdpManagerAddr);
27
+ const targetRatioEncoded = AbiCoder.encodeParameter('uint256', targetRatioWei);
28
+ const daiAddrEncoded = AbiCoder.encodeParameter('address', _daiAddr);
29
+ const mcdManagerAddrEncoded = AbiCoder.encodeParameter('address', _mcdCdpManagerAddr);
31
30
 
32
31
  return [vaultIdEncoded, targetRatioEncoded, daiAddrEncoded, mcdManagerAddrEncoded];
33
32
  },
34
33
  decode(subData: SubData): { vaultId: number, daiAddr: string, mcdManagerAddr: string, targetRatio: number } {
35
- const vaultId = +mockedWeb3.eth.abi.decodeParameter('uint256', subData[0]).toString();
34
+ const vaultId = +AbiCoder.decodeParameter('uint256', subData[0])!.toString();
36
35
 
37
- const weiRatio = mockedWeb3.eth.abi.decodeParameter('uint256', subData[1]) as any as string;
36
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
38
37
  const targetRatio = weiToRatioPercentage(weiRatio);
39
38
 
40
- const daiAddr = mockedWeb3.eth.abi.decodeParameter('address', subData[2]).toString();
41
- const mcdManagerAddr = mockedWeb3.eth.abi.decodeParameter('address', subData[3]).toString();
39
+ const daiAddr = AbiCoder.decodeParameter('address', subData[2])!.toString();
40
+ const mcdManagerAddr = AbiCoder.decodeParameter('address', subData[3])!.toString();
42
41
 
43
42
  return {
44
43
  vaultId, targetRatio, daiAddr, mcdManagerAddr,
@@ -58,23 +57,23 @@ export const makerCloseSubData = {
58
57
  // @ts-ignore // TODO - this requires change in @defisaver/tokens
59
58
  const _mcdCdpManagerAddr = mcdCdpManagerAddr || otherAddresses(chainId).McdCdpManager;
60
59
 
61
- const vaultIdEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', vaultId.toString());
62
- const daiAddrEncoded = mockedWeb3.eth.abi.encodeParameter('address', _daiAddr);
63
- const mcdManagerAddrEncoded = mockedWeb3.eth.abi.encodeParameter('address', _mcdCdpManagerAddr);
60
+ const vaultIdEncoded = AbiCoder.encodeParameter('uint256', vaultId.toString());
61
+ const daiAddrEncoded = AbiCoder.encodeParameter('address', _daiAddr);
62
+ const mcdManagerAddrEncoded = AbiCoder.encodeParameter('address', _mcdCdpManagerAddr);
64
63
 
65
64
  if (compareAddresses(closeToAssetAddr, _daiAddr)) {
66
65
  // Close to DAI strategy
67
66
  return [vaultIdEncoded, daiAddrEncoded, mcdManagerAddrEncoded];
68
67
  }
69
68
  // Close to collateral strategy
70
- const collAddrEncoded = mockedWeb3.eth.abi.encodeParameter('address', closeToAssetAddr);
69
+ const collAddrEncoded = AbiCoder.encodeParameter('address', closeToAssetAddr);
71
70
  return [vaultIdEncoded, collAddrEncoded, daiAddrEncoded, mcdManagerAddrEncoded];
72
71
  },
73
72
  decode(subData: SubData): { vaultId: number, closeToAssetAddr: EthereumAddress } {
74
- const vaultId = +mockedWeb3.eth.abi.decodeParameter('uint256', subData[0]);
73
+ const vaultId = +AbiCoder.decodeParameter('uint256', subData[0])!;
75
74
  // if closing to collateral, asset addr will be 2nd param out of 4
76
75
  // if closing to DAI, will return 2nd param out of 3, which will be DAI addr
77
- const closeToAssetAddr = mockedWeb3.eth.abi.decodeParameter('address', subData[1]).toString().toLowerCase();
76
+ const closeToAssetAddr = AbiCoder.decodeParameter('address', subData[1])!.toString().toLowerCase();
78
77
 
79
78
  return {
80
79
  vaultId, closeToAssetAddr,
@@ -92,15 +91,15 @@ export const makerLeverageManagementSubData = {
92
91
  // boostEnabled,
93
92
  // ],
94
93
  decode: (subData:SubData) => {
95
- const vaultId = +mockedWeb3.eth.abi.decodeParameter('uint256', subData[0]).toString();
96
- const weiRatio = mockedWeb3.eth.abi.decodeParameter('uint256', subData[1]) as any as string;
94
+ const vaultId = +AbiCoder.decodeParameter('uint256', subData[0])!.toString();
95
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
97
96
  const targetRatio = weiToRatioPercentage(weiRatio);
98
97
  return { vaultId, targetRatio };
99
98
  },
100
99
  };
101
100
  export const liquityLeverageManagementSubData = {
102
101
  decode: (subData:SubData) => {
103
- const weiRatio = mockedWeb3.eth.abi.decodeParameter('uint256', subData[1]) as any as string;
102
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
104
103
  const targetRatio = weiToRatioPercentage(weiRatio);
105
104
  return { targetRatio };
106
105
  },
@@ -115,8 +114,8 @@ export const liquityCloseSubData = {
115
114
  const _collAddr = collAddr || getAssetInfo('WETH', chainId).address;
116
115
  const _debtAddr = debtAddr || getAssetInfo('LUSD', chainId).address;
117
116
 
118
- const collAddrEncoded = mockedWeb3.eth.abi.encodeParameter('address', _collAddr);
119
- const debtAddrEncoded = mockedWeb3.eth.abi.encodeParameter('address', _debtAddr);
117
+ const collAddrEncoded = AbiCoder.encodeParameter('address', _collAddr);
118
+ const debtAddrEncoded = AbiCoder.encodeParameter('address', _debtAddr);
120
119
  // if (compareAddresses(closeToAssetAddr, daiAddr)) { // TODO - Uhm, wth?
121
120
  // // close to LUSD strategy
122
121
  // return [daiAddrEncoded, mcdManagerAddrEncoded];
@@ -125,8 +124,8 @@ export const liquityCloseSubData = {
125
124
  return [collAddrEncoded, debtAddrEncoded];
126
125
  },
127
126
  decode(subData: SubData): { closeToAssetAddr: EthereumAddress, debtAddr: string } {
128
- const closeToAssetAddr = mockedWeb3.eth.abi.decodeParameter('address', subData[0]).toString().toLowerCase();
129
- const debtAddr = mockedWeb3.eth.abi.decodeParameter('address', subData[1]).toString().toLowerCase();
127
+ const closeToAssetAddr = AbiCoder.decodeParameter('address', subData[0])!.toString().toLowerCase();
128
+ const debtAddr = AbiCoder.decodeParameter('address', subData[1])!.toString().toLowerCase();
130
129
 
131
130
  return { closeToAssetAddr, debtAddr };
132
131
  },
@@ -150,7 +149,7 @@ export const aaveV2LeverageManagementSubData = {
150
149
  ];
151
150
  },
152
151
  decode(subData: SubData): { targetRatio: number } {
153
- const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint256', subData[1]) as any as string;
152
+ const ratioWei = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
154
153
  const targetRatio = weiToRatioPercentage(ratioWei);
155
154
 
156
155
  return { targetRatio };
@@ -159,7 +158,7 @@ export const aaveV2LeverageManagementSubData = {
159
158
 
160
159
  export const aaveV3LeverageManagementSubData = { // TODO encode?
161
160
  decode(subData: SubData): { targetRatio: number } {
162
- const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint256', subData[0]) as any as string;
161
+ const ratioWei = AbiCoder.decodeParameter('uint256', subData[0]) as any as string;
163
162
  const targetRatio = weiToRatioPercentage(ratioWei);
164
163
 
165
164
  return { targetRatio };
@@ -174,22 +173,22 @@ export const aaveV3QuotePriceSubData = {
174
173
  debtAssetId: number,
175
174
  nullAddress: EthereumAddress = ZERO_ADDRESS,
176
175
  ): SubData {
177
- const encodedColl = mockedWeb3.eth.abi.encodeParameter('address', collAsset);
178
- const encodedCollId = mockedWeb3.eth.abi.encodeParameter('uint8', collAssetId);
176
+ const encodedColl = AbiCoder.encodeParameter('address', collAsset);
177
+ const encodedCollId = AbiCoder.encodeParameter('uint8', collAssetId);
179
178
 
180
- const encodedDebt = mockedWeb3.eth.abi.encodeParameter('address', debtAsset);
181
- const encodedDebtId = mockedWeb3.eth.abi.encodeParameter('uint8', debtAssetId);
179
+ const encodedDebt = AbiCoder.encodeParameter('address', debtAsset);
180
+ const encodedDebtId = AbiCoder.encodeParameter('uint8', debtAssetId);
182
181
 
183
- const encodedNullAddress = mockedWeb3.eth.abi.encodeParameter('address', nullAddress);
182
+ const encodedNullAddress = AbiCoder.encodeParameter('address', nullAddress);
184
183
 
185
184
  return [encodedColl, encodedCollId, encodedDebt, encodedDebtId, encodedNullAddress];
186
185
  },
187
186
  decode(subData: SubData): { collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number } {
188
- const collAsset = mockedWeb3.eth.abi.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
189
- const collAssetId = Number(mockedWeb3.eth.abi.decodeParameter('uint8', subData[1]));
187
+ const collAsset = AbiCoder.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
188
+ const collAssetId = Number(AbiCoder.decodeParameter('uint8', subData[1]));
190
189
 
191
- const debtAsset = mockedWeb3.eth.abi.decodeParameter('address', subData[2]) as unknown as EthereumAddress;
192
- const debtAssetId = Number(mockedWeb3.eth.abi.decodeParameter('uint8', subData[3]));
190
+ const debtAsset = AbiCoder.decodeParameter('address', subData[2]) as unknown as EthereumAddress;
191
+ const debtAssetId = Number(AbiCoder.decodeParameter('uint8', subData[3]));
193
192
 
194
193
  return {
195
194
  collAsset, collAssetId, debtAsset, debtAssetId,
@@ -215,7 +214,7 @@ export const compoundV2LeverageManagementSubData = {
215
214
  ];
216
215
  },
217
216
  decode(subData: SubData): { targetRatio: number } {
218
- const weiRatio = mockedWeb3.eth.abi.decodeParameter('uint256', subData[0]) as any as string;
217
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[0]) as any as string;
219
218
  const targetRatio = weiToRatioPercentage(weiRatio);
220
219
 
221
220
  return { targetRatio };
@@ -245,7 +244,7 @@ export const compoundV3LeverageManagementSubData = {
245
244
  ];
246
245
  },
247
246
  decode(subData: SubData): { targetRatio: number } {
248
- const weiRatio = mockedWeb3.eth.abi.decodeParameter('uint256', subData[3]) as any as string;
247
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[3]) as any as string;
249
248
  const targetRatio = weiToRatioPercentage(weiRatio);
250
249
 
251
250
  return { targetRatio };
@@ -270,7 +269,7 @@ export const morphoAaveV2LeverageManagementSubData = {
270
269
  ];
271
270
  },
272
271
  decode(subData: SubData): { targetRatio: number } {
273
- const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint128', subData[1]) as any as string;
272
+ const ratioWei = AbiCoder.decodeParameter('uint128', subData[1]) as any as string;
274
273
  const targetRatio = weiToRatioPercentage(ratioWei);
275
274
 
276
275
  return { targetRatio };
@@ -279,11 +278,11 @@ export const morphoAaveV2LeverageManagementSubData = {
279
278
 
280
279
  export const cBondsRebondSubData = {
281
280
  encode(bondId: number | string): SubData {
282
- const bondIdEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', bondId);
281
+ const bondIdEncoded = AbiCoder.encodeParameter('uint256', bondId);
283
282
  return [bondIdEncoded];
284
283
  },
285
284
  decode(subData: SubData): { bondId: string } {
286
- const bondId = mockedWeb3.eth.abi.decodeParameter('uint256', subData[1]).toString();
285
+ const bondId = AbiCoder.decodeParameter('uint256', subData[1])!.toString();
287
286
  return { bondId };
288
287
  },
289
288
  };
@@ -295,16 +294,16 @@ export const liquityPaybackUsingChickenBondSubData = {
295
294
  * @param chainId
296
295
  */
297
296
  encode: (sourceId: string, sourceType: number, chainId: ChainId = ChainId.Ethereum): SubData => {
298
- const sourceIdEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', sourceId);
299
- const sourceTypeEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', sourceType);
300
- const lusdAddressEncoded = mockedWeb3.eth.abi.encodeParameter('address', getAssetInfo('LUSD', chainId).address);
301
- const bLusdAddressEncoded = mockedWeb3.eth.abi.encodeParameter('address', getAssetInfo('bLUSD', chainId).address);
297
+ const sourceIdEncoded = AbiCoder.encodeParameter('uint256', sourceId);
298
+ const sourceTypeEncoded = AbiCoder.encodeParameter('uint256', sourceType);
299
+ const lusdAddressEncoded = AbiCoder.encodeParameter('address', getAssetInfo('LUSD', chainId).address);
300
+ const bLusdAddressEncoded = AbiCoder.encodeParameter('address', getAssetInfo('bLUSD', chainId).address);
302
301
 
303
302
  return [sourceIdEncoded, sourceTypeEncoded, lusdAddressEncoded, bLusdAddressEncoded];
304
303
  },
305
304
  decode: (subData: SubData) => {
306
- const sourceId = mockedWeb3.eth.abi.decodeParameter('uint256', subData[0]).toString();
307
- const sourceType = mockedWeb3.eth.abi.decodeParameter('uint256', subData[1]).toString();
305
+ const sourceId = AbiCoder.decodeParameter('uint256', subData[0])!.toString();
306
+ const sourceType = AbiCoder.decodeParameter('uint256', subData[1])!.toString();
308
307
 
309
308
  return { sourceId, sourceType };
310
309
  },
@@ -312,18 +311,18 @@ export const liquityPaybackUsingChickenBondSubData = {
312
311
 
313
312
  export const exchangeDcaSubData = {
314
313
  encode: (fromToken: EthereumAddress, toToken: EthereumAddress, amount: string, interval: number) : SubData => {
315
- const sellTokenEncoded = mockedWeb3.eth.abi.encodeParameter('address', fromToken);
316
- const buyTokenEncoded = mockedWeb3.eth.abi.encodeParameter('address', toToken);
317
- const amountEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', amount);
318
- const intervalEncoded = mockedWeb3.eth.abi.encodeParameter('uint256', interval);
314
+ const sellTokenEncoded = AbiCoder.encodeParameter('address', fromToken);
315
+ const buyTokenEncoded = AbiCoder.encodeParameter('address', toToken);
316
+ const amountEncoded = AbiCoder.encodeParameter('uint256', amount);
317
+ const intervalEncoded = AbiCoder.encodeParameter('uint256', interval);
319
318
 
320
319
  return [sellTokenEncoded, buyTokenEncoded, amountEncoded, intervalEncoded];
321
320
  },
322
321
  decode: (subData: SubData, chainId: ChainId) => {
323
- const fromToken = mockedWeb3.eth.abi.decodeParameter('address', subData[0]).toString();
324
- const toToken = mockedWeb3.eth.abi.decodeParameter('address', subData[1]).toString();
325
- const amount = assetAmountInEth(mockedWeb3.eth.abi.decodeParameter('uint256', subData[2]).toString(), getAssetInfoByAddress(fromToken, chainId).symbol);
326
- const interval = mockedWeb3.eth.abi.decodeParameter('uint256', subData[3]).toString();
322
+ const fromToken = AbiCoder.decodeParameter('address', subData[0])!.toString();
323
+ const toToken = AbiCoder.decodeParameter('address', subData[1])!.toString();
324
+ const amount = assetAmountInEth(AbiCoder.decodeParameter('uint256', subData[2])!.toString(), getAssetInfoByAddress(fromToken, chainId).symbol);
325
+ const interval = AbiCoder.decodeParameter('uint256', subData[3])!.toString();
327
326
  return {
328
327
  fromToken,
329
328
  toToken,
@@ -345,16 +344,16 @@ export const exchangeLimitOrderSubData = {
345
344
  ];
346
345
  },
347
346
  decode: (subData: SubData, chainId: ChainId) => {
348
- const fromToken = mockedWeb3.eth.abi.decodeParameter('address', subData[0]).toString();
349
- const toToken = mockedWeb3.eth.abi.decodeParameter('address', subData[1]).toString();
350
- const amount = assetAmountInEth(mockedWeb3.eth.abi.decodeParameter('uint256', subData[2]).toString(), getAssetInfoByAddress(fromToken, chainId).symbol);
347
+ const fromToken = AbiCoder.decodeParameter('address', subData[0])!.toString();
348
+ const toToken = AbiCoder.decodeParameter('address', subData[1])!.toString();
349
+ const amount = assetAmountInEth(AbiCoder.decodeParameter('uint256', subData[2])!.toString(), getAssetInfoByAddress(fromToken, chainId).symbol);
351
350
  return { fromToken, toToken, amount };
352
351
  },
353
352
  };
354
353
 
355
354
  export const sparkLeverageManagementSubData = { // TODO encode?
356
355
  decode(subData: SubData): { targetRatio: number } {
357
- const ratioWei = mockedWeb3.eth.abi.decodeParameter('uint256', subData[0]) as any as string;
356
+ const ratioWei = AbiCoder.decodeParameter('uint256', subData[0]) as any as string;
358
357
  const targetRatio = weiToRatioPercentage(ratioWei);
359
358
 
360
359
  return { targetRatio };
@@ -369,25 +368,63 @@ export const sparkQuotePriceSubData = {
369
368
  debtAssetId: number,
370
369
  nullAddress: EthereumAddress = ZERO_ADDRESS,
371
370
  ): SubData {
372
- const encodedColl = mockedWeb3.eth.abi.encodeParameter('address', collAsset);
373
- const encodedCollId = mockedWeb3.eth.abi.encodeParameter('uint8', collAssetId);
371
+ const encodedColl = AbiCoder.encodeParameter('address', collAsset);
372
+ const encodedCollId = AbiCoder.encodeParameter('uint8', collAssetId);
374
373
 
375
- const encodedDebt = mockedWeb3.eth.abi.encodeParameter('address', debtAsset);
376
- const encodedDebtId = mockedWeb3.eth.abi.encodeParameter('uint8', debtAssetId);
374
+ const encodedDebt = AbiCoder.encodeParameter('address', debtAsset);
375
+ const encodedDebtId = AbiCoder.encodeParameter('uint8', debtAssetId);
377
376
 
378
- const encodedNullAddress = mockedWeb3.eth.abi.encodeParameter('address', nullAddress);
377
+ const encodedNullAddress = AbiCoder.encodeParameter('address', nullAddress);
379
378
 
380
379
  return [encodedColl, encodedCollId, encodedDebt, encodedDebtId, encodedNullAddress];
381
380
  },
382
381
  decode(subData: SubData): { collAsset: EthereumAddress, collAssetId: number, debtAsset: EthereumAddress, debtAssetId: number } {
383
- const collAsset = mockedWeb3.eth.abi.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
384
- const collAssetId = Number(mockedWeb3.eth.abi.decodeParameter('uint8', subData[1]));
382
+ const collAsset = AbiCoder.decodeParameter('address', subData[0]) as unknown as EthereumAddress;
383
+ const collAssetId = Number(AbiCoder.decodeParameter('uint8', subData[1]));
385
384
 
386
- const debtAsset = mockedWeb3.eth.abi.decodeParameter('address', subData[2]) as unknown as EthereumAddress;
387
- const debtAssetId = Number(mockedWeb3.eth.abi.decodeParameter('uint8', subData[3]));
385
+ const debtAsset = AbiCoder.decodeParameter('address', subData[2]) as unknown as EthereumAddress;
386
+ const debtAssetId = Number(AbiCoder.decodeParameter('uint8', subData[3]));
388
387
 
389
388
  return {
390
389
  collAsset, collAssetId, debtAsset, debtAssetId,
391
390
  };
392
391
  },
393
392
  };
393
+
394
+ export const liquityDsrPaybackSubData = {
395
+ encode: (targetRatio: number) => {
396
+ const daiAddress = getAssetInfo('DAI').address;
397
+ const lusdAddress = getAssetInfo('LUSD').address;
398
+
399
+ const ratioStateEncoded = AbiCoder.encodeParameter('uint8', RatioState.UNDER);
400
+ const targetRatioEncoded = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
401
+ const daiAddressEncoded = AbiCoder.encodeParameter('address', daiAddress);
402
+ const lusdAddressEncoded = AbiCoder.encodeParameter('address', lusdAddress);
403
+
404
+ return [ratioStateEncoded, targetRatioEncoded, daiAddressEncoded, lusdAddressEncoded];
405
+ },
406
+ decode: (subData: SubData) => {
407
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
408
+ const targetRatio = weiToRatioPercentage(weiRatio);
409
+ return { targetRatio };
410
+ },
411
+ };
412
+
413
+ export const liquityDsrSupplySubData = {
414
+ encode: (targetRatio: number) => {
415
+ const daiAddress = getAssetInfo('DAI').address;
416
+ const wethAddress = getAssetInfo('WETH').address;
417
+
418
+ const ratioStateEncoded = AbiCoder.encodeParameter('uint8', RatioState.UNDER);
419
+ const targetRatioEncoded = AbiCoder.encodeParameter('uint256', ratioPercentageToWei(targetRatio));
420
+ const daiAddressEncoded = AbiCoder.encodeParameter('address', daiAddress);
421
+ const wethAddressEncoded = AbiCoder.encodeParameter('address', wethAddress);
422
+
423
+ return [ratioStateEncoded, targetRatioEncoded, daiAddressEncoded, wethAddressEncoded];
424
+ },
425
+ decode: (subData: SubData) => {
426
+ const weiRatio = AbiCoder.decodeParameter('uint256', subData[1]) as any as string;
427
+ const targetRatio = weiToRatioPercentage(weiRatio);
428
+ return { targetRatio };
429
+ },
430
+ };