@dhedge/v2-sdk 1.11.1 → 2.0.1

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 (38) hide show
  1. package/dist/entities/pool.d.ts +91 -91
  2. package/dist/services/flatmoney/stableLp.d.ts +4 -4
  3. package/dist/services/odos/index.d.ts +5 -1
  4. package/dist/services/pendle/index.d.ts +4 -1
  5. package/dist/services/toros/completeWithdrawal.d.ts +7 -0
  6. package/dist/services/toros/easySwapper.d.ts +2 -2
  7. package/dist/services/toros/initWithdrawal.d.ts +3 -0
  8. package/dist/services/toros/retry.d.ts +5 -0
  9. package/dist/services/toros/swapData.d.ts +11 -0
  10. package/dist/types.d.ts +5 -0
  11. package/dist/utils/contract.d.ts +3 -2
  12. package/dist/v2-sdk.cjs.development.js +5716 -2693
  13. package/dist/v2-sdk.cjs.development.js.map +1 -1
  14. package/dist/v2-sdk.cjs.production.min.js +1 -1
  15. package/dist/v2-sdk.cjs.production.min.js.map +1 -1
  16. package/dist/v2-sdk.esm.js +5716 -2693
  17. package/dist/v2-sdk.esm.js.map +1 -1
  18. package/package.json +1 -1
  19. package/src/abi/IAaveLendingPoolAssetGuard.json +645 -0
  20. package/src/abi/IEasySwapperV2.json +1507 -0
  21. package/src/abi/pendle/PT.json +15 -0
  22. package/src/abi/pendle/SY.json +1 -0
  23. package/src/entities/pool.ts +240 -149
  24. package/src/services/flatmoney/stableLp.ts +27 -21
  25. package/src/services/odos/index.ts +6 -3
  26. package/src/services/pendle/index.ts +43 -8
  27. package/src/services/toros/completeWithdrawal.ts +209 -0
  28. package/src/services/toros/easySwapper.ts +16 -84
  29. package/src/services/toros/initWithdrawal.ts +166 -0
  30. package/src/services/toros/retry.ts +28 -0
  31. package/src/services/toros/swapData.ts +70 -0
  32. package/src/test/constants.ts +1 -1
  33. package/src/test/odos.test.ts +8 -7
  34. package/src/test/oneInch.test.ts +20 -22
  35. package/src/test/pendle.test.ts +63 -37
  36. package/src/test/toros.test.ts +10 -8
  37. package/src/types.ts +8 -0
  38. package/src/utils/contract.ts +70 -16
@@ -1,11 +1,14 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
 
3
3
  import BigNumber from "bignumber.js";
4
- import { Pool, ethers } from "../..";
4
+ import { Pool, SDKOptions, ethers } from "../..";
5
5
  import DelayedOrderAbi from "../../abi/flatmoney/DelayedOrder.json";
6
6
  import IOrderExecutionModuleAbi from "../../abi/flatmoney/v2/IOrderExecutionModule.json";
7
7
  import { flatMoneyContractAddresses } from "../../config";
8
- import { getPoolTxOrGasEstimate } from "../../utils/contract";
8
+ import {
9
+ getPoolTxOrGasEstimate,
10
+ isSdkOptionsBoolean
11
+ } from "../../utils/contract";
9
12
  import { getStableDepositQuote, getStableWithdrawQuote } from "./stableModule";
10
13
  import { getKeeperFee } from "./keeperFee";
11
14
 
