@dhedge/v2-sdk 1.9.9 → 1.10.0

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.
@@ -3,13 +3,14 @@
3
3
  import { Contract, ethers, Wallet, BigNumber } from "ethers";
4
4
 
5
5
  import IERC20 from "../abi/IERC20.json";
6
+
7
+ import IERC721 from "../abi/IERC721.json";
6
8
  import IMiniChefV2 from "../abi/IMiniChefV2.json";
7
9
  import ILendingPool from "../abi/ILendingPool.json";
8
10
  import ISynthetix from "../abi/ISynthetix.json";
9
11
  import IUniswapV2Router from "../abi/IUniswapV2Router.json";
10
12
  import INonfungiblePositionManager from "../abi/INonfungiblePositionManager.json";
11
13
  import IAaveIncentivesController from "../abi/IAaveIncentivesController.json";
12
- import IArrakisV1RouterStaking from "../abi/IArrakisV1RouterStaking.json";
13
14
  import ILiquidityGaugeV4 from "../abi/ILiquidityGaugeV4.json";
14
15
  import IBalancerRewardsGauge from "../abi/IBalancerRewardsGauge.json";
15
16
 
@@ -34,19 +35,23 @@ import {
34
35
 
35
36
  import { Utils } from "./utils";
36
37
  import {
37
- getUniswapV3Liquidity,
38
- getUniswapV3MintParams
38
+ getDecreaseLiquidityTxData,
39
+ getIncreaseLiquidityTxData,
40
+ getUniswapV3MintTxData
39
41
  } from "../services/uniswap/V3Liquidity";
40
- import { FeeAmount } from "@uniswap/v3-sdk";
41
42
  import { getUniswapV3SwapTxData } from "../services/uniswap/V3Trade";
42
43
  import { getEasySwapperTxData } from "../services/toros/easySwapper";
43
44
  import { getAaveV3ClaimTxData } from "../services/aave/incentives";
44
45
  import {
45
46
  getVelodromeAddLiquidityTxData,
47
+ getVelodromeCLDecreaseStakedLiquidityTxData,
48
+ getVelodromeCLIncreaseStakedLiquidityTxData,
49
+ getVelodromeClOwner,
46
50
  getVelodromeRemoveLiquidityTxData
47
51
  } from "../services/velodrome/liquidity";
48
52
  import {
49
53
  getVelodromeClaimTxData,
54
+ getVelodromeCLClaimTxData,
50
55
  getVelodromeStakeTxData
51
56
  } from "../services/velodrome/staking";
52
57
  import { getLyraOptionTxData } from "../services/lyra/trade";
@@ -261,7 +266,7 @@ export class Pool {
261
266
  ): Promise<any> {
262
267
  const iERC20 = new ethers.utils.Interface(IERC20.abi);
263
268
  const approveTxData = iERC20.encodeFunctionData("approve", [
264
- nonfungiblePositionManagerAddress[this.network],
269
+ nonfungiblePositionManagerAddress[this.network][Dapp.UNISWAPV3],
265
270
  amount
266
271
  ]);
267
272
  const tx = await getPoolTxOrGasEstimate(
@@ -301,6 +306,35 @@ export class Pool {
301
306
  return tx;
302
307
  }
303
308
 
309
+ /**
310
+ * Approve NFT for provided spender address
311
+ * @param {string} spender Spender address
312
+ * @param {string} asset Address of asset
313
+ * @param {string} tokenId NFT id
314
+ * @param {any} options Transaction options
315
+ * @param {boolean} estimateGas Simulate/estimate gas
316
+ * @returns {Promise<any>} Transaction
317
+ */
318
+ async approveSpenderNFT(
319
+ spender: string,
320
+ asset: string,
321
+ tokenId: string,
322
+ options: any = null,
323
+ estimateGas = false
324
+ ): Promise<any> {
325
+ const iERC721 = new ethers.utils.Interface(IERC721.abi);
326
+ const approveTxData = iERC721.encodeFunctionData("approve", [
327
+ spender,
328
+ tokenId
329
+ ]);
330
+ const tx = await getPoolTxOrGasEstimate(
331
+ this,
332
+ [asset, approveTxData, options],
333
+ estimateGas
334
+ );
335
+ return tx;
336
+ }
337
+
304
338
  /**
305
339
  * Trade an asset into another asset
306
340
  * @param {Dapp} dapp Platform like Sushiswap or Uniswap
@@ -509,7 +543,7 @@ export class Pool {
509
543
  * Stake liquidity pool tokens in gauge contract
510
544
  * @param {Dapp} dapp Platform like Balancer or Velodrome
511
545
  * @param {string} gauge Gauge contract address
512
- * @param {BigNumber | string} amount Amount of liquidity pool tokens
546
+ * @param {BigNumber | string} amount Amount of liquidity pool tokens or token ID for Velodrome CL
513
547
  * @param {any} options Transaction options
514
548
  * @param {boolean} estimateGas Simulate/estimate gas
515
549
  * @returns {Promise<any>} Transaction
@@ -537,6 +571,7 @@ export class Pool {
537
571
  break;
538
572
  case Dapp.VELODROMEV2:
539
573
  case Dapp.AERODROME:
574
+ case Dapp.VELODROMECL:
540
575
  stakeTxData = getVelodromeStakeTxData(amount, true);
541
576
  break;
542
577
  default:
@@ -584,7 +619,7 @@ export class Pool {
584
619
  /**
585
620
  * Unstake liquidity pool tokens from Velodrome or Balancer gauge
586
621
  * @param {string} gauge Gauge contract address
587
- * @param {BigNumber | string} amount Amount of liquidity pool tokens
622
+ * @param {BigNumber | string} amount Amount of liquidity pool tokens or CL token ID
588
623
  * @param {any} options Transaction options
589
624
  * @param {boolean} estimateGas Simulate/estimate gas
590
625
  * @returns {Promise<any>} Transaction
@@ -946,6 +981,7 @@ export class Pool {
946
981
 
947
982
  /**
948
983
  * Create UniswapV3 liquidity pool
984
+ * @param {dapp} Platform either UniswapV3 or VelodromeCL
949
985
  * @param {string} assetA First asset
950
986
  * @param {string} assetB Second asset
951
987
  * @param {BigNumber | string} amountA Amount first asset
@@ -954,12 +990,13 @@ export class Pool {
954
990
  * @param { number } maxPrice Upper price range (assetB per assetA)
955
991
  * @param { number } minTick Lower tick range
956
992
  * @param { number } maxTick Upper tick range
957
- * @param { FeeAmount } feeAmount Fee tier (Low 0.05%, Medium 0.3%, High 1%)
993
+ * @param { number } feeAmountOrTickSpacing Fee tier UniswapV3 or tick spacing VelodromeCL
958
994
  * @param {any} options Transaction options
959
995
  * @param {boolean} estimateGas Simulate/estimate gas
960
996
  * @returns {Promise<any>} Transaction
961
997
  */
962
998
  async addLiquidityUniswapV3(
999
+ dapp: Dapp.UNISWAPV3 | Dapp.VELODROMECL,
963
1000
  assetA: string,
964
1001
  assetB: string,
965
1002
  amountA: BigNumber | string,
@@ -968,7 +1005,7 @@ export class Pool {
968
1005
  maxPrice: number | null,
969
1006
  minTick: number | null,
970
1007
  maxTick: number | null,
971
- feeAmount: FeeAmount,
1008
+ feeAmountOrTickSpacing: number,
972
1009
  options: any = null,
973
1010
  estimateGas = false
974
1011
  ): Promise<any> {
@@ -977,12 +1014,11 @@ export class Pool {
977
1014
  (minTick === null || maxTick === null)
978
1015
  )
979
1016
  throw new Error("Need to provide price or tick range");
1017
+ if ((minPrice || maxPrice) && dapp === Dapp.VELODROMECL)
1018
+ throw new Error("no price conversion for Velodrome CL");
980
1019
 
981
- const iNonfungiblePositionManager = new ethers.utils.Interface(
982
- INonfungiblePositionManager.abi
983
- );
984
-
985
- const mintTxParams = await getUniswapV3MintParams(
1020
+ const mintTxData = await getUniswapV3MintTxData(
1021
+ dapp,
986
1022
  this,
987
1023
  assetA,
988
1024
  assetB,
@@ -992,15 +1028,16 @@ export class Pool {
992
1028
  maxPrice,
993
1029
  minTick,
994
1030
  maxTick,
995
- feeAmount
996
- );
997
- const mintTxData = iNonfungiblePositionManager.encodeFunctionData(
998
- Transaction.MINT,
999
- [mintTxParams]
1031
+ feeAmountOrTickSpacing
1000
1032
  );
1033
+
1001
1034
  const tx = await getPoolTxOrGasEstimate(
1002
1035
  this,
1003
- [nonfungiblePositionManagerAddress[this.network], mintTxData, options],
1036
+ [
1037
+ nonfungiblePositionManagerAddress[this.network][dapp],
1038
+ mintTxData,
1039
+ options
1040
+ ],
1004
1041
  estimateGas
1005
1042
  );
1006
1043
  return tx;
@@ -1022,46 +1059,37 @@ export class Pool {
1022
1059
  options: any = null,
1023
1060
  estimateGas = false
1024
1061
  ): Promise<any> {
1025
- let txData;
1026
1062
  let dappAddress;
1027
- if (dapp === Dapp.UNISWAPV3) {
1028
- dappAddress = nonfungiblePositionManagerAddress[this.network];
1029
- const abi = new ethers.utils.Interface(INonfungiblePositionManager.abi);
1030
- const liquidity = (await getUniswapV3Liquidity(tokenId, this))
1031
- .mul(Math.round(amount * 1e4))
1032
- .div(1e6);
1033
- const decreaseLiquidityTxData = abi.encodeFunctionData(
1034
- Transaction.DECREASE_LIQUIDITY,
1035
- [[tokenId, liquidity, 0, 0, await getDeadline(this)]]
1036
- );
1037
- const collectTxData = abi.encodeFunctionData(Transaction.COLLECT, [
1038
- [tokenId, this.address, MaxUint128, MaxUint128]
1039
- ]);
1040
-
1041
- const multicallParams = [decreaseLiquidityTxData, collectTxData];
1042
-
1043
- if (amount === 100) {
1044
- const burnTxData = abi.encodeFunctionData(Transaction.BURN, [tokenId]);
1045
- multicallParams.push(burnTxData);
1046
- }
1047
- txData = abi.encodeFunctionData(Transaction.MULTI_CALL, [
1048
- multicallParams
1049
- ]);
1050
- } else if (dapp === Dapp.ARRAKIS) {
1051
- dappAddress = routerAddress[this.network][dapp];
1052
- const abi = new ethers.utils.Interface(IArrakisV1RouterStaking.abi);
1053
- const liquidity = (await this.utils.getBalance(tokenId, this.address))
1054
- .mul(Math.round(amount * 1e4))
1055
- .div(1e6);
1056
- txData = abi.encodeFunctionData(Transaction.REMOVE_LIQUIDITY_UNSTAKE, [
1057
- tokenId,
1058
- liquidity,
1059
- 0,
1060
- 0,
1061
- this.address
1062
- ]);
1063
+ let isStaked = false;
1064
+ let txData;
1065
+ switch (dapp) {
1066
+ case Dapp.UNISWAPV3:
1067
+ dappAddress = nonfungiblePositionManagerAddress[this.network][dapp];
1068
+ break;
1069
+ case Dapp.VELODROMECL:
1070
+ const tokenIdOwner = await getVelodromeClOwner(this, tokenId);
1071
+ if (tokenIdOwner.toLowerCase() === this.address.toLowerCase()) {
1072
+ dappAddress = nonfungiblePositionManagerAddress[this.network][dapp];
1073
+ } else {
1074
+ //staked in gauge
1075
+ dappAddress = tokenIdOwner;
1076
+ isStaked = true;
1077
+ }
1078
+ break;
1079
+ case Dapp.ARRAKIS:
1080
+ dappAddress = routerAddress[this.network][dapp];
1081
+ break;
1082
+ default:
1083
+ throw new Error("dapp not supported");
1084
+ }
1085
+ if (!isStaked) {
1086
+ txData = await getDecreaseLiquidityTxData(this, dapp, tokenId, amount);
1063
1087
  } else {
1064
- throw new Error("dapp not supported");
1088
+ txData = await getVelodromeCLDecreaseStakedLiquidityTxData(
1089
+ this,
1090
+ tokenId,
1091
+ amount
1092
+ );
1065
1093
  }
1066
1094
  const tx = await getPoolTxOrGasEstimate(
1067
1095
  this,
@@ -1072,7 +1100,7 @@ export class Pool {
1072
1100
  }
1073
1101
 
1074
1102
  /**
1075
- * Increase liquidity of an UniswapV3 or Arrakis liquidity pool
1103
+ * Increase liquidity of an UniswapV, VelodromeCL or Arrakis liquidity pool
1076
1104
  * @param {Dapp} dapp Platform either UniswapV3 or Arrakis
1077
1105
  * @param {string} tokenId Token Id of UniswapV3 position
1078
1106
  * @param {BigNumber | string} amountA Amount first asset
@@ -1089,28 +1117,44 @@ export class Pool {
1089
1117
  options: any = null,
1090
1118
  estimateGas = false
1091
1119
  ): Promise<any> {
1092
- let txData;
1093
1120
  let dappAddress;
1094
- if (dapp === Dapp.UNISWAPV3) {
1095
- dappAddress = nonfungiblePositionManagerAddress[this.network];
1096
- const abi = new ethers.utils.Interface(INonfungiblePositionManager.abi);
1097
- txData = abi.encodeFunctionData(Transaction.INCREASE_LIQUIDITY, [
1098
- [tokenId, amountA, amountB, 0, 0, await getDeadline(this)]
1099
- ]);
1100
- } else if (dapp === Dapp.ARRAKIS) {
1101
- dappAddress = routerAddress[this.network][dapp];
1102
- const abi = new ethers.utils.Interface(IArrakisV1RouterStaking.abi);
1103
- txData = abi.encodeFunctionData(Transaction.ADD_LIQUIDITY_STAKE, [
1121
+ let isStaked = false;
1122
+ let txData;
1123
+ switch (dapp) {
1124
+ case Dapp.UNISWAPV3:
1125
+ dappAddress = nonfungiblePositionManagerAddress[this.network][dapp];
1126
+ break;
1127
+ case Dapp.VELODROMECL:
1128
+ const tokenIdOwner = await getVelodromeClOwner(this, tokenId);
1129
+ if (tokenIdOwner.toLowerCase() === this.address.toLowerCase()) {
1130
+ dappAddress = nonfungiblePositionManagerAddress[this.network][dapp];
1131
+ } else {
1132
+ //staked in gauge
1133
+ dappAddress = tokenIdOwner;
1134
+ isStaked = true;
1135
+ }
1136
+ break;
1137
+ case Dapp.ARRAKIS:
1138
+ dappAddress = routerAddress[this.network][dapp];
1139
+ break;
1140
+ default:
1141
+ throw new Error("dapp not supported");
1142
+ }
1143
+ if (!isStaked) {
1144
+ txData = await getIncreaseLiquidityTxData(
1145
+ this,
1146
+ dapp,
1104
1147
  tokenId,
1105
1148
  amountA,
1106
- amountB,
1107
- 0,
1108
- 0,
1109
- 0,
1110
- this.address
1111
- ]);
1149
+ amountB
1150
+ );
1112
1151
  } else {
1113
- throw new Error("dapp not supported");
1152
+ txData = await getVelodromeCLIncreaseStakedLiquidityTxData(
1153
+ this,
1154
+ tokenId,
1155
+ amountA,
1156
+ amountB
1157
+ );
1114
1158
  }
1115
1159
  const tx = await getPoolTxOrGasEstimate(
1116
1160
  this,
@@ -1136,12 +1180,12 @@ export class Pool {
1136
1180
  ): Promise<any> {
1137
1181
  let txData;
1138
1182
  let contractAddress;
1183
+ const iNonfungiblePositionManager = new ethers.utils.Interface(
1184
+ INonfungiblePositionManager.abi
1185
+ );
1139
1186
  switch (dapp) {
1140
1187
  case Dapp.UNISWAPV3:
1141
- contractAddress = nonfungiblePositionManagerAddress[this.network];
1142
- const iNonfungiblePositionManager = new ethers.utils.Interface(
1143
- INonfungiblePositionManager.abi
1144
- );
1188
+ contractAddress = nonfungiblePositionManagerAddress[this.network][dapp];
1145
1189
  txData = iNonfungiblePositionManager.encodeFunctionData(
1146
1190
  Transaction.COLLECT,
1147
1191
  [[tokenId, this.address, MaxUint128, MaxUint128]]
@@ -1163,6 +1207,21 @@ export class Pool {
1163
1207
  contractAddress = tokenId;
1164
1208
  txData = getVelodromeClaimTxData(this, tokenId, true);
1165
1209
  break;
1210
+ case Dapp.VELODROMECL:
1211
+ const tokenIdOwner = await getVelodromeClOwner(this, tokenId);
1212
+ if (tokenIdOwner.toLowerCase() === this.address.toLowerCase()) {
1213
+ contractAddress =
1214
+ nonfungiblePositionManagerAddress[this.network][dapp];
1215
+ txData = iNonfungiblePositionManager.encodeFunctionData(
1216
+ Transaction.COLLECT,
1217
+ [[tokenId, this.address, MaxUint128, MaxUint128]]
1218
+ );
1219
+ } else {
1220
+ //staked in gauge
1221
+ contractAddress = tokenIdOwner;
1222
+ txData = getVelodromeCLClaimTxData(tokenId);
1223
+ }
1224
+ break;
1166
1225
  default:
1167
1226
  throw new Error("dapp not supported");
1168
1227
  }
@@ -1190,7 +1249,7 @@ export class Pool {
1190
1249
  assetFrom: string,
1191
1250
  assetTo: string,
1192
1251
  amountIn: BigNumber | string,
1193
- feeAmount: FeeAmount,
1252
+ feeAmount: number,
1194
1253
  slippage = 0.5,
1195
1254
  options: any = null,
1196
1255
  estimateGas = false
@@ -27,7 +27,7 @@ export async function getLyraOptionTxData(
27
27
  const filteredPosition = positions.filter(
28
28
  e =>
29
29
  e.strikeId.toNumber() === strikeId &&
30
- isCall(e.optionType) == (optionType === "call") &&
30
+ isCall(e.optionType) === (optionType === "call") &&
31
31
  e.state === 1
32
32
  );
33
33
  const positionId =
@@ -1,4 +1,6 @@
1
- import { Price, Token } from "@uniswap/sdk-core";
1
+ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ import { Token, Price } from "@uniswap/sdk-core";
2
4
  import {
3
5
  encodeSqrtRatioX96,
4
6
  FeeAmount,
@@ -9,14 +11,17 @@ import {
9
11
  } from "@uniswap/v3-sdk";
10
12
  import { ethers } from "ethers";
11
13
  import JSBI from "jsbi";
12
- import { Pool } from "../..";
14
+ import { Dapp, Pool, Transaction } from "../..";
13
15
  import {
16
+ MaxUint128,
14
17
  networkChainIdMap,
15
18
  nonfungiblePositionManagerAddress
16
19
  } from "../../config";
17
- import { UniswapV3MintParams } from "./types";
18
20
  import INonfungiblePositionManager from "../../abi/INonfungiblePositionManager.json";
21
+ import IVeldodromePositionManager from "../../abi/IVelodromeNonfungiblePositionManager.json";
22
+ import IArrakisV1RouterStaking from "../../abi/IArrakisV1RouterStaking.json";
19
23
  import { getDeadline } from "../../utils/deadline";
24
+ import BigNumber from "bignumber.js";
20
25
 
21
26
  export function tryParsePrice(
22
27
  baseToken: Token,
@@ -42,7 +47,7 @@ export function tryParsePrice(
42
47
  export function tryParseTick(
43
48
  baseToken: Token,
44
49
  quoteToken: Token,
45
- feeAmount: FeeAmount,
50
+ feeAmount: number,
46
51
  value: string
47
52
  ): number {
48
53
  const price = tryParsePrice(baseToken, quoteToken, value);
@@ -61,10 +66,11 @@ export function tryParseTick(
61
66
  tick = priceToClosestTick(price);
62
67
  }
63
68
 
64
- return nearestUsableTick(tick, TICK_SPACINGS[feeAmount]);
69
+ return nearestUsableTick(tick, TICK_SPACINGS[feeAmount as FeeAmount]);
65
70
  }
66
71
 
67
- export async function getUniswapV3MintParams(
72
+ export async function getUniswapV3MintTxData(
73
+ dapp: Dapp.UNISWAPV3 | Dapp.VELODROMECL,
68
74
  pool: Pool,
69
75
  assetA: string,
70
76
  assetB: string,
@@ -74,8 +80,8 @@ export async function getUniswapV3MintParams(
74
80
  maxPrice: number | null,
75
81
  minTick: number | null,
76
82
  maxTick: number | null,
77
- feeAmount: FeeAmount
78
- ): Promise<UniswapV3MintParams> {
83
+ feeAmountOrTickSpacing: number
84
+ ): Promise<any> {
79
85
  let tickLower = 0;
80
86
  let tickUpper = 0;
81
87
  const chainId = networkChainIdMap[pool.network];
@@ -88,14 +94,33 @@ export async function getUniswapV3MintParams(
88
94
  ? [tokenA, tokenB]
89
95
  : [tokenB, tokenA];
90
96
  const invertPrice = !tokenA.equals(token0);
91
-
92
97
  if (minPrice && maxPrice) {
93
98
  tickLower = invertPrice
94
- ? tryParseTick(token1, token0, feeAmount, maxPrice.toString())
95
- : tryParseTick(token0, token1, feeAmount, minPrice.toString());
99
+ ? tryParseTick(
100
+ token1,
101
+ token0,
102
+ feeAmountOrTickSpacing,
103
+ maxPrice.toString()
104
+ )
105
+ : tryParseTick(
106
+ token0,
107
+ token1,
108
+ feeAmountOrTickSpacing,
109
+ minPrice.toString()
110
+ );
96
111
  tickUpper = invertPrice
97
- ? tryParseTick(token1, token0, feeAmount, minPrice.toString())
98
- : tryParseTick(token0, token1, feeAmount, maxPrice.toString());
112
+ ? tryParseTick(
113
+ token1,
114
+ token0,
115
+ feeAmountOrTickSpacing,
116
+ minPrice.toString()
117
+ )
118
+ : tryParseTick(
119
+ token0,
120
+ token1,
121
+ feeAmountOrTickSpacing,
122
+ maxPrice.toString()
123
+ );
99
124
  } else if (minTick && maxTick) {
100
125
  tickLower = minTick;
101
126
  tickUpper = maxTick;
@@ -104,10 +129,10 @@ export async function getUniswapV3MintParams(
104
129
  ? [amountB, amountA]
105
130
  : [amountA, amountB];
106
131
 
107
- return [
132
+ const mintParams = [
108
133
  token0.address,
109
134
  token1.address,
110
- feeAmount,
135
+ feeAmountOrTickSpacing,
111
136
  tickLower,
112
137
  tickUpper,
113
138
  amount0,
@@ -117,17 +142,115 @@ export async function getUniswapV3MintParams(
117
142
  pool.address,
118
143
  await getDeadline(pool)
119
144
  ];
145
+
146
+ let iNonfungiblePositionManager = new ethers.utils.Interface(
147
+ INonfungiblePositionManager.abi
148
+ );
149
+
150
+ if (dapp === Dapp.VELODROMECL) {
151
+ iNonfungiblePositionManager = new ethers.utils.Interface(
152
+ IVeldodromePositionManager.abi
153
+ );
154
+ mintParams.push(0);
155
+ }
156
+
157
+ return iNonfungiblePositionManager.encodeFunctionData(Transaction.MINT, [
158
+ mintParams
159
+ ]);
160
+
161
+ return;
120
162
  }
121
163
 
122
164
  export async function getUniswapV3Liquidity(
165
+ dapp: Dapp.UNISWAPV3 | Dapp.VELODROMECL,
123
166
  tokenId: string,
124
167
  pool: Pool
125
- ): Promise<ethers.BigNumber> {
168
+ ): Promise<BigNumber> {
126
169
  const iNonfungiblePositionManager = new ethers.Contract(
127
- nonfungiblePositionManagerAddress[pool.network],
170
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
171
+ nonfungiblePositionManagerAddress[pool.network][dapp]!,
128
172
  INonfungiblePositionManager.abi,
129
173
  pool.signer
130
174
  );
131
175
  const result = await iNonfungiblePositionManager.positions(tokenId);
132
- return result.liquidity;
176
+ return new BigNumber(result.liquidity.toString());
177
+ }
178
+
179
+ export async function getIncreaseLiquidityTxData(
180
+ pool: Pool,
181
+ dapp: Dapp,
182
+ tokenId: string,
183
+ amountA: ethers.BigNumber | string,
184
+ amountB: ethers.BigNumber | string
185
+ ): Promise<any> {
186
+ let txData;
187
+ if (dapp === Dapp.UNISWAPV3 || dapp === Dapp.VELODROMECL) {
188
+ const abi = new ethers.utils.Interface(INonfungiblePositionManager.abi);
189
+ txData = abi.encodeFunctionData(Transaction.INCREASE_LIQUIDITY, [
190
+ [tokenId, amountA, amountB, 0, 0, await getDeadline(pool)]
191
+ ]);
192
+ } else if (dapp === Dapp.ARRAKIS) {
193
+ const abi = new ethers.utils.Interface(IArrakisV1RouterStaking.abi);
194
+ txData = abi.encodeFunctionData(Transaction.ADD_LIQUIDITY_STAKE, [
195
+ tokenId,
196
+ amountA,
197
+ amountB,
198
+ 0,
199
+ 0,
200
+ 0,
201
+ pool.address
202
+ ]);
203
+ } else {
204
+ throw new Error("dapp not supported");
205
+ }
206
+
207
+ return txData;
208
+ }
209
+
210
+ export async function getDecreaseLiquidityTxData(
211
+ pool: Pool,
212
+ dapp: Dapp,
213
+ tokenId: string,
214
+ amount = 100
215
+ ): Promise<any> {
216
+ let txData;
217
+ if (dapp === Dapp.UNISWAPV3 || dapp === Dapp.VELODROMECL) {
218
+ const abi = new ethers.utils.Interface(INonfungiblePositionManager.abi);
219
+ const liquidity = (await getUniswapV3Liquidity(dapp, tokenId, pool))
220
+ .times(amount)
221
+ .div(100);
222
+
223
+ const decreaseLiquidityTxData = abi.encodeFunctionData(
224
+ Transaction.DECREASE_LIQUIDITY,
225
+ [[tokenId, liquidity.toFixed(0), 0, 0, await getDeadline(pool)]]
226
+ );
227
+ const collectTxData = abi.encodeFunctionData(Transaction.COLLECT, [
228
+ [tokenId, pool.address, MaxUint128, MaxUint128]
229
+ ]);
230
+
231
+ const multicallParams = [decreaseLiquidityTxData, collectTxData];
232
+
233
+ if (amount === 100) {
234
+ const burnTxData = abi.encodeFunctionData(Transaction.BURN, [tokenId]);
235
+ multicallParams.push(burnTxData);
236
+ }
237
+ txData = abi.encodeFunctionData(Transaction.MULTI_CALL, [multicallParams]);
238
+ } else if (dapp === Dapp.ARRAKIS) {
239
+ const abi = new ethers.utils.Interface(IArrakisV1RouterStaking.abi);
240
+ const liquidity = new BigNumber(
241
+ (await pool.utils.getBalance(tokenId, pool.address)).toString()
242
+ )
243
+ .times(amount)
244
+ .div(100);
245
+ txData = abi.encodeFunctionData(Transaction.REMOVE_LIQUIDITY_UNSTAKE, [
246
+ tokenId,
247
+ liquidity,
248
+ 0,
249
+ 0,
250
+ pool.address
251
+ ]);
252
+ } else {
253
+ throw new Error("dapp not supported");
254
+ }
255
+ return txData;
133
256
  }
@@ -1,4 +1,3 @@
1
- import { FeeAmount } from "@uniswap/v3-sdk";
2
1
  import { ethers } from "ethers";
3
2
  import { Pool } from "../..";
4
3
 
@@ -12,7 +11,7 @@ export async function getUniswapV3SwapTxData(
12
11
  assetB: string,
13
12
  amountIn: string | ethers.BigNumber,
14
13
  slippage: number,
15
- feeAmount: FeeAmount
14
+ feeAmount: number
16
15
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
16
  ): Promise<any> {
18
17
  const quoterContract = new ethers.Contract(