@curvefi/api 2.3.4 → 2.4.2

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') {
@@ -607,6 +842,7 @@ var PoolTemplate = /** @class */ (function () {
607
842
  });
608
843
  });
609
844
  };
845
+ // Used by mixin. Don't delete it!!!
610
846
  this._underlyingPrices = function () { return __awaiter(_this, void 0, void 0, function () {
611
847
  var promises, _i, _a, addr;
612
848
  return __generator(this, function (_c) {
@@ -622,6 +858,7 @@ var PoolTemplate = /** @class */ (function () {
622
858
  }
623
859
  });
624
860
  }); };
861
+ // Used by mixin. Don't delete it!!!
625
862
  // NOTE! It may crash!
626
863
  this._wrappedPrices = function () { return __awaiter(_this, void 0, void 0, function () {
627
864
  var promises, _i, _a, addr;
@@ -638,82 +875,6 @@ var PoolTemplate = /** @class */ (function () {
638
875
  }
639
876
  });
640
877
  }); };
641
- this._withdrawCryptoBonus = function (totalAmountUSD, lpTokenAmount, useUnderlying) {
642
- if (useUnderlying === void 0) { useUnderlying = true; }
643
- return __awaiter(_this, void 0, void 0, function () {
644
- var prices, _a, balancedAmounts, _c, balancedTotalAmountsUSD;
645
- return __generator(this, function (_d) {
646
- switch (_d.label) {
647
- case 0:
648
- if (!useUnderlying) return [3 /*break*/, 2];
649
- return [4 /*yield*/, this._underlyingPrices()];
650
- case 1:
651
- _a = _d.sent();
652
- return [3 /*break*/, 4];
653
- case 2: return [4 /*yield*/, this._wrappedPrices()];
654
- case 3:
655
- _a = _d.sent();
656
- _d.label = 4;
657
- case 4:
658
- prices = _a;
659
- if (!useUnderlying) return [3 /*break*/, 6];
660
- return [4 /*yield*/, this.withdrawExpected(String(lpTokenAmount))];
661
- case 5:
662
- _c = _d.sent();
663
- return [3 /*break*/, 8];
664
- case 6: return [4 /*yield*/, this.withdrawWrappedExpected(String(lpTokenAmount))];
665
- case 7:
666
- _c = _d.sent();
667
- _d.label = 8;
668
- case 8:
669
- balancedAmounts = _c;
670
- balancedTotalAmountsUSD = balancedAmounts.reduce(function (s, b, i) { return s + (Number(b) * prices[i]); }, 0);
671
- return [2 /*return*/, String((totalAmountUSD - balancedTotalAmountsUSD) / totalAmountUSD * 100)];
672
- }
673
- });
674
- });
675
- };
676
- // TODO make the same as _withdrawCryptoBonus
677
- this._withdrawBonus = function (totalAmount, expected, useUnderlying) {
678
- if (useUnderlying === void 0) { useUnderlying = true; }
679
- return __awaiter(_this, void 0, void 0, function () {
680
- var poolBalances, _a, poolTotalBalance, poolBalancesRatios, balancedAmounts, balancedExpected, _c, _d, _e;
681
- return __generator(this, function (_f) {
682
- switch (_f.label) {
683
- case 0:
684
- if (!useUnderlying) return [3 /*break*/, 2];
685
- return [4 /*yield*/, this.stats.underlyingBalances()];
686
- case 1:
687
- _a = (_f.sent()).map(Number);
688
- return [3 /*break*/, 4];
689
- case 2: return [4 /*yield*/, this.stats.wrappedBalances()];
690
- case 3:
691
- _a = (_f.sent()).map(Number);
692
- _f.label = 4;
693
- case 4:
694
- poolBalances = _a;
695
- poolTotalBalance = poolBalances.reduce(function (a, b) { return a + b; });
696
- poolBalancesRatios = poolBalances.map(function (b) { return b / poolTotalBalance; });
697
- balancedAmounts = poolBalancesRatios.map(function (r) { return String(r * totalAmount); });
698
- if (!useUnderlying) return [3 /*break*/, 6];
699
- _d = Number;
700
- return [4 /*yield*/, this.withdrawImbalanceExpected(balancedAmounts)];
701
- case 5:
702
- _c = _d.apply(void 0, [_f.sent()]);
703
- return [3 /*break*/, 8];
704
- case 6:
705
- _e = Number;
706
- return [4 /*yield*/, this.withdrawImbalanceWrappedExpected(balancedAmounts)];
707
- case 7:
708
- _c = _e.apply(void 0, [_f.sent()]);
709
- _f.label = 8;
710
- case 8:
711
- balancedExpected = _c;
712
- return [2 /*return*/, String((balancedExpected - expected) / balancedExpected * 100)];
713
- }
714
- });
715
- });
716
- };
717
878
  var poolData = __assign(__assign(__assign({}, curve_1.curve.constants.POOLS_DATA), curve_1.curve.constants.FACTORY_POOLS_DATA), curve_1.curve.constants.CRYPTO_FACTORY_POOLS_DATA)[id];