@@ -55,7 +58,9 @@ export async function mintUnitViaFlatMoney(
55
58
  slippage: number, // 0.5 means 0.5%
56
59
  maxKeeperFeeInUsd: number | null,
57
60
  options: any = null,
58
- estimateGas = false
61
+ sdkOptions: SDKOptions = {
62
+ estimateGas: false
63
+ }
59
64
  ): Promise<any> {
60
65
  const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
61
66
  if (!flatMoneyContracts) {
@@ -85,7 +90,7 @@ export async function mintUnitViaFlatMoney(
85
90
  const tx = await getPoolTxOrGasEstimate(
86
91
  pool,
87
92
  [flatMoneyContracts.DelayedOrder, mintUnitTxData, options],
88
- estimateGas
93
+ sdkOptions
89
94
  );
90
95
  return tx;
91
96
  }
@@ -96,7 +101,9 @@ export async function redeemUnitViaFlatMoney(
96
101
  slippage: number, // 0.5 means 0.5%
97
102
  maxKeeperFeeInUsd: number | null,
98
103
  options: any = null,
99
- estimateGas = false
104
+ sdkOptions: SDKOptions = {
105
+ estimateGas: false
106
+ }
100
107
  ): Promise<any> {
101
108
  const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
102
109
  if (!flatMoneyContracts) {
@@ -118,7 +125,7 @@ export async function redeemUnitViaFlatMoney(
118
125
  const tx = await getPoolTxOrGasEstimate(
119
126
  pool,
120
127
  [flatMoneyContracts.DelayedOrder, redeemUnitTxData, options],
121
- estimateGas
128
+ sdkOptions
122
129
  );
123
130
  return tx;
124
131
  }
@@ -126,7 +133,9 @@ export async function redeemUnitViaFlatMoney(
126
133
  export async function cancelOrderViaFlatMoney(
127
134
  pool: Pool,
128
135
  options: any = null,
129
- estimateGas = false
136
+ sdkOptions: SDKOptions = {
137
+ estimateGas: false
138
+ }
130
139
  ): Promise<any> {
131
140
  const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
132
141
  if (!flatMoneyContracts) {
@@ -140,18 +149,15 @@ export async function cancelOrderViaFlatMoney(
140
149
  toAddress = flatMoneyContracts.OrderExecution;
141
150
  cancelOrderTxData = await getCancelExistingOrderTxDataForV2(pool.address);
142
151
  }
143
- // use trader address to cancel order
144
- if (estimateGas) {
145
- return pool.signer.estimateGas({
146
- to: toAddress,
147
- data: cancelOrderTxData
148
- });
149
- } else {
150
- const tx = await pool.signer.sendTransaction({
151
- to: toAddress,
152
- data: cancelOrderTxData,
153
- ...options
154
- });
155
- return tx;
156
- }
152
+ const tx = await getPoolTxOrGasEstimate(
153
+ pool,
154
+ [toAddress, cancelOrderTxData, options],
155
+ {
156
+ ...(isSdkOptionsBoolean(sdkOptions)
157
+ ? { estimateGas: sdkOptions }
158
+ : sdkOptions),
159
+ useTraderAddressAsFrom: true
160
+ }
161
+ );
162
+ return tx;
157
163
  }
@@ -4,7 +4,7 @@ import { ApiError, ethers } from "../..";
4
4
  import { networkChainIdMap } from "../../config";
5
5
  import { Pool } from "../../entities";
6
6
 
7
- const odosBaseUrl = "https://api.odos.xyz/sor";
7
+ export const odosBaseUrl = "https://api.odos.xyz/sor";
8
8
 
9
9
  export async function getOdosSwapTxData(
10
10
  pool: Pool,
@@ -12,7 +12,7 @@ export async function getOdosSwapTxData(
12
12
  assetTo: string,
13
13
  amountIn: ethers.BigNumber | string,
14
14
  slippage: number
15
- ): Promise<string> {
15
+ ): Promise<{ swapTxData: string; minAmountOut: string }> {
16
16
  let referralCode = 0; // Defaults to 0 for unregistered activity.
17
17
  if (
18
18
  process.env.ODOS_REFERAL_CODE &&
@@ -53,7 +53,10 @@ export async function getOdosSwapTxData(
53
53
  `${odosBaseUrl}/assemble`,
54
54
  assembleParams
55
55
  );
56
- return assembleResult.data.transaction.data;
56
+ return {
57
+ swapTxData: assembleResult.data.transaction.data,
58
+ minAmountOut: assembleResult.data.outputTokens[0].amount
59
+ };
57
60
  } catch (e) {
58
61
  console.error("Error in Odos API request:", e);
59
62
  throw new ApiError("Swap api request of Odos failed");
@@ -4,6 +4,9 @@ import { ApiError, ethers } from "../..";
4
4
  import { networkChainIdMap } from "../../config";
5
5
  import { Pool } from "../../entities";
6
6
  import ActionMiscV3Abi from "../../abi/pendle/ActionMiscV3.json";
7
+ import PTAbi from "../../abi/pendle/PT.json";
8
+ import SYAbi from "../../abi/pendle/SY.json";
9
+ import BigNumber from "bignumber.js";
7
10
 
8
11
  const pendleBaseUrl = "https://api-v2.pendle.finance/core/v1";
9
12
 
@@ -13,17 +16,27 @@ export async function getPendleSwapTxData(
13
16
  tokenOut: string,
14
17
  amountIn: ethers.BigNumber | string,
15
18
  slippage: number
16
- ): Promise<string> {
19
+ ): Promise<{ swapTxData: string; minAmountOut: string | null }> {
17
20
  const expiredMarket = await checkExitPostExpPT(pool, tokenIn, tokenOut);
18
21
  if (expiredMarket) {
19
- return getExitExpPTTxData(pool, tokenOut, amountIn, expiredMarket);
22
+ const result = await getExitExpPTTxData(
23
+ pool,
24
+ tokenIn,
25
+ tokenOut,
26
+ amountIn,
27
+ expiredMarket
28
+ );
29
+ return {
30
+ swapTxData: result.txData,
31
+ minAmountOut: result.minAmountOut
32
+ };
20
33
  }
21
34
  const params = {
22
35
  receiver: pool.address,
23
36
  tokenIn,
24
37
  tokenOut,
25
38
  amountIn: amountIn.toString(),
26
- slippage
39
+ slippage: slippage / 100
27
40
  };
28
41
  const market = await getMarket(pool, tokenIn, tokenOut);
29
42
  try {
@@ -33,8 +46,10 @@ export async function getPendleSwapTxData(
33
46
  }/markets/${market}/swap`,
34
47
  { params }
35
48
  );
36
-
37
- return swapResult.data.tx.data;
49
+ return {
50
+ swapTxData: swapResult.data.tx.data,
51
+ minAmountOut: swapResult.data.data.amountOut
52
+ };
38
53
  } catch (e) {
39
54
  console.error("Error in Pendle API request:", e);
40
55
  throw new ApiError("Pendle api request failed");
@@ -111,12 +126,13 @@ const checkExitPostExpPT = async (
111
126
  }
112
127
  };
113
128
 
114
- const getExitExpPTTxData = (
129
+ const getExitExpPTTxData = async (
115
130
  pool: Pool,
131
+ tokenIn: string,
116
132
  tokenOut: string,
117
133
  amountIn: ethers.BigNumber | string,
118
134
  market: string
119
- ) => {
135
+ ): Promise<{ txData: string; minAmountOut: string | null }> => {
120
136
  const actionMiscV3 = new ethers.utils.Interface(ActionMiscV3Abi);
121
137
  const txData = actionMiscV3.encodeFunctionData("exitPostExpToToken", [
122
138
  pool.address, // receiver
@@ -137,5 +153,24 @@ const getExitExpPTTxData = (
137
153
  ]
138
154
  ]
139
155
  ]);
140
- return txData;
156
+
157
+ // Get the PT contract instance
158
+ const PTcontract = new ethers.Contract(tokenIn, PTAbi, pool.signer);
159
+ // Get the SY contract instance
160
+ const SYcontract = new ethers.Contract(
161
+ await PTcontract.SY(),
162
+ SYAbi,
163
+ pool.signer
164
+ );
165
+
166
+ const exchangeRate = await SYcontract.exchangeRate();
167
+ const minAmountOut = new BigNumber(amountIn.toString())
168
+ .times(1e18)
169
+ .div(exchangeRate.toString())
170
+ .decimalPlaces(0, BigNumber.ROUND_DOWN)
171
+ .toFixed(0);
172
+ return {
173
+ txData,
174
+ minAmountOut
175
+ };
141
176
  };
@@ -0,0 +1,209 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { Dapp, ethers, Pool } from "../..";
3
+ import { networkChainIdMap, routerAddress } from "../../config";
4
+ import IEasySwapperV2 from "../../abi/IEasySwapperV2.json";
5
+ import BigNumber from "bignumber.js";
6
+ import AssetHandlerAbi from "../../abi/AssetHandler.json";
7
+ import IERC20Abi from "../../abi/IERC20.json";
8
+ import {
9
+ LOW_USD_VALUE_FOR_WITHDRAWAL,
10
+ SLIPPAGE_FOR_LOW_VALUE_SWAP
11
+ } from "./easySwapper";
12
+ import { retry } from "./retry";
13
+ import { getSwapDataViaOdos, SWAPPER_ADDERSS } from "./swapData";
14
+
15
+ export interface TrackedAsset {
16
+ token: string;
17
+ balance: ethers.BigNumber;
18
+ }
19
+
20
+ const getSwapWithdrawData = async (
21
+ pool: Pool,
22
+ trackedAssets: TrackedAsset[],
23
+ receiveToken: string,
24
+ slippage: number,
25
+ swapDestMinDestAmount: BigNumber
26
+ ) => {
27
+ const srcData = [];
28
+ const routerKey = ethers.utils.formatBytes32String("ODOS_V2");
29
+ // const destData
30
+ for (const { token, balance } of trackedAssets) {
31
+ if (token.toLowerCase() === receiveToken.toLowerCase()) {
32
+ continue;
33
+ }
34
+ const swapData = await retry({
35
+ fn: () => {
36
+ return getSwapDataViaOdos({
37
+ srcAsset: token,
38
+ srcAmount: balance.toString(),
39
+ dstAsset: receiveToken,
40
+ chainId: networkChainIdMap[pool.network],
41
+ from: SWAPPER_ADDERSS,
42
+ receiver: SWAPPER_ADDERSS,
43
+ slippage
44
+ });
45
+ },
46
+ delayMs: 1500,
47
+ maxRetries: 7
48
+ });
49
+ srcData.push({
50
+ token,
51
+ amount: balance,
52
+ aggregatorData: { routerKey, swapData }
53
+ });
54
+ }
55
+ return {
56
+ srcData,
57
+ destData: {
58
+ destToken: receiveToken,
59
+ minDestAmount: swapDestMinDestAmount.toString()
60
+ }
61
+ };
62
+ };
63
+ export const createCompleteWithdrawalTxArguments = async (
64
+ pool: Pool,
65
+ receiveToken: string,
66
+ slippage: number
67
+ ): Promise<any> => {
68
+ const easySwapper = new ethers.Contract(
69
+ routerAddress[pool.network][Dapp.TOROS] as string,
70
+ IEasySwapperV2,
71
+ pool.signer
72
+ );
73
+ const trackedAssets: TrackedAsset[] = await easySwapper.getTrackedAssets(
74
+ pool.address
75
+ );
76
+
77
+ if (
78
+ trackedAssets.length === 0 ||
79
+ trackedAssets.every(
80
+ ({ token }) => token.toLowerCase() === receiveToken.toLowerCase()
81
+ )
82
+ ) {
83
+ // just do simple complete withdraw
84
+ return {
85
+ isSwapNeeded: false,
86
+ swapData: null,
87
+ estimatedMinReceiveAmount: null
88
+ };
89
+ }
90
+
91
+ const swapTrackedAssets = trackedAssets.filter(
92
+ ({ token }) => token.toLowerCase() !== receiveToken.toLowerCase()
93
+ );
94
+
95
+ const assetHandlerAddress = await pool.factory.callStatic.getAssetHandler();
96
+ const assetHandler = new ethers.Contract(
97
+ assetHandlerAddress,
98
+ AssetHandlerAbi.abi,
99
+ pool.signer
100
+ );
101
+ const receiveTokenPriceD18 = new BigNumber(
102
+ (await assetHandler.getUSDPrice(receiveToken)).toString()
103
+ );
104
+ const receiveTokenErc20 = await new ethers.Contract(
105
+ receiveToken,
106
+ IERC20Abi.abi,
107
+ pool.signer
108
+ );
109
+ const receiveTokenDecimals = await receiveTokenErc20.decimals();
110
+ // swap dest minDestAmount
111
+ const tAssetInfos = await Promise.all(
112
+ swapTrackedAssets.map(async swapTAsset => {
113
+ const swapTAssetPriceD18 = new BigNumber(
114
+ (await assetHandler.getUSDPrice(swapTAsset.token)).toString()
115
+ );
116
+ const swapTAssetTokenErc20 = await new ethers.Contract(
117
+ swapTAsset.token,
118
+ IERC20Abi.abi,
119
+ pool.signer
120
+ );
121
+ const swapTAssetDecimals = await swapTAssetTokenErc20.decimals();
122
+ const tokenBalanceBN = new BigNumber(swapTAsset.balance.toString());
123
+ const estimatedValueToSwapD0 = tokenBalanceBN
124
+ .times(swapTAssetPriceD18)
125
+ .div(10 ** 18)
126
+ .div(10 ** Number(swapTAssetDecimals.toString()));
127
+
128
+ // --- caution: if the estimated value to swap is less than the low USD value for withdrawal, use a higher slippage
129
+ const adjustedSlippage = estimatedValueToSwapD0.lte(
130
+ LOW_USD_VALUE_FOR_WITHDRAWAL
131
+ )
132
+ ? SLIPPAGE_FOR_LOW_VALUE_SWAP
133
+ : slippage;
134
+ // -----
135
+
136
+ const estimatedMinReceiveAmount = tokenBalanceBN
137
+ .times(swapTAssetPriceD18)
138
+ .div(receiveTokenPriceD18)
139
+ .div(10 ** Number(swapTAssetDecimals.toString()))
140
+ .times(10 ** Number(receiveTokenDecimals.toString()))
141
+ .times(1 - adjustedSlippage / 10000) // slippage is in basis points, so divide by 10000
142
+ .decimalPlaces(0, BigNumber.ROUND_DOWN);
143
+
144
+ return {
145
+ token: swapTAsset.token,
146
+ balance: swapTAsset.balance,
147
+ estimatedMinReceiveAmount
148
+ };
149
+ })
150
+ );
151
+ const swapDestMinDestAmount = tAssetInfos.reduce(
152
+ (acc, { estimatedMinReceiveAmount }) => acc.plus(estimatedMinReceiveAmount),
153
+ new BigNumber(0)
154
+ );
155
+
156
+ const withdrawalVaultAddress = await easySwapper.withdrawalContracts(
157
+ pool.address
158
+ );
159
+ const balanceOfReceiveToken = await receiveTokenErc20.balanceOf(
160
+ withdrawalVaultAddress
161
+ );
162
+
163
+ // complete withdraw _expectedDestTokenAmount
164
+ const estimatedMinReceiveAmount = swapDestMinDestAmount.plus(
165
+ balanceOfReceiveToken.toString()
166
+ );
167
+
168
+ const swapData = await getSwapWithdrawData(
169
+ pool,
170
+ swapTrackedAssets,
171
+ receiveToken,
172
+ slippage,
173
+ estimatedMinReceiveAmount
174
+ );
175
+
176
+ return {
177
+ isSwapNeeded: true,
178
+ swapData,
179
+ estimatedMinReceiveAmount: estimatedMinReceiveAmount.toFixed(0)
180
+ };
181
+ };
182
+
183
+ export const getCompleteWithdrawalTxData = async (
184
+ pool: Pool,
185
+ receiveToken: string,
186
+ slippage: number,
187
+ useOnChainSwap: boolean
188
+ ): Promise<string> => {
189
+ const completeWithdrawTxArguments = await createCompleteWithdrawalTxArguments(
190
+ pool,
191
+ receiveToken,
192
+ slippage
193
+ );
194
+
195
+ const isSwapNeeded = completeWithdrawTxArguments.isSwapNeeded;
196
+ const isOffchainSwap = !useOnChainSwap && isSwapNeeded;
197
+ const iEasySwapperV2 = new ethers.utils.Interface(IEasySwapperV2);
198
+ if (isOffchainSwap) {
199
+ return iEasySwapperV2.encodeFunctionData(
200
+ "completeWithdrawal(((address,uint256,(bytes32,bytes))[],(address,uint256)),uint256)",
201
+ [
202
+ completeWithdrawTxArguments.swapData,
203
+ completeWithdrawTxArguments.estimatedMinReceiveAmount
204
+ ]
205
+ );
206
+ } else {
207
+ return iEasySwapperV2.encodeFunctionData("completeWithdrawal()");
208
+ }
209
+ };
@@ -1,12 +1,15 @@
1
1
  import { ethers } from "ethers";
2
2
  import { Dapp, Pool } from "../..";
3
3
 
4
- import IDhedgeEasySwapper from "../../abi/IDhedgeEasySwapper.json";
4
+ import IEasySwapperV2 from "../../abi/IEasySwapperV2.json";
5
5
  import { routerAddress } from "../../config";
6
- import { getChainlinkPriceInUsd } from "../chainLink/price";
6
+
7
7
  import { isPool, loadPool } from "./pool";
8
- import { getOneInchSwapTxData } from "../oneInch";
9
- import { wait } from "../../test/utils/testingHelper";
8
+
9
+ import { getInitWithdrawalTxData } from "./initWithdrawal";
10
+
11
+ export const LOW_USD_VALUE_FOR_WITHDRAWAL = 1; // 1 USD minimum value for withdrawal
12
+ export const SLIPPAGE_FOR_LOW_VALUE_SWAP = 500;
10
13
 
11
14
  export async function getPoolDepositAsset(
12
15
  pool: Pool,
@@ -39,32 +42,13 @@ export async function getEasySwapperDepositQuote(
39
42
  ): Promise<ethers.BigNumber> {
40
43
  const easySwapper = new ethers.Contract(
41
44
  routerAddress[pool.network][Dapp.TOROS] as string,
42
- IDhedgeEasySwapper,
45
+ IEasySwapperV2,
43
46
  pool.signer
44
47
  );
45
48
 
46
49
  return await easySwapper.depositQuote(torosAsset, investAsset, amountIn);
47
50
  }
48
51
 
49
- export async function getEasySwapperWithdrawalQuote(
50
- pool: Pool,
51
- torosAsset: string,
52
- investAsset: string,
53
- amountIn: ethers.BigNumber
54
- ): Promise<ethers.BigNumber> {
55
- const [torosTokenPrice, assetPrice, assetDecimals] = await Promise.all([
56
- getTorosPoolTokenPrice(pool, torosAsset),
57
- getChainlinkPriceInUsd(pool, investAsset),
58
- pool.utils.getDecimals(investAsset)
59
- ]);
60
-
61
- return amountIn
62
- .mul(torosTokenPrice)
63
- .div(assetPrice)
64
- .div(1e10)
65
- .div(10 ** (18 - assetDecimals));
66
- }
67
-
68
52
  export async function getEasySwapperTxData(
69
53
  pool: Pool,
70
54
  assetFrom: string,
@@ -77,13 +61,15 @@ export async function getEasySwapperTxData(
77
61
  const [torosAsset, investAsset] = isWithdrawal
78
62
  ? [assetFrom, assetTo]
79
63
  : [assetTo, assetFrom];
80
- const iDhedgeEasySwapper = new ethers.utils.Interface(IDhedgeEasySwapper);
64
+ const iEasySwapperV2 = new ethers.utils.Interface(IEasySwapperV2);
81
65
  if (isWithdrawal) {
82
- return iDhedgeEasySwapper.encodeFunctionData("initWithdrawal", [
66
+ return getInitWithdrawalTxData(
67
+ pool,
83
68
  torosAsset,
84
- amountIn,
85
- slippage * 100
86
- ]);
69
+ amountIn.toString(),
70
+ slippage * 100,
71
+ false
72
+ );
87
73
  } else {
88
74
  const depositAsset = await getPoolDepositAsset(
89
75
  pool,
@@ -99,7 +85,7 @@ export async function getEasySwapperTxData(
99
85
  investAsset,
100
86
  amountIn
101
87
  );
102
- return iDhedgeEasySwapper.encodeFunctionData("depositWithCustomCooldown", [
88
+ return iEasySwapperV2.encodeFunctionData("depositWithCustomCooldown", [
103
89
  torosAsset,
104
90
  depositAsset,
105
91
  amountIn,
@@ -107,57 +93,3 @@ export async function getEasySwapperTxData(
107
93
  ]);
108
94
  }
109
95
  }
110
-
111
- export async function getCompleteWithdrawalTxData(
112
- pool: Pool,
113
- destToken: string,
114
- slippage: number
115
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
116
- ): Promise<string> {
117
- const easySwapper = new ethers.Contract(
118
- routerAddress[pool.network][Dapp.TOROS] as string,
119
- IDhedgeEasySwapper,
120
- pool.signer
121
- );
122
- const trackedAssets: {
123
- token: string;
124
- balance: ethers.BigNumber;
125
- }[] = await easySwapper.getTrackedAssets(pool.address);
126
- const trackedAssetsExcludingDestToken = trackedAssets.filter(
127
- ({ token }) => token.toLowerCase() !== destToken.toLowerCase()
128
- );
129
-
130
- const srcData = [];
131
- let minDestAmount = ethers.BigNumber.from(0);
132
- for (const { token, balance } of trackedAssetsExcludingDestToken) {
133
- const { swapTxData, dstAmount } = await getOneInchSwapTxData(
134
- pool,
135
- token,
136
- destToken,
137
- balance,
138
- slippage,
139
- true
140
- );
141
- srcData.push({
142
- token,
143
- amount: balance,
144
- aggregatorData: {
145
- routerKey: ethers.utils.formatBytes32String("ONE_INCH"),
146
- swapData: swapTxData
147
- }
148
- });
149
- minDestAmount = minDestAmount.add(dstAmount);
150
- await wait(2);
151
- }
152
-
153
- return easySwapper.interface.encodeFunctionData("completeWithdrawal", [
154
- {
155
- srcData,
156
- destData: {
157
- destToken,
158
- minDestAmount
159
- }
160
- },
161
- minDestAmount.mul(10000 - slippage * 100).div(10000)
162
- ]);
163
- }