@curvefi/api 2.46.7 → 2.47.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/router.js CHANGED
@@ -61,49 +61,36 @@ import { curve } from "./curve.js";
61
61
  import { _getCoinAddresses, _getCoinDecimals, _getUsdRate, ensureAllowance, ensureAllowanceEstimateGas, fromBN, hasAllowance, isEth, toBN, BN, parseUnits, _cutZeros, ETH_ADDRESS, _get_small_x, _get_price_impact, } from "./utils.js";
62
62
  import { getPool } from "./pools/index.js";
63
63
  import { _getAmplificationCoefficientsFromApi } from "./pools/utils.js";
64
- var getNewRoute = function (routeTvl, poolId, poolAddress, inputCoinAddress, outputCoinAddress, i, j, swapType, swapAddress, tvl) {
65
- var routePoolIds = routeTvl.route.map(function (s) { return s.poolId; });
66
- // Steps <= 4
67
- if (routePoolIds.length >= 4)
64
+ var MAX_STEPS = 5;
65
+ var ROUTE_LENGTH = (MAX_STEPS * 2) + 1;
66
+ // 4 --> 6, 5 --> 7 not allowed
67
+ // 4 --> 7, 5 --> 6 allowed
68
+ var _handleSwapType = function (swapType) {
69
+ if (swapType === 6)
70
+ return "4";
71
+ if (swapType === 7)
72
+ return "5";
73
+ return swapType.toString();
74
+ };
75
+ var _getNewRoute = function (routeTvl, poolId, swapAddress, inputCoinAddress, outputCoinAddress, swapParams, // i, j, swap_type, pool_type, n_coins
76
+ poolAddress, basePool, baseToken, secondBasePool, secondBaseToken, tvl) {
77
+ var routePoolIdsPlusSwapType = routeTvl.route.map(function (s) { return s.poolId + "+" + _handleSwapType(s.swapParams[2]); });
78
+ // Steps <= MAX_STEPS
79
+ if (routePoolIdsPlusSwapType.length >= MAX_STEPS)
68
80
  return { route: [], minTvl: Infinity, totalTvl: 0 };
69
81
  // Exclude such cases as cvxeth -> tricrypto2 -> tricrypto2 -> susd
70
- if (routePoolIds.includes(poolId))
82
+ if (routePoolIdsPlusSwapType.includes(poolId + "+" + _handleSwapType(swapParams[2])))
71
83
  return { route: [], minTvl: Infinity, totalTvl: 0 };
72
84
  return {
73
- route: __spreadArray(__spreadArray([], routeTvl.route, true), [{ poolId: poolId, poolAddress: poolAddress, inputCoinAddress: inputCoinAddress, outputCoinAddress: outputCoinAddress, i: i, j: j, swapType: swapType, swapAddress: swapAddress }], false),
85
+ route: __spreadArray(__spreadArray([], routeTvl.route, true), [
86
+ { poolId: poolId, swapAddress: swapAddress, inputCoinAddress: inputCoinAddress, outputCoinAddress: outputCoinAddress, swapParams: swapParams, poolAddress: poolAddress, basePool: basePool, baseToken: baseToken, secondBasePool: secondBasePool, secondBaseToken: secondBaseToken },
87
+ ], false),
74
88
  minTvl: Math.min(tvl, routeTvl.minTvl),
75
89
  totalTvl: routeTvl.totalTvl + tvl,
76
90
  };
77
91
  };
78
- // TODO REMOVE IT!!!
79
- var filterMaticFactory83Route = function (routes) {
80
- return routes.filter(function (r) {
81
- for (var _i = 0, _a = r.route; _i < _a.length; _i++) {
82
- var step = _a[_i];
83
- if (step.poolId === "factory-crypto-83" && step.inputCoinAddress === curve.constants.NATIVE_TOKEN.address)
84
- return false;
85
- }
86
- return true;
87
- });
88
- };
89
- // TODO REMOVE IT!!!
90
- var filterAvax = function (routes) {
91
- return routes.filter(function (r) {
92
- for (var _i = 0, _a = r.route; _i < _a.length; _i++) {
93
- var step = _a[_i];
94
- if (step.poolId == 'avaxcrypto' && step.swapType == 4 && (step.i === 3 || step.j === 3))
95
- return false;
96
- }
97
- return true;
98
- });
99
- };
100
92
  var MAX_ROUTES_FOR_ONE_COIN = 3;
101
- var filterRoutes = function (routes, inputCoinAddress, sortFn) {
102
- // TODO REMOVE IT!!!
103
- if (curve.chainId === 137)
104
- routes = filterMaticFactory83Route(routes);
105
- if (curve.chainId === 43114)
106
- routes = filterAvax(routes);
93
+ var _filterRoutes = function (routes, inputCoinAddress, sortFn) {
107
94
  return routes
108
95
  .filter(function (r) { return r.route.length > 0; })
109
96
  .filter(function (r) { return r.route[0].inputCoinAddress === inputCoinAddress; }) // Truncated routes
@@ -113,8 +100,22 @@ var filterRoutes = function (routes, inputCoinAddress, sortFn) {
113
100
  }) // Route duplications
114
101
  .sort(sortFn).slice(0, MAX_ROUTES_FOR_ONE_COIN);
115
102
  };
116
- var sortByTvl = function (a, b) { return b.minTvl - a.minTvl || b.totalTvl - a.totalTvl || a.route.length - b.route.length; };
117
- var sortByLength = function (a, b) { return a.route.length - b.route.length || b.minTvl - a.minTvl || b.totalTvl - a.totalTvl; };
103
+ var _sortByTvl = function (a, b) { return b.minTvl - a.minTvl || b.totalTvl - a.totalTvl || a.route.length - b.route.length; };
104
+ var _sortByLength = function (a, b) { return a.route.length - b.route.length || b.minTvl - a.minTvl || b.totalTvl - a.totalTvl; };
105
+ var _updateRoutes = function (inputCoinAddress, routesByTvl, routesByLength, poolId, swapAddress, inCoin, outCoin, swapParams, // i, j, swap_type, pool_type, n_coins
106
+ poolAddress, basePool, baseToken, secondBasePool, secondBaseToken, tvl) {
107
+ var _a, _b;
108
+ var newRoutesByTvl = routesByTvl[inCoin].map(function (route) {
109
+ return _getNewRoute(route, poolId, swapAddress, inCoin, outCoin, swapParams, poolAddress, basePool, baseToken, secondBasePool, secondBaseToken, tvl);
110
+ });
111
+ var newRoutesByLength = routesByLength[inCoin].map(function (route) {
112
+ return _getNewRoute(route, poolId, swapAddress, inCoin, outCoin, swapParams, poolAddress, basePool, baseToken, secondBasePool, secondBaseToken, tvl);
113
+ });
114
+ routesByTvl[outCoin] = __spreadArray(__spreadArray([], ((_a = routesByTvl[outCoin]) !== null && _a !== void 0 ? _a : []), true), newRoutesByTvl, true);
115
+ routesByTvl[outCoin] = _filterRoutes(routesByTvl[outCoin], inputCoinAddress, _sortByTvl);
116
+ routesByLength[outCoin] = __spreadArray(__spreadArray([], ((_b = routesByLength[outCoin]) !== null && _b !== void 0 ? _b : []), true), newRoutesByLength, true);
117
+ routesByLength[outCoin] = _filterRoutes(routesByLength[outCoin], inputCoinAddress, _sortByLength);
118
+ };
118
119
  var _getTVL = memoize(function (poolId) { return __awaiter(void 0, void 0, void 0, function () { var _a; return __generator(this, function (_b) {
119
120
  switch (_b.label) {
120
121
  case 0:
@@ -126,11 +127,31 @@ var _getTVL = memoize(function (poolId) { return __awaiter(void 0, void 0, void
126
127
  promise: true,
127
128
  maxAge: 5 * 60 * 1000, // 5m
128
129
  });
130
+ var SNX = {
131
+ 1: {
132
+ swap: "0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F".toLowerCase(),
133
+ coins: [
134
+ "0x57Ab1ec28D129707052df4dF418D58a2D46d5f51",
135
+ "0xD71eCFF9342A5Ced620049e616c5035F1dB98620",
136
+ "0x5e74C9036fb86BD7eCdcb084a0673EFc32eA31cb",
137
+ "0xfE18be6b3Bd88A2D2A7f928d00292E7a9963CfC6", // sBTC
138
+ ].map(function (a) { return a.toLowerCase(); }),
139
+ },
140
+ 10: {
141
+ swap: "0x8700dAec35aF8Ff88c16BdF0418774CB3D7599B4".toLowerCase(),
142
+ coins: [
143
+ "0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9",
144
+ "0xFBc4198702E81aE77c06D58f81b629BDf36f0a71",
145
+ "0xe405de8f52ba7559f9df3c368500b6e6ae6cee49",
146
+ "0x298b9b95708152ff6968aafd889c6586e9169f1d", // sBTC
147
+ ].map(function (a) { return a.toLowerCase(); }),
148
+ },
149
+ };
129
150
  // Inspired by Dijkstra's algorithm
130
151
  var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __awaiter(void 0, void 0, void 0, function () {
131
- var ALL_POOLS, amplificationCoefficientDict, curCoins, nextCoins, routesByTvl, routesByLength, step, _loop_1, _i, curCoins_1, inCoin, routes;
132
- var _a, _b;
133
- var _c, _d, _e, _f, _h, _j, _k, _l, _m, _o, _p, _q, _r;
152
+ var ALL_POOLS, amplificationCoefficientDict, curCoins, nextCoins, routesByTvl, routesByLength, step, _i, curCoins_1, inCoin, outCoin, _a, _b, outCoin, outCoin, outCoin, _c, _d, outCoin, _e, ALL_POOLS_1, _f, poolId, poolData, wrapped_coin_addresses, underlying_coin_addresses, pool_address, token_address, is_aave_like_lending, pool_type, tvl_multiplier, base_pool, base_pool_address, base_token_address, second_base_pool, second_base_pool_address, second_base_token_address, meta_coin_addresses, swap_address, inCoinIndexes, tvl, j, outputCoinIdx, j, outputCoinIdx, swapType, swapType, j, outputCoinIdx, j, outputCoinIdx, hasEth, swapType, routes;
153
+ var _h, _j;
154
+ var _k, _l, _m, _o, _p, _q, _r;
134
155
  return __generator(this, function (_s) {
135
156
  switch (_s.label) {
136
157
  case 0:
@@ -145,212 +166,205 @@ var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __a
145
166
  amplificationCoefficientDict = _s.sent();
146
167
  curCoins = [inputCoinAddress];
147
168
  nextCoins = new Set();
148
- routesByTvl = (_a = {},
149
- _a[inputCoinAddress] = [{ route: [], minTvl: Infinity, totalTvl: 0 }],
150
- _a);
151
- routesByLength = (_b = {},
152
- _b[inputCoinAddress] = [{ route: [], minTvl: Infinity, totalTvl: 0 }],
153
- _b);
169
+ routesByTvl = (_h = {},
170
+ _h[inputCoinAddress] = [{ route: [], minTvl: Infinity, totalTvl: 0 }],
171
+ _h);
172
+ routesByLength = (_j = {},
173
+ _j[inputCoinAddress] = [{ route: [], minTvl: Infinity, totalTvl: 0 }],
174
+ _j);
154
175
  step = 0;
155
176
  _s.label = 2;
156
177
  case 2:
157
- if (!(step < 4)) return [3 /*break*/, 8];
158
- _loop_1 = function (inCoin) {
159
- var outCoin_1, newRoutesByTvl, newRoutesByLength, _loop_2, _t, ALL_POOLS_1, _u, poolId, poolData;
160
- return __generator(this, function (_v) {
161
- switch (_v.label) {
162
- case 0:
163
- if (curve.chainId !== 42220 && [curve.constants.NATIVE_TOKEN.address, curve.constants.NATIVE_TOKEN.wrappedAddress].includes(inCoin)) { // Exclude Celo
164
- outCoin_1 = inCoin === curve.constants.NATIVE_TOKEN.address ? curve.constants.NATIVE_TOKEN.wrappedAddress : curve.constants.NATIVE_TOKEN.address;
165
- newRoutesByTvl = routesByTvl[inCoin].map(function (route) { return getNewRoute(route, "wrapper", curve.constants.NATIVE_TOKEN.wrappedAddress, inCoin, outCoin_1, 0, 0, 15, curve.constants.ZERO_ADDRESS, Infinity); });
166
- newRoutesByLength = routesByLength[inCoin].map(function (route) { return getNewRoute(route, "wrapper", curve.constants.NATIVE_TOKEN.wrappedAddress, inCoin, outCoin_1, 0, 0, 15, curve.constants.ZERO_ADDRESS, Infinity); });
167
- routesByTvl[outCoin_1] = __spreadArray(__spreadArray([], ((_c = routesByTvl[outCoin_1]) !== null && _c !== void 0 ? _c : []), true), newRoutesByTvl, true);
168
- routesByTvl[outCoin_1] = filterRoutes(routesByTvl[outCoin_1], inputCoinAddress, sortByTvl);
169
- routesByLength[outCoin_1] = __spreadArray(__spreadArray([], ((_d = routesByLength[outCoin_1]) !== null && _d !== void 0 ? _d : []), true), newRoutesByLength, true);
170
- routesByLength[outCoin_1] = filterRoutes(routesByLength[outCoin_1], inputCoinAddress, sortByLength);
171
- nextCoins.add(outCoin_1);
172
- }
173
- _loop_2 = function (poolId, poolData) {
174
- var wrapped_coin_addresses, underlying_coin_addresses, base_pool, meta_coin_addresses, token_address, is_aave_like_lending, tvlMultiplier, inCoinIndexes, tvl, _w, poolAddress, coin_addresses, _loop_3, j, inCoinIndex, swapType_1, newRoutesByTvl, newRoutesByLength, _loop_4, j, _loop_5, j;
175
- return __generator(this, function (_x) {
176
- switch (_x.label) {
177
- case 0:
178
- wrapped_coin_addresses = poolData.wrapped_coin_addresses.map(function (a) { return a.toLowerCase(); });
179
- underlying_coin_addresses = poolData.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); });
180
- base_pool = poolData.is_meta ? __assign(__assign({}, curve.constants.POOLS_DATA), curve.constants.FACTORY_POOLS_DATA)[poolData.base_pool] : null;
181
- meta_coin_addresses = base_pool ? base_pool.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); }) : [];
182
- token_address = poolData.token_address.toLowerCase();
183
- is_aave_like_lending = poolData.is_lending && wrapped_coin_addresses.length === 3 && !poolData.deposit_address;
184
- tvlMultiplier = poolData.is_crypto ? 1 : ((_e = amplificationCoefficientDict[poolData.swap_address]) !== null && _e !== void 0 ? _e : 1);
185
- inCoinIndexes = {
186
- wrapped_coin: wrapped_coin_addresses.indexOf(inCoin),
187
- underlying_coin: underlying_coin_addresses.indexOf(inCoin),
188
- meta_coin: meta_coin_addresses ? meta_coin_addresses.indexOf(inCoin) : -1,
189
- };
190
- // Skip pools which don't contain inCoin
191
- if (inCoinIndexes.wrapped_coin === -1 && inCoinIndexes.underlying_coin === -1 && inCoinIndexes.meta_coin === -1 && inCoin !== token_address)
192
- return [2 /*return*/, "continue"];
193
- if (!poolId.startsWith('factory-crvusd-')) return [3 /*break*/, 1];
194
- _w = 500000 * 100;
195
- return [3 /*break*/, 3];
196
- case 1: return [4 /*yield*/, _getTVL(poolId)];
197
- case 2:
198
- _w = (_x.sent()) * tvlMultiplier;
199
- _x.label = 3;
200
- case 3:
201
- tvl = _w;
202
- // Skip empty pools
203
- if (tvl === 0)
204
- return [2 /*return*/, "continue"];
205
- poolAddress = poolData.is_fake ? poolData.deposit_address : poolData.swap_address;
206
- coin_addresses = (is_aave_like_lending || poolData.is_fake) ? underlying_coin_addresses : wrapped_coin_addresses;
207
- // LP -> wrapped coin (underlying for lending or fake pool) "swaps" (actually remove_liquidity_one_coin)
208
- if (coin_addresses.length < 6 && inCoin === token_address) {
209
- _loop_3 = function (j) {
210
- // Looking for outputCoinAddress only on the final step
211
- if (step === 3 && coin_addresses[j] !== outputCoinAddress)
212
- return "continue";
213
- // Exclude such cases as cvxeth -> tricrypto2 -> tusd -> susd or cvxeth -> tricrypto2 -> susd -> susd
214
- var outputCoinIdx = coin_addresses.indexOf(outputCoinAddress);
215
- if (outputCoinIdx >= 0 && j !== outputCoinIdx)
216
- return "continue";
217
- var swapType = poolData.is_crypto ? 14 : is_aave_like_lending ? 13 : 12;
218
- var newRoutesByTvl = routesByTvl[inCoin].map(function (route) { return getNewRoute(route, poolId, poolAddress, inCoin, coin_addresses[j], 0, j, swapType, curve.constants.ZERO_ADDRESS, tvl); });
219
- var newRoutesByLength = routesByLength[inCoin].map(function (route) { return getNewRoute(route, poolId, poolAddress, inCoin, coin_addresses[j], 0, j, swapType, curve.constants.ZERO_ADDRESS, tvl); });
220
- routesByTvl[coin_addresses[j]] = __spreadArray(__spreadArray([], ((_f = routesByTvl[coin_addresses[j]]) !== null && _f !== void 0 ? _f : []), true), newRoutesByTvl, true);
221
- routesByTvl[coin_addresses[j]] = filterRoutes(routesByTvl[coin_addresses[j]], inputCoinAddress, sortByTvl);
222
- routesByLength[coin_addresses[j]] = __spreadArray(__spreadArray([], ((_h = routesByLength[coin_addresses[j]]) !== null && _h !== void 0 ? _h : []), true), newRoutesByLength, true);
223
- routesByLength[coin_addresses[j]] = filterRoutes(routesByLength[coin_addresses[j]], inputCoinAddress, sortByLength);
224
- nextCoins.add(coin_addresses[j]);
225
- };
226
- for (j = 0; j < coin_addresses.length; j++) {
227
- _loop_3(j);
228
- }
229
- }
230
- inCoinIndex = (is_aave_like_lending || poolData.is_fake) ? inCoinIndexes.underlying_coin : inCoinIndexes.wrapped_coin;
231
- if (coin_addresses.length < 6 && inCoinIndex >= 0 && !poolData.is_llamma) {
232
- // Looking for outputCoinAddress only on the final step
233
- if (!(step === 3 && token_address !== outputCoinAddress)) {
234
- swapType_1 = is_aave_like_lending ? 9
235
- : coin_addresses.length === 2 ? 7
236
- : coin_addresses.length === 3 ? 8
237
- : coin_addresses.length === 4 ? 10 : 11;
238
- newRoutesByTvl = routesByTvl[inCoin].map(function (route) { return getNewRoute(route, poolId, poolAddress, inCoin, token_address, coin_addresses.indexOf(inCoin), 0, swapType_1, curve.constants.ZERO_ADDRESS, tvl); });
239
- newRoutesByLength = routesByLength[inCoin].map(function (route) { return getNewRoute(route, poolId, poolAddress, inCoin, token_address, coin_addresses.indexOf(inCoin), 0, swapType_1, curve.constants.ZERO_ADDRESS, tvl); });
240
- routesByTvl[token_address] = __spreadArray(__spreadArray([], ((_j = routesByTvl[token_address]) !== null && _j !== void 0 ? _j : []), true), newRoutesByTvl, true);
241
- routesByTvl[token_address] = filterRoutes(routesByTvl[token_address], inputCoinAddress, sortByTvl);
242
- routesByLength[token_address] = __spreadArray(__spreadArray([], ((_k = routesByLength[token_address]) !== null && _k !== void 0 ? _k : []), true), newRoutesByLength, true);
243
- routesByLength[token_address] = filterRoutes(routesByLength[token_address], inputCoinAddress, sortByLength);
244
- nextCoins.add(token_address);
245
- }
246
- }
247
- // Wrapped swaps
248
- if (inCoinIndexes.wrapped_coin >= 0 && !poolData.is_fake) {
249
- _loop_4 = function (j) {
250
- if (j === inCoinIndexes.wrapped_coin)
251
- return "continue";
252
- // Native swaps spend less gas
253
- // TODO uncomment
254
- // if (wrapped_coin_addresses[j] !== outputCoinAddress && wrapped_coin_addresses[j] === curve.constants.NATIVE_TOKEN.wrappedAddress) continue;
255
- // Looking for outputCoinAddress only on the final step
256
- if (step === 3 && wrapped_coin_addresses[j] !== outputCoinAddress)
257
- return "continue";
258
- // Exclude such cases as cvxeth -> tricrypto2 -> tusd -> susd or cvxeth -> tricrypto2 -> susd -> susd
259
- var outputCoinIdx = wrapped_coin_addresses.indexOf(outputCoinAddress);
260
- if (outputCoinIdx >= 0 && j !== outputCoinIdx)
261
- return "continue";
262
- var swapType = poolData.is_crypto ? 3 : 1;
263
- var newRoutesByTvl = routesByTvl[inCoin].map(function (route) { return getNewRoute(route, poolId, poolData.swap_address, inCoin, wrapped_coin_addresses[j], inCoinIndexes.wrapped_coin, j, swapType, curve.constants.ZERO_ADDRESS, tvl); });
264
- var newRoutesByLength = routesByLength[inCoin].map(function (route) { return getNewRoute(route, poolId, poolData.swap_address, inCoin, wrapped_coin_addresses[j], inCoinIndexes.wrapped_coin, j, swapType, curve.constants.ZERO_ADDRESS, tvl); });
265
- routesByTvl[wrapped_coin_addresses[j]] = __spreadArray(__spreadArray([], ((_l = routesByTvl[wrapped_coin_addresses[j]]) !== null && _l !== void 0 ? _l : []), true), newRoutesByTvl, true);
266
- routesByTvl[wrapped_coin_addresses[j]] = filterRoutes(routesByTvl[wrapped_coin_addresses[j]], inputCoinAddress, sortByTvl);
267
- routesByLength[wrapped_coin_addresses[j]] = __spreadArray(__spreadArray([], ((_m = routesByLength[wrapped_coin_addresses[j]]) !== null && _m !== void 0 ? _m : []), true), newRoutesByLength, true);
268
- routesByLength[wrapped_coin_addresses[j]] = filterRoutes(routesByLength[wrapped_coin_addresses[j]], inputCoinAddress, sortByLength);
269
- nextCoins.add(wrapped_coin_addresses[j]);
270
- };
271
- for (j = 0; j < wrapped_coin_addresses.length; j++) {
272
- _loop_4(j);
273
- }
274
- }
275
- // Only for underlying swaps
276
- poolAddress = (poolData.is_crypto && poolData.is_meta) || ((base_pool === null || base_pool === void 0 ? void 0 : base_pool.is_lending) && poolData.is_factory) ?
277
- poolData.deposit_address : poolData.swap_address;
278
- // Underlying swaps
279
- if (!poolData.is_plain && inCoinIndexes.underlying_coin >= 0) {
280
- _loop_5 = function (j) {
281
- if (j === inCoinIndexes.underlying_coin)
282
- return "continue";
283
- // Don't swap metacoins since they can be swapped directly in base pool
284
- if (inCoinIndexes.meta_coin >= 0 && meta_coin_addresses.includes(underlying_coin_addresses[j]))
285
- return "continue";
286
- // Looking for outputCoinAddress only on the final step
287
- if (step === 3 && underlying_coin_addresses[j] !== outputCoinAddress)
288
- return "continue";
289
- // Exclude such cases as cvxeth -> tricrypto2 -> tusd -> susd or cvxeth -> tricrypto2 -> susd -> susd
290
- var outputCoinIdx = underlying_coin_addresses.indexOf(outputCoinAddress);
291
- if (outputCoinIdx >= 0 && j !== outputCoinIdx)
292
- return "continue";
293
- // Skip empty pools
294
- if (tvl === 0)
295
- return "continue";
296
- var hasEth = (inCoin === curve.constants.NATIVE_TOKEN.address || underlying_coin_addresses[j] === curve.constants.NATIVE_TOKEN.address);
297
- var swapType = (poolData.is_crypto && poolData.is_meta && poolData.is_factory) ? 6
298
- : ((base_pool === null || base_pool === void 0 ? void 0 : base_pool.is_lending) && poolData.is_factory) ? 5
299
- : hasEth && poolId !== 'avaxcrypto' ? 3
300
- : poolData.is_crypto ? 4
301
- : 2;
302
- var newRoutesByTvl = routesByTvl[inCoin].map(function (route) { return getNewRoute(route, poolId, poolAddress, inCoin, underlying_coin_addresses[j], inCoinIndexes.underlying_coin, j, swapType, (swapType === 5 || swapType === 6) ? poolData.swap_address : curve.constants.ZERO_ADDRESS, tvl); });
303
- var newRoutesByLength = routesByLength[inCoin].map(function (route) { return getNewRoute(route, poolId, poolAddress, inCoin, underlying_coin_addresses[j], inCoinIndexes.underlying_coin, j, swapType, (swapType === 5 || swapType === 6) ? poolData.swap_address : curve.constants.ZERO_ADDRESS, tvl); });
304
- routesByTvl[underlying_coin_addresses[j]] = __spreadArray(__spreadArray([], ((_o = routesByTvl[underlying_coin_addresses[j]]) !== null && _o !== void 0 ? _o : []), true), newRoutesByTvl, true);
305
- routesByTvl[underlying_coin_addresses[j]] = filterRoutes(routesByTvl[underlying_coin_addresses[j]], inputCoinAddress, sortByTvl);
306
- routesByLength[underlying_coin_addresses[j]] = __spreadArray(__spreadArray([], ((_p = routesByLength[underlying_coin_addresses[j]]) !== null && _p !== void 0 ? _p : []), true), newRoutesByLength, true);
307
- routesByLength[underlying_coin_addresses[j]] = filterRoutes(routesByLength[underlying_coin_addresses[j]], inputCoinAddress, sortByLength);
308
- nextCoins.add(underlying_coin_addresses[j]);
309
- };
310
- for (j = 0; j < underlying_coin_addresses.length; j++) {
311
- _loop_5(j);
312
- }
313
- }
314
- return [2 /*return*/];
315
- }
316
- });
317
- };
318
- _t = 0, ALL_POOLS_1 = ALL_POOLS;
319
- _v.label = 1;
320
- case 1:
321
- if (!(_t < ALL_POOLS_1.length)) return [3 /*break*/, 4];
322
- _u = ALL_POOLS_1[_t], poolId = _u[0], poolData = _u[1];
323
- return [5 /*yield**/, _loop_2(poolId, poolData)];
324
- case 2:
325
- _v.sent();
326
- _v.label = 3;
327
- case 3:
328
- _t++;
329
- return [3 /*break*/, 1];
330
- case 4: return [2 /*return*/];
331
- }
332
- });
333
- };
178
+ if (!(step < MAX_STEPS)) return [3 /*break*/, 10];
334
179
  _i = 0, curCoins_1 = curCoins;
335
180
  _s.label = 3;
336
181
  case 3:
337
- if (!(_i < curCoins_1.length)) return [3 /*break*/, 6];
182
+ if (!(_i < curCoins_1.length)) return [3 /*break*/, 8];
338
183
  inCoin = curCoins_1[_i];
339
- return [5 /*yield**/, _loop_1(inCoin)];
184
+ // ETH <-> WETH (exclude Celo)
185
+ if (curve.chainId !== 42220 && [curve.constants.NATIVE_TOKEN.address, curve.constants.NATIVE_TOKEN.wrappedAddress].includes(inCoin)) {
186
+ outCoin = inCoin === curve.constants.NATIVE_TOKEN.address ? curve.constants.NATIVE_TOKEN.wrappedAddress : curve.constants.NATIVE_TOKEN.address;
187
+ _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, "WETH", curve.constants.NATIVE_TOKEN.wrappedAddress, inCoin, outCoin, [0, 0, 8, 0, 0], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, Infinity);
188
+ nextCoins.add(outCoin);
189
+ }
190
+ // ETH -> stETH, ETH -> frxETH, ETH -> wBETH (Ethereum only)
191
+ if (curve.chainId == 1 && inCoin === curve.constants.NATIVE_TOKEN.address) {
192
+ for (_a = 0, _b = ["stETH", "frxETH", "wBETH"]; _a < _b.length; _a++) {
193
+ outCoin = _b[_a];
194
+ _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, outCoin === "frxETH" ? "frxETH minter" : outCoin, outCoin === "frxETH" ? "0xbAFA44EFE7901E04E39Dad13167D089C559c1138".toLowerCase() : curve.constants.COINS[outCoin.toLowerCase()], inCoin, curve.constants.COINS[outCoin.toLowerCase()], [0, 0, 8, 0, 0], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, Infinity);
195
+ nextCoins.add(curve.constants.COINS[outCoin.toLowerCase()]);
196
+ }
197
+ }
198
+ // stETH <-> wstETH (Ethereum only)
199
+ if (curve.chainId === 1 && [curve.constants.COINS.steth, curve.constants.COINS.wsteth].includes(inCoin)) {
200
+ outCoin = inCoin === curve.constants.COINS.steth ? curve.constants.COINS.wsteth : curve.constants.COINS.steth;
201
+ _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, "wstETH", curve.constants.COINS["wsteth"], inCoin, outCoin, [0, 0, 8, 0, 0], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, Infinity);
202
+ nextCoins.add(outCoin);
203
+ }
204
+ // frxETH <-> sfrxETH (Ethereum only)
205
+ if (curve.chainId === 1 && [curve.constants.COINS.frxeth, curve.constants.COINS.sfrxeth].includes(inCoin)) {
206
+ outCoin = inCoin === curve.constants.COINS.frxeth ? curve.constants.COINS.sfrxeth : curve.constants.COINS.frxeth;
207
+ _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, "sfrxETH", curve.constants.COINS["sfrxeth"], inCoin, outCoin, [0, 0, 8, 0, 0], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, Infinity);
208
+ nextCoins.add(outCoin);
209
+ }
210
+ // SNX swaps
211
+ // @ts-ignore
212
+ if (((_l = (_k = SNX[curve.chainId]) === null || _k === void 0 ? void 0 : _k.coins) !== null && _l !== void 0 ? _l : []).includes(inCoin)) {
213
+ // @ts-ignore
214
+ for (_c = 0, _d = SNX[curve.chainId].coins; _c < _d.length; _c++) {
215
+ outCoin = _d[_c];
216
+ if (inCoin === outCoin)
217
+ continue;
218
+ _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, "SNX exchange",
219
+ // @ts-ignore
220
+ SNX[curve.chainId].swap, inCoin, outCoin, [0, 0, 9, 0, 0], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, Infinity);
221
+ nextCoins.add(outCoin);
222
+ }
223
+ }
224
+ _e = 0, ALL_POOLS_1 = ALL_POOLS;
225
+ _s.label = 4;
340
226
  case 4:
341
- _s.sent();
342
- _s.label = 5;
227
+ if (!(_e < ALL_POOLS_1.length)) return [3 /*break*/, 7];
228
+ _f = ALL_POOLS_1[_e], poolId = _f[0], poolData = _f[1];
229
+ wrapped_coin_addresses = poolData.wrapped_coin_addresses.map(function (a) { return a.toLowerCase(); });
230
+ underlying_coin_addresses = poolData.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); });
231
+ pool_address = poolData.swap_address.toLowerCase();
232
+ token_address = poolData.token_address.toLowerCase();
233
+ is_aave_like_lending = poolData.is_lending && wrapped_coin_addresses.length === 3 && !poolData.deposit_address;
234
+ pool_type = poolData.is_llamma ? 4 : poolData.is_crypto ? Math.min(poolData.wrapped_coins.length, 3) : 1;
235
+ tvl_multiplier = poolData.is_crypto ? 1 : ((_m = amplificationCoefficientDict[poolData.swap_address]) !== null && _m !== void 0 ? _m : 1);
236
+ base_pool = poolData.is_meta ? __assign(__assign({}, curve.constants.POOLS_DATA), curve.constants.FACTORY_POOLS_DATA)[poolData.base_pool] : null;
237
+ base_pool_address = base_pool ? base_pool.swap_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
238
+ base_token_address = base_pool ? base_pool.token_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
239
+ second_base_pool = base_pool && base_pool.base_pool ? __assign(__assign(__assign({}, curve.constants.POOLS_DATA), curve.constants.FACTORY_POOLS_DATA), curve.constants.CRVUSD_FACTORY_POOLS_DATA)[base_pool.base_pool] : null;
240
+ second_base_pool_address = second_base_pool ? second_base_pool.swap_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
241
+ // for double meta underlying (crv/tricrypto, wmatic/tricrypto)
242
+ if (base_pool && second_base_pool_address !== curve.constants.ZERO_ADDRESS)
243
+ base_token_address = (_o = base_pool.deposit_address) === null || _o === void 0 ? void 0 : _o.toLowerCase();
244
+ second_base_token_address = second_base_pool ? second_base_pool.token_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
245
+ meta_coin_addresses = base_pool ? base_pool.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); }) : [];
246
+ swap_address = poolData.is_fake ? (_p = poolData.deposit_address) === null || _p === void 0 ? void 0 : _p.toLowerCase() : pool_address;
247
+ inCoinIndexes = {
248
+ wrapped_coin: wrapped_coin_addresses.indexOf(inCoin),
249
+ underlying_coin: underlying_coin_addresses.indexOf(inCoin),
250
+ meta_coin: meta_coin_addresses ? meta_coin_addresses.indexOf(inCoin) : -1,
251
+ };
252
+ // Skip pools which don't contain inCoin
253
+ if (inCoinIndexes.wrapped_coin === -1 && inCoinIndexes.underlying_coin === -1 && inCoinIndexes.meta_coin === -1 && inCoin !== token_address)
254
+ return [3 /*break*/, 6];
255
+ return [4 /*yield*/, _getTVL(poolId)];
343
256
  case 5:
