@dhedge/v2-sdk 1.2.0 → 1.4.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/dist/config.d.ts +5 -0
- package/dist/entities/pool.d.ts +72 -5
- package/dist/entities/utils.d.ts +6 -0
- package/dist/services/claim-balancer/claim.service.d.ts +1 -5
- package/dist/services/uniswap/V3Liquidity.d.ts +9 -0
- package/dist/services/uniswap/V3Trade.d.ts +4 -0
- package/dist/services/uniswap/types.d.ts +3 -0
- package/dist/test/constants.d.ts +3 -2
- package/dist/test/txOptions.d.ts +1 -0
- package/dist/types.d.ts +19 -10
- package/dist/v2-sdk.cjs.development.js +4172 -1593
- 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 +4175 -1596
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +4 -1
- package/src/abi/IArrakisV1RouterStaking.json +107 -0
- package/src/abi/IERC20.json +15 -1
- package/src/abi/ILiquidityGaugeV4.json +153 -0
- package/src/abi/INonfungiblePositionManager.json +1221 -0
- package/src/abi/ISynthetix.json +139 -0
- package/src/abi/IUniswapV3Quoter.json +195 -0
- package/src/abi/IUniswapV3Router.json +221 -0
- package/src/config.ts +40 -9
- package/src/entities/dhedge.ts +4 -2
- package/src/entities/pool.ts +316 -30
- package/src/entities/utils.ts +12 -0
- package/src/services/claim-balancer/claim.service.ts +14 -76
- package/src/services/uniswap/V3Liquidity.ts +134 -0
- package/src/services/uniswap/V3Trade.ts +47 -0
- package/src/services/uniswap/types.ts +16 -0
- package/src/test/aave.test.ts +53 -25
- package/src/test/arrakis.test.ts +89 -0
- package/src/test/constants.ts +10 -2
- package/src/test/oneInch.test.ts +13 -20
- package/src/test/synthetix.test.ts +34 -0
- package/src/test/txOptions.ts +15 -0
- package/src/test/uniswap.test.ts +125 -0
- package/src/test/wallet.ts +4 -0
- package/src/types.ts +19 -10
package/src/entities/pool.ts
CHANGED
|
@@ -6,10 +6,22 @@ import { Contract, ethers, Wallet, BigNumber } from "ethers";
|
|
|
6
6
|
import IERC20 from "../abi/IERC20.json";
|
|
7
7
|
import IMiniChefV2 from "../abi/IMiniChefV2.json";
|
|
8
8
|
import ILendingPool from "../abi/ILendingPool.json";
|
|
9
|
+
import ISynthetix from "../abi/ISynthetix.json";
|
|
9
10
|
import IUniswapV2Router from "../abi/IUniswapV2Router.json";
|
|
11
|
+
import INonfungiblePositionManager from "../abi/INonfungiblePositionManager.json";
|
|
10
12
|
import IBalancerMerkleOrchard from "../abi/IBalancerMerkleOrchard.json";
|
|
11
13
|
import IAaveIncentivesController from "../abi/IAaveIncentivesController.json";
|
|
12
|
-
import
|
|
14
|
+
import IArrakisV1RouterStaking from "../abi/IArrakisV1RouterStaking.json";
|
|
15
|
+
import ILiquidityGaugeV4 from "../abi/ILiquidityGaugeV4.json";
|
|
16
|
+
import {
|
|
17
|
+
deadline,
|
|
18
|
+
MaxUint128,
|
|
19
|
+
networkChainIdMap,
|
|
20
|
+
nonfungiblePositionManagerAddress,
|
|
21
|
+
routerAddress,
|
|
22
|
+
stakingAddress,
|
|
23
|
+
SYNTHETIX_TRACKING_CODE
|
|
24
|
+
} from "../config";
|
|
13
25
|
import {
|
|
14
26
|
Dapp,
|
|
15
27
|
Transaction,
|
|
@@ -20,10 +32,17 @@ import {
|
|
|
20
32
|
|
|
21
33
|
import { Utils } from "./utils";
|
|
22
34
|
import { ClaimService } from "../services/claim-balancer/claim.service";
|
|
35
|
+
import {
|
|
36
|
+
getUniswapV3Liquidity,
|
|
37
|
+
getUniswapV3MintParams
|
|
38
|
+
} from "../services/uniswap/V3Liquidity";
|
|
39
|
+
import { FeeAmount } from "@uniswap/v3-sdk";
|
|
40
|
+
import { getUniswapV3SwapTxData } from "../services/uniswap/V3Trade";
|
|
23
41
|
|
|
24
42
|
export class Pool {
|
|
25
43
|
public readonly poolLogic: Contract;
|
|
26
44
|
public readonly managerLogic: Contract;
|
|
45
|
+
public readonly factory: Contract;
|
|
27
46
|
public readonly signer: Wallet;
|
|
28
47
|
public readonly address: string;
|
|
29
48
|
public readonly utils: Utils;
|
|
@@ -34,7 +53,8 @@ export class Pool {
|
|
|
34
53
|
signer: Wallet,
|
|
35
54
|
poolLogic: Contract,
|
|
36
55
|
mangerLogic: Contract,
|
|
37
|
-
utils: Utils
|
|
56
|
+
utils: Utils,
|
|
57
|
+
factory: Contract
|
|
38
58
|
) {
|
|
39
59
|
this.network = network;
|
|
40
60
|
this.poolLogic = poolLogic;
|
|
@@ -42,6 +62,7 @@ export class Pool {
|
|
|
42
62
|
this.managerLogic = mangerLogic;
|
|
43
63
|
this.signer = signer;
|
|
44
64
|
this.utils = utils;
|
|
65
|
+
this.factory = factory;
|
|
45
66
|
}
|
|
46
67
|
|
|
47
68
|
/**
|
|
@@ -170,13 +191,39 @@ export class Pool {
|
|
|
170
191
|
return tx;
|
|
171
192
|
}
|
|
172
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Approve the liquidity pool token for staking
|
|
196
|
+
* @param {Dapp} dapp Platform like Sushiswap or Uniswap
|
|
197
|
+
* @param {string} asset Address of liquidity pool token
|
|
198
|
+
* @param {BigNumber | string} amount Aamount to be approved
|
|
199
|
+
* @param {any} options Transaction options
|
|
200
|
+
* @returns {Promise<any>} Transaction
|
|
201
|
+
*/
|
|
202
|
+
async approveUniswapV3Liquidity(
|
|
203
|
+
asset: string,
|
|
204
|
+
amount: BigNumber | string,
|
|
205
|
+
options: any = null
|
|
206
|
+
): Promise<any> {
|
|
207
|
+
const iERC20 = new ethers.utils.Interface(IERC20.abi);
|
|
208
|
+
const approveTxData = iERC20.encodeFunctionData("approve", [
|
|
209
|
+
nonfungiblePositionManagerAddress[this.network],
|
|
210
|
+
amount
|
|
211
|
+
]);
|
|
212
|
+
const tx = await this.poolLogic.execTransaction(
|
|
213
|
+
asset,
|
|
214
|
+
approveTxData,
|
|
215
|
+
options
|
|
216
|
+
);
|
|
217
|
+
return tx;
|
|
218
|
+
}
|
|
219
|
+
|
|
173
220
|
/**
|
|
174
221
|
* Trade an asset into another asset
|
|
175
222
|
* @param {Dapp} dapp Platform like Sushiswap or Uniswap
|
|
176
223
|
* @param {string} assetFrom Asset to trade from
|
|
177
224
|
* @param {string} assetTo Asset to trade into
|
|
178
225
|
* @param {BigNumber | string} amountIn Amount
|
|
179
|
-
* @param {
|
|
226
|
+
* @param {number} slippage Slippage tolerance in %
|
|
180
227
|
* @param {any} options Transaction options
|
|
181
228
|
* @returns {Promise<any>} Transaction
|
|
182
229
|
*/
|
|
@@ -190,7 +237,8 @@ export class Pool {
|
|
|
190
237
|
): Promise<any> {
|
|
191
238
|
let swapTxData: string;
|
|
192
239
|
if (dapp === Dapp.ONEINCH) {
|
|
193
|
-
const
|
|
240
|
+
const chainId = networkChainIdMap[this.network];
|
|
241
|
+
const apiUrl = `https://api.1inch.exchange/v4.0/${chainId}/swap?fromTokenAddress=${assetFrom}&toTokenAddress=${assetTo}&amount=${amountIn.toString()}&fromAddress=${
|
|
194
242
|
this.address
|
|
195
243
|
}&destReceiver=${
|
|
196
244
|
this.address
|
|
@@ -205,6 +253,19 @@ export class Pool {
|
|
|
205
253
|
amountIn,
|
|
206
254
|
slippage
|
|
207
255
|
);
|
|
256
|
+
} else if (dapp === Dapp.SYNTHETIX) {
|
|
257
|
+
const iSynthetix = new ethers.utils.Interface(ISynthetix.abi);
|
|
258
|
+
const assets = [assetFrom, assetTo].map(asset =>
|
|
259
|
+
ethers.utils.formatBytes32String(asset)
|
|
260
|
+
);
|
|
261
|
+
const daoAddress = await this.factory.owner();
|
|
262
|
+
swapTxData = iSynthetix.encodeFunctionData(Transaction.SWAP_SYNTHS, [
|
|
263
|
+
assets[0],
|
|
264
|
+
amountIn,
|
|
265
|
+
assets[1],
|
|
266
|
+
daoAddress,
|
|
267
|
+
SYNTHETIX_TRACKING_CODE
|
|
268
|
+
]);
|
|
208
269
|
} else {
|
|
209
270
|
const iUniswapV2Router = new ethers.utils.Interface(IUniswapV2Router.abi);
|
|
210
271
|
const minAmountOut = await this.utils.getMinAmountOut(
|
|
@@ -219,7 +280,7 @@ export class Pool {
|
|
|
219
280
|
minAmountOut,
|
|
220
281
|
[assetFrom, assetTo],
|
|
221
282
|
this.address,
|
|
222
|
-
|
|
283
|
+
deadline
|
|
223
284
|
]);
|
|
224
285
|
}
|
|
225
286
|
const tx = await this.poolLogic.execTransaction(
|
|
@@ -251,16 +312,7 @@ export class Pool {
|
|
|
251
312
|
const iUniswapV2Router = new ethers.utils.Interface(IUniswapV2Router.abi);
|
|
252
313
|
const addLiquidityTxData = iUniswapV2Router.encodeFunctionData(
|
|
253
314
|
Transaction.ADD_LIQUIDITY,
|
|
254
|
-
[
|
|
255
|
-
assetA,
|
|
256
|
-
assetB,
|
|
257
|
-
amountA,
|
|
258
|
-
amountB,
|
|
259
|
-
0,
|
|
260
|
-
0,
|
|
261
|
-
this.address,
|
|
262
|
-
Math.floor(Date.now() / 1000) + 60 * 20 // 20 minutes from the current Unix time
|
|
263
|
-
]
|
|
315
|
+
[assetA, assetB, amountA, amountB, 0, 0, this.address, deadline]
|
|
264
316
|
);
|
|
265
317
|
const tx = await this.poolLogic.execTransaction(
|
|
266
318
|
routerAddress[this.network][dapp],
|
|
@@ -289,15 +341,7 @@ export class Pool {
|
|
|
289
341
|
const iUniswapV2Router = new ethers.utils.Interface(IUniswapV2Router.abi);
|
|
290
342
|
const removeLiquidityTxData = iUniswapV2Router.encodeFunctionData(
|
|
291
343
|
Transaction.REMOVE_LIQUIDITY,
|
|
292
|
-
[
|
|
293
|
-
assetA,
|
|
294
|
-
assetB,
|
|
295
|
-
amount,
|
|
296
|
-
0,
|
|
297
|
-
0,
|
|
298
|
-
this.address,
|
|
299
|
-
Math.floor(Date.now() / 1000) + 60 * 20 // 20 minutes from the current Unix time
|
|
300
|
-
]
|
|
344
|
+
[assetA, assetB, amount, 0, 0, this.address, deadline]
|
|
301
345
|
);
|
|
302
346
|
const tx = await this.poolLogic.execTransaction(
|
|
303
347
|
routerAddress[this.network][dapp],
|
|
@@ -370,7 +414,8 @@ export class Pool {
|
|
|
370
414
|
* Lend asset to a lending pool
|
|
371
415
|
* @param {Dapp} dapp Platform like Aave
|
|
372
416
|
* @param {string} asset Asset
|
|
373
|
-
* @param
|
|
417
|
+
* @param {BigNumber | string} amount Amount of asset to lend
|
|
418
|
+
* @param {number} referrralCode Code from Aave referral program
|
|
374
419
|
* @param {any} options Transaction options
|
|
375
420
|
* @returns {Promise<any>} Transaction
|
|
376
421
|
*/
|
|
@@ -378,6 +423,7 @@ export class Pool {
|
|
|
378
423
|
dapp: Dapp,
|
|
379
424
|
asset: string,
|
|
380
425
|
amount: BigNumber | string,
|
|
426
|
+
referrralCode = 0,
|
|
381
427
|
options: any = null
|
|
382
428
|
): Promise<any> {
|
|
383
429
|
const iLendingPool = new ethers.utils.Interface(ILendingPool.abi);
|
|
@@ -385,7 +431,7 @@ export class Pool {
|
|
|
385
431
|
asset,
|
|
386
432
|
amount,
|
|
387
433
|
this.address,
|
|
388
|
-
|
|
434
|
+
referrralCode
|
|
389
435
|
]);
|
|
390
436
|
const tx = await this.poolLogic.execTransaction(
|
|
391
437
|
routerAddress[this.network][dapp],
|
|
@@ -427,6 +473,7 @@ export class Pool {
|
|
|
427
473
|
* @param {Dapp} dapp Platform like Aave
|
|
428
474
|
* @param {string} asset Asset
|
|
429
475
|
* @param {BigNumber | string} amount Amount of asset to lend
|
|
476
|
+
* @param {number} referrralCode Code from Aave referral program
|
|
430
477
|
* @param {any} options Transaction options
|
|
431
478
|
* @returns {Promise<any>} Transaction
|
|
432
479
|
*/
|
|
@@ -434,6 +481,7 @@ export class Pool {
|
|
|
434
481
|
dapp: Dapp,
|
|
435
482
|
asset: string,
|
|
436
483
|
amount: BigNumber | string,
|
|
484
|
+
referrralCode = 0,
|
|
437
485
|
options: any = null
|
|
438
486
|
): Promise<any> {
|
|
439
487
|
const iLendingPool = new ethers.utils.Interface(ILendingPool.abi);
|
|
@@ -441,7 +489,7 @@ export class Pool {
|
|
|
441
489
|
asset,
|
|
442
490
|
amount,
|
|
443
491
|
2,
|
|
444
|
-
|
|
492
|
+
referrralCode,
|
|
445
493
|
this.address
|
|
446
494
|
]);
|
|
447
495
|
const tx = await this.poolLogic.execTransaction(
|
|
@@ -653,16 +701,13 @@ export class Pool {
|
|
|
653
701
|
iAaveIncentivesController,
|
|
654
702
|
this.signer
|
|
655
703
|
);
|
|
656
|
-
|
|
657
704
|
const amount = await aaveIncentivesController.getUserUnclaimedRewards(
|
|
658
705
|
this.address
|
|
659
706
|
);
|
|
660
|
-
|
|
661
707
|
const claimTxData = iAaveIncentivesController.encodeFunctionData(
|
|
662
708
|
Transaction.CLAIM_REWARDS,
|
|
663
709
|
[assets, amount, this.address]
|
|
664
710
|
);
|
|
665
|
-
|
|
666
711
|
const tx = await this.poolLogic.execTransaction(
|
|
667
712
|
aaveIncentivesAddress,
|
|
668
713
|
claimTxData,
|
|
@@ -670,4 +715,245 @@ export class Pool {
|
|
|
670
715
|
);
|
|
671
716
|
return tx;
|
|
672
717
|
}
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* Create UniswapV3 liquidity pool
|
|
721
|
+
* @param {string} assetA First asset
|
|
722
|
+
* @param {string} assetB Second asset
|
|
723
|
+
* @param {BigNumber | string} amountA Amount first asset
|
|
724
|
+
* @param {BigNumber | string} amountB Amount second asset
|
|
725
|
+
* @param { number } minPrice Lower price range (assetB per assetA)
|
|
726
|
+
* @param { number } maxPrice Upper price range (assetB per assetA)
|
|
727
|
+
* @param { number } minTick Lower tick range
|
|
728
|
+
* @param { number } maxTick Upper tick range
|
|
729
|
+
* @param { FeeAmount } feeAmount Fee tier (Low 0.05%, Medium 0.3%, High 1%)
|
|
730
|
+
* @param {any} options Transaction options
|
|
731
|
+
* @returns {Promise<any>} Transaction
|
|
732
|
+
*/
|
|
733
|
+
async addLiquidityUniswapV3(
|
|
734
|
+
assetA: string,
|
|
735
|
+
assetB: string,
|
|
736
|
+
amountA: BigNumber | string,
|
|
737
|
+
amountB: BigNumber | string,
|
|
738
|
+
minPrice: number | null,
|
|
739
|
+
maxPrice: number | null,
|
|
740
|
+
minTick: number | null,
|
|
741
|
+
maxTick: number | null,
|
|
742
|
+
feeAmount: FeeAmount,
|
|
743
|
+
options: any = null
|
|
744
|
+
): Promise<any> {
|
|
745
|
+
if ((!minPrice || !maxPrice) && (!minTick || !maxTick))
|
|
746
|
+
throw new Error("Need to provide price or tick range");
|
|
747
|
+
|
|
748
|
+
const iNonfungiblePositionManager = new ethers.utils.Interface(
|
|
749
|
+
INonfungiblePositionManager.abi
|
|
750
|
+
);
|
|
751
|
+
|
|
752
|
+
const mintTxParams = await getUniswapV3MintParams(
|
|
753
|
+
this,
|
|
754
|
+
assetA,
|
|
755
|
+
assetB,
|
|
756
|
+
amountA,
|
|
757
|
+
amountB,
|
|
758
|
+
minPrice,
|
|
759
|
+
maxPrice,
|
|
760
|
+
minTick,
|
|
761
|
+
maxTick,
|
|
762
|
+
feeAmount
|
|
763
|
+
);
|
|
764
|
+
const mintTxData = iNonfungiblePositionManager.encodeFunctionData(
|
|
765
|
+
Transaction.MINT,
|
|
766
|
+
[mintTxParams]
|
|
767
|
+
);
|
|
768
|
+
const tx = await this.poolLogic.execTransaction(
|
|
769
|
+
nonfungiblePositionManagerAddress[this.network],
|
|
770
|
+
mintTxData,
|
|
771
|
+
options
|
|
772
|
+
);
|
|
773
|
+
return tx;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Remove liquidity from an UniswapV3 or Arrakis liquidity pool
|
|
778
|
+
* @param {Dapp} dapp Platform either UniswapV3 or Arrakis
|
|
779
|
+
* @param {string} tokenId Token Id of UniswapV3 position
|
|
780
|
+
* @param {number} amount Amount in percent of assets to be removed
|
|
781
|
+
* @param {any} options Transaction options
|
|
782
|
+
* @returns {Promise<any>} Transaction
|
|
783
|
+
*/
|
|
784
|
+
async decreaseLiquidity(
|
|
785
|
+
dapp: Dapp,
|
|
786
|
+
tokenId: string,
|
|
787
|
+
amount = 100,
|
|
788
|
+
options: any = null
|
|
789
|
+
): Promise<any> {
|
|
790
|
+
let txData;
|
|
791
|
+
let dappAddress;
|
|
792
|
+
if (dapp === Dapp.UNISWAPV3) {
|
|
793
|
+
dappAddress = nonfungiblePositionManagerAddress[this.network];
|
|
794
|
+
const abi = new ethers.utils.Interface(INonfungiblePositionManager.abi);
|
|
795
|
+
const liquidity = (await getUniswapV3Liquidity(tokenId, this))
|
|
796
|
+
.mul(amount)
|
|
797
|
+
.div(100);
|
|
798
|
+
const decreaseLiquidityTxData = abi.encodeFunctionData(
|
|
799
|
+
Transaction.DECREASE_LIQUIDITY,
|
|
800
|
+
[[tokenId, liquidity, 0, 0, deadline]]
|
|
801
|
+
);
|
|
802
|
+
const collectTxData = abi.encodeFunctionData(Transaction.COLLECT, [
|
|
803
|
+
[tokenId, this.address, MaxUint128, MaxUint128]
|
|
804
|
+
]);
|
|
805
|
+
|
|
806
|
+
const multicallParams = [decreaseLiquidityTxData, collectTxData];
|
|
807
|
+
|
|
808
|
+
if (amount === 100) {
|
|
809
|
+
const burnTxData = abi.encodeFunctionData(Transaction.BURN, [tokenId]);
|
|
810
|
+
multicallParams.push(burnTxData);
|
|
811
|
+
}
|
|
812
|
+
txData = abi.encodeFunctionData(Transaction.MULTI_CALL, [
|
|
813
|
+
multicallParams
|
|
814
|
+
]);
|
|
815
|
+
} else if (dapp === Dapp.ARRAKIS) {
|
|
816
|
+
dappAddress = routerAddress[this.network][dapp];
|
|
817
|
+
const abi = new ethers.utils.Interface(IArrakisV1RouterStaking.abi);
|
|
818
|
+
const liquidity = (await this.utils.getBalance(tokenId, this.address))
|
|
819
|
+
.mul(amount)
|
|
820
|
+
.div(100);
|
|
821
|
+
txData = abi.encodeFunctionData(Transaction.REMOVE_LIQUIDITY_UNSTAKE, [
|
|
822
|
+
tokenId,
|
|
823
|
+
liquidity,
|
|
824
|
+
0,
|
|
825
|
+
0,
|
|
826
|
+
this.address
|
|
827
|
+
]);
|
|
828
|
+
} else {
|
|
829
|
+
throw new Error("dapp not supported");
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
const tx = await this.poolLogic.execTransaction(
|
|
833
|
+
dappAddress,
|
|
834
|
+
txData,
|
|
835
|
+
options
|
|
836
|
+
);
|
|
837
|
+
return tx;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Increase liquidity of an UniswapV3 or Arrakis liquidity pool
|
|
842
|
+
* @param {Dapp} dapp Platform either UniswapV3 or Arrakis
|
|
843
|
+
* @param {string} tokenId Token Id of UniswapV3 position
|
|
844
|
+
* @param {BigNumber | string} amountA Amount first asset
|
|
845
|
+
* @param {BigNumber | string} amountB Amount second asset
|
|
846
|
+
* @param {any} options Transaction options
|
|
847
|
+
* @returns {Promise<any>} Transaction
|
|
848
|
+
*/
|
|
849
|
+
async increaseLiquidity(
|
|
850
|
+
dapp: Dapp,
|
|
851
|
+
tokenId: string,
|
|
852
|
+
amountA: BigNumber | string,
|
|
853
|
+
amountB: BigNumber | string,
|
|
854
|
+
options: any = null
|
|
855
|
+
): Promise<any> {
|
|
856
|
+
let txData;
|
|
857
|
+
let dappAddress;
|
|
858
|
+
if (dapp === Dapp.UNISWAPV3) {
|
|
859
|
+
dappAddress = nonfungiblePositionManagerAddress[this.network];
|
|
860
|
+
const abi = new ethers.utils.Interface(INonfungiblePositionManager.abi);
|
|
861
|
+
txData = abi.encodeFunctionData(Transaction.INCREASE_LIQUIDITY, [
|
|
862
|
+
[tokenId, amountA, amountB, 0, 0, deadline]
|
|
863
|
+
]);
|
|
864
|
+
} else if (dapp === Dapp.ARRAKIS) {
|
|
865
|
+
dappAddress = routerAddress[this.network][dapp];
|
|
866
|
+
const abi = new ethers.utils.Interface(IArrakisV1RouterStaking.abi);
|
|
867
|
+
txData = abi.encodeFunctionData(Transaction.ADD_LIQUIDITY_STAKE, [
|
|
868
|
+
tokenId,
|
|
869
|
+
amountA,
|
|
870
|
+
amountB,
|
|
871
|
+
0,
|
|
872
|
+
0,
|
|
873
|
+
this.address
|
|
874
|
+
]);
|
|
875
|
+
} else {
|
|
876
|
+
throw new Error("dapp not supported");
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
const tx = await this.poolLogic.execTransaction(
|
|
880
|
+
dappAddress,
|
|
881
|
+
txData,
|
|
882
|
+
options
|
|
883
|
+
);
|
|
884
|
+
return tx;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/**
|
|
888
|
+
* Claim fees of an UniswapV3 liquidity or Arrakis pool
|
|
889
|
+
* @param {Dapp} dapp Platform either UniswapV3 or Arrakis
|
|
890
|
+
* @param {string} tokenId Token Id of UniswapV3 or Arrakis position
|
|
891
|
+
* @param {any} options Transaction options
|
|
892
|
+
* @returns {Promise<any>} Transaction
|
|
893
|
+
*/
|
|
894
|
+
async claimFees(
|
|
895
|
+
dapp: Dapp,
|
|
896
|
+
tokenId: string,
|
|
897
|
+
options: any = null
|
|
898
|
+
): Promise<any> {
|
|
899
|
+
let txData;
|
|
900
|
+
let contractAddress;
|
|
901
|
+
if (dapp === Dapp.UNISWAPV3) {
|
|
902
|
+
contractAddress = nonfungiblePositionManagerAddress[this.network];
|
|
903
|
+
const iNonfungiblePositionManager = new ethers.utils.Interface(
|
|
904
|
+
INonfungiblePositionManager.abi
|
|
905
|
+
);
|
|
906
|
+
txData = iNonfungiblePositionManager.encodeFunctionData(
|
|
907
|
+
Transaction.COLLECT,
|
|
908
|
+
[[tokenId, this.address, MaxUint128, MaxUint128]]
|
|
909
|
+
);
|
|
910
|
+
} else if (dapp === Dapp.ARRAKIS) {
|
|
911
|
+
contractAddress = tokenId;
|
|
912
|
+
const abi = new ethers.utils.Interface(ILiquidityGaugeV4.abi);
|
|
913
|
+
txData = abi.encodeFunctionData("claim_rewards()", []);
|
|
914
|
+
} else {
|
|
915
|
+
throw new Error("dapp not supported");
|
|
916
|
+
}
|
|
917
|
+
const tx = await this.poolLogic.execTransaction(
|
|
918
|
+
contractAddress,
|
|
919
|
+
txData,
|
|
920
|
+
options
|
|
921
|
+
);
|
|
922
|
+
return tx;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* Trade an asset into another asset
|
|
927
|
+
* @param {Dapp} dapp Platform like Sushiswap or Uniswap
|
|
928
|
+
* @param {string} assetFrom Asset to trade from
|
|
929
|
+
* @param {string} assetTo Asset to trade into
|
|
930
|
+
* @param {BigNumber | string} amountIn Amount
|
|
931
|
+
* @param { FeeAmount } feeAmount Fee tier (Low 0.05%, Medium 0.3%, High 1%)
|
|
932
|
+
* @param {number} slippage Slippage tolerance in %
|
|
933
|
+
* @param {any} options Transaction options
|
|
934
|
+
* @returns {Promise<any>} Transaction
|
|
935
|
+
*/
|
|
936
|
+
async tradeUniswapV3(
|
|
937
|
+
assetFrom: string,
|
|
938
|
+
assetTo: string,
|
|
939
|
+
amountIn: BigNumber | string,
|
|
940
|
+
feeAmount: FeeAmount,
|
|
941
|
+
slippage = 0.5,
|
|
942
|
+
options: any = null
|
|
943
|
+
): Promise<any> {
|
|
944
|
+
const swapxData = await getUniswapV3SwapTxData(
|
|
945
|
+
this,
|
|
946
|
+
assetFrom,
|
|
947
|
+
assetTo,
|
|
948
|
+
amountIn,
|
|
949
|
+
slippage,
|
|
950
|
+
feeAmount
|
|
951
|
+
);
|
|
952
|
+
const tx = await this.poolLogic.execTransaction(
|
|
953
|
+
routerAddress[this.network][Dapp.UNISWAPV3],
|
|
954
|
+
swapxData,
|
|
955
|
+
options
|
|
956
|
+
);
|
|
957
|
+
return tx;
|
|
958
|
+
}
|
|
673
959
|
}
|
package/src/entities/utils.ts
CHANGED
|
@@ -125,6 +125,18 @@ export class Utils {
|
|
|
125
125
|
return balance;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Returns the decimals of an asset (ERC20) token
|
|
130
|
+
* @param {string} asset string token address
|
|
131
|
+
* @returns { number } Balance of asset
|
|
132
|
+
*/
|
|
133
|
+
|
|
134
|
+
async getDecimals(asset: string): Promise<number> {
|
|
135
|
+
const iERC20 = new ethers.Contract(asset, IERC20.abi, this.signer);
|
|
136
|
+
const decimals = await iERC20.decimals();
|
|
137
|
+
return decimals;
|
|
138
|
+
}
|
|
139
|
+
|
|
128
140
|
/**
|
|
129
141
|
* Return the minimum amount out for a trade between two assets
|
|
130
142
|
* given the trade amount and slippage
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import axios from "axios";
|
|
3
|
-
import { chunk, flatten
|
|
3
|
+
import { chunk, flatten } from "lodash";
|
|
4
4
|
import merkleOrchardAbi from "../../abi/IBalancerMerkleOrchard.json";
|
|
5
5
|
import { ethers, Wallet } from "ethers";
|
|
6
6
|
|
|
@@ -11,14 +11,10 @@ import { bnum, loadTree, scale } from "../../utils";
|
|
|
11
11
|
|
|
12
12
|
import { ipfsService } from "./ipfs.service";
|
|
13
13
|
|
|
14
|
-
import MultiTokenClaim from "./MultiTokenClaim.json";
|
|
15
|
-
|
|
16
14
|
import {
|
|
17
15
|
ClaimProofTuple,
|
|
18
16
|
ClaimStatus,
|
|
19
17
|
ComputeClaimProofPayload,
|
|
20
|
-
MultiTokenCurrentRewardsEstimate,
|
|
21
|
-
MultiTokenCurrentRewardsEstimateResponse,
|
|
22
18
|
MultiTokenPendingClaims,
|
|
23
19
|
Report,
|
|
24
20
|
Snapshot,
|
|
@@ -26,7 +22,7 @@ import {
|
|
|
26
22
|
} from "./types";
|
|
27
23
|
|
|
28
24
|
import { Network } from "../../types";
|
|
29
|
-
import { stakingAddress } from "../../config";
|
|
25
|
+
import { networkChainIdMap, stakingAddress } from "../../config";
|
|
30
26
|
import { soliditySha3 } from "web3-utils";
|
|
31
27
|
import { Dapp } from "../..";
|
|
32
28
|
|
|
@@ -40,7 +36,7 @@ export class ClaimService {
|
|
|
40
36
|
public async getMultiTokensPendingClaims(
|
|
41
37
|
account: string
|
|
42
38
|
): Promise<MultiTokenPendingClaims[]> {
|
|
43
|
-
const tokenClaimsInfo = this.getTokenClaimsInfo();
|
|
39
|
+
const tokenClaimsInfo = await this.getTokenClaimsInfo();
|
|
44
40
|
if (tokenClaimsInfo != null) {
|
|
45
41
|
const multiTokenPendingClaims = await Promise.all(
|
|
46
42
|
tokenClaimsInfo.map(tokenClaimInfo =>
|
|
@@ -100,73 +96,6 @@ export class ClaimService {
|
|
|
100
96
|
};
|
|
101
97
|
}
|
|
102
98
|
|
|
103
|
-
public async getMultiTokensCurrentRewardsEstimate(
|
|
104
|
-
account: string
|
|
105
|
-
): Promise<{
|
|
106
|
-
data: MultiTokenCurrentRewardsEstimate[];
|
|
107
|
-
timestamp: string | null;
|
|
108
|
-
}> {
|
|
109
|
-
try {
|
|
110
|
-
const response = await axios.get<
|
|
111
|
-
MultiTokenCurrentRewardsEstimateResponse
|
|
112
|
-
>(
|
|
113
|
-
`https://api.balancer.finance/liquidity-mining/v1/liquidity-provider-multitoken/${account}`
|
|
114
|
-
);
|
|
115
|
-
if (response.data.success) {
|
|
116
|
-
const multiTokenLiquidityProviders = response.data.result[
|
|
117
|
-
"liquidity-providers"
|
|
118
|
-
]
|
|
119
|
-
.filter(incentive => incentive.chain_id === 137)
|
|
120
|
-
.map(incentive => ({
|
|
121
|
-
...incentive,
|
|
122
|
-
token_address: getAddress(incentive.token_address)
|
|
123
|
-
}));
|
|
124
|
-
|
|
125
|
-
const multiTokenCurrentRewardsEstimate: MultiTokenCurrentRewardsEstimate[] = [];
|
|
126
|
-
|
|
127
|
-
const multiTokenLiquidityProvidersByToken = Object.entries(
|
|
128
|
-
groupBy(multiTokenLiquidityProviders, "token_address")
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
for (const [
|
|
132
|
-
token,
|
|
133
|
-
liquidityProvider
|
|
134
|
-
] of multiTokenLiquidityProvidersByToken) {
|
|
135
|
-
const rewards = liquidityProvider
|
|
136
|
-
.reduce(
|
|
137
|
-
(total, { current_estimate }) => total.plus(current_estimate),
|
|
138
|
-
bnum(0)
|
|
139
|
-
)
|
|
140
|
-
.toString();
|
|
141
|
-
|
|
142
|
-
const velocity =
|
|
143
|
-
liquidityProvider
|
|
144
|
-
.find(liquidityProvider => Number(liquidityProvider.velocity) > 0)
|
|
145
|
-
?.velocity.toString() ?? "0";
|
|
146
|
-
|
|
147
|
-
if (Number(rewards) > 0) {
|
|
148
|
-
multiTokenCurrentRewardsEstimate.push({
|
|
149
|
-
rewards,
|
|
150
|
-
velocity,
|
|
151
|
-
token: getAddress(token)
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return {
|
|
157
|
-
data: multiTokenCurrentRewardsEstimate,
|
|
158
|
-
timestamp: response.data.result.current_timestamp
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
} catch (e) {
|
|
162
|
-
console.log("[Claim] Current Rewards Estimate Error", e);
|
|
163
|
-
}
|
|
164
|
-
return {
|
|
165
|
-
data: [],
|
|
166
|
-
timestamp: null
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
99
|
public async multiTokenClaimRewards(
|
|
171
100
|
account: string,
|
|
172
101
|
multiTokenPendingClaims: MultiTokenPendingClaims[]
|
|
@@ -243,8 +172,17 @@ export class ClaimService {
|
|
|
243
172
|
] as ClaimProofTuple;
|
|
244
173
|
}
|
|
245
174
|
|
|
246
|
-
private getTokenClaimsInfo() {
|
|
247
|
-
|
|
175
|
+
private async getTokenClaimsInfo() {
|
|
176
|
+
let tokenClaims;
|
|
177
|
+
try {
|
|
178
|
+
const multiTokenClaim = await axios.get(
|
|
179
|
+
"https://raw.githubusercontent.com/balancer-labs/frontend-v2/develop/src/services/claim/MultiTokenClaim.json"
|
|
180
|
+
);
|
|
181
|
+
const chainId = networkChainIdMap[this.network];
|
|
182
|
+
tokenClaims = multiTokenClaim.data[chainId];
|
|
183
|
+
} catch (e) {
|
|
184
|
+
console.log("balancer multi token info error", e);
|
|
185
|
+
}
|
|
248
186
|
|
|
249
187
|
if (tokenClaims != null) {
|
|
250
188
|
return (tokenClaims as TokenClaimInfo[]).map(tokenClaim => ({
|