@dhedge/v2-sdk 1.4.0 → 1.4.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhedge/v2-sdk",
3
- "version": "1.4.0",
3
+ "version": "1.4.3",
4
4
  "license": "MIT",
5
5
  "description": "🛠 An SDK for building applications on top of dHEDGE V2",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,239 @@
1
+ {
2
+ "abi": [
3
+ {
4
+ "inputs": [
5
+ {
6
+ "internalType": "address",
7
+ "name": "user",
8
+ "type": "address"
9
+ }
10
+ ],
11
+ "name": "balanceOf",
12
+ "outputs": [
13
+ {
14
+ "internalType": "uint256",
15
+ "name": "",
16
+ "type": "uint256"
17
+ }
18
+ ],
19
+ "stateMutability": "view",
20
+ "type": "function"
21
+ },
22
+ {
23
+ "inputs": [
24
+ {
25
+ "internalType": "address",
26
+ "name": "user",
27
+ "type": "address"
28
+ }
29
+ ],
30
+ "name": "claim_rewards",
31
+ "outputs": [],
32
+ "stateMutability": "nonpayable",
33
+ "type": "function"
34
+ },
35
+ {
36
+ "inputs": [
37
+ {
38
+ "internalType": "address",
39
+ "name": "user",
40
+ "type": "address"
41
+ },
42
+ {
43
+ "internalType": "address",
44
+ "name": "receiver",
45
+ "type": "address"
46
+ }
47
+ ],
48
+ "name": "claim_rewards",
49
+ "outputs": [],
50
+ "stateMutability": "nonpayable",
51
+ "type": "function"
52
+ },
53
+ {
54
+ "inputs": [],
55
+ "name": "claim_rewards",
56
+ "outputs": [],
57
+ "stateMutability": "nonpayable",
58
+ "type": "function"
59
+ },
60
+ {
61
+ "inputs": [
62
+ {
63
+ "internalType": "address",
64
+ "name": "user",
65
+ "type": "address"
66
+ },
67
+ {
68
+ "internalType": "address",
69
+ "name": "rewardToken",
70
+ "type": "address"
71
+ }
72
+ ],
73
+ "name": "claimable_reward",
74
+ "outputs": [
75
+ {
76
+ "internalType": "uint256",
77
+ "name": "",
78
+ "type": "uint256"
79
+ }
80
+ ],
81
+ "stateMutability": "view",
82
+ "type": "function"
83
+ },
84
+ {
85
+ "inputs": [
86
+ {
87
+ "internalType": "address",
88
+ "name": "user",
89
+ "type": "address"
90
+ },
91
+ {
92
+ "internalType": "address",
93
+ "name": "rewardToken",
94
+ "type": "address"
95
+ }
96
+ ],
97
+ "name": "claimable_reward_write",
98
+ "outputs": [
99
+ {
100
+ "internalType": "uint256",
101
+ "name": "",
102
+ "type": "uint256"
103
+ }
104
+ ],
105
+ "stateMutability": "nonpayable",
106
+ "type": "function"
107
+ },
108
+ {
109
+ "inputs": [
110
+ {
111
+ "internalType": "uint256",
112
+ "name": "amount",
113
+ "type": "uint256"
114
+ },
115
+ {
116
+ "internalType": "address",
117
+ "name": "user",
118
+ "type": "address"
119
+ }
120
+ ],
121
+ "name": "deposit",
122
+ "outputs": [],
123
+ "stateMutability": "nonpayable",
124
+ "type": "function"
125
+ },
126
+ {
127
+ "inputs": [
128
+ {
129
+ "internalType": "uint256",
130
+ "name": "amount",
131
+ "type": "uint256"
132
+ },
133
+ {
134
+ "internalType": "address",
135
+ "name": "onBehalf",
136
+ "type": "address"
137
+ },
138
+ {
139
+ "internalType": "bool",
140
+ "name": "isClaimRewards",
141
+ "type": "bool"
142
+ }
143
+ ],
144
+ "name": "deposit",
145
+ "outputs": [],
146
+ "stateMutability": "nonpayable",
147
+ "type": "function"
148
+ },
149
+ {
150
+ "inputs": [
151
+ {
152
+ "internalType": "uint256",
153
+ "name": "amount",
154
+ "type": "uint256"
155
+ }
156
+ ],
157
+ "name": "deposit",
158
+ "outputs": [],
159
+ "stateMutability": "nonpayable",
160
+ "type": "function"
161
+ },
162
+ {
163
+ "inputs": [],
164
+ "name": "lp_token",
165
+ "outputs": [
166
+ {
167
+ "internalType": "address",
168
+ "name": "",
169
+ "type": "address"
170
+ }
171
+ ],
172
+ "stateMutability": "view",
173
+ "type": "function"
174
+ },
175
+ {
176
+ "inputs": [],
177
+ "name": "reward_contract",
178
+ "outputs": [
179
+ {
180
+ "internalType": "address",
181
+ "name": "",
182
+ "type": "address"
183
+ }
184
+ ],
185
+ "stateMutability": "view",
186
+ "type": "function"
187
+ },
188
+ {
189
+ "inputs": [
190
+ {
191
+ "internalType": "uint256",
192
+ "name": "index",
193
+ "type": "uint256"
194
+ }
195
+ ],
196
+ "name": "reward_tokens",
197
+ "outputs": [
198
+ {
199
+ "internalType": "address",
200
+ "name": "",
201
+ "type": "address"
202
+ }
203
+ ],
204
+ "stateMutability": "view",
205
+ "type": "function"
206
+ },
207
+ {
208
+ "inputs": [
209
+ {
210
+ "internalType": "uint256",
211
+ "name": "amount",
212
+ "type": "uint256"
213
+ }
214
+ ],
215
+ "name": "withdraw",
216
+ "outputs": [],
217
+ "stateMutability": "nonpayable",
218
+ "type": "function"
219
+ },
220
+ {
221
+ "inputs": [
222
+ {
223
+ "internalType": "uint256",
224
+ "name": "amount",
225
+ "type": "uint256"
226
+ },
227
+ {
228
+ "internalType": "bool",
229
+ "name": "isClaimRewards",
230
+ "type": "bool"
231
+ }
232
+ ],
233
+ "name": "withdraw",
234
+ "outputs": [],
235
+ "stateMutability": "nonpayable",
236
+ "type": "function"
237
+ }
238
+ ]
239
+ }
@@ -88,7 +88,6 @@ export class Dhedge {
88
88
  * @returns {Pool} Loaded Pool
89
89
  */
90
90
  public async loadPool(address: string): Promise<Pool> {
91
- this.validatePool(address);
92
91
  const poolLogic = new Contract(address, PoolLogic.abi, this.signer);
93
92
  const managerLogicAddress = await poolLogic.poolManagerLogic();
94
93
  const managerLogic = new Contract(
@@ -106,14 +105,4 @@ export class Dhedge {
106
105
  this.factory
107
106
  );
108
107
  }
109
-
110
- /**
111
- * Check if pool address is valid
112
- * @param {string} address Pool address
113
- * @returns {boolean} Is valid pool address
114
- */
115
- private async validatePool(address: string): Promise<void> {
116
- const isPool = await this.factory.isPool(address);
117
- if (!isPool) throw new Error("Given address not a pool");
118
- }
119
108
  }
@@ -13,6 +13,8 @@ import IBalancerMerkleOrchard from "../abi/IBalancerMerkleOrchard.json";
13
13
  import IAaveIncentivesController from "../abi/IAaveIncentivesController.json";
14
14
  import IArrakisV1RouterStaking from "../abi/IArrakisV1RouterStaking.json";
15
15
  import ILiquidityGaugeV4 from "../abi/ILiquidityGaugeV4.json";
16
+ import IBalancerRewardsGauge from "../abi/IBalancerRewardsGauge.json";
17
+
16
18
  import {
17
19
  deadline,
18
20
  MaxUint128,
@@ -217,6 +219,33 @@ export class Pool {
217
219
  return tx;
218
220
  }
219
221
 
222
+ /**
223
+ * Approve the asset for provided spender address
224
+ * @param {string} spender Spender address
225
+ * @param {string} asset Address of asset
226
+ * @param {BigNumber | string} amount to be approved
227
+ * @param {any} options Transaction options
228
+ * @returns {Promise<any>} Transaction
229
+ */
230
+ async approveSpender(
231
+ spender: string,
232
+ asset: string,
233
+ amount: BigNumber | string,
234
+ options: any = null
235
+ ): Promise<any> {
236
+ const iERC20 = new ethers.utils.Interface(IERC20.abi);
237
+ const approveTxData = iERC20.encodeFunctionData("approve", [
238
+ spender,
239
+ amount
240
+ ]);
241
+ const tx = await this.poolLogic.execTransaction(
242
+ asset,
243
+ approveTxData,
244
+ options
245
+ );
246
+ return tx;
247
+ }
248
+
220
249
  /**
221
250
  * Trade an asset into another asset
222
251
  * @param {Dapp} dapp Platform like Sushiswap or Uniswap
@@ -377,7 +406,30 @@ export class Pool {
377
406
  stakeTxData,
378
407
  options
379
408
  );
409
+ return tx;
410
+ }
380
411
 
412
+ /**
413
+ * Stake liquidity pool tokens in gauge contract
414
+ * @param {string} gauge Gauge contract address
415
+ * @param {BigNumber | string} amount Amount of liquidity pool tokens
416
+ * @param {any} options Transaction options
417
+ * @returns {Promise<any>} Transaction
418
+ */
419
+ async stakeInGauge(
420
+ gauge: string,
421
+ amount: BigNumber | string,
422
+ options: any = null
423
+ ): Promise<any> {
424
+ const rewardsGauge = new ethers.utils.Interface(IBalancerRewardsGauge.abi);
425
+ const stakeTxData = rewardsGauge.encodeFunctionData("deposit(uint256)", [
426
+ amount
427
+ ]);
428
+ const tx = await this.poolLogic.execTransaction(
429
+ gauge,
430
+ stakeTxData,
431
+ options
432
+ );
381
433
  return tx;
382
434
  }
383
435
 
@@ -410,12 +462,36 @@ export class Pool {
410
462
  return tx;
411
463
  }
412
464
 
465
+ /**
466
+ * Unstake liquidity pool tokens from gauge contract
467
+ * @param {string} gauge Gauge contract address
468
+ * @param {BigNumber | string} amount Amount of liquidity pool tokens
469
+ * @param {any} options Transaction options
470
+ * @returns {Promise<any>} Transaction
471
+ */
472
+ async unstakeFromGauge(
473
+ gauge: string,
474
+ amount: BigNumber | string,
475
+ options: any = null
476
+ ): Promise<any> {
477
+ const rewardsGauge = new ethers.utils.Interface(IBalancerRewardsGauge.abi);
478
+ const unstakeTxData = rewardsGauge.encodeFunctionData("withdraw(uint256)", [
479
+ amount
480
+ ]);
481
+ const tx = await this.poolLogic.execTransaction(
482
+ gauge,
483
+ unstakeTxData,
484
+ options
485
+ );
486
+ return tx;
487
+ }
488
+
413
489
  /**
414
490
  * Lend asset to a lending pool
415
491
  * @param {Dapp} dapp Platform like Aave
416
492
  * @param {string} asset Asset
417
493
  * @param {BigNumber | string} amount Amount of asset to lend
418
- * @param {number} referrralCode Code from Aave referral program
494
+ * @param {number} referralCode Code from Aave referral program
419
495
  * @param {any} options Transaction options
420
496
  * @returns {Promise<any>} Transaction
421
497
  */
@@ -423,7 +499,7 @@ export class Pool {
423
499
  dapp: Dapp,
424
500
  asset: string,
425
501
  amount: BigNumber | string,
426
- referrralCode = 0,
502
+ referralCode = 0,
427
503
  options: any = null
428
504
  ): Promise<any> {
429
505
  const iLendingPool = new ethers.utils.Interface(ILendingPool.abi);
@@ -431,7 +507,7 @@ export class Pool {
431
507
  asset,
432
508
  amount,
433
509
  this.address,
434
- referrralCode
510
+ referralCode
435
511
  ]);
436
512
  const tx = await this.poolLogic.execTransaction(
437
513
  routerAddress[this.network][dapp],
@@ -473,7 +549,7 @@ export class Pool {
473
549
  * @param {Dapp} dapp Platform like Aave
474
550
  * @param {string} asset Asset
475
551
  * @param {BigNumber | string} amount Amount of asset to lend
476
- * @param {number} referrralCode Code from Aave referral program
552
+ * @param {number} referralCode Code from Aave referral program
477
553
  * @param {any} options Transaction options
478
554
  * @returns {Promise<any>} Transaction
479
555
  */
@@ -481,7 +557,7 @@ export class Pool {
481
557
  dapp: Dapp,
482
558
  asset: string,
483
559
  amount: BigNumber | string,
484
- referrralCode = 0,
560
+ referralCode = 0,
485
561
  options: any = null
486
562
  ): Promise<any> {
487
563
  const iLendingPool = new ethers.utils.Interface(ILendingPool.abi);
@@ -489,7 +565,7 @@ export class Pool {
489
565
  asset,
490
566
  amount,
491
567
  2,
492
- referrralCode,
568
+ referralCode,
493
569
  this.address
494
570
  ]);
495
571
  const tx = await this.poolLogic.execTransaction(
@@ -624,6 +700,7 @@ export class Pool {
624
700
  * @param {string} poolId Balancer pool id
625
701
  * @param {string[] | } assets Array of balancer pool assets
626
702
  * @param {BigNumber | string } amount Amount of pool tokens to withdraw
703
+ * @param { null | number } singleExitAssetIndex Index of asset to withdraw to
627
704
  * @param {any} options Transaction options
628
705
  * @returns {Promise<any>} Transaction
629
706
  */
@@ -631,12 +708,14 @@ export class Pool {
631
708
  poolId: string,
632
709
  assets: string[],
633
710
  amount: string | BigNumber,
711
+ singleExitAssetIndex: number | null = null,
634
712
  options: any = null
635
713
  ): Promise<any> {
636
714
  const exitPoolTxData = this.utils.getBalancerExitPoolTx(
637
715
  this,
638
716
  poolId,
639
717
  assets,
718
+ singleExitAssetIndex,
640
719
  amount
641
720
  );
642
721
  const tx = await this.poolLogic.execTransaction(
@@ -793,8 +872,8 @@ export class Pool {
793
872
  dappAddress = nonfungiblePositionManagerAddress[this.network];
794
873
  const abi = new ethers.utils.Interface(INonfungiblePositionManager.abi);
795
874
  const liquidity = (await getUniswapV3Liquidity(tokenId, this))
796
- .mul(amount)
797
- .div(100);
875
+ .mul(Math.round(amount * 1e4))
876
+ .div(1e6);
798
877
  const decreaseLiquidityTxData = abi.encodeFunctionData(
799
878
  Transaction.DECREASE_LIQUIDITY,
800
879
  [[tokenId, liquidity, 0, 0, deadline]]
@@ -816,8 +895,8 @@ export class Pool {
816
895
  dappAddress = routerAddress[this.network][dapp];
817
896
  const abi = new ethers.utils.Interface(IArrakisV1RouterStaking.abi);
818
897
  const liquidity = (await this.utils.getBalance(tokenId, this.address))
819
- .mul(amount)
820
- .div(100);
898
+ .mul(Math.round(amount * 1e4))
899
+ .div(1e6);
821
900
  txData = abi.encodeFunctionData(Transaction.REMOVE_LIQUIDITY_UNSTAKE, [
822
901
  tokenId,
823
902
  liquidity,
@@ -887,8 +966,8 @@ export class Pool {
887
966
  /**
888
967
  * Claim fees of an UniswapV3 liquidity or Arrakis pool
889
968
  * @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
969
+ * @param {string} tokenId Token Id of UniswapV3 or Gauge address
970
+ * @param {any} options Transaction option
892
971
  * @returns {Promise<any>} Transaction
893
972
  */
894
973
  async claimFees(
@@ -907,7 +986,7 @@ export class Pool {
907
986
  Transaction.COLLECT,
908
987
  [[tokenId, this.address, MaxUint128, MaxUint128]]
909
988
  );
910
- } else if (dapp === Dapp.ARRAKIS) {
989
+ } else if (dapp === Dapp.ARRAKIS || dapp === Dapp.BALANCER) {
911
990
  contractAddress = tokenId;
912
991
  const abi = new ethers.utils.Interface(ILiquidityGaugeV4.abi);
913
992
  txData = abi.encodeFunctionData("claim_rewards()", []);
@@ -295,25 +295,29 @@ export class Utils {
295
295
  pool: Pool,
296
296
  balancerPoolId: string,
297
297
  assets: string[],
298
+ singleExitAssetIndex: null | number,
298
299
  amount: string | ethers.BigNumber
299
300
 
300
301
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
301
302
  ): Promise<any> {
302
303
  const minimumAmountOut = new Array(assets.length).fill(0);
303
304
  const iBalancerV2Vault = new ethers.utils.Interface(IBalancerV2Vault.abi);
305
+ const userTxData =
306
+ singleExitAssetIndex === null
307
+ ? ethers.utils.defaultAbiCoder.encode(
308
+ ["uint256", "uint256"],
309
+ [1, amount]
310
+ )
311
+ : ethers.utils.defaultAbiCoder.encode(
312
+ ["uint256", "uint256", "uint256"],
313
+ [0, amount, singleExitAssetIndex]
314
+ );
315
+
304
316
  const txData = [
305
317
  balancerPoolId,
306
318
  pool.address,
307
319
  pool.address,
308
- [
309
- assets,
310
- minimumAmountOut,
311
- ethers.utils.defaultAbiCoder.encode(
312
- ["uint256", "uint256"],
313
- [1, amount]
314
- ),
315
- false
316
- ]
320
+ [assets, minimumAmountOut, userTxData, false]
317
321
  ];
318
322
  const exitPoolTx = iBalancerV2Vault.encodeFunctionData("exitPool", txData);
319
323
  return exitPoolTx;
@@ -0,0 +1,54 @@
1
+ import { Dhedge } from "..";
2
+ import { Dapp, Network } from "../types";
3
+ import { TEST_POOL, USDC, WETH } from "./constants";
4
+ import { getTxOptions } from "./txOptions";
5
+
6
+ import { wallet } from "./wallet";
7
+
8
+ let dhedge: Dhedge;
9
+ let options: any;
10
+
11
+ jest.setTimeout(100000);
12
+
13
+ describe("pool", () => {
14
+ beforeAll(async () => {
15
+ dhedge = new Dhedge(wallet, Network.OPTIMISM);
16
+ options = await getTxOptions(Network.OPTIMISM);
17
+ });
18
+
19
+ // it("approves unlimited USDC on 1Inch", async () => {
20
+ // let result;
21
+ // const pool = await dhedge.loadPool(TEST_POOL);
22
+ // try {
23
+ // result = await pool.approve(
24
+ // Dapp.ONEINCH,
25
+ // USDC,
26
+ // ethers.constants.MaxInt256,
27
+ // options
28
+ // );
29
+ // console.log(result);
30
+ // } catch (e) {
31
+ // console.log(e);
32
+ // }
33
+ // expect(result).not.toBe(null);
34
+ // });
35
+
36
+ it("trades 1 USDC into WETH on 1Inch", async () => {
37
+ let result;
38
+ const pool = await dhedge.loadPool(TEST_POOL);
39
+ try {
40
+ result = await pool.trade(
41
+ Dapp.ONEINCH,
42
+ USDC,
43
+ WETH,
44
+ "1000000",
45
+ 0.5,
46
+ options
47
+ );
48
+ console.log(result);
49
+ } catch (e) {
50
+ console.log(e);
51
+ }
52
+ expect(result).not.toBe(null);
53
+ });
54
+ });
@@ -14,7 +14,7 @@ jest.setTimeout(100000);
14
14
  describe("pool", () => {
15
15
  beforeAll(async () => {
16
16
  dhedge = new Dhedge(wallet, Network.POLYGON);
17
- options = await getTxOptions();
17
+ options = await getTxOptions(Network.POLYGON);
18
18
  });
19
19
 
20
20
  // it("approves unlimited WETH on Arrakis", async () => {
@@ -69,7 +69,7 @@ describe("pool", () => {
69
69
  const result = await pool.decreaseLiquidity(
70
70
  Dapp.ARRAKIS,
71
71
  ARRAKIS_USDC_WETH_GAUGE,
72
- 100,
72
+ 50.6576575755,
73
73
  options
74
74
  );
75
75
  console.log("result", result);