@dhedge/v2-sdk 1.1.0 → 1.2.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.
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 +37 -3
  4. package/dist/entities/utils.d.ts +4 -0
  5. package/dist/services/claim-balancer/claim.service.d.ts +17 -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 +3497 -690
  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 +3497 -690
  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 +21 -4
  25. package/src/entities/pool.ts +148 -5
  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 +262 -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 -244
  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
@@ -7,16 +7,22 @@ import {
7
7
  import { ChainId } from "@sushiswap/sdk";
8
8
  import { NetworkChainIdMap } from ".";
9
9
 
10
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
11
+ require("dotenv").config();
12
+
10
13
  export const factoryAddress: AddressNetworkMap = {
11
- [Network.POLYGON]: "0xfdc7b8bFe0DD3513Cc669bB8d601Cb83e2F69cB0"
14
+ [Network.POLYGON]: process.env.STAGING_CONTRACTS
15
+ ? "0xDd87eCdB10cFF7004276AAbAbd30e7a08F69bb53"
16
+ : "0xfdc7b8bFe0DD3513Cc669bB8d601Cb83e2F69cB0"
12
17
  };
13
18
 
14
19
  export const routerAddress: AddressDappNetworkMap = {
15
20
  [Network.POLYGON]: {
16
21
  [Dapp.SUSHISWAP]: "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506",
17
22
  [Dapp.AAVE]: "0x8dFf5E27EA6b7AC08EbFdf9eB090F32ee9a30fcf",
18
- [Dapp.ONEINCH]: "0x11111112542D85B3EF69AE05771c2dCCff4fAa26",
19
- [Dapp.QUICKSWAP]: "0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff"
23
+ [Dapp.ONEINCH]: "0x1111111254fb6c44bac0bed2854e76f90643097d",
24
+ [Dapp.QUICKSWAP]: "0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff",
25
+ [Dapp.BALANCER]: "0xBA12222222228d8Ba445958a75a0704d566BF2C8"
20
26
  }
21
27
  };
22
28
 
@@ -29,10 +35,21 @@ export const dappFactoryAddress: AddressDappNetworkMap = {
29
35
 
30
36
  export const stakingAddress: AddressDappNetworkMap = {
31
37
  [Network.POLYGON]: {
32
- [Dapp.SUSHISWAP]: "0x0769fd68dFb93167989C6f7254cd0D766Fb2841F"
38
+ [Dapp.SUSHISWAP]: "0x0769fd68dFb93167989C6f7254cd0D766Fb2841F",
39
+ [Dapp.BALANCER]: "0x0F3e0c4218b7b0108a3643cFe9D3ec0d4F57c54e",
40
+ [Dapp.AAVE]: "0x357D51124f59836DeD84c8a1730D72B749d8BC23"
33
41
  }
34
42
  };
35
43
 
36
44
  export const networkChainIdMap: NetworkChainIdMap = {
37
45
  [Network.POLYGON]: ChainId.MATIC
38
46
  };
47
+
48
+ export const balancerSubgraph: AddressNetworkMap = {
49
+ [Network.POLYGON]:
50
+ "https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-polygon-v2"
51
+ };
52
+
53
+ export const multiCallAddress: AddressNetworkMap = {
54
+ [Network.POLYGON]: "0x275617327c958bD06b5D6b871E7f491D76113dd8"
55
+ };
@@ -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;
@@ -187,13 +190,21 @@ export class Pool {
187
190
  ): Promise<any> {
188
191
  let swapTxData: string;
189
192
  if (dapp === Dapp.ONEINCH) {
190
- const apiUrl = `https://api.1inch.exchange/v3.0/137/swap?fromTokenAddress=${assetFrom}&toTokenAddress=${assetTo}&amount=${amountIn.toString()}&fromAddress=${
193
+ const apiUrl = `https://api.1inch.exchange/v4.0/137/swap?fromTokenAddress=${assetFrom}&toTokenAddress=${assetTo}&amount=${amountIn.toString()}&fromAddress=${
191
194
  this.address
192
195
  }&destReceiver=${
193
196
  this.address
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
@@ -359,7 +370,8 @@ export class Pool {
359
370
  * Lend asset to a lending pool
360
371
  * @param {Dapp} dapp Platform like Aave
361
372
  * @param {string} asset Asset
362
- * @param {BigNumber | string} amount Amount of asset to lend
373
+ * @param {BigNumber | string} amount Amount of asset to lend
374
+ * @param {number} referrralCode Code from Aave referral program
363
375
  * @param {any} options Transaction options
364
376
  * @returns {Promise<any>} Transaction
365
377
  */
@@ -367,6 +379,7 @@ export class Pool {
367
379
  dapp: Dapp,
368
380
  asset: string,
369
381
  amount: BigNumber | string,
382
+ referrralCode = 0,
370
383
  options: any = null
371
384
  ): Promise<any> {
372
385
  const iLendingPool = new ethers.utils.Interface(ILendingPool.abi);
@@ -374,7 +387,7 @@ export class Pool {
374
387
  asset,
375
388
  amount,
376
389
  this.address,
377
- 0
390
+ referrralCode
378
391
  ]);
379
392
  const tx = await this.poolLogic.execTransaction(
380
393
  routerAddress[this.network][dapp],
@@ -416,6 +429,7 @@ export class Pool {
416
429
  * @param {Dapp} dapp Platform like Aave
417
430
  * @param {string} asset Asset
418
431
  * @param {BigNumber | string} amount Amount of asset to lend
432
+ * @param {number} referrralCode Code from Aave referral program
419
433
  * @param {any} options Transaction options
420
434
  * @returns {Promise<any>} Transaction
421
435
  */
@@ -423,6 +437,7 @@ export class Pool {
423
437
  dapp: Dapp,
424
438
  asset: string,
425
439
  amount: BigNumber | string,
440
+ referrralCode = 0,
426
441
  options: any = null
427
442
  ): Promise<any> {
428
443
  const iLendingPool = new ethers.utils.Interface(ILendingPool.abi);
@@ -430,7 +445,7 @@ export class Pool {
430
445
  asset,
431
446
  amount,
432
447
  2,
433
- 0,
448
+ referrralCode,
434
449
  this.address
435
450
  ]);
436
451
  const tx = await this.poolLogic.execTransaction(
@@ -531,4 +546,132 @@ export class Pool {
531
546
  const tx = await this.managerLogic.setTrader(trader, options);
532
547
  return tx;
533
548
  }
549
+
550
+ /**
551
+ * Invest into a Balancer pool
552
+ * @param {string} poolId Balancer pool id
553
+ * @param {string[] | } assetsIn Array of balancer pool assets
554
+ * @param {BigNumber[] | string[]} amountsIn Array of maximum amounts to provide to pool
555
+ * @param {any} options Transaction options
556
+ * @returns {Promise<any>} Transaction
557
+ */
558
+ async joinBalancerPool(
559
+ poolId: string,
560
+ assets: string[],
561
+ amountsIn: string[] | BigNumber[],
562
+ options: any = null
563
+ ): Promise<any> {
564
+ const joinPoolTxData = this.utils.getBalancerJoinPoolTx(
565
+ this,
566
+ poolId,
567
+ assets,
568
+ amountsIn
569
+ );
570
+ const tx = await this.poolLogic.execTransaction(
571
+ routerAddress[this.network][Dapp.BALANCER],
572
+ joinPoolTxData,
573
+ options
574
+ );
575
+ return tx;
576
+ }
577
+
578
+ /**
579
+ * Invest into a Balancer pool
580
+ * @param {string} poolId Balancer pool id
581
+ * @param {string[] | } assets Array of balancer pool assets
582
+ * @param {BigNumber | string } amount Amount of pool tokens to withdraw
583
+ * @param {any} options Transaction options
584
+ * @returns {Promise<any>} Transaction
585
+ */
586
+ async exitBalancerPool(
587
+ poolId: string,
588
+ assets: string[],
589
+ amount: string | BigNumber,
590
+ options: any = null
591
+ ): Promise<any> {
592
+ const exitPoolTxData = this.utils.getBalancerExitPoolTx(
593
+ this,
594
+ poolId,
595
+ assets,
596
+ amount
597
+ );
598
+ const tx = await this.poolLogic.execTransaction(
599
+ routerAddress[this.network][Dapp.BALANCER],
600
+ exitPoolTxData,
601
+ options
602
+ );
603
+ return tx;
604
+ }
605
+
606
+ /**
607
+ * Claim rewards from Balancer pools
608
+ * @param {string[]} assets Array of tokens being claimed
609
+ * @param {any} options Transaction options
610
+ * @returns {Promise<any>} Transaction
611
+ */
612
+ async harvestBalancerRewards(options: any = null): Promise<any> {
613
+ const claimService = new ClaimService(this.network, this.signer);
614
+ const multiTokenPendingClaims = await claimService.getMultiTokensPendingClaims(
615
+ this.address
616
+ );
617
+ const tokens = multiTokenPendingClaims.map(
618
+ tokenPendingClaims => tokenPendingClaims.tokenClaimInfo.token
619
+ );
620
+ const claims = await claimService.multiTokenClaimRewards(
621
+ this.address,
622
+ multiTokenPendingClaims
623
+ );
624
+ const iBalancerMerkleOrchard = new ethers.utils.Interface(
625
+ IBalancerMerkleOrchard.abi
626
+ );
627
+ const harvestTxData = iBalancerMerkleOrchard.encodeFunctionData(
628
+ Transaction.CLAIM_DISTRIBIUTIONS,
629
+ [this.address, claims, tokens]
630
+ );
631
+ const tx = await this.poolLogic.execTransaction(
632
+ stakingAddress[this.network][Dapp.BALANCER],
633
+ harvestTxData,
634
+ options
635
+ );
636
+ return tx;
637
+ }
638
+
639
+ /**
640
+ * Claim rewards from Aave platform
641
+ * @param {string[]} assets Aave tokens (deposit/debt) hold by pool
642
+ * @param {any} options Transaction options
643
+ * @returns {Promise<any>} Transaction
644
+ */
645
+ async harvestAaveRewards(
646
+ assets: string[],
647
+ options: any = null
648
+ ): Promise<any> {
649
+ const aaveIncentivesAddress = stakingAddress[this.network][
650
+ Dapp.AAVE
651
+ ] as string;
652
+ const iAaveIncentivesController = new ethers.utils.Interface(
653
+ IAaveIncentivesController.abi
654
+ );
655
+ const aaveIncentivesController = new ethers.Contract(
656
+ aaveIncentivesAddress,
657
+ iAaveIncentivesController,
658
+ this.signer
659
+ );
660
+
661
+ const amount = await aaveIncentivesController.getUserUnclaimedRewards(
662
+ this.address
663
+ );
664
+
665
+ const claimTxData = iAaveIncentivesController.encodeFunctionData(
666
+ Transaction.CLAIM_REWARDS,
667
+ [assets, amount, this.address]
668
+ );
669
+
670
+ const tx = await this.poolLogic.execTransaction(
671
+ aaveIncentivesAddress,
672
+ claimTxData,
673
+ options
674
+ );
675
+ return tx;
676
+ }
534
677
  }
@@ -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
+ }