@dhedge/v2-sdk 1.1.1 → 1.2.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.
Files changed (42) hide show
  1. package/README.md +60 -3
  2. package/dist/config.d.ts +2 -0
  3. package/dist/entities/pool.d.ts +32 -0
  4. package/dist/entities/utils.d.ts +4 -0
  5. package/dist/services/claim-balancer/claim.service.d.ts +21 -0
  6. package/dist/services/claim-balancer/claim.worker.d.ts +4 -0
  7. package/dist/services/claim-balancer/ipfs.service.d.ts +4 -0
  8. package/dist/services/claim-balancer/types.d.ts +54 -0
  9. package/dist/test/constants.d.ts +12 -0
  10. package/dist/types.d.ts +5 -2
  11. package/dist/utils/contract.d.ts +14 -0
  12. package/dist/utils/index.d.ts +7 -0
  13. package/dist/utils/merkle.d.ts +22 -0
  14. package/dist/v2-sdk.cjs.development.js +3623 -672
  15. package/dist/v2-sdk.cjs.development.js.map +1 -1
  16. package/dist/v2-sdk.cjs.production.min.js +1 -1
  17. package/dist/v2-sdk.cjs.production.min.js.map +1 -1
  18. package/dist/v2-sdk.esm.js +3623 -672
  19. package/dist/v2-sdk.esm.js.map +1 -1
  20. package/package.json +9 -2
  21. package/src/abi/IAaveIncentivesController.json +50 -0
  22. package/src/abi/IBalancerMerkleOrchard.json +353 -0
  23. package/src/abi/IBalancertV2Vault.json +938 -0
  24. package/src/config.ts +16 -3
  25. package/src/entities/pool.ts +140 -1
  26. package/src/entities/utils.ts +135 -0
  27. package/src/services/claim-balancer/MultiTokenClaim.json +115 -0
  28. package/src/services/claim-balancer/claim.service.ts +324 -0
  29. package/src/services/claim-balancer/claim.worker.ts +32 -0
  30. package/src/services/claim-balancer/ipfs.service.ts +12 -0
  31. package/src/services/claim-balancer/types.ts +66 -0
  32. package/src/test/aave.test.ts +73 -0
  33. package/src/test/balancer.test.ts +109 -0
  34. package/src/test/constants.ts +13 -0
  35. package/src/test/oneInch.test.ts +56 -0
  36. package/src/test/pool.test.ts +5 -249
  37. package/src/test/sushi.test.ts +173 -0
  38. package/src/test/utils.test.ts +41 -26
  39. package/src/types.ts +6 -3
  40. package/src/utils/contract.ts +95 -0
  41. package/src/utils/index.ts +38 -0
  42. package/src/utils/merkle.ts +172 -0
package/src/config.ts CHANGED
@@ -9,14 +9,16 @@ import { NetworkChainIdMap } from ".";
9
9
 
10
10
  export const factoryAddress: AddressNetworkMap = {
11
11
  [Network.POLYGON]: "0xfdc7b8bFe0DD3513Cc669bB8d601Cb83e2F69cB0"
12
+ //[Network.POLYGON]: "0xDd87eCdB10cFF7004276AAbAbd30e7a08F69bb53"
12
13
  };
13
14
 
14
15
  export const routerAddress: AddressDappNetworkMap = {
15
16
  [Network.POLYGON]: {
16
17
  [Dapp.SUSHISWAP]: "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506",
17
18
  [Dapp.AAVE]: "0x8dFf5E27EA6b7AC08EbFdf9eB090F32ee9a30fcf",
18
- [Dapp.ONEINCH]: "0x1111111254fb6c44bAC0beD2854e76F90643097d",
19
- [Dapp.QUICKSWAP]: "0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff"
19
+ [Dapp.ONEINCH]: "0x1111111254fb6c44bac0bed2854e76f90643097d",
20
+ [Dapp.QUICKSWAP]: "0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff",
21
+ [Dapp.BALANCER]: "0xBA12222222228d8Ba445958a75a0704d566BF2C8"
20
22
  }
21
23
  };
22
24
 
@@ -29,10 +31,21 @@ export const dappFactoryAddress: AddressDappNetworkMap = {
29
31
 
30
32
  export const stakingAddress: AddressDappNetworkMap = {
31
33
  [Network.POLYGON]: {
32
- [Dapp.SUSHISWAP]: "0x0769fd68dFb93167989C6f7254cd0D766Fb2841F"
34
+ [Dapp.SUSHISWAP]: "0x0769fd68dFb93167989C6f7254cd0D766Fb2841F",
35
+ [Dapp.BALANCER]: "0x0F3e0c4218b7b0108a3643cFe9D3ec0d4F57c54e",
36
+ [Dapp.AAVE]: "0x357D51124f59836DeD84c8a1730D72B749d8BC23"
33
37
  }
34
38
  };
35
39
 
36
40
  export const networkChainIdMap: NetworkChainIdMap = {
37
41
  [Network.POLYGON]: ChainId.MATIC
38
42
  };
43
+
44
+ export const balancerSubgraph: AddressNetworkMap = {
45
+ [Network.POLYGON]:
46
+ "https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-polygon-v2"
47
+ };
48
+
49
+ export const multiCallAddress: AddressNetworkMap = {
50
+ [Network.POLYGON]: "0x275617327c958bD06b5D6b871E7f491D76113dd8"
51
+ };
@@ -7,6 +7,8 @@ import IERC20 from "../abi/IERC20.json";
7
7
  import IMiniChefV2 from "../abi/IMiniChefV2.json";
8
8
  import ILendingPool from "../abi/ILendingPool.json";
9
9
  import IUniswapV2Router from "../abi/IUniswapV2Router.json";
10
+ import IBalancerMerkleOrchard from "../abi/IBalancerMerkleOrchard.json";
11
+ import IAaveIncentivesController from "../abi/IAaveIncentivesController.json";
10
12
  import { routerAddress, stakingAddress } from "../config";
11
13
  import {
12
14
  Dapp,
@@ -17,6 +19,7 @@ import {
17
19
  } from "../types";
18
20
 
19
21
  import { Utils } from "./utils";
22
+ import { ClaimService } from "../services/claim-balancer/claim.service";
20
23
 
21
24
  export class Pool {
22
25
  public readonly poolLogic: Contract;
@@ -194,6 +197,14 @@ export class Pool {
194
197
  }&slippage=${slippage.toString()}&disableEstimate=true`;
195
198
  const response = await axios.get(apiUrl);
196
199
  swapTxData = response.data.tx.data;
200
+ } else if (dapp === Dapp.BALANCER) {
201
+ swapTxData = await this.utils.getBalancerSwapTx(
202
+ this,
203
+ assetFrom,
204
+ assetTo,
205
+ amountIn,
206
+ slippage
207
+ );
197
208
  } else {
198
209
  const iUniswapV2Router = new ethers.utils.Interface(IUniswapV2Router.abi);
199
210
  const minAmountOut = await this.utils.getMinAmountOut(
@@ -342,7 +353,7 @@ export class Pool {
342
353
  ): Promise<any> {
343
354
  const iMiniChefV2 = new ethers.utils.Interface(IMiniChefV2.abi);
344
355
  const poolId = await this.utils.getLpPoolId(dapp, asset);
345
- const unStakeTxData = iMiniChefV2.encodeFunctionData(Transaction.UNSTAKE, [
356
+ const unStakeTxData = iMiniChefV2.encodeFunctionData(Transaction.WITHDRAW, [
346
357
  poolId,
347
358
  amount,
348
359
  this.address
@@ -531,4 +542,132 @@ export class Pool {
531
542
  const tx = await this.managerLogic.setTrader(trader, options);
532
543
  return tx;
533
544
  }
545
+
546
+ /**
547
+ * Invest into a Balancer pool
548
+ * @param {string} poolId Balancer pool id
549
+ * @param {string[] | } assetsIn Array of balancer pool assets
550
+ * @param {BigNumber[] | string[]} amountsIn Array of maximum amounts to provide to pool
551
+ * @param {any} options Transaction options
552
+ * @returns {Promise<any>} Transaction
553
+ */
554
+ async joinBalancerPool(
555
+ poolId: string,
556
+ assets: string[],
557
+ amountsIn: string[] | BigNumber[],
558
+ options: any = null
559
+ ): Promise<any> {
560
+ const joinPoolTxData = this.utils.getBalancerJoinPoolTx(
561
+ this,
562
+ poolId,
563
+ assets,
564
+ amountsIn
565
+ );
566
+ const tx = await this.poolLogic.execTransaction(
567
+ routerAddress[this.network][Dapp.BALANCER],
568
+ joinPoolTxData,
569
+ options
570
+ );
571
+ return tx;
572
+ }
573
+
574
+ /**
575
+ * Invest into a Balancer pool
576
+ * @param {string} poolId Balancer pool id
577
+ * @param {string[] | } assets Array of balancer pool assets
578
+ * @param {BigNumber | string } amount Amount of pool tokens to withdraw
579
+ * @param {any} options Transaction options
580
+ * @returns {Promise<any>} Transaction
581
+ */
582
+ async exitBalancerPool(
583
+ poolId: string,
584
+ assets: string[],
585
+ amount: string | BigNumber,
586
+ options: any = null
587
+ ): Promise<any> {
588
+ const exitPoolTxData = this.utils.getBalancerExitPoolTx(
589
+ this,
590
+ poolId,
591
+ assets,
592
+ amount
593
+ );
594
+ const tx = await this.poolLogic.execTransaction(
595
+ routerAddress[this.network][Dapp.BALANCER],
596
+ exitPoolTxData,
597
+ options
598
+ );
599
+ return tx;
600
+ }
601
+
602
+ /**
603
+ * Claim rewards from Balancer pools
604
+ * @param {string[]} assets Array of tokens being claimed
605
+ * @param {any} options Transaction options
606
+ * @returns {Promise<any>} Transaction
607
+ */
608
+ async harvestBalancerRewards(options: any = null): Promise<any> {
609
+ const claimService = new ClaimService(this.network, this.signer);
610
+ const multiTokenPendingClaims = await claimService.getMultiTokensPendingClaims(
611
+ this.address
612
+ );
613
+ const tokens = multiTokenPendingClaims.map(
614
+ tokenPendingClaims => tokenPendingClaims.tokenClaimInfo.token
615
+ );
616
+ const claims = await claimService.multiTokenClaimRewards(
617
+ this.address,
618
+ multiTokenPendingClaims
619
+ );
620
+ const iBalancerMerkleOrchard = new ethers.utils.Interface(
621
+ IBalancerMerkleOrchard.abi
622
+ );
623
+ const harvestTxData = iBalancerMerkleOrchard.encodeFunctionData(
624
+ Transaction.CLAIM_DISTRIBIUTIONS,
625
+ [this.address, claims, tokens]
626
+ );
627
+ const tx = await this.poolLogic.execTransaction(
628
+ stakingAddress[this.network][Dapp.BALANCER],
629
+ harvestTxData,
630
+ options
631
+ );
632
+ return tx;
633
+ }
634
+
635
+ /**
636
+ * Claim rewards from Aave platform
637
+ * @param {string[]} assets Aave tokens (deposit/debt) hold by pool
638
+ * @param {any} options Transaction options
639
+ * @returns {Promise<any>} Transaction
640
+ */
641
+ async harvestAaveRewards(
642
+ assets: string[],
643
+ options: any = null
644
+ ): Promise<any> {
645
+ const aaveIncentivesAddress = stakingAddress[this.network][
646
+ Dapp.AAVE
647
+ ] as string;
648
+ const iAaveIncentivesController = new ethers.utils.Interface(
649
+ IAaveIncentivesController.abi
650
+ );
651
+ const aaveIncentivesController = new ethers.Contract(
652
+ aaveIncentivesAddress,
653
+ iAaveIncentivesController,
654
+ this.signer
655
+ );
656
+
657
+ const amount = await aaveIncentivesController.getUserUnclaimedRewards(
658
+ this.address
659
+ );
660
+
661
+ const claimTxData = iAaveIncentivesController.encodeFunctionData(
662
+ Transaction.CLAIM_REWARDS,
663
+ [assets, amount, this.address]
664
+ );
665
+
666
+ const tx = await this.poolLogic.execTransaction(
667
+ aaveIncentivesAddress,
668
+ claimTxData,
669
+ options
670
+ );
671
+ return tx;
672
+ }
534
673
  }
@@ -8,17 +8,22 @@ import {
8
8
  Trade,
9
9
  Percent
10
10
  } from "@sushiswap/sdk";
11
+ import { SOR, SwapTypes } from "@balancer-labs/sor";
12
+ import { BaseProvider } from "@ethersproject/providers";
11
13
 
12
14
  import IERC20 from "../abi/IERC20.json";
13
15
  import IMiniChefV2 from "../abi/IMiniChefV2.json";
14
16
  import UniswapV2Factory from "../abi/IUniswapV2Factory.json";
15
17
  import UniswapV2Pair from "../abi/IUniswapV2Pair.json";
18
+ import IBalancerV2Vault from "../abi/IBalancertV2Vault.json";
16
19
  import {
20
+ balancerSubgraph,
17
21
  dappFactoryAddress,
18
22
  networkChainIdMap,
19
23
  stakingAddress
20
24
  } from "../config";
21
25
  import { Dapp, Network, Reserves } from "../types";
26
+ import { Pool } from ".";
22
27
 
23
28
  export class Utils {
24
29
  network: Network;
@@ -171,4 +176,134 @@ export class Utils {
171
176
  .raw.toString()
172
177
  );
173
178
  }
179
+
180
+ async getBalancerSwapTx(
181
+ pool: Pool,
182
+ assetFrom: string,
183
+ assetTo: string,
184
+ amountIn: ethers.BigNumber | string,
185
+ slippage: number
186
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
187
+ ): Promise<any> {
188
+ const sor = new SOR(
189
+ this.signer.provider as BaseProvider,
190
+ networkChainIdMap[this.network],
191
+ balancerSubgraph[this.network]
192
+ );
193
+ // isFetched will be true on success
194
+ const isFetched = await sor.fetchPools();
195
+
196
+ if (!isFetched) throw new Error("Error fetching balancer pools");
197
+
198
+ const swapType = SwapTypes.SwapExactIn;
199
+ const { swaps, tokenAddresses, returnAmount } = await sor.getSwaps(
200
+ assetFrom,
201
+ assetTo,
202
+ swapType,
203
+ ethers.BigNumber.from(amountIn)
204
+ );
205
+
206
+ const minimumAmountOut = returnAmount
207
+ .mul(10000 - slippage * 100)
208
+ .div(10000);
209
+
210
+ const iBalancerV2Vault = new ethers.utils.Interface(IBalancerV2Vault.abi);
211
+
212
+ if (swaps.length === 1) {
213
+ const swap = swaps[0];
214
+ //do single swap
215
+ const swapTx = iBalancerV2Vault.encodeFunctionData("swap", [
216
+ [
217
+ swap.poolId,
218
+ SwapTypes.SwapExactIn,
219
+ tokenAddresses[swap.assetInIndex],
220
+ tokenAddresses[swap.assetOutIndex],
221
+ swap.amount,
222
+ swap.userData
223
+ ],
224
+ [pool.address, false, pool.address, false],
225
+ minimumAmountOut,
226
+ Math.floor(Date.now() / 1000) + 60 * 20 // 20 minutes from the current Unix time
227
+ ]);
228
+ return swapTx;
229
+ } else {
230
+ // Limits:
231
+ // +ve means max to send
232
+ // -ve mean min to receive
233
+ // For a multihop the intermediate tokens should be 0
234
+ const limits: string[] = [];
235
+ tokenAddresses.forEach((token, i) => {
236
+ if (token.toLowerCase() === assetFrom.toLowerCase()) {
237
+ limits[i] = amountIn.toString();
238
+ } else if (token.toLowerCase() === assetTo.toLowerCase()) {
239
+ limits[i] = minimumAmountOut.mul(-1).toString();
240
+ } else {
241
+ limits[i] = "0";
242
+ }
243
+ });
244
+ const swapTx = iBalancerV2Vault.encodeFunctionData("batchSwap", [
245
+ SwapTypes.SwapExactIn,
246
+ swaps,
247
+ tokenAddresses,
248
+ [pool.address, false, pool.address, false],
249
+ limits,
250
+ Math.floor(Date.now() / 1000) + 60 * 20 // 20 minutes from the current Unix time
251
+ ]);
252
+ return swapTx;
253
+ }
254
+ }
255
+
256
+ async getBalancerJoinPoolTx(
257
+ pool: Pool,
258
+ balancerPoolId: string,
259
+ assets: string[],
260
+ amountsIn: string[] | ethers.BigNumber[]
261
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
262
+ ): Promise<any> {
263
+ const iBalancerV2Vault = new ethers.utils.Interface(IBalancerV2Vault.abi);
264
+ const txData = [
265
+ balancerPoolId,
266
+ pool.address,
267
+ pool.address,
268
+ [
269
+ assets,
270
+ amountsIn,
271
+ ethers.utils.defaultAbiCoder.encode(
272
+ ["uint256", "uint256[]", "uint256"],
273
+ [1, amountsIn, 0]
274
+ ),
275
+ false
276
+ ]
277
+ ];
278
+ const joinPoolTx = iBalancerV2Vault.encodeFunctionData("joinPool", txData);
279
+ return joinPoolTx;
280
+ }
281
+
282
+ async getBalancerExitPoolTx(
283
+ pool: Pool,
284
+ balancerPoolId: string,
285
+ assets: string[],
286
+ amount: string | ethers.BigNumber
287
+
288
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
289
+ ): Promise<any> {
290
+ const minimumAmountOut = new Array(assets.length).fill(0);
291
+ const iBalancerV2Vault = new ethers.utils.Interface(IBalancerV2Vault.abi);
292
+ const txData = [
293
+ balancerPoolId,
294
+ pool.address,
295
+ pool.address,
296
+ [
297
+ assets,
298
+ minimumAmountOut,
299
+ ethers.utils.defaultAbiCoder.encode(
300
+ ["uint256", "uint256"],
301
+ [1, amount]
302
+ ),
303
+ false
304
+ ]
305
+ ];
306
+ const exitPoolTx = iBalancerV2Vault.encodeFunctionData("exitPool", txData);
307
+ return exitPoolTx;
308
+ }
174
309
  }
@@ -0,0 +1,115 @@
1
+ {
2
+ "1": [
3
+ {
4
+ "label": "BAL",
5
+ "distributor": "0xd2EB7Bd802A7CA68d9AcD209bEc4E664A9abDD7b",
6
+ "token": "0xba100000625a3754423978a60c9317c58a424e3d",
7
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current.json",
8
+ "weekStart": 52
9
+ },
10
+ {
11
+ "label": "UNN",
12
+ "distributor": "0xBfbd6e720ffdF0497f69C95E5C03a4861C65A6E7",
13
+ "token": "0x226f7b842E0F0120b7E194D05432b3fd14773a9D",
14
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-union.json",
15
+ "weekStart": 1
16
+ },
17
+ {
18
+ "label": "BANK",
19
+ "distributor": "0x9d20FE66eC5Dd15a3D3213556534C77cA20318bE",
20
+ "token": "0x2d94AA3e47d9D5024503Ca8491fcE9A2fB4DA198",
21
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-bankless.json",
22
+ "weekStart": 1
23
+ },
24
+ {
25
+ "label": "NOTE",
26
+ "distributor": "0xF1C2dD9bD863f2444086B739383F1043E6b88F69",
27
+ "token": "0xcfeaead4947f0705a14ec42ac3d44129e1ef3ed5",
28
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-note.json",
29
+ "weekStart": 1
30
+ },
31
+ {
32
+ "label": "NEXO",
33
+ "distributor": "0x0000000000000000000000000000000000000000",
34
+ "token": "0xB62132e35a6c13ee1EE0f84dC5d40bad8d815206",
35
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-nexo.json",
36
+ "weekStart": 1
37
+ }
38
+ ],
39
+ "42": [
40
+ {
41
+ "label": "BAL",
42
+ "distributor": "0x95FaE1C936B4Cd6c5099d7A705D792ee6aC9FEc3",
43
+ "token": "0x41286Bb1D3E870f3F750eB7E1C25d7E48c8A1Ac7",
44
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/sample-tree/reports-kovan/_current.json",
45
+ "weekStart": 52
46
+ },
47
+ {
48
+ "label": "DAI",
49
+ "distributor": "0x95FaE1C936B4Cd6c5099d7A705D792ee6aC9FEc3",
50
+ "token": "0x04DF6e4121c27713ED22341E7c7Df330F56f289B",
51
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/sample-tree/reports-kovan/_current-dai.json",
52
+ "weekStart": 1
53
+ }
54
+ ],
55
+ "137": [
56
+ {
57
+ "label": "BAL",
58
+ "distributor": "0xd2EB7Bd802A7CA68d9AcD209bEc4E664A9abDD7b",
59
+ "token": "0x9a71012b13ca4d3d0cdc72a177df3ef03b0e76a3",
60
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-polygon.json",
61
+ "weekStart": 1
62
+ },
63
+ {
64
+ "label": "WMATIC",
65
+ "distributor": "0x087A7AFB6975A2837453BE685EB6272576c0bC06",
66
+ "token": "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270",
67
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-wmatic-polygon.json",
68
+ "weekStart": 1
69
+ },
70
+ {
71
+ "label": "WMATIC",
72
+ "distributor": "0xBd44C01EC7d623372B4572247afB6231eDD8486F",
73
+ "token": "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270",
74
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-wmatic-polygon.json",
75
+ "weekStart": 4
76
+ },
77
+ {
78
+ "label": "WMATIC",
79
+ "distributor": "0x632208491602Dd205da8Cb9C0BA98620fc19854A",
80
+ "token": "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270",
81
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-wmatic-polygon.json",
82
+ "weekStart": 5
83
+ },
84
+ {
85
+ "label": "TUSD",
86
+ "distributor": "0x09f3010ec0f6d72ef8ff2008f8e756d60482c9a8",
87
+ "token": "0x2e1ad108ff1d8c782fcbbb89aad783ac49586756",
88
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-tusd-polygon.json",
89
+ "weekStart": 1
90
+ }
91
+ ],
92
+ "42161": [
93
+ {
94
+ "label": "BAL",
95
+ "distributor": "0xd2EB7Bd802A7CA68d9AcD209bEc4E664A9abDD7b",
96
+ "token": "0x040d1EdC9569d4Bab2D15287Dc5A4F10F56a56B8",
97
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-arbitrum.json",
98
+ "weekStart": 6
99
+ },
100
+ {
101
+ "label": "MCB",
102
+ "distributor": "0x25c646adf184051b35a405b9aaeba321e8d5342a",
103
+ "token": "0x4e352cf164e64adcbad318c3a1e222e9eba4ce42",
104
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-mcdex-arbitrum.json",
105
+ "weekStart": 4
106
+ },
107
+ {
108
+ "label": "PICKLE",
109
+ "distributor": "0xf02CeB58d549E4b403e8F85FBBaEe4c5dfA47c01",
110
+ "token": "0x965772e0e9c84b6f359c8597c891108dcf1c5b1a",
111
+ "manifest": "https://raw.githubusercontent.com/balancer-labs/bal-mining-scripts/master/reports/_current-pickle-arbitrum.json",
112
+ "weekStart": 4
113
+ }
114
+ ]
115
+ }