257
+ tvl = (_s.sent()) * tvl_multiplier;
258
+ // Skip empty pools
259
+ if (curve.chainId === 1 && tvl < 1000)
260
+ return [3 /*break*/, 6];
261
+ if (curve.chainId !== 1 && tvl < 100)
262
+ return [3 /*break*/, 6];
263
+ // LP -> wrapped coin "swaps" (actually remove_liquidity_one_coin)
264
+ if (!poolData.is_fake && !poolData.is_llamma && wrapped_coin_addresses.length < 6 && inCoin === token_address) {
265
+ for (j = 0; j < wrapped_coin_addresses.length; j++) {
266
+ // Looking for outputCoinAddress only on the final step
267
+ if (step === MAX_STEPS - 1 && wrapped_coin_addresses[j] !== outputCoinAddress)
268
+ continue;
269
+ outputCoinIdx = wrapped_coin_addresses.indexOf(outputCoinAddress);
270
+ if (outputCoinIdx >= 0 && j !== outputCoinIdx)
271
+ continue;
272
+ _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, swap_address, inCoin, wrapped_coin_addresses[j], [0, j, 6, pool_type, wrapped_coin_addresses.length], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, tvl);
273
+ nextCoins.add(wrapped_coin_addresses[j]);
274
+ }
275
+ }
276
+ // LP -> underlying coin "swaps" (actually remove_liquidity_one_coin)
277
+ if ((poolData.is_fake || is_aave_like_lending) && underlying_coin_addresses.length < 6 && inCoin === token_address) {
278
+ for (j = 0; j < underlying_coin_addresses.length; j++) {
279
+ // Looking for outputCoinAddress only on the final step
280
+ if (step === MAX_STEPS - 1 && underlying_coin_addresses[j] !== outputCoinAddress)
281
+ continue;
282
+ outputCoinIdx = underlying_coin_addresses.indexOf(outputCoinAddress);
283
+ if (outputCoinIdx >= 0 && j !== outputCoinIdx)
284
+ continue;
285
+ swapType = is_aave_like_lending ? 7 : 6;
286
+ _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, swap_address, inCoin, underlying_coin_addresses[j], [0, j, swapType, pool_type, underlying_coin_addresses.length], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, tvl);
287
+ nextCoins.add(underlying_coin_addresses[j]);
288
+ }
289
+ }
290
+ // Wrapped coin -> LP "swaps" (actually add_liquidity)
291
+ if (!poolData.is_fake && !poolData.is_llamma && wrapped_coin_addresses.length < 6 && inCoinIndexes.wrapped_coin >= 0) {
292
+ // Looking for outputCoinAddress only on the final step
293
+ if (!(step === MAX_STEPS - 1 && token_address !== outputCoinAddress)) {
294
+ _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, swap_address, inCoin, token_address, [wrapped_coin_addresses.indexOf(inCoin), 0, 4, pool_type, wrapped_coin_addresses.length], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, tvl);
295
+ nextCoins.add(token_address);
296
+ }
297
+ }
298
+ // Underlying coin -> LP "swaps" (actually add_liquidity)
299
+ if ((poolData.is_fake || is_aave_like_lending) && underlying_coin_addresses.length < 6 && inCoinIndexes.underlying_coin >= 0) {
300
+ // Looking for outputCoinAddress only on the final step
301
+ if (!(step === MAX_STEPS - 1 && token_address !== outputCoinAddress)) {
302
+ swapType = is_aave_like_lending ? 5 : 4;
303
+ _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, swap_address, inCoin, token_address, [underlying_coin_addresses.indexOf(inCoin), 0, swapType, pool_type, underlying_coin_addresses.length], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, tvl);
304
+ nextCoins.add(token_address);
305
+ }
306
+ }
307
+ // Wrapped swaps
308
+ if (inCoinIndexes.wrapped_coin >= 0 && !poolData.is_fake) {
309
+ for (j = 0; j < wrapped_coin_addresses.length; j++) {
310
+ if (j === inCoinIndexes.wrapped_coin)
311
+ continue;
312
+ // Native swaps spend less gas
313
+ if (wrapped_coin_addresses[j] !== outputCoinAddress && wrapped_coin_addresses[j] === curve.constants.NATIVE_TOKEN.wrappedAddress)
314
+ continue;
315
+ // Looking for outputCoinAddress only on the final step
316
+ if (step === MAX_STEPS - 1 && wrapped_coin_addresses[j] !== outputCoinAddress)
317
+ continue;
318
+ outputCoinIdx = wrapped_coin_addresses.indexOf(outputCoinAddress);
319
+ if (outputCoinIdx >= 0 && j !== outputCoinIdx)
320
+ continue;
321
+ _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, pool_address, inCoin, wrapped_coin_addresses[j], [inCoinIndexes.wrapped_coin, j, 1, pool_type, wrapped_coin_addresses.length], pool_address, base_pool_address, base_token_address, second_base_pool_address, second_base_token_address, tvl);
322
+ nextCoins.add(wrapped_coin_addresses[j]);
323
+ }
324
+ }
325
+ // Only for underlying swaps
326
+ swap_address = (poolData.is_crypto && poolData.is_meta) || ((base_pool === null || base_pool === void 0 ? void 0 : base_pool.is_lending) && poolData.is_factory) ?
327
+ poolData.deposit_address : poolData.swap_address;
328
+ // Underlying swaps
329
+ if (!poolData.is_plain && inCoinIndexes.underlying_coin >= 0) {
330
+ for (j = 0; j < underlying_coin_addresses.length; j++) {
331
+ if (j === inCoinIndexes.underlying_coin)
332
+ continue;
333
+ // Don't swap metacoins since they can be swapped directly in base pool
334
+ if (inCoinIndexes.meta_coin >= 0 && meta_coin_addresses.includes(underlying_coin_addresses[j]))
335
+ continue;
336
+ // Looking for outputCoinAddress only on the final step
337
+ if (step === MAX_STEPS - 1 && underlying_coin_addresses[j] !== outputCoinAddress)
338
+ continue;
339
+ outputCoinIdx = underlying_coin_addresses.indexOf(outputCoinAddress);
340
+ if (outputCoinIdx >= 0 && j !== outputCoinIdx)
341
+ continue;
342
+ // Skip empty pools
343
+ if (tvl === 0)
344
+ continue;
345
+ hasEth = (inCoin === curve.constants.NATIVE_TOKEN.address || underlying_coin_addresses[j] === curve.constants.NATIVE_TOKEN.address);
346
+ swapType = (poolData.is_crypto && poolData.is_meta && poolData.is_factory) || ((base_pool === null || base_pool === void 0 ? void 0 : base_pool.is_lending) && poolData.is_factory) ? 3
347
+ : hasEth && poolId !== 'avaxcrypto' ? 1
348
+ : 2;
349
+ _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, swap_address, inCoin, underlying_coin_addresses[j], [inCoinIndexes.underlying_coin, j, swapType, pool_type, underlying_coin_addresses.length], pool_address, base_pool_address, base_token_address, second_base_pool_address, second_base_token_address, tvl);
350
+ nextCoins.add(underlying_coin_addresses[j]);
351
+ }
352
+ }
353
+ _s.label = 6;
354
+ case 6:
355
+ _e++;
356
+ return [3 /*break*/, 4];
357
+ case 7:
344
358
  _i++;
345
359
  return [3 /*break*/, 3];
346
- case 6:
360
+ case 8:
347
361
  curCoins = Array.from(nextCoins);
348
362
  nextCoins = new Set();
349
- _s.label = 7;
350
- case 7:
363
+ _s.label = 9;
364
+ case 9:
351
365
  step++;
352
366
  return [3 /*break*/, 2];
353
- case 8:
367
+ case 10:
354
368
  routes = __spreadArray(__spreadArray([], ((_q = routesByTvl[outputCoinAddress]) !== null && _q !== void 0 ? _q : []), true), ((_r = routesByLength[outputCoinAddress]) !== null && _r !== void 0 ? _r : []), true);
355
369
  return [2 /*return*/, routes.map(function (r) { return r.route; })];
356
370
  }
@@ -366,42 +380,54 @@ var _getRouteKey = function (route, inputCoinAddress, outputCoinAddress) {
366
380
  key += sortedCoins[1];
367
381
  return key;
368
382
  };
369
- var _getExchangeMultipleArgs = function (route) {
383
+ var _getExchangeArgs = function (route) {
370
384
  var _route = [];
371
385
  if (route.length > 0)
372
386
  _route.push(route[0].inputCoinAddress);
373
387
  var _swapParams = [];
374
- var _factorySwapAddresses = [];
388
+ var _pools = [];
389
+ var _basePools = [];
390
+ var _baseTokens = [];
391
+ var _secondBasePools = [];
392
+ var _secondBaseTokens = [];
375
393
  for (var _i = 0, route_2 = route; _i < route_2.length; _i++) {
376
394
  var routeStep = route_2[_i];
377
- _route.push(routeStep.poolAddress, routeStep.outputCoinAddress);
378
- _swapParams.push([routeStep.i, routeStep.j, routeStep.swapType]);
379
- _factorySwapAddresses.push(routeStep.swapAddress);
395
+ _route.push(routeStep.swapAddress, routeStep.outputCoinAddress);
396
+ _swapParams.push(routeStep.swapParams);
397
+ _pools.push(routeStep.poolAddress);
398
+ _basePools.push(routeStep.basePool);
399
+ _baseTokens.push(routeStep.baseToken);
400
+ _secondBasePools.push(routeStep.secondBasePool);
401
+ _secondBaseTokens.push(routeStep.secondBaseToken);
380
402
  }
381
- _route = _route.concat(Array(9 - _route.length).fill(curve.constants.ZERO_ADDRESS));
382
- _swapParams = _swapParams.concat(Array(4 - _swapParams.length).fill([0, 0, 0]));
383
- _factorySwapAddresses = _factorySwapAddresses.concat(Array(4 - _factorySwapAddresses.length).fill(curve.constants.ZERO_ADDRESS));
384
- return { _route: _route, _swapParams: _swapParams, _factorySwapAddresses: _factorySwapAddresses };
403
+ _route = _route.concat(Array(ROUTE_LENGTH - _route.length).fill(curve.constants.ZERO_ADDRESS));
404
+ _swapParams = _swapParams.concat(Array(MAX_STEPS - _swapParams.length).fill([0, 0, 0, 0, 0]));
405
+ _pools = _pools.concat(Array(MAX_STEPS - _pools.length).fill(curve.constants.ZERO_ADDRESS));
406
+ _basePools = _basePools.concat(Array(MAX_STEPS - _basePools.length).fill(curve.constants.ZERO_ADDRESS));
407
+ _baseTokens = _baseTokens.concat(Array(MAX_STEPS - _baseTokens.length).fill(curve.constants.ZERO_ADDRESS));
408
+ _secondBasePools = _secondBasePools.concat(Array(MAX_STEPS - _secondBasePools.length).fill(curve.constants.ZERO_ADDRESS));
409
+ _secondBaseTokens = _secondBaseTokens.concat(Array(MAX_STEPS - _secondBaseTokens.length).fill(curve.constants.ZERO_ADDRESS));
410
+ return { _route: _route, _swapParams: _swapParams, _pools: _pools, _basePools: _basePools, _baseTokens: _baseTokens, _secondBasePools: _secondBasePools, _secondBaseTokens: _secondBaseTokens };
385
411
  };
386
412
  var _estimatedGasForDifferentRoutesCache = {};
387
413
  var _estimateGasForDifferentRoutes = function (routes, inputCoinAddress, outputCoinAddress, _amount) { return __awaiter(void 0, void 0, void 0, function () {
388
- var contract, gasPromises, value, _i, routes_1, route, routeKey, gasPromise, _a, _route, _swapParams, _factorySwapAddresses, _gasAmounts_1, err_1;
414
+ var contract, gasPromises, value, _i, routes_1, route, routeKey, gasPromise, _a, _route, _swapParams, _pools, _gasAmounts_1, err_1;
389
415
  var _b;
390
416
  return __generator(this, function (_c) {
391
417
  switch (_c.label) {
392
418
  case 0:
393
419
  inputCoinAddress = inputCoinAddress.toLowerCase();
394
420
  outputCoinAddress = outputCoinAddress.toLowerCase();
395
- contract = curve.contracts[curve.constants.ALIASES.registry_exchange].contract;
421
+ contract = curve.contracts[curve.constants.ALIASES.router].contract;
396
422
  gasPromises = [];
397
423
  value = isEth(inputCoinAddress) ? _amount : curve.parseUnits("0");
398
424
  for (_i = 0, routes_1 = routes; _i < routes_1.length; _i++) {
399
425
  route = routes_1[_i];
400
426
  routeKey = _getRouteKey(route, inputCoinAddress, outputCoinAddress);
401
427
  gasPromise = void 0;
402
- _a = _getExchangeMultipleArgs(route), _route = _a._route, _swapParams = _a._swapParams, _factorySwapAddresses = _a._factorySwapAddresses;
428
+ _a = _getExchangeArgs(route), _route = _a._route, _swapParams = _a._swapParams, _pools = _a._pools;
403
429
  if ((((_b = _estimatedGasForDifferentRoutesCache[routeKey]) === null || _b === void 0 ? void 0 : _b.time) || 0) + 3600000 < Date.now()) {
404
- gasPromise = contract.exchange_multiple.estimateGas(_route, _swapParams, _amount, 0, _factorySwapAddresses, __assign(__assign({}, curve.constantOptions), { value: value }));
430
+ gasPromise = contract.exchange.estimateGas(_route, _swapParams, _amount, 0, _pools, __assign(__assign({}, curve.constantOptions), { value: value }));
405
431
  }
406
432
  else {
407
433
  gasPromise = Promise.resolve(_estimatedGasForDifferentRoutesCache[routeKey].gas);
@@ -427,7 +453,7 @@ var _estimateGasForDifferentRoutes = function (routes, inputCoinAddress, outputC
427
453
  });
428
454
  }); };
429
455
  var _getBestRoute = memoize(function (inputCoinAddress, outputCoinAddress, amount) { return __awaiter(void 0, void 0, void 0, function () {
430
- var _a, inputCoinDecimals, outputCoinDecimals, _amount, routesRaw, routes, calls, multicallContract, _i, routesRaw_1, r, _b, _route, _swapParams, _factorySwapAddresses, _outputAmounts, i, err_2, contract, _outputs, _c, routesRaw_2, r, _d, _route, _swapParams, _factorySwapAddresses, _e, _f, e_1, i, _h, gasAmounts, outputCoinUsdRate, gasData, ethUsdRate, gasPrice, expectedAmounts, expectedAmountsUsd, txCostsUsd;
456
+ var _a, inputCoinDecimals, outputCoinDecimals, _amount, routesRaw, routes, calls, multicallContract, _i, routesRaw_1, r, _b, _route, _swapParams, _pools, _outputAmounts, i, err_2, contract, _outputs, _c, routesRaw_2, r, _d, _route, _swapParams, _pools, _e, _f, e_1, i, _h, gasAmounts, outputCoinUsdRate, gasData, ethUsdRate, gasPrice, expectedAmounts, expectedAmountsUsd, txCostsUsd;
431
457
  return __generator(this, function (_j) {
432
458
  switch (_j.label) {
433
459
  case 0:
@@ -443,11 +469,11 @@ var _getBestRoute = memoize(function (inputCoinAddress, outputCoinAddress, amoun
443
469
  case 2:
444
470
  _j.trys.push([2, 4, , 11]);
445
471
  calls = [];
446
- multicallContract = curve.contracts[curve.constants.ALIASES.registry_exchange].multicallContract;
472
+ multicallContract = curve.contracts[curve.constants.ALIASES.router].multicallContract;
447
473
  for (_i = 0, routesRaw_1 = routesRaw; _i < routesRaw_1.length; _i++) {
448
474
  r = routesRaw_1[_i];
449
- _b = _getExchangeMultipleArgs(r.route), _route = _b._route, _swapParams = _b._swapParams, _factorySwapAddresses = _b._factorySwapAddresses;
450
- calls.push(multicallContract.get_exchange_multiple_amount(_route, _swapParams, _amount, _factorySwapAddresses));
475
+ _b = _getExchangeArgs(r.route), _route = _b._route, _swapParams = _b._swapParams, _pools = _b._pools;
476
+ calls.push(multicallContract.get_dy(_route, _swapParams, _amount, _pools));
451
477
  }
452
478
  return [4 /*yield*/, curve.multicallProvider.all(calls)];
453
479
  case 3:
@@ -459,19 +485,19 @@ var _getBestRoute = memoize(function (inputCoinAddress, outputCoinAddress, amoun
459
485
  return [3 /*break*/, 11];
460
486
  case 4:
461
487
  err_2 = _j.sent();
462
- contract = curve.contracts[curve.constants.ALIASES.registry_exchange].contract;
488
+ contract = curve.contracts[curve.constants.ALIASES.router].contract;
463
489
  _outputs = [];
464
490
  _c = 0, routesRaw_2 = routesRaw;
465
491
  _j.label = 5;
466
492
  case 5:
467
493
  if (!(_c < routesRaw_2.length)) return [3 /*break*/, 10];
468
494
  r = routesRaw_2[_c];
469
- _d = _getExchangeMultipleArgs(r.route), _route = _d._route, _swapParams = _d._swapParams, _factorySwapAddresses = _d._factorySwapAddresses;
495
+ _d = _getExchangeArgs(r.route), _route = _d._route, _swapParams = _d._swapParams, _pools = _d._pools;
470
496
  _j.label = 6;
471
497
  case 6:
472
498
  _j.trys.push([6, 8, , 9]);
473
499
  _f = (_e = _outputs).push;
474
- return [4 /*yield*/, contract.get_exchange_multiple_amount(_route, _swapParams, _amount, _factorySwapAddresses, curve.constantOptions)];
500
+ return [4 /*yield*/, contract.get_dy(_route, _swapParams, _amount, _pools, curve.constantOptions)];
475
501
  case 7:
476
502
  _f.apply(_e, [_j.sent()]);
477
503
  return [3 /*break*/, 9];
@@ -528,13 +554,13 @@ var _getBestRoute = memoize(function (inputCoinAddress, outputCoinAddress, amoun
528
554
  maxAge: 5 * 60 * 1000, // 5m
529
555
  });
530
556
  var _getOutputForRoute = memoize(function (route, _amount) { return __awaiter(void 0, void 0, void 0, function () {
531
- var contract, _a, _route, _swapParams, _factorySwapAddresses;
557
+ var contract, _a, _route, _swapParams, _pools;
532
558
  return __generator(this, function (_b) {
533
559
  switch (_b.label) {
534
560
  case 0:
535
- contract = curve.contracts[curve.constants.ALIASES.registry_exchange].contract;
536
- _a = _getExchangeMultipleArgs(route), _route = _a._route, _swapParams = _a._swapParams, _factorySwapAddresses = _a._factorySwapAddresses;
537
- return [4 /*yield*/, contract.get_exchange_multiple_amount(_route, _swapParams, _amount, _factorySwapAddresses, curve.constantOptions)];
561
+ contract = curve.contracts[curve.constants.ALIASES.router].contract;
562
+ _a = _getExchangeArgs(route), _route = _a._route, _swapParams = _a._swapParams, _pools = _a._pools;
563
+ return [4 /*yield*/, contract.get_dy(_route, _swapParams, _amount, _pools, curve.constantOptions)];
538
564
  case 1: return [2 /*return*/, _b.sent()];
539
565
  }
540
566
  });
@@ -561,6 +587,9 @@ export var getBestRouteAndOutput = function (inputCoin, outputCoin, amount) { re
561
587
  }
562
588
  });
563
589
  }); };
590
+ export var getArgs = function (route) {
591
+ return _getExchangeArgs(route);
592
+ };
564
593
  export var swapExpected = function (inputCoin, outputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
565
594
  return __generator(this, function (_a) {
566
595
  switch (_a.label) {
@@ -569,8 +598,42 @@ export var swapExpected = function (inputCoin, outputCoin, amount) { return __aw
569
598
  }
570
599
  });
571
600
  }); };
601
+ export var swapRequired = function (inputCoin, outputCoin, outAmount) { return __awaiter(void 0, void 0, void 0, function () {
602
+ var _a, inputCoinAddress, outputCoinAddress, _b, inputCoinDecimals, outputCoinDecimals, _outAmount, p1, p2, approximateRequiredAmount, route, contract, _c, _route, _swapParams, _pools, _basePools, _baseTokens, _secondBasePools, _secondBaseTokens, _required;
603
+ return __generator(this, function (_d) {
604
+ switch (_d.label) {
605
+ case 0:
606
+ _a = _getCoinAddresses(inputCoin, outputCoin), inputCoinAddress = _a[0], outputCoinAddress = _a[1];
607
+ _b = _getCoinDecimals(inputCoinAddress, outputCoinAddress), inputCoinDecimals = _b[0], outputCoinDecimals = _b[1];
608
+ _outAmount = parseUnits(outAmount, outputCoinDecimals);
609
+ return [4 /*yield*/, _getUsdRate(inputCoinAddress)];
610
+ case 1:
611
+ p1 = (_d.sent()) || 1;
612
+ return [4 /*yield*/, _getUsdRate(outputCoinAddress)];
613
+ case 2:
614
+ p2 = (_d.sent()) || 1;
615
+ approximateRequiredAmount = Number(outAmount) * p2 / p1;
616
+ return [4 /*yield*/, _getBestRoute(inputCoinAddress, outputCoinAddress, approximateRequiredAmount)];
617
+ case 3:
618
+ route = _d.sent();
619
+ contract = curve.contracts[curve.constants.ALIASES.router].contract;
620
+ _c = _getExchangeArgs(route), _route = _c._route, _swapParams = _c._swapParams, _pools = _c._pools, _basePools = _c._basePools, _baseTokens = _c._baseTokens, _secondBasePools = _c._secondBasePools, _secondBaseTokens = _c._secondBaseTokens;
621
+ _required = 0;
622
+ if (!("get_dx(address[11],uint256[5][5],uint256,address[5],address[5],address[5],address[5],address[5])" in contract)) return [3 /*break*/, 5];
623
+ return [4 /*yield*/, contract.get_dx(_route, _swapParams, _outAmount, _pools, _basePools, _baseTokens, _secondBasePools, _secondBaseTokens, curve.constantOptions)];
624
+ case 4:
625
+ _required = _d.sent();
626
+ return [3 /*break*/, 7];
627
+ case 5: return [4 /*yield*/, contract.get_dx(_route, _swapParams, _outAmount, _pools, _basePools, _baseTokens, curve.constantOptions)];
628
+ case 6:
629
+ _required = _d.sent();
630
+ _d.label = 7;
631
+ case 7: return [2 /*return*/, curve.formatUnits(_required, inputCoinDecimals)];
632
+ }
633
+ });
634
+ }); };
572
635
  export var swapPriceImpact = function (inputCoin, outputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
573
- var _a, inputCoinAddress, outputCoinAddress, _b, inputCoinDecimals, outputCoinDecimals, _c, route, output, _amount, _output, smallAmountIntBN, amountIntBN, contract, _smallAmount, _d, _route, _swapParams, _factorySwapAddresses, _smallOutput, e_2, priceImpactBN;
636
+ var _a, inputCoinAddress, outputCoinAddress, _b, inputCoinDecimals, outputCoinDecimals, _c, route, output, _amount, _output, smallAmountIntBN, amountIntBN, contract, _smallAmount, _d, _route, _swapParams, _pools, _smallOutput, e_2, priceImpactBN;
574
637
  return __generator(this, function (_e) {
575
638
  switch (_e.label) {
576
639
  case 0:
@@ -585,20 +648,20 @@ export var swapPriceImpact = function (inputCoin, outputCoin, amount) { return _
585
648
  amountIntBN = toBN(_amount, 0);
586
649
  if (smallAmountIntBN.gte(amountIntBN))
587
650
  return [2 /*return*/, 0];
588
- contract = curve.contracts[curve.constants.ALIASES.registry_exchange].contract;
651
+ contract = curve.contracts[curve.constants.ALIASES.router].contract;
589
652
  _smallAmount = fromBN(smallAmountIntBN.div(Math.pow(10, inputCoinDecimals)), inputCoinDecimals);
590
- _d = _getExchangeMultipleArgs(route), _route = _d._route, _swapParams = _d._swapParams, _factorySwapAddresses = _d._factorySwapAddresses;
653
+ _d = _getExchangeArgs(route), _route = _d._route, _swapParams = _d._swapParams, _pools = _d._pools;
591
654
  _e.label = 2;
592
655
  case 2:
593
656
  _e.trys.push([2, 4, , 6]);
594
- return [4 /*yield*/, contract.get_exchange_multiple_amount(_route, _swapParams, _smallAmount, _factorySwapAddresses, curve.constantOptions)];
657
+ return [4 /*yield*/, contract.get_dy(_route, _swapParams, _smallAmount, _pools, curve.constantOptions)];
595
658
  case 3:
596
659
  _smallOutput = _e.sent();
597
660
  return [3 /*break*/, 6];
598
661
  case 4:
599
662
  e_2 = _e.sent();
600
663
  _smallAmount = curve.parseUnits("1", inputCoinDecimals); // Dirty hack
601
- return [4 /*yield*/, contract.get_exchange_multiple_amount(_route, _swapParams, _smallAmount, _factorySwapAddresses, curve.constantOptions)];
664
+ return [4 /*yield*/, contract.get_dy(_route, _swapParams, _smallAmount, _pools, curve.constantOptions)];
602
665
  case 5:
603
666
  _smallOutput = _e.sent();
604
667
  return [3 /*break*/, 6];
@@ -611,7 +674,7 @@ export var swapPriceImpact = function (inputCoin, outputCoin, amount) { return _
611
674
  export var swapIsApproved = function (inputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
612
675
  return __generator(this, function (_a) {
613
676
  switch (_a.label) {
614
- case 0: return [4 /*yield*/, hasAllowance([inputCoin], [amount], curve.signerAddress, curve.constants.ALIASES.registry_exchange)];
677
+ case 0: return [4 /*yield*/, hasAllowance([inputCoin], [amount], curve.signerAddress, curve.constants.ALIASES.router)];
615
678
  case 1: return [2 /*return*/, _a.sent()];
616
679
  }
617
680
  });
@@ -619,7 +682,7 @@ export var swapIsApproved = function (inputCoin, amount) { return __awaiter(void
619
682
  export var swapApproveEstimateGas = function (inputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
620
683
  return __generator(this, function (_a) {
621
684
  switch (_a.label) {
622
- case 0: return [4 /*yield*/, ensureAllowanceEstimateGas([inputCoin], [amount], curve.constants.ALIASES.registry_exchange)];
685
+ case 0: return [4 /*yield*/, ensureAllowanceEstimateGas([inputCoin], [amount], curve.constants.ALIASES.router)];
623
686
  case 1: return [2 /*return*/, _a.sent()];
624
687
  }
625
688
  });
@@ -627,7 +690,7 @@ export var swapApproveEstimateGas = function (inputCoin, amount) { return __awai
627
690
  export var swapApprove = function (inputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
628
691
  return __generator(this, function (_a) {
629
692
  switch (_a.label) {
630
- case 0: return [4 /*yield*/, ensureAllowance([inputCoin], [amount], curve.constants.ALIASES.registry_exchange)];
693
+ case 0: return [4 /*yield*/, ensureAllowance([inputCoin], [amount], curve.constants.ALIASES.router)];
631
694
  case 1: return [2 /*return*/, _a.sent()];
632
695
  }
633
696
  });
@@ -655,7 +718,7 @@ export var swapEstimateGas = function (inputCoin, outputCoin, amount) { return _
655
718
  export var swap = function (inputCoin, outputCoin, amount, slippage) {
656
719
  if (slippage === void 0) { slippage = 0.5; }
657
720
  return __awaiter(void 0, void 0, void 0, function () {
658
- var _a, inputCoinAddress, outputCoinAddress, _b, inputCoinDecimals, outputCoinDecimals, _c, route, output, _d, _route, _swapParams, _factorySwapAddresses, _amount, minRecvAmountBN, _minRecvAmount, contract, value, gasLimit;
721
+ var _a, inputCoinAddress, outputCoinAddress, _b, inputCoinDecimals, outputCoinDecimals, _c, route, output, _d, _route, _swapParams, _pools, _amount, minRecvAmountBN, _minRecvAmount, contract, value, gasLimit;
659
722
  return __generator(this, function (_e) {
660
723
  switch (_e.label) {
661
724
  case 0:
@@ -670,19 +733,19 @@ export var swap = function (inputCoin, outputCoin, amount, slippage) {
670
733
  if (route.length === 0) {
671
734
  throw new Error("This pair can't be exchanged");
672
735
  }
673
- _d = _getExchangeMultipleArgs(route), _route = _d._route, _swapParams = _d._swapParams, _factorySwapAddresses = _d._factorySwapAddresses;
736
+ _d = _getExchangeArgs(route), _route = _d._route, _swapParams = _d._swapParams, _pools = _d._pools;
674
737
  _amount = parseUnits(amount, inputCoinDecimals);
675
738
  minRecvAmountBN = BN(output).times(100 - slippage).div(100);
676
739
  _minRecvAmount = fromBN(minRecvAmountBN, outputCoinDecimals);
677
- contract = curve.contracts[curve.constants.ALIASES.registry_exchange].contract;
740
+ contract = curve.contracts[curve.constants.ALIASES.router].contract;
678
741
  value = isEth(inputCoinAddress) ? _amount : curve.parseUnits("0");
679
742
  return [4 /*yield*/, curve.updateFeeData()];
680
743
  case 3:
681
744
  _e.sent();
682
- return [4 /*yield*/, contract.exchange_multiple.estimateGas(_route, _swapParams, _amount, _minRecvAmount, _factorySwapAddresses, __assign(__assign({}, curve.constantOptions), { value: value }))];
745
+ return [4 /*yield*/, contract.exchange.estimateGas(_route, _swapParams, _amount, _minRecvAmount, _pools, __assign(__assign({}, curve.constantOptions), { value: value }))];
683
746
  case 4:
684
747
  gasLimit = (_e.sent()) * (curve.chainId === 1 ? curve.parseUnits("130", 0) : curve.parseUnits("160", 0)) / curve.parseUnits("100", 0);
685
- return [4 /*yield*/, contract.exchange_multiple(_route, _swapParams, _amount, _minRecvAmount, _factorySwapAddresses, __assign(__assign({}, curve.options), { value: value, gasLimit: gasLimit }))];
748
+ return [4 /*yield*/, contract.exchange(_route, _swapParams, _amount, _minRecvAmount, _pools, __assign(__assign({}, curve.options), { value: value, gasLimit: gasLimit }))];
686
749
  case 5: return [2 /*return*/, _e.sent()];
687
750
  }
688
751
  });
@@ -703,7 +766,7 @@ export var getSwappedAmount = function (tx, outputCoin) { return __awaiter(void
703
766
  for (i = 1; i <= txInfo.logs.length; i++) {
704
767
  try {
705
768
  abiCoder = ethers.AbiCoder.defaultAbiCoder();
706
- res = abiCoder.decode(['address[9]', 'uint256[3][4]', 'address[4]', 'uint256', 'uint256'], ethers.dataSlice(txInfo.logs[txInfo.logs.length - i].data, 0));
769
+ res = abiCoder.decode(["address[".concat(ROUTE_LENGTH, "]"), "uint256[".concat(MAX_STEPS, "][").concat(MAX_STEPS, "]"), "address[".concat(MAX_STEPS, "]"), 'uint256', 'uint256'], ethers.dataSlice(txInfo.logs[txInfo.logs.length - i].data, 0));
707
770
  break;
708
771
  }
709
772
  catch (err) { }