@curvefi/api 2.31.0 → 2.31.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.
- package/lib/boosting.js +137 -402
- package/lib/constants/aliases.d.ts +11 -11
- package/lib/constants/aliases.js +12 -15
- package/lib/constants/coins/arbitrum.js +6 -9
- package/lib/constants/coins/aurora.js +6 -9
- package/lib/constants/coins/avalanche.js +7 -10
- package/lib/constants/coins/celo.js +6 -9
- package/lib/constants/coins/ethereum.js +10 -13
- package/lib/constants/coins/fantom.js +8 -11
- package/lib/constants/coins/kava.js +6 -9
- package/lib/constants/coins/moonbeam.js +6 -9
- package/lib/constants/coins/optimism.js +6 -9
- package/lib/constants/coins/polygon.js +7 -10
- package/lib/constants/coins/xdai.js +6 -9
- package/lib/constants/pools/arbitrum.d.ts +2 -4
- package/lib/constants/pools/arbitrum.js +22 -28
- package/lib/constants/pools/aurora.d.ts +2 -4
- package/lib/constants/pools/aurora.js +6 -12
- package/lib/constants/pools/avalanche.d.ts +2 -4
- package/lib/constants/pools/avalanche.js +21 -27
- package/lib/constants/pools/celo.d.ts +2 -4
- package/lib/constants/pools/celo.js +2 -5
- package/lib/constants/pools/ethereum.js +247 -253
- package/lib/constants/pools/fantom.d.ts +2 -4
- package/lib/constants/pools/fantom.js +28 -34
- package/lib/constants/pools/index.d.ts +11 -11
- package/lib/constants/pools/index.js +12 -25
- package/lib/constants/pools/kava.d.ts +2 -4
- package/lib/constants/pools/kava.js +2 -5
- package/lib/constants/pools/moonbeam.d.ts +2 -4
- package/lib/constants/pools/moonbeam.js +6 -12
- package/lib/constants/pools/optimism.d.ts +2 -4
- package/lib/constants/pools/optimism.js +9 -15
- package/lib/constants/pools/polygon.d.ts +2 -4
- package/lib/constants/pools/polygon.js +22 -28
- package/lib/constants/pools/xdai.d.ts +2 -4
- package/lib/constants/pools/xdai.js +24 -30
- package/lib/constants/utils.js +20 -29
- package/lib/curve.d.ts +9 -7
- package/lib/curve.js +397 -615
- package/lib/external-api.d.ts +1 -1
- package/lib/external-api.js +47 -140
- package/lib/factory/common.js +6 -10
- package/lib/factory/constants-crypto.js +48 -54
- package/lib/factory/constants.js +274 -280
- package/lib/factory/deploy.d.ts +8 -8
- package/lib/factory/deploy.js +177 -347
- package/lib/factory/factory-api.js +195 -278
- package/lib/factory/factory-crypto.js +170 -323
- package/lib/factory/factory.js +195 -350
- package/lib/index.d.ts +24 -25
- package/lib/index.js +87 -143
- package/lib/interfaces.d.ts +5 -5
- package/lib/interfaces.js +1 -2
- package/lib/pools/PoolTemplate.js +1516 -2929
- package/lib/pools/index.d.ts +2 -2
- package/lib/pools/index.js +3 -7
- package/lib/pools/mixins/common.d.ts +3 -4
- package/lib/pools/mixins/common.js +23 -112
- package/lib/pools/mixins/depositBalancedAmountsMixins.d.ts +1 -1
- package/lib/pools/mixins/depositBalancedAmountsMixins.js +50 -139
- package/lib/pools/mixins/depositMixins.d.ts +1 -1
- package/lib/pools/mixins/depositMixins.js +144 -417
- package/lib/pools/mixins/depositWrappedMixins.d.ts +1 -1
- package/lib/pools/mixins/depositWrappedMixins.js +72 -227
- package/lib/pools/mixins/poolBalancesMixin.d.ts +1 -1
- package/lib/pools/mixins/poolBalancesMixin.js +25 -105
- package/lib/pools/mixins/swapMixins.d.ts +1 -1
- package/lib/pools/mixins/swapMixins.js +127 -353
- package/lib/pools/mixins/swapWrappedMixins.d.ts +1 -1
- package/lib/pools/mixins/swapWrappedMixins.js +90 -276
- package/lib/pools/mixins/withdrawExpectedMixins.d.ts +1 -1
- package/lib/pools/mixins/withdrawExpectedMixins.js +26 -110
- package/lib/pools/mixins/withdrawImbalanceMixins.d.ts +1 -1
- package/lib/pools/mixins/withdrawImbalanceMixins.js +99 -321
- package/lib/pools/mixins/withdrawImbalanceWrappedMixins.d.ts +1 -1
- package/lib/pools/mixins/withdrawImbalanceWrappedMixins.js +53 -192
- package/lib/pools/mixins/withdrawMixins.d.ts +1 -1
- package/lib/pools/mixins/withdrawMixins.js +123 -390
- package/lib/pools/mixins/withdrawOneCoinExpectedMixins.d.ts +1 -1
- package/lib/pools/mixins/withdrawOneCoinExpectedMixins.js +17 -92
- package/lib/pools/mixins/withdrawOneCoinMixins.d.ts +1 -1
- package/lib/pools/mixins/withdrawOneCoinMixins.js +124 -390
- package/lib/pools/mixins/withdrawOneCoinWrappedExpectedMixins.d.ts +1 -1
- package/lib/pools/mixins/withdrawOneCoinWrappedExpectedMixins.js +9 -66
- package/lib/pools/mixins/withdrawOneCoinWrappedMixins.d.ts +1 -1
- package/lib/pools/mixins/withdrawOneCoinWrappedMixins.js +55 -190
- package/lib/pools/mixins/withdrawWrappedMixins.d.ts +1 -1
- package/lib/pools/mixins/withdrawWrappedMixins.js +52 -191
- package/lib/pools/poolConstructor.d.ts +1 -1
- package/lib/pools/poolConstructor.js +77 -101
- package/lib/pools/utils.js +298 -500
- package/lib/router.d.ts +2 -2
- package/lib/router.js +390 -653
- package/lib/utils.d.ts +9 -9
- package/lib/utils.js +377 -731
- package/package.json +8 -8
|
@@ -1,1120 +1,737 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
-
default:
|
|
37
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
-
if (t[2]) _.ops.pop();
|
|
42
|
-
_.trys.pop(); continue;
|
|
1
|
+
import memoize from "memoizee";
|
|
2
|
+
import { _getPoolsFromApi, _getSubgraphData, _getFactoryAPYsAndVolumes, _getLegacyAPYsAndVolumes } from '../external-api.js';
|
|
3
|
+
import { _getCoinAddresses, _getBalances, _prepareAddresses, _ensureAllowance, _getUsdRate, hasAllowance, ensureAllowance, ensureAllowanceEstimateGas, BN, toBN, toStringFromBN, parseUnits, getEthIndex, fromBN, _cutZeros, _setContracts, _get_small_x, _get_price_impact, checkNumber, _getCrvApyFromApi, _getRewardsFromApi, mulBy1_3, } from '../utils.js';
|
|
4
|
+
import { curve as _curve, curve } from "../curve.js";
|
|
5
|
+
import ERC20Abi from '../constants/abis/ERC20.json' assert { type: 'json' };
|
|
6
|
+
const DAY = 86400;
|
|
7
|
+
const WEEK = 7 * DAY;
|
|
8
|
+
const MONTH = 30 * DAY;
|
|
9
|
+
const YEAR = 365 * DAY;
|
|
10
|
+
export class PoolTemplate {
|
|
11
|
+
constructor(id) {
|
|
12
|
+
this.statsParameters = async () => {
|
|
13
|
+
const multicallContract = curve.contracts[this.address].multicallContract;
|
|
14
|
+
const lpMulticallContract = curve.contracts[this.lpToken].multicallContract;
|
|
15
|
+
const calls = [
|
|
16
|
+
multicallContract.get_virtual_price(),
|
|
17
|
+
multicallContract.fee(),
|
|
18
|
+
multicallContract.admin_fee(),
|
|
19
|
+
multicallContract.A(),
|
|
20
|
+
lpMulticallContract.totalSupply(),
|
|
21
|
+
];
|
|
22
|
+
if (this.isCrypto) {
|
|
23
|
+
calls.push(multicallContract.gamma());
|
|
24
|
+
if (this.wrappedCoins.length === 2) {
|
|
25
|
+
calls.push(multicallContract.price_oracle());
|
|
26
|
+
calls.push(multicallContract.price_scale());
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
for (let i = 0; i < this.wrappedCoins.length - 1; i++) {
|
|
30
|
+
calls.push(multicallContract.price_oracle(i));
|
|
31
|
+
calls.push(multicallContract.price_scale(i));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
43
34
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
60
|
-
};
|
|
61
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
62
|
-
exports.PoolTemplate = void 0;
|
|
63
|
-
var ethers_1 = require("ethers");
|
|
64
|
-
var memoizee_1 = __importDefault(require("memoizee"));
|
|
65
|
-
var external_api_1 = require("../external-api");
|
|
66
|
-
var utils_1 = require("../utils");
|
|
67
|
-
var curve_1 = require("../curve");
|
|
68
|
-
var ERC20_json_1 = __importDefault(require("../constants/abis/ERC20.json"));
|
|
69
|
-
var DAY = 86400;
|
|
70
|
-
var WEEK = 7 * DAY;
|
|
71
|
-
var MONTH = 30 * DAY;
|
|
72
|
-
var YEAR = 365 * DAY;
|
|
73
|
-
var PoolTemplate = /** @class */ (function () {
|
|
74
|
-
function PoolTemplate(id) {
|
|
75
|
-
var _this = this;
|
|
76
|
-
var _c, _d;
|
|
77
|
-
this.statsParameters = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
78
|
-
var multicallContract, lpMulticallContract, calls, i, additionalCalls, _virtualPrice, _fee, _prices, _adminFee, _A, _lpTokenSupply, _gamma, e_1, _c, virtualPrice, fee, adminFee, A, lpTokenSupply, gamma, priceOracle, priceScale, prices, i, A_PRECISION, _d, _future_A, _initial_A, _future_A_time, _initial_A_time, _e, future_A, initial_A, future_A_time, initial_A_time;
|
|
79
|
-
var _f, _g, _h;
|
|
80
|
-
return __generator(this, function (_j) {
|
|
81
|
-
switch (_j.label) {
|
|
82
|
-
case 0:
|
|
83
|
-
multicallContract = curve_1.curve.contracts[this.address].multicallContract;
|
|
84
|
-
lpMulticallContract = curve_1.curve.contracts[this.lpToken].multicallContract;
|
|
85
|
-
calls = [
|
|
86
|
-
multicallContract.get_virtual_price(),
|
|
87
|
-
multicallContract.fee(),
|
|
88
|
-
multicallContract.admin_fee(),
|
|
89
|
-
multicallContract.A(),
|
|
90
|
-
lpMulticallContract.totalSupply(),
|
|
91
|
-
];
|
|
92
|
-
if (this.isCrypto) {
|
|
93
|
-
calls.push(multicallContract.gamma());
|
|
94
|
-
if (this.wrappedCoins.length === 2) {
|
|
95
|
-
calls.push(multicallContract.price_oracle());
|
|
96
|
-
calls.push(multicallContract.price_scale());
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
for (i = 0; i < this.wrappedCoins.length - 1; i++) {
|
|
100
|
-
calls.push(multicallContract.price_oracle(i));
|
|
101
|
-
calls.push(multicallContract.price_scale(i));
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
additionalCalls = this.isCrypto ? [] : [multicallContract.future_A()];
|
|
106
|
-
if ('initial_A' in multicallContract) {
|
|
107
|
-
additionalCalls.push(multicallContract.initial_A(), multicallContract.future_A_time(), multicallContract.initial_A_time());
|
|
108
|
-
}
|
|
109
|
-
_virtualPrice = ethers_1.ethers.BigNumber.from(0);
|
|
110
|
-
_fee = ethers_1.ethers.BigNumber.from(0);
|
|
111
|
-
_j.label = 1;
|
|
112
|
-
case 1:
|
|
113
|
-
_j.trys.push([1, 3, , 8]);
|
|
114
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all(calls)];
|
|
115
|
-
case 2:
|
|
116
|
-
_f = (_j.sent()), _virtualPrice = _f[0], _fee = _f[1], _adminFee = _f[2], _A = _f[3], _lpTokenSupply = _f[4], _gamma = _f[5], _prices = _f.slice(6);
|
|
117
|
-
return [3 /*break*/, 8];
|
|
118
|
-
case 3:
|
|
119
|
-
e_1 = _j.sent();
|
|
120
|
-
calls.shift();
|
|
121
|
-
if (!this.isCrypto) return [3 /*break*/, 5];
|
|
122
|
-
calls.shift();
|
|
123
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all(calls)];
|
|
124
|
-
case 4:
|
|
125
|
-
_g = (_j.sent()), _adminFee = _g[0], _A = _g[1], _lpTokenSupply = _g[2], _gamma = _g[3], _prices = _g.slice(4);
|
|
126
|
-
return [3 /*break*/, 7];
|
|
127
|
-
case 5: return [4 /*yield*/, curve_1.curve.multicallProvider.all(calls)];
|
|
128
|
-
case 6:
|
|
129
|
-
_h = (_j.sent()), _fee = _h[0], _adminFee = _h[1], _A = _h[2], _lpTokenSupply = _h[3], _gamma = _h[4], _prices = _h.slice(5);
|
|
130
|
-
_j.label = 7;
|
|
131
|
-
case 7: return [3 /*break*/, 8];
|
|
132
|
-
case 8:
|
|
133
|
-
_c = [
|
|
134
|
-
ethers_1.ethers.utils.formatUnits(_virtualPrice),
|
|
135
|
-
ethers_1.ethers.utils.formatUnits(_fee, 8),
|
|
136
|
-
ethers_1.ethers.utils.formatUnits(_adminFee.mul(_fee)),
|
|
137
|
-
ethers_1.ethers.utils.formatUnits(_A, 0),
|
|
138
|
-
ethers_1.ethers.utils.formatUnits(_lpTokenSupply),
|
|
139
|
-
_gamma ? ethers_1.ethers.utils.formatUnits(_gamma) : _gamma,
|
|
140
|
-
], virtualPrice = _c[0], fee = _c[1], adminFee = _c[2], A = _c[3], lpTokenSupply = _c[4], gamma = _c[5];
|
|
141
|
-
if (this.isCrypto) {
|
|
142
|
-
prices = _prices.map(function (_p) { return ethers_1.ethers.utils.formatUnits(_p); });
|
|
143
|
-
priceOracle = [];
|
|
144
|
-
priceScale = [];
|
|
145
|
-
for (i = 0; i < this.wrappedCoins.length - 1; i++) {
|
|
146
|
-
priceOracle.push(prices.shift());
|
|
147
|
-
priceScale.push(prices.shift());
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
A_PRECISION = curve_1.curve.chainId === 1 && ['compound', 'usdt', 'y', 'busd', 'susd', 'pax', 'ren', 'sbtc', 'hbtc', '3pool'].includes(this.id) ? 1 : 100;
|
|
151
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all(additionalCalls)];
|
|
152
|
-
case 9:
|
|
153
|
-
_d = _j.sent(), _future_A = _d[0], _initial_A = _d[1], _future_A_time = _d[2], _initial_A_time = _d[3];
|
|
154
|
-
_e = [
|
|
155
|
-
_future_A ? String(Number(ethers_1.ethers.utils.formatUnits(_future_A, 0)) / A_PRECISION) : undefined,
|
|
156
|
-
_initial_A ? String(Number(ethers_1.ethers.utils.formatUnits(_initial_A, 0)) / A_PRECISION) : undefined,
|
|
157
|
-
_future_A_time ? Number(ethers_1.ethers.utils.formatUnits(_future_A_time, 0)) * 1000 : undefined,
|
|
158
|
-
_initial_A_time ? Number(ethers_1.ethers.utils.formatUnits(_initial_A_time, 0)) * 1000 : undefined,
|
|
159
|
-
], future_A = _e[0], initial_A = _e[1], future_A_time = _e[2], initial_A_time = _e[3];
|
|
160
|
-
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, priceOracle: priceOracle, priceScale: priceScale }];
|
|
35
|
+
const additionalCalls = this.isCrypto ? [] : [multicallContract.future_A()];
|
|
36
|
+
if ('initial_A' in multicallContract) {
|
|
37
|
+
additionalCalls.push(multicallContract.initial_A(), multicallContract.future_A_time(), multicallContract.initial_A_time());
|
|
38
|
+
}
|
|
39
|
+
let _virtualPrice = 0n;
|
|
40
|
+
let _fee = 0n;
|
|
41
|
+
let _prices, _adminFee, _A, _lpTokenSupply, _gamma;
|
|
42
|
+
try {
|
|
43
|
+
[_virtualPrice, _fee, _adminFee, _A, _lpTokenSupply, _gamma, ..._prices] = await curve.multicallProvider.all(calls);
|
|
44
|
+
}
|
|
45
|
+
catch (e) { // Empty pool
|
|
46
|
+
calls.shift();
|
|
47
|
+
if (this.isCrypto) {
|
|
48
|
+
calls.shift();
|
|
49
|
+
[_adminFee, _A, _lpTokenSupply, _gamma, ..._prices] = await curve.multicallProvider.all(calls);
|
|
161
50
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
for (_i = 0, _c = this.underlyingCoinAddresses; _i < _c.length; _i++) {
|
|
194
|
-
addr = _c[_i];
|
|
195
|
-
promises.push((0, utils_1._getUsdRate)(addr));
|
|
196
|
-
}
|
|
197
|
-
return [4 /*yield*/, Promise.all(promises)];
|
|
198
|
-
case 4:
|
|
199
|
-
prices = _d.sent();
|
|
200
|
-
totalLiquidity = balances.reduce(function (liquidity, b, i) { return liquidity + (Number(b) * prices[i]); }, 0);
|
|
201
|
-
return [2 /*return*/, totalLiquidity.toFixed(8)];
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
});
|
|
51
|
+
else {
|
|
52
|
+
[_fee, _adminFee, _A, _lpTokenSupply, _gamma, ..._prices] = await curve.multicallProvider.all(calls);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const [virtualPrice, fee, adminFee, A, lpTokenSupply, gamma] = [
|
|
56
|
+
curve.formatUnits(_virtualPrice),
|
|
57
|
+
curve.formatUnits(_fee, 8),
|
|
58
|
+
curve.formatUnits(_adminFee * _fee),
|
|
59
|
+
curve.formatUnits(_A, 0),
|
|
60
|
+
curve.formatUnits(_lpTokenSupply),
|
|
61
|
+
_gamma ? curve.formatUnits(_gamma) : undefined,
|
|
62
|
+
];
|
|
63
|
+
let priceOracle, priceScale;
|
|
64
|
+
if (this.isCrypto) {
|
|
65
|
+
const prices = _prices.map((_p) => curve.formatUnits(_p));
|
|
66
|
+
priceOracle = [];
|
|
67
|
+
priceScale = [];
|
|
68
|
+
for (let i = 0; i < this.wrappedCoins.length - 1; i++) {
|
|
69
|
+
priceOracle.push(prices.shift());
|
|
70
|
+
priceScale.push(prices.shift());
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const A_PRECISION = curve.chainId === 1 && ['compound', 'usdt', 'y', 'busd', 'susd', 'pax', 'ren', 'sbtc', 'hbtc', '3pool'].includes(this.id) ? 1 : 100;
|
|
74
|
+
const [_future_A, _initial_A, _future_A_time, _initial_A_time] = await curve.multicallProvider.all(additionalCalls);
|
|
75
|
+
const [future_A, initial_A, future_A_time, initial_A_time] = [
|
|
76
|
+
_future_A ? String(Number(curve.formatUnits(_future_A, 0)) / A_PRECISION) : undefined,
|
|
77
|
+
_initial_A ? String(Number(curve.formatUnits(_initial_A, 0)) / A_PRECISION) : undefined,
|
|
78
|
+
_future_A_time ? Number(curve.formatUnits(_future_A_time, 0)) * 1000 : undefined,
|
|
79
|
+
_initial_A_time ? Number(curve.formatUnits(_initial_A_time, 0)) * 1000 : undefined,
|
|
80
|
+
];
|
|
81
|
+
return { lpTokenSupply, virtualPrice, fee, adminFee, A, future_A, initial_A, future_A_time, initial_A_time, gamma, priceOracle, priceScale };
|
|
205
82
|
};
|
|
206
|
-
this.
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (this.id in mainPoolsData) {
|
|
221
|
-
return [2 /*return*/, ((_d = mainPoolsData[this.id].volume) !== null && _d !== void 0 ? _d : 0).toString()];
|
|
222
|
-
}
|
|
223
|
-
poolData_1 = factoryPoolsData.find(function (d) { return d.poolAddress.toLowerCase() === _this.address; });
|
|
224
|
-
if (!poolData_1)
|
|
225
|
-
throw Error("Can't get Volume for ".concat(this.name, " (id: ").concat(this.id, ")"));
|
|
226
|
-
return [4 /*yield*/, (0, utils_1._getUsdRate)(this.lpToken)];
|
|
227
|
-
case 2:
|
|
228
|
-
lpPrice = _e.sent();
|
|
229
|
-
return [2 /*return*/, (poolData_1.volume * lpPrice).toString()];
|
|
230
|
-
case 3:
|
|
231
|
-
network = curve_1.curve.constants.NETWORK_NAME;
|
|
232
|
-
return [4 /*yield*/, (0, external_api_1._getSubgraphData)(network)];
|
|
233
|
-
case 4:
|
|
234
|
-
poolsData = (_e.sent()).poolsData;
|
|
235
|
-
poolData = poolsData.find(function (d) { return d.address.toLowerCase() === _this.address; });
|
|
236
|
-
if (!poolData)
|
|
237
|
-
throw Error("Can't get Volume for ".concat(this.name, " (id: ").concat(this.id, ")"));
|
|
238
|
-
return [2 /*return*/, poolData.volumeUSD.toString()];
|
|
83
|
+
this.statsTotalLiquidity = async (useApi = true) => {
|
|
84
|
+
if (useApi) {
|
|
85
|
+
const network = curve.constants.NETWORK_NAME;
|
|
86
|
+
const poolType = !this.isFactory && !this.isCrypto ? "main" :
|
|
87
|
+
!this.isFactory ? "crypto" :
|
|
88
|
+
!(this.isCrypto && this.isFactory) ? "factory" :
|
|
89
|
+
"factory-crypto";
|
|
90
|
+
const poolsData = (await _getPoolsFromApi(network, poolType)).poolData;
|
|
91
|
+
try {
|
|
92
|
+
const totalLiquidity = poolsData.filter((data) => data.address.toLowerCase() === this.address.toLowerCase())[0].usdTotal;
|
|
93
|
+
return String(totalLiquidity);
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
console.log(this.id, err.message);
|
|
239
97
|
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
98
|
+
}
|
|
99
|
+
const balances = await this.statsUnderlyingBalances();
|
|
100
|
+
const promises = [];
|
|
101
|
+
for (const addr of this.underlyingCoinAddresses) {
|
|
102
|
+
promises.push(_getUsdRate(addr));
|
|
103
|
+
}
|
|
104
|
+
const prices = await Promise.all(promises);
|
|
105
|
+
const totalLiquidity = balances.reduce((liquidity, b, i) => liquidity + (Number(b) * prices[i]), 0);
|
|
106
|
+
return totalLiquidity.toFixed(8);
|
|
107
|
+
};
|
|
108
|
+
this.statsVolume = async () => {
|
|
109
|
+
if ([1284, 2222, 42220, 1313161554].includes(curve.chainId)) { // Moonbeam || Kava || Celo || Aurora
|
|
110
|
+
const [mainPoolsData, factoryPoolsData] = await Promise.all([
|
|
111
|
+
_getLegacyAPYsAndVolumes(curve.constants.NETWORK_NAME),
|
|
112
|
+
_getFactoryAPYsAndVolumes(curve.constants.NETWORK_NAME),
|
|
113
|
+
]);
|
|
114
|
+
if (this.id in mainPoolsData) {
|
|
115
|
+
return (mainPoolsData[this.id].volume ?? 0).toString();
|
|
116
|
+
}
|
|
117
|
+
const poolData = factoryPoolsData.find((d) => d.poolAddress.toLowerCase() === this.address);
|
|
118
|
+
if (!poolData)
|
|
119
|
+
throw Error(`Can't get Volume for ${this.name} (id: ${this.id})`);
|
|
120
|
+
const lpPrice = await _getUsdRate(this.lpToken);
|
|
121
|
+
return (poolData.volume * lpPrice).toString();
|
|
122
|
+
}
|
|
123
|
+
const network = curve.constants.NETWORK_NAME;
|
|
124
|
+
const poolsData = (await _getSubgraphData(network)).poolsData;
|
|
125
|
+
const poolData = poolsData.find((d) => d.address.toLowerCase() === this.address);
|
|
126
|
+
if (!poolData)
|
|
127
|
+
throw Error(`Can't get Volume for ${this.name} (id: ${this.id})`);
|
|
128
|
+
return poolData.volumeUSD.toString();
|
|
129
|
+
};
|
|
130
|
+
this.statsBaseApy = async () => {
|
|
131
|
+
if ([1284, 2222, 42220, 1313161554].includes(curve.chainId)) { // Moonbeam || Kava || Celo || Aurora
|
|
132
|
+
const [mainPoolsData, factoryPoolsData] = await Promise.all([
|
|
133
|
+
_getLegacyAPYsAndVolumes(curve.constants.NETWORK_NAME),
|
|
134
|
+
_getFactoryAPYsAndVolumes(curve.constants.NETWORK_NAME),
|
|
135
|
+
]);
|
|
136
|
+
if (this.id in mainPoolsData) {
|
|
137
|
+
return {
|
|
138
|
+
day: mainPoolsData[this.id].apy.day.toString(),
|
|
139
|
+
week: mainPoolsData[this.id].apy.week.toString(),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const poolData = factoryPoolsData.find((d) => d.poolAddress.toLowerCase() === this.address);
|
|
143
|
+
if (!poolData)
|
|
144
|
+
throw Error(`Can't get base APY for ${this.name} (id: ${this.id})`);
|
|
145
|
+
return {
|
|
146
|
+
day: poolData.apy.toString(),
|
|
147
|
+
week: poolData.apy.toString(),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
const network = curve.constants.NETWORK_NAME;
|
|
151
|
+
const poolsData = (await _getSubgraphData(network)).poolsData;
|
|
152
|
+
const poolData = poolsData.find((d) => d.address.toLowerCase() === this.address);
|
|
153
|
+
if (!poolData)
|
|
154
|
+
throw Error(`Can't get base APY for ${this.name} (id: ${this.id})`);
|
|
155
|
+
return {
|
|
156
|
+
day: poolData.latestDailyApy.toString(),
|
|
157
|
+
week: poolData.latestWeeklyApy.toString(),
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
this.statsTokenApy = async (useApi = true) => {
|
|
161
|
+
if (this.rewardsOnly())
|
|
162
|
+
throw Error(`${this.name} has Rewards-Only Gauge. Use stats.rewardsApy instead`);
|
|
163
|
+
const isDisabledChain = [1313161554].includes(curve.chainId); // Disable Aurora
|
|
164
|
+
if (useApi && !isDisabledChain) {
|
|
165
|
+
const crvAPYs = await _getCrvApyFromApi();
|
|
166
|
+
const poolCrvApy = crvAPYs[this.gauge] ?? [0, 0]; // new pools might be missing
|
|
167
|
+
return [poolCrvApy[0], poolCrvApy[1]];
|
|
168
|
+
}
|
|
169
|
+
const totalLiquidityUSD = await this.statsTotalLiquidity();
|
|
170
|
+
if (Number(totalLiquidityUSD) === 0)
|
|
171
|
+
return [0, 0];
|
|
172
|
+
let inflationRateBN, workingSupplyBN, totalSupplyBN;
|
|
173
|
+
if (curve.chainId !== 1) {
|
|
174
|
+
const gaugeContract = curve.contracts[this.gauge].multicallContract;
|
|
175
|
+
const lpTokenContract = curve.contracts[this.lpToken].multicallContract;
|
|
176
|
+
const crvContract = curve.contracts[curve.constants.ALIASES.crv].contract;
|
|
177
|
+
const currentWeek = Math.floor(Date.now() / 1000 / WEEK);
|
|
178
|
+
[inflationRateBN, workingSupplyBN, totalSupplyBN] = (await curve.multicallProvider.all([
|
|
179
|
+
gaugeContract.inflation_rate(currentWeek),
|
|
180
|
+
gaugeContract.working_supply(),
|
|
181
|
+
lpTokenContract.totalSupply(),
|
|
182
|
+
])).map((value) => toBN(value));
|
|
183
|
+
if (inflationRateBN.eq(0)) {
|
|
184
|
+
inflationRateBN = toBN(await crvContract.balanceOf(this.gauge, curve.constantOptions)).div(WEEK);
|
|
280
185
|
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
case 3:
|
|
303
|
-
totalLiquidityUSD = _g.sent();
|
|
304
|
-
if (Number(totalLiquidityUSD) === 0)
|
|
305
|
-
return [2 /*return*/, [0, 0]];
|
|
306
|
-
if (!(curve_1.curve.chainId !== 1)) return [3 /*break*/, 7];
|
|
307
|
-
gaugeContract = curve_1.curve.contracts[this.gauge].multicallContract;
|
|
308
|
-
lpTokenContract = curve_1.curve.contracts[this.lpToken].multicallContract;
|
|
309
|
-
crvContract = curve_1.curve.contracts[curve_1.curve.constants.ALIASES.crv].contract;
|
|
310
|
-
currentWeek = Math.floor(Date.now() / 1000 / WEEK);
|
|
311
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all([
|
|
312
|
-
gaugeContract.inflation_rate(currentWeek),
|
|
313
|
-
gaugeContract.working_supply(),
|
|
314
|
-
lpTokenContract.totalSupply(),
|
|
315
|
-
])];
|
|
316
|
-
case 4:
|
|
317
|
-
_d = (_g.sent()).map(function (value) { return (0, utils_1.toBN)(value); }), inflationRateBN = _d[0], workingSupplyBN = _d[1], totalSupplyBN = _d[2];
|
|
318
|
-
if (!inflationRateBN.eq(0)) return [3 /*break*/, 6];
|
|
319
|
-
_c = utils_1.toBN;
|
|
320
|
-
return [4 /*yield*/, crvContract.balanceOf(this.gauge, curve_1.curve.constantOptions)];
|
|
321
|
-
case 5:
|
|
322
|
-
inflationRateBN = _c.apply(void 0, [_g.sent()]).div(WEEK);
|
|
323
|
-
_g.label = 6;
|
|
324
|
-
case 6: return [3 /*break*/, 9];
|
|
325
|
-
case 7:
|
|
326
|
-
gaugeContract = curve_1.curve.contracts[this.gauge].multicallContract;
|
|
327
|
-
lpTokenContract = curve_1.curve.contracts[this.lpToken].multicallContract;
|
|
328
|
-
gaugeControllerContract = curve_1.curve.contracts[curve_1.curve.constants.ALIASES.gauge_controller].multicallContract;
|
|
329
|
-
weightBN = void 0;
|
|
330
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all([
|
|
331
|
-
gaugeContract.inflation_rate(),
|
|
332
|
-
gaugeControllerContract.gauge_relative_weight(this.gauge),
|
|
333
|
-
gaugeContract.working_supply(),
|
|
334
|
-
lpTokenContract.totalSupply(),
|
|
335
|
-
])];
|
|
336
|
-
case 8:
|
|
337
|
-
_e = (_g.sent()).map(function (value) { return (0, utils_1.toBN)(value); }), inflationRateBN = _e[0], weightBN = _e[1], workingSupplyBN = _e[2], totalSupplyBN = _e[3];
|
|
338
|
-
inflationRateBN = inflationRateBN.times(weightBN);
|
|
339
|
-
_g.label = 9;
|
|
340
|
-
case 9:
|
|
341
|
-
if (inflationRateBN.eq(0))
|
|
342
|
-
return [2 /*return*/, [0, 0]];
|
|
343
|
-
rateBN = inflationRateBN.times(31536000).times(0.4).div(workingSupplyBN).times(totalSupplyBN).div(Number(totalLiquidityUSD));
|
|
344
|
-
return [4 /*yield*/, (0, utils_1._getUsdRate)(curve_1.curve.constants.ALIASES.crv)];
|
|
345
|
-
case 10:
|
|
346
|
-
crvPrice = _g.sent();
|
|
347
|
-
baseApyBN = rateBN.times(crvPrice);
|
|
348
|
-
boostedApyBN = baseApyBN.times(2.5);
|
|
349
|
-
return [2 /*return*/, [baseApyBN.times(100).toNumber(), boostedApyBN.times(100).toNumber()]];
|
|
350
|
-
}
|
|
351
|
-
});
|
|
352
|
-
});
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
const gaugeContract = curve.contracts[this.gauge].multicallContract;
|
|
189
|
+
const lpTokenContract = curve.contracts[this.lpToken].multicallContract;
|
|
190
|
+
const gaugeControllerContract = curve.contracts[curve.constants.ALIASES.gauge_controller].multicallContract;
|
|
191
|
+
let weightBN;
|
|
192
|
+
[inflationRateBN, weightBN, workingSupplyBN, totalSupplyBN] = (await curve.multicallProvider.all([
|
|
193
|
+
gaugeContract.inflation_rate(),
|
|
194
|
+
gaugeControllerContract.gauge_relative_weight(this.gauge),
|
|
195
|
+
gaugeContract.working_supply(),
|
|
196
|
+
lpTokenContract.totalSupply(),
|
|
197
|
+
])).map((value) => toBN(value));
|
|
198
|
+
inflationRateBN = inflationRateBN.times(weightBN);
|
|
199
|
+
}
|
|
200
|
+
if (inflationRateBN.eq(0))
|
|
201
|
+
return [0, 0];
|
|
202
|
+
const rateBN = inflationRateBN.times(31536000).times(0.4).div(workingSupplyBN).times(totalSupplyBN).div(Number(totalLiquidityUSD));
|
|
203
|
+
const crvPrice = await _getUsdRate(curve.constants.ALIASES.crv);
|
|
204
|
+
const baseApyBN = rateBN.times(crvPrice);
|
|
205
|
+
const boostedApyBN = baseApyBN.times(2.5);
|
|
206
|
+
return [baseApyBN.times(100).toNumber(), boostedApyBN.times(100).toNumber()];
|
|
353
207
|
};
|
|
354
|
-
this.statsRewardsApy =
|
|
355
|
-
if (
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
rewardRate = _d.sent();
|
|
390
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all([
|
|
391
|
-
rewardContract.reward_data(rewardToken.token),
|
|
392
|
-
gaugeContract.totalSupply(),
|
|
393
|
-
lpTokenContract.totalSupply(),
|
|
394
|
-
])];
|
|
395
|
-
case 7:
|
|
396
|
-
_c = _d.sent(), rewardData = _c[0], _stakedSupply = _c[1], _totalSupply = _c[2];
|
|
397
|
-
stakedSupplyBN = (0, utils_1.toBN)(_stakedSupply);
|
|
398
|
-
totalSupplyBN = (0, utils_1.toBN)(_totalSupply);
|
|
399
|
-
inflationBN = (0, utils_1.toBN)(rewardData.rate, rewardToken.decimals);
|
|
400
|
-
periodFinish = Number(ethers_1.ethers.utils.formatUnits(rewardData.period_finish, 0)) * 1000;
|
|
401
|
-
baseApy = periodFinish > Date.now() ?
|
|
402
|
-
inflationBN.times(31536000).times(rewardRate).div(stakedSupplyBN).times(totalSupplyBN).div(Number(totalLiquidityUSD)) :
|
|
403
|
-
(0, utils_1.BN)(0);
|
|
404
|
-
apy.push({
|
|
405
|
-
gaugeAddress: this.gauge,
|
|
406
|
-
tokenAddress: rewardToken.token,
|
|
407
|
-
symbol: rewardToken.symbol,
|
|
408
|
-
apy: baseApy.times(100).toNumber(),
|
|
409
|
-
});
|
|
410
|
-
_d.label = 8;
|
|
411
|
-
case 8:
|
|
412
|
-
_i++;
|
|
413
|
-
return [3 /*break*/, 4];
|
|
414
|
-
case 9: return [2 /*return*/, apy];
|
|
415
|
-
}
|
|
208
|
+
this.statsRewardsApy = async (useApi = true) => {
|
|
209
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS)
|
|
210
|
+
return [];
|
|
211
|
+
const isDisabledChain = [1313161554].includes(curve.chainId); // Disable Aurora
|
|
212
|
+
if (curve.chainId === 1 || (useApi && !isDisabledChain)) {
|
|
213
|
+
const rewards = await _getRewardsFromApi();
|
|
214
|
+
if (!rewards[this.gauge])
|
|
215
|
+
return [];
|
|
216
|
+
return rewards[this.gauge].map((r) => ({ gaugeAddress: r.gaugeAddress, tokenAddress: r.tokenAddress, symbol: r.symbol, apy: r.apy }));
|
|
217
|
+
}
|
|
218
|
+
const apy = [];
|
|
219
|
+
const rewardTokens = await this.rewardTokens(false);
|
|
220
|
+
for (const rewardToken of rewardTokens) {
|
|
221
|
+
const gaugeContract = curve.contracts[this.gauge].multicallContract;
|
|
222
|
+
const lpTokenContract = curve.contracts[this.lpToken].multicallContract;
|
|
223
|
+
const rewardContract = curve.contracts[this.sRewardContract || this.gauge].multicallContract;
|
|
224
|
+
const totalLiquidityUSD = await this.statsTotalLiquidity();
|
|
225
|
+
const rewardRate = await _getUsdRate(rewardToken.token);
|
|
226
|
+
const [rewardData, _stakedSupply, _totalSupply] = await curve.multicallProvider.all([
|
|
227
|
+
rewardContract.reward_data(rewardToken.token),
|
|
228
|
+
gaugeContract.totalSupply(),
|
|
229
|
+
lpTokenContract.totalSupply(),
|
|
230
|
+
]);
|
|
231
|
+
const stakedSupplyBN = toBN(_stakedSupply);
|
|
232
|
+
const totalSupplyBN = toBN(_totalSupply);
|
|
233
|
+
const inflationBN = toBN(rewardData.rate, rewardToken.decimals);
|
|
234
|
+
const periodFinish = Number(curve.formatUnits(rewardData.period_finish, 0)) * 1000;
|
|
235
|
+
const baseApy = periodFinish > Date.now() ?
|
|
236
|
+
inflationBN.times(31536000).times(rewardRate).div(stakedSupplyBN).times(totalSupplyBN).div(Number(totalLiquidityUSD)) :
|
|
237
|
+
BN(0);
|
|
238
|
+
apy.push({
|
|
239
|
+
gaugeAddress: this.gauge,
|
|
240
|
+
tokenAddress: rewardToken.token,
|
|
241
|
+
symbol: rewardToken.symbol,
|
|
242
|
+
apy: baseApy.times(100).toNumber(),
|
|
416
243
|
});
|
|
417
|
-
}
|
|
244
|
+
}
|
|
245
|
+
return apy;
|
|
418
246
|
};
|
|
419
|
-
this._calcLpTokenAmount = (
|
|
420
|
-
|
|
421
|
-
if (
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
curve_1.curve.multicallProvider.all(calls),
|
|
485
|
-
this.isMeta && useUnderlying ? this.stats.underlyingBalances() : this.stats.wrappedBalances(),
|
|
486
|
-
])];
|
|
487
|
-
case 9:
|
|
488
|
-
res = _e.sent();
|
|
489
|
-
_c = res[0], _totalSupply = _c[0], _fee = _c[1], _lpTokenAmount = _c[2];
|
|
490
|
-
balances = res[1];
|
|
491
|
-
_d = [(0, utils_1.toBN)(_totalSupply), (0, utils_1.toBN)(_fee, 10).times(N_coins).div(4 * (N_coins - 1)), (0, utils_1.toBN)(_lpTokenAmount)], totalSupplyBN = _d[0], feeBN = _d[1], lpTokenAmountBN = _d[2];
|
|
492
|
-
balancesBN = balances.map(function (b) { return (0, utils_1.BN)(b); });
|
|
493
|
-
amountsBN = _amounts.map(function (_a, i) { return (0, utils_1.toBN)(_a, decimals_2[i]); });
|
|
494
|
-
feesBN = Array(N_coins).fill((0, utils_1.BN)(0));
|
|
495
|
-
if (totalSupplyBN.gt(0)) {
|
|
496
|
-
for (i = 0; i < N_coins; i++) {
|
|
497
|
-
feesBN[i] = balancesBN[i].times(lpTokenAmountBN).div(totalSupplyBN).minus(amountsBN[i]).times(feeBN);
|
|
498
|
-
if (feesBN[i].lt(0))
|
|
499
|
-
feesBN[i] = feesBN[i].times(-1);
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
_fees = feesBN.map(function (fBN, i) { return (0, utils_1.fromBN)(fBN, decimals_2[i]); });
|
|
503
|
-
return [4 /*yield*/, this._pureCalcLpTokenAmount(_fees, !isDeposit, this.isMeta && useUnderlying)];
|
|
504
|
-
case 10:
|
|
505
|
-
_lpTokenFee = _e.sent();
|
|
506
|
-
if (isDeposit)
|
|
507
|
-
_lpTokenFee = _lpTokenFee.mul(-1);
|
|
508
|
-
return [2 /*return*/, _lpTokenAmount.add(_lpTokenFee)];
|
|
509
|
-
case 11:
|
|
510
|
-
e_3 = _e.sent();
|
|
511
|
-
if (!isDeposit)
|
|
512
|
-
throw e_3; // Seeding is only for deposit
|
|
513
|
-
lpContract = curve_1.curve.contracts[this.lpToken].contract;
|
|
514
|
-
return [4 /*yield*/, lpContract.totalSupply(curve_1.curve.constantOptions)];
|
|
515
|
-
case 12:
|
|
516
|
-
_lpTotalSupply = _e.sent();
|
|
517
|
-
if (_lpTotalSupply.gt(0))
|
|
518
|
-
throw e_3; // Already seeded
|
|
519
|
-
decimals_3 = useUnderlying ? this.underlyingDecimals : this.wrappedDecimals;
|
|
520
|
-
amounts_1 = _amounts.map(function (_a, i) { return ethers_1.ethers.utils.formatUnits(_a, decimals_3[i]); });
|
|
521
|
-
if (!(this.isMeta && useUnderlying)) return [3 /*break*/, 14];
|
|
522
|
-
return [4 /*yield*/, this.metaUnderlyingSeedAmounts(amounts_1[0])];
|
|
523
|
-
case 13:
|
|
524
|
-
seedAmounts_2 = _e.sent();
|
|
525
|
-
amounts_1.forEach(function (a, i) {
|
|
526
|
-
if (!(0, utils_1.BN)(a).eq((0, utils_1.BN)(seedAmounts_2[i])))
|
|
527
|
-
throw Error("Amounts must be = ".concat(seedAmounts_2));
|
|
528
|
-
});
|
|
529
|
-
return [3 /*break*/, 15];
|
|
530
|
-
case 14:
|
|
531
|
-
if (_amounts[0].lte(0))
|
|
532
|
-
throw Error("Initial deposit amounts must be >0");
|
|
533
|
-
amounts_1.forEach(function (a) {
|
|
534
|
-
if (a !== amounts_1[0])
|
|
535
|
-
throw Error("Initial deposit amounts must be equal");
|
|
536
|
-
});
|
|
537
|
-
_e.label = 15;
|
|
538
|
-
case 15:
|
|
539
|
-
_amounts18Decimals = amounts_1.map(function (a) { return (0, utils_1.parseUnits)(a); });
|
|
540
|
-
return [2 /*return*/, _amounts18Decimals.reduce(function (_a, _b) { return _a.add(_b); })];
|
|
541
|
-
case 16: return [2 /*return*/];
|
|
247
|
+
this._calcLpTokenAmount = memoize(async (_amounts, isDeposit = true, useUnderlying = true) => {
|
|
248
|
+
let _rates = [];
|
|
249
|
+
if (!this.isMeta && useUnderlying) {
|
|
250
|
+
// For lending pools. For others rate = 1
|
|
251
|
+
_rates = await this._getRates();
|
|
252
|
+
_amounts = _amounts.map((_amount, i) => _amount * (10n ** 18n) / _rates[i]);
|
|
253
|
+
}
|
|
254
|
+
if (this.isCrypto) {
|
|
255
|
+
try {
|
|
256
|
+
return await this._pureCalcLpTokenAmount(_amounts, isDeposit, useUnderlying);
|
|
257
|
+
}
|
|
258
|
+
catch (e) {
|
|
259
|
+
const lpContract = curve.contracts[this.lpToken].contract;
|
|
260
|
+
const _lpTotalSupply = await lpContract.totalSupply(curve.constantOptions);
|
|
261
|
+
if (_lpTotalSupply > 0n)
|
|
262
|
+
throw e; // Already seeded
|
|
263
|
+
if (this.isMeta && useUnderlying)
|
|
264
|
+
throw Error("Initial deposit for crypto meta pools must be in wrapped coins");
|
|
265
|
+
const decimals = useUnderlying ? this.underlyingDecimals : this.wrappedDecimals;
|
|
266
|
+
const amounts = _amounts.map((_a, i) => curve.formatUnits(_a, decimals[i]));
|
|
267
|
+
const seedAmounts = await this.cryptoSeedAmounts(amounts[0]); // Checks N coins == 2 and amounts > 0
|
|
268
|
+
amounts.forEach((a, i) => {
|
|
269
|
+
if (!BN(a).eq(BN(seedAmounts[i])))
|
|
270
|
+
throw Error(`Amounts must be = ${seedAmounts}`);
|
|
271
|
+
});
|
|
272
|
+
return parseUnits(Math.sqrt(Number(amounts[0]) * Number(amounts[1])));
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
try {
|
|
276
|
+
// --- Getting lpAmount before fees and pool params ---
|
|
277
|
+
const N_coins = this.isMeta && useUnderlying ? this.underlyingCoins.length : this.wrappedCoins.length;
|
|
278
|
+
const decimals = this.isMeta && useUnderlying ? this.underlyingDecimals : this.wrappedDecimals;
|
|
279
|
+
const calcContractAddress = this.isMeta && useUnderlying ? this.zap : this.address;
|
|
280
|
+
const calcContract = curve.contracts[calcContractAddress].multicallContract;
|
|
281
|
+
const poolContract = curve.contracts[this.address].multicallContract;
|
|
282
|
+
const lpContract = curve.contracts[this.lpToken].multicallContract;
|
|
283
|
+
// totalSupply and fee
|
|
284
|
+
const calls = [lpContract.totalSupply(), poolContract.fee()];
|
|
285
|
+
// lpAmount before fees
|
|
286
|
+
if (this.isMetaFactory && useUnderlying) {
|
|
287
|
+
calls.push(calcContract.calc_token_amount(this.address, _amounts, isDeposit));
|
|
288
|
+
}
|
|
289
|
+
else if (calcContract[`calc_token_amount(uint256[${N_coins}],bool)`]) {
|
|
290
|
+
calls.push(calcContract.calc_token_amount(_amounts, isDeposit, curve.constantOptions));
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
calls.push(calcContract.calc_token_amount(_amounts, curve.constantOptions));
|
|
294
|
+
}
|
|
295
|
+
const res = await Promise.all([
|
|
296
|
+
curve.multicallProvider.all(calls),
|
|
297
|
+
this.isMeta && useUnderlying ? this.stats.underlyingBalances() : this.stats.wrappedBalances(),
|
|
298
|
+
]);
|
|
299
|
+
const [_totalSupply, _fee, _lpTokenAmount] = res[0];
|
|
300
|
+
const balances = res[1];
|
|
301
|
+
const [totalSupplyBN, feeBN, lpTokenAmountBN] = [toBN(_totalSupply), toBN(_fee, 10).times(N_coins).div(4 * (N_coins - 1)), toBN(_lpTokenAmount)];
|
|
302
|
+
const balancesBN = balances.map((b) => BN(b));
|
|
303
|
+
const amountsBN = _amounts.map((_a, i) => toBN(_a, decimals[i]));
|
|
304
|
+
// --- Calculating new amounts (old amounts minus fees) ---
|
|
305
|
+
// fees[i] = | expected1/total_supply * balances[i] - amounts[i] | * fee
|
|
306
|
+
const feesBN = Array(N_coins).fill(BN(0));
|
|
307
|
+
if (totalSupplyBN.gt(0)) {
|
|
308
|
+
for (let i = 0; i < N_coins; i++) {
|
|
309
|
+
feesBN[i] = balancesBN[i].times(lpTokenAmountBN).div(totalSupplyBN).minus(amountsBN[i]).times(feeBN);
|
|
310
|
+
if (feesBN[i].lt(0))
|
|
311
|
+
feesBN[i] = feesBN[i].times(-1);
|
|
542
312
|
}
|
|
543
|
-
}
|
|
544
|
-
|
|
313
|
+
}
|
|
314
|
+
const _fees = feesBN.map((fBN, i) => fromBN(fBN, decimals[i]));
|
|
315
|
+
// --- Getting final lpAmount ---
|
|
316
|
+
let _lpTokenFee = await this._pureCalcLpTokenAmount(_fees, !isDeposit, this.isMeta && useUnderlying);
|
|
317
|
+
if (isDeposit)
|
|
318
|
+
_lpTokenFee = _lpTokenFee * (-1n);
|
|
319
|
+
return _lpTokenAmount + _lpTokenFee;
|
|
320
|
+
}
|
|
321
|
+
catch (e) { // Seeding
|
|
322
|
+
if (!isDeposit)
|
|
323
|
+
throw e; // Seeding is only for deposit
|
|
324
|
+
const lpContract = curve.contracts[this.lpToken].contract;
|
|
325
|
+
const _lpTotalSupply = await lpContract.totalSupply(curve.constantOptions);
|
|
326
|
+
if (_lpTotalSupply > 0n)
|
|
327
|
+
throw e; // Already seeded
|
|
328
|
+
const decimals = useUnderlying ? this.underlyingDecimals : this.wrappedDecimals;
|
|
329
|
+
const amounts = _amounts.map((_a, i) => curve.formatUnits(_a, decimals[i]));
|
|
330
|
+
if (this.isMeta && useUnderlying) {
|
|
331
|
+
const seedAmounts = this.metaUnderlyingSeedAmounts(amounts[0]); // Checks N coins == 2 and amounts > 0
|
|
332
|
+
amounts.forEach((a, i) => {
|
|
333
|
+
if (!BN(a).eq(BN(seedAmounts[i])))
|
|
334
|
+
throw Error(`Amounts must be = ${seedAmounts}`);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
if (_amounts[0] <= 0n)
|
|
339
|
+
throw Error("Initial deposit amounts must be >0");
|
|
340
|
+
amounts.forEach((a) => {
|
|
341
|
+
if (a !== amounts[0])
|
|
342
|
+
throw Error("Initial deposit amounts must be equal");
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
const _amounts18Decimals = amounts.map((a) => parseUnits(a));
|
|
346
|
+
return _amounts18Decimals.reduce((_a, _b) => _a + _b);
|
|
347
|
+
}
|
|
545
348
|
}, {
|
|
546
349
|
primitive: true,
|
|
547
350
|
promise: true,
|
|
548
351
|
maxAge: 60 * 1000, // 1m
|
|
549
352
|
});
|
|
550
353
|
// ---------------- CRV PROFIT, CLAIM, BOOSTING ----------------
|
|
551
|
-
this.crvProfit =
|
|
552
|
-
if (
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
price: crvPrice,
|
|
608
|
-
}];
|
|
609
|
-
dailyIncome = inflationRateBN.times(DAY).times(workingBalanceBN).div(workingSupplyBN);
|
|
610
|
-
weeklyIncome = inflationRateBN.times(WEEK).times(workingBalanceBN).div(workingSupplyBN);
|
|
611
|
-
monthlyIncome = inflationRateBN.times(MONTH).times(workingBalanceBN).div(workingSupplyBN);
|
|
612
|
-
annualIncome = inflationRateBN.times(YEAR).times(workingBalanceBN).div(workingSupplyBN);
|
|
613
|
-
return [2 /*return*/, {
|
|
614
|
-
day: dailyIncome.toString(),
|
|
615
|
-
week: weeklyIncome.toString(),
|
|
616
|
-
month: monthlyIncome.toString(),
|
|
617
|
-
year: annualIncome.toString(),
|
|
618
|
-
token: curve_1.curve.constants.ALIASES.crv,
|
|
619
|
-
symbol: 'CRV',
|
|
620
|
-
price: crvPrice,
|
|
621
|
-
}];
|
|
622
|
-
}
|
|
623
|
-
});
|
|
624
|
-
});
|
|
354
|
+
this.crvProfit = async (address = "") => {
|
|
355
|
+
if (this.rewardsOnly())
|
|
356
|
+
throw Error(`${this.name} has Rewards-Only Gauge. Use rewardsProfit instead`);
|
|
357
|
+
address = address || curve.signerAddress;
|
|
358
|
+
if (!address)
|
|
359
|
+
throw Error("Need to connect wallet or pass address into args");
|
|
360
|
+
let inflationRateBN, workingSupplyBN, workingBalanceBN;
|
|
361
|
+
if (curve.chainId !== 1) {
|
|
362
|
+
const gaugeContract = curve.contracts[this.gauge].multicallContract;
|
|
363
|
+
const crvContract = curve.contracts[curve.constants.ALIASES.crv].contract;
|
|
364
|
+
const currentWeek = Math.floor(Date.now() / 1000 / WEEK);
|
|
365
|
+
[inflationRateBN, workingBalanceBN, workingSupplyBN] = (await curve.multicallProvider.all([
|
|
366
|
+
gaugeContract.inflation_rate(currentWeek),
|
|
367
|
+
gaugeContract.working_balances(address),
|
|
368
|
+
gaugeContract.working_supply(),
|
|
369
|
+
])).map((value) => toBN(value));
|
|
370
|
+
if (inflationRateBN.eq(0)) {
|
|
371
|
+
inflationRateBN = toBN(await crvContract.balanceOf(this.gauge, curve.constantOptions)).div(WEEK);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
const gaugeContract = curve.contracts[this.gauge].multicallContract;
|
|
376
|
+
const gaugeControllerContract = curve.contracts[curve.constants.ALIASES.gauge_controller].multicallContract;
|
|
377
|
+
let weightBN;
|
|
378
|
+
[inflationRateBN, weightBN, workingBalanceBN, workingSupplyBN] = (await curve.multicallProvider.all([
|
|
379
|
+
gaugeContract.inflation_rate(),
|
|
380
|
+
gaugeControllerContract.gauge_relative_weight(this.gauge),
|
|
381
|
+
gaugeContract.working_balances(address),
|
|
382
|
+
gaugeContract.working_supply(),
|
|
383
|
+
])).map((value) => toBN(value));
|
|
384
|
+
inflationRateBN = inflationRateBN.times(weightBN);
|
|
385
|
+
}
|
|
386
|
+
const crvPrice = await _getUsdRate('CRV');
|
|
387
|
+
if (workingSupplyBN.eq(0))
|
|
388
|
+
return {
|
|
389
|
+
day: "0.0",
|
|
390
|
+
week: "0.0",
|
|
391
|
+
month: "0.0",
|
|
392
|
+
year: "0.0",
|
|
393
|
+
token: curve.constants.ALIASES.crv,
|
|
394
|
+
symbol: 'CRV',
|
|
395
|
+
price: crvPrice,
|
|
396
|
+
};
|
|
397
|
+
const dailyIncome = inflationRateBN.times(DAY).times(workingBalanceBN).div(workingSupplyBN);
|
|
398
|
+
const weeklyIncome = inflationRateBN.times(WEEK).times(workingBalanceBN).div(workingSupplyBN);
|
|
399
|
+
const monthlyIncome = inflationRateBN.times(MONTH).times(workingBalanceBN).div(workingSupplyBN);
|
|
400
|
+
const annualIncome = inflationRateBN.times(YEAR).times(workingBalanceBN).div(workingSupplyBN);
|
|
401
|
+
return {
|
|
402
|
+
day: dailyIncome.toString(),
|
|
403
|
+
week: weeklyIncome.toString(),
|
|
404
|
+
month: monthlyIncome.toString(),
|
|
405
|
+
year: annualIncome.toString(),
|
|
406
|
+
token: curve.constants.ALIASES.crv,
|
|
407
|
+
symbol: 'CRV',
|
|
408
|
+
price: crvPrice,
|
|
409
|
+
};
|
|
625
410
|
};
|
|
626
|
-
this.boost =
|
|
627
|
-
if (
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all([
|
|
642
|
-
gaugeContract.working_balances(address),
|
|
643
|
-
gaugeContract.balanceOf(address),
|
|
644
|
-
])];
|
|
645
|
-
case 1:
|
|
646
|
-
_c = (_d.sent()).map(function (value) { return (0, utils_1.toBN)(value); }), workingBalanceBN = _c[0], balanceBN = _c[1];
|
|
647
|
-
boostBN = workingBalanceBN.div(0.4).div(balanceBN);
|
|
648
|
-
return [2 /*return*/, boostBN.toFixed(4).replace(/([0-9])0+$/, '$1')];
|
|
649
|
-
}
|
|
650
|
-
});
|
|
651
|
-
});
|
|
411
|
+
this.boost = async (address = "") => {
|
|
412
|
+
if (curve.chainId !== 1)
|
|
413
|
+
throw Error("Boosting is available only on Ethereum network");
|
|
414
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS)
|
|
415
|
+
throw Error(`${this.name} doesn't have gauge`);
|
|
416
|
+
address = address || curve.signerAddress;
|
|
417
|
+
if (!address)
|
|
418
|
+
throw Error("Need to connect wallet or pass address into args");
|
|
419
|
+
const gaugeContract = curve.contracts[this.gauge].multicallContract;
|
|
420
|
+
const [workingBalanceBN, balanceBN] = (await curve.multicallProvider.all([
|
|
421
|
+
gaugeContract.working_balances(address),
|
|
422
|
+
gaugeContract.balanceOf(address),
|
|
423
|
+
])).map((value) => toBN(value));
|
|
424
|
+
const boostBN = workingBalanceBN.div(0.4).div(balanceBN);
|
|
425
|
+
return boostBN.toFixed(4).replace(/([0-9])0+$/, '$1');
|
|
652
426
|
};
|
|
653
|
-
this.currentCrvApy =
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
if (curve_1.curve.chainId !== 1)
|
|
667
|
-
return [2 /*return*/, baseApy];
|
|
668
|
-
return [4 /*yield*/, this.boost(address)];
|
|
669
|
-
case 2:
|
|
670
|
-
boost = _d.sent();
|
|
671
|
-
if (boost == "2.5")
|
|
672
|
-
return [2 /*return*/, maxApy];
|
|
673
|
-
if (boost === "NaN")
|
|
674
|
-
return [2 /*return*/, NaN];
|
|
675
|
-
return [2 /*return*/, (0, utils_1.BN)(baseApy).times((0, utils_1.BN)(boost)).toNumber()];
|
|
676
|
-
}
|
|
677
|
-
});
|
|
678
|
-
});
|
|
427
|
+
this.currentCrvApy = async (address = "") => {
|
|
428
|
+
address = address || curve.signerAddress;
|
|
429
|
+
if (!address)
|
|
430
|
+
throw Error("Need to connect wallet or pass address into args");
|
|
431
|
+
const [baseApy, maxApy] = await this.statsTokenApy();
|
|
432
|
+
if (curve.chainId !== 1)
|
|
433
|
+
return baseApy;
|
|
434
|
+
const boost = await this.boost(address);
|
|
435
|
+
if (boost == "2.5")
|
|
436
|
+
return maxApy;
|
|
437
|
+
if (boost === "NaN")
|
|
438
|
+
return NaN;
|
|
439
|
+
return BN(baseApy).times(BN(boost)).toNumber();
|
|
679
440
|
};
|
|
680
|
-
this.maxBoostedStake =
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
441
|
+
this.maxBoostedStake = async (...addresses) => {
|
|
442
|
+
if (curve.chainId !== 1)
|
|
443
|
+
throw Error("Boosting is available only on Ethereum network");
|
|
444
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS)
|
|
445
|
+
throw Error(`${this.name} doesn't have gauge`);
|
|
446
|
+
if (addresses.length == 1 && Array.isArray(addresses[0]))
|
|
447
|
+
addresses = addresses[0];
|
|
448
|
+
if (addresses.length === 0 && curve.signerAddress !== '')
|
|
449
|
+
addresses = [curve.signerAddress];
|
|
450
|
+
if (addresses.length === 0)
|
|
451
|
+
throw Error("Need to connect wallet or pass addresses into args");
|
|
452
|
+
const votingEscrowContract = curve.contracts[curve.constants.ALIASES.voting_escrow].multicallContract;
|
|
453
|
+
const gaugeContract = curve.contracts[this.gauge].multicallContract;
|
|
454
|
+
const contractCalls = [votingEscrowContract.totalSupply(), gaugeContract.totalSupply()];
|
|
455
|
+
addresses.forEach((account) => {
|
|
456
|
+
contractCalls.push(votingEscrowContract.balanceOf(account));
|
|
457
|
+
});
|
|
458
|
+
const _response = await curve.multicallProvider.all(contractCalls);
|
|
459
|
+
const responseBN = _response.map((value) => toBN(value));
|
|
460
|
+
const [veTotalSupplyBN, gaugeTotalSupplyBN] = responseBN.splice(0, 2);
|
|
461
|
+
const resultBN = {};
|
|
462
|
+
addresses.forEach((acct, i) => {
|
|
463
|
+
resultBN[acct] = responseBN[i].div(veTotalSupplyBN).times(gaugeTotalSupplyBN);
|
|
464
|
+
});
|
|
465
|
+
const result = {};
|
|
466
|
+
for (const entry of Object.entries(resultBN)) {
|
|
467
|
+
result[entry[0]] = toStringFromBN(entry[1]);
|
|
684
468
|
}
|
|
685
|
-
return
|
|
686
|
-
var votingEscrowContract, gaugeContract, contractCalls, _response, responseBN, _c, veTotalSupplyBN, gaugeTotalSupplyBN, resultBN, result, _d, _e, entry;
|
|
687
|
-
return __generator(this, function (_f) {
|
|
688
|
-
switch (_f.label) {
|
|
689
|
-
case 0:
|
|
690
|
-
if (curve_1.curve.chainId !== 1)
|
|
691
|
-
throw Error("Boosting is available only on Ethereum network");
|
|
692
|
-
if (this.gauge === ethers_1.ethers.constants.AddressZero)
|
|
693
|
-
throw Error("".concat(this.name, " doesn't have gauge"));
|
|
694
|
-
if (addresses.length == 1 && Array.isArray(addresses[0]))
|
|
695
|
-
addresses = addresses[0];
|
|
696
|
-
if (addresses.length === 0 && curve_1.curve.signerAddress !== '')
|
|
697
|
-
addresses = [curve_1.curve.signerAddress];
|
|
698
|
-
if (addresses.length === 0)
|
|
699
|
-
throw Error("Need to connect wallet or pass addresses into args");
|
|
700
|
-
votingEscrowContract = curve_1.curve.contracts[curve_1.curve.constants.ALIASES.voting_escrow].multicallContract;
|
|
701
|
-
gaugeContract = curve_1.curve.contracts[this.gauge].multicallContract;
|
|
702
|
-
contractCalls = [votingEscrowContract.totalSupply(), gaugeContract.totalSupply()];
|
|
703
|
-
addresses.forEach(function (account) {
|
|
704
|
-
contractCalls.push(votingEscrowContract.balanceOf(account));
|
|
705
|
-
});
|
|
706
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all(contractCalls)];
|
|
707
|
-
case 1:
|
|
708
|
-
_response = _f.sent();
|
|
709
|
-
responseBN = _response.map(function (value) { return (0, utils_1.toBN)(value); });
|
|
710
|
-
_c = responseBN.splice(0, 2), veTotalSupplyBN = _c[0], gaugeTotalSupplyBN = _c[1];
|
|
711
|
-
resultBN = {};
|
|
712
|
-
addresses.forEach(function (acct, i) {
|
|
713
|
-
resultBN[acct] = responseBN[i].div(veTotalSupplyBN).times(gaugeTotalSupplyBN);
|
|
714
|
-
});
|
|
715
|
-
result = {};
|
|
716
|
-
for (_d = 0, _e = Object.entries(resultBN); _d < _e.length; _d++) {
|
|
717
|
-
entry = _e[_d];
|
|
718
|
-
result[entry[0]] = (0, utils_1.toStringFromBN)(entry[1]);
|
|
719
|
-
}
|
|
720
|
-
return [2 /*return*/, addresses.length === 1 ? result[addresses[0]] : result];
|
|
721
|
-
}
|
|
722
|
-
});
|
|
723
|
-
});
|
|
469
|
+
return addresses.length === 1 ? result[addresses[0]] : result;
|
|
724
470
|
};
|
|
725
471
|
// ---------------- REWARDS PROFIT, CLAIM ----------------
|
|
726
|
-
this.rewardTokens = (
|
|
727
|
-
if (
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
}
|
|
778
|
-
return [2 /*return*/, tokens.map(function (token, i) { return ({ token: token, symbol: tokenInfo_1[i * 2], decimals: tokenInfo_1[(i * 2) + 1] }); })];
|
|
779
|
-
case 7:
|
|
780
|
-
if (!('claimable_reward(address)' in gaugeContract)) return [3 /*break*/, 10];
|
|
781
|
-
rewardContract = curve_1.curve.contracts[this.sRewardContract].contract;
|
|
782
|
-
method = "snx()" in rewardContract ? "snx" : "rewardsToken" // susd, tbtc : dusd, musd, rsv, sbtc
|
|
783
|
-
;
|
|
784
|
-
return [4 /*yield*/, rewardContract[method](curve_1.curve.constantOptions)];
|
|
785
|
-
case 8:
|
|
786
|
-
token = (_f.sent()).toLowerCase();
|
|
787
|
-
(0, utils_1._setContracts)(token, ERC20_json_1.default);
|
|
788
|
-
tokenMulticallContract = curve_1.curve.contracts[token].multicallContract;
|
|
789
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all([
|
|
790
|
-
tokenMulticallContract.symbol(),
|
|
791
|
-
tokenMulticallContract.decimals(),
|
|
792
|
-
])];
|
|
793
|
-
case 9:
|
|
794
|
-
res = _f.sent();
|
|
795
|
-
symbol = res[0];
|
|
796
|
-
decimals = res[1];
|
|
797
|
-
return [2 /*return*/, [{ token: token, symbol: symbol, decimals: decimals }]];
|
|
798
|
-
case 10: return [2 /*return*/, []]; // gauge
|
|
799
|
-
}
|
|
800
|
-
});
|
|
801
|
-
});
|
|
472
|
+
this.rewardTokens = memoize(async (useApi = true) => {
|
|
473
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS)
|
|
474
|
+
return [];
|
|
475
|
+
if (useApi) {
|
|
476
|
+
const rewards = await _getRewardsFromApi();
|
|
477
|
+
if (!rewards[this.gauge])
|
|
478
|
+
return [];
|
|
479
|
+
rewards[this.gauge].forEach((r) => _setContracts(r.tokenAddress, ERC20Abi));
|
|
480
|
+
return rewards[this.gauge].map((r) => ({ token: r.tokenAddress, symbol: r.symbol, decimals: r.decimals }));
|
|
481
|
+
}
|
|
482
|
+
const gaugeContract = curve.contracts[this.gauge].contract;
|
|
483
|
+
const gaugeMulticallContract = curve.contracts[this.gauge].multicallContract;
|
|
484
|
+
if ("reward_tokens(uint256)" in gaugeContract) {
|
|
485
|
+
let rewardCount = 8; // gauge_v2, gauge_v3, gauge_rewards_only, gauge_child
|
|
486
|
+
if ("reward_count()" in gaugeContract) { // gauge_v4, gauge_v5, gauge_factory
|
|
487
|
+
rewardCount = Number(curve.formatUnits(await gaugeContract.reward_count(curve.constantOptions), 0));
|
|
488
|
+
}
|
|
489
|
+
const tokenCalls = [];
|
|
490
|
+
for (let i = 0; i < rewardCount; i++) {
|
|
491
|
+
tokenCalls.push(gaugeMulticallContract.reward_tokens(i));
|
|
492
|
+
}
|
|
493
|
+
const tokens = (await curve.multicallProvider.all(tokenCalls))
|
|
494
|
+
.filter((addr) => addr !== curve.constants.ZERO_ADDRESS)
|
|
495
|
+
.map((addr) => addr.toLowerCase());
|
|
496
|
+
const tokenInfoCalls = [];
|
|
497
|
+
for (const token of tokens) {
|
|
498
|
+
_setContracts(token, ERC20Abi);
|
|
499
|
+
const tokenMulticallContract = curve.contracts[token].multicallContract;
|
|
500
|
+
tokenInfoCalls.push(tokenMulticallContract.symbol(), tokenMulticallContract.decimals());
|
|
501
|
+
}
|
|
502
|
+
const tokenInfo = await curve.multicallProvider.all(tokenInfoCalls);
|
|
503
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
504
|
+
curve.constants.DECIMALS[tokens[i]] = tokenInfo[(i * 2) + 1];
|
|
505
|
+
}
|
|
506
|
+
return tokens.map((token, i) => ({ token, symbol: tokenInfo[i * 2], decimals: tokenInfo[(i * 2) + 1] }));
|
|
507
|
+
}
|
|
508
|
+
else if ('claimable_reward(address)' in gaugeContract) { // gauge_synthetix
|
|
509
|
+
const rewardContract = curve.contracts[this.sRewardContract].contract;
|
|
510
|
+
const method = "snx()" in rewardContract ? "snx" : "rewardsToken"; // susd, tbtc : dusd, musd, rsv, sbtc
|
|
511
|
+
const token = (await rewardContract[method](curve.constantOptions)).toLowerCase();
|
|
512
|
+
_setContracts(token, ERC20Abi);
|
|
513
|
+
const tokenMulticallContract = curve.contracts[token].multicallContract;
|
|
514
|
+
const res = await curve.multicallProvider.all([
|
|
515
|
+
tokenMulticallContract.symbol(),
|
|
516
|
+
tokenMulticallContract.decimals(),
|
|
517
|
+
]);
|
|
518
|
+
const symbol = res[0];
|
|
519
|
+
const decimals = res[1];
|
|
520
|
+
return [{ token, symbol, decimals }];
|
|
521
|
+
}
|
|
522
|
+
return []; // gauge
|
|
802
523
|
}, {
|
|
803
524
|
promise: true,
|
|
804
525
|
maxAge: 30 * 60 * 1000, // 30m
|
|
805
526
|
});
|
|
806
|
-
this.rewardsProfit =
|
|
807
|
-
if (
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
rewardToken = rewardTokens[0];
|
|
862
|
-
sRewardContract = curve_1.curve.contracts[this.sRewardContract].multicallContract;
|
|
863
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all([
|
|
864
|
-
sRewardContract.rewardRate(),
|
|
865
|
-
sRewardContract.periodFinish(),
|
|
866
|
-
gaugeContract.balanceOf(address),
|
|
867
|
-
gaugeContract.totalSupply(),
|
|
868
|
-
])];
|
|
869
|
-
case 8:
|
|
870
|
-
_d = _f.sent(), _inflationRate = _d[0], _periodFinish = _d[1], _balance = _d[2], _totalSupply = _d[3];
|
|
871
|
-
periodFinish = _periodFinish.toNumber() * 1000;
|
|
872
|
-
inflationRateBN = periodFinish > Date.now() ? (0, utils_1.toBN)(_inflationRate, rewardToken.decimals) : (0, utils_1.BN)(0);
|
|
873
|
-
balanceBN = (0, utils_1.toBN)(_balance);
|
|
874
|
-
totalSupplyBN = (0, utils_1.toBN)(_totalSupply);
|
|
875
|
-
return [4 /*yield*/, (0, utils_1._getUsdRate)(rewardToken.token)];
|
|
876
|
-
case 9:
|
|
877
|
-
tokenPrice = _f.sent();
|
|
878
|
-
result.push({
|
|
879
|
-
day: inflationRateBN.times(DAY).times(balanceBN).div(totalSupplyBN).toString(),
|
|
880
|
-
week: inflationRateBN.times(WEEK).times(balanceBN).div(totalSupplyBN).toString(),
|
|
881
|
-
month: inflationRateBN.times(MONTH).times(balanceBN).div(totalSupplyBN).toString(),
|
|
882
|
-
year: inflationRateBN.times(YEAR).times(balanceBN).div(totalSupplyBN).toString(),
|
|
883
|
-
token: rewardToken.token,
|
|
884
|
-
symbol: rewardToken.symbol,
|
|
885
|
-
price: tokenPrice,
|
|
886
|
-
});
|
|
887
|
-
return [3 /*break*/, 14];
|
|
888
|
-
case 10:
|
|
889
|
-
if (!['aave', 'saave', 'ankreth'].includes(this.id)) return [3 /*break*/, 14];
|
|
890
|
-
_e = 0, rewardTokens_4 = rewardTokens;
|
|
891
|
-
_f.label = 11;
|
|
892
|
-
case 11:
|
|
893
|
-
if (!(_e < rewardTokens_4.length)) return [3 /*break*/, 14];
|
|
894
|
-
rewardToken = rewardTokens_4[_e];
|
|
895
|
-
return [4 /*yield*/, (0, utils_1._getUsdRate)(rewardToken.token)];
|
|
896
|
-
case 12:
|
|
897
|
-
tokenPrice = _f.sent();
|
|
898
|
-
result.push({
|
|
899
|
-
day: "0",
|
|
900
|
-
week: "0",
|
|
901
|
-
month: "0",
|
|
902
|
-
year: "0",
|
|
903
|
-
token: rewardToken.token,
|
|
904
|
-
symbol: rewardToken.symbol,
|
|
905
|
-
price: tokenPrice,
|
|
906
|
-
});
|
|
907
|
-
_f.label = 13;
|
|
908
|
-
case 13:
|
|
909
|
-
_e++;
|
|
910
|
-
return [3 /*break*/, 11];
|
|
911
|
-
case 14: return [2 /*return*/, result];
|
|
912
|
-
}
|
|
527
|
+
this.rewardsProfit = async (address = "") => {
|
|
528
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS)
|
|
529
|
+
throw Error(`${this.name} doesn't have gauge`);
|
|
530
|
+
address = address || curve.signerAddress;
|
|
531
|
+
if (!address)
|
|
532
|
+
throw Error("Need to connect wallet or pass address into args");
|
|
533
|
+
const rewardTokens = await this.rewardTokens();
|
|
534
|
+
const gaugeContract = curve.contracts[this.gauge].multicallContract;
|
|
535
|
+
const result = [];
|
|
536
|
+
if ('reward_data(address)' in curve.contracts[this.gauge].contract) {
|
|
537
|
+
const calls = [gaugeContract.balanceOf(address), gaugeContract.totalSupply()];
|
|
538
|
+
for (const rewardToken of rewardTokens) {
|
|
539
|
+
calls.push(gaugeContract.reward_data(rewardToken.token));
|
|
540
|
+
}
|
|
541
|
+
const res = await curve.multicallProvider.all(calls);
|
|
542
|
+
const balanceBN = toBN(res.shift());
|
|
543
|
+
const totalSupplyBN = toBN(res.shift());
|
|
544
|
+
for (const rewardToken of rewardTokens) {
|
|
545
|
+
const _rewardData = res.shift();
|
|
546
|
+
const periodFinish = Number(curve.formatUnits(_rewardData.period_finish, 0)) * 1000;
|
|
547
|
+
const inflationRateBN = periodFinish > Date.now() ? toBN(_rewardData.rate, rewardToken.decimals) : BN(0);
|
|
548
|
+
const tokenPrice = await _getUsdRate(rewardToken.token);
|
|
549
|
+
result.push({
|
|
550
|
+
day: inflationRateBN.times(DAY).times(balanceBN).div(totalSupplyBN).toString(),
|
|
551
|
+
week: inflationRateBN.times(WEEK).times(balanceBN).div(totalSupplyBN).toString(),
|
|
552
|
+
month: inflationRateBN.times(MONTH).times(balanceBN).div(totalSupplyBN).toString(),
|
|
553
|
+
year: inflationRateBN.times(YEAR).times(balanceBN).div(totalSupplyBN).toString(),
|
|
554
|
+
token: rewardToken.token,
|
|
555
|
+
symbol: rewardToken.symbol,
|
|
556
|
+
price: tokenPrice,
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
else if (this.sRewardContract && "rewardRate()" in _curve.contracts[this.sRewardContract].contract && "periodFinish()" && rewardTokens.length === 1) {
|
|
561
|
+
const rewardToken = rewardTokens[0];
|
|
562
|
+
const sRewardContract = curve.contracts[this.sRewardContract].multicallContract;
|
|
563
|
+
const [_inflationRate, _periodFinish, _balance, _totalSupply] = await curve.multicallProvider.all([
|
|
564
|
+
sRewardContract.rewardRate(),
|
|
565
|
+
sRewardContract.periodFinish(),
|
|
566
|
+
gaugeContract.balanceOf(address),
|
|
567
|
+
gaugeContract.totalSupply(),
|
|
568
|
+
]);
|
|
569
|
+
const periodFinish = Number(_periodFinish) * 1000;
|
|
570
|
+
const inflationRateBN = periodFinish > Date.now() ? toBN(_inflationRate, rewardToken.decimals) : BN(0);
|
|
571
|
+
const balanceBN = toBN(_balance);
|
|
572
|
+
const totalSupplyBN = toBN(_totalSupply);
|
|
573
|
+
const tokenPrice = await _getUsdRate(rewardToken.token);
|
|
574
|
+
result.push({
|
|
575
|
+
day: inflationRateBN.times(DAY).times(balanceBN).div(totalSupplyBN).toString(),
|
|
576
|
+
week: inflationRateBN.times(WEEK).times(balanceBN).div(totalSupplyBN).toString(),
|
|
577
|
+
month: inflationRateBN.times(MONTH).times(balanceBN).div(totalSupplyBN).toString(),
|
|
578
|
+
year: inflationRateBN.times(YEAR).times(balanceBN).div(totalSupplyBN).toString(),
|
|
579
|
+
token: rewardToken.token,
|
|
580
|
+
symbol: rewardToken.symbol,
|
|
581
|
+
price: tokenPrice,
|
|
913
582
|
});
|
|
914
|
-
}
|
|
583
|
+
}
|
|
584
|
+
else if (['aave', 'saave', 'ankreth'].includes(this.id)) {
|
|
585
|
+
for (const rewardToken of rewardTokens) {
|
|
586
|
+
const tokenPrice = await _getUsdRate(rewardToken.token);
|
|
587
|
+
result.push({
|
|
588
|
+
day: "0",
|
|
589
|
+
week: "0",
|
|
590
|
+
month: "0",
|
|
591
|
+
year: "0",
|
|
592
|
+
token: rewardToken.token,
|
|
593
|
+
symbol: rewardToken.symbol,
|
|
594
|
+
price: tokenPrice,
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
return result;
|
|
915
599
|
};
|
|
916
600
|
// ---------------- ... ----------------
|
|
917
|
-
this.gaugeOptimalDeposits =
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
601
|
+
this.gaugeOptimalDeposits = async (...accounts) => {
|
|
602
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS)
|
|
603
|
+
throw Error(`${this.name} doesn't have gauge`);
|
|
604
|
+
if (accounts.length == 1 && Array.isArray(accounts[0]))
|
|
605
|
+
accounts = accounts[0];
|
|
606
|
+
const votingEscrowContract = curve.contracts[curve.constants.ALIASES.voting_escrow].multicallContract;
|
|
607
|
+
const lpTokenContract = curve.contracts[this.lpToken].multicallContract;
|
|
608
|
+
const gaugeContract = curve.contracts[this.gauge].multicallContract;
|
|
609
|
+
const contractCalls = [votingEscrowContract.totalSupply(), gaugeContract.totalSupply()];
|
|
610
|
+
accounts.forEach((account) => {
|
|
611
|
+
contractCalls.push(votingEscrowContract.balanceOf(account), lpTokenContract.balanceOf(account), gaugeContract.balanceOf(account));
|
|
612
|
+
});
|
|
613
|
+
const _response = await curve.multicallProvider.all(contractCalls);
|
|
614
|
+
const response = _response.map((value) => toBN(value));
|
|
615
|
+
const [veTotalSupply, gaugeTotalSupply] = response.splice(0, 2);
|
|
616
|
+
const votingPower = {};
|
|
617
|
+
let totalBalance = BN(0);
|
|
618
|
+
for (const acct of accounts) {
|
|
619
|
+
votingPower[acct] = response[0];
|
|
620
|
+
totalBalance = totalBalance.plus(response[1]).plus(response[2]);
|
|
621
|
+
response.splice(0, 3);
|
|
921
622
|
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
contractCalls = [votingEscrowContract.totalSupply(), gaugeContract.totalSupply()];
|
|
935
|
-
accounts.forEach(function (account) {
|
|
936
|
-
contractCalls.push(votingEscrowContract.balanceOf(account), lpTokenContract.balanceOf(account), gaugeContract.balanceOf(account));
|
|
937
|
-
});
|
|
938
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all(contractCalls)];
|
|
939
|
-
case 1:
|
|
940
|
-
_response = _j.sent();
|
|
941
|
-
response = _response.map(function (value) { return (0, utils_1.toBN)(value); });
|
|
942
|
-
_c = response.splice(0, 2), veTotalSupply = _c[0], gaugeTotalSupply = _c[1];
|
|
943
|
-
votingPower = {};
|
|
944
|
-
totalBalance = (0, utils_1.BN)(0);
|
|
945
|
-
for (_d = 0, accounts_1 = accounts; _d < accounts_1.length; _d++) {
|
|
946
|
-
acct = accounts_1[_d];
|
|
947
|
-
votingPower[acct] = response[0];
|
|
948
|
-
totalBalance = totalBalance.plus(response[1]).plus(response[2]);
|
|
949
|
-
response.splice(0, 3);
|
|
950
|
-
}
|
|
951
|
-
totalPower = Object.values(votingPower).reduce(function (sum, item) { return sum.plus(item); });
|
|
952
|
-
optimalBN = Object.fromEntries(accounts.map(function (acc) { return [acc, (0, utils_1.BN)(0)]; }));
|
|
953
|
-
if (totalBalance.lt(gaugeTotalSupply.times(totalPower).div(veTotalSupply))) {
|
|
954
|
-
for (_e = 0, accounts_2 = accounts; _e < accounts_2.length; _e++) {
|
|
955
|
-
acct = accounts_2[_e];
|
|
956
|
-
amount = gaugeTotalSupply.times(votingPower[acct]).div(veTotalSupply).lt(totalBalance) ?
|
|
957
|
-
gaugeTotalSupply.times(votingPower[acct]).div(veTotalSupply) : totalBalance;
|
|
958
|
-
optimalBN[acct] = amount;
|
|
959
|
-
totalBalance = totalBalance.minus(amount);
|
|
960
|
-
if (totalBalance.lte(0)) {
|
|
961
|
-
break;
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
else {
|
|
966
|
-
if (totalPower.lt(0)) {
|
|
967
|
-
for (_f = 0, accounts_3 = accounts; _f < accounts_3.length; _f++) {
|
|
968
|
-
acct = accounts_3[_f];
|
|
969
|
-
optimalBN[acct] = totalBalance.times(votingPower[acct]).div(totalPower);
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
optimalBN[accounts[0]] = optimalBN[accounts[0]].plus(totalBalance.minus(Object.values(optimalBN).reduce(function (sum, item) { return sum.plus(item); })));
|
|
973
|
-
}
|
|
974
|
-
optimal = {};
|
|
975
|
-
for (_g = 0, _h = Object.entries(optimalBN); _g < _h.length; _g++) {
|
|
976
|
-
entry = _h[_g];
|
|
977
|
-
optimal[entry[0]] = (0, utils_1.toStringFromBN)(entry[1]);
|
|
978
|
-
}
|
|
979
|
-
return [2 /*return*/, optimal];
|
|
623
|
+
const totalPower = Object.values(votingPower).reduce((sum, item) => sum.plus(item));
|
|
624
|
+
// @ts-ignore
|
|
625
|
+
const optimalBN = Object.fromEntries(accounts.map((acc) => [acc, BN(0)]));
|
|
626
|
+
if (totalBalance.lt(gaugeTotalSupply.times(totalPower).div(veTotalSupply))) {
|
|
627
|
+
for (const acct of accounts) {
|
|
628
|
+
// min(voting, lp)
|
|
629
|
+
const amount = gaugeTotalSupply.times(votingPower[acct]).div(veTotalSupply).lt(totalBalance) ?
|
|
630
|
+
gaugeTotalSupply.times(votingPower[acct]).div(veTotalSupply) : totalBalance;
|
|
631
|
+
optimalBN[acct] = amount;
|
|
632
|
+
totalBalance = totalBalance.minus(amount);
|
|
633
|
+
if (totalBalance.lte(0)) {
|
|
634
|
+
break;
|
|
980
635
|
}
|
|
981
|
-
}
|
|
982
|
-
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
else {
|
|
639
|
+
if (totalPower.lt(0)) {
|
|
640
|
+
for (const acct of accounts) {
|
|
641
|
+
optimalBN[acct] = totalBalance.times(votingPower[acct]).div(totalPower);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
optimalBN[accounts[0]] = optimalBN[accounts[0]].plus(totalBalance.minus(Object.values(optimalBN).reduce((sum, item) => sum.plus(item))));
|
|
645
|
+
}
|
|
646
|
+
const optimal = {};
|
|
647
|
+
for (const entry of Object.entries(optimalBN)) {
|
|
648
|
+
optimal[entry[0]] = toStringFromBN(entry[1]);
|
|
649
|
+
}
|
|
650
|
+
return optimal;
|
|
983
651
|
};
|
|
984
|
-
this._getCoinIdx =
|
|
985
|
-
if (useUnderlying === void 0) { useUnderlying = true; }
|
|
652
|
+
this._getCoinIdx = (coin, useUnderlying = true) => {
|
|
986
653
|
if (typeof coin === 'number') {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
if (!Number.isInteger(
|
|
654
|
+
const coins_N = useUnderlying ? this.underlyingCoins.length : this.wrappedCoins.length;
|
|
655
|
+
const idx = coin;
|
|
656
|
+
if (!Number.isInteger(idx)) {
|
|
990
657
|
throw Error('Index must be integer');
|
|
991
658
|
}
|
|
992
|
-
if (
|
|
659
|
+
if (idx < 0) {
|
|
993
660
|
throw Error('Index must be >= 0');
|
|
994
661
|
}
|
|
995
|
-
if (
|
|
996
|
-
throw Error(
|
|
662
|
+
if (idx > coins_N - 1) {
|
|
663
|
+
throw Error(`Index must be < ${coins_N}`);
|
|
997
664
|
}
|
|
998
|
-
return
|
|
665
|
+
return idx;
|
|
999
666
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
667
|
+
const [coinAddress] = _getCoinAddresses(coin);
|
|
668
|
+
const lowerCaseCoinAddresses = useUnderlying ?
|
|
669
|
+
this.underlyingCoinAddresses.map((c) => c.toLowerCase()) :
|
|
670
|
+
this.wrappedCoinAddresses.map((c) => c.toLowerCase());
|
|
671
|
+
const idx = lowerCaseCoinAddresses.indexOf(coinAddress.toLowerCase());
|
|
1005
672
|
if (idx === -1) {
|
|
1006
|
-
throw Error(
|
|
673
|
+
throw Error(`There is no ${coin} among ${this.name} pool ${useUnderlying ? 'underlying' : 'wrapped'} coins`);
|
|
1007
674
|
}
|
|
1008
675
|
return idx;
|
|
1009
676
|
};
|
|
1010
|
-
this._getRates =
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
return [3 /*break*/, 6];
|
|
1028
|
-
case 3:
|
|
1029
|
-
if (!['y', 'busd', 'pax'].includes(this.id)) return [3 /*break*/, 5];
|
|
1030
|
-
_f = (_e = _rates).push;
|
|
1031
|
-
return [4 /*yield*/, curve_1.curve.contracts[addr].contract.getPricePerFullShare()];
|
|
1032
|
-
case 4:
|
|
1033
|
-
_f.apply(_e, [_g.sent()]);
|
|
1034
|
-
return [3 /*break*/, 6];
|
|
1035
|
-
case 5:
|
|
1036
|
-
_rates.push(ethers_1.ethers.BigNumber.from(10).pow(18)); // Aave ratio 1:1
|
|
1037
|
-
_g.label = 6;
|
|
1038
|
-
case 6: return [3 /*break*/, 8];
|
|
1039
|
-
case 7:
|
|
1040
|
-
_rates.push(ethers_1.ethers.BigNumber.from(10).pow(18));
|
|
1041
|
-
_g.label = 8;
|
|
1042
|
-
case 8:
|
|
1043
|
-
i++;
|
|
1044
|
-
return [3 /*break*/, 1];
|
|
1045
|
-
case 9: return [2 /*return*/, _rates];
|
|
677
|
+
this._getRates = async () => {
|
|
678
|
+
const _rates = [];
|
|
679
|
+
for (let i = 0; i < this.wrappedCoinAddresses.length; i++) {
|
|
680
|
+
const addr = this.wrappedCoinAddresses[i];
|
|
681
|
+
if (this.useLending[i]) {
|
|
682
|
+
if (['compound', 'usdt', 'ib'].includes(this.id)) {
|
|
683
|
+
_rates.push(await curve.contracts[addr].contract.exchangeRateStored());
|
|
684
|
+
}
|
|
685
|
+
else if (['y', 'busd', 'pax'].includes(this.id)) {
|
|
686
|
+
_rates.push(await curve.contracts[addr].contract.getPricePerFullShare());
|
|
687
|
+
}
|
|
688
|
+
else {
|
|
689
|
+
_rates.push(10n ** 18n); // Aave ratio 1:1
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
else {
|
|
693
|
+
_rates.push(10n ** 18n);
|
|
1046
694
|
}
|
|
1047
|
-
});
|
|
1048
|
-
}); };
|
|
1049
|
-
this._balances = function (rawCoinNames, rawCoinAddresses) {
|
|
1050
|
-
var addresses = [];
|
|
1051
|
-
for (var _i = 2; _i < arguments.length; _i++) {
|
|
1052
|
-
addresses[_i - 2] = arguments[_i];
|
|
1053
695
|
}
|
|
1054
|
-
return
|
|
1055
|
-
var coinNames, coinAddresses, i, rawBalances, balances, _c, addresses_1, address, _d, coinNames_1, coinName;
|
|
1056
|
-
return __generator(this, function (_e) {
|
|
1057
|
-
switch (_e.label) {
|
|
1058
|
-
case 0:
|
|
1059
|
-
coinNames = [];
|
|
1060
|
-
coinAddresses = [];
|
|
1061
|
-
// removing duplicates
|
|
1062
|
-
for (i = 0; i < rawCoinAddresses.length; i++) {
|
|
1063
|
-
if (!coinAddresses.includes(rawCoinAddresses[i])) {
|
|
1064
|
-
coinNames.push(rawCoinNames[i]);
|
|
1065
|
-
coinAddresses.push(rawCoinAddresses[i]);
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
addresses = (0, utils_1._prepareAddresses)(addresses);
|
|
1069
|
-
return [4 /*yield*/, (0, utils_1._getBalances)(coinAddresses, addresses)];
|
|
1070
|
-
case 1:
|
|
1071
|
-
rawBalances = _e.sent();
|
|
1072
|
-
balances = {};
|
|
1073
|
-
for (_c = 0, addresses_1 = addresses; _c < addresses_1.length; _c++) {
|
|
1074
|
-
address = addresses_1[_c];
|
|
1075
|
-
balances[address] = {};
|
|
1076
|
-
for (_d = 0, coinNames_1 = coinNames; _d < coinNames_1.length; _d++) {
|
|
1077
|
-
coinName = coinNames_1[_d];
|
|
1078
|
-
balances[address][coinName] = rawBalances[address].shift();
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
return [2 /*return*/, addresses.length === 1 ? balances[addresses[0]] : balances];
|
|
1082
|
-
}
|
|
1083
|
-
});
|
|
1084
|
-
});
|
|
696
|
+
return _rates;
|
|
1085
697
|
};
|
|
1086
|
-
this.
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
promises.push((0, utils_1._getUsdRate)(addr));
|
|
1095
|
-
}
|
|
1096
|
-
return [4 /*yield*/, Promise.all(promises)];
|
|
1097
|
-
case 1: return [2 /*return*/, _d.sent()];
|
|
698
|
+
this._balances = async (rawCoinNames, rawCoinAddresses, ...addresses) => {
|
|
699
|
+
const coinNames = [];
|
|
700
|
+
const coinAddresses = [];
|
|
701
|
+
// removing duplicates
|
|
702
|
+
for (let i = 0; i < rawCoinAddresses.length; i++) {
|
|
703
|
+
if (!coinAddresses.includes(rawCoinAddresses[i])) {
|
|
704
|
+
coinNames.push(rawCoinNames[i]);
|
|
705
|
+
coinAddresses.push(rawCoinAddresses[i]);
|
|
1098
706
|
}
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
promises = [];
|
|
1108
|
-
for (_i = 0, _c = this.wrappedCoinAddresses; _i < _c.length; _i++) {
|
|
1109
|
-
addr = _c[_i];
|
|
1110
|
-
promises.push((0, utils_1._getUsdRate)(addr));
|
|
1111
|
-
}
|
|
1112
|
-
return [4 /*yield*/, Promise.all(promises)];
|
|
1113
|
-
case 1: return [2 /*return*/, _d.sent()];
|
|
707
|
+
}
|
|
708
|
+
addresses = _prepareAddresses(addresses);
|
|
709
|
+
const rawBalances = await _getBalances(coinAddresses, addresses);
|
|
710
|
+
const balances = {};
|
|
711
|
+
for (const address of addresses) {
|
|
712
|
+
balances[address] = {};
|
|
713
|
+
for (const coinName of coinNames) {
|
|
714
|
+
balances[address][coinName] = rawBalances[address].shift();
|
|
1114
715
|
}
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
|
|
716
|
+
}
|
|
717
|
+
return addresses.length === 1 ? balances[addresses[0]] : balances;
|
|
718
|
+
};
|
|
719
|
+
this._underlyingPrices = async () => {
|
|
720
|
+
const promises = [];
|
|
721
|
+
for (const addr of this.underlyingCoinAddresses) {
|
|
722
|
+
promises.push(_getUsdRate(addr));
|
|
723
|
+
}
|
|
724
|
+
return await Promise.all(promises);
|
|
725
|
+
};
|
|
726
|
+
// NOTE! It may crash!
|
|
727
|
+
this._wrappedPrices = async () => {
|
|
728
|
+
const promises = [];
|
|
729
|
+
for (const addr of this.wrappedCoinAddresses) {
|
|
730
|
+
promises.push(_getUsdRate(addr));
|
|
731
|
+
}
|
|
732
|
+
return await Promise.all(promises);
|
|
733
|
+
};
|
|
734
|
+
const poolData = { ...curve.constants.POOLS_DATA, ...curve.constants.FACTORY_POOLS_DATA, ...curve.constants.CRYPTO_FACTORY_POOLS_DATA }[id];
|
|
1118
735
|
this.id = id;
|
|
1119
736
|
this.name = poolData.name;
|
|
1120
737
|
this.fullName = poolData.full_name;
|
|
@@ -1134,15 +751,15 @@ var PoolTemplate = /** @class */ (function () {
|
|
|
1134
751
|
this.isFactory = poolData.is_factory || false;
|
|
1135
752
|
this.isMetaFactory = (this.isMeta && this.isFactory) || this.zap === '0xa79828df1850e8a3a3064576f380d90aecdd3359';
|
|
1136
753
|
this.basePool = poolData.base_pool || '';
|
|
1137
|
-
this.metaCoinIdx = this.isMeta ?
|
|
754
|
+
this.metaCoinIdx = this.isMeta ? poolData.meta_coin_idx ?? poolData.wrapped_coins.length - 1 : -1;
|
|
1138
755
|
this.underlyingCoins = poolData.underlying_coins;
|
|
1139
756
|
this.wrappedCoins = poolData.wrapped_coins;
|
|
1140
757
|
this.underlyingCoinAddresses = poolData.underlying_coin_addresses;
|
|
1141
758
|
this.wrappedCoinAddresses = poolData.wrapped_coin_addresses;
|
|
1142
759
|
this.underlyingDecimals = poolData.underlying_decimals;
|
|
1143
760
|
this.wrappedDecimals = poolData.wrapped_decimals;
|
|
1144
|
-
this.useLending = poolData.use_lending || poolData.underlying_coin_addresses.map(
|
|
1145
|
-
this.inApi =
|
|
761
|
+
this.useLending = poolData.use_lending || poolData.underlying_coin_addresses.map(() => false);
|
|
762
|
+
this.inApi = poolData.in_api ?? false;
|
|
1146
763
|
this.estimateGas = {
|
|
1147
764
|
depositApprove: this.depositApproveEstimateGas.bind(this),
|
|
1148
765
|
deposit: this.depositEstimateGas.bind(this),
|
|
@@ -1189,168 +806,92 @@ var PoolTemplate = /** @class */ (function () {
|
|
|
1189
806
|
allCoinBalances: this.walletAllCoinBalances.bind(this),
|
|
1190
807
|
};
|
|
1191
808
|
}
|
|
1192
|
-
|
|
1193
|
-
if (
|
|
809
|
+
rewardsOnly() {
|
|
810
|
+
if (curve.chainId === 2222)
|
|
1194
811
|
return true; // TODO remove this for Kava and Celo
|
|
1195
|
-
if (this.gauge ===
|
|
1196
|
-
throw Error(
|
|
1197
|
-
|
|
812
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS)
|
|
813
|
+
throw Error(`${this.name} doesn't have gauge`);
|
|
814
|
+
const gaugeContract = curve.contracts[this.gauge].contract;
|
|
1198
815
|
return !('inflation_rate()' in gaugeContract || 'inflation_rate(uint256)' in gaugeContract);
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
case 0:
|
|
1207
|
-
swapContract = curve_1.curve.contracts[this.address].multicallContract;
|
|
1208
|
-
contractCalls = this.wrappedCoins.map(function (_, i) { return swapContract.balances(i); });
|
|
1209
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all(contractCalls)];
|
|
1210
|
-
case 1:
|
|
1211
|
-
_wrappedBalances = _c.sent();
|
|
1212
|
-
return [2 /*return*/, _wrappedBalances.map(function (_b, i) { return ethers_1.ethers.utils.formatUnits(_b, _this.wrappedDecimals[i]); })];
|
|
1213
|
-
}
|
|
1214
|
-
});
|
|
1215
|
-
});
|
|
1216
|
-
};
|
|
816
|
+
}
|
|
817
|
+
async statsWrappedBalances() {
|
|
818
|
+
const swapContract = curve.contracts[this.address].multicallContract;
|
|
819
|
+
const contractCalls = this.wrappedCoins.map((_, i) => swapContract.balances(i));
|
|
820
|
+
const _wrappedBalances = await curve.multicallProvider.all(contractCalls);
|
|
821
|
+
return _wrappedBalances.map((_b, i) => curve.formatUnits(_b, this.wrappedDecimals[i]));
|
|
822
|
+
}
|
|
1217
823
|
// OVERRIDE
|
|
1218
|
-
|
|
1219
|
-
return
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
}
|
|
1255
|
-
PoolTemplate.prototype.calcLpTokenAmount = function (amounts, isDeposit) {
|
|
1256
|
-
if (isDeposit === void 0) { isDeposit = true; }
|
|
1257
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1258
|
-
var _underlyingAmounts, _expected;
|
|
1259
|
-
var _this = this;
|
|
1260
|
-
return __generator(this, function (_c) {
|
|
1261
|
-
switch (_c.label) {
|
|
1262
|
-
case 0:
|
|
1263
|
-
if (amounts.length !== this.underlyingCoinAddresses.length) {
|
|
1264
|
-
throw Error("".concat(this.name, " pool has ").concat(this.underlyingCoinAddresses.length, " coins (amounts provided for ").concat(amounts.length, ")"));
|
|
1265
|
-
}
|
|
1266
|
-
_underlyingAmounts = amounts.map(function (amount, i) { return (0, utils_1.parseUnits)(amount, _this.underlyingDecimals[i]); });
|
|
1267
|
-
return [4 /*yield*/, this._calcLpTokenAmount(_underlyingAmounts, isDeposit, true)];
|
|
1268
|
-
case 1:
|
|
1269
|
-
_expected = _c.sent();
|
|
1270
|
-
return [2 /*return*/, ethers_1.ethers.utils.formatUnits(_expected)];
|
|
1271
|
-
}
|
|
1272
|
-
});
|
|
1273
|
-
});
|
|
1274
|
-
};
|
|
1275
|
-
PoolTemplate.prototype.calcLpTokenAmountWrapped = function (amounts, isDeposit) {
|
|
1276
|
-
if (isDeposit === void 0) { isDeposit = true; }
|
|
1277
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1278
|
-
var _amounts, _expected;
|
|
1279
|
-
var _this = this;
|
|
1280
|
-
return __generator(this, function (_c) {
|
|
1281
|
-
switch (_c.label) {
|
|
1282
|
-
case 0:
|
|
1283
|
-
if (amounts.length !== this.wrappedCoinAddresses.length) {
|
|
1284
|
-
throw Error("".concat(this.name, " pool has ").concat(this.wrappedCoinAddresses.length, " coins (amounts provided for ").concat(amounts.length, ")"));
|
|
1285
|
-
}
|
|
1286
|
-
if (this.isFake) {
|
|
1287
|
-
throw Error("".concat(this.name, " pool doesn't have this method"));
|
|
1288
|
-
}
|
|
1289
|
-
_amounts = amounts.map(function (amount, i) { return (0, utils_1.parseUnits)(amount, _this.wrappedDecimals[i]); });
|
|
1290
|
-
return [4 /*yield*/, this._calcLpTokenAmount(_amounts, isDeposit, false)];
|
|
1291
|
-
case 1:
|
|
1292
|
-
_expected = _c.sent();
|
|
1293
|
-
return [2 /*return*/, ethers_1.ethers.utils.formatUnits(_expected)];
|
|
1294
|
-
}
|
|
1295
|
-
});
|
|
1296
|
-
});
|
|
1297
|
-
};
|
|
824
|
+
async statsUnderlyingBalances() {
|
|
825
|
+
return await this.statsWrappedBalances();
|
|
826
|
+
}
|
|
827
|
+
async _pureCalcLpTokenAmount(_amounts, isDeposit = true, useUnderlying = true) {
|
|
828
|
+
const calcContractAddress = this.isMeta && useUnderlying ? this.zap : this.address;
|
|
829
|
+
const N_coins = useUnderlying ? this.underlyingCoins.length : this.wrappedCoins.length;
|
|
830
|
+
const contract = curve.contracts[calcContractAddress].contract;
|
|
831
|
+
if (this.isMetaFactory && useUnderlying) {
|
|
832
|
+
if (contract[`calc_token_amount(address,uint256[${N_coins}],bool)`]) {
|
|
833
|
+
return await contract.calc_token_amount(this.address, _amounts, isDeposit, curve.constantOptions);
|
|
834
|
+
}
|
|
835
|
+
return await contract.calc_token_amount(this.address, _amounts, curve.constantOptions);
|
|
836
|
+
}
|
|
837
|
+
if (contract[`calc_token_amount(uint256[${N_coins}],bool)`]) {
|
|
838
|
+
return await contract.calc_token_amount(_amounts, isDeposit, curve.constantOptions);
|
|
839
|
+
}
|
|
840
|
+
return await contract.calc_token_amount(_amounts, curve.constantOptions);
|
|
841
|
+
}
|
|
842
|
+
async calcLpTokenAmount(amounts, isDeposit = true) {
|
|
843
|
+
if (amounts.length !== this.underlyingCoinAddresses.length) {
|
|
844
|
+
throw Error(`${this.name} pool has ${this.underlyingCoinAddresses.length} coins (amounts provided for ${amounts.length})`);
|
|
845
|
+
}
|
|
846
|
+
const _underlyingAmounts = amounts.map((amount, i) => parseUnits(amount, this.underlyingDecimals[i]));
|
|
847
|
+
const _expected = await this._calcLpTokenAmount(_underlyingAmounts, isDeposit, true);
|
|
848
|
+
return curve.formatUnits(_expected);
|
|
849
|
+
}
|
|
850
|
+
async calcLpTokenAmountWrapped(amounts, isDeposit = true) {
|
|
851
|
+
if (amounts.length !== this.wrappedCoinAddresses.length) {
|
|
852
|
+
throw Error(`${this.name} pool has ${this.wrappedCoinAddresses.length} coins (amounts provided for ${amounts.length})`);
|
|
853
|
+
}
|
|
854
|
+
if (this.isFake) {
|
|
855
|
+
throw Error(`${this.name} pool doesn't have this method`);
|
|
856
|
+
}
|
|
857
|
+
const _amounts = amounts.map((amount, i) => parseUnits(amount, this.wrappedDecimals[i]));
|
|
858
|
+
const _expected = await this._calcLpTokenAmount(_amounts, isDeposit, false);
|
|
859
|
+
return curve.formatUnits(_expected);
|
|
860
|
+
}
|
|
1298
861
|
// ---------------- DEPOSIT ----------------
|
|
1299
|
-
|
|
862
|
+
metaUnderlyingSeedAmounts(amount1) {
|
|
1300
863
|
if (this.isCrypto)
|
|
1301
|
-
throw Error(
|
|
864
|
+
throw Error(`Use cryptoSeedAmounts method for ${this.name} pool`);
|
|
1302
865
|
if (!this.isMeta)
|
|
1303
866
|
throw Error("metaUnderlyingSeedAmounts method exists only for meta stable pools");
|
|
1304
|
-
|
|
867
|
+
const amount1BN = BN(amount1);
|
|
1305
868
|
if (amount1BN.lte(0))
|
|
1306
869
|
throw Error("Initial deposit amounts must be > 0");
|
|
1307
|
-
|
|
1308
|
-
for (
|
|
870
|
+
const amounts = [_cutZeros(amount1BN.toFixed(this.underlyingDecimals[0]))];
|
|
871
|
+
for (let i = 1; i < this.underlyingDecimals.length; i++) {
|
|
1309
872
|
amounts.push(amount1BN.div(this.underlyingDecimals.length - 1).toFixed(this.underlyingDecimals[i]));
|
|
1310
873
|
}
|
|
1311
874
|
return amounts;
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
if (amount1BN.lte(0))
|
|
1326
|
-
throw Error("Initial deposit amounts must be > 0");
|
|
1327
|
-
_c = utils_1.toBN;
|
|
1328
|
-
return [4 /*yield*/, curve_1.curve.contracts[this.address].contract.price_scale(curve_1.curve.constantOptions)];
|
|
1329
|
-
case 1:
|
|
1330
|
-
priceScaleBN = _c.apply(void 0, [_d.sent()]);
|
|
1331
|
-
return [2 /*return*/, [(0, utils_1._cutZeros)(amount1BN.toFixed(decimals[0])), (0, utils_1._cutZeros)(amount1BN.div(priceScaleBN).toFixed(decimals[1]))]];
|
|
1332
|
-
}
|
|
1333
|
-
});
|
|
1334
|
-
});
|
|
1335
|
-
};
|
|
875
|
+
}
|
|
876
|
+
async cryptoSeedAmounts(amount1) {
|
|
877
|
+
if (!this.isCrypto)
|
|
878
|
+
throw Error("cryptoSeedAmounts method doesn't exist for stable pools");
|
|
879
|
+
const decimals = this.isMeta ? this.wrappedDecimals : this.underlyingDecimals;
|
|
880
|
+
if (decimals.length > 2)
|
|
881
|
+
throw Error("cryptoSeedAmounts method doesn't exist for pools with N coins > 2");
|
|
882
|
+
const amount1BN = BN(amount1);
|
|
883
|
+
if (amount1BN.lte(0))
|
|
884
|
+
throw Error("Initial deposit amounts must be > 0");
|
|
885
|
+
const priceScaleBN = toBN(await curve.contracts[this.address].contract.price_scale(curve.constantOptions));
|
|
886
|
+
return [_cutZeros(amount1BN.toFixed(decimals[0])), _cutZeros(amount1BN.div(priceScaleBN).toFixed(decimals[1]))];
|
|
887
|
+
}
|
|
1336
888
|
// OVERRIDE
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
};
|
|
1344
|
-
PoolTemplate.prototype.depositExpected = function (amounts) {
|
|
1345
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1346
|
-
return __generator(this, function (_c) {
|
|
1347
|
-
switch (_c.label) {
|
|
1348
|
-
case 0: return [4 /*yield*/, this.calcLpTokenAmount(amounts)];
|
|
1349
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
1350
|
-
}
|
|
1351
|
-
});
|
|
1352
|
-
});
|
|
1353
|
-
};
|
|
889
|
+
async depositBalancedAmounts() {
|
|
890
|
+
throw Error(`depositBalancedAmounts method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
891
|
+
}
|
|
892
|
+
async depositExpected(amounts) {
|
|
893
|
+
return await this.calcLpTokenAmount(amounts);
|
|
894
|
+
}
|
|
1354
895
|
// | balanced[i] / sum(balanced[j]) = balance[i] / sum(balance[j]) |
|
|
1355
896
|
// | sum(pj * balanced[j]) = sum(aj * pj) |
|
|
1356
897
|
//
|
|
@@ -1361,1761 +902,807 @@ var PoolTemplate = /** @class */ (function () {
|
|
|
1361
902
|
// totalBalanceBN = sum(balance[j])
|
|
1362
903
|
// ratiosBN[i] = balancesBN[i] / totalBalanceBN = ri = balance[i] / sum(balance[j])
|
|
1363
904
|
// denominatorBN = sum(rj * pj / ri)
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
.div(ratiosBN[i])
|
|
905
|
+
_balancedAmountsWithSameValue(amountsBN, pricesBN, balancesBN) {
|
|
906
|
+
const valuesBN = amountsBN.map((aBN, i) => aBN.times(pricesBN[i]));
|
|
907
|
+
const totalValueBN = valuesBN.reduce((v1BN, v2BN) => v1BN.plus(v2BN));
|
|
908
|
+
const totalBalanceBN = balancesBN.reduce((b1BN, b2BN) => b1BN.plus(b2BN));
|
|
909
|
+
const ratiosBN = balancesBN.map((bBN) => bBN.div(totalBalanceBN));
|
|
910
|
+
const balancedAmountsBN = [];
|
|
911
|
+
for (let i = 0; i < amountsBN.length; i++) {
|
|
912
|
+
const denominatorBN = ratiosBN.map((rBN, j) => rBN.times(pricesBN[j])
|
|
913
|
+
.div(ratiosBN[i])).reduce((xBN, yBN) => xBN.plus(yBN));
|
|
1373
914
|
balancedAmountsBN.push(totalValueBN.div(denominatorBN));
|
|
1374
|
-
};
|
|
1375
|
-
for (var i = 0; i < amountsBN.length; i++) {
|
|
1376
|
-
_loop_1(i);
|
|
1377
915
|
}
|
|
1378
916
|
return balancedAmountsBN.map(String);
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
case 4:
|
|
1400
|
-
balancesBN = (_f.sent()).map(utils_1.BN);
|
|
1401
|
-
balancedAmounts = this._balancedAmountsWithSameValue(amountsBN, pricesBN, balancesBN);
|
|
1402
|
-
_d = utils_1.BN;
|
|
1403
|
-
return [4 /*yield*/, this.depositExpected(amounts)];
|
|
1404
|
-
case 5:
|
|
1405
|
-
expectedBN = _d.apply(void 0, [_f.sent()]);
|
|
1406
|
-
_e = utils_1.BN;
|
|
1407
|
-
return [4 /*yield*/, this.depositExpected(balancedAmounts)];
|
|
1408
|
-
case 6:
|
|
1409
|
-
balancedExpectedBN = _e.apply(void 0, [_f.sent()]);
|
|
1410
|
-
return [2 /*return*/, String(expectedBN.minus(balancedExpectedBN).div(balancedExpectedBN).times(100))];
|
|
1411
|
-
}
|
|
1412
|
-
});
|
|
1413
|
-
});
|
|
1414
|
-
};
|
|
1415
|
-
PoolTemplate.prototype.depositIsApproved = function (amounts) {
|
|
1416
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1417
|
-
return __generator(this, function (_c) {
|
|
1418
|
-
switch (_c.label) {
|
|
1419
|
-
case 0: return [4 /*yield*/, (0, utils_1.hasAllowance)(this.underlyingCoinAddresses, amounts, curve_1.curve.signerAddress, this.zap || this.address)];
|
|
1420
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
1421
|
-
}
|
|
1422
|
-
});
|
|
1423
|
-
});
|
|
1424
|
-
};
|
|
1425
|
-
PoolTemplate.prototype.depositApproveEstimateGas = function (amounts) {
|
|
1426
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1427
|
-
return __generator(this, function (_c) {
|
|
1428
|
-
switch (_c.label) {
|
|
1429
|
-
case 0: return [4 /*yield*/, (0, utils_1.ensureAllowanceEstimateGas)(this.underlyingCoinAddresses, amounts, this.zap || this.address)];
|
|
1430
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
1431
|
-
}
|
|
1432
|
-
});
|
|
1433
|
-
});
|
|
1434
|
-
};
|
|
1435
|
-
PoolTemplate.prototype.depositApprove = function (amounts) {
|
|
1436
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1437
|
-
return __generator(this, function (_c) {
|
|
1438
|
-
switch (_c.label) {
|
|
1439
|
-
case 0: return [4 /*yield*/, (0, utils_1.ensureAllowance)(this.underlyingCoinAddresses, amounts, this.zap || this.address)];
|
|
1440
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
1441
|
-
}
|
|
1442
|
-
});
|
|
1443
|
-
});
|
|
1444
|
-
};
|
|
917
|
+
}
|
|
918
|
+
async depositBonus(amounts) {
|
|
919
|
+
const amountsBN = amounts.map(BN);
|
|
920
|
+
const prices = (this.isCrypto || this.id === 'wsteth') ? await this._underlyingPrices() : this.underlyingCoins.map(() => 1);
|
|
921
|
+
const pricesBN = prices.map(BN);
|
|
922
|
+
const balancesBN = (await this.stats.underlyingBalances()).map(BN);
|
|
923
|
+
const balancedAmounts = this._balancedAmountsWithSameValue(amountsBN, pricesBN, balancesBN);
|
|
924
|
+
const expectedBN = BN(await this.depositExpected(amounts));
|
|
925
|
+
const balancedExpectedBN = BN(await this.depositExpected(balancedAmounts));
|
|
926
|
+
return String(expectedBN.minus(balancedExpectedBN).div(balancedExpectedBN).times(100));
|
|
927
|
+
}
|
|
928
|
+
async depositIsApproved(amounts) {
|
|
929
|
+
return await hasAllowance(this.underlyingCoinAddresses, amounts, curve.signerAddress, this.zap || this.address);
|
|
930
|
+
}
|
|
931
|
+
async depositApproveEstimateGas(amounts) {
|
|
932
|
+
return await ensureAllowanceEstimateGas(this.underlyingCoinAddresses, amounts, this.zap || this.address);
|
|
933
|
+
}
|
|
934
|
+
async depositApprove(amounts) {
|
|
935
|
+
return await ensureAllowance(this.underlyingCoinAddresses, amounts, this.zap || this.address);
|
|
936
|
+
}
|
|
1445
937
|
// OVERRIDE
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
throw Error("depositEstimateGas method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
1450
|
-
});
|
|
1451
|
-
});
|
|
1452
|
-
};
|
|
938
|
+
async depositEstimateGas(amounts) {
|
|
939
|
+
throw Error(`depositEstimateGas method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
940
|
+
}
|
|
1453
941
|
// OVERRIDE
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
return __generator(this, function (_c) {
|
|
1458
|
-
throw Error("deposit method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
1459
|
-
});
|
|
1460
|
-
});
|
|
1461
|
-
};
|
|
942
|
+
async deposit(amounts, slippage = 0.5) {
|
|
943
|
+
throw Error(`deposit method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
944
|
+
}
|
|
1462
945
|
// ---------------- DEPOSIT WRAPPED ----------------
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
return
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
return [4 /*yield*/, this.depositWrappedExpected(amounts)];
|
|
1500
|
-
case 3:
|
|
1501
|
-
expectedBN = _c.apply(void 0, [_e.sent()]);
|
|
1502
|
-
_d = utils_1.BN;
|
|
1503
|
-
return [4 /*yield*/, this.depositWrappedExpected(balancedAmounts)];
|
|
1504
|
-
case 4:
|
|
1505
|
-
balancedExpectedBN = _d.apply(void 0, [_e.sent()]);
|
|
1506
|
-
return [2 /*return*/, String(expectedBN.minus(balancedExpectedBN).div(balancedExpectedBN).times(100))];
|
|
1507
|
-
}
|
|
1508
|
-
});
|
|
1509
|
-
});
|
|
1510
|
-
};
|
|
1511
|
-
PoolTemplate.prototype.depositWrappedIsApproved = function (amounts) {
|
|
1512
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1513
|
-
return __generator(this, function (_c) {
|
|
1514
|
-
switch (_c.label) {
|
|
1515
|
-
case 0:
|
|
1516
|
-
if (this.isFake) {
|
|
1517
|
-
throw Error("depositWrappedIsApproved method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
1518
|
-
}
|
|
1519
|
-
return [4 /*yield*/, (0, utils_1.hasAllowance)(this.wrappedCoinAddresses, amounts, curve_1.curve.signerAddress, this.address)];
|
|
1520
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
1521
|
-
}
|
|
1522
|
-
});
|
|
1523
|
-
});
|
|
1524
|
-
};
|
|
1525
|
-
PoolTemplate.prototype.depositWrappedApproveEstimateGas = function (amounts) {
|
|
1526
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1527
|
-
return __generator(this, function (_c) {
|
|
1528
|
-
switch (_c.label) {
|
|
1529
|
-
case 0:
|
|
1530
|
-
if (this.isFake) {
|
|
1531
|
-
throw Error("depositWrappedApprove method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
1532
|
-
}
|
|
1533
|
-
return [4 /*yield*/, (0, utils_1.ensureAllowanceEstimateGas)(this.wrappedCoinAddresses, amounts, this.address)];
|
|
1534
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
1535
|
-
}
|
|
1536
|
-
});
|
|
1537
|
-
});
|
|
1538
|
-
};
|
|
1539
|
-
PoolTemplate.prototype.depositWrappedApprove = function (amounts) {
|
|
1540
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1541
|
-
return __generator(this, function (_c) {
|
|
1542
|
-
switch (_c.label) {
|
|
1543
|
-
case 0:
|
|
1544
|
-
if (this.isFake) {
|
|
1545
|
-
throw Error("depositWrappedApprove method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
1546
|
-
}
|
|
1547
|
-
return [4 /*yield*/, (0, utils_1.ensureAllowance)(this.wrappedCoinAddresses, amounts, this.address)];
|
|
1548
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
1549
|
-
}
|
|
1550
|
-
});
|
|
1551
|
-
});
|
|
1552
|
-
};
|
|
946
|
+
async depositWrappedBalancedAmounts() {
|
|
947
|
+
throw Error(`depositWrappedBalancedAmounts method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
948
|
+
}
|
|
949
|
+
async depositWrappedExpected(amounts) {
|
|
950
|
+
if (this.isFake) {
|
|
951
|
+
throw Error(`depositWrappedExpected method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
952
|
+
}
|
|
953
|
+
return await this.calcLpTokenAmountWrapped(amounts);
|
|
954
|
+
}
|
|
955
|
+
async depositWrappedBonus(amounts) {
|
|
956
|
+
const amountsBN = amounts.map(BN);
|
|
957
|
+
const pricesBN = (await this._wrappedPrices()).map(BN);
|
|
958
|
+
const balancesBN = (await this.stats.wrappedBalances()).map(BN);
|
|
959
|
+
const balancedAmounts = this._balancedAmountsWithSameValue(amountsBN, pricesBN, balancesBN);
|
|
960
|
+
const expectedBN = BN(await this.depositWrappedExpected(amounts));
|
|
961
|
+
const balancedExpectedBN = BN(await this.depositWrappedExpected(balancedAmounts));
|
|
962
|
+
return String(expectedBN.minus(balancedExpectedBN).div(balancedExpectedBN).times(100));
|
|
963
|
+
}
|
|
964
|
+
async depositWrappedIsApproved(amounts) {
|
|
965
|
+
if (this.isFake) {
|
|
966
|
+
throw Error(`depositWrappedIsApproved method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
967
|
+
}
|
|
968
|
+
return await hasAllowance(this.wrappedCoinAddresses, amounts, curve.signerAddress, this.address);
|
|
969
|
+
}
|
|
970
|
+
async depositWrappedApproveEstimateGas(amounts) {
|
|
971
|
+
if (this.isFake) {
|
|
972
|
+
throw Error(`depositWrappedApprove method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
973
|
+
}
|
|
974
|
+
return await ensureAllowanceEstimateGas(this.wrappedCoinAddresses, amounts, this.address);
|
|
975
|
+
}
|
|
976
|
+
async depositWrappedApprove(amounts) {
|
|
977
|
+
if (this.isFake) {
|
|
978
|
+
throw Error(`depositWrappedApprove method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
979
|
+
}
|
|
980
|
+
return await ensureAllowance(this.wrappedCoinAddresses, amounts, this.address);
|
|
981
|
+
}
|
|
1553
982
|
// OVERRIDE
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
throw Error("depositWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
1558
|
-
});
|
|
1559
|
-
});
|
|
1560
|
-
};
|
|
983
|
+
async depositWrappedEstimateGas(amounts) {
|
|
984
|
+
throw Error(`depositWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
985
|
+
}
|
|
1561
986
|
// OVERRIDE
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
return __generator(this, function (_c) {
|
|
1566
|
-
throw Error("depositWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
1567
|
-
});
|
|
1568
|
-
});
|
|
1569
|
-
};
|
|
987
|
+
async depositWrapped(amounts, slippage = 0.5) {
|
|
988
|
+
throw Error(`depositWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
989
|
+
}
|
|
1570
990
|
// ---------------- STAKING ----------------
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
return [4 /*yield*/, curve_1.curve.updateFeeData()];
|
|
1643
|
-
case 2:
|
|
1644
|
-
_c.sent();
|
|
1645
|
-
return [4 /*yield*/, curve_1.curve.contracts[this.gauge].contract.estimateGas.deposit(_lpTokenAmount, curve_1.curve.constantOptions)];
|
|
1646
|
-
case 3:
|
|
1647
|
-
gasLimit = (_c.sent()).mul(150).div(100);
|
|
1648
|
-
return [4 /*yield*/, curve_1.curve.contracts[this.gauge].contract.deposit(_lpTokenAmount, __assign(__assign({}, curve_1.curve.options), { gasLimit: gasLimit }))];
|
|
1649
|
-
case 4: return [2 /*return*/, (_c.sent()).hash];
|
|
1650
|
-
}
|
|
1651
|
-
});
|
|
1652
|
-
});
|
|
1653
|
-
};
|
|
1654
|
-
PoolTemplate.prototype.unstakeEstimateGas = function (lpTokenAmount) {
|
|
1655
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1656
|
-
var _lpTokenAmount;
|
|
1657
|
-
return __generator(this, function (_c) {
|
|
1658
|
-
switch (_c.label) {
|
|
1659
|
-
case 0:
|
|
1660
|
-
if (this.gauge === ethers_1.ethers.constants.AddressZero) {
|
|
1661
|
-
throw Error("unstakeEstimateGas method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, "). There is no gauge"));
|
|
1662
|
-
}
|
|
1663
|
-
_lpTokenAmount = (0, utils_1.parseUnits)(lpTokenAmount);
|
|
1664
|
-
return [4 /*yield*/, curve_1.curve.contracts[this.gauge].contract.estimateGas.withdraw(_lpTokenAmount, curve_1.curve.constantOptions)];
|
|
1665
|
-
case 1: return [2 /*return*/, (_c.sent()).toNumber()];
|
|
1666
|
-
}
|
|
1667
|
-
});
|
|
1668
|
-
});
|
|
1669
|
-
};
|
|
1670
|
-
PoolTemplate.prototype.unstake = function (lpTokenAmount) {
|
|
1671
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1672
|
-
var _lpTokenAmount, gasLimit;
|
|
1673
|
-
return __generator(this, function (_c) {
|
|
1674
|
-
switch (_c.label) {
|
|
1675
|
-
case 0:
|
|
1676
|
-
if (this.gauge === ethers_1.ethers.constants.AddressZero) {
|
|
1677
|
-
throw Error("unstake method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, "). There is no gauge"));
|
|
1678
|
-
}
|
|
1679
|
-
_lpTokenAmount = (0, utils_1.parseUnits)(lpTokenAmount);
|
|
1680
|
-
return [4 /*yield*/, curve_1.curve.updateFeeData()];
|
|
1681
|
-
case 1:
|
|
1682
|
-
_c.sent();
|
|
1683
|
-
return [4 /*yield*/, curve_1.curve.contracts[this.gauge].contract.estimateGas.withdraw(_lpTokenAmount, curve_1.curve.constantOptions)];
|
|
1684
|
-
case 2:
|
|
1685
|
-
gasLimit = (_c.sent()).mul(200).div(100);
|
|
1686
|
-
return [4 /*yield*/, curve_1.curve.contracts[this.gauge].contract.withdraw(_lpTokenAmount, __assign(__assign({}, curve_1.curve.options), { gasLimit: gasLimit }))];
|
|
1687
|
-
case 3: return [2 /*return*/, (_c.sent()).hash];
|
|
1688
|
-
}
|
|
1689
|
-
});
|
|
1690
|
-
});
|
|
1691
|
-
};
|
|
1692
|
-
PoolTemplate.prototype.claimableCrv = function (address) {
|
|
1693
|
-
if (address === void 0) { address = ""; }
|
|
1694
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1695
|
-
var _c, _d;
|
|
1696
|
-
return __generator(this, function (_e) {
|
|
1697
|
-
switch (_e.label) {
|
|
1698
|
-
case 0:
|
|
1699
|
-
if (this.rewardsOnly())
|
|
1700
|
-
throw Error("".concat(this.name, " has Rewards-Only Gauge. Use claimableRewards instead"));
|
|
1701
|
-
address = address || curve_1.curve.signerAddress;
|
|
1702
|
-
if (!address)
|
|
1703
|
-
throw Error("Need to connect wallet or pass address into args");
|
|
1704
|
-
_d = (_c = ethers_1.ethers.utils).formatUnits;
|
|
1705
|
-
return [4 /*yield*/, curve_1.curve.contracts[this.gauge].contract.claimable_tokens(address, curve_1.curve.constantOptions)];
|
|
1706
|
-
case 1: return [2 /*return*/, _d.apply(_c, [_e.sent()])];
|
|
1707
|
-
}
|
|
1708
|
-
});
|
|
1709
|
-
});
|
|
1710
|
-
};
|
|
1711
|
-
PoolTemplate.prototype.claimCrvEstimateGas = function () {
|
|
1712
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1713
|
-
return __generator(this, function (_c) {
|
|
1714
|
-
switch (_c.label) {
|
|
1715
|
-
case 0:
|
|
1716
|
-
if (this.rewardsOnly())
|
|
1717
|
-
throw Error("".concat(this.name, " has Rewards-Only Gauge. Use claimRewards instead"));
|
|
1718
|
-
return [4 /*yield*/, curve_1.curve.contracts[curve_1.curve.constants.ALIASES.minter].contract.estimateGas.mint(this.gauge, curve_1.curve.constantOptions)];
|
|
1719
|
-
case 1: return [2 /*return*/, (_c.sent()).toNumber()];
|
|
1720
|
-
}
|
|
1721
|
-
});
|
|
1722
|
-
});
|
|
1723
|
-
};
|
|
1724
|
-
PoolTemplate.prototype.claimCrv = function () {
|
|
1725
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1726
|
-
var contract, gasLimit;
|
|
1727
|
-
return __generator(this, function (_c) {
|
|
1728
|
-
switch (_c.label) {
|
|
1729
|
-
case 0:
|
|
1730
|
-
if (this.rewardsOnly())
|
|
1731
|
-
throw Error("".concat(this.name, " has Rewards-Only Gauge. Use claimRewards instead"));
|
|
1732
|
-
contract = curve_1.curve.contracts[curve_1.curve.constants.ALIASES.minter].contract;
|
|
1733
|
-
return [4 /*yield*/, contract.estimateGas.mint(this.gauge, curve_1.curve.constantOptions)];
|
|
1734
|
-
case 1:
|
|
1735
|
-
gasLimit = (_c.sent()).mul(130).div(100);
|
|
1736
|
-
return [4 /*yield*/, contract.mint(this.gauge, __assign(__assign({}, curve_1.curve.options), { gasLimit: gasLimit }))];
|
|
1737
|
-
case 2: return [2 /*return*/, (_c.sent()).hash];
|
|
1738
|
-
}
|
|
1739
|
-
});
|
|
1740
|
-
});
|
|
1741
|
-
};
|
|
991
|
+
async stakeIsApproved(lpTokenAmount) {
|
|
992
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
993
|
+
throw Error(`stakeIsApproved method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
994
|
+
}
|
|
995
|
+
return await hasAllowance([this.lpToken], [lpTokenAmount], curve.signerAddress, this.gauge);
|
|
996
|
+
}
|
|
997
|
+
async stakeApproveEstimateGas(lpTokenAmount) {
|
|
998
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
999
|
+
throw Error(`stakeApproveEstimateGas method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1000
|
+
}
|
|
1001
|
+
return await ensureAllowanceEstimateGas([this.lpToken], [lpTokenAmount], this.gauge);
|
|
1002
|
+
}
|
|
1003
|
+
async stakeApprove(lpTokenAmount) {
|
|
1004
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1005
|
+
throw Error(`stakeApprove method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1006
|
+
}
|
|
1007
|
+
return await ensureAllowance([this.lpToken], [lpTokenAmount], this.gauge);
|
|
1008
|
+
}
|
|
1009
|
+
async stakeEstimateGas(lpTokenAmount) {
|
|
1010
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1011
|
+
throw Error(`stakeEstimateGas method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1012
|
+
}
|
|
1013
|
+
const _lpTokenAmount = parseUnits(lpTokenAmount);
|
|
1014
|
+
return Number(await curve.contracts[this.gauge].contract.deposit.estimateGas(_lpTokenAmount, curve.constantOptions));
|
|
1015
|
+
}
|
|
1016
|
+
async stake(lpTokenAmount) {
|
|
1017
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1018
|
+
throw Error(`stake method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1019
|
+
}
|
|
1020
|
+
const _lpTokenAmount = parseUnits(lpTokenAmount);
|
|
1021
|
+
await _ensureAllowance([this.lpToken], [_lpTokenAmount], this.gauge);
|
|
1022
|
+
await curve.updateFeeData();
|
|
1023
|
+
const gasLimit = mulBy1_3(await curve.contracts[this.gauge].contract.deposit.estimateGas(_lpTokenAmount, curve.constantOptions));
|
|
1024
|
+
return (await curve.contracts[this.gauge].contract.deposit(_lpTokenAmount, { ...curve.options, gasLimit })).hash;
|
|
1025
|
+
}
|
|
1026
|
+
async unstakeEstimateGas(lpTokenAmount) {
|
|
1027
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1028
|
+
throw Error(`unstakeEstimateGas method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1029
|
+
}
|
|
1030
|
+
const _lpTokenAmount = parseUnits(lpTokenAmount);
|
|
1031
|
+
return Number(await curve.contracts[this.gauge].contract.withdraw.estimateGas(_lpTokenAmount, curve.constantOptions));
|
|
1032
|
+
}
|
|
1033
|
+
async unstake(lpTokenAmount) {
|
|
1034
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1035
|
+
throw Error(`unstake method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1036
|
+
}
|
|
1037
|
+
const _lpTokenAmount = parseUnits(lpTokenAmount);
|
|
1038
|
+
await curve.updateFeeData();
|
|
1039
|
+
const gasLimit = (await curve.contracts[this.gauge].contract.withdraw.estimateGas(_lpTokenAmount, curve.constantOptions)) * 200n / 100n;
|
|
1040
|
+
return (await curve.contracts[this.gauge].contract.withdraw(_lpTokenAmount, { ...curve.options, gasLimit })).hash;
|
|
1041
|
+
}
|
|
1042
|
+
async claimableCrv(address = "") {
|
|
1043
|
+
if (this.rewardsOnly())
|
|
1044
|
+
throw Error(`${this.name} has Rewards-Only Gauge. Use claimableRewards instead`);
|
|
1045
|
+
address = address || curve.signerAddress;
|
|
1046
|
+
if (!address)
|
|
1047
|
+
throw Error("Need to connect wallet or pass address into args");
|
|
1048
|
+
return curve.formatUnits(await curve.contracts[this.gauge].contract.claimable_tokens(address, curve.constantOptions));
|
|
1049
|
+
}
|
|
1050
|
+
async claimCrvEstimateGas() {
|
|
1051
|
+
if (this.rewardsOnly())
|
|
1052
|
+
throw Error(`${this.name} has Rewards-Only Gauge. Use claimRewards instead`);
|
|
1053
|
+
return Number(await curve.contracts[curve.constants.ALIASES.minter].contract.mint.estimateGas(this.gauge, curve.constantOptions));
|
|
1054
|
+
}
|
|
1055
|
+
async claimCrv() {
|
|
1056
|
+
if (this.rewardsOnly())
|
|
1057
|
+
throw Error(`${this.name} has Rewards-Only Gauge. Use claimRewards instead`);
|
|
1058
|
+
const contract = curve.contracts[curve.constants.ALIASES.minter].contract;
|
|
1059
|
+
const gasLimit = mulBy1_3(await contract.mint.estimateGas(this.gauge, curve.constantOptions));
|
|
1060
|
+
return (await contract.mint(this.gauge, { ...curve.options, gasLimit })).hash;
|
|
1061
|
+
}
|
|
1742
1062
|
// TODO 1. Fix aave and saave error
|
|
1743
|
-
|
|
1744
|
-
if (
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
token: rewardToken.token,
|
|
1772
|
-
symbol: rewardToken.symbol,
|
|
1773
|
-
amount: ethers_1.ethers.utils.formatUnits(_amount, rewardToken.decimals),
|
|
1774
|
-
});
|
|
1775
|
-
_c.label = 4;
|
|
1776
|
-
case 4:
|
|
1777
|
-
_i++;
|
|
1778
|
-
return [3 /*break*/, 2];
|
|
1779
|
-
case 5: return [3 /*break*/, 9];
|
|
1780
|
-
case 6:
|
|
1781
|
-
if (!('claimable_reward(address)' in gaugeContract && rewardTokens.length > 0)) return [3 /*break*/, 9];
|
|
1782
|
-
rewardToken = rewardTokens[0];
|
|
1783
|
-
return [4 /*yield*/, gaugeContract.claimable_reward(address, curve_1.curve.constantOptions)];
|
|
1784
|
-
case 7:
|
|
1785
|
-
_totalAmount = _c.sent();
|
|
1786
|
-
return [4 /*yield*/, gaugeContract.claimed_rewards_for(address, curve_1.curve.constantOptions)];
|
|
1787
|
-
case 8:
|
|
1788
|
-
_claimedAmount = _c.sent();
|
|
1789
|
-
rewards.push({
|
|
1790
|
-
token: rewardToken.token,
|
|
1791
|
-
symbol: rewardToken.symbol,
|
|
1792
|
-
amount: ethers_1.ethers.utils.formatUnits(_totalAmount.sub(_claimedAmount), rewardToken.decimals),
|
|
1793
|
-
});
|
|
1794
|
-
_c.label = 9;
|
|
1795
|
-
case 9: return [2 /*return*/, rewards];
|
|
1796
|
-
}
|
|
1797
|
-
});
|
|
1798
|
-
});
|
|
1799
|
-
};
|
|
1800
|
-
PoolTemplate.prototype.claimRewardsEstimateGas = function () {
|
|
1801
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1802
|
-
var gaugeContract;
|
|
1803
|
-
return __generator(this, function (_c) {
|
|
1804
|
-
switch (_c.label) {
|
|
1805
|
-
case 0:
|
|
1806
|
-
if (this.gauge === ethers_1.ethers.constants.AddressZero) {
|
|
1807
|
-
throw Error("claimRewards method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, "). There is no gauge"));
|
|
1808
|
-
}
|
|
1809
|
-
gaugeContract = curve_1.curve.contracts[this.gauge].contract;
|
|
1810
|
-
if (!("claim_rewards()" in gaugeContract))
|
|
1811
|
-
throw Error("".concat(this.name, " pool doesn't have such method"));
|
|
1812
|
-
return [4 /*yield*/, gaugeContract.estimateGas.claim_rewards(curve_1.curve.constantOptions)];
|
|
1813
|
-
case 1: return [2 /*return*/, (_c.sent()).toNumber()];
|
|
1814
|
-
}
|
|
1815
|
-
});
|
|
1816
|
-
});
|
|
1817
|
-
};
|
|
1818
|
-
PoolTemplate.prototype.claimRewards = function () {
|
|
1819
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1820
|
-
var gaugeContract, gasLimit;
|
|
1821
|
-
return __generator(this, function (_c) {
|
|
1822
|
-
switch (_c.label) {
|
|
1823
|
-
case 0:
|
|
1824
|
-
if (this.gauge === ethers_1.ethers.constants.AddressZero) {
|
|
1825
|
-
throw Error("claimRewards method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, "). There is no gauge"));
|
|
1826
|
-
}
|
|
1827
|
-
gaugeContract = curve_1.curve.contracts[this.gauge].contract;
|
|
1828
|
-
if (!("claim_rewards()" in gaugeContract))
|
|
1829
|
-
throw Error("".concat(this.name, " pool doesn't have such method"));
|
|
1830
|
-
return [4 /*yield*/, gaugeContract.estimateGas.claim_rewards(curve_1.curve.constantOptions)];
|
|
1831
|
-
case 1:
|
|
1832
|
-
gasLimit = (_c.sent()).mul(130).div(100);
|
|
1833
|
-
return [4 /*yield*/, gaugeContract.claim_rewards(__assign(__assign({}, curve_1.curve.options), { gasLimit: gasLimit }))];
|
|
1834
|
-
case 2: return [2 /*return*/, (_c.sent()).hash];
|
|
1835
|
-
}
|
|
1063
|
+
async claimableRewards(address = "") {
|
|
1064
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1065
|
+
throw Error(`claimableRewards method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1066
|
+
}
|
|
1067
|
+
address = address || curve.signerAddress;
|
|
1068
|
+
if (!address)
|
|
1069
|
+
throw Error("Need to connect wallet or pass address into args");
|
|
1070
|
+
const gaugeContract = curve.contracts[this.gauge].contract;
|
|
1071
|
+
const rewardTokens = await this.rewardTokens();
|
|
1072
|
+
const rewards = [];
|
|
1073
|
+
if ('claimable_reward(address,address)' in gaugeContract) {
|
|
1074
|
+
for (const rewardToken of rewardTokens) {
|
|
1075
|
+
const _amount = await gaugeContract.claimable_reward(address, rewardToken.token, curve.constantOptions);
|
|
1076
|
+
rewards.push({
|
|
1077
|
+
token: rewardToken.token,
|
|
1078
|
+
symbol: rewardToken.symbol,
|
|
1079
|
+
amount: curve.formatUnits(_amount, rewardToken.decimals),
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
else if ('claimable_reward(address)' in gaugeContract && rewardTokens.length > 0) { // Synthetix Gauge
|
|
1084
|
+
const rewardToken = rewardTokens[0];
|
|
1085
|
+
const _totalAmount = await gaugeContract.claimable_reward(address, curve.constantOptions);
|
|
1086
|
+
const _claimedAmount = await gaugeContract.claimed_rewards_for(address, curve.constantOptions);
|
|
1087
|
+
rewards.push({
|
|
1088
|
+
token: rewardToken.token,
|
|
1089
|
+
symbol: rewardToken.symbol,
|
|
1090
|
+
amount: curve.formatUnits(_totalAmount.sub(_claimedAmount), rewardToken.decimals),
|
|
1836
1091
|
});
|
|
1837
|
-
}
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
});
|
|
1852
|
-
}
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
return
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
return [4 /*yield*/, (0, utils_1.ensureAllowance)(this.underlyingCoinAddresses, amounts, curve_1.curve.constants.ALIASES.deposit_and_stake)];
|
|
1928
|
-
case 1:
|
|
1929
|
-
approveCoinsTx = _c.sent();
|
|
1930
|
-
gaugeContract = curve_1.curve.contracts[this.gauge].contract;
|
|
1931
|
-
if (!Object.prototype.hasOwnProperty.call(gaugeContract, 'approved_to_deposit')) return [3 /*break*/, 5];
|
|
1932
|
-
return [4 /*yield*/, gaugeContract.approved_to_deposit(curve_1.curve.constants.ALIASES.deposit_and_stake, curve_1.curve.signerAddress, curve_1.curve.constantOptions)];
|
|
1933
|
-
case 2:
|
|
1934
|
-
gaugeAllowance = _c.sent();
|
|
1935
|
-
if (!!gaugeAllowance) return [3 /*break*/, 5];
|
|
1936
|
-
return [4 /*yield*/, gaugeContract.estimateGas.set_approve_deposit(curve_1.curve.constants.ALIASES.deposit_and_stake, true, curve_1.curve.constantOptions)];
|
|
1937
|
-
case 3:
|
|
1938
|
-
gasLimit = (_c.sent()).mul(130).div(100);
|
|
1939
|
-
return [4 /*yield*/, gaugeContract.set_approve_deposit(curve_1.curve.constants.ALIASES.deposit_and_stake, true, __assign(__assign({}, curve_1.curve.options), { gasLimit: gasLimit }))];
|
|
1940
|
-
case 4:
|
|
1941
|
-
approveGaugeTx = (_c.sent()).hash;
|
|
1942
|
-
return [2 /*return*/, __spreadArray(__spreadArray([], approveCoinsTx, true), [approveGaugeTx], false)];
|
|
1943
|
-
case 5: return [2 /*return*/, approveCoinsTx];
|
|
1944
|
-
}
|
|
1945
|
-
});
|
|
1946
|
-
});
|
|
1947
|
-
};
|
|
1948
|
-
PoolTemplate.prototype.depositAndStakeEstimateGas = function (amounts) {
|
|
1949
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1950
|
-
return __generator(this, function (_c) {
|
|
1951
|
-
switch (_c.label) {
|
|
1952
|
-
case 0:
|
|
1953
|
-
if (this.gauge === ethers_1.ethers.constants.AddressZero) {
|
|
1954
|
-
throw Error("depositAndStake method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, "). There is no gauge"));
|
|
1955
|
-
}
|
|
1956
|
-
return [4 /*yield*/, this._depositAndStake(amounts, 1, true, true)];
|
|
1957
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
1958
|
-
}
|
|
1959
|
-
});
|
|
1960
|
-
});
|
|
1961
|
-
};
|
|
1962
|
-
PoolTemplate.prototype.depositAndStake = function (amounts, slippage) {
|
|
1963
|
-
if (slippage === void 0) { slippage = 0.1; }
|
|
1964
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1965
|
-
return __generator(this, function (_c) {
|
|
1966
|
-
switch (_c.label) {
|
|
1967
|
-
case 0:
|
|
1968
|
-
if (this.gauge === ethers_1.ethers.constants.AddressZero) {
|
|
1969
|
-
throw Error("depositAndStake method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, "). There is no gauge"));
|
|
1970
|
-
}
|
|
1971
|
-
return [4 /*yield*/, this._depositAndStake(amounts, slippage, true, false)];
|
|
1972
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
1973
|
-
}
|
|
1974
|
-
});
|
|
1975
|
-
});
|
|
1976
|
-
};
|
|
1092
|
+
}
|
|
1093
|
+
return rewards;
|
|
1094
|
+
}
|
|
1095
|
+
async claimRewardsEstimateGas() {
|
|
1096
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1097
|
+
throw Error(`claimRewards method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1098
|
+
}
|
|
1099
|
+
const gaugeContract = curve.contracts[this.gauge].contract;
|
|
1100
|
+
if (!("claim_rewards()" in gaugeContract))
|
|
1101
|
+
throw Error(`${this.name} pool doesn't have such method`);
|
|
1102
|
+
return Number(await gaugeContract.claim_rewards.estimateGas(curve.constantOptions));
|
|
1103
|
+
}
|
|
1104
|
+
async claimRewards() {
|
|
1105
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1106
|
+
throw Error(`claimRewards method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1107
|
+
}
|
|
1108
|
+
const gaugeContract = curve.contracts[this.gauge].contract;
|
|
1109
|
+
if (!("claim_rewards()" in gaugeContract))
|
|
1110
|
+
throw Error(`${this.name} pool doesn't have such method`);
|
|
1111
|
+
const gasLimit = mulBy1_3(await gaugeContract.claim_rewards.estimateGas(curve.constantOptions));
|
|
1112
|
+
return (await gaugeContract.claim_rewards({ ...curve.options, gasLimit })).hash;
|
|
1113
|
+
}
|
|
1114
|
+
// ---------------- DEPOSIT & STAKE ----------------
|
|
1115
|
+
async depositAndStakeExpected(amounts) {
|
|
1116
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1117
|
+
throw Error(`depositAndStakeExpected method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1118
|
+
}
|
|
1119
|
+
return await this.depositExpected(amounts);
|
|
1120
|
+
}
|
|
1121
|
+
async depositAndStakeBonus(amounts) {
|
|
1122
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1123
|
+
throw Error(`depositAndStakeBonus method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1124
|
+
}
|
|
1125
|
+
return await this.depositBonus(amounts);
|
|
1126
|
+
}
|
|
1127
|
+
async depositAndStakeIsApproved(amounts) {
|
|
1128
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1129
|
+
throw Error(`depositAndStakeIsApproved method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1130
|
+
}
|
|
1131
|
+
const coinsAllowance = await hasAllowance(this.underlyingCoinAddresses, amounts, curve.signerAddress, curve.constants.ALIASES.deposit_and_stake);
|
|
1132
|
+
const gaugeContract = curve.contracts[this.gauge].contract;
|
|
1133
|
+
if (Object.prototype.hasOwnProperty.call(gaugeContract, 'approved_to_deposit')) {
|
|
1134
|
+
const gaugeAllowance = await gaugeContract.approved_to_deposit(curve.constants.ALIASES.deposit_and_stake, curve.signerAddress, curve.constantOptions);
|
|
1135
|
+
return coinsAllowance && gaugeAllowance;
|
|
1136
|
+
}
|
|
1137
|
+
return coinsAllowance;
|
|
1138
|
+
}
|
|
1139
|
+
async depositAndStakeApproveEstimateGas(amounts) {
|
|
1140
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1141
|
+
throw Error(`depositAndStakeApprove method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1142
|
+
}
|
|
1143
|
+
const approveCoinsGas = await ensureAllowanceEstimateGas(this.underlyingCoinAddresses, amounts, curve.constants.ALIASES.deposit_and_stake);
|
|
1144
|
+
const gaugeContract = curve.contracts[this.gauge].contract;
|
|
1145
|
+
if (Object.prototype.hasOwnProperty.call(gaugeContract, 'approved_to_deposit')) {
|
|
1146
|
+
const gaugeAllowance = await gaugeContract.approved_to_deposit(curve.constants.ALIASES.deposit_and_stake, curve.signerAddress, curve.constantOptions);
|
|
1147
|
+
if (!gaugeAllowance) {
|
|
1148
|
+
const approveGaugeGas = Number(await gaugeContract.set_approve_deposit.estimateGas(curve.constants.ALIASES.deposit_and_stake, true, curve.constantOptions));
|
|
1149
|
+
return approveCoinsGas + approveGaugeGas;
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
return approveCoinsGas;
|
|
1153
|
+
}
|
|
1154
|
+
async depositAndStakeApprove(amounts) {
|
|
1155
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1156
|
+
throw Error(`depositAndStakeApprove method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1157
|
+
}
|
|
1158
|
+
const approveCoinsTx = await ensureAllowance(this.underlyingCoinAddresses, amounts, curve.constants.ALIASES.deposit_and_stake);
|
|
1159
|
+
const gaugeContract = curve.contracts[this.gauge].contract;
|
|
1160
|
+
if (Object.prototype.hasOwnProperty.call(gaugeContract, 'approved_to_deposit')) {
|
|
1161
|
+
const gaugeAllowance = await gaugeContract.approved_to_deposit(curve.constants.ALIASES.deposit_and_stake, curve.signerAddress, curve.constantOptions);
|
|
1162
|
+
if (!gaugeAllowance) {
|
|
1163
|
+
const gasLimit = mulBy1_3(await gaugeContract.set_approve_deposit.estimateGas(curve.constants.ALIASES.deposit_and_stake, true, curve.constantOptions));
|
|
1164
|
+
const approveGaugeTx = (await gaugeContract.set_approve_deposit(curve.constants.ALIASES.deposit_and_stake, true, { ...curve.options, gasLimit })).hash;
|
|
1165
|
+
return [...approveCoinsTx, approveGaugeTx];
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
return approveCoinsTx;
|
|
1169
|
+
}
|
|
1170
|
+
async depositAndStakeEstimateGas(amounts) {
|
|
1171
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1172
|
+
throw Error(`depositAndStake method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1173
|
+
}
|
|
1174
|
+
return await this._depositAndStake(amounts, 1, true, true);
|
|
1175
|
+
}
|
|
1176
|
+
async depositAndStake(amounts, slippage = 0.1) {
|
|
1177
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1178
|
+
throw Error(`depositAndStake method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1179
|
+
}
|
|
1180
|
+
return await this._depositAndStake(amounts, slippage, true, false);
|
|
1181
|
+
}
|
|
1977
1182
|
// ---------------- DEPOSIT & STAKE WRAPPED ----------------
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
});
|
|
1992
|
-
|
|
1993
|
-
}
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2108
|
-
}
|
|
2109
|
-
});
|
|
2110
|
-
});
|
|
2111
|
-
};
|
|
2112
|
-
PoolTemplate.prototype.depositAndStakeWrapped = function (amounts, slippage) {
|
|
2113
|
-
if (slippage === void 0) { slippage = 0.1; }
|
|
2114
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2115
|
-
return __generator(this, function (_c) {
|
|
2116
|
-
switch (_c.label) {
|
|
2117
|
-
case 0:
|
|
2118
|
-
if (this.gauge === ethers_1.ethers.constants.AddressZero) {
|
|
2119
|
-
throw Error("depositAndStakeWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, "). There is no gauge"));
|
|
2120
|
-
}
|
|
2121
|
-
if (this.isPlain || this.isFake)
|
|
2122
|
-
throw Error("depositAndStakeWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2123
|
-
return [4 /*yield*/, this._depositAndStake(amounts, slippage, false, false)];
|
|
2124
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2125
|
-
}
|
|
2126
|
-
});
|
|
2127
|
-
});
|
|
2128
|
-
};
|
|
2129
|
-
PoolTemplate.prototype._depositAndStake = function (amounts, slippage, isUnderlying, estimateGas) {
|
|
2130
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2131
|
-
var coinAddresses, coins, decimals, depositAddress, balances, _c, _d, _e, _f, _g, i, allowance, _h, _amounts, contract, useUnderlying, _expectedLpTokenAmount, _j, _k, _l, _m, _o, minAmountBN, _minMintAmount, ethIndex, value, maxCoins, i, _gas, gasLimit;
|
|
2132
|
-
return __generator(this, function (_q) {
|
|
2133
|
-
switch (_q.label) {
|
|
2134
|
-
case 0:
|
|
2135
|
-
coinAddresses = isUnderlying ? __spreadArray([], this.underlyingCoinAddresses, true) : __spreadArray([], this.wrappedCoinAddresses, true);
|
|
2136
|
-
coins = isUnderlying ? this.underlyingCoins : this.wrappedCoinAddresses;
|
|
2137
|
-
decimals = isUnderlying ? this.underlyingDecimals : this.wrappedDecimals;
|
|
2138
|
-
depositAddress = isUnderlying ? this.zap || this.address : this.address;
|
|
2139
|
-
if (amounts.length !== coinAddresses.length) {
|
|
2140
|
-
throw Error("".concat(this.name, " pool has ").concat(coinAddresses.length, " coins (amounts provided for ").concat(amounts.length, ")"));
|
|
2141
|
-
}
|
|
2142
|
-
if (!isUnderlying) return [3 /*break*/, 2];
|
|
2143
|
-
_e = (_d = Object).values;
|
|
2144
|
-
return [4 /*yield*/, this.walletUnderlyingCoinBalances()];
|
|
2145
|
-
case 1:
|
|
2146
|
-
_c = _e.apply(_d, [_q.sent()]);
|
|
2147
|
-
return [3 /*break*/, 4];
|
|
2148
|
-
case 2:
|
|
2149
|
-
_g = (_f = Object).values;
|
|
2150
|
-
return [4 /*yield*/, this.walletWrappedCoinBalances()];
|
|
2151
|
-
case 3:
|
|
2152
|
-
_c = _g.apply(_f, [_q.sent()]);
|
|
2153
|
-
_q.label = 4;
|
|
2154
|
-
case 4:
|
|
2155
|
-
balances = _c;
|
|
2156
|
-
for (i = 0; i < balances.length; i++) {
|
|
2157
|
-
if (Number(balances[i]) < Number(amounts[i])) {
|
|
2158
|
-
throw Error("Not enough ".concat(coins[i], ". Actual: ").concat(balances[i], ", required: ").concat(amounts[i]));
|
|
2159
|
-
}
|
|
2160
|
-
}
|
|
2161
|
-
if (!isUnderlying) return [3 /*break*/, 6];
|
|
2162
|
-
return [4 /*yield*/, this.depositAndStakeIsApproved(amounts)];
|
|
2163
|
-
case 5:
|
|
2164
|
-
_h = _q.sent();
|
|
2165
|
-
return [3 /*break*/, 8];
|
|
2166
|
-
case 6: return [4 /*yield*/, this.depositAndStakeWrappedIsApproved(amounts)];
|
|
2167
|
-
case 7:
|
|
2168
|
-
_h = _q.sent();
|
|
2169
|
-
_q.label = 8;
|
|
2170
|
-
case 8:
|
|
2171
|
-
allowance = _h;
|
|
2172
|
-
if (estimateGas && !allowance) {
|
|
2173
|
-
throw Error("Token allowance is needed to estimate gas");
|
|
2174
|
-
}
|
|
2175
|
-
if (!!estimateGas) return [3 /*break*/, 12];
|
|
2176
|
-
if (!isUnderlying) return [3 /*break*/, 10];
|
|
2177
|
-
return [4 /*yield*/, this.depositAndStakeApprove(amounts)];
|
|
2178
|
-
case 9:
|
|
2179
|
-
_q.sent();
|
|
2180
|
-
return [3 /*break*/, 12];
|
|
2181
|
-
case 10: return [4 /*yield*/, this.depositAndStakeWrappedApprove(amounts)];
|
|
2182
|
-
case 11:
|
|
2183
|
-
_q.sent();
|
|
2184
|
-
_q.label = 12;
|
|
2185
|
-
case 12:
|
|
2186
|
-
_amounts = amounts.map(function (amount, i) { return (0, utils_1.parseUnits)(amount, decimals[i]); });
|
|
2187
|
-
contract = curve_1.curve.contracts[curve_1.curve.constants.ALIASES.deposit_and_stake].contract;
|
|
2188
|
-
useUnderlying = isUnderlying && (this.isLending || (this.isCrypto && !this.isPlain)) && (!this.zap || this.id == 'avaxcrypto');
|
|
2189
|
-
if (!isUnderlying) return [3 /*break*/, 14];
|
|
2190
|
-
_l = (_k = ethers_1.ethers.utils).parseUnits;
|
|
2191
|
-
return [4 /*yield*/, this.depositAndStakeExpected(amounts)];
|
|
2192
|
-
case 13:
|
|
2193
|
-
_j = _l.apply(_k, [_q.sent()]);
|
|
2194
|
-
return [3 /*break*/, 16];
|
|
2195
|
-
case 14:
|
|
2196
|
-
_o = (_m = ethers_1.ethers.utils).parseUnits;
|
|
2197
|
-
return [4 /*yield*/, this.depositAndStakeWrappedExpected(amounts)];
|
|
2198
|
-
case 15:
|
|
2199
|
-
_j = _o.apply(_m, [_q.sent()]);
|
|
2200
|
-
_q.label = 16;
|
|
2201
|
-
case 16:
|
|
2202
|
-
_expectedLpTokenAmount = _j;
|
|
2203
|
-
minAmountBN = (0, utils_1.toBN)(_expectedLpTokenAmount).times(100 - slippage).div(100);
|
|
2204
|
-
_minMintAmount = (0, utils_1.fromBN)(minAmountBN);
|
|
2205
|
-
ethIndex = (0, utils_1.getEthIndex)(coinAddresses);
|
|
2206
|
-
value = _amounts[ethIndex] || ethers_1.ethers.BigNumber.from(0);
|
|
2207
|
-
maxCoins = curve_1.curve.chainId === 137 ? 6 : 5;
|
|
2208
|
-
for (i = 0; i < maxCoins; i++) {
|
|
2209
|
-
coinAddresses[i] = coinAddresses[i] || ethers_1.ethers.constants.AddressZero;
|
|
2210
|
-
_amounts[i] = _amounts[i] || ethers_1.ethers.BigNumber.from(0);
|
|
2211
|
-
}
|
|
2212
|
-
return [4 /*yield*/, contract.estimateGas.deposit_and_stake(depositAddress, this.lpToken, this.gauge, coins.length, coinAddresses, _amounts, _minMintAmount, useUnderlying, this.isMetaFactory && isUnderlying ? this.address : ethers_1.ethers.constants.AddressZero, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
|
|
2213
|
-
case 17:
|
|
2214
|
-
_gas = (_q.sent());
|
|
2215
|
-
if (estimateGas)
|
|
2216
|
-
return [2 /*return*/, _gas.toNumber()];
|
|
2217
|
-
return [4 /*yield*/, curve_1.curve.updateFeeData()];
|
|
2218
|
-
case 18:
|
|
2219
|
-
_q.sent();
|
|
2220
|
-
gasLimit = _gas.mul(200).div(100);
|
|
2221
|
-
return [4 /*yield*/, contract.deposit_and_stake(depositAddress, this.lpToken, this.gauge, coins.length, coinAddresses, _amounts, _minMintAmount, useUnderlying, this.isMetaFactory && isUnderlying ? this.address : ethers_1.ethers.constants.AddressZero, __assign(__assign({}, curve_1.curve.options), { gasLimit: gasLimit, value: value }))];
|
|
2222
|
-
case 19: return [2 /*return*/, (_q.sent()).hash];
|
|
2223
|
-
}
|
|
2224
|
-
});
|
|
2225
|
-
});
|
|
2226
|
-
};
|
|
1183
|
+
async depositAndStakeWrappedExpected(amounts) {
|
|
1184
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1185
|
+
throw Error(`depositAndStakeWrappedExpected method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1186
|
+
}
|
|
1187
|
+
if (this.isPlain || this.isFake)
|
|
1188
|
+
throw Error(`depositAndStakeWrappedExpected method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1189
|
+
return await this.depositWrappedExpected(amounts);
|
|
1190
|
+
}
|
|
1191
|
+
async depositAndStakeWrappedBonus(amounts) {
|
|
1192
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1193
|
+
throw Error(`depositAndStakeWrappedBonus method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1194
|
+
}
|
|
1195
|
+
if (this.isPlain || this.isFake)
|
|
1196
|
+
throw Error(`depositAndStakeWrappedBonus method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1197
|
+
return await this.depositWrappedBonus(amounts);
|
|
1198
|
+
}
|
|
1199
|
+
async depositAndStakeWrappedIsApproved(amounts) {
|
|
1200
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1201
|
+
throw Error(`depositAndStakeWrappedIsApproved method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1202
|
+
}
|
|
1203
|
+
if (this.isPlain || this.isFake)
|
|
1204
|
+
throw Error(`depositAndStakeWrappedIsApproved method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1205
|
+
const coinsAllowance = await hasAllowance(this.wrappedCoinAddresses, amounts, curve.signerAddress, curve.constants.ALIASES.deposit_and_stake);
|
|
1206
|
+
const gaugeContract = curve.contracts[this.gauge].contract;
|
|
1207
|
+
if (Object.prototype.hasOwnProperty.call(gaugeContract, 'approved_to_deposit')) {
|
|
1208
|
+
const gaugeAllowance = await gaugeContract.approved_to_deposit(curve.constants.ALIASES.deposit_and_stake, curve.signerAddress, curve.constantOptions);
|
|
1209
|
+
return coinsAllowance && gaugeAllowance;
|
|
1210
|
+
}
|
|
1211
|
+
return coinsAllowance;
|
|
1212
|
+
}
|
|
1213
|
+
async depositAndStakeWrappedApproveEstimateGas(amounts) {
|
|
1214
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1215
|
+
throw Error(`depositAndStakeWrappedApprove method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1216
|
+
}
|
|
1217
|
+
if (this.isPlain || this.isFake)
|
|
1218
|
+
throw Error(`depositAndStakeWrappedApprove method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1219
|
+
const approveCoinsGas = await ensureAllowanceEstimateGas(this.wrappedCoinAddresses, amounts, curve.constants.ALIASES.deposit_and_stake);
|
|
1220
|
+
const gaugeContract = curve.contracts[this.gauge].contract;
|
|
1221
|
+
if (Object.prototype.hasOwnProperty.call(gaugeContract, 'approved_to_deposit')) {
|
|
1222
|
+
const gaugeAllowance = await gaugeContract.approved_to_deposit(curve.constants.ALIASES.deposit_and_stake, curve.signerAddress, curve.constantOptions);
|
|
1223
|
+
if (!gaugeAllowance) {
|
|
1224
|
+
const approveGaugeGas = Number(await gaugeContract.set_approve_deposit.estimateGas(curve.constants.ALIASES.deposit_and_stake, true, curve.constantOptions));
|
|
1225
|
+
return approveCoinsGas + approveGaugeGas;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
return approveCoinsGas;
|
|
1229
|
+
}
|
|
1230
|
+
async depositAndStakeWrappedApprove(amounts) {
|
|
1231
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1232
|
+
throw Error(`depositAndStakeWrappedApprove method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1233
|
+
}
|
|
1234
|
+
if (this.isPlain || this.isFake)
|
|
1235
|
+
throw Error(`depositAndStakeWrappedApprove method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1236
|
+
const approveCoinsTx = await ensureAllowance(this.wrappedCoinAddresses, amounts, curve.constants.ALIASES.deposit_and_stake);
|
|
1237
|
+
const gaugeContract = curve.contracts[this.gauge].contract;
|
|
1238
|
+
if (Object.prototype.hasOwnProperty.call(gaugeContract, 'approved_to_deposit')) {
|
|
1239
|
+
const gaugeAllowance = await gaugeContract.approved_to_deposit(curve.constants.ALIASES.deposit_and_stake, curve.signerAddress, curve.constantOptions);
|
|
1240
|
+
if (!gaugeAllowance) {
|
|
1241
|
+
const gasLimit = mulBy1_3(await gaugeContract.set_approve_deposit.estimateGas(curve.constants.ALIASES.deposit_and_stake, true, curve.constantOptions));
|
|
1242
|
+
const approveGaugeTx = (await gaugeContract.set_approve_deposit(curve.constants.ALIASES.deposit_and_stake, true, { ...curve.options, gasLimit })).hash;
|
|
1243
|
+
return [...approveCoinsTx, approveGaugeTx];
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
return approveCoinsTx;
|
|
1247
|
+
}
|
|
1248
|
+
async depositAndStakeWrappedEstimateGas(amounts) {
|
|
1249
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1250
|
+
throw Error(`depositAndStakeWrapped method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1251
|
+
}
|
|
1252
|
+
if (this.isPlain || this.isFake)
|
|
1253
|
+
throw Error(`depositAndStakeWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1254
|
+
return await this._depositAndStake(amounts, 1, false, true);
|
|
1255
|
+
}
|
|
1256
|
+
async depositAndStakeWrapped(amounts, slippage = 0.1) {
|
|
1257
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1258
|
+
throw Error(`depositAndStakeWrapped method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
|
|
1259
|
+
}
|
|
1260
|
+
if (this.isPlain || this.isFake)
|
|
1261
|
+
throw Error(`depositAndStakeWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1262
|
+
return await this._depositAndStake(amounts, slippage, false, false);
|
|
1263
|
+
}
|
|
1264
|
+
async _depositAndStake(amounts, slippage, isUnderlying, estimateGas) {
|
|
1265
|
+
const coinAddresses = isUnderlying ? [...this.underlyingCoinAddresses] : [...this.wrappedCoinAddresses];
|
|
1266
|
+
const coins = isUnderlying ? this.underlyingCoins : this.wrappedCoinAddresses;
|
|
1267
|
+
const decimals = isUnderlying ? this.underlyingDecimals : this.wrappedDecimals;
|
|
1268
|
+
const depositAddress = isUnderlying ? this.zap || this.address : this.address;
|
|
1269
|
+
if (amounts.length !== coinAddresses.length) {
|
|
1270
|
+
throw Error(`${this.name} pool has ${coinAddresses.length} coins (amounts provided for ${amounts.length})`);
|
|
1271
|
+
}
|
|
1272
|
+
const balances = isUnderlying ? Object.values(await this.walletUnderlyingCoinBalances()) : Object.values(await this.walletWrappedCoinBalances());
|
|
1273
|
+
for (let i = 0; i < balances.length; i++) {
|
|
1274
|
+
if (Number(balances[i]) < Number(amounts[i])) {
|
|
1275
|
+
throw Error(`Not enough ${coins[i]}. Actual: ${balances[i]}, required: ${amounts[i]}`);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
const allowance = isUnderlying ? await this.depositAndStakeIsApproved(amounts) : await this.depositAndStakeWrappedIsApproved(amounts);
|
|
1279
|
+
if (estimateGas && !allowance) {
|
|
1280
|
+
throw Error("Token allowance is needed to estimate gas");
|
|
1281
|
+
}
|
|
1282
|
+
if (!estimateGas) {
|
|
1283
|
+
if (isUnderlying) {
|
|
1284
|
+
await this.depositAndStakeApprove(amounts);
|
|
1285
|
+
}
|
|
1286
|
+
else {
|
|
1287
|
+
await this.depositAndStakeWrappedApprove(amounts);
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
const _amounts = amounts.map((amount, i) => parseUnits(amount, decimals[i]));
|
|
1291
|
+
const contract = curve.contracts[curve.constants.ALIASES.deposit_and_stake].contract;
|
|
1292
|
+
const useUnderlying = isUnderlying && (this.isLending || (this.isCrypto && !this.isPlain)) && (!this.zap || this.id == 'avaxcrypto');
|
|
1293
|
+
const _expectedLpTokenAmount = isUnderlying ?
|
|
1294
|
+
curve.parseUnits(await this.depositAndStakeExpected(amounts)) :
|
|
1295
|
+
curve.parseUnits(await this.depositAndStakeWrappedExpected(amounts));
|
|
1296
|
+
const minAmountBN = toBN(_expectedLpTokenAmount).times(100 - slippage).div(100);
|
|
1297
|
+
const _minMintAmount = fromBN(minAmountBN);
|
|
1298
|
+
const ethIndex = getEthIndex(coinAddresses);
|
|
1299
|
+
const value = _amounts[ethIndex] || 0n;
|
|
1300
|
+
const maxCoins = curve.chainId === 137 ? 6 : 5;
|
|
1301
|
+
for (let i = 0; i < maxCoins; i++) {
|
|
1302
|
+
coinAddresses[i] = coinAddresses[i] || curve.constants.ZERO_ADDRESS;
|
|
1303
|
+
_amounts[i] = _amounts[i] || 0n;
|
|
1304
|
+
}
|
|
1305
|
+
const _gas = (await contract.deposit_and_stake.estimateGas(depositAddress, this.lpToken, this.gauge, coins.length, coinAddresses, _amounts, _minMintAmount, useUnderlying, this.isMetaFactory && isUnderlying ? this.address : curve.constants.ZERO_ADDRESS, { ...curve.constantOptions, value }));
|
|
1306
|
+
if (estimateGas)
|
|
1307
|
+
return Number(_gas);
|
|
1308
|
+
await curve.updateFeeData();
|
|
1309
|
+
const gasLimit = _gas * 200n / 100n;
|
|
1310
|
+
return (await contract.deposit_and_stake(depositAddress, this.lpToken, this.gauge, coins.length, coinAddresses, _amounts, _minMintAmount, useUnderlying, this.isMetaFactory && isUnderlying ? this.address : curve.constants.ZERO_ADDRESS, { ...curve.options, gasLimit, value })).hash;
|
|
1311
|
+
}
|
|
2227
1312
|
// ---------------- WITHDRAW ----------------
|
|
2228
1313
|
// OVERRIDE
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
});
|
|
2248
|
-
};
|
|
2249
|
-
PoolTemplate.prototype.withdrawApproveEstimateGas = function (lpTokenAmount) {
|
|
2250
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2251
|
-
return __generator(this, function (_c) {
|
|
2252
|
-
switch (_c.label) {
|
|
2253
|
-
case 0:
|
|
2254
|
-
if (!this.zap)
|
|
2255
|
-
return [2 /*return*/, 0];
|
|
2256
|
-
return [4 /*yield*/, (0, utils_1.ensureAllowanceEstimateGas)([this.lpToken], [lpTokenAmount], this.zap)];
|
|
2257
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2258
|
-
}
|
|
2259
|
-
});
|
|
2260
|
-
});
|
|
2261
|
-
};
|
|
2262
|
-
PoolTemplate.prototype.withdrawApprove = function (lpTokenAmount) {
|
|
2263
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2264
|
-
return __generator(this, function (_c) {
|
|
2265
|
-
switch (_c.label) {
|
|
2266
|
-
case 0:
|
|
2267
|
-
if (!this.zap)
|
|
2268
|
-
return [2 /*return*/, []];
|
|
2269
|
-
return [4 /*yield*/, (0, utils_1.ensureAllowance)([this.lpToken], [lpTokenAmount], this.zap)];
|
|
2270
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2271
|
-
}
|
|
2272
|
-
});
|
|
2273
|
-
});
|
|
2274
|
-
};
|
|
1314
|
+
async withdrawExpected(lpTokenAmount) {
|
|
1315
|
+
throw Error(`withdrawExpected method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1316
|
+
}
|
|
1317
|
+
async withdrawIsApproved(lpTokenAmount) {
|
|
1318
|
+
if (!this.zap)
|
|
1319
|
+
return true;
|
|
1320
|
+
return await hasAllowance([this.lpToken], [lpTokenAmount], curve.signerAddress, this.zap);
|
|
1321
|
+
}
|
|
1322
|
+
async withdrawApproveEstimateGas(lpTokenAmount) {
|
|
1323
|
+
if (!this.zap)
|
|
1324
|
+
return 0;
|
|
1325
|
+
return await ensureAllowanceEstimateGas([this.lpToken], [lpTokenAmount], this.zap);
|
|
1326
|
+
}
|
|
1327
|
+
async withdrawApprove(lpTokenAmount) {
|
|
1328
|
+
if (!this.zap)
|
|
1329
|
+
return [];
|
|
1330
|
+
return await ensureAllowance([this.lpToken], [lpTokenAmount], this.zap);
|
|
1331
|
+
}
|
|
2275
1332
|
// OVERRIDE
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
throw Error("withdraw method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2280
|
-
});
|
|
2281
|
-
});
|
|
2282
|
-
};
|
|
1333
|
+
async withdrawEstimateGas(lpTokenAmount) {
|
|
1334
|
+
throw Error(`withdraw method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1335
|
+
}
|
|
2283
1336
|
// OVERRIDE
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
return __generator(this, function (_c) {
|
|
2288
|
-
throw Error("withdraw method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2289
|
-
});
|
|
2290
|
-
});
|
|
2291
|
-
};
|
|
1337
|
+
async withdraw(lpTokenAmount, slippage = 0.5) {
|
|
1338
|
+
throw Error(`withdraw method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1339
|
+
}
|
|
2292
1340
|
// ---------------- WITHDRAW WRAPPED ----------------
|
|
2293
1341
|
// OVERRIDE
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
throw Error("withdrawWrappedExpected method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2298
|
-
});
|
|
2299
|
-
});
|
|
2300
|
-
};
|
|
1342
|
+
async withdrawWrappedExpected(lpTokenAmount) {
|
|
1343
|
+
throw Error(`withdrawWrappedExpected method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1344
|
+
}
|
|
2301
1345
|
// OVERRIDE
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
throw Error("withdrawWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2306
|
-
});
|
|
2307
|
-
});
|
|
2308
|
-
};
|
|
1346
|
+
async withdrawWrappedEstimateGas(lpTokenAmount) {
|
|
1347
|
+
throw Error(`withdrawWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1348
|
+
}
|
|
2309
1349
|
// OVERRIDE
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
return __generator(this, function (_c) {
|
|
2314
|
-
throw Error("withdrawWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2315
|
-
});
|
|
2316
|
-
});
|
|
2317
|
-
};
|
|
1350
|
+
async withdrawWrapped(lpTokenAmount, slippage = 0.5) {
|
|
1351
|
+
throw Error(`withdrawWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1352
|
+
}
|
|
2318
1353
|
// ---------------- WITHDRAW IMBALANCE ----------------
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
}
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
}
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2363
|
-
var _amounts, _maxBurnAmount;
|
|
2364
|
-
var _this = this;
|
|
2365
|
-
return __generator(this, function (_c) {
|
|
2366
|
-
switch (_c.label) {
|
|
2367
|
-
case 0:
|
|
2368
|
-
if (this.isCrypto)
|
|
2369
|
-
throw Error("withdrawImbalanceIsApproved method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2370
|
-
if (!this.zap) return [3 /*break*/, 3];
|
|
2371
|
-
_amounts = amounts.map(function (amount, i) { return (0, utils_1.parseUnits)(amount, _this.underlyingDecimals[i]); });
|
|
2372
|
-
return [4 /*yield*/, this._calcLpTokenAmount(_amounts, false)];
|
|
2373
|
-
case 1:
|
|
2374
|
-
_maxBurnAmount = (_c.sent()).mul(101).div(100);
|
|
2375
|
-
return [4 /*yield*/, (0, utils_1.hasAllowance)([this.lpToken], [ethers_1.ethers.utils.formatUnits(_maxBurnAmount, 18)], curve_1.curve.signerAddress, this.zap)];
|
|
2376
|
-
case 2: return [2 /*return*/, _c.sent()];
|
|
2377
|
-
case 3: return [2 /*return*/, true];
|
|
2378
|
-
}
|
|
2379
|
-
});
|
|
2380
|
-
});
|
|
2381
|
-
};
|
|
2382
|
-
PoolTemplate.prototype.withdrawImbalanceApproveEstimateGas = function (amounts) {
|
|
2383
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2384
|
-
var _amounts, _maxBurnAmount;
|
|
2385
|
-
var _this = this;
|
|
2386
|
-
return __generator(this, function (_c) {
|
|
2387
|
-
switch (_c.label) {
|
|
2388
|
-
case 0:
|
|
2389
|
-
if (this.isCrypto)
|
|
2390
|
-
throw Error("withdrawImbalanceApprove method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2391
|
-
if (!this.zap) return [3 /*break*/, 3];
|
|
2392
|
-
_amounts = amounts.map(function (amount, i) { return (0, utils_1.parseUnits)(amount, _this.underlyingDecimals[i]); });
|
|
2393
|
-
return [4 /*yield*/, this._calcLpTokenAmount(_amounts, false)];
|
|
2394
|
-
case 1:
|
|
2395
|
-
_maxBurnAmount = (_c.sent()).mul(101).div(100);
|
|
2396
|
-
return [4 /*yield*/, (0, utils_1.ensureAllowanceEstimateGas)([this.lpToken], [ethers_1.ethers.utils.formatUnits(_maxBurnAmount, 18)], this.zap)];
|
|
2397
|
-
case 2: return [2 /*return*/, _c.sent()];
|
|
2398
|
-
case 3: return [2 /*return*/, 0];
|
|
2399
|
-
}
|
|
2400
|
-
});
|
|
2401
|
-
});
|
|
2402
|
-
};
|
|
2403
|
-
PoolTemplate.prototype.withdrawImbalanceApprove = function (amounts) {
|
|
2404
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2405
|
-
var _amounts, _maxBurnAmount;
|
|
2406
|
-
var _this = this;
|
|
2407
|
-
return __generator(this, function (_c) {
|
|
2408
|
-
switch (_c.label) {
|
|
2409
|
-
case 0:
|
|
2410
|
-
if (this.isCrypto)
|
|
2411
|
-
throw Error("withdrawImbalanceApprove method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2412
|
-
if (!this.zap) return [3 /*break*/, 3];
|
|
2413
|
-
_amounts = amounts.map(function (amount, i) { return (0, utils_1.parseUnits)(amount, _this.underlyingDecimals[i]); });
|
|
2414
|
-
return [4 /*yield*/, this._calcLpTokenAmount(_amounts, false)];
|
|
2415
|
-
case 1:
|
|
2416
|
-
_maxBurnAmount = (_c.sent()).mul(101).div(100);
|
|
2417
|
-
return [4 /*yield*/, (0, utils_1.ensureAllowance)([this.lpToken], [ethers_1.ethers.utils.formatUnits(_maxBurnAmount, 18)], this.zap)];
|
|
2418
|
-
case 2: return [2 /*return*/, _c.sent()];
|
|
2419
|
-
case 3: return [2 /*return*/, []];
|
|
2420
|
-
}
|
|
2421
|
-
});
|
|
2422
|
-
});
|
|
2423
|
-
};
|
|
1354
|
+
async withdrawImbalanceExpected(amounts) {
|
|
1355
|
+
if (this.isCrypto)
|
|
1356
|
+
throw Error(`withdrawImbalanceExpected method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1357
|
+
return await this.calcLpTokenAmount(amounts, false);
|
|
1358
|
+
}
|
|
1359
|
+
async withdrawImbalanceBonus(amounts) {
|
|
1360
|
+
const prices = (this.isCrypto || this.id === 'wsteth') ? await this._underlyingPrices() : this.underlyingCoins.map(() => 1);
|
|
1361
|
+
const value = amounts.map(checkNumber).map(Number).reduce((s, a, i) => s + (a * prices[i]), 0);
|
|
1362
|
+
const lpTokenAmount = await this.withdrawImbalanceExpected(amounts);
|
|
1363
|
+
const balancedAmounts = await this.withdrawExpected(lpTokenAmount);
|
|
1364
|
+
const balancedValue = balancedAmounts.map(Number).reduce((s, a, i) => s + (a * prices[i]), 0);
|
|
1365
|
+
return String((value - balancedValue) / balancedValue * 100);
|
|
1366
|
+
}
|
|
1367
|
+
async withdrawImbalanceIsApproved(amounts) {
|
|
1368
|
+
if (this.isCrypto)
|
|
1369
|
+
throw Error(`withdrawImbalanceIsApproved method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1370
|
+
if (this.zap) {
|
|
1371
|
+
const _amounts = amounts.map((amount, i) => parseUnits(amount, this.underlyingDecimals[i]));
|
|
1372
|
+
const _maxBurnAmount = (await this._calcLpTokenAmount(_amounts, false)) * 101n / 100n;
|
|
1373
|
+
return await hasAllowance([this.lpToken], [curve.formatUnits(_maxBurnAmount, 18)], curve.signerAddress, this.zap);
|
|
1374
|
+
}
|
|
1375
|
+
return true;
|
|
1376
|
+
}
|
|
1377
|
+
async withdrawImbalanceApproveEstimateGas(amounts) {
|
|
1378
|
+
if (this.isCrypto)
|
|
1379
|
+
throw Error(`withdrawImbalanceApprove method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1380
|
+
if (this.zap) {
|
|
1381
|
+
const _amounts = amounts.map((amount, i) => parseUnits(amount, this.underlyingDecimals[i]));
|
|
1382
|
+
const _maxBurnAmount = (await this._calcLpTokenAmount(_amounts, false)) * 101n / 100n;
|
|
1383
|
+
return await ensureAllowanceEstimateGas([this.lpToken], [curve.formatUnits(_maxBurnAmount, 18)], this.zap);
|
|
1384
|
+
}
|
|
1385
|
+
return 0;
|
|
1386
|
+
}
|
|
1387
|
+
async withdrawImbalanceApprove(amounts) {
|
|
1388
|
+
if (this.isCrypto)
|
|
1389
|
+
throw Error(`withdrawImbalanceApprove method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1390
|
+
if (this.zap) {
|
|
1391
|
+
const _amounts = amounts.map((amount, i) => parseUnits(amount, this.underlyingDecimals[i]));
|
|
1392
|
+
const _maxBurnAmount = (await this._calcLpTokenAmount(_amounts, false)) * 101n / 100n;
|
|
1393
|
+
return await ensureAllowance([this.lpToken], [curve.formatUnits(_maxBurnAmount, 18)], this.zap);
|
|
1394
|
+
}
|
|
1395
|
+
return [];
|
|
1396
|
+
}
|
|
2424
1397
|
// OVERRIDE
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
throw Error("withdrawImbalance method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2429
|
-
});
|
|
2430
|
-
});
|
|
2431
|
-
};
|
|
1398
|
+
async withdrawImbalanceEstimateGas(amounts) {
|
|
1399
|
+
throw Error(`withdrawImbalance method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1400
|
+
}
|
|
2432
1401
|
// OVERRIDE
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
return __generator(this, function (_c) {
|
|
2437
|
-
throw Error("withdrawImbalance method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2438
|
-
});
|
|
2439
|
-
});
|
|
2440
|
-
};
|
|
1402
|
+
async withdrawImbalance(amounts, slippage = 0.5) {
|
|
1403
|
+
throw Error(`withdrawImbalance method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1404
|
+
}
|
|
2441
1405
|
// ---------------- WITHDRAW IMBALANCE WRAPPED ----------------
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
}
|
|
2455
|
-
PoolTemplate.prototype.withdrawImbalanceWrappedBonus = function (amounts) {
|
|
2456
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2457
|
-
var prices, value, lpTokenAmount, _c, balancedAmounts, balancedValue;
|
|
2458
|
-
return __generator(this, function (_d) {
|
|
2459
|
-
switch (_d.label) {
|
|
2460
|
-
case 0: return [4 /*yield*/, this._wrappedPrices()];
|
|
2461
|
-
case 1:
|
|
2462
|
-
prices = _d.sent();
|
|
2463
|
-
value = amounts.map(utils_1.checkNumber).map(Number).reduce(function (s, a, i) { return s + (a * prices[i]); }, 0);
|
|
2464
|
-
_c = Number;
|
|
2465
|
-
return [4 /*yield*/, this.withdrawImbalanceWrappedExpected(amounts)];
|
|
2466
|
-
case 2:
|
|
2467
|
-
lpTokenAmount = _c.apply(void 0, [_d.sent()]);
|
|
2468
|
-
return [4 /*yield*/, this.withdrawWrappedExpected(lpTokenAmount)];
|
|
2469
|
-
case 3:
|
|
2470
|
-
balancedAmounts = _d.sent();
|
|
2471
|
-
balancedValue = balancedAmounts.map(Number).reduce(function (s, a, i) { return s + (a * prices[i]); }, 0);
|
|
2472
|
-
return [2 /*return*/, String((value - balancedValue) / balancedValue * 100)];
|
|
2473
|
-
}
|
|
2474
|
-
});
|
|
2475
|
-
});
|
|
2476
|
-
};
|
|
1406
|
+
async withdrawImbalanceWrappedExpected(amounts) {
|
|
1407
|
+
if (this.isCrypto || this.isPlain || this.isFake)
|
|
1408
|
+
throw Error(`withdrawImbalanceWrappedExpected method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1409
|
+
return await this.calcLpTokenAmountWrapped(amounts, false);
|
|
1410
|
+
}
|
|
1411
|
+
async withdrawImbalanceWrappedBonus(amounts) {
|
|
1412
|
+
const prices = await this._wrappedPrices();
|
|
1413
|
+
const value = amounts.map(checkNumber).map(Number).reduce((s, a, i) => s + (a * prices[i]), 0);
|
|
1414
|
+
const lpTokenAmount = Number(await this.withdrawImbalanceWrappedExpected(amounts));
|
|
1415
|
+
const balancedAmounts = await this.withdrawWrappedExpected(lpTokenAmount);
|
|
1416
|
+
const balancedValue = balancedAmounts.map(Number).reduce((s, a, i) => s + (a * prices[i]), 0);
|
|
1417
|
+
return String((value - balancedValue) / balancedValue * 100);
|
|
1418
|
+
}
|
|
2477
1419
|
// OVERRIDE
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
throw Error("withdrawImbalanceWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2482
|
-
});
|
|
2483
|
-
});
|
|
2484
|
-
};
|
|
1420
|
+
async withdrawImbalanceWrappedEstimateGas(amounts) {
|
|
1421
|
+
throw Error(`withdrawImbalanceWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1422
|
+
}
|
|
2485
1423
|
// OVERRIDE
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
return __generator(this, function (_c) {
|
|
2490
|
-
throw Error("withdrawImbalanceWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2491
|
-
});
|
|
2492
|
-
});
|
|
2493
|
-
};
|
|
1424
|
+
async withdrawImbalanceWrapped(amounts, slippage = 0.5) {
|
|
1425
|
+
throw Error(`withdrawImbalanceWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1426
|
+
}
|
|
2494
1427
|
// ---------------- WITHDRAW ONE COIN ----------------
|
|
2495
1428
|
// OVERRIDE
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
}
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
return [3 /*break*/, 3];
|
|
2530
|
-
case 2:
|
|
2531
|
-
_c = this.underlyingCoins.map(function () { return 1; });
|
|
2532
|
-
_e.label = 3;
|
|
2533
|
-
case 3:
|
|
2534
|
-
prices = _c;
|
|
2535
|
-
coinPrice = prices[this._getCoinIdx(coin)];
|
|
2536
|
-
_d = Number;
|
|
2537
|
-
return [4 /*yield*/, this.withdrawOneCoinExpected(lpTokenAmount, coin)];
|
|
2538
|
-
case 4:
|
|
2539
|
-
amount = _d.apply(void 0, [_e.sent()]);
|
|
2540
|
-
value = amount * coinPrice;
|
|
2541
|
-
return [4 /*yield*/, this.withdrawExpected(lpTokenAmount)];
|
|
2542
|
-
case 5:
|
|
2543
|
-
balancedAmounts = _e.sent();
|
|
2544
|
-
balancedValue = balancedAmounts.map(Number).reduce(function (s, a, i) { return s + (a * prices[i]); }, 0);
|
|
2545
|
-
return [2 /*return*/, String((value - balancedValue) / balancedValue * 100)];
|
|
2546
|
-
}
|
|
2547
|
-
});
|
|
2548
|
-
});
|
|
2549
|
-
};
|
|
2550
|
-
PoolTemplate.prototype.withdrawOneCoinIsApproved = function (lpTokenAmount) {
|
|
2551
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2552
|
-
return __generator(this, function (_c) {
|
|
2553
|
-
switch (_c.label) {
|
|
2554
|
-
case 0:
|
|
2555
|
-
if (!this.zap)
|
|
2556
|
-
return [2 /*return*/, true];
|
|
2557
|
-
return [4 /*yield*/, (0, utils_1.hasAllowance)([this.lpToken], [lpTokenAmount], curve_1.curve.signerAddress, this.zap)];
|
|
2558
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2559
|
-
}
|
|
2560
|
-
});
|
|
2561
|
-
});
|
|
2562
|
-
};
|
|
2563
|
-
PoolTemplate.prototype.withdrawOneCoinApproveEstimateGas = function (lpTokenAmount) {
|
|
2564
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2565
|
-
return __generator(this, function (_c) {
|
|
2566
|
-
switch (_c.label) {
|
|
2567
|
-
case 0:
|
|
2568
|
-
if (!this.zap)
|
|
2569
|
-
return [2 /*return*/, 0];
|
|
2570
|
-
return [4 /*yield*/, (0, utils_1.ensureAllowanceEstimateGas)([this.lpToken], [lpTokenAmount], this.zap)];
|
|
2571
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2572
|
-
}
|
|
2573
|
-
});
|
|
2574
|
-
});
|
|
2575
|
-
};
|
|
2576
|
-
PoolTemplate.prototype.withdrawOneCoinApprove = function (lpTokenAmount) {
|
|
2577
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2578
|
-
return __generator(this, function (_c) {
|
|
2579
|
-
switch (_c.label) {
|
|
2580
|
-
case 0:
|
|
2581
|
-
if (!this.zap)
|
|
2582
|
-
return [2 /*return*/, []];
|
|
2583
|
-
return [4 /*yield*/, (0, utils_1.ensureAllowance)([this.lpToken], [lpTokenAmount], this.zap)];
|
|
2584
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2585
|
-
}
|
|
2586
|
-
});
|
|
2587
|
-
});
|
|
2588
|
-
};
|
|
1429
|
+
async _withdrawOneCoinExpected(_lpTokenAmount, i) {
|
|
1430
|
+
throw Error(`withdrawOneCoinExpected method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1431
|
+
}
|
|
1432
|
+
async withdrawOneCoinExpected(lpTokenAmount, coin) {
|
|
1433
|
+
const i = this._getCoinIdx(coin);
|
|
1434
|
+
const _lpTokenAmount = parseUnits(lpTokenAmount);
|
|
1435
|
+
const _expected = await this._withdrawOneCoinExpected(_lpTokenAmount, i);
|
|
1436
|
+
return curve.formatUnits(_expected, this.underlyingDecimals[i]);
|
|
1437
|
+
}
|
|
1438
|
+
async withdrawOneCoinBonus(lpTokenAmount, coin) {
|
|
1439
|
+
const prices = (this.isCrypto || this.id === 'wsteth') ? await this._underlyingPrices() : this.underlyingCoins.map(() => 1);
|
|
1440
|
+
const coinPrice = prices[this._getCoinIdx(coin)];
|
|
1441
|
+
const amount = Number(await this.withdrawOneCoinExpected(lpTokenAmount, coin));
|
|
1442
|
+
const value = amount * coinPrice;
|
|
1443
|
+
const balancedAmounts = await this.withdrawExpected(lpTokenAmount);
|
|
1444
|
+
const balancedValue = balancedAmounts.map(Number).reduce((s, a, i) => s + (a * prices[i]), 0);
|
|
1445
|
+
return String((value - balancedValue) / balancedValue * 100);
|
|
1446
|
+
}
|
|
1447
|
+
async withdrawOneCoinIsApproved(lpTokenAmount) {
|
|
1448
|
+
if (!this.zap)
|
|
1449
|
+
return true;
|
|
1450
|
+
return await hasAllowance([this.lpToken], [lpTokenAmount], curve.signerAddress, this.zap);
|
|
1451
|
+
}
|
|
1452
|
+
async withdrawOneCoinApproveEstimateGas(lpTokenAmount) {
|
|
1453
|
+
if (!this.zap)
|
|
1454
|
+
return 0;
|
|
1455
|
+
return await ensureAllowanceEstimateGas([this.lpToken], [lpTokenAmount], this.zap);
|
|
1456
|
+
}
|
|
1457
|
+
async withdrawOneCoinApprove(lpTokenAmount) {
|
|
1458
|
+
if (!this.zap)
|
|
1459
|
+
return [];
|
|
1460
|
+
return await ensureAllowance([this.lpToken], [lpTokenAmount], this.zap);
|
|
1461
|
+
}
|
|
2589
1462
|
// OVERRIDE
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
throw Error("withdrawOneCoin method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2594
|
-
});
|
|
2595
|
-
});
|
|
2596
|
-
};
|
|
1463
|
+
async withdrawOneCoinEstimateGas(lpTokenAmount, coin) {
|
|
1464
|
+
throw Error(`withdrawOneCoin method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1465
|
+
}
|
|
2597
1466
|
// OVERRIDE
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
return __generator(this, function (_c) {
|
|
2602
|
-
throw Error("withdrawOneCoin method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2603
|
-
});
|
|
2604
|
-
});
|
|
2605
|
-
};
|
|
1467
|
+
async withdrawOneCoin(lpTokenAmount, coin, slippage = 0.5) {
|
|
1468
|
+
throw Error(`withdrawOneCoin method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1469
|
+
}
|
|
2606
1470
|
// ---------------- WITHDRAW ONE COIN WRAPPED ----------------
|
|
2607
1471
|
// OVERRIDE
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
return [2 /*return*/, ethers_1.ethers.utils.formatUnits(_expected, this.wrappedDecimals[i])];
|
|
2627
|
-
}
|
|
2628
|
-
});
|
|
2629
|
-
});
|
|
2630
|
-
};
|
|
2631
|
-
PoolTemplate.prototype.withdrawOneCoinWrappedBonus = function (lpTokenAmount, coin) {
|
|
2632
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2633
|
-
var prices, coinPrice, amount, _c, value, balancedAmounts, balancedValue;
|
|
2634
|
-
return __generator(this, function (_d) {
|
|
2635
|
-
switch (_d.label) {
|
|
2636
|
-
case 0: return [4 /*yield*/, this._wrappedPrices()];
|
|
2637
|
-
case 1:
|
|
2638
|
-
prices = _d.sent();
|
|
2639
|
-
coinPrice = prices[this._getCoinIdx(coin, false)];
|
|
2640
|
-
_c = Number;
|
|
2641
|
-
return [4 /*yield*/, this.withdrawOneCoinWrappedExpected(lpTokenAmount, coin)];
|
|
2642
|
-
case 2:
|
|
2643
|
-
amount = _c.apply(void 0, [_d.sent()]);
|
|
2644
|
-
value = amount * coinPrice;
|
|
2645
|
-
return [4 /*yield*/, this.withdrawWrappedExpected(lpTokenAmount)];
|
|
2646
|
-
case 3:
|
|
2647
|
-
balancedAmounts = _d.sent();
|
|
2648
|
-
balancedValue = balancedAmounts.map(Number).reduce(function (s, a, i) { return s + (a * prices[i]); }, 0);
|
|
2649
|
-
return [2 /*return*/, String((value - balancedValue) / balancedValue * 100)];
|
|
2650
|
-
}
|
|
2651
|
-
});
|
|
2652
|
-
});
|
|
2653
|
-
};
|
|
1472
|
+
async _withdrawOneCoinWrappedExpected(_lpTokenAmount, i) {
|
|
1473
|
+
throw Error(`withdrawOneCoinWrappedExpected method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1474
|
+
}
|
|
1475
|
+
async withdrawOneCoinWrappedExpected(lpTokenAmount, coin) {
|
|
1476
|
+
const i = this._getCoinIdx(coin, false);
|
|
1477
|
+
const _lpTokenAmount = parseUnits(lpTokenAmount);
|
|
1478
|
+
const _expected = await this._withdrawOneCoinWrappedExpected(_lpTokenAmount, i);
|
|
1479
|
+
return curve.formatUnits(_expected, this.wrappedDecimals[i]);
|
|
1480
|
+
}
|
|
1481
|
+
async withdrawOneCoinWrappedBonus(lpTokenAmount, coin) {
|
|
1482
|
+
const prices = await this._wrappedPrices();
|
|
1483
|
+
const coinPrice = prices[this._getCoinIdx(coin, false)];
|
|
1484
|
+
const amount = Number(await this.withdrawOneCoinWrappedExpected(lpTokenAmount, coin));
|
|
1485
|
+
const value = amount * coinPrice;
|
|
1486
|
+
const balancedAmounts = await this.withdrawWrappedExpected(lpTokenAmount);
|
|
1487
|
+
const balancedValue = balancedAmounts.map(Number).reduce((s, a, i) => s + (a * prices[i]), 0);
|
|
1488
|
+
return String((value - balancedValue) / balancedValue * 100);
|
|
1489
|
+
}
|
|
2654
1490
|
// OVERRIDE
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
throw Error("withdrawOneCoinWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2659
|
-
});
|
|
2660
|
-
});
|
|
2661
|
-
};
|
|
1491
|
+
async withdrawOneCoinWrappedEstimateGas(lpTokenAmount, coin) {
|
|
1492
|
+
throw Error(`withdrawOneCoinWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1493
|
+
}
|
|
2662
1494
|
// OVERRIDE
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
return __generator(this, function (_c) {
|
|
2667
|
-
throw Error("withdrawOneCoinWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
2668
|
-
});
|
|
2669
|
-
});
|
|
2670
|
-
};
|
|
1495
|
+
async withdrawOneCoinWrapped(lpTokenAmount, coin, slippage = 0.5) {
|
|
1496
|
+
throw Error(`withdrawOneCoinWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1497
|
+
}
|
|
2671
1498
|
// ---------------- WALLET BALANCES ----------------
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
addresses[_i] = arguments[_i];
|
|
2676
|
-
}
|
|
2677
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2678
|
-
return __generator(this, function (_c) {
|
|
2679
|
-
switch (_c.label) {
|
|
2680
|
-
case 0:
|
|
2681
|
-
if (!(this.gauge === ethers_1.ethers.constants.AddressZero)) return [3 /*break*/, 2];
|
|
2682
|
-
return [4 /*yield*/, this._balances.apply(this, __spreadArray([__spreadArray(__spreadArray(['lpToken'], this.underlyingCoinAddresses, true), this.wrappedCoinAddresses, true), __spreadArray(__spreadArray([this.lpToken], this.underlyingCoinAddresses, true), this.wrappedCoinAddresses, true)], addresses, false))];
|
|
2683
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2684
|
-
case 2: return [4 /*yield*/, this._balances.apply(this, __spreadArray([__spreadArray(__spreadArray(['lpToken', 'gauge'], this.underlyingCoinAddresses, true), this.wrappedCoinAddresses, true), __spreadArray(__spreadArray([this.lpToken, this.gauge], this.underlyingCoinAddresses, true), this.wrappedCoinAddresses, true)], addresses, false))];
|
|
2685
|
-
case 3: return [2 /*return*/, _c.sent()];
|
|
2686
|
-
}
|
|
2687
|
-
});
|
|
2688
|
-
});
|
|
2689
|
-
};
|
|
2690
|
-
PoolTemplate.prototype.walletLpTokenBalances = function () {
|
|
2691
|
-
var addresses = [];
|
|
2692
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2693
|
-
addresses[_i] = arguments[_i];
|
|
1499
|
+
async walletBalances(...addresses) {
|
|
1500
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1501
|
+
return await this._balances(['lpToken', ...this.underlyingCoinAddresses, ...this.wrappedCoinAddresses], [this.lpToken, ...this.underlyingCoinAddresses, ...this.wrappedCoinAddresses], ...addresses);
|
|
2694
1502
|
}
|
|
2695
|
-
|
|
2696
|
-
return
|
|
2697
|
-
switch (_c.label) {
|
|
2698
|
-
case 0:
|
|
2699
|
-
if (!(this.gauge === ethers_1.ethers.constants.AddressZero)) return [3 /*break*/, 2];
|
|
2700
|
-
return [4 /*yield*/, this._balances.apply(this, __spreadArray([['lpToken'], [this.lpToken]], addresses, false))];
|
|
2701
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2702
|
-
case 2: return [4 /*yield*/, this._balances.apply(this, __spreadArray([['lpToken', 'gauge'], [this.lpToken, this.gauge]], addresses, false))];
|
|
2703
|
-
case 3: return [2 /*return*/, _c.sent()];
|
|
2704
|
-
}
|
|
2705
|
-
});
|
|
2706
|
-
});
|
|
2707
|
-
};
|
|
2708
|
-
PoolTemplate.prototype.walletUnderlyingCoinBalances = function () {
|
|
2709
|
-
var addresses = [];
|
|
2710
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2711
|
-
addresses[_i] = arguments[_i];
|
|
1503
|
+
else {
|
|
1504
|
+
return await this._balances(['lpToken', 'gauge', ...this.underlyingCoinAddresses, ...this.wrappedCoinAddresses], [this.lpToken, this.gauge, ...this.underlyingCoinAddresses, ...this.wrappedCoinAddresses], ...addresses);
|
|
2712
1505
|
}
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2718
|
-
}
|
|
2719
|
-
});
|
|
2720
|
-
});
|
|
2721
|
-
};
|
|
2722
|
-
PoolTemplate.prototype.walletWrappedCoinBalances = function () {
|
|
2723
|
-
var addresses = [];
|
|
2724
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2725
|
-
addresses[_i] = arguments[_i];
|
|
1506
|
+
}
|
|
1507
|
+
async walletLpTokenBalances(...addresses) {
|
|
1508
|
+
if (this.gauge === curve.constants.ZERO_ADDRESS) {
|
|
1509
|
+
return await this._balances(['lpToken'], [this.lpToken], ...addresses);
|
|
2726
1510
|
}
|
|
2727
|
-
|
|
2728
|
-
return
|
|
2729
|
-
switch (_c.label) {
|
|
2730
|
-
case 0: return [4 /*yield*/, this._balances.apply(this, __spreadArray([this.wrappedCoinAddresses, this.wrappedCoinAddresses], addresses, false))];
|
|
2731
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2732
|
-
}
|
|
2733
|
-
});
|
|
2734
|
-
});
|
|
2735
|
-
};
|
|
2736
|
-
PoolTemplate.prototype.walletAllCoinBalances = function () {
|
|
2737
|
-
var addresses = [];
|
|
2738
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2739
|
-
addresses[_i] = arguments[_i];
|
|
1511
|
+
else {
|
|
1512
|
+
return await this._balances(['lpToken', 'gauge'], [this.lpToken, this.gauge], ...addresses);
|
|
2740
1513
|
}
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
1514
|
+
}
|
|
1515
|
+
async walletUnderlyingCoinBalances(...addresses) {
|
|
1516
|
+
return await this._balances(this.underlyingCoinAddresses, this.underlyingCoinAddresses, ...addresses);
|
|
1517
|
+
}
|
|
1518
|
+
async walletWrappedCoinBalances(...addresses) {
|
|
1519
|
+
return await this._balances(this.wrappedCoinAddresses, this.wrappedCoinAddresses, ...addresses);
|
|
1520
|
+
}
|
|
1521
|
+
async walletAllCoinBalances(...addresses) {
|
|
1522
|
+
return await this._balances([...this.underlyingCoinAddresses, ...this.wrappedCoinAddresses], [...this.underlyingCoinAddresses, ...this.wrappedCoinAddresses], ...addresses);
|
|
1523
|
+
}
|
|
2750
1524
|
// ---------------- USER BALANCES, BASE PROFIT AND SHARE ----------------
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
}
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
}
|
|
2825
|
-
}
|
|
2826
|
-
PoolTemplate.prototype.baseProfit = function (address) {
|
|
2827
|
-
if (address === void 0) { address = ""; }
|
|
2828
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2829
|
-
var apyData, apyBN, totalLiquidityBN, _c, annualProfitBN, monthlyProfitBN, weeklyProfitBN, dailyProfitBN;
|
|
2830
|
-
return __generator(this, function (_d) {
|
|
2831
|
-
switch (_d.label) {
|
|
2832
|
-
case 0: return [4 /*yield*/, this.statsBaseApy()];
|
|
2833
|
-
case 1:
|
|
2834
|
-
apyData = _d.sent();
|
|
2835
|
-
if (!('week' in apyData))
|
|
2836
|
-
return [2 /*return*/, { day: "0", week: "0", month: "0", year: "0" }];
|
|
2837
|
-
apyBN = (0, utils_1.BN)(apyData.week).div(100);
|
|
2838
|
-
_c = utils_1.BN;
|
|
2839
|
-
return [4 /*yield*/, this.userLiquidityUSD(address)];
|
|
2840
|
-
case 2:
|
|
2841
|
-
totalLiquidityBN = _c.apply(void 0, [_d.sent()]);
|
|
2842
|
-
annualProfitBN = apyBN.times(totalLiquidityBN);
|
|
2843
|
-
monthlyProfitBN = annualProfitBN.div(12);
|
|
2844
|
-
weeklyProfitBN = annualProfitBN.div(52);
|
|
2845
|
-
dailyProfitBN = annualProfitBN.div(365);
|
|
2846
|
-
return [2 /*return*/, {
|
|
2847
|
-
day: dailyProfitBN.toString(),
|
|
2848
|
-
week: weeklyProfitBN.toString(),
|
|
2849
|
-
month: monthlyProfitBN.toString(),
|
|
2850
|
-
year: annualProfitBN.toString(),
|
|
2851
|
-
}];
|
|
2852
|
-
}
|
|
2853
|
-
});
|
|
2854
|
-
});
|
|
2855
|
-
};
|
|
2856
|
-
PoolTemplate.prototype.userShare = function (address) {
|
|
2857
|
-
if (address === void 0) { address = ""; }
|
|
2858
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2859
|
-
var withGauge, userLpBalance, userLpTotalBalanceBN, totalLp, gaugeLp, _c, _d;
|
|
2860
|
-
var _e;
|
|
2861
|
-
return __generator(this, function (_f) {
|
|
2862
|
-
switch (_f.label) {
|
|
2863
|
-
case 0:
|
|
2864
|
-
withGauge = this.gauge !== ethers_1.ethers.constants.AddressZero;
|
|
2865
|
-
address = address || curve_1.curve.signerAddress;
|
|
2866
|
-
if (!address)
|
|
2867
|
-
throw Error("Need to connect wallet or pass address into args");
|
|
2868
|
-
return [4 /*yield*/, this.walletLpTokenBalances(address)];
|
|
2869
|
-
case 1:
|
|
2870
|
-
userLpBalance = _f.sent();
|
|
2871
|
-
userLpTotalBalanceBN = (0, utils_1.BN)(userLpBalance.lpToken);
|
|
2872
|
-
if (withGauge)
|
|
2873
|
-
userLpTotalBalanceBN = userLpTotalBalanceBN.plus((0, utils_1.BN)(userLpBalance.gauge));
|
|
2874
|
-
if (!withGauge) return [3 /*break*/, 3];
|
|
2875
|
-
return [4 /*yield*/, curve_1.curve.multicallProvider.all([
|
|
2876
|
-
curve_1.curve.contracts[this.lpToken].multicallContract.totalSupply(),
|
|
2877
|
-
curve_1.curve.contracts[this.gauge].multicallContract.totalSupply(),
|
|
2878
|
-
])];
|
|
2879
|
-
case 2:
|
|
2880
|
-
_e = (_f.sent()).map(function (_supply) { return ethers_1.ethers.utils.formatUnits(_supply); }), totalLp = _e[0], gaugeLp = _e[1];
|
|
2881
|
-
return [3 /*break*/, 5];
|
|
2882
|
-
case 3:
|
|
2883
|
-
_d = (_c = ethers_1.ethers.utils).formatUnits;
|
|
2884
|
-
return [4 /*yield*/, curve_1.curve.contracts[this.lpToken].contract.totalSupply(curve_1.curve.constantOptions)];
|
|
2885
|
-
case 4:
|
|
2886
|
-
totalLp = _d.apply(_c, [_f.sent()]);
|
|
2887
|
-
_f.label = 5;
|
|
2888
|
-
case 5: return [2 /*return*/, {
|
|
2889
|
-
lpUser: userLpTotalBalanceBN.toString(),
|
|
2890
|
-
lpTotal: totalLp,
|
|
2891
|
-
lpShare: (0, utils_1.BN)(totalLp).gt(0) ? userLpTotalBalanceBN.div(totalLp).times(100).toString() : '0',
|
|
2892
|
-
gaugeUser: userLpBalance.gauge,
|
|
2893
|
-
gaugeTotal: gaugeLp,
|
|
2894
|
-
gaugeShare: !withGauge ? undefined : (0, utils_1.BN)(gaugeLp).gt(0) ? (0, utils_1.BN)(userLpBalance.gauge).div(gaugeLp).times(100).toString() : '0',
|
|
2895
|
-
}];
|
|
2896
|
-
}
|
|
2897
|
-
});
|
|
2898
|
-
});
|
|
2899
|
-
};
|
|
1525
|
+
async _userLpTotalBalance(address) {
|
|
1526
|
+
const lpBalances = await this.walletLpTokenBalances(address);
|
|
1527
|
+
let lpTotalBalanceBN = BN(lpBalances.lpToken);
|
|
1528
|
+
if ('gauge' in lpBalances)
|
|
1529
|
+
lpTotalBalanceBN = lpTotalBalanceBN.plus(BN(lpBalances.gauge));
|
|
1530
|
+
return lpTotalBalanceBN;
|
|
1531
|
+
}
|
|
1532
|
+
async userBalances(address = "") {
|
|
1533
|
+
address = address || curve.signerAddress;
|
|
1534
|
+
if (!address)
|
|
1535
|
+
throw Error("Need to connect wallet or pass address into args");
|
|
1536
|
+
const lpTotalBalanceBN = await this._userLpTotalBalance(address);
|
|
1537
|
+
if (lpTotalBalanceBN.eq(0))
|
|
1538
|
+
return this.underlyingCoins.map(() => "0");
|
|
1539
|
+
return await this.withdrawExpected(lpTotalBalanceBN.toFixed(18));
|
|
1540
|
+
}
|
|
1541
|
+
async userWrappedBalances(address = "") {
|
|
1542
|
+
address = address || curve.signerAddress;
|
|
1543
|
+
if (!address)
|
|
1544
|
+
throw Error("Need to connect wallet or pass address into args");
|
|
1545
|
+
const lpTotalBalanceBN = await this._userLpTotalBalance(address);
|
|
1546
|
+
if (lpTotalBalanceBN.eq(0))
|
|
1547
|
+
return this.wrappedCoins.map(() => "0");
|
|
1548
|
+
return await this.withdrawWrappedExpected(lpTotalBalanceBN.toFixed(18));
|
|
1549
|
+
}
|
|
1550
|
+
async userLiquidityUSD(address = "") {
|
|
1551
|
+
const lpBalanceBN = await this._userLpTotalBalance(address);
|
|
1552
|
+
const lpPrice = await _getUsdRate(this.lpToken);
|
|
1553
|
+
return lpBalanceBN.times(lpPrice).toFixed(8);
|
|
1554
|
+
}
|
|
1555
|
+
async baseProfit(address = "") {
|
|
1556
|
+
const apyData = await this.statsBaseApy();
|
|
1557
|
+
if (!('week' in apyData))
|
|
1558
|
+
return { day: "0", week: "0", month: "0", year: "0" };
|
|
1559
|
+
const apyBN = BN(apyData.week).div(100);
|
|
1560
|
+
const totalLiquidityBN = BN(await this.userLiquidityUSD(address));
|
|
1561
|
+
const annualProfitBN = apyBN.times(totalLiquidityBN);
|
|
1562
|
+
const monthlyProfitBN = annualProfitBN.div(12);
|
|
1563
|
+
const weeklyProfitBN = annualProfitBN.div(52);
|
|
1564
|
+
const dailyProfitBN = annualProfitBN.div(365);
|
|
1565
|
+
return {
|
|
1566
|
+
day: dailyProfitBN.toString(),
|
|
1567
|
+
week: weeklyProfitBN.toString(),
|
|
1568
|
+
month: monthlyProfitBN.toString(),
|
|
1569
|
+
year: annualProfitBN.toString(),
|
|
1570
|
+
};
|
|
1571
|
+
}
|
|
1572
|
+
async userShare(address = "") {
|
|
1573
|
+
const withGauge = this.gauge !== curve.constants.ZERO_ADDRESS;
|
|
1574
|
+
address = address || curve.signerAddress;
|
|
1575
|
+
if (!address)
|
|
1576
|
+
throw Error("Need to connect wallet or pass address into args");
|
|
1577
|
+
const userLpBalance = await this.walletLpTokenBalances(address);
|
|
1578
|
+
let userLpTotalBalanceBN = BN(userLpBalance.lpToken);
|
|
1579
|
+
if (withGauge)
|
|
1580
|
+
userLpTotalBalanceBN = userLpTotalBalanceBN.plus(BN(userLpBalance.gauge));
|
|
1581
|
+
let totalLp, gaugeLp;
|
|
1582
|
+
if (withGauge) {
|
|
1583
|
+
[totalLp, gaugeLp] = (await curve.multicallProvider.all([
|
|
1584
|
+
curve.contracts[this.lpToken].multicallContract.totalSupply(),
|
|
1585
|
+
curve.contracts[this.gauge].multicallContract.totalSupply(),
|
|
1586
|
+
])).map((_supply) => curve.formatUnits(_supply));
|
|
1587
|
+
}
|
|
1588
|
+
else {
|
|
1589
|
+
totalLp = curve.formatUnits(await curve.contracts[this.lpToken].contract.totalSupply(curve.constantOptions));
|
|
1590
|
+
}
|
|
1591
|
+
return {
|
|
1592
|
+
lpUser: userLpTotalBalanceBN.toString(),
|
|
1593
|
+
lpTotal: totalLp,
|
|
1594
|
+
lpShare: BN(totalLp).gt(0) ? userLpTotalBalanceBN.div(totalLp).times(100).toString() : '0',
|
|
1595
|
+
gaugeUser: userLpBalance.gauge,
|
|
1596
|
+
gaugeTotal: gaugeLp,
|
|
1597
|
+
gaugeShare: !withGauge ? undefined : BN(gaugeLp).gt(0) ? BN(userLpBalance.gauge).div(gaugeLp).times(100).toString() : '0',
|
|
1598
|
+
};
|
|
1599
|
+
}
|
|
2900
1600
|
// ---------------- SWAP ----------------
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
});
|
|
2938
|
-
});
|
|
2939
|
-
};
|
|
2940
|
-
PoolTemplate.prototype.swapPriceImpact = function (inputCoin, outputCoin, amount) {
|
|
2941
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2942
|
-
var i, j, _c, inputCoinDecimals, outputCoinDecimals, _amount, _output, smallAmountIntBN, amountIntBN, _smallAmount, _smallOutput, priceImpactBN;
|
|
2943
|
-
return __generator(this, function (_d) {
|
|
2944
|
-
switch (_d.label) {
|
|
2945
|
-
case 0:
|
|
2946
|
-
i = this._getCoinIdx(inputCoin);
|
|
2947
|
-
j = this._getCoinIdx(outputCoin);
|
|
2948
|
-
_c = [this.underlyingDecimals[i], this.underlyingDecimals[j]], inputCoinDecimals = _c[0], outputCoinDecimals = _c[1];
|
|
2949
|
-
_amount = (0, utils_1.parseUnits)(amount, inputCoinDecimals);
|
|
2950
|
-
return [4 /*yield*/, this._swapExpected(i, j, _amount)];
|
|
2951
|
-
case 1:
|
|
2952
|
-
_output = _d.sent();
|
|
2953
|
-
smallAmountIntBN = (0, utils_1._get_small_x)(_amount, _output, inputCoinDecimals, outputCoinDecimals);
|
|
2954
|
-
amountIntBN = (0, utils_1.toBN)(_amount, 0);
|
|
2955
|
-
if (smallAmountIntBN.gte(amountIntBN))
|
|
2956
|
-
return [2 /*return*/, 0];
|
|
2957
|
-
_smallAmount = (0, utils_1.fromBN)(smallAmountIntBN.div(Math.pow(10, inputCoinDecimals)), inputCoinDecimals);
|
|
2958
|
-
return [4 /*yield*/, this._swapExpected(i, j, _smallAmount)];
|
|
2959
|
-
case 2:
|
|
2960
|
-
_smallOutput = _d.sent();
|
|
2961
|
-
priceImpactBN = (0, utils_1._get_price_impact)(_amount, _output, _smallAmount, _smallOutput, inputCoinDecimals, outputCoinDecimals);
|
|
2962
|
-
return [2 /*return*/, Number((0, utils_1._cutZeros)(priceImpactBN.toFixed(4)))];
|
|
2963
|
-
}
|
|
2964
|
-
});
|
|
2965
|
-
});
|
|
2966
|
-
};
|
|
2967
|
-
PoolTemplate.prototype._swapContractAddress = function () {
|
|
1601
|
+
async _swapExpected(i, j, _amount) {
|
|
1602
|
+
const contractAddress = this.isCrypto && this.isMeta ? this.zap : this.address;
|
|
1603
|
+
const contract = curve.contracts[contractAddress].contract;
|
|
1604
|
+
if (Object.prototype.hasOwnProperty.call(contract, 'get_dy_underlying')) {
|
|
1605
|
+
return await contract.get_dy_underlying(i, j, _amount, curve.constantOptions);
|
|
1606
|
+
}
|
|
1607
|
+
else {
|
|
1608
|
+
if ('get_dy(address,uint256,uint256,uint256)' in contract) { // atricrypto3 based metapools
|
|
1609
|
+
return await contract.get_dy(this.address, i, j, _amount, curve.constantOptions);
|
|
1610
|
+
}
|
|
1611
|
+
return await contract.get_dy(i, j, _amount, curve.constantOptions);
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
async swapExpected(inputCoin, outputCoin, amount) {
|
|
1615
|
+
const i = this._getCoinIdx(inputCoin);
|
|
1616
|
+
const j = this._getCoinIdx(outputCoin);
|
|
1617
|
+
const _amount = parseUnits(amount, this.underlyingDecimals[i]);
|
|
1618
|
+
const _expected = await this._swapExpected(i, j, _amount);
|
|
1619
|
+
return curve.formatUnits(_expected, this.underlyingDecimals[j]);
|
|
1620
|
+
}
|
|
1621
|
+
async swapPriceImpact(inputCoin, outputCoin, amount) {
|
|
1622
|
+
const i = this._getCoinIdx(inputCoin);
|
|
1623
|
+
const j = this._getCoinIdx(outputCoin);
|
|
1624
|
+
const [inputCoinDecimals, outputCoinDecimals] = [this.underlyingDecimals[i], this.underlyingDecimals[j]];
|
|
1625
|
+
const _amount = parseUnits(amount, inputCoinDecimals);
|
|
1626
|
+
const _output = await this._swapExpected(i, j, _amount);
|
|
1627
|
+
const smallAmountIntBN = _get_small_x(_amount, _output, inputCoinDecimals, outputCoinDecimals);
|
|
1628
|
+
const amountIntBN = toBN(_amount, 0);
|
|
1629
|
+
if (smallAmountIntBN.gte(amountIntBN))
|
|
1630
|
+
return 0;
|
|
1631
|
+
const _smallAmount = fromBN(smallAmountIntBN.div(10 ** inputCoinDecimals), inputCoinDecimals);
|
|
1632
|
+
const _smallOutput = await this._swapExpected(i, j, _smallAmount);
|
|
1633
|
+
const priceImpactBN = _get_price_impact(_amount, _output, _smallAmount, _smallOutput, inputCoinDecimals, outputCoinDecimals);
|
|
1634
|
+
return Number(_cutZeros(priceImpactBN.toFixed(4)));
|
|
1635
|
+
}
|
|
1636
|
+
_swapContractAddress() {
|
|
2968
1637
|
return (this.isCrypto && this.isMeta) || (this.isMetaFactory && (new PoolTemplate(this.basePool).isLending)) ? this.zap : this.address;
|
|
2969
|
-
}
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2986
|
-
var contractAddress, i;
|
|
2987
|
-
return __generator(this, function (_c) {
|
|
2988
|
-
switch (_c.label) {
|
|
2989
|
-
case 0:
|
|
2990
|
-
contractAddress = this._swapContractAddress();
|
|
2991
|
-
i = this._getCoinIdx(inputCoin);
|
|
2992
|
-
return [4 /*yield*/, (0, utils_1.ensureAllowanceEstimateGas)([this.underlyingCoinAddresses[i]], [amount], contractAddress)];
|
|
2993
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
2994
|
-
}
|
|
2995
|
-
});
|
|
2996
|
-
});
|
|
2997
|
-
};
|
|
2998
|
-
PoolTemplate.prototype.swapApprove = function (inputCoin, amount) {
|
|
2999
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
3000
|
-
var contractAddress, i;
|
|
3001
|
-
return __generator(this, function (_c) {
|
|
3002
|
-
switch (_c.label) {
|
|
3003
|
-
case 0:
|
|
3004
|
-
contractAddress = this._swapContractAddress();
|
|
3005
|
-
i = this._getCoinIdx(inputCoin);
|
|
3006
|
-
return [4 /*yield*/, (0, utils_1.ensureAllowance)([this.underlyingCoinAddresses[i]], [amount], contractAddress)];
|
|
3007
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
3008
|
-
}
|
|
3009
|
-
});
|
|
3010
|
-
});
|
|
3011
|
-
};
|
|
1638
|
+
}
|
|
1639
|
+
async swapIsApproved(inputCoin, amount) {
|
|
1640
|
+
const contractAddress = this._swapContractAddress();
|
|
1641
|
+
const i = this._getCoinIdx(inputCoin);
|
|
1642
|
+
return await hasAllowance([this.underlyingCoinAddresses[i]], [amount], curve.signerAddress, contractAddress);
|
|
1643
|
+
}
|
|
1644
|
+
async swapApproveEstimateGas(inputCoin, amount) {
|
|
1645
|
+
const contractAddress = this._swapContractAddress();
|
|
1646
|
+
const i = this._getCoinIdx(inputCoin);
|
|
1647
|
+
return await ensureAllowanceEstimateGas([this.underlyingCoinAddresses[i]], [amount], contractAddress);
|
|
1648
|
+
}
|
|
1649
|
+
async swapApprove(inputCoin, amount) {
|
|
1650
|
+
const contractAddress = this._swapContractAddress();
|
|
1651
|
+
const i = this._getCoinIdx(inputCoin);
|
|
1652
|
+
return await ensureAllowance([this.underlyingCoinAddresses[i]], [amount], contractAddress);
|
|
1653
|
+
}
|
|
3012
1654
|
// OVERRIDE
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
throw Error("swap method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
3017
|
-
});
|
|
3018
|
-
});
|
|
3019
|
-
};
|
|
1655
|
+
async swapEstimateGas(inputCoin, outputCoin, amount) {
|
|
1656
|
+
throw Error(`swap method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1657
|
+
}
|
|
3020
1658
|
// OVERRIDE
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
return __generator(this, function (_c) {
|
|
3025
|
-
throw Error("swap method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
3026
|
-
});
|
|
3027
|
-
});
|
|
3028
|
-
};
|
|
1659
|
+
async swap(inputCoin, outputCoin, amount, slippage = 0.5) {
|
|
1660
|
+
throw Error(`swap method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1661
|
+
}
|
|
3029
1662
|
// ---------------- SWAP WRAPPED ----------------
|
|
3030
|
-
|
|
3031
|
-
return
|
|
3032
|
-
|
|
3033
|
-
switch (_c.label) {
|
|
3034
|
-
case 0: return [4 /*yield*/, curve_1.curve.contracts[this.address].contract.get_dy(i, j, _amount, curve_1.curve.constantOptions)];
|
|
3035
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
3036
|
-
}
|
|
3037
|
-
});
|
|
3038
|
-
});
|
|
3039
|
-
};
|
|
1663
|
+
async _swapWrappedExpected(i, j, _amount) {
|
|
1664
|
+
return await curve.contracts[this.address].contract.get_dy(i, j, _amount, curve.constantOptions);
|
|
1665
|
+
}
|
|
3040
1666
|
// OVERRIDE
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
case 1:
|
|
3063
|
-
_output = _d.sent();
|
|
3064
|
-
smallAmountIntBN = (0, utils_1._get_small_x)(_amount, _output, inputCoinDecimals, outputCoinDecimals);
|
|
3065
|
-
amountIntBN = (0, utils_1.toBN)(_amount, 0);
|
|
3066
|
-
if (smallAmountIntBN.gte(amountIntBN))
|
|
3067
|
-
return [2 /*return*/, 0];
|
|
3068
|
-
_smallAmount = (0, utils_1.fromBN)(smallAmountIntBN.div(Math.pow(10, inputCoinDecimals)), inputCoinDecimals);
|
|
3069
|
-
return [4 /*yield*/, this._swapWrappedExpected(i, j, _smallAmount)];
|
|
3070
|
-
case 2:
|
|
3071
|
-
_smallOutput = _d.sent();
|
|
3072
|
-
priceImpactBN = (0, utils_1._get_price_impact)(_amount, _output, _smallAmount, _smallOutput, inputCoinDecimals, outputCoinDecimals);
|
|
3073
|
-
return [2 /*return*/, Number((0, utils_1._cutZeros)(priceImpactBN.toFixed(4)))];
|
|
3074
|
-
}
|
|
3075
|
-
});
|
|
3076
|
-
});
|
|
3077
|
-
};
|
|
1667
|
+
async swapWrappedExpected(inputCoin, outputCoin, amount) {
|
|
1668
|
+
throw Error(`swapWrappedExpected method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1669
|
+
}
|
|
1670
|
+
async swapWrappedPriceImpact(inputCoin, outputCoin, amount) {
|
|
1671
|
+
if (this.isPlain || this.isFake) {
|
|
1672
|
+
throw Error(`swapWrappedPriceImpact method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1673
|
+
}
|
|
1674
|
+
const i = this._getCoinIdx(inputCoin, false);
|
|
1675
|
+
const j = this._getCoinIdx(outputCoin, false);
|
|
1676
|
+
const [inputCoinDecimals, outputCoinDecimals] = [this.wrappedDecimals[i], this.wrappedDecimals[j]];
|
|
1677
|
+
const _amount = parseUnits(amount, inputCoinDecimals);
|
|
1678
|
+
const _output = await this._swapWrappedExpected(i, j, _amount);
|
|
1679
|
+
const smallAmountIntBN = _get_small_x(_amount, _output, inputCoinDecimals, outputCoinDecimals);
|
|
1680
|
+
const amountIntBN = toBN(_amount, 0);
|
|
1681
|
+
if (smallAmountIntBN.gte(amountIntBN))
|
|
1682
|
+
return 0;
|
|
1683
|
+
const _smallAmount = fromBN(smallAmountIntBN.div(10 ** inputCoinDecimals), inputCoinDecimals);
|
|
1684
|
+
const _smallOutput = await this._swapWrappedExpected(i, j, _smallAmount);
|
|
1685
|
+
const priceImpactBN = _get_price_impact(_amount, _output, _smallAmount, _smallOutput, inputCoinDecimals, outputCoinDecimals);
|
|
1686
|
+
return Number(_cutZeros(priceImpactBN.toFixed(4)));
|
|
1687
|
+
}
|
|
3078
1688
|
// OVERRIDE
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
throw Error("swapWrappedIsApproved method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
3083
|
-
});
|
|
3084
|
-
});
|
|
3085
|
-
};
|
|
1689
|
+
async swapWrappedIsApproved(inputCoin, amount) {
|
|
1690
|
+
throw Error(`swapWrappedIsApproved method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1691
|
+
}
|
|
3086
1692
|
// OVERRIDE
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
throw Error("swapWrappedApprove method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
3091
|
-
});
|
|
3092
|
-
});
|
|
3093
|
-
};
|
|
1693
|
+
async swapWrappedApproveEstimateGas(inputCoin, amount) {
|
|
1694
|
+
throw Error(`swapWrappedApprove method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1695
|
+
}
|
|
3094
1696
|
// OVERRIDE
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
throw Error("swapWrappedApprove method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
3099
|
-
});
|
|
3100
|
-
});
|
|
3101
|
-
};
|
|
1697
|
+
async swapWrappedApprove(inputCoin, amount) {
|
|
1698
|
+
throw Error(`swapWrappedApprove method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1699
|
+
}
|
|
3102
1700
|
// OVERRIDE
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
throw Error("swapWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
3107
|
-
});
|
|
3108
|
-
});
|
|
3109
|
-
};
|
|
1701
|
+
async swapWrappedEstimateGas(inputCoin, outputCoin, amount) {
|
|
1702
|
+
throw Error(`swapWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1703
|
+
}
|
|
3110
1704
|
// OVERRIDE
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
throw Error("swapWrapped method doesn't exist for pool ".concat(this.name, " (id: ").concat(this.name, ")"));
|
|
3116
|
-
});
|
|
3117
|
-
});
|
|
3118
|
-
};
|
|
3119
|
-
return PoolTemplate;
|
|
3120
|
-
}());
|
|
3121
|
-
exports.PoolTemplate = PoolTemplate;
|
|
1705
|
+
async swapWrapped(inputCoin, outputCoin, amount, slippage = 0.5) {
|
|
1706
|
+
throw Error(`swapWrapped method doesn't exist for pool ${this.name} (id: ${this.name})`);
|
|
1707
|
+
}
|
|
1708
|
+
}
|