@dhedge/v2-sdk 1.9.8 → 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.
- package/README.md +34 -0
- package/dist/config.d.ts +8 -2
- package/dist/entities/pool.d.ts +39 -8
- package/dist/services/flatmoney/keeperFee.d.ts +6 -0
- package/dist/services/flatmoney/stableLp.d.ts +9 -0
- package/dist/services/flatmoney/stableModule.d.ts +4 -0
- 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 +8 -1
- package/dist/test/wallet.d.ts +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/v2-sdk.cjs.development.js +14286 -10087
- 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 +14292 -10093
- 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/abi/flatmoney/DelayedOrder.json +547 -0
- package/src/abi/flatmoney/IFlatcoinVault.json +570 -0
- package/src/abi/flatmoney/KeeperFee.json +364 -0
- package/src/abi/flatmoney/StableModule.json +770 -0
- package/src/config.ts +33 -6
- package/src/entities/pool.ts +208 -82
- package/src/services/flatmoney/keeperFee.ts +84 -0
- package/src/services/flatmoney/stableLp.ts +135 -0
- package/src/services/flatmoney/stableModule.ts +43 -0
- 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/flatmoney.test.ts +164 -0
- package/src/test/uniswap.test.ts +24 -15
- package/src/test/utils/testingHelper.ts +29 -4
- package/src/test/velodromeCL.test.ts +223 -0
- package/src/test/wallet.ts +4 -1
- 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/config.ts
CHANGED
|
@@ -98,12 +98,20 @@ export const aaveAddressProvider: AddressDappNetworkMap = {
|
|
|
98
98
|
[Dapp.AAVEV3]: "0xe20fCBdBfFC4Dd138cE8b2E6FBb6CB49777ad64D"
|
|
99
99
|
}
|
|
100
100
|
};
|
|
101
|
-
export const nonfungiblePositionManagerAddress:
|
|
102
|
-
[Network.POLYGON]:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
101
|
+
export const nonfungiblePositionManagerAddress: AddressDappNetworkMap = {
|
|
102
|
+
[Network.POLYGON]: {
|
|
103
|
+
[Dapp.UNISWAPV3]: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88"
|
|
104
|
+
},
|
|
105
|
+
[Network.OPTIMISM]: {
|
|
106
|
+
[Dapp.UNISWAPV3]: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
|
|
107
|
+
[Dapp.VELODROMECL]: "0xbb5dfe1380333cee4c2eebd7202c80de2256adf4"
|
|
108
|
+
},
|
|
109
|
+
[Network.ARBITRUM]: {
|
|
110
|
+
[Dapp.UNISWAPV3]: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88"
|
|
111
|
+
},
|
|
112
|
+
[Network.BASE]: {
|
|
113
|
+
[Dapp.UNISWAPV3]: "0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1"
|
|
114
|
+
}
|
|
107
115
|
};
|
|
108
116
|
|
|
109
117
|
export const networkChainIdMap: NetworkChainIdMap = {
|
|
@@ -138,3 +146,22 @@ export const UNISWAPV3_QUOTER_ADDRESS =
|
|
|
138
146
|
|
|
139
147
|
export const SYNTHETIX_TRACKING_CODE =
|
|
140
148
|
"0x4448454447450000000000000000000000000000000000000000000000000000";
|
|
149
|
+
|
|
150
|
+
export const flatMoneyContractAddresses: Readonly<Partial<
|
|
151
|
+
Record<
|
|
152
|
+
Network,
|
|
153
|
+
{
|
|
154
|
+
DelayedOrder: string;
|
|
155
|
+
FlatcoinVault: string;
|
|
156
|
+
StableModule: string;
|
|
157
|
+
RETH: string;
|
|
158
|
+
}
|
|
159
|
+
>
|
|
160
|
+
>> = {
|
|
161
|
+
[Network.BASE]: {
|
|
162
|
+
DelayedOrder: "0x6D857e9D24a7566bB72a3FB0847A3E0e4E1c2879",
|
|
163
|
+
FlatcoinVault: "0x95Fa1ddc9a78273f795e67AbE8f1Cd2Cd39831fF",
|
|
164
|
+
StableModule: "0xb95fB324b8A2fAF8ec4f76e3dF46C718402736e2",
|
|
165
|
+
RETH: "0xb6fe221fe9eef5aba221c348ba20a1bf5e73624c"
|
|
166
|
+
}
|
|
167
|
+
};
|
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";
|
|
@@ -64,6 +69,11 @@ import {
|
|
|
64
69
|
getExitVestTxData
|
|
65
70
|
} from "../services/ramses/vesting";
|
|
66
71
|
import { getPoolTxOrGasEstimate } from "../utils/contract";
|
|
72
|
+
import {
|
|
73
|
+
cancelOrderViaFlatMoney,
|
|
74
|
+
mintUnitViaFlatMoney,
|
|
75
|
+
redeemUnitViaFlatMoney
|
|
76
|
+
} from "../services/flatmoney/stableLp";
|
|
67
77
|
|
|
68
78
|
export class Pool {
|
|
69
79
|
public readonly poolLogic: Contract;
|
|
@@ -256,7 +266,7 @@ export class Pool {
|
|
|
256
266
|
): Promise<any> {
|
|
257
267
|
const iERC20 = new ethers.utils.Interface(IERC20.abi);
|
|
258
268
|
const approveTxData = iERC20.encodeFunctionData("approve", [
|
|
259
|
-
nonfungiblePositionManagerAddress[this.network],
|
|
269
|
+
nonfungiblePositionManagerAddress[this.network][Dapp.UNISWAPV3],
|
|
260
270
|
amount
|
|
261
271
|
]);
|
|
262
272
|
const tx = await getPoolTxOrGasEstimate(
|
|
@@ -296,6 +306,35 @@ export class Pool {
|
|
|
296
306
|
return tx;
|
|
297
307
|
}
|
|
298
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
|
+
|
|
299
338
|
/**
|
|
300
339
|
* Trade an asset into another asset
|
|
301
340
|
* @param {Dapp} dapp Platform like Sushiswap or Uniswap
|
|
@@ -504,7 +543,7 @@ export class Pool {
|
|
|
504
543
|
* Stake liquidity pool tokens in gauge contract
|
|
505
544
|
* @param {Dapp} dapp Platform like Balancer or Velodrome
|
|
506
545
|
* @param {string} gauge Gauge contract address
|
|
507
|
-
* @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
|
|
508
547
|
* @param {any} options Transaction options
|
|
509
548
|
* @param {boolean} estimateGas Simulate/estimate gas
|
|
510
549
|
* @returns {Promise<any>} Transaction
|
|
@@ -532,6 +571,7 @@ export class Pool {
|
|
|
532
571
|
break;
|
|
533
572
|
case Dapp.VELODROMEV2:
|
|
534
573
|
case Dapp.AERODROME:
|
|
574
|
+
case Dapp.VELODROMECL:
|
|
535
575
|
stakeTxData = getVelodromeStakeTxData(amount, true);
|
|
536
576
|
break;
|
|
537
577
|
default:
|
|
@@ -579,7 +619,7 @@ export class Pool {
|
|
|
579
619
|
/**
|
|
580
620
|
* Unstake liquidity pool tokens from Velodrome or Balancer gauge
|
|
581
621
|
* @param {string} gauge Gauge contract address
|
|
582
|
-
* @param {BigNumber | string} amount Amount of liquidity pool tokens
|
|
622
|
+
* @param {BigNumber | string} amount Amount of liquidity pool tokens or CL token ID
|
|
583
623
|
* @param {any} options Transaction options
|
|
584
624
|
* @param {boolean} estimateGas Simulate/estimate gas
|
|
585
625
|
* @returns {Promise<any>} Transaction
|
|
@@ -941,6 +981,7 @@ export class Pool {
|
|
|
941
981
|
|
|
942
982
|
/**
|
|
943
983
|
* Create UniswapV3 liquidity pool
|
|
984
|
+
* @param {dapp} Platform either UniswapV3 or VelodromeCL
|
|
944
985
|
* @param {string} assetA First asset
|
|
945
986
|
* @param {string} assetB Second asset
|
|
946
987
|
* @param {BigNumber | string} amountA Amount first asset
|
|
@@ -949,12 +990,13 @@ export class Pool {
|
|
|
949
990
|
* @param { number } maxPrice Upper price range (assetB per assetA)
|
|
950
991
|
* @param { number } minTick Lower tick range
|
|
951
992
|
* @param { number } maxTick Upper tick range
|
|
952
|
-
* @param {
|
|
993
|
+
* @param { number } feeAmountOrTickSpacing Fee tier UniswapV3 or tick spacing VelodromeCL
|
|
953
994
|
* @param {any} options Transaction options
|
|
954
995
|
* @param {boolean} estimateGas Simulate/estimate gas
|
|
955
996
|
* @returns {Promise<any>} Transaction
|
|
956
997
|
*/
|
|
957
998
|
async addLiquidityUniswapV3(
|
|
999
|
+
dapp: Dapp.UNISWAPV3 | Dapp.VELODROMECL,
|
|
958
1000
|
assetA: string,
|
|
959
1001
|
assetB: string,
|
|
960
1002
|
amountA: BigNumber | string,
|
|
@@ -963,7 +1005,7 @@ export class Pool {
|
|
|
963
1005
|
maxPrice: number | null,
|
|
964
1006
|
minTick: number | null,
|
|
965
1007
|
maxTick: number | null,
|
|
966
|
-
|
|
1008
|
+
feeAmountOrTickSpacing: number,
|
|
967
1009
|
options: any = null,
|
|
968
1010
|
estimateGas = false
|
|
969
1011
|
): Promise<any> {
|
|
@@ -972,12 +1014,11 @@ export class Pool {
|
|
|
972
1014
|
(minTick === null || maxTick === null)
|
|
973
1015
|
)
|
|
974
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");
|
|
975
1019
|
|
|
976
|
-
const
|
|
977
|
-
|
|
978
|
-
);
|
|
979
|
-
|
|
980
|
-
const mintTxParams = await getUniswapV3MintParams(
|
|
1020
|
+
const mintTxData = await getUniswapV3MintTxData(
|
|
1021
|
+
dapp,
|
|
981
1022
|
this,
|
|
982
1023
|
assetA,
|
|
983
1024
|
assetB,
|
|
@@ -987,15 +1028,16 @@ export class Pool {
|
|
|
987
1028
|
maxPrice,
|
|
988
1029
|
minTick,
|
|
989
1030
|
maxTick,
|
|
990
|
-
|
|
991
|
-
);
|
|
992
|
-
const mintTxData = iNonfungiblePositionManager.encodeFunctionData(
|
|
993
|
-
Transaction.MINT,
|
|
994
|
-
[mintTxParams]
|
|
1031
|
+
feeAmountOrTickSpacing
|
|
995
1032
|
);
|
|
1033
|
+
|
|
996
1034
|
const tx = await getPoolTxOrGasEstimate(
|
|
997
1035
|
this,
|
|
998
|
-
[
|
|
1036
|
+
[
|
|
1037
|
+
nonfungiblePositionManagerAddress[this.network][dapp],
|
|
1038
|
+
mintTxData,
|
|
1039
|
+
options
|
|
1040
|
+
],
|
|
999
1041
|
estimateGas
|
|
1000
1042
|
);
|
|
1001
1043
|
return tx;
|
|
@@ -1017,46 +1059,37 @@ export class Pool {
|
|
|
1017
1059
|
options: any = null,
|
|
1018
1060
|
estimateGas = false
|
|
1019
1061
|
): Promise<any> {
|
|
1020
|
-
let txData;
|
|
1021
1062
|
let dappAddress;
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
dappAddress = routerAddress[this.network][dapp];
|
|
1047
|
-
const abi = new ethers.utils.Interface(IArrakisV1RouterStaking.abi);
|
|
1048
|
-
const liquidity = (await this.utils.getBalance(tokenId, this.address))
|
|
1049
|
-
.mul(Math.round(amount * 1e4))
|
|
1050
|
-
.div(1e6);
|
|
1051
|
-
txData = abi.encodeFunctionData(Transaction.REMOVE_LIQUIDITY_UNSTAKE, [
|
|
1052
|
-
tokenId,
|
|
1053
|
-
liquidity,
|
|
1054
|
-
0,
|
|
1055
|
-
0,
|
|
1056
|
-
this.address
|
|
1057
|
-
]);
|
|
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);
|
|
1058
1087
|
} else {
|
|
1059
|
-
|
|
1088
|
+
txData = await getVelodromeCLDecreaseStakedLiquidityTxData(
|
|
1089
|
+
this,
|
|
1090
|
+
tokenId,
|
|
1091
|
+
amount
|
|
1092
|
+
);
|
|
1060
1093
|
}
|
|
1061
1094
|
const tx = await getPoolTxOrGasEstimate(
|
|
1062
1095
|
this,
|
|
@@ -1067,7 +1100,7 @@ export class Pool {
|
|
|
1067
1100
|
}
|
|
1068
1101
|
|
|
1069
1102
|
/**
|
|
1070
|
-
* Increase liquidity of an
|
|
1103
|
+
* Increase liquidity of an UniswapV, VelodromeCL or Arrakis liquidity pool
|
|
1071
1104
|
* @param {Dapp} dapp Platform either UniswapV3 or Arrakis
|
|
1072
1105
|
* @param {string} tokenId Token Id of UniswapV3 position
|
|
1073
1106
|
* @param {BigNumber | string} amountA Amount first asset
|
|
@@ -1084,28 +1117,44 @@ export class Pool {
|
|
|
1084
1117
|
options: any = null,
|
|
1085
1118
|
estimateGas = false
|
|
1086
1119
|
): Promise<any> {
|
|
1087
|
-
let txData;
|
|
1088
1120
|
let dappAddress;
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
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,
|
|
1099
1147
|
tokenId,
|
|
1100
1148
|
amountA,
|
|
1101
|
-
amountB
|
|
1102
|
-
|
|
1103
|
-
0,
|
|
1104
|
-
0,
|
|
1105
|
-
this.address
|
|
1106
|
-
]);
|
|
1149
|
+
amountB
|
|
1150
|
+
);
|
|
1107
1151
|
} else {
|
|
1108
|
-
|
|
1152
|
+
txData = await getVelodromeCLIncreaseStakedLiquidityTxData(
|
|
1153
|
+
this,
|
|
1154
|
+
tokenId,
|
|
1155
|
+
amountA,
|
|
1156
|
+
amountB
|
|
1157
|
+
);
|
|
1109
1158
|
}
|
|
1110
1159
|
const tx = await getPoolTxOrGasEstimate(
|
|
1111
1160
|
this,
|
|
@@ -1131,12 +1180,12 @@ export class Pool {
|
|
|
1131
1180
|
): Promise<any> {
|
|
1132
1181
|
let txData;
|
|
1133
1182
|
let contractAddress;
|
|
1183
|
+
const iNonfungiblePositionManager = new ethers.utils.Interface(
|
|
1184
|
+
INonfungiblePositionManager.abi
|
|
1185
|
+
);
|
|
1134
1186
|
switch (dapp) {
|
|
1135
1187
|
case Dapp.UNISWAPV3:
|
|
1136
|
-
contractAddress = nonfungiblePositionManagerAddress[this.network];
|
|
1137
|
-
const iNonfungiblePositionManager = new ethers.utils.Interface(
|
|
1138
|
-
INonfungiblePositionManager.abi
|
|
1139
|
-
);
|
|
1188
|
+
contractAddress = nonfungiblePositionManagerAddress[this.network][dapp];
|
|
1140
1189
|
txData = iNonfungiblePositionManager.encodeFunctionData(
|
|
1141
1190
|
Transaction.COLLECT,
|
|
1142
1191
|
[[tokenId, this.address, MaxUint128, MaxUint128]]
|
|
@@ -1158,6 +1207,21 @@ export class Pool {
|
|
|
1158
1207
|
contractAddress = tokenId;
|
|
1159
1208
|
txData = getVelodromeClaimTxData(this, tokenId, true);
|
|
1160
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;
|
|
1161
1225
|
default:
|
|
1162
1226
|
throw new Error("dapp not supported");
|
|
1163
1227
|
}
|
|
@@ -1185,7 +1249,7 @@ export class Pool {
|
|
|
1185
1249
|
assetFrom: string,
|
|
1186
1250
|
assetTo: string,
|
|
1187
1251
|
amountIn: BigNumber | string,
|
|
1188
|
-
feeAmount:
|
|
1252
|
+
feeAmount: number,
|
|
1189
1253
|
slippage = 0.5,
|
|
1190
1254
|
options: any = null,
|
|
1191
1255
|
estimateGas = false
|
|
@@ -1629,4 +1693,66 @@ export class Pool {
|
|
|
1629
1693
|
);
|
|
1630
1694
|
return tx;
|
|
1631
1695
|
}
|
|
1696
|
+
|
|
1697
|
+
/** deposit rETH to mint UNIT via the Flat Money protocol
|
|
1698
|
+
*
|
|
1699
|
+
* @param { BigNumber | string } depositAmount Amount of rETH to deposit
|
|
1700
|
+
* @param { number } slippage slippage, 0.5 represents 0.5%
|
|
1701
|
+
* @param { number | null } maxKeeperFeeInUsd 5 represents $5; null will skip the maxKeeperFee check
|
|
1702
|
+
* @param {any} options Transaction options
|
|
1703
|
+
* @param {boolean} estimateGas Simulate/estimate gas
|
|
1704
|
+
* @returns {Promise<any>} Transaction
|
|
1705
|
+
*/
|
|
1706
|
+
async mintUnitViaFlatMoney(
|
|
1707
|
+
depositAmount: ethers.BigNumber | string,
|
|
1708
|
+
slippage = 0.5,
|
|
1709
|
+
maxKeeperFeeInUsd: number | null,
|
|
1710
|
+
options: any = null,
|
|
1711
|
+
estimateGas = false
|
|
1712
|
+
): Promise<any> {
|
|
1713
|
+
const tx = await mintUnitViaFlatMoney(
|
|
1714
|
+
this,
|
|
1715
|
+
depositAmount,
|
|
1716
|
+
slippage,
|
|
1717
|
+
maxKeeperFeeInUsd,
|
|
1718
|
+
options,
|
|
1719
|
+
estimateGas
|
|
1720
|
+
);
|
|
1721
|
+
return tx;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
/** redeem UNIT via the Flat Money protocol
|
|
1725
|
+
*
|
|
1726
|
+
* @param { BigNumber | string } depositAmount Amount of UNIT to withdraw
|
|
1727
|
+
* @param { number } slippage slippage, 0.5 represents 0.5%
|
|
1728
|
+
* @param { number | null } maxKeeperFeeInUsd 5 represents $5; null will skip the maxKeeperFee check
|
|
1729
|
+
* @param {any} options Transaction options
|
|
1730
|
+
* @param {boolean} estimateGas Simulate/estimate gas
|
|
1731
|
+
* @returns {Promise<any>} Transaction
|
|
1732
|
+
*/
|
|
1733
|
+
async redeemUnitViaFlatMoney(
|
|
1734
|
+
withdrawAmount: ethers.BigNumber | string,
|
|
1735
|
+
slippage = 0.5,
|
|
1736
|
+
maxKeeperFeeInUsd: number | null,
|
|
1737
|
+
options: any = null,
|
|
1738
|
+
estimateGas = false
|
|
1739
|
+
): Promise<any> {
|
|
1740
|
+
const tx = await redeemUnitViaFlatMoney(
|
|
1741
|
+
this,
|
|
1742
|
+
withdrawAmount,
|
|
1743
|
+
slippage,
|
|
1744
|
+
maxKeeperFeeInUsd,
|
|
1745
|
+
options,
|
|
1746
|
+
estimateGas
|
|
1747
|
+
);
|
|
1748
|
+
return tx;
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
async cancelOrderViaFlatMoney(
|
|
1752
|
+
options: any = null,
|
|
1753
|
+
estimateGas = false
|
|
1754
|
+
): Promise<any> {
|
|
1755
|
+
const tx = await cancelOrderViaFlatMoney(this, options, estimateGas);
|
|
1756
|
+
return tx;
|
|
1757
|
+
}
|
|
1632
1758
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Contract, ethers } from "ethers";
|
|
2
|
+
import { Pool } from "../../entities";
|
|
3
|
+
import IFlatcoinVaultAbi from "../../abi/flatmoney/IFlatcoinVault.json";
|
|
4
|
+
import KeeperFeeAbi from "../../abi/flatmoney/KeeperFee.json";
|
|
5
|
+
import { flatMoneyContractAddresses } from "../../config";
|
|
6
|
+
import BigNumber from "bignumber.js";
|
|
7
|
+
|
|
8
|
+
export const getKeeperFeeContract = async (pool: Pool): Promise<Contract> => {
|
|
9
|
+
const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
|
|
10
|
+
if (!flatMoneyContracts) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
`getStableModuleContract: network of ${pool.network} not supported`
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
const flatcoinVaultContract = new Contract(
|
|
16
|
+
flatMoneyContracts.FlatcoinVault,
|
|
17
|
+
IFlatcoinVaultAbi,
|
|
18
|
+
pool.signer
|
|
19
|
+
);
|
|
20
|
+
const key = ethers.utils.formatBytes32String("keeperFee");
|
|
21
|
+
const keeperFeeContractAddress: string = await flatcoinVaultContract.callStatic.moduleAddress(
|
|
22
|
+
key
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const keeperFeeContract = new ethers.Contract(
|
|
26
|
+
keeperFeeContractAddress,
|
|
27
|
+
KeeperFeeAbi,
|
|
28
|
+
pool.signer
|
|
29
|
+
);
|
|
30
|
+
return keeperFeeContract;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const getKeeperFee = async (
|
|
34
|
+
pool: Pool,
|
|
35
|
+
maxKeeperFeeInUsd: number | null
|
|
36
|
+
): Promise<ethers.BigNumber> => {
|
|
37
|
+
const keeperFeeContract = await getKeeperFeeContract(pool);
|
|
38
|
+
const gasPrice = await pool.signer.provider.getGasPrice();
|
|
39
|
+
|
|
40
|
+
let keeperfee: ethers.BigNumber;
|
|
41
|
+
if (gasPrice) {
|
|
42
|
+
keeperfee = await keeperFeeContract["getKeeperFee(uint256)"](
|
|
43
|
+
new BigNumber(gasPrice.toString()).times(1.2).toFixed(0)
|
|
44
|
+
);
|
|
45
|
+
} else {
|
|
46
|
+
keeperfee = await keeperFeeContract["getKeeperFee()"]();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const keeperFeeInUsd = await getKeeperFeeInUsd(pool, keeperfee);
|
|
50
|
+
|
|
51
|
+
if (
|
|
52
|
+
Number.isFinite(maxKeeperFeeInUsd) &&
|
|
53
|
+
keeperFeeInUsd.gt(ethers.BigNumber.from(maxKeeperFeeInUsd).toString())
|
|
54
|
+
) {
|
|
55
|
+
throw new Error("mintUnitViaFlatMoney: keeperFee too large");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return keeperfee;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const getKeeperFeeInUsd = async (
|
|
62
|
+
pool: Pool,
|
|
63
|
+
keeperFee: ethers.BigNumber
|
|
64
|
+
): Promise<BigNumber> => {
|
|
65
|
+
const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
|
|
66
|
+
if (!flatMoneyContracts) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
`getKeeperFeeInUsd: network of ${pool.network} not supported`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
const fundComposition = await pool.getComposition();
|
|
72
|
+
const filteredFc = fundComposition.filter(
|
|
73
|
+
fc =>
|
|
74
|
+
fc.asset.toLocaleLowerCase() ===
|
|
75
|
+
flatMoneyContracts.RETH.toLocaleLowerCase()
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
if (!filteredFc[0])
|
|
79
|
+
throw new Error(`getKeeperFeeInUsd: required asset not enabled yet`);
|
|
80
|
+
|
|
81
|
+
const rateD1 = new BigNumber(filteredFc[0].rate.toString()).div(1e18);
|
|
82
|
+
|
|
83
|
+
return rateD1.times(keeperFee.toString()).div(1e18);
|
|
84
|
+
};
|