@curvefi/api 1.20.2 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/pools.js CHANGED
@@ -59,13 +59,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
59
59
  return (mod && mod.__esModule) ? mod : { "default": mod };
60
60
  };
61
61
  Object.defineProperty(exports, "__esModule", { value: true });
62
- exports.getUserPoolList = exports.crossAssetExchange = exports.crossAssetExchangeEstimateGas = exports.crossAssetExchangeApprove = exports.crossAssetExchangeApproveEstimateGas = exports.crossAssetExchangeIsApproved = exports.crossAssetExchangeExpected = exports.crossAssetExchangeOutputAndSlippage = exports._crossAssetExchangeInfo = exports._getSmallAmountForCoin = exports.crossAssetExchangeAvailable = exports.exchange = exports.exchangeEstimateGas = exports.exchangeApprove = exports.exchangeApproveEstimateGas = exports.exchangeIsApproved = exports.exchangeExpected = exports.getBestPoolAndOutput = exports.Pool = void 0;
62
+ exports.routerExchange = exports.routerExchangeEstimateGas = exports.routerExchangeApprove = exports.routerExchangeApproveEstimateGas = exports.routerExchangeIsApproved = exports.routerExchangeExpected = exports.getBestRouteAndOutput = exports._findAllRoutes = exports.getUserPoolList = exports.crossAssetExchange = exports.crossAssetExchangeEstimateGas = exports.crossAssetExchangeApprove = exports.crossAssetExchangeApproveEstimateGas = exports.crossAssetExchangeIsApproved = exports.crossAssetExchangeExpected = exports.crossAssetExchangeOutputAndSlippage = exports._crossAssetExchangeInfo = exports._getSmallAmountForCoin = exports.crossAssetExchangeAvailable = exports.exchange = exports.exchangeEstimateGas = exports.exchangeApprove = exports.exchangeApproveEstimateGas = exports.exchangeIsApproved = exports.exchangeExpected = exports.getBestPoolAndOutput = exports.Pool = void 0;
63
+ var axios_1 = __importDefault(require("axios"));
63
64
  var ethers_1 = require("ethers");
65
+ var memoizee_1 = __importDefault(require("memoizee"));
66
+ var external_api_1 = require("./external-api");
64
67
  var utils_1 = require("./utils");
65
68
  var curve_1 = require("./curve");
66
- var axios_1 = __importDefault(require("axios"));
67
69
  var Pool = /** @class */ (function () {
68
- function Pool(name) {
70
+ function Pool(id) {
69
71
  var _this = this;
70
72
  this.calcLpTokenAmount = function (amounts, isDeposit) {
71
73
  if (isDeposit === void 0) { isDeposit = true; }
@@ -81,9 +83,9 @@ var Pool = /** @class */ (function () {
81
83
  _amounts = amounts.map(function (amount, i) {
82
84
  return ethers_1.ethers.utils.parseUnits(amount, _this.underlyingDecimals[i]);
83
85
  });
84
- if (!(['compound', 'usdt', 'y', 'busd', 'pax', 'aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
86
+ if (!(['compound', 'usdt', 'y', 'busd', 'pax', 'aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
85
87
  this.isCryptoFactory ||
86
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 2];
88
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 2];
87
89
  return [4 /*yield*/, this._calcLpTokenAmountWithUnderlying(_amounts, isDeposit)];
88
90
  case 1:
89
91
  _expected = _a.sent(); // Lending pools
@@ -156,7 +158,7 @@ var Pool = /** @class */ (function () {
156
158
  ethers_1.ethers.utils.formatUnits(_A, 0),
157
159
  _gamma ? ethers_1.ethers.utils.formatUnits(_gamma) : _gamma,
158
160
  ], virtualPrice = _c[0], fee = _c[1], adminFee = _c[2], A = _c[3], gamma = _c[4];
159
- A_PRECISION = curve_1.curve.chainId === 1 && ['compound', 'usdt', 'y', 'busd', 'susd', 'pax', 'ren', 'sbtc', 'hbtc', '3pool'].includes(this.name) ? 1 : 100;
161
+ A_PRECISION = curve_1.curve.chainId === 1 && ['compound', 'usdt', 'y', 'busd', 'susd', 'pax', 'ren', 'sbtc', 'hbtc', '3pool'].includes(this.id) ? 1 : 100;
160
162
  return [4 /*yield*/, curve_1.curve.multicallProvider.all(additionalCalls)];
161
163
  case 2:
162
164
  _d = _f.sent(), _future_A = _d[0], _initial_A = _d[1], _future_A_time = _d[2], _initial_A_time = _d[3];
@@ -183,7 +185,7 @@ var Pool = /** @class */ (function () {
183
185
  _poolWrappedBalances = _a.sent();
184
186
  _poolUnderlyingBalances = [];
185
187
  if (!this.isMeta) return [3 /*break*/, 3];
186
- if (this.name !== 'atricrypto3') {
188
+ if (this.id !== 'atricrypto3') {
187
189
  _poolWrappedBalances.unshift(_poolWrappedBalances.pop());
188
190
  }
189
191
  _poolMetaCoinBalance = _poolWrappedBalances[0], _poolUnderlyingBalance = _poolWrappedBalances.slice(1);
@@ -191,12 +193,12 @@ var Pool = /** @class */ (function () {
191
193
  return [4 /*yield*/, basePool._calcExpectedAmounts(_poolMetaCoinBalance)];
192
194
  case 2:
193
195
  _basePoolExpectedAmounts = _a.sent();
194
- _poolUnderlyingBalances = this.name !== 'atricrypto3' ? __spreadArray(__spreadArray([], _poolUnderlyingBalance, true), _basePoolExpectedAmounts, true) : __spreadArray(__spreadArray([], _basePoolExpectedAmounts, true), _poolUnderlyingBalance, true);
196
+ _poolUnderlyingBalances = this.id !== 'atricrypto3' ? __spreadArray(__spreadArray([], _poolUnderlyingBalance, true), _basePoolExpectedAmounts, true) : __spreadArray(__spreadArray([], _basePoolExpectedAmounts, true), _poolUnderlyingBalance, true);
195
197
  return [3 /*break*/, 6];
196
198
  case 3:
197
- if (!(['compound', 'usdt', 'y', 'busd', 'pax', 'aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
199
+ if (!(['compound', 'usdt', 'y', 'busd', 'pax', 'aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
198
200
  this.isCryptoFactory ||
199
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 5];
201
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 5];
200
202
  return [4 /*yield*/, this._getRates()];
201
203
  case 4:
202
204
  _rates_1 = _a.sent();
@@ -224,33 +226,55 @@ var Pool = /** @class */ (function () {
224
226
  }
225
227
  });
226
228
  }); };
227
- this.getTotalLiquidity = function () { return __awaiter(_this, void 0, void 0, function () {
228
- var balances, promises, _i, _a, addr, prices, totalLiquidity;
229
- return __generator(this, function (_c) {
230
- switch (_c.label) {
231
- case 0: return [4 /*yield*/, this.getPoolBalances()];
232
- case 1:
233
- balances = _c.sent();
234
- promises = [];
235
- for (_i = 0, _a = this.underlyingCoinAddresses; _i < _a.length; _i++) {
236
- addr = _a[_i];
237
- promises.push((0, utils_1._getUsdRate)(addr));
238
- }
239
- return [4 /*yield*/, Promise.all(promises)];
240
- case 2:
241
- prices = _c.sent();
242
- totalLiquidity = balances.reduce(function (liquidity, b, i) { return liquidity + (Number(b) * prices[i]); }, 0);
243
- return [2 /*return*/, totalLiquidity.toFixed(8)];
244
- }
229
+ this.getTotalLiquidity = function (useApi) {
230
+ if (useApi === void 0) { useApi = true; }
231
+ return __awaiter(_this, void 0, void 0, function () {
232
+ var network, poolType, poolsData, totalLiquidity_1, balances, promises, _i, _a, addr, prices, totalLiquidity;
233
+ var _this = this;
234
+ return __generator(this, function (_c) {
235
+ switch (_c.label) {
236
+ case 0:
237
+ if (!useApi) return [3 /*break*/, 2];
238
+ network = curve_1.curve.chainId === 137 ? "polygon" : "ethereum";
239
+ poolType = !this.isFactory && !this.isCrypto ? "main" :
240
+ !this.isFactory ? "crypto" :
241
+ !this.isCryptoFactory ? "factory" :
242
+ "factory-crypto";
243
+ return [4 /*yield*/, (0, external_api_1._getPoolsFromApi)(network, poolType)];
244
+ case 1:
245
+ poolsData = (_c.sent()).poolData;
246
+ try {
247
+ totalLiquidity_1 = poolsData.filter(function (data) { return data.address.toLowerCase() === _this.swap.toLowerCase(); })[0].usdTotal;
248
+ return [2 /*return*/, String(totalLiquidity_1)];
249
+ }
250
+ catch (err) {
251
+ console.log(err.message);
252
+ }
253
+ _c.label = 2;
254
+ case 2: return [4 /*yield*/, this.getPoolBalances()];
255
+ case 3:
256
+ balances = _c.sent();
257
+ promises = [];
258
+ for (_i = 0, _a = this.underlyingCoinAddresses; _i < _a.length; _i++) {
259
+ addr = _a[_i];
260
+ promises.push((0, utils_1._getUsdRate)(addr));
261
+ }
262
+ return [4 /*yield*/, Promise.all(promises)];
263
+ case 4:
264
+ prices = _c.sent();
265
+ totalLiquidity = balances.reduce(function (liquidity, b, i) { return liquidity + (Number(b) * prices[i]); }, 0);
266
+ return [2 /*return*/, totalLiquidity.toFixed(8)];
267
+ }
268
+ });
245
269
  });
246
- }); };
270
+ };
247
271
  this._getPoolStats = function () { return __awaiter(_this, void 0, void 0, function () {
248
272
  var statsUrl, name, key;
249
273
  return __generator(this, function (_a) {
250
274
  switch (_a.label) {
251
275
  case 0:
252
276
  statsUrl = this.isFactory ? (0, utils_1._getFactoryStatsUrl)() : (0, utils_1._getStatsUrl)(this.isCrypto);
253
- name = (this.name === 'ren' && curve_1.curve.chainId === 1) ? 'ren2' : this.name === 'sbtc' ? 'rens' : this.name;
277
+ name = (this.id === 'ren' && curve_1.curve.chainId === 1) ? 'ren2' : this.id === 'sbtc' ? 'rens' : this.id;
254
278
  key = this.isFactory ? this.swap.toLowerCase() : name;
255
279
  if (!this.isFactory) return [3 /*break*/, 4];
256
280
  if (!(curve_1.curve.chainId === 137)) return [3 /*break*/, 2];
@@ -273,7 +297,7 @@ var Pool = /** @class */ (function () {
273
297
  if (!(this.isCrypto || (curve_1.curve.chainId === 1 && this.isFactory))) return [3 /*break*/, 2];
274
298
  _a = 1;
275
299
  return [3 /*break*/, 4];
276
- case 2: return [4 /*yield*/, (0, utils_1._getUsdRate)(this.referenceAsset)];
300
+ case 2: return [4 /*yield*/, (0, utils_1._getUsdRate)(this.coinAddresses[0])];
277
301
  case 3:
278
302
  _a = _c.sent();
279
303
  _c.label = 4;
@@ -482,13 +506,13 @@ var Pool = /** @class */ (function () {
482
506
  _amounts = amounts.map(function (amount, i) {
483
507
  return ethers_1.ethers.utils.parseUnits(amount, _this.underlyingDecimals[i]);
484
508
  });
485
- if (!['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.name)) return [3 /*break*/, 4];
509
+ if (!['compound', 'usdt', 'y', 'busd', 'pax', 'tricrypto2'].includes(this.id)) return [3 /*break*/, 4];
486
510
  return [4 /*yield*/, this._addLiquidityZap(_amounts, true)];
487
511
  case 3: return [2 /*return*/, _d.sent()];
488
512
  case 4:
489
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
513
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
490
514
  this.isCryptoFactory ||
491
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 6];
515
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 6];
492
516
  return [4 /*yield*/, this._addLiquidity(_amounts, true, true)];
493
517
  case 5: return [2 /*return*/, _d.sent()];
494
518
  case 6:
@@ -540,13 +564,13 @@ var Pool = /** @class */ (function () {
540
564
  return [4 /*yield*/, curve_1.curve.updateFeeData()];
541
565
  case 1:
542
566
  _a.sent();
543
- if (!['compound', 'usdt', 'y', 'busd', 'pax', 'tricrypto2'].includes(this.name)) return [3 /*break*/, 3];
567
+ if (!['compound', 'usdt', 'y', 'busd', 'pax', 'tricrypto2'].includes(this.id)) return [3 /*break*/, 3];
544
568
  return [4 /*yield*/, this._addLiquidityZap(_amounts)];
545
569
  case 2: return [2 /*return*/, _a.sent()];
546
570
  case 3:
547
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
571
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
548
572
  this.isCryptoFactory ||
549
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 5];
573
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 5];
550
574
  return [4 /*yield*/, this._addLiquidity(_amounts, true)];
551
575
  case 4: return [2 /*return*/, _a.sent()];
552
576
  case 5:
@@ -725,9 +749,9 @@ var Pool = /** @class */ (function () {
725
749
  return ethers_1.ethers.utils.parseUnits(amount, decimals[i]);
726
750
  });
727
751
  contract = curve_1.curve.contracts[curve_1.ALIASES.deposit_and_stake].contract;
728
- useUnderlying = isUnderlying && (['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
752
+ useUnderlying = isUnderlying && (['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
729
753
  this.isCryptoFactory ||
730
- (curve_1.curve.chainId === 137 && this.name === 'ren'));
754
+ (curve_1.curve.chainId === 137 && this.id === 'ren'));
731
755
  if (!isUnderlying) return [3 /*break*/, 14];
732
756
  _l = (_k = ethers_1.ethers.utils).parseUnits;
733
757
  return [4 /*yield*/, this.depositAndStakeExpected(amounts)];
@@ -898,9 +922,9 @@ var Pool = /** @class */ (function () {
898
922
  _amounts = amounts.map(function (amount, i) {
899
923
  return ethers_1.ethers.utils.parseUnits(amount, _this.decimals[i]);
900
924
  });
901
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
925
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
902
926
  this.isCryptoFactory ||
903
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 4];
927
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 4];
904
928
  return [4 /*yield*/, this._addLiquidity(_amounts, false, true)];
905
929
  case 3: return [2 /*return*/, _d.sent()];
906
930
  case 4: return [4 /*yield*/, this._addLiquiditySwap(_amounts, true)];
@@ -928,9 +952,9 @@ var Pool = /** @class */ (function () {
928
952
  return [4 /*yield*/, curve_1.curve.updateFeeData()];
929
953
  case 1:
930
954
  _a.sent();
931
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
955
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
932
956
  this.isCryptoFactory ||
933
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 3];
957
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 3];
934
958
  return [4 /*yield*/, this._addLiquidity(_amounts, false)];
935
959
  case 2: return [2 /*return*/, _a.sent()];
936
960
  case 3: return [4 /*yield*/, this._addLiquiditySwap(_amounts)];
@@ -1072,9 +1096,9 @@ var Pool = /** @class */ (function () {
1072
1096
  switch (_a.label) {
1073
1097
  case 0:
1074
1098
  _lpTokenAmount = ethers_1.ethers.utils.parseUnits(lpTokenAmount);
1075
- if (!(['compound', 'usdt', 'y', 'busd', 'pax', 'aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
1099
+ if (!(['compound', 'usdt', 'y', 'busd', 'pax', 'aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
1076
1100
  this.isCryptoFactory ||
1077
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 2];
1101
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 2];
1078
1102
  return [4 /*yield*/, this._calcExpectedUnderlyingAmounts(_lpTokenAmount)];
1079
1103
  case 1:
1080
1104
  _expected = _a.sent(); // Lending pools
@@ -1147,13 +1171,13 @@ var Pool = /** @class */ (function () {
1147
1171
  throw Error("Token allowance is needed to estimate gas");
1148
1172
  }
1149
1173
  _lpTokenAmount = ethers_1.ethers.utils.parseUnits(lpTokenAmount);
1150
- if (!['compound', 'usdt', 'y', 'busd', 'pax', 'tricrypto2'].includes(this.name)) return [3 /*break*/, 5];
1174
+ if (!['compound', 'usdt', 'y', 'busd', 'pax', 'tricrypto2'].includes(this.id)) return [3 /*break*/, 5];
1151
1175
  return [4 /*yield*/, this._removeLiquidityZap(_lpTokenAmount, true)];
1152
1176
  case 4: return [2 /*return*/, _c.sent()];
1153
1177
  case 5:
1154
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
1178
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
1155
1179
  this.isCryptoFactory ||
1156
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 7];
1180
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 7];
1157
1181
  return [4 /*yield*/, this._removeLiquidity(_lpTokenAmount, true, true)];
1158
1182
  case 6: return [2 /*return*/, _c.sent()];
1159
1183
  case 7:
@@ -1174,13 +1198,13 @@ var Pool = /** @class */ (function () {
1174
1198
  return [4 /*yield*/, curve_1.curve.updateFeeData()];
1175
1199
  case 1:
1176
1200
  _a.sent();
1177
- if (!['compound', 'usdt', 'y', 'busd', 'pax', 'tricrypto2'].includes(this.name)) return [3 /*break*/, 3];
1201
+ if (!['compound', 'usdt', 'y', 'busd', 'pax', 'tricrypto2'].includes(this.id)) return [3 /*break*/, 3];
1178
1202
  return [4 /*yield*/, this._removeLiquidityZap(_lpTokenAmount)];
1179
1203
  case 2: return [2 /*return*/, _a.sent()];
1180
1204
  case 3:
1181
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
1205
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
1182
1206
  this.isCryptoFactory ||
1183
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 5];
1207
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 5];
1184
1208
  return [4 /*yield*/, this._removeLiquidity(_lpTokenAmount, true)];
1185
1209
  case 4: return [2 /*return*/, _a.sent()];
1186
1210
  case 5:
@@ -1224,9 +1248,9 @@ var Pool = /** @class */ (function () {
1224
1248
  if (Number(lpTokenBalance) < Number(lpTokenAmount)) {
1225
1249
  throw Error("Not enough LP tokens. Actual: ".concat(lpTokenBalance, ", required: ").concat(lpTokenAmount));
1226
1250
  }
1227
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
1251
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
1228
1252
  this.isCryptoFactory ||
1229
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 3];
1253
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 3];
1230
1254
  return [4 /*yield*/, this._removeLiquidity(_lpTokenAmount, false, true)];
1231
1255
  case 2: return [2 /*return*/, _a.sent()];
1232
1256
  case 3: return [4 /*yield*/, this._removeLiquiditySwap(_lpTokenAmount, true)];
@@ -1246,9 +1270,9 @@ var Pool = /** @class */ (function () {
1246
1270
  return [4 /*yield*/, curve_1.curve.updateFeeData()];
1247
1271
  case 1:
1248
1272
  _a.sent();
1249
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
1273
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
1250
1274
  this.isCryptoFactory ||
1251
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 3];
1275
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 3];
1252
1276
  return [4 /*yield*/, this._removeLiquidity(_lpTokenAmount, false)];
1253
1277
  case 2: return [2 /*return*/, _a.sent()];
1254
1278
  case 3: return [4 /*yield*/, this._removeLiquiditySwap(_lpTokenAmount)];
@@ -1298,7 +1322,7 @@ var Pool = /** @class */ (function () {
1298
1322
  throw Error("".concat(this.name, " pool doesn't have remove_liquidity_imbalance method"));
1299
1323
  }
1300
1324
  _amounts = amounts.map(function (amount, i) { return ethers_1.ethers.utils.parseUnits(amount, _this.underlyingDecimals[i]); });
1301
- if (!['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.name)) return [3 /*break*/, 3];
1325
+ if (!['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.id)) return [3 /*break*/, 3];
1302
1326
  return [4 /*yield*/, this._calcLpTokenAmountWithUnderlying(_amounts, false)];
1303
1327
  case 1:
1304
1328
  _maxBurnAmount = (_a.sent()).mul(101).div(100);
@@ -1325,7 +1349,7 @@ var Pool = /** @class */ (function () {
1325
1349
  throw Error("".concat(this.name, " pool doesn't have remove_liquidity_imbalance method"));
1326
1350
  }
1327
1351
  _amounts = amounts.map(function (amount, i) { return ethers_1.ethers.utils.parseUnits(amount, _this.underlyingDecimals[i]); });
1328
- if (!['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.name)) return [3 /*break*/, 3];
1352
+ if (!['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.id)) return [3 /*break*/, 3];
1329
1353
  return [4 /*yield*/, this._calcLpTokenAmountWithUnderlying(_amounts, false)];
1330
1354
  case 1:
1331
1355
  _maxBurnAmount = (_a.sent()).mul(101).div(100);
@@ -1352,7 +1376,7 @@ var Pool = /** @class */ (function () {
1352
1376
  throw Error("".concat(this.name, " pool doesn't have remove_liquidity_imbalance method"));
1353
1377
  }
1354
1378
  _amounts = amounts.map(function (amount, i) { return ethers_1.ethers.utils.parseUnits(amount, _this.underlyingDecimals[i]); });
1355
- if (!['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.name)) return [3 /*break*/, 3];
1379
+ if (!['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.id)) return [3 /*break*/, 3];
1356
1380
  return [4 /*yield*/, this._calcLpTokenAmountWithUnderlying(_amounts, false)];
1357
1381
  case 1:
1358
1382
  _maxBurnAmount = (_a.sent()).mul(101).div(100);
@@ -1398,11 +1422,11 @@ var Pool = /** @class */ (function () {
1398
1422
  throw Error("Token allowance is needed to estimate gas");
1399
1423
  }
1400
1424
  _amounts = amounts.map(function (amount, i) { return ethers_1.ethers.utils.parseUnits(amount, _this.underlyingDecimals[i]); });
1401
- if (!['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.name)) return [3 /*break*/, 6];
1425
+ if (!['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.id)) return [3 /*break*/, 6];
1402
1426
  return [4 /*yield*/, this._removeLiquidityImbalanceZap(_amounts, true)];
1403
1427
  case 5: return [2 /*return*/, _c.sent()];
1404
1428
  case 6:
1405
- if (!(['aave', 'saave', 'ib'].includes(this.name) || (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 8];
1429
+ if (!(['aave', 'saave', 'ib'].includes(this.id) || (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 8];
1406
1430
  return [4 /*yield*/, this._removeLiquidityImbalance(_amounts, true, true)];
1407
1431
  case 7: return [2 /*return*/, _c.sent()];
1408
1432
  case 8:
@@ -1427,11 +1451,11 @@ var Pool = /** @class */ (function () {
1427
1451
  return [4 /*yield*/, curve_1.curve.updateFeeData()];
1428
1452
  case 1:
1429
1453
  _a.sent();
1430
- if (!['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.name)) return [3 /*break*/, 3];
1454
+ if (!['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.id)) return [3 /*break*/, 3];
1431
1455
  return [4 /*yield*/, this._removeLiquidityImbalanceZap(_amounts)];
1432
1456
  case 2: return [2 /*return*/, _a.sent()];
1433
1457
  case 3:
1434
- if (!(['aave', 'saave', 'ib'].includes(this.name) || (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 5];
1458
+ if (!(['aave', 'saave', 'ib'].includes(this.id) || (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 5];
1435
1459
  return [4 /*yield*/, this._removeLiquidityImbalance(_amounts, true)];
1436
1460
  case 4: return [2 /*return*/, _a.sent()];
1437
1461
  case 5:
@@ -1494,7 +1518,7 @@ var Pool = /** @class */ (function () {
1494
1518
  throw Error("Not enough LP tokens. Actual: ".concat(lpTokenBalance, ", required: ").concat(lpTokenAmount));
1495
1519
  }
1496
1520
  _amounts = amounts.map(function (amount, i) { return ethers_1.ethers.utils.parseUnits(amount, _this.decimals[i]); });
1497
- if (!(['aave', 'saave', 'ib'].includes(this.name) || (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 4];
1521
+ if (!(['aave', 'saave', 'ib'].includes(this.id) || (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 4];
1498
1522
  return [4 /*yield*/, this._removeLiquidityImbalance(_amounts, false, true)];
1499
1523
  case 3: return [2 /*return*/, _a.sent()];
1500
1524
  case 4: return [4 /*yield*/, this._removeLiquidityImbalanceSwap(_amounts, true)];
@@ -1517,7 +1541,7 @@ var Pool = /** @class */ (function () {
1517
1541
  return [4 /*yield*/, curve_1.curve.updateFeeData()];
1518
1542
  case 1:
1519
1543
  _a.sent();
1520
- if (!(['aave', 'saave', 'ib'].includes(this.name) || (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 3];
1544
+ if (!(['aave', 'saave', 'ib'].includes(this.id) || (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 3];
1521
1545
  return [4 /*yield*/, this._removeLiquidityImbalance(_amounts, false, estimateGas)];
1522
1546
  case 2: return [2 /*return*/, _a.sent()];
1523
1547
  case 3: return [4 /*yield*/, this._removeLiquidityImbalanceSwap(_amounts, estimateGas)];
@@ -1533,13 +1557,13 @@ var Pool = /** @class */ (function () {
1533
1557
  case 0:
1534
1558
  i = this._getCoinIdx(coin);
1535
1559
  _lpTokenAmount = ethers_1.ethers.utils.parseUnits(lpTokenAmount);
1536
- if (!(['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.name) || this.name === 'susd' || this.isMeta)) return [3 /*break*/, 2];
1560
+ if (!(['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.id) || this.id === 'susd' || this.isMeta)) return [3 /*break*/, 2];
1537
1561
  return [4 /*yield*/, this._calcWithdrawOneCoinZap(_lpTokenAmount, i)];
1538
1562
  case 1:
1539
1563
  _expected = _a.sent(); // Lending pools with zap, susd and metapools
1540
1564
  return [3 /*break*/, 6];
1541
1565
  case 2:
1542
- if (!(this.name === 'ib')) return [3 /*break*/, 4];
1566
+ if (!(this.id === 'ib')) return [3 /*break*/, 4];
1543
1567
  return [4 /*yield*/, this._calcWithdrawOneCoin(_lpTokenAmount, i, true)];
1544
1568
  case 3:
1545
1569
  _expected = _a.sent(); // ib
@@ -1627,13 +1651,13 @@ var Pool = /** @class */ (function () {
1627
1651
  }
1628
1652
  i = this._getCoinIdx(coin);
1629
1653
  _lpTokenAmount = ethers_1.ethers.utils.parseUnits(lpTokenAmount);
1630
- if (!(['compound', 'usdt', 'y', 'busd', 'pax', 'tricrypto2'].includes(this.name) || this.name === 'susd' || this.isMeta)) return [3 /*break*/, 5];
1654
+ if (!(['compound', 'usdt', 'y', 'busd', 'pax', 'tricrypto2'].includes(this.id) || this.id === 'susd' || this.isMeta)) return [3 /*break*/, 5];
1631
1655
  return [4 /*yield*/, this._removeLiquidityOneCoinZap(_lpTokenAmount, i, true)];
1632
1656
  case 4: return [2 /*return*/, _c.sent()];
1633
1657
  case 5:
1634
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
1658
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
1635
1659
  this.isCryptoFactory ||
1636
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 7];
1660
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 7];
1637
1661
  return [4 /*yield*/, this._removeLiquidityOneCoin(_lpTokenAmount, i, true, true)];
1638
1662
  case 6: return [2 /*return*/, _c.sent()];
1639
1663
  case 7: return [4 /*yield*/, this._removeLiquidityOneCoinSwap(_lpTokenAmount, i, true)];
@@ -1653,13 +1677,13 @@ var Pool = /** @class */ (function () {
1653
1677
  return [4 /*yield*/, curve_1.curve.updateFeeData()];
1654
1678
  case 1:
1655
1679
  _a.sent();
1656
- if (!(['compound', 'usdt', 'y', 'busd', 'pax', 'tricrypto2'].includes(this.name) || this.name === 'susd' || this.isMeta)) return [3 /*break*/, 3];
1680
+ if (!(['compound', 'usdt', 'y', 'busd', 'pax', 'tricrypto2'].includes(this.id) || this.id === 'susd' || this.isMeta)) return [3 /*break*/, 3];
1657
1681
  return [4 /*yield*/, this._removeLiquidityOneCoinZap(_lpTokenAmount, i)];
1658
1682
  case 2: return [2 /*return*/, _a.sent()];
1659
1683
  case 3:
1660
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
1684
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
1661
1685
  this.isCryptoFactory ||
1662
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 5];
1686
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 5];
1663
1687
  return [4 /*yield*/, this._removeLiquidityOneCoin(_lpTokenAmount, i, true)];
1664
1688
  case 4: return [2 /*return*/, _a.sent()];
1665
1689
  case 5: return [4 /*yield*/, this._removeLiquidityOneCoinSwap(_lpTokenAmount, i)];
@@ -1677,12 +1701,12 @@ var Pool = /** @class */ (function () {
1677
1701
  if (this.isFake) {
1678
1702
  throw Error("".concat(this.name, " pool doesn't have this method"));
1679
1703
  }
1680
- if (['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.name)) {
1704
+ if (['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.id)) {
1681
1705
  throw Error("".concat(this.name, " pool doesn't have remove_liquidity_one_coin method for wrapped tokens"));
1682
1706
  }
1683
1707
  i = this._getCoinIdx(coin, false);
1684
1708
  _lpTokenAmount = ethers_1.ethers.utils.parseUnits(lpTokenAmount);
1685
- if (!(this.name === 'ib')) return [3 /*break*/, 2];
1709
+ if (!(this.id === 'ib')) return [3 /*break*/, 2];
1686
1710
  return [4 /*yield*/, this._calcWithdrawOneCoin(_lpTokenAmount, i, false)];
1687
1711
  case 1:
1688
1712
  _expected = _a.sent(); // ib
@@ -1733,13 +1757,13 @@ var Pool = /** @class */ (function () {
1733
1757
  throw Error("Not enough LP tokens. Actual: ".concat(lpTokenBalance, ", required: ").concat(lpTokenAmount));
1734
1758
  }
1735
1759
  i = this._getCoinIdx(coin, false);
1736
- if (['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.name)) {
1760
+ if (['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.id)) {
1737
1761
  throw Error("".concat(this.name, " pool doesn't have remove_liquidity_one_coin method for wrapped tokens"));
1738
1762
  }
1739
1763
  _lpTokenAmount = ethers_1.ethers.utils.parseUnits(lpTokenAmount);
1740
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
1764
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
1741
1765
  this.isCryptoFactory ||
1742
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 3];
1766
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 3];
1743
1767
  return [4 /*yield*/, this._removeLiquidityOneCoin(_lpTokenAmount, i, false, true)];
1744
1768
  case 2: return [2 /*return*/, _a.sent()];
1745
1769
  case 3: return [4 /*yield*/, this._removeLiquidityOneCoinSwap(_lpTokenAmount, i, true)];
@@ -1756,16 +1780,16 @@ var Pool = /** @class */ (function () {
1756
1780
  throw Error("".concat(this.name, " pool doesn't have this method"));
1757
1781
  }
1758
1782
  i = this._getCoinIdx(coin, false);
1759
- if (['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.name)) {
1783
+ if (['compound', 'usdt', 'y', 'busd', 'pax'].includes(this.id)) {
1760
1784
  throw Error("".concat(this.name, " pool doesn't have remove_liquidity_one_coin method for wrapped tokens"));
1761
1785
  }
1762
1786
  return [4 /*yield*/, curve_1.curve.updateFeeData()];
1763
1787
  case 1:
1764
1788
  _a.sent();
1765
1789
  _lpTokenAmount = ethers_1.ethers.utils.parseUnits(lpTokenAmount);
1766
- if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.name) ||
1790
+ if (!(['aave', 'saave', 'ib', 'crveth', "cvxeth", "spelleth", "teth"].includes(this.id) ||
1767
1791
  this.isCryptoFactory ||
1768
- (curve_1.curve.chainId === 137 && this.name === 'ren'))) return [3 /*break*/, 3];
1792
+ (curve_1.curve.chainId === 137 && this.id === 'ren'))) return [3 /*break*/, 3];
1769
1793
  return [4 /*yield*/, this._removeLiquidityOneCoin(_lpTokenAmount, i, false)];
1770
1794
  case 2: return [2 /*return*/, _a.sent()];
1771
1795
  case 3: return [4 /*yield*/, this._removeLiquidityOneCoinSwap(_lpTokenAmount, i)];
@@ -2090,8 +2114,8 @@ var Pool = /** @class */ (function () {
2090
2114
  return __generator(this, function (_a) {
2091
2115
  switch (_a.label) {
2092
2116
  case 0:
2093
- contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.name) ||
2094
- (curve_1.curve.chainId === 137 && this.isFactory) ? this.zap : this.swap;
2117
+ contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.id) ||
2118
+ (curve_1.curve.chainId === 137 && this.isMetaFactory) ? this.zap : this.swap;
2095
2119
  i = this._getCoinIdx(inputCoin);
2096
2120
  return [4 /*yield*/, (0, utils_1.hasAllowance)([this.underlyingCoinAddresses[i]], [amount], curve_1.curve.signerAddress, contractAddress)];
2097
2121
  case 1: return [2 /*return*/, _a.sent()];
@@ -2103,8 +2127,8 @@ var Pool = /** @class */ (function () {
2103
2127
  return __generator(this, function (_a) {
2104
2128
  switch (_a.label) {
2105
2129
  case 0:
2106
- contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.name) ||
2107
- (curve_1.curve.chainId === 137 && this.isFactory) ? this.zap : this.swap;
2130
+ contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.id) ||
2131
+ (curve_1.curve.chainId === 137 && this.isMetaFactory) ? this.zap : this.swap;
2108
2132
  i = this._getCoinIdx(inputCoin);
2109
2133
  return [4 /*yield*/, (0, utils_1.ensureAllowanceEstimateGas)([this.underlyingCoinAddresses[i]], [amount], contractAddress)];
2110
2134
  case 1: return [2 /*return*/, _a.sent()];
@@ -2116,8 +2140,8 @@ var Pool = /** @class */ (function () {
2116
2140
  return __generator(this, function (_a) {
2117
2141
  switch (_a.label) {
2118
2142
  case 0:
2119
- contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.name) ||
2120
- (curve_1.curve.chainId === 137 && this.isFactory) ? this.zap : this.swap;
2143
+ contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.id) ||
2144
+ (curve_1.curve.chainId === 137 && this.isMetaFactory) ? this.zap : this.swap;
2121
2145
  i = this._getCoinIdx(inputCoin);
2122
2146
  return [4 /*yield*/, (0, utils_1.ensureAllowance)([this.underlyingCoinAddresses[i]], [amount], contractAddress)];
2123
2147
  case 1: return [2 /*return*/, _a.sent()];
@@ -2131,8 +2155,8 @@ var Pool = /** @class */ (function () {
2131
2155
  return __generator(this, function (_d) {
2132
2156
  switch (_d.label) {
2133
2157
  case 0:
2134
- contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.name) ||
2135
- (curve_1.curve.chainId === 137 && this.isFactory) ? this.zap : this.swap;
2158
+ contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.id) ||
2159
+ (curve_1.curve.chainId === 137 && this.isMetaFactory) ? this.zap : this.swap;
2136
2160
  i = this._getCoinIdx(inputCoin);
2137
2161
  j = this._getCoinIdx(outputCoin);
2138
2162
  _c = (_a = Object).values;
@@ -2157,11 +2181,11 @@ var Pool = /** @class */ (function () {
2157
2181
  contract = curve_1.curve.contracts[contractAddress].contract;
2158
2182
  exchangeMethod = Object.prototype.hasOwnProperty.call(contract, 'exchange_underlying') ? 'exchange_underlying' : 'exchange';
2159
2183
  value = (0, utils_1.isEth)(this.underlyingCoinAddresses[i]) ? _amount : ethers_1.ethers.BigNumber.from(0);
2160
- if (!(this.name === "tricrypto2")) return [3 /*break*/, 5];
2184
+ if (!(this.id === "tricrypto2")) return [3 /*break*/, 5];
2161
2185
  return [4 /*yield*/, contract.estimateGas[exchangeMethod](i, j, _amount, _minRecvAmount, true, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
2162
2186
  case 4: return [2 /*return*/, (_d.sent()).toNumber()];
2163
2187
  case 5:
2164
- if (!(curve_1.curve.chainId === 137 && this.isFactory)) return [3 /*break*/, 7];
2188
+ if (!(curve_1.curve.chainId === 137 && this.isMetaFactory)) return [3 /*break*/, 7];
2165
2189
  return [4 /*yield*/, contract.estimateGas[exchangeMethod](this.swap, i, j, _amount, _minRecvAmount, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
2166
2190
  case 6: return [2 /*return*/, (_d.sent()).toNumber()];
2167
2191
  case 7: return [4 /*yield*/, contract.estimateGas[exchangeMethod](i, j, _amount, _minRecvAmount, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
@@ -2177,8 +2201,8 @@ var Pool = /** @class */ (function () {
2177
2201
  return __generator(this, function (_a) {
2178
2202
  switch (_a.label) {
2179
2203
  case 0:
2180
- contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.name) ||
2181
- (curve_1.curve.chainId === 137 && this.isFactory) ? this.zap : this.swap;
2204
+ contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.id) ||
2205
+ (curve_1.curve.chainId === 137 && this.isMetaFactory) ? this.zap : this.swap;
2182
2206
  i = this._getCoinIdx(inputCoin);
2183
2207
  j = this._getCoinIdx(outputCoin);
2184
2208
  _amount = ethers_1.ethers.utils.parseUnits(amount, this.underlyingDecimals[i]);
@@ -2197,14 +2221,14 @@ var Pool = /** @class */ (function () {
2197
2221
  return [4 /*yield*/, curve_1.curve.updateFeeData()];
2198
2222
  case 3:
2199
2223
  _a.sent();
2200
- if (!(this.name === 'tricrypto2')) return [3 /*break*/, 6];
2224
+ if (!(this.id === 'tricrypto2')) return [3 /*break*/, 6];
2201
2225
  return [4 /*yield*/, contract.estimateGas[exchangeMethod](i, j, _amount, _minRecvAmount, true, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
2202
2226
  case 4:
2203
2227
  gasLimit_1 = (_a.sent()).mul(130).div(100);
2204
2228
  return [4 /*yield*/, contract[exchangeMethod](i, j, _amount, _minRecvAmount, true, __assign(__assign({}, curve_1.curve.options), { value: value, gasLimit: gasLimit_1 }))];
2205
2229
  case 5: return [2 /*return*/, (_a.sent()).hash];
2206
2230
  case 6:
2207
- if (!(curve_1.curve.chainId === 137 && this.isFactory)) return [3 /*break*/, 9];
2231
+ if (!(curve_1.curve.chainId === 137 && this.isMetaFactory)) return [3 /*break*/, 9];
2208
2232
  return [4 /*yield*/, contract.estimateGas[exchangeMethod](this.swap, i, j, _amount, _minRecvAmount, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
2209
2233
  case 7:
2210
2234
  gasLimit_2 = (_a.sent()).mul(140).div(100);
@@ -2213,7 +2237,7 @@ var Pool = /** @class */ (function () {
2213
2237
  case 9: return [4 /*yield*/, contract.estimateGas[exchangeMethod](i, j, _amount, _minRecvAmount, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
2214
2238
  case 10:
2215
2239
  estimatedGas = _a.sent();
2216
- gasLimit = curve_1.curve.chainId === 137 && this.name === 'ren' ?
2240
+ gasLimit = curve_1.curve.chainId === 137 && this.id === 'ren' ?
2217
2241
  estimatedGas.mul(160).div(100) :
2218
2242
  estimatedGas.mul(130).div(100);
2219
2243
  return [4 /*yield*/, contract[exchangeMethod](i, j, _amount, _minRecvAmount, __assign(__assign({}, curve_1.curve.options), { value: value, gasLimit: gasLimit }))];
@@ -2315,7 +2339,7 @@ var Pool = /** @class */ (function () {
2315
2339
  _minRecvAmount = (0, utils_1.fromBN)(minRecvAmountBN, outputCoinDecimals);
2316
2340
  contract = curve_1.curve.contracts[this.swap].contract;
2317
2341
  value = (0, utils_1.isEth)(this.coinAddresses[i]) ? _amount : ethers_1.ethers.BigNumber.from(0);
2318
- if (!(this.name === 'tricrypto2')) return [3 /*break*/, 5];
2342
+ if (!(this.id === 'tricrypto2')) return [3 /*break*/, 5];
2319
2343
  return [4 /*yield*/, contract.estimateGas.exchange(i, j, _amount, _minRecvAmount, false, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
2320
2344
  case 4: return [2 /*return*/, (_d.sent()).toNumber()];
2321
2345
  case 5: return [4 /*yield*/, contract.estimateGas.exchange(i, j, _amount, _minRecvAmount, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
@@ -2351,7 +2375,7 @@ var Pool = /** @class */ (function () {
2351
2375
  return [4 /*yield*/, curve_1.curve.updateFeeData()];
2352
2376
  case 3:
2353
2377
  _a.sent();
2354
- if (!(this.name === 'tricrypto2')) return [3 /*break*/, 6];
2378
+ if (!(this.id === 'tricrypto2')) return [3 /*break*/, 6];
2355
2379
  return [4 /*yield*/, contract.estimateGas.exchange(i, j, _amount, _minRecvAmount, false, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
2356
2380
  case 4:
2357
2381
  gasLimit_3 = (_a.sent()).mul(130).div(100);
@@ -2360,7 +2384,7 @@ var Pool = /** @class */ (function () {
2360
2384
  case 6: return [4 /*yield*/, contract.estimateGas.exchange(i, j, _amount, _minRecvAmount, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
2361
2385
  case 7:
2362
2386
  estimatedGas = _a.sent();
2363
- gasLimit = curve_1.curve.chainId === 137 && this.name === 'ren' ?
2387
+ gasLimit = curve_1.curve.chainId === 137 && this.id === 'ren' ?
2364
2388
  estimatedGas.mul(140).div(100) :
2365
2389
  estimatedGas.mul(130).div(100);
2366
2390
  return [4 /*yield*/, contract.exchange(i, j, _amount, _minRecvAmount, __assign(__assign({}, curve_1.curve.options), { value: value, gasLimit: gasLimit }))];
@@ -2532,14 +2556,14 @@ var Pool = /** @class */ (function () {
2532
2556
  if (!(i < this.coinAddresses.length)) return [3 /*break*/, 9];
2533
2557
  addr = this.coinAddresses[i];
2534
2558
  if (!this.useLending[i]) return [3 /*break*/, 7];
2535
- if (!['compound', 'usdt', 'ib'].includes(this.name)) return [3 /*break*/, 3];
2559
+ if (!['compound', 'usdt', 'ib'].includes(this.id)) return [3 /*break*/, 3];
2536
2560
  _c = (_a = _rates).push;
2537
2561
  return [4 /*yield*/, curve_1.curve.contracts[addr].contract.exchangeRateStored()];
2538
2562
  case 2:
2539
2563
  _c.apply(_a, [_f.sent()]);
2540
2564
  return [3 /*break*/, 6];
2541
2565
  case 3:
2542
- if (!['y', 'busd', 'pax'].includes(this.name)) return [3 /*break*/, 5];
2566
+ if (!['y', 'busd', 'pax'].includes(this.id)) return [3 /*break*/, 5];
2543
2567
  _e = (_d = _rates).push;
2544
2568
  return [4 /*yield*/, curve_1.curve.contracts[addr].contract.getPricePerFullShare()];
2545
2569
  case 4:
@@ -2816,7 +2840,7 @@ var Pool = /** @class */ (function () {
2816
2840
  switch (_a.label) {
2817
2841
  case 0:
2818
2842
  contract = curve_1.curve.contracts[this.swap].contract;
2819
- if (!(["eurtusd", "xautusd", "crveth", "cvxeth", "spelleth", "teth"].includes(this.name) || this.isCryptoFactory)) return [3 /*break*/, 2];
2843
+ if (!(["eurtusd", "xautusd", "crveth", "cvxeth", "spelleth", "teth"].includes(this.id) || this.isCryptoFactory)) return [3 /*break*/, 2];
2820
2844
  return [4 /*yield*/, contract.calc_token_amount(_amounts, curve_1.curve.constantOptions)];
2821
2845
  case 1: return [2 /*return*/, _a.sent()];
2822
2846
  case 2: return [4 /*yield*/, contract.calc_token_amount(_amounts, isDeposit, curve_1.curve.constantOptions)];
@@ -2837,7 +2861,7 @@ var Pool = /** @class */ (function () {
2837
2861
  return [4 /*yield*/, contract.calc_token_amount(this.swap, _amounts, isDeposit, curve_1.curve.constantOptions)];
2838
2862
  case 1: return [2 /*return*/, _a.sent()];
2839
2863
  case 2:
2840
- if (!["eurtusd", "xautusd"].includes(this.name)) return [3 /*break*/, 4];
2864
+ if (!["eurtusd", "xautusd"].includes(this.id)) return [3 /*break*/, 4];
2841
2865
  return [4 /*yield*/, contract.calc_token_amount(_amounts, curve_1.curve.constantOptions)];
2842
2866
  case 3: return [2 /*return*/, _a.sent()];
2843
2867
  case 4: return [4 /*yield*/, contract.calc_token_amount(_amounts, isDeposit, curve_1.curve.constantOptions)];
@@ -3080,7 +3104,7 @@ var Pool = /** @class */ (function () {
3080
3104
  case 0: return [4 /*yield*/, this._calcExpectedAmounts(_lpTokenAmount)];
3081
3105
  case 1:
3082
3106
  _expectedWrappedAmounts = _a.sent();
3083
- if (this.name !== 'atricrypto3') {
3107
+ if (this.id !== 'atricrypto3') {
3084
3108
  _expectedWrappedAmounts.unshift(_expectedWrappedAmounts.pop());
3085
3109
  }
3086
3110
  _expectedMetaCoinAmount = _expectedWrappedAmounts[0], _expectedUnderlyingAmounts = _expectedWrappedAmounts.slice(1);
@@ -3088,7 +3112,7 @@ var Pool = /** @class */ (function () {
3088
3112
  return [4 /*yield*/, basePool._calcExpectedAmounts(_expectedMetaCoinAmount)];
3089
3113
  case 2:
3090
3114
  _basePoolExpectedAmounts = _a.sent();
3091
- return [2 /*return*/, this.name !== 'atricrypto3' ? __spreadArray(__spreadArray([], _expectedUnderlyingAmounts, true), _basePoolExpectedAmounts, true) : __spreadArray(__spreadArray([], _basePoolExpectedAmounts, true), _expectedUnderlyingAmounts, true)];
3115
+ return [2 /*return*/, this.id !== 'atricrypto3' ? __spreadArray(__spreadArray([], _expectedUnderlyingAmounts, true), _basePoolExpectedAmounts, true) : __spreadArray(__spreadArray([], _basePoolExpectedAmounts, true), _expectedUnderlyingAmounts, true)];
3092
3116
  }
3093
3117
  });
3094
3118
  }); };
@@ -3342,7 +3366,7 @@ var Pool = /** @class */ (function () {
3342
3366
  if (estimateGas) {
3343
3367
  return [2 /*return*/, gas.toNumber()];
3344
3368
  }
3345
- gasLimit = curve_1.curve.chainId === 137 && this.name === 'ren' ?
3369
+ gasLimit = curve_1.curve.chainId === 137 && this.id === 'ren' ?
3346
3370
  gas.mul(140).div(100) :
3347
3371
  gas.mul(130).div(100);
3348
3372
  return [4 /*yield*/, contract.remove_liquidity_imbalance(_amounts, _maxBurnAmount, useUnderlying, __assign(__assign({}, curve_1.curve.options), { gasLimit: gasLimit }))];
@@ -3420,7 +3444,7 @@ var Pool = /** @class */ (function () {
3420
3444
  _c.sent();
3421
3445
  _c.label = 2;
3422
3446
  case 2:
3423
- if (!(this.name === 'tricrypto2')) return [3 /*break*/, 4];
3447
+ if (!(this.id === 'tricrypto2')) return [3 /*break*/, 4];
3424
3448
  return [4 /*yield*/, this._calcWithdrawOneCoinSwap(_lpTokenAmount, i)];
3425
3449
  case 3:
3426
3450
  _a = _c.sent();
@@ -3464,7 +3488,7 @@ var Pool = /** @class */ (function () {
3464
3488
  return __generator(this, function (_c) {
3465
3489
  switch (_c.label) {
3466
3490
  case 0:
3467
- if (!(this.name === 'ib')) return [3 /*break*/, 2];
3491
+ if (!(this.id === 'ib')) return [3 /*break*/, 2];
3468
3492
  return [4 /*yield*/, this._calcWithdrawOneCoin(_lpTokenAmount, i, useUnderlying)];
3469
3493
  case 1:
3470
3494
  _a = _c.sent();
@@ -3483,7 +3507,7 @@ var Pool = /** @class */ (function () {
3483
3507
  if (estimateGas) {
3484
3508
  return [2 /*return*/, gas.toNumber()];
3485
3509
  }
3486
- gasLimit = curve_1.curve.chainId === 137 && this.name === 'ren' ?
3510
+ gasLimit = curve_1.curve.chainId === 137 && this.id === 'ren' ?
3487
3511
  gas.mul(160).div(100) :
3488
3512
  gas.mul(130).div(100);
3489
3513
  return [4 /*yield*/, contract.remove_liquidity_one_coin(_lpTokenAmount, i, _minAmount, useUnderlying, __assign(__assign({}, curve_1.curve.options), { gasLimit: gasLimit }))];
@@ -3497,7 +3521,7 @@ var Pool = /** @class */ (function () {
3497
3521
  return __generator(this, function (_a) {
3498
3522
  switch (_a.label) {
3499
3523
  case 0:
3500
- contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.name) ? this.zap : this.swap;
3524
+ contractAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(this.id) ? this.zap : this.swap;
3501
3525
  contract = curve_1.curve.contracts[contractAddress].contract;
3502
3526
  if (!Object.prototype.hasOwnProperty.call(contract, 'get_dy_underlying')) return [3 /*break*/, 2];
3503
3527
  return [4 /*yield*/, contract.get_dy_underlying(i, j, _amount, curve_1.curve.constantOptions)];
@@ -3515,8 +3539,11 @@ var Pool = /** @class */ (function () {
3515
3539
  }
3516
3540
  });
3517
3541
  }); };
3518
- var poolData = __assign(__assign(__assign({}, curve_1.POOLS_DATA), (curve_1.curve.constants.FACTORY_POOLS_DATA || {})), (curve_1.curve.constants.CRYPTO_FACTORY_POOLS_DATA || {}))[name];
3519
- this.name = name;
3542
+ var poolData = __assign(__assign(__assign({}, curve_1.POOLS_DATA), (curve_1.curve.constants.FACTORY_POOLS_DATA || {})), (curve_1.curve.constants.CRYPTO_FACTORY_POOLS_DATA || {}))[id];
3543
+ this.id = id;
3544
+ this.name = poolData.name;
3545
+ this.fullName = poolData.full_name;
3546
+ this.symbol = poolData.symbol;
3520
3547
  this.referenceAsset = poolData.reference_asset;
3521
3548
  this.swap = poolData.swap_address;
3522
3549
  this.zap = poolData.deposit_address || null;
@@ -4154,3 +4181,506 @@ var getUserPoolList = function (address) { return __awaiter(void 0, void 0, void
4154
4181
  });
4155
4182
  }); };
4156
4183
  exports.getUserPoolList = getUserPoolList;
4184
+ // --------- Multi-Pool Exchange ---------
4185
+ var IMBALANCED_POOLS = [];
4186
+ // Inspired by Dijkstra's algorithm
4187
+ var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __awaiter(void 0, void 0, void 0, function () {
4188
+ var ALL_POOLS, markedCoins, curCoins, nextCoins, routes, step, _i, curCoins_1, inCoin, _a, ALL_POOLS_1, _c, poolId, poolData, coin_addresses, underlying_coin_addresses, meta_coin_addresses, inCoinIndexes, j, tvl, _d, swapType, _e, _f, inCoinRoute, poolAddress, j, tvl, _h, swapType, _j, _k, inCoinRoute, j, tvl, _l, swapType, _m, _o, inCoinRoute, tvl, _p, swapType, _q, _r, inCoinRoute;
4189
+ var _s;
4190
+ var _t, _u, _v, _w, _x, _y;
4191
+ return __generator(this, function (_z) {
4192
+ switch (_z.label) {
4193
+ case 0:
4194
+ inputCoinAddress = inputCoinAddress.toLowerCase();
4195
+ outputCoinAddress = outputCoinAddress.toLowerCase();
4196
+ ALL_POOLS = Object.entries(__assign(__assign(__assign({}, curve_1.POOLS_DATA), curve_1.curve.constants.FACTORY_POOLS_DATA), curve_1.curve.constants.CRYPTO_FACTORY_POOLS_DATA));
4197
+ markedCoins = [];
4198
+ curCoins = [inputCoinAddress];
4199
+ nextCoins = new Set();
4200
+ routes = (_s = {},
4201
+ _s[inputCoinAddress] = [[]],
4202
+ _s);
4203
+ step = 0;
4204
+ _z.label = 1;
4205
+ case 1:
4206
+ if (!(step < 4)) return [3 /*break*/, 21];
4207
+ _i = 0, curCoins_1 = curCoins;
4208
+ _z.label = 2;
4209
+ case 2:
4210
+ if (!(_i < curCoins_1.length)) return [3 /*break*/, 19];
4211
+ inCoin = curCoins_1[_i];
4212
+ _a = 0, ALL_POOLS_1 = ALL_POOLS;
4213
+ _z.label = 3;
4214
+ case 3:
4215
+ if (!(_a < ALL_POOLS_1.length)) return [3 /*break*/, 18];
4216
+ _c = ALL_POOLS_1[_a], poolId = _c[0], poolData = _c[1];
4217
+ coin_addresses = poolData.coin_addresses.map(function (a) { return a.toLowerCase(); });
4218
+ underlying_coin_addresses = poolData.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); });
4219
+ meta_coin_addresses = ((_t = poolData.meta_coin_addresses) === null || _t === void 0 ? void 0 : _t.map(function (a) { return a.toLowerCase(); })) || [];
4220
+ inCoinIndexes = {
4221
+ coin: coin_addresses.indexOf(inCoin),
4222
+ underlying_coin: underlying_coin_addresses.indexOf(inCoin),
4223
+ meta_coin: meta_coin_addresses ? meta_coin_addresses.indexOf(inCoin) : -1,
4224
+ };
4225
+ // No input coin in this pool --> slip
4226
+ if (inCoinIndexes.coin === -1 && inCoinIndexes.underlying_coin === -1 && inCoinIndexes.meta_coin === -1)
4227
+ return [3 /*break*/, 17];
4228
+ if (!(inCoinIndexes.coin >= 0 && poolId !== "atricrypto3")) return [3 /*break*/, 7];
4229
+ j = 0;
4230
+ _z.label = 4;
4231
+ case 4:
4232
+ if (!(j < coin_addresses.length)) return [3 /*break*/, 7];
4233
+ // If this coin already marked or will be marked on the current step, no need to consider it on the next step
4234
+ if (markedCoins.includes(coin_addresses[j]) || curCoins.includes(coin_addresses[j]))
4235
+ return [3 /*break*/, 6];
4236
+ // Looking for outputCoinAddress only on the final step
4237
+ if (step === 3 && coin_addresses[j] !== outputCoinAddress)
4238
+ return [3 /*break*/, 6];
4239
+ _d = Number;
4240
+ return [4 /*yield*/, (new Pool(poolId)).stats.getTotalLiquidity()];
4241
+ case 5:
4242
+ tvl = _d.apply(void 0, [_z.sent()]);
4243
+ if (tvl === 0)
4244
+ return [3 /*break*/, 6];
4245
+ // Skip imbalanced pools
4246
+ if (IMBALANCED_POOLS.includes(poolId))
4247
+ return [3 /*break*/, 6];
4248
+ swapType = poolData.is_crypto ? 3 : 1;
4249
+ for (_e = 0, _f = routes[inCoin]; _e < _f.length; _e++) {
4250
+ inCoinRoute = _f[_e];
4251
+ routes[coin_addresses[j]] = ((_u = routes[coin_addresses[j]]) !== null && _u !== void 0 ? _u : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
4252
+ {
4253
+ poolId: poolId,
4254
+ poolAddress: poolData.swap_address,
4255
+ outputCoinAddress: coin_addresses[j],
4256
+ i: inCoinIndexes.coin,
4257
+ j: j,
4258
+ swapType: swapType,
4259
+ swapAddress: ethers_1.ethers.constants.AddressZero,
4260
+ },
4261
+ ], false)]);
4262
+ }
4263
+ nextCoins.add(coin_addresses[j]);
4264
+ _z.label = 6;
4265
+ case 6:
4266
+ j++;
4267
+ return [3 /*break*/, 4];
4268
+ case 7:
4269
+ poolAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(poolId) ||
4270
+ (curve_1.curve.chainId === 137 && poolData.is_factory) ? poolData.deposit_address : poolData.swap_address;
4271
+ if (!(coin_addresses.join("|") !== underlying_coin_addresses.join("|") && inCoinIndexes.underlying_coin >= 0)) return [3 /*break*/, 11];
4272
+ j = 0;
4273
+ _z.label = 8;
4274
+ case 8:
4275
+ if (!(j < underlying_coin_addresses.length)) return [3 /*break*/, 11];
4276
+ if (poolId === "atricrypto3" && inCoinIndexes.meta_coin >= 0 && meta_coin_addresses.includes(underlying_coin_addresses[j]))
4277
+ return [3 /*break*/, 10];
4278
+ // If this coin already marked or will be marked on the current step, no need to consider it on the next step
4279
+ if (markedCoins.includes(underlying_coin_addresses[j]) || curCoins.includes(underlying_coin_addresses[j]))
4280
+ return [3 /*break*/, 10];
4281
+ // Looking for outputCoinAddress only on the final step
4282
+ if (step === 3 && underlying_coin_addresses[j] !== outputCoinAddress)
4283
+ return [3 /*break*/, 10];
4284
+ _h = Number;
4285
+ return [4 /*yield*/, (new Pool(poolId)).stats.getTotalLiquidity()];
4286
+ case 9:
4287
+ tvl = _h.apply(void 0, [_z.sent()]);
4288
+ if (tvl === 0)
4289
+ return [3 /*break*/, 10];
4290
+ // Skip imbalanced pools
4291
+ if (IMBALANCED_POOLS.includes(poolId))
4292
+ return [3 /*break*/, 10];
4293
+ swapType = poolData.is_crypto && (poolData.is_fake || poolData.is_meta) ? 4 : poolData.is_crypto ? 3 : 2;
4294
+ for (_j = 0, _k = routes[inCoin]; _j < _k.length; _j++) {
4295
+ inCoinRoute = _k[_j];
4296
+ routes[underlying_coin_addresses[j]] = ((_v = routes[underlying_coin_addresses[j]]) !== null && _v !== void 0 ? _v : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
4297
+ {
4298
+ poolId: poolId,
4299
+ poolAddress: poolAddress,
4300
+ outputCoinAddress: underlying_coin_addresses[j],
4301
+ i: inCoinIndexes.underlying_coin,
4302
+ j: j,
4303
+ swapType: swapType,
4304
+ swapAddress: ethers_1.ethers.constants.AddressZero,
4305
+ },
4306
+ ], false)]);
4307
+ }
4308
+ nextCoins.add(underlying_coin_addresses[j]);
4309
+ _z.label = 10;
4310
+ case 10:
4311
+ j++;
4312
+ return [3 /*break*/, 8];
4313
+ case 11:
4314
+ if (!(inCoinIndexes.coin === 0 && meta_coin_addresses.length > 0 && poolId !== "atricrypto3")) return [3 /*break*/, 15];
4315
+ j = 0;
4316
+ _z.label = 12;
4317
+ case 12:
4318
+ if (!(j < meta_coin_addresses.length)) return [3 /*break*/, 15];
4319
+ // If this coin already marked or will be marked on the current step, no need to consider it on the next step
4320
+ if (markedCoins.includes(meta_coin_addresses[j]) || curCoins.includes(meta_coin_addresses[j]))
4321
+ return [3 /*break*/, 14];
4322
+ // Looking for outputCoinAddress only on the final step
4323
+ if (step === 3 && meta_coin_addresses[j] !== outputCoinAddress)
4324
+ return [3 /*break*/, 14];
4325
+ _l = Number;
4326
+ return [4 /*yield*/, (new Pool(poolId)).stats.getTotalLiquidity()];
4327
+ case 13:
4328
+ tvl = _l.apply(void 0, [_z.sent()]);
4329
+ if (tvl === 0)
4330
+ return [3 /*break*/, 14];
4331
+ // Skip imbalanced pools
4332
+ if (IMBALANCED_POOLS.includes(poolId))
4333
+ return [3 /*break*/, 14];
4334
+ swapType = (curve_1.curve.chainId === 137 && poolData.is_factory) ? 5 : poolData.is_crypto ? 4 : 2;
4335
+ for (_m = 0, _o = routes[inCoin]; _m < _o.length; _m++) {
4336
+ inCoinRoute = _o[_m];
4337
+ routes[meta_coin_addresses[j]] = ((_w = routes[meta_coin_addresses[j]]) !== null && _w !== void 0 ? _w : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
4338
+ {
4339
+ poolId: poolId,
4340
+ poolAddress: poolAddress,
4341
+ outputCoinAddress: meta_coin_addresses[j],
4342
+ i: inCoinIndexes.coin,
4343
+ j: j + 1,
4344
+ swapType: swapType,
4345
+ swapAddress: swapType === 5 ? poolData.swap_address : ethers_1.ethers.constants.AddressZero,
4346
+ },
4347
+ ], false)]);
4348
+ }
4349
+ nextCoins.add(meta_coin_addresses[j]);
4350
+ _z.label = 14;
4351
+ case 14:
4352
+ j++;
4353
+ return [3 /*break*/, 12];
4354
+ case 15:
4355
+ if (!(inCoinIndexes.meta_coin >= 0 && poolId !== "atricrypto3")) return [3 /*break*/, 17];
4356
+ // If this coin already marked or will be marked on the current step, no need to consider it on the next step
4357
+ if (markedCoins.includes(coin_addresses[0]) || curCoins.includes(coin_addresses[0]))
4358
+ return [3 /*break*/, 17];
4359
+ // Looking for outputCoinAddress only on the final step
4360
+ if (step === 3 && coin_addresses[0] !== outputCoinAddress)
4361
+ return [3 /*break*/, 17];
4362
+ _p = Number;
4363
+ return [4 /*yield*/, (new Pool(poolId)).stats.getTotalLiquidity()];
4364
+ case 16:
4365
+ tvl = _p.apply(void 0, [_z.sent()]);
4366
+ if (tvl === 0)
4367
+ return [3 /*break*/, 17];
4368
+ // Skip imbalanced pools
4369
+ if (IMBALANCED_POOLS.includes(poolId))
4370
+ return [3 /*break*/, 17];
4371
+ swapType = (curve_1.curve.chainId === 137 && poolData.is_factory) ? 5 : poolData.is_crypto ? 4 : 2;
4372
+ for (_q = 0, _r = routes[inCoin]; _q < _r.length; _q++) {
4373
+ inCoinRoute = _r[_q];
4374
+ routes[coin_addresses[0]] = ((_x = routes[coin_addresses[0]]) !== null && _x !== void 0 ? _x : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
4375
+ {
4376
+ poolId: poolId,
4377
+ poolAddress: poolAddress,
4378
+ outputCoinAddress: coin_addresses[0],
4379
+ i: inCoinIndexes.meta_coin + 1,
4380
+ j: 0,
4381
+ swapType: swapType,
4382
+ swapAddress: swapType === 5 ? poolData.swap_address : ethers_1.ethers.constants.AddressZero,
4383
+ },
4384
+ ], false)]);
4385
+ nextCoins.add(coin_addresses[0]);
4386
+ }
4387
+ _z.label = 17;
4388
+ case 17:
4389
+ _a++;
4390
+ return [3 /*break*/, 3];
4391
+ case 18:
4392
+ _i++;
4393
+ return [3 /*break*/, 2];
4394
+ case 19:
4395
+ // If target output coin is reached, search is finished. Assumption: the shorter route, the better.
4396
+ if (outputCoinAddress in routes)
4397
+ return [3 /*break*/, 21];
4398
+ markedCoins.push.apply(markedCoins, curCoins);
4399
+ curCoins = Array.from(nextCoins);
4400
+ nextCoins = new Set();
4401
+ _z.label = 20;
4402
+ case 20:
4403
+ step++;
4404
+ return [3 /*break*/, 1];
4405
+ case 21: return [2 /*return*/, (_y = routes[outputCoinAddress]) !== null && _y !== void 0 ? _y : []];
4406
+ }
4407
+ });
4408
+ }); };
4409
+ exports._findAllRoutes = _findAllRoutes;
4410
+ var _getRouteKey = function (route, inputCoinAddress, outputCoinAddress) {
4411
+ var sortedCoins = [inputCoinAddress, outputCoinAddress].sort();
4412
+ var key = "".concat(sortedCoins[0], "-->");
4413
+ for (var _i = 0, _a = route.steps; _i < _a.length; _i++) {
4414
+ var routeStep = _a[_i];
4415
+ key += "".concat(routeStep.poolId, "-->");
4416
+ }
4417
+ key += sortedCoins[1];
4418
+ return key;
4419
+ };
4420
+ var _getExchangeMultipleArgs = function (inputCoinAddress, route) {
4421
+ var _route = [inputCoinAddress];
4422
+ var _swapParams = [];
4423
+ var _factorySwapAddresses = [];
4424
+ for (var _i = 0, _a = route.steps; _i < _a.length; _i++) {
4425
+ var routeStep = _a[_i];
4426
+ _route.push(routeStep.poolAddress, routeStep.outputCoinAddress);
4427
+ _swapParams.push([routeStep.i, routeStep.j, routeStep.swapType]);
4428
+ _factorySwapAddresses.push(routeStep.swapAddress);
4429
+ }
4430
+ _route = _route.concat(Array(9 - _route.length).fill(ethers_1.ethers.constants.AddressZero));
4431
+ _swapParams = _swapParams.concat(Array(4 - _swapParams.length).fill([0, 0, 0]));
4432
+ _factorySwapAddresses = _factorySwapAddresses.concat(Array(4 - _factorySwapAddresses.length).fill(ethers_1.ethers.constants.AddressZero));
4433
+ return { _route: _route, _swapParams: _swapParams, _factorySwapAddresses: _factorySwapAddresses };
4434
+ };
4435
+ var _estimatedGasForDifferentRoutesCache = {};
4436
+ var _estimateGasForDifferentRoutes = function (routes, inputCoinAddress, outputCoinAddress, _amount) { return __awaiter(void 0, void 0, void 0, function () {
4437
+ var registryExchangeContract, gasPromises, _i, routes_1, route, routeKey, gasPromise, _a, _route, _swapParams, _factorySwapAddresses, _gasAmounts_2, err_3;
4438
+ var _c;
4439
+ return __generator(this, function (_d) {
4440
+ switch (_d.label) {
4441
+ case 0:
4442
+ inputCoinAddress = inputCoinAddress.toLowerCase();
4443
+ outputCoinAddress = outputCoinAddress.toLowerCase();
4444
+ registryExchangeContract = curve_1.curve.contracts[curve_1.ALIASES.registry_exchange].contract;
4445
+ gasPromises = [];
4446
+ for (_i = 0, routes_1 = routes; _i < routes_1.length; _i++) {
4447
+ route = routes_1[_i];
4448
+ routeKey = _getRouteKey(route, inputCoinAddress, outputCoinAddress);
4449
+ gasPromise = void 0;
4450
+ _a = _getExchangeMultipleArgs(inputCoinAddress, route), _route = _a._route, _swapParams = _a._swapParams, _factorySwapAddresses = _a._factorySwapAddresses;
4451
+ if ((((_c = _estimatedGasForDifferentRoutesCache[routeKey]) === null || _c === void 0 ? void 0 : _c.time) || 0) + 3600000 < Date.now()) {
4452
+ gasPromise = registryExchangeContract.estimateGas.exchange_multiple(_route, _swapParams, _amount, 0, _factorySwapAddresses, curve_1.curve.constantOptions);
4453
+ }
4454
+ else {
4455
+ gasPromise = Promise.resolve(_estimatedGasForDifferentRoutesCache[routeKey].gas);
4456
+ }
4457
+ gasPromises.push(gasPromise);
4458
+ }
4459
+ _d.label = 1;
4460
+ case 1:
4461
+ _d.trys.push([1, 3, , 4]);
4462
+ return [4 /*yield*/, Promise.all(gasPromises)];
4463
+ case 2:
4464
+ _gasAmounts_2 = _d.sent();
4465
+ routes.forEach(function (route, i) {
4466
+ var routeKey = _getRouteKey(route, inputCoinAddress, outputCoinAddress);
4467
+ _estimatedGasForDifferentRoutesCache[routeKey] = { 'gas': _gasAmounts_2[i], 'time': Date.now() };
4468
+ });
4469
+ return [2 /*return*/, _gasAmounts_2.map(function (_g) { return Number(ethers_1.ethers.utils.formatUnits(_g, 0)); })];
4470
+ case 3:
4471
+ err_3 = _d.sent();
4472
+ return [2 /*return*/, routes.map(function () { return 0; })];
4473
+ case 4: return [2 /*return*/];
4474
+ }
4475
+ });
4476
+ }); };
4477
+ var _getBestRouteAndOutput = (0, memoizee_1.default)(function (inputCoinAddress, outputCoinAddress, amount) { return __awaiter(void 0, void 0, void 0, function () {
4478
+ var _a, inputCoinDecimals, outputCoinDecimals, _amount, routesRaw, routes, _i, routesRaw_1, route, _outputAmount, _c, _d, routeStep, poolId, poolAddress, i, j, swapType, swapAddress, contract, _e, err_4, _f, gasAmounts, outputCoinUsdRate, gasData, ethUsdRate, gasPrice, expectedAmounts, expectedAmountsUsd, txCostsUsd;
4479
+ return __generator(this, function (_h) {
4480
+ switch (_h.label) {
4481
+ case 0:
4482
+ _a = (0, utils_1._getCoinDecimals)(inputCoinAddress, outputCoinAddress), inputCoinDecimals = _a[0], outputCoinDecimals = _a[1];
4483
+ _amount = ethers_1.ethers.utils.parseUnits(amount.toString(), inputCoinDecimals);
4484
+ return [4 /*yield*/, (0, exports._findAllRoutes)(inputCoinAddress, outputCoinAddress)];
4485
+ case 1:
4486
+ routesRaw = (_h.sent()).map(function (steps) { return ({ steps: steps, _output: ethers_1.ethers.BigNumber.from(0), outputUsd: 0, txCostUsd: 0 }); });
4487
+ routes = [];
4488
+ _i = 0, routesRaw_1 = routesRaw;
4489
+ _h.label = 2;
4490
+ case 2:
4491
+ if (!(_i < routesRaw_1.length)) return [3 /*break*/, 13];
4492
+ route = routesRaw_1[_i];
4493
+ // If one of pools in the route is imbalanced
4494
+ if (route.steps.reduce(function (acc, step) { return acc || IMBALANCED_POOLS.includes(step.poolId); }, false))
4495
+ return [3 /*break*/, 12];
4496
+ _outputAmount = _amount;
4497
+ _c = 0, _d = route.steps;
4498
+ _h.label = 3;
4499
+ case 3:
4500
+ if (!(_c < _d.length)) return [3 /*break*/, 11];
4501
+ routeStep = _d[_c];
4502
+ poolId = routeStep.poolId, poolAddress = routeStep.poolAddress, i = routeStep.i, j = routeStep.j, swapType = routeStep.swapType, swapAddress = routeStep.swapAddress;
4503
+ contract = curve_1.curve.contracts[swapAddress === ethers_1.ethers.constants.AddressZero ? poolAddress : swapAddress].contract;
4504
+ _h.label = 4;
4505
+ case 4:
4506
+ _h.trys.push([4, 9, , 10]);
4507
+ if (![2, 4, 5].includes(swapType)) return [3 /*break*/, 6];
4508
+ return [4 /*yield*/, contract.get_dy_underlying(i, j, _outputAmount, curve_1.curve.constantOptions)];
4509
+ case 5:
4510
+ _e = _h.sent();
4511
+ return [3 /*break*/, 8];
4512
+ case 6: return [4 /*yield*/, contract.get_dy(i, j, _outputAmount, curve_1.curve.constantOptions)];
4513
+ case 7:
4514
+ _e = _h.sent();
4515
+ _h.label = 8;
4516
+ case 8:
4517
+ _outputAmount = _e;
4518
+ return [3 /*break*/, 10];
4519
+ case 9:
4520
+ err_4 = _h.sent();
4521
+ console.log("Pool ".concat(poolId, " is empty or very imbalanced"));
4522
+ IMBALANCED_POOLS.push(poolId);
4523
+ return [3 /*break*/, 12];
4524
+ case 10:
4525
+ _c++;
4526
+ return [3 /*break*/, 3];
4527
+ case 11:
4528
+ route._output = _outputAmount;
4529
+ routes.push(route);
4530
+ _h.label = 12;
4531
+ case 12:
4532
+ _i++;
4533
+ return [3 /*break*/, 2];
4534
+ case 13:
4535
+ if (routes.length === 0) {
4536
+ return [2 /*return*/, {
4537
+ steps: [],
4538
+ _output: ethers_1.ethers.BigNumber.from(0),
4539
+ outputUsd: 0,
4540
+ txCostUsd: 0,
4541
+ }];
4542
+ }
4543
+ if (routes.length === 1)
4544
+ return [2 /*return*/, routes[0]];
4545
+ return [4 /*yield*/, Promise.all([
4546
+ _estimateGasForDifferentRoutes(routes, inputCoinAddress, outputCoinAddress, _amount),
4547
+ (0, utils_1._getUsdRate)(outputCoinAddress),
4548
+ axios_1.default.get("https://api.curve.fi/api/getGas"),
4549
+ (0, utils_1._getUsdRate)(curve_1.curve.chainId === 137 ? curve_1.COINS.matic : curve_1.COINS.eth),
4550
+ ])];
4551
+ case 14:
4552
+ _f = _h.sent(), gasAmounts = _f[0], outputCoinUsdRate = _f[1], gasData = _f[2], ethUsdRate = _f[3];
4553
+ gasPrice = gasData.data.data.gas.standard;
4554
+ expectedAmounts = (routes).map(function (route) { return Number(ethers_1.ethers.utils.formatUnits(route._output, outputCoinDecimals)); });
4555
+ expectedAmountsUsd = expectedAmounts.map(function (a) { return a * outputCoinUsdRate; });
4556
+ txCostsUsd = gasAmounts.map(function (a) { return ethUsdRate * a * gasPrice / 1e18; });
4557
+ routes.forEach(function (route, i) {
4558
+ route.outputUsd = expectedAmountsUsd[i];
4559
+ route.txCostUsd = txCostsUsd[i];
4560
+ });
4561
+ return [2 /*return*/, routes.reduce(function (route1, route2) { return (route1.outputUsd - route1.txCostUsd) - (route2.outputUsd - route2.txCostUsd) >= 0 ? route1 : route2; })];
4562
+ }
4563
+ });
4564
+ }); }, {
4565
+ promise: true,
4566
+ maxAge: 5 * 60 * 1000, // 5m
4567
+ });
4568
+ var getBestRouteAndOutput = function (inputCoin, outputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
4569
+ var _a, inputCoinAddress, outputCoinAddress, outputCoinDecimals, _c, steps, _output;
4570
+ return __generator(this, function (_d) {
4571
+ switch (_d.label) {
4572
+ case 0:
4573
+ _a = (0, utils_1._getCoinAddresses)(inputCoin, outputCoin), inputCoinAddress = _a[0], outputCoinAddress = _a[1];
4574
+ outputCoinDecimals = (0, utils_1._getCoinDecimals)(outputCoinAddress)[0];
4575
+ return [4 /*yield*/, _getBestRouteAndOutput(inputCoinAddress, outputCoinAddress, amount)];
4576
+ case 1:
4577
+ _c = _d.sent(), steps = _c.steps, _output = _c._output;
4578
+ return [2 /*return*/, { route: steps, output: ethers_1.ethers.utils.formatUnits(_output, outputCoinDecimals) }];
4579
+ }
4580
+ });
4581
+ }); };
4582
+ exports.getBestRouteAndOutput = getBestRouteAndOutput;
4583
+ var routerExchangeExpected = function (inputCoin, outputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
4584
+ return __generator(this, function (_a) {
4585
+ switch (_a.label) {
4586
+ case 0: return [4 /*yield*/, (0, exports.getBestRouteAndOutput)(inputCoin, outputCoin, amount)];
4587
+ case 1: return [2 /*return*/, (_a.sent())['output']];
4588
+ }
4589
+ });
4590
+ }); };
4591
+ exports.routerExchangeExpected = routerExchangeExpected;
4592
+ var routerExchangeIsApproved = function (inputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
4593
+ return __generator(this, function (_a) {
4594
+ switch (_a.label) {
4595
+ case 0: return [4 /*yield*/, (0, utils_1.hasAllowance)([inputCoin], [amount], curve_1.curve.signerAddress, curve_1.ALIASES.registry_exchange)];
4596
+ case 1: return [2 /*return*/, _a.sent()];
4597
+ }
4598
+ });
4599
+ }); };
4600
+ exports.routerExchangeIsApproved = routerExchangeIsApproved;
4601
+ var routerExchangeApproveEstimateGas = function (inputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
4602
+ return __generator(this, function (_a) {
4603
+ switch (_a.label) {
4604
+ case 0: return [4 /*yield*/, (0, utils_1.ensureAllowanceEstimateGas)([inputCoin], [amount], curve_1.ALIASES.registry_exchange)];
4605
+ case 1: return [2 /*return*/, _a.sent()];
4606
+ }
4607
+ });
4608
+ }); };
4609
+ exports.routerExchangeApproveEstimateGas = routerExchangeApproveEstimateGas;
4610
+ var routerExchangeApprove = function (inputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
4611
+ return __generator(this, function (_a) {
4612
+ switch (_a.label) {
4613
+ case 0: return [4 /*yield*/, (0, utils_1.ensureAllowance)([inputCoin], [amount], curve_1.ALIASES.registry_exchange)];
4614
+ case 1: return [2 /*return*/, _a.sent()];
4615
+ }
4616
+ });
4617
+ }); };
4618
+ exports.routerExchangeApprove = routerExchangeApprove;
4619
+ var routerExchangeEstimateGas = function (inputCoin, outputCoin, amount, maxSlippage) {
4620
+ if (maxSlippage === void 0) { maxSlippage = 0.01; }
4621
+ return __awaiter(void 0, void 0, void 0, function () {
4622
+ var _a, inputCoinAddress, outputCoinAddress, _c, inputCoinDecimals, outputCoinDecimals, route, _d, _route, _swapParams, _factorySwapAddresses, _amount, minRecvAmountBN, _minRecvAmount, contract, value;
4623
+ return __generator(this, function (_e) {
4624
+ switch (_e.label) {
4625
+ case 0:
4626
+ _a = (0, utils_1._getCoinAddresses)(inputCoin, outputCoin), inputCoinAddress = _a[0], outputCoinAddress = _a[1];
4627
+ _c = (0, utils_1._getCoinDecimals)(inputCoinAddress, outputCoinAddress), inputCoinDecimals = _c[0], outputCoinDecimals = _c[1];
4628
+ return [4 /*yield*/, _getBestRouteAndOutput(inputCoinAddress, outputCoinAddress, amount)];
4629
+ case 1:
4630
+ route = _e.sent();
4631
+ if (route.steps.length === 0) {
4632
+ throw new Error("This pair can't be exchanged");
4633
+ }
4634
+ _d = _getExchangeMultipleArgs(inputCoinAddress, route), _route = _d._route, _swapParams = _d._swapParams, _factorySwapAddresses = _d._factorySwapAddresses;
4635
+ _amount = ethers_1.ethers.utils.parseUnits(amount, inputCoinDecimals);
4636
+ minRecvAmountBN = (0, utils_1.toBN)(route._output, outputCoinDecimals).times(1 - maxSlippage);
4637
+ _minRecvAmount = (0, utils_1.fromBN)(minRecvAmountBN, outputCoinDecimals);
4638
+ contract = curve_1.curve.contracts[curve_1.ALIASES.registry_exchange].contract;
4639
+ value = (0, utils_1.isEth)(inputCoinAddress) ? _amount : ethers_1.ethers.BigNumber.from(0);
4640
+ return [4 /*yield*/, curve_1.curve.updateFeeData()];
4641
+ case 2:
4642
+ _e.sent();
4643
+ return [4 /*yield*/, contract.estimateGas.exchange_multiple(_route, _swapParams, _amount, _minRecvAmount, _factorySwapAddresses, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
4644
+ case 3: return [2 /*return*/, (_e.sent()).toNumber()];
4645
+ }
4646
+ });
4647
+ });
4648
+ };
4649
+ exports.routerExchangeEstimateGas = routerExchangeEstimateGas;
4650
+ var routerExchange = function (inputCoin, outputCoin, amount, maxSlippage) {
4651
+ if (maxSlippage === void 0) { maxSlippage = 0.01; }
4652
+ return __awaiter(void 0, void 0, void 0, function () {
4653
+ var _a, inputCoinAddress, outputCoinAddress, _c, inputCoinDecimals, outputCoinDecimals, route, _d, _route, _swapParams, _factorySwapAddresses, _amount, minRecvAmountBN, _minRecvAmount, contract, value, gasLimit;
4654
+ return __generator(this, function (_e) {
4655
+ switch (_e.label) {
4656
+ case 0:
4657
+ _a = (0, utils_1._getCoinAddresses)(inputCoin, outputCoin), inputCoinAddress = _a[0], outputCoinAddress = _a[1];
4658
+ _c = (0, utils_1._getCoinDecimals)(inputCoinAddress, outputCoinAddress), inputCoinDecimals = _c[0], outputCoinDecimals = _c[1];
4659
+ return [4 /*yield*/, (0, utils_1.ensureAllowance)([inputCoin], [amount], curve_1.ALIASES.registry_exchange)];
4660
+ case 1:
4661
+ _e.sent();
4662
+ return [4 /*yield*/, _getBestRouteAndOutput(inputCoinAddress, outputCoinAddress, amount)];
4663
+ case 2:
4664
+ route = _e.sent();
4665
+ if (route.steps.length === 0) {
4666
+ throw new Error("This pair can't be exchanged");
4667
+ }
4668
+ _d = _getExchangeMultipleArgs(inputCoinAddress, route), _route = _d._route, _swapParams = _d._swapParams, _factorySwapAddresses = _d._factorySwapAddresses;
4669
+ _amount = ethers_1.ethers.utils.parseUnits(amount, inputCoinDecimals);
4670
+ minRecvAmountBN = (0, utils_1.toBN)(route._output, outputCoinDecimals).times(1 - maxSlippage);
4671
+ _minRecvAmount = (0, utils_1.fromBN)(minRecvAmountBN, outputCoinDecimals);
4672
+ contract = curve_1.curve.contracts[curve_1.ALIASES.registry_exchange].contract;
4673
+ value = (0, utils_1.isEth)(inputCoinAddress) ? _amount : ethers_1.ethers.BigNumber.from(0);
4674
+ return [4 /*yield*/, curve_1.curve.updateFeeData()];
4675
+ case 3:
4676
+ _e.sent();
4677
+ return [4 /*yield*/, contract.estimateGas.exchange_multiple(_route, _swapParams, _amount, _minRecvAmount, _factorySwapAddresses, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
4678
+ case 4:
4679
+ gasLimit = (_e.sent()).mul(130).div(100);
4680
+ return [4 /*yield*/, contract.exchange_multiple(_route, _swapParams, _amount, _minRecvAmount, _factorySwapAddresses, __assign(__assign({}, curve_1.curve.options), { value: value, gasLimit: gasLimit }))];
4681
+ case 5: return [2 /*return*/, (_e.sent()).hash];
4682
+ }
4683
+ });
4684
+ });
4685
+ };
4686
+ exports.routerExchange = routerExchange;