@dhedge/v2-sdk 1.9.9 → 1.10.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.
- package/dist/config.d.ts +1 -1
- package/dist/entities/pool.d.ts +17 -7
- package/dist/services/uniswap/V3Liquidity.d.ts +8 -7
- package/dist/services/uniswap/V3Trade.d.ts +1 -2
- package/dist/services/velodrome/liquidity.d.ts +7 -3
- package/dist/services/velodrome/staking.d.ts +1 -0
- package/dist/test/constants.d.ts +14 -0
- package/dist/test/utils/testingHelper.d.ts +6 -0
- package/dist/types.d.ts +1 -0
- package/dist/v2-sdk.cjs.development.js +2675 -1370
- package/dist/v2-sdk.cjs.development.js.map +1 -1
- package/dist/v2-sdk.cjs.production.min.js +1 -1
- package/dist/v2-sdk.cjs.production.min.js.map +1 -1
- package/dist/v2-sdk.esm.js +2688 -1383
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +2 -2
- package/src/abi/IERC721.json +217 -0
- package/src/abi/IVelodromeCLGauge.json +165 -0
- package/src/abi/IVelodromeNonfungiblePositionManager.json +408 -0
- package/src/config.ts +17 -7
- package/src/entities/pool.ts +141 -82
- package/src/services/lyra/trade.ts +1 -1
- package/src/services/uniswap/V3Liquidity.ts +141 -18
- package/src/services/uniswap/V3Trade.ts +1 -2
- package/src/services/velodrome/liquidity.ts +77 -5
- package/src/services/velodrome/staking.ts +6 -0
- package/src/test/constants.ts +22 -6
- package/src/test/uniswap.test.ts +24 -15
- package/src/test/utils/testingHelper.ts +25 -1
- package/src/test/velodromeCL.test.ts +223 -0
- package/src/types.ts +1 -0
- package/dist/services/uniswap/types.d.ts +0 -3
- package/src/services/uniswap/types.ts +0 -16
package/src/entities/pool.ts
CHANGED
|
@@ -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
|
-
|
|
38
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
|
982
|
-
|
|
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
|
-
|
|
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
|
-
[
|
|
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
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
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
|
-
|
|
1108
|
-
0,
|
|
1109
|
-
0,
|
|
1110
|
-
this.address
|
|
1111
|
-
]);
|
|
1149
|
+
amountB
|
|
1150
|
+
);
|
|
1112
1151
|
} else {
|
|
1113
|
-
|
|
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:
|
|
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)
|
|
30
|
+
isCall(e.optionType) === (optionType === "call") &&
|
|
31
31
|
e.state === 1
|
|
32
32
|
);
|
|
33
33
|
const positionId =
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
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:
|
|
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
|
|
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
|
-
|
|
78
|
-
): Promise<
|
|
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(
|
|
95
|
-
|
|
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(
|
|
98
|
-
|
|
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
|
-
|
|
132
|
+
const mintParams = [
|
|
108
133
|
token0.address,
|
|
109
134
|
token1.address,
|
|
110
|
-
|
|
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<
|
|
168
|
+
): Promise<BigNumber> {
|
|
126
169
|
const iNonfungiblePositionManager = new ethers.Contract(
|
|
127
|
-
|
|
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:
|
|
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(
|