718
879
  this.id = id;
719
880
  this.name = poolData.name;
@@ -1225,7 +1386,7 @@ var PoolTemplate = /** @class */ (function () {
1225
1386
  PoolTemplate.prototype.claimableRewards = function (address) {
1226
1387
  if (address === void 0) { address = ""; }
1227
1388
  return __awaiter(this, void 0, void 0, function () {
1228
- var gaugeContract, rewardTokens, rewards, _i, rewardTokens_2, rewardToken, _amount, rewardToken, _totalAmount, _claimedAmount;
1389
+ var gaugeContract, rewardTokens, rewards, _i, rewardTokens_5, rewardToken, _amount, rewardToken, _totalAmount, _claimedAmount;
1229
1390
  return __generator(this, function (_a) {
1230
1391
  switch (_a.label) {
1231
1392
  case 0:
@@ -1241,11 +1402,11 @@ var PoolTemplate = /** @class */ (function () {
1241
1402
  rewardTokens = _a.sent();
1242
1403
  rewards = [];
1243
1404
  if (!('claimable_reward(address,address)' in gaugeContract)) return [3 /*break*/, 6];
1244
- _i = 0, rewardTokens_2 = rewardTokens;
1405
+ _i = 0, rewardTokens_5 = rewardTokens;
1245
1406
  _a.label = 2;
1246
1407
  case 2:
1247
- if (!(_i < rewardTokens_2.length)) return [3 /*break*/, 5];
1248
- rewardToken = rewardTokens_2[_i];
1408
+ if (!(_i < rewardTokens_5.length)) return [3 /*break*/, 5];
1409
+ rewardToken = rewardTokens_5[_i];
1249
1410
  return [4 /*yield*/, gaugeContract.claimable_reward(address, rewardToken.token, curve_1.curve.constantOptions)];
1250
1411
  case 3:
1251
1412
  _amount = _a.sent();
@@ -1665,7 +1826,7 @@ var PoolTemplate = /** @class */ (function () {
1665
1826
  case 12:
1666
1827
  _amounts = amounts.map(function (amount, i) { return (0, utils_1.parseUnits)(amount, decimals[i]); });
1667
1828
  contract = curve_1.curve.contracts[curve_1.curve.constants.ALIASES.deposit_and_stake].contract;
1668
- useUnderlying = isUnderlying && (this.isLending || this.isCrypto) && !this.zap;
1829
+ useUnderlying = isUnderlying && (this.isLending || (this.isCrypto && !this.isPlain)) && !this.zap;
1669
1830
  if (!isUnderlying) return [3 /*break*/, 14];
1670
1831
  _k = (_j = ethers_1.ethers.utils).parseUnits;
1671
1832
  return [4 /*yield*/, this.depositAndStakeExpected(amounts)];
@@ -1806,22 +1967,11 @@ var PoolTemplate = /** @class */ (function () {
1806
1967
  });
1807
1968
  });
1808
1969
  };
1970
+ // OVERRIDE
1809
1971
  PoolTemplate.prototype.withdrawImbalanceBonus = function (amounts) {
1810
1972
  return __awaiter(this, void 0, void 0, function () {
1811
- var totalAmount, expected, _a;
1812
- return __generator(this, function (_c) {
1813
- switch (_c.label) {
1814
- case 0:
1815
- if (this.isCrypto)
1816
- throw Error("withdrawImbalanceBonus method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
1817
- totalAmount = amounts.map(utils_1.checkNumber).map(Number).reduce(function (a, b) { return a + b; });
1818
- _a = Number;
1819
- return [4 /*yield*/, this.withdrawImbalanceExpected(amounts)];
1820
- case 1:
1821
- expected = _a.apply(void 0, [_c.sent()]);
1822
- return [4 /*yield*/, this._withdrawBonus(totalAmount, expected)];
1823
- case 2: return [2 /*return*/, _c.sent()];
1824
- }
1973
+ return __generator(this, function (_a) {
1974
+ throw Error("withdrawImbalanceBonus method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
1825
1975
  });
1826
1976
  });
1827
1977
  };
@@ -1919,22 +2069,11 @@ var PoolTemplate = /** @class */ (function () {
1919
2069
  });
1920
2070
  });
1921
2071
  };
2072
+ // OVERRIDE
1922
2073
  PoolTemplate.prototype.withdrawImbalanceWrappedBonus = function (amounts) {
1923
2074
  return __awaiter(this, void 0, void 0, function () {
1924
- var totalAmount, expected, _a;
1925
- return __generator(this, function (_c) {
1926
- switch (_c.label) {
1927
- case 0:
1928
- if (this.isCrypto)
1929
- throw Error("withdrawImbalanceWrappedBonus method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
1930
- totalAmount = amounts.map(utils_1.checkNumber).map(Number).reduce(function (a, b) { return a + b; });
1931
- _a = Number;
1932
- return [4 /*yield*/, this.withdrawImbalanceWrappedExpected(amounts)];
1933
- case 1:
1934
- expected = _a.apply(void 0, [_c.sent()]);
1935
- return [4 /*yield*/, this._withdrawBonus(totalAmount, expected, false)];
1936
- case 2: return [2 /*return*/, _c.sent()];
1937
- }
2075
+ return __generator(this, function (_a) {
2076
+ throw Error("withdrawImbalanceWrappedBonus method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
1938
2077
  });
1939
2078
  });
1940
2079
  };
@@ -1980,25 +2119,11 @@ var PoolTemplate = /** @class */ (function () {
1980
2119
  });
1981
2120
  });
1982
2121
  };
2122
+ // OVERRIDE
1983
2123
  PoolTemplate.prototype.withdrawOneCoinBonus = function (lpTokenAmount, coin) {
1984
2124
  return __awaiter(this, void 0, void 0, function () {
1985
- var totalAmount, _a, coinPrice;
1986
- return __generator(this, function (_c) {
1987
- switch (_c.label) {
1988
- case 0:
1989
- _a = Number;
1990
- return [4 /*yield*/, this.withdrawOneCoinExpected(lpTokenAmount, coin)];
1991
- case 1:
1992
- totalAmount = _a.apply(void 0, [_c.sent()]);
1993
- if (!this.isCrypto) return [3 /*break*/, 4];
1994
- return [4 /*yield*/, this._underlyingPrices()];
1995
- case 2:
1996
- coinPrice = (_c.sent())[this._getCoinIdx(coin)];
1997
- return [4 /*yield*/, this._withdrawCryptoBonus(totalAmount * coinPrice, Number(lpTokenAmount))];
1998
- case 3: return [2 /*return*/, _c.sent()];
1999
- case 4: return [4 /*yield*/, this._withdrawBonus(totalAmount, Number(lpTokenAmount))];
2000
- case 5: return [2 /*return*/, _c.sent()];
2001
- }
2125
+ return __generator(this, function (_a) {
2126
+ throw Error("withdrawOneCoinBonus method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
2002
2127
  });
2003
2128
  });
2004
2129
  };
@@ -2083,28 +2208,11 @@ var PoolTemplate = /** @class */ (function () {
2083
2208
  });
2084
2209
  });
2085
2210
  };
2211
+ // OVERRIDE
2086
2212
  PoolTemplate.prototype.withdrawOneCoinWrappedBonus = function (lpTokenAmount, coin) {
2087
2213
  return __awaiter(this, void 0, void 0, function () {
2088
- var totalAmount, _a, coinPrice;
2089
- return __generator(this, function (_c) {
2090
- switch (_c.label) {
2091
- case 0:
2092
- if (this.isFake) {
2093
- throw Error("".concat(this.name, " pool doesn't have this method"));
2094
- }
2095
- _a = Number;
2096
- return [4 /*yield*/, this.withdrawOneCoinWrappedExpected(lpTokenAmount, coin)];
2097
- case 1:
2098
- totalAmount = _a.apply(void 0, [_c.sent()]);
2099
- if (!this.isCrypto) return [3 /*break*/, 4];
2100
- return [4 /*yield*/, this._underlyingPrices()];
2101
- case 2:
2102
- coinPrice = (_c.sent())[this._getCoinIdx(coin, false)];
2103
- return [4 /*yield*/, this._withdrawCryptoBonus(totalAmount * coinPrice, Number(lpTokenAmount))];
2104
- case 3: return [2 /*return*/, _c.sent()];
2105
- case 4: return [4 /*yield*/, this._withdrawBonus(totalAmount, Number(lpTokenAmount), false)];
2106
- case 5: return [2 /*return*/, _c.sent()];
2107
- }
2214
+ return __generator(this, function (_a) {
2215
+ throw Error("withdrawOneCoinWrappedBonus method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
2108
2216
  });
2109
2217
  });
2110
2218
  };
@@ -2204,6 +2312,158 @@ var PoolTemplate = /** @class */ (function () {
2204
2312
  });
2205
2313
  });
2206
2314
  };
2315
+ // ---------------- USER BALANCES, BASE PROFIT AND SHARE ----------------
2316
+ PoolTemplate.prototype._userLpTotalBalance = function (address) {
2317
+ return __awaiter(this, void 0, void 0, function () {
2318
+ var lpBalances, lpTotalBalanceBN;
2319
+ return __generator(this, function (_a) {
2320
+ switch (_a.label) {
2321
+ case 0: return [4 /*yield*/, this.walletLpTokenBalances(address)];
2322
+ case 1:
2323
+ lpBalances = _a.sent();
2324
+ lpTotalBalanceBN = (0, utils_1.BN)(lpBalances.lpToken);
2325
+ if ('gauge' in lpBalances)
2326
+ lpTotalBalanceBN = lpTotalBalanceBN.plus((0, utils_1.BN)(lpBalances.gauge));
2327
+ return [2 /*return*/, lpTotalBalanceBN.toString()];
2328
+ }
2329
+ });
2330
+ });
2331
+ };
2332
+ PoolTemplate.prototype.userBalances = function (address) {
2333
+ if (address === void 0) { address = ""; }
2334
+ return __awaiter(this, void 0, void 0, function () {
2335
+ var lpTotalBalanceBN;
2336
+ return __generator(this, function (_a) {
2337
+ switch (_a.label) {
2338
+ case 0:
2339
+ address = address || curve_1.curve.signerAddress;
2340
+ if (!address)
2341
+ throw Error("Need to connect wallet or pass address into args");
2342
+ return [4 /*yield*/, this._userLpTotalBalance(address)];
2343
+ case 1:
2344
+ lpTotalBalanceBN = _a.sent();
2345
+ return [4 /*yield*/, this.withdrawExpected(lpTotalBalanceBN.toString())];
2346
+ case 2: return [2 /*return*/, _a.sent()];
2347
+ }
2348
+ });
2349
+ });
2350
+ };
2351
+ PoolTemplate.prototype.userWrappedBalances = function (address) {
2352
+ if (address === void 0) { address = ""; }
2353
+ return __awaiter(this, void 0, void 0, function () {
2354
+ var lpTotalBalanceBN;
2355
+ return __generator(this, function (_a) {
2356
+ switch (_a.label) {
2357
+ case 0:
2358
+ address = address || curve_1.curve.signerAddress;
2359
+ if (!address)
2360
+ throw Error("Need to connect wallet or pass address into args");
2361
+ return [4 /*yield*/, this._userLpTotalBalance(address)];
2362
+ case 1:
2363
+ lpTotalBalanceBN = _a.sent();
2364
+ return [4 /*yield*/, this.withdrawWrappedExpected(lpTotalBalanceBN.toString())];
2365
+ case 2: return [2 /*return*/, _a.sent()];
2366
+ }
2367
+ });
2368
+ });
2369
+ };
2370
+ PoolTemplate.prototype.userLiquidityUSD = function (address) {
2371
+ if (address === void 0) { address = ""; }
2372
+ return __awaiter(this, void 0, void 0, function () {
2373
+ var balances, promises, _i, _a, addr, prices, totalLiquidity;
2374
+ return __generator(this, function (_c) {
2375
+ switch (_c.label) {
2376
+ case 0: return [4 /*yield*/, this.userBalances(address)];
2377
+ case 1:
2378
+ balances = _c.sent();
2379
+ promises = [];
2380
+ for (_i = 0, _a = this.underlyingCoinAddresses; _i < _a.length; _i++) {
2381
+ addr = _a[_i];
2382
+ promises.push((0, utils_1._getUsdRate)(addr));
2383
+ }
2384
+ return [4 /*yield*/, Promise.all(promises)];
2385
+ case 2:
2386
+ prices = _c.sent();
2387
+ totalLiquidity = balances.reduce(function (liquidity, b, i) { return liquidity + (Number(b) * prices[i]); }, 0);
2388
+ return [2 /*return*/, totalLiquidity.toFixed(8)];
2389
+ }
2390
+ });
2391
+ });
2392
+ };
2393
+ PoolTemplate.prototype.baseProfit = function (address) {
2394
+ if (address === void 0) { address = ""; }
2395
+ return __awaiter(this, void 0, void 0, function () {
2396
+ var apyData, apyBN, totalLiquidityBN, _a, annualProfitBN, monthlyProfitBN, weeklyProfitBN, daylyProfitBN;
2397
+ return __generator(this, function (_c) {
2398
+ switch (_c.label) {
2399
+ case 0: return [4 /*yield*/, this.statsBaseApy()];
2400
+ case 1:
2401
+ apyData = _c.sent();
2402
+ if (!('week' in apyData))
2403
+ return [2 /*return*/, { day: "0", week: "0", month: "0", year: "0" }];
2404
+ apyBN = (0, utils_1.BN)(apyData.week).div(100);
2405
+ _a = utils_1.BN;
2406
+ return [4 /*yield*/, this.userLiquidityUSD(address)];
2407
+ case 2:
2408
+ totalLiquidityBN = _a.apply(void 0, [_c.sent()]);
2409
+ annualProfitBN = apyBN.times(totalLiquidityBN);
2410
+ monthlyProfitBN = annualProfitBN.div(12);
2411
+ weeklyProfitBN = annualProfitBN.div(52);
2412
+ daylyProfitBN = annualProfitBN.div(365);
2413
+ return [2 /*return*/, {
2414
+ day: daylyProfitBN.toString(),
2415
+ week: weeklyProfitBN.toString(),
2416
+ month: monthlyProfitBN.toString(),
2417
+ year: annualProfitBN.toString(),
2418
+ }];
2419
+ }
2420
+ });
2421
+ });
2422
+ };
2423
+ PoolTemplate.prototype.userShare = function (address) {
2424
+ if (address === void 0) { address = ""; }
2425
+ return __awaiter(this, void 0, void 0, function () {
2426
+ var withGauge, userLpBalance, userLpTotalBalanceBN, totalLp, gaugeLp, _a, _c;
2427
+ var _d;
2428
+ return __generator(this, function (_e) {
2429
+ switch (_e.label) {
2430
+ case 0:
2431
+ withGauge = this.gauge !== ethers_1.ethers.constants.AddressZero;
2432
+ address = address || curve_1.curve.signerAddress;
2433
+ if (!address)
2434
+ throw Error("Need to connect wallet or pass address into args");
2435
+ return [4 /*yield*/, this.walletLpTokenBalances(address)];
2436
+ case 1:
2437
+ userLpBalance = _e.sent();
2438
+ userLpTotalBalanceBN = (0, utils_1.BN)(userLpBalance.lpToken);
2439
+ if (withGauge)
2440
+ userLpTotalBalanceBN = userLpTotalBalanceBN.plus((0, utils_1.BN)(userLpBalance.gauge));
2441
+ if (!withGauge) return [3 /*break*/, 3];
2442
+ return [4 /*yield*/, curve_1.curve.multicallProvider.all([
2443
+ curve_1.curve.contracts[this.lpToken].multicallContract.totalSupply(),
2444
+ curve_1.curve.contracts[this.gauge].multicallContract.totalSupply(),
2445
+ ])];
2446
+ case 2:
2447
+ _d = (_e.sent()).map(function (_supply) { return ethers_1.ethers.utils.formatUnits(_supply); }), totalLp = _d[0], gaugeLp = _d[1];
2448
+ return [3 /*break*/, 5];
2449
+ case 3:
2450
+ _c = (_a = ethers_1.ethers.utils).formatUnits;
2451
+ return [4 /*yield*/, curve_1.curve.contracts[this.lpToken].contract.totalSupply()];
2452
+ case 4:
2453
+ totalLp = _c.apply(_a, [_e.sent()]);
2454
+ _e.label = 5;
2455
+ case 5: return [2 /*return*/, {
2456
+ lpUser: userLpTotalBalanceBN.toString(),
2457
+ lpTotal: totalLp,
2458
+ lpShare: userLpTotalBalanceBN.div(totalLp).times(100).toString(),
2459
+ gaugeUser: userLpBalance.gauge,
2460
+ gaugeTotal: gaugeLp,
2461
+ gaugeShare: withGauge ? (0, utils_1.BN)(userLpBalance.gauge).div((0, utils_1.BN)(gaugeLp)).times(100).toString() : undefined,
2462
+ }];
2463
+ }
2464
+ });
2465
+ });
2466
+ };
2207
2467
  // ---------------- SWAP ----------------
2208
2468
  PoolTemplate.prototype._swapExpected = function (i, j, _amount) {
2209
2469
  return __awaiter(this, void 0, void 0, function () {