@curvefi/api 2.3.2 → 2.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.
@@ -67,16 +67,22 @@ var external_api_1 = require("../external-api");
67
67
  var utils_1 = require("../utils");
68
68
  var curve_1 = require("../curve");
69
69
  var ERC20_json_1 = __importDefault(require("../constants/abis/ERC20.json"));
70
+ var DAY = 86400;
71
+ var WEEK = 7 * DAY;
72
+ var MONTH = 30 * DAY;
73
+ var YEAR = 365 * DAY;
70
74
  var PoolTemplate = /** @class */ (function () {
71
75
  function PoolTemplate(id) {
72
76
  var _this = this;
73
77
  this.statsParameters = function () { return __awaiter(_this, void 0, void 0, function () {
74
- var multicallContract, calls, additionalCalls, _a, _virtualPrice, _fee, _adminFee, _A, _gamma, _c, virtualPrice, fee, adminFee, A, gamma, A_PRECISION, _d, _future_A, _initial_A, _future_A_time, _initial_A_time, _e, future_A, initial_A, future_A_time, initial_A_time;
78
+ var multicallContract, lpMulticallContract, calls, additionalCalls, _a, _lpTokenSupply, _virtualPrice, _fee, _adminFee, _A, _gamma, _c, lpTokenSupply, virtualPrice, fee, adminFee, A, gamma, A_PRECISION, _d, _future_A, _initial_A, _future_A_time, _initial_A_time, _e, future_A, initial_A, future_A_time, initial_A_time;
75
79
  return __generator(this, function (_f) {
76
80
  switch (_f.label) {
77
81
  case 0:
78
82
  multicallContract = curve_1.curve.contracts[this.address].multicallContract;
83
+ lpMulticallContract = curve_1.curve.contracts[this.lpToken].multicallContract;
79
84
  calls = [
85
+ lpMulticallContract.totalSupply(),
80
86
  multicallContract.get_virtual_price(),
81
87
  multicallContract.fee(),
82
88
  multicallContract.admin_fee(),
@@ -90,14 +96,15 @@ var PoolTemplate = /** @class */ (function () {
90
96
  }
91
97
  return [4 /*yield*/, curve_1.curve.multicallProvider.all(calls)];
92
98
  case 1:
93
- _a = _f.sent(), _virtualPrice = _a[0], _fee = _a[1], _adminFee = _a[2], _A = _a[3], _gamma = _a[4];
99
+ _a = _f.sent(), _lpTokenSupply = _a[0], _virtualPrice = _a[1], _fee = _a[2], _adminFee = _a[3], _A = _a[4], _gamma = _a[5];
94
100
  _c = [
101
+ ethers_1.ethers.utils.formatUnits(_lpTokenSupply),
95
102
  ethers_1.ethers.utils.formatUnits(_virtualPrice),
96
103
  ethers_1.ethers.utils.formatUnits(_fee, 8),
97
104
  ethers_1.ethers.utils.formatUnits(_adminFee.mul(_fee)),
98
105
  ethers_1.ethers.utils.formatUnits(_A, 0),
99
106
  _gamma ? ethers_1.ethers.utils.formatUnits(_gamma) : _gamma,
100
- ], virtualPrice = _c[0], fee = _c[1], adminFee = _c[2], A = _c[3], gamma = _c[4];
107
+ ], lpTokenSupply = _c[0], virtualPrice = _c[1], fee = _c[2], adminFee = _c[3], A = _c[4], gamma = _c[5];
101
108
  A_PRECISION = curve_1.curve.chainId === 1 && ['compound', 'usdt', 'y', 'busd', 'susd', 'pax', 'ren', 'sbtc', 'hbtc', '3pool'].includes(this.id) ? 1 : 100;
102
109
  return [4 /*yield*/, curve_1.curve.multicallProvider.all(additionalCalls)];
103
110
  case 2:
@@ -108,7 +115,7 @@ var PoolTemplate = /** @class */ (function () {
108
115
  _future_A_time ? Number(ethers_1.ethers.utils.formatUnits(_future_A_time, 0)) * 1000 : undefined,
109
116
  _initial_A_time ? Number(ethers_1.ethers.utils.formatUnits(_initial_A_time, 0)) * 1000 : undefined,
110
117
  ], future_A = _e[0], initial_A = _e[1], future_A_time = _e[2], initial_A_time = _e[3];
111
- return [2 /*return*/, { virtualPrice: virtualPrice, fee: fee, adminFee: adminFee, A: A, future_A: future_A, initial_A: initial_A, future_A_time: future_A_time, initial_A_time: initial_A_time, gamma: gamma }];
118
+ return [2 /*return*/, { lpTokenSupply: lpTokenSupply, virtualPrice: virtualPrice, fee: fee, adminFee: adminFee, A: A, future_A: future_A, initial_A: initial_A, future_A_time: future_A_time, initial_A_time: initial_A_time, gamma: gamma }];
112
119
  }
113
120
  });
114
121
  }); };
@@ -313,6 +320,182 @@ var PoolTemplate = /** @class */ (function () {
313
320
  }
314
321
  });
315
322
  }); };
323
+ // ---------------- CRV PROFIT, CLAIM, BOOSTING ----------------
324
+ this.crvProfit = function (address) {
325
+ if (address === void 0) { address = ""; }
326
+ return __awaiter(_this, void 0, void 0, function () {
327
+ var inflationRateBN, workingSupplyBN, workingBalanceBN, gaugeContract, crvContract, currentWeek, _a, gaugeContract, gaugeControllerContract, weightBN, crvPrice, dailyIncome, weeklyIncome, monthlyIncome, annualIncome;
328
+ var _c, _d;
329
+ return __generator(this, function (_e) {
330
+ switch (_e.label) {
331
+ case 0:
332
+ if (this.gauge === ethers_1.ethers.constants.AddressZero)
333
+ throw Error("".concat(this.name, " doesn't have gauge"));
334
+ address = address || curve_1.curve.signerAddress;
335
+ if (!address)
336
+ throw Error("Need to connect wallet or pass address into args");
337
+ if (!(curve_1.curve.chainId !== 1)) return [3 /*break*/, 4];
338
+ gaugeContract = curve_1.curve.contracts[this.gauge].multicallContract;
339
+ crvContract = curve_1.curve.contracts[curve_1.curve.constants.ALIASES.crv].contract;
340
+ currentWeek = Math.floor(Date.now() / 1000 / WEEK);
341
+ return [4 /*yield*/, curve_1.curve.multicallProvider.all([
342
+ gaugeContract.inflation_rate(currentWeek),
343
+ gaugeContract.working_balances(address),
344
+ gaugeContract.working_supply(),
345
+ ])];
346
+ case 1:
347
+ _c = (_e.sent()).map(function (value) { return (0, utils_1.toBN)(value); }), inflationRateBN = _c[0], workingBalanceBN = _c[1], workingSupplyBN = _c[2];
348
+ if (!inflationRateBN.eq(0)) return [3 /*break*/, 3];
349
+ _a = utils_1.toBN;
350
+ return [4 /*yield*/, crvContract.balanceOf(this.gauge, curve_1.curve.constantOptions)];
351
+ case 2:
352
+ inflationRateBN = _a.apply(void 0, [_e.sent()]).div(WEEK);
353
+ _e.label = 3;
354
+ case 3: return [3 /*break*/, 6];
355
+ case 4:
356
+ gaugeContract = curve_1.curve.contracts[this.gauge].multicallContract;
357
+ gaugeControllerContract = curve_1.curve.contracts[curve_1.curve.constants.ALIASES.gauge_controller].multicallContract;
358
+ weightBN = void 0;
359
+ return [4 /*yield*/, curve_1.curve.multicallProvider.all([
360
+ gaugeContract.inflation_rate(),
361
+ gaugeControllerContract.gauge_relative_weight(this.gauge),
362
+ gaugeContract.working_balances(address),
363
+ gaugeContract.working_supply(),
364
+ ])];
365
+ case 5:
366
+ _d = (_e.sent()).map(function (value) { return (0, utils_1.toBN)(value); }), inflationRateBN = _d[0], weightBN = _d[1], workingBalanceBN = _d[2], workingSupplyBN = _d[3];
367
+ inflationRateBN = inflationRateBN.times(weightBN);
368
+ _e.label = 6;
369
+ case 6: return [4 /*yield*/, (0, utils_1._getUsdRate)('CRV')];
370
+ case 7:
371
+ crvPrice = _e.sent();
372
+ if (workingSupplyBN.eq(0))
373
+ return [2 /*return*/, {
374
+ day: "0.0",
375
+ week: "0.0",
376
+ month: "0.0",
377
+ year: "0.0",
378
+ token: curve_1.curve.constants.ALIASES.crv,
379
+ symbol: 'CRV',
380
+ price: crvPrice,
381
+ }];
382
+ dailyIncome = inflationRateBN.times(DAY).times(workingBalanceBN).div(workingSupplyBN);
383
+ weeklyIncome = inflationRateBN.times(WEEK).times(workingBalanceBN).div(workingSupplyBN);
384
+ monthlyIncome = inflationRateBN.times(MONTH).times(workingBalanceBN).div(workingSupplyBN);
385
+ annualIncome = inflationRateBN.times(YEAR).times(workingBalanceBN).div(workingSupplyBN);
386
+ return [2 /*return*/, {
387
+ day: dailyIncome.toString(),
388
+ week: weeklyIncome.toString(),
389
+ month: monthlyIncome.toString(),
390
+ year: annualIncome.toString(),
391
+ token: curve_1.curve.constants.ALIASES.crv,
392
+ symbol: 'CRV',
393
+ price: crvPrice,
394
+ }];
395
+ }
396
+ });
397
+ });
398
+ };
399
+ this.boost = function (address) {
400
+ if (address === void 0) { address = ""; }
401
+ return __awaiter(_this, void 0, void 0, function () {
402
+ var gaugeContract, _a, workingBalanceBN, balanceBN, boostBN;
403
+ return __generator(this, function (_c) {
404
+ switch (_c.label) {
405
+ case 0:
406
+ if (curve_1.curve.chainId !== 1)
407
+ throw Error("Boosting is available only on Ethereum network");
408
+ if (this.gauge === ethers_1.ethers.constants.AddressZero)
409
+ throw Error("".concat(this.name, " doesn't have gauge"));
410
+ address = address || curve_1.curve.signerAddress;
411
+ if (!address)
412
+ throw Error("Need to connect wallet or pass address into args");
413
+ gaugeContract = curve_1.curve.contracts[this.gauge].multicallContract;
414
+ return [4 /*yield*/, curve_1.curve.multicallProvider.all([
415
+ gaugeContract.working_balances(address),
416
+ gaugeContract.balanceOf(address),
417
+ ])];
418
+ case 1:
419
+ _a = (_c.sent()).map(function (value) { return (0, utils_1.toBN)(value); }), workingBalanceBN = _a[0], balanceBN = _a[1];
420
+ boostBN = workingBalanceBN.div(0.4).div(balanceBN);
421
+ return [2 /*return*/, boostBN.toFixed(4).replace(/([0-9])0+$/, '$1')];
422
+ }
423
+ });
424
+ });
425
+ };
426
+ this.currentCrvApy = function (address) {
427
+ if (address === void 0) { address = ""; }
428
+ return __awaiter(_this, void 0, void 0, function () {
429
+ var _a, baseApy, maxApy, boost;
430
+ return __generator(this, function (_c) {
431
+ switch (_c.label) {
432
+ case 0:
433
+ address = address || curve_1.curve.signerAddress;
434
+ if (!address)
435
+ throw Error("Need to connect wallet or pass address into args");
436
+ return [4 /*yield*/, this.statsTokenApy()];
437
+ case 1:
438
+ _a = _c.sent(), baseApy = _a[0], maxApy = _a[1];
439
+ if (curve_1.curve.chainId !== 1)
440
+ return [2 /*return*/, baseApy];
441
+ return [4 /*yield*/, this.boost(address)];
442
+ case 2:
443
+ boost = _c.sent();
444
+ if (boost == "2.5")
445
+ return [2 /*return*/, maxApy];
446
+ if (boost === "NaN")
447
+ return [2 /*return*/, "NaN"];
448
+ return [2 /*return*/, (0, utils_1.BN)(baseApy).times((0, utils_1.BN)(boost)).toFixed(4).replace(/([0-9])0+$/, '$1')];
449
+ }
450
+ });
451
+ });
452
+ };
453
+ this.maxBoostedStake = function () {
454
+ var addresses = [];
455
+ for (var _i = 0; _i < arguments.length; _i++) {
456
+ addresses[_i] = arguments[_i];
457
+ }
458
+ return __awaiter(_this, void 0, void 0, function () {
459
+ var votingEscrowContract, gaugeContract, contractCalls, _response, responseBN, _a, veTotalSupplyBN, gaugeTotalSupplyBN, resultBN, result, _c, _d, entry;
460
+ return __generator(this, function (_e) {
461
+ switch (_e.label) {
462
+ case 0:
463
+ if (curve_1.curve.chainId !== 1)
464
+ throw Error("Boosting is available only on Ethereum network");
465
+ if (this.gauge === ethers_1.ethers.constants.AddressZero)
466
+ throw Error("".concat(this.name, " doesn't have gauge"));
467
+ if (addresses.length == 1 && Array.isArray(addresses[0]))
468
+ addresses = addresses[0];
469
+ if (addresses.length === 0 && curve_1.curve.signerAddress !== '')
470
+ addresses = [curve_1.curve.signerAddress];
471
+ if (addresses.length === 0)
472
+ throw Error("Need to connect wallet or pass addresses into args");
473
+ votingEscrowContract = curve_1.curve.contracts[curve_1.curve.constants.ALIASES.voting_escrow].multicallContract;
474
+ gaugeContract = curve_1.curve.contracts[this.gauge].multicallContract;
475
+ contractCalls = [votingEscrowContract.totalSupply(), gaugeContract.totalSupply()];
476
+ addresses.forEach(function (account) {
477
+ contractCalls.push(votingEscrowContract.balanceOf(account));
478
+ });
479
+ return [4 /*yield*/, curve_1.curve.multicallProvider.all(contractCalls)];
480
+ case 1:
481
+ _response = _e.sent();
482
+ responseBN = _response.map(function (value) { return (0, utils_1.toBN)(value); });
483
+ _a = responseBN.splice(0, 2), veTotalSupplyBN = _a[0], gaugeTotalSupplyBN = _a[1];
484
+ resultBN = {};
485
+ addresses.forEach(function (acct, i) {
486
+ resultBN[acct] = responseBN[i].div(veTotalSupplyBN).times(gaugeTotalSupplyBN);
487
+ });
488
+ result = {};
489
+ for (_c = 0, _d = Object.entries(resultBN); _c < _d.length; _c++) {
490
+ entry = _d[_c];
491
+ result[entry[0]] = (0, utils_1.toStringFromBN)(entry[1]);
492
+ }
493
+ return [2 /*return*/, addresses.length === 1 ? result[addresses[0]] : result];
494
+ }
495
+ });
496
+ });
497
+ };
498
+ // ---------------- REWARDS PROFIT, CLAIM ----------------
316
499
  this.rewardTokens = (0, memoizee_1.default)(function () { return __awaiter(_this, void 0, void 0, function () {
317
500
  var gaugeContract, gaugeMulticallContract, rewardCount, _a, _c, _d, tokenCalls, i, tokens, tokenInfoCalls, _i, tokens_1, token, tokenMulticallContract, tokenInfo_1, i, rewardContract, method, token, tokenMulticallContract, _e, symbol, decimals;
318
501
  return __generator(this, function (_f) {
@@ -379,46 +562,117 @@ var PoolTemplate = /** @class */ (function () {
379
562
  promise: true,
380
563
  maxAge: 30 * 60 * 1000, // 30m
381
564
  });
382
- // ---------------- ... ----------------
383
- this.gaugeMaxBoostedDeposit = function () {
384
- var addresses = [];
385
- for (var _i = 0; _i < arguments.length; _i++) {
386
- addresses[_i] = arguments[_i];
387
- }
565
+ this.rewardsProfit = function (address) {
566
+ if (address === void 0) { address = ""; }
388
567
  return __awaiter(_this, void 0, void 0, function () {
389
- var votingEscrowContract, gaugeContract, contractCalls, _response, responseBN, _a, veTotalSupplyBN, gaugeTotalSupplyBN, resultBN, result, _c, _d, entry;
568
+ var rewardTokens, gaugeContract, result, calls, _i, rewardTokens_2, rewardToken, res, balanceBN, totalSupplyBN, _a, rewardTokens_3, rewardToken, _rewardData, periodFinish, inflationRateBN, tokenPrice, rewardToken, sRewardContract, _c, _inflationRate, _periodFinish, _balance, _totalSupply, periodFinish, inflationRateBN, balanceBN, totalSupplyBN, tokenPrice, _d, rewardTokens_4, rewardToken, tokenPrice;
390
569
  return __generator(this, function (_e) {
391
570
  switch (_e.label) {
392
571
  case 0:
393
572
  if (this.gauge === ethers_1.ethers.constants.AddressZero)
394
573
  throw Error("".concat(this.name, " doesn't have gauge"));
395
- if (addresses.length == 1 && Array.isArray(addresses[0]))
396
- addresses = addresses[0];
397
- votingEscrowContract = curve_1.curve.contracts[curve_1.curve.constants.ALIASES.voting_escrow].multicallContract;
574
+ address = address || curve_1.curve.signerAddress;
575
+ if (!address)
576
+ throw Error("Need to connect wallet or pass address into args");
577
+ return [4 /*yield*/, this.rewardTokens()];
578
+ case 1:
579
+ rewardTokens = _e.sent();
398
580
  gaugeContract = curve_1.curve.contracts[this.gauge].multicallContract;
399
- contractCalls = [votingEscrowContract.totalSupply(), gaugeContract.totalSupply()];
400
- addresses.forEach(function (account) {
401
- contractCalls.push(votingEscrowContract.balanceOf(account));
581
+ result = [];
582
+ if (!('reward_data(address)' in curve_1.curve.contracts[this.gauge].contract)) return [3 /*break*/, 7];
583
+ calls = [gaugeContract.balanceOf(address), gaugeContract.totalSupply()];
584
+ for (_i = 0, rewardTokens_2 = rewardTokens; _i < rewardTokens_2.length; _i++) {
585
+ rewardToken = rewardTokens_2[_i];
586
+ calls.push(gaugeContract.reward_data(rewardToken.token));
587
+ }
588
+ return [4 /*yield*/, curve_1.curve.multicallProvider.all(calls)];
589
+ case 2:
590
+ res = _e.sent();
591
+ balanceBN = (0, utils_1.toBN)(res.shift());
592
+ totalSupplyBN = (0, utils_1.toBN)(res.shift());
593
+ _a = 0, rewardTokens_3 = rewardTokens;
594
+ _e.label = 3;
595
+ case 3:
596
+ if (!(_a < rewardTokens_3.length)) return [3 /*break*/, 6];
597
+ rewardToken = rewardTokens_3[_a];
598
+ _rewardData = res.shift();
599
+ periodFinish = Number(ethers_1.ethers.utils.formatUnits(_rewardData.period_finish, 0)) * 1000;
600
+ inflationRateBN = periodFinish > Date.now() ? (0, utils_1.toBN)(_rewardData.rate, rewardToken.decimals) : (0, utils_1.BN)(0);
601
+ return [4 /*yield*/, (0, utils_1._getUsdRate)(rewardToken.token)];
602
+ case 4:
603
+ tokenPrice = _e.sent();
604
+ result.push({
605
+ day: inflationRateBN.times(DAY).times(balanceBN).div(totalSupplyBN).toString(),
606
+ week: inflationRateBN.times(WEEK).times(balanceBN).div(totalSupplyBN).toString(),
607
+ month: inflationRateBN.times(MONTH).times(balanceBN).div(totalSupplyBN).toString(),
608
+ year: inflationRateBN.times(YEAR).times(balanceBN).div(totalSupplyBN).toString(),
609
+ token: rewardToken.token,
610
+ symbol: rewardToken.symbol,
611
+ price: tokenPrice,
402
612
  });
403
- return [4 /*yield*/, curve_1.curve.multicallProvider.all(contractCalls)];
404
- case 1:
405
- _response = _e.sent();
406
- responseBN = _response.map(function (value) { return (0, utils_1.toBN)(value); });
407
- _a = responseBN.splice(0, 2), veTotalSupplyBN = _a[0], gaugeTotalSupplyBN = _a[1];
408
- resultBN = {};
409
- addresses.forEach(function (acct, i) {
410
- resultBN[acct] = responseBN[i].div(veTotalSupplyBN).times(gaugeTotalSupplyBN);
613
+ _e.label = 5;
614
+ case 5:
615
+ _a++;
616
+ return [3 /*break*/, 3];
617
+ case 6: return [3 /*break*/, 14];
618
+ case 7:
619
+ if (!(this.sRewardContract && "rewardRate()" in curve_1.curve.contracts[this.sRewardContract].contract && "periodFinish()" && rewardTokens.length === 1)) return [3 /*break*/, 10];
620
+ rewardToken = rewardTokens[0];
621
+ sRewardContract = curve_1.curve.contracts[this.sRewardContract].multicallContract;
622
+ return [4 /*yield*/, curve_1.curve.multicallProvider.all([
623
+ sRewardContract.rewardRate(),
624
+ sRewardContract.periodFinish(),
625
+ gaugeContract.balanceOf(address),
626
+ gaugeContract.totalSupply(),
627
+ ])];
628
+ case 8:
629
+ _c = _e.sent(), _inflationRate = _c[0], _periodFinish = _c[1], _balance = _c[2], _totalSupply = _c[3];
630
+ periodFinish = Number(ethers_1.ethers.utils.formatUnits(_periodFinish, 0)) * 1000;
631
+ inflationRateBN = periodFinish > Date.now() ? (0, utils_1.toBN)(_inflationRate, rewardToken.decimals) : (0, utils_1.BN)(0);
632
+ balanceBN = (0, utils_1.toBN)(_balance);
633
+ totalSupplyBN = (0, utils_1.toBN)(_totalSupply);
634
+ return [4 /*yield*/, (0, utils_1._getUsdRate)(rewardToken.token)];
635
+ case 9:
636
+ tokenPrice = _e.sent();
637
+ result.push({
638
+ day: inflationRateBN.times(DAY).times(balanceBN).div(totalSupplyBN).toString(),
639
+ week: inflationRateBN.times(WEEK).times(balanceBN).div(totalSupplyBN).toString(),
640
+ month: inflationRateBN.times(MONTH).times(balanceBN).div(totalSupplyBN).toString(),
641
+ year: inflationRateBN.times(YEAR).times(balanceBN).div(totalSupplyBN).toString(),
642
+ token: rewardToken.token,
643
+ symbol: rewardToken.symbol,
644
+ price: tokenPrice,
411
645
  });
412
- result = {};
413
- for (_c = 0, _d = Object.entries(resultBN); _c < _d.length; _c++) {
414
- entry = _d[_c];
415
- result[entry[0]] = (0, utils_1.toStringFromBN)(entry[1]);
416
- }
417
- return [2 /*return*/, result];
646
+ return [3 /*break*/, 14];
647
+ case 10:
648
+ if (!['aave', 'saave', 'ankreth'].includes(this.id)) return [3 /*break*/, 14];
649
+ _d = 0, rewardTokens_4 = rewardTokens;
650
+ _e.label = 11;
651
+ case 11:
652
+ if (!(_d < rewardTokens_4.length)) return [3 /*break*/, 14];
653
+ rewardToken = rewardTokens_4[_d];
654
+ return [4 /*yield*/, (0, utils_1._getUsdRate)(rewardToken.token)];
655
+ case 12:
656
+ tokenPrice = _e.sent();
657
+ result.push({
658
+ day: "0",
659
+ week: "0",
660
+ month: "0",
661
+ year: "0",
662
+ token: rewardToken.token,
663
+ symbol: rewardToken.symbol,
664
+ price: tokenPrice,
665
+ });
666
+ _e.label = 13;
667
+ case 13:
668
+ _d++;
669
+ return [3 /*break*/, 11];
670
+ case 14: return [2 /*return*/, result];
418
671
  }
419
672
  });
420
673
  });
421
674
  };
675
+ // ---------------- ... ----------------
422
676
  this.gaugeOptimalDeposits = function () {
423
677
  var accounts = [];
424
678
  for (var _i = 0; _i < arguments.length; _i++) {
@@ -486,25 +740,6 @@ var PoolTemplate = /** @class */ (function () {
486
740
  });
487
741
  });
488
742
  };
489
- this.boost = function (address) { return __awaiter(_this, void 0, void 0, function () {
490
- var gaugeContract, _a, workingBalance, balance, boost;
491
- return __generator(this, function (_c) {
492
- switch (_c.label) {
493
- case 0:
494
- if (this.gauge === ethers_1.ethers.constants.AddressZero)
495
- throw Error("".concat(this.name, " doesn't have gauge"));
496
- gaugeContract = curve_1.curve.contracts[this.gauge].multicallContract;
497
- return [4 /*yield*/, curve_1.curve.multicallProvider.all([
498
- gaugeContract.working_balances(address),
499
- gaugeContract.balanceOf(address),
500
- ])];
501
- case 1:
502
- _a = (_c.sent()).map(function (value) { return Number(ethers_1.ethers.utils.formatUnits(value)); }), workingBalance = _a[0], balance = _a[1];
503
- boost = workingBalance / (0.4 * balance);
504
- return [2 /*return*/, boost.toFixed(4).replace(/([0-9])0+$/, '$1')];
505
- }
506
- });
507
- }); };
508
743
  this._getCoinIdx = function (coin, useUnderlying) {
509
744
  if (useUnderlying === void 0) { useUnderlying = true; }
510
745
  if (typeof coin === 'number') {
@@ -1225,9 +1460,9 @@ var PoolTemplate = /** @class */ (function () {
1225
1460
  PoolTemplate.prototype.claimableRewards = function (address) {
1226
1461
  if (address === void 0) { address = ""; }
1227
1462
  return __awaiter(this, void 0, void 0, function () {
1228
- var gaugeContract, rewardTokens, rewards, _i, rewardTokens_2, rewardToken, amount, _a, _c, rewardToken, _totalAmount, _claimedAmount;
1229
- return __generator(this, function (_d) {
1230
- switch (_d.label) {
1463
+ var gaugeContract, rewardTokens, rewards, _i, rewardTokens_5, rewardToken, _amount, rewardToken, _totalAmount, _claimedAmount;
1464
+ return __generator(this, function (_a) {
1465
+ switch (_a.label) {
1231
1466
  case 0:
1232
1467
  if (this.gauge === ethers_1.ethers.constants.AddressZero) {
1233
1468
  throw Error("claimableRewards method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, "). There is no gauge"));
@@ -1238,24 +1473,23 @@ var PoolTemplate = /** @class */ (function () {
1238
1473
  gaugeContract = curve_1.curve.contracts[this.gauge].contract;
1239
1474
  return [4 /*yield*/, this.rewardTokens()];
1240
1475
  case 1:
1241
- rewardTokens = _d.sent();
1476
+ rewardTokens = _a.sent();
1242
1477
  rewards = [];
1243
1478
  if (!('claimable_reward(address,address)' in gaugeContract)) return [3 /*break*/, 6];
1244
- _i = 0, rewardTokens_2 = rewardTokens;
1245
- _d.label = 2;
1479
+ _i = 0, rewardTokens_5 = rewardTokens;
1480
+ _a.label = 2;
1246
1481
  case 2:
1247
- if (!(_i < rewardTokens_2.length)) return [3 /*break*/, 5];
1248
- rewardToken = rewardTokens_2[_i];
1249
- _c = (_a = ethers_1.ethers.utils).formatUnits;
1250
- return [4 /*yield*/, gaugeContract.claimable_reward(address, rewardToken, curve_1.curve.constantOptions)];
1482
+ if (!(_i < rewardTokens_5.length)) return [3 /*break*/, 5];
1483
+ rewardToken = rewardTokens_5[_i];
1484
+ return [4 /*yield*/, gaugeContract.claimable_reward(address, rewardToken.token, curve_1.curve.constantOptions)];
1251
1485
  case 3:
1252
- amount = _c.apply(_a, [_d.sent(), rewardToken.decimals]);
1486
+ _amount = _a.sent();
1253
1487
  rewards.push({
1254
1488
  token: rewardToken.token,
1255
1489
  symbol: rewardToken.symbol,
1256
- amount: amount,
1490
+ amount: ethers_1.ethers.utils.formatUnits(_amount, rewardToken.decimals),
1257
1491
  });
1258
- _d.label = 4;
1492
+ _a.label = 4;
1259
1493
  case 4:
1260
1494
  _i++;
1261
1495
  return [3 /*break*/, 2];
@@ -1265,16 +1499,16 @@ var PoolTemplate = /** @class */ (function () {
1265
1499
  rewardToken = rewardTokens[0];
1266
1500
  return [4 /*yield*/, gaugeContract.claimable_reward(address, curve_1.curve.constantOptions)];
1267
1501
  case 7:
1268
- _totalAmount = _d.sent();
1502
+ _totalAmount = _a.sent();
1269
1503
  return [4 /*yield*/, gaugeContract.claimed_rewards_for(address, curve_1.curve.constantOptions)];
1270
1504
  case 8:
1271
- _claimedAmount = _d.sent();
1505
+ _claimedAmount = _a.sent();
1272
1506
  rewards.push({
1273
1507
  token: rewardToken.token,
1274
1508
  symbol: rewardToken.symbol,
1275
1509
  amount: ethers_1.ethers.utils.formatUnits(_totalAmount.sub(_claimedAmount), rewardToken.decimals),
1276
1510
  });
1277
- _d.label = 9;
1511
+ _a.label = 9;
1278
1512
  case 9: return [2 /*return*/, rewards];
1279
1513
  }
1280
1514
  });
@@ -2205,6 +2439,158 @@ var PoolTemplate = /** @class */ (function () {
2205
2439
  });
2206
2440
  });
2207
2441
  };
2442
+ // ---------------- USER BALANCES, BASE PROFIT AND SHARE ----------------
2443
+ PoolTemplate.prototype._userLpTotalBalance = function (address) {
2444
+ return __awaiter(this, void 0, void 0, function () {
2445
+ var lpBalances, lpTotalBalanceBN;
2446
+ return __generator(this, function (_a) {
2447
+ switch (_a.label) {
2448
+ case 0: return [4 /*yield*/, this.walletLpTokenBalances(address)];
2449
+ case 1:
2450
+ lpBalances = _a.sent();
2451
+ lpTotalBalanceBN = (0, utils_1.BN)(lpBalances.lpToken);
2452
+ if ('gauge' in lpBalances)
2453
+ lpTotalBalanceBN = lpTotalBalanceBN.plus((0, utils_1.BN)(lpBalances.gauge));
2454
+ return [2 /*return*/, lpTotalBalanceBN.toString()];
2455
+ }
2456
+ });
2457
+ });
2458
+ };
2459
+ PoolTemplate.prototype.userBalances = function (address) {
2460
+ if (address === void 0) { address = ""; }
2461
+ return __awaiter(this, void 0, void 0, function () {
2462
+ var lpTotalBalanceBN;
2463
+ return __generator(this, function (_a) {
2464
+ switch (_a.label) {
2465
+ case 0:
2466
+ address = address || curve_1.curve.signerAddress;
2467
+ if (!address)
2468
+ throw Error("Need to connect wallet or pass address into args");
2469
+ return [4 /*yield*/, this._userLpTotalBalance(address)];
2470
+ case 1:
2471
+ lpTotalBalanceBN = _a.sent();
2472
+ return [4 /*yield*/, this.withdrawExpected(lpTotalBalanceBN.toString())];
2473
+ case 2: return [2 /*return*/, _a.sent()];
2474
+ }
2475
+ });
2476
+ });
2477
+ };
2478
+ PoolTemplate.prototype.userWrappedBalances = function (address) {
2479
+ if (address === void 0) { address = ""; }
2480
+ return __awaiter(this, void 0, void 0, function () {
2481
+ var lpTotalBalanceBN;
2482
+ return __generator(this, function (_a) {
2483
+ switch (_a.label) {
2484
+ case 0:
2485
+ address = address || curve_1.curve.signerAddress;
2486
+ if (!address)
2487
+ throw Error("Need to connect wallet or pass address into args");
2488
+ return [4 /*yield*/, this._userLpTotalBalance(address)];
2489
+ case 1:
2490
+ lpTotalBalanceBN = _a.sent();
2491
+ return [4 /*yield*/, this.withdrawWrappedExpected(lpTotalBalanceBN.toString())];
2492
+ case 2: return [2 /*return*/, _a.sent()];
2493
+ }
2494
+ });
2495
+ });
2496
+ };
2497
+ PoolTemplate.prototype.userLiquidityUSD = function (address) {
2498
+ if (address === void 0) { address = ""; }
2499
+ return __awaiter(this, void 0, void 0, function () {
2500
+ var balances, promises, _i, _a, addr, prices, totalLiquidity;
2501
+ return __generator(this, function (_c) {
2502
+ switch (_c.label) {
2503
+ case 0: return [4 /*yield*/, this.userBalances(address)];
2504
+ case 1:
2505
+ balances = _c.sent();
2506
+ promises = [];
2507
+ for (_i = 0, _a = this.underlyingCoinAddresses; _i < _a.length; _i++) {
2508
+ addr = _a[_i];
2509
+ promises.push((0, utils_1._getUsdRate)(addr));
2510
+ }
2511
+ return [4 /*yield*/, Promise.all(promises)];
2512
+ case 2:
2513
+ prices = _c.sent();
2514
+ totalLiquidity = balances.reduce(function (liquidity, b, i) { return liquidity + (Number(b) * prices[i]); }, 0);
2515
+ return [2 /*return*/, totalLiquidity.toFixed(8)];
2516
+ }
2517
+ });
2518
+ });
2519
+ };
2520
+ PoolTemplate.prototype.baseProfit = function (address) {
2521
+ if (address === void 0) { address = ""; }
2522
+ return __awaiter(this, void 0, void 0, function () {
2523
+ var apyData, apyBN, totalLiquidityBN, _a, annualProfitBN, monthlyProfitBN, weeklyProfitBN, daylyProfitBN;
2524
+ return __generator(this, function (_c) {
2525
+ switch (_c.label) {
2526
+ case 0: return [4 /*yield*/, this.statsBaseApy()];
2527
+ case 1:
2528
+ apyData = _c.sent();
2529
+ if (!('week' in apyData))
2530
+ return [2 /*return*/, { day: "0", week: "0", month: "0", year: "0" }];
2531
+ apyBN = (0, utils_1.BN)(apyData.week).div(100);
2532
+ _a = utils_1.BN;
2533
+ return [4 /*yield*/, this.userLiquidityUSD(address)];
2534
+ case 2:
2535
+ totalLiquidityBN = _a.apply(void 0, [_c.sent()]);
2536
+ annualProfitBN = apyBN.times(totalLiquidityBN);
2537
+ monthlyProfitBN = annualProfitBN.div(12);
2538
+ weeklyProfitBN = annualProfitBN.div(52);
2539
+ daylyProfitBN = annualProfitBN.div(365);
2540
+ return [2 /*return*/, {
2541
+ day: daylyProfitBN.toString(),
2542
+ week: weeklyProfitBN.toString(),
2543
+ month: monthlyProfitBN.toString(),
2544
+ year: annualProfitBN.toString(),
2545
+ }];
2546
+ }
2547
+ });
2548
+ });
2549
+ };
2550
+ PoolTemplate.prototype.userShare = function (address) {
2551
+ if (address === void 0) { address = ""; }
2552
+ return __awaiter(this, void 0, void 0, function () {
2553
+ var withGauge, userLpBalance, userLpTotalBalanceBN, totalLp, gaugeLp, _a, _c;
2554
+ var _d;
2555
+ return __generator(this, function (_e) {
2556
+ switch (_e.label) {
2557
+ case 0:
2558
+ withGauge = this.gauge !== ethers_1.ethers.constants.AddressZero;
2559
+ address = address || curve_1.curve.signerAddress;
2560
+ if (!address)
2561
+ throw Error("Need to connect wallet or pass address into args");
2562
+ return [4 /*yield*/, this.walletLpTokenBalances(address)];
2563
+ case 1:
2564
+ userLpBalance = _e.sent();
2565
+ userLpTotalBalanceBN = (0, utils_1.BN)(userLpBalance.lpToken);
2566
+ if (withGauge)
2567
+ userLpTotalBalanceBN = userLpTotalBalanceBN.plus((0, utils_1.BN)(userLpBalance.gauge));
2568
+ if (!withGauge) return [3 /*break*/, 3];
2569
+ return [4 /*yield*/, curve_1.curve.multicallProvider.all([
2570
+ curve_1.curve.contracts[this.lpToken].multicallContract.totalSupply(),
2571
+ curve_1.curve.contracts[this.gauge].multicallContract.totalSupply(),
2572
+ ])];
2573
+ case 2:
2574
+ _d = (_e.sent()).map(function (_supply) { return ethers_1.ethers.utils.formatUnits(_supply); }), totalLp = _d[0], gaugeLp = _d[1];
2575
+ return [3 /*break*/, 5];
2576
+ case 3:
2577
+ _c = (_a = ethers_1.ethers.utils).formatUnits;
2578
+ return [4 /*yield*/, curve_1.curve.contracts[this.lpToken].contract.totalSupply()];
2579
+ case 4:
2580
+ totalLp = _c.apply(_a, [_e.sent()]);
2581
+ _e.label = 5;
2582
+ case 5: return [2 /*return*/, {
2583
+ lpUser: userLpTotalBalanceBN.toString(),
2584
+ lpTotal: totalLp,
2585
+ lpShare: userLpTotalBalanceBN.div(totalLp).times(100).toString(),
2586
+ gaugeUser: userLpBalance.gauge,
2587
+ gaugeTotal: gaugeLp,
2588
+ gaugeShare: withGauge ? (0, utils_1.BN)(userLpBalance.gauge).div((0, utils_1.BN)(gaugeLp)).times(100).toString() : undefined,
2589
+ }];
2590
+ }
2591
+ });
2592
+ });
2593
+ };
2208
2594
  // ---------------- SWAP ----------------
2209
2595
  PoolTemplate.prototype._swapExpected = function (i, j, _amount) {
2210
2596
  return __awaiter(this, void 0, void 0, function () {
package/lib/utils.js CHANGED
@@ -464,6 +464,7 @@ var _getUsdRate = function (assetId) { return __awaiter(void 0, void 0, void 0,
464
464
  throw Error('curve object is not initialized');
465
465
  }
466
466
  assetId = {
467
+ 'CRV': 'curve-dao-token',
467
468
  'EUR': curve_1.curve.constants.COINS.eurt,
468
469
  'BTC': 'bitcoin',
469
470
  'ETH': 'ethereum',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curvefi/api",
3
- "version": "2.3.2",
3
+ "version": "2.4.0",
4
4
  "description": "JavaScript library for curve.fi",
5
5
  "main": "lib/index.js",
6
6
  "author": "Macket",