@curvefi/api 2.9.0 → 2.10.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/factory/constants.js +6 -0
- package/lib/factory/factory-api.js +2 -0
- package/lib/factory/factory-crypto.js +1 -0
- package/lib/interfaces.d.ts +5 -0
- package/lib/router.d.ts +10 -0
- package/lib/router.js +458 -123
- package/package.json +1 -1
package/lib/factory/constants.js
CHANGED
|
@@ -313,6 +313,7 @@ exports.basePoolIdZapDictXDai = {
|
|
|
313
313
|
},
|
|
314
314
|
};
|
|
315
315
|
exports.basePoolIdZapDictMoonbeam = {};
|
|
316
|
+
// TODO Move to another place
|
|
316
317
|
exports.NATIVE_TOKEN_ADDRESS = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
|
|
317
318
|
exports.NATIVE_TOKENS = {
|
|
318
319
|
1: {
|
|
@@ -345,6 +346,11 @@ exports.NATIVE_TOKENS = {
|
|
|
345
346
|
wrappedSymbol: 'WGLMR',
|
|
346
347
|
wrappedAddress: '0xAcc15dC74880C9944775448304B263D191c6077F'.toLowerCase(),
|
|
347
348
|
},
|
|
349
|
+
43114: {
|
|
350
|
+
symbol: 'AVAX',
|
|
351
|
+
wrappedSymbol: 'WAVAX',
|
|
352
|
+
wrappedAddress: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7'.toLowerCase(),
|
|
353
|
+
},
|
|
348
354
|
42161: {
|
|
349
355
|
symbol: 'ETH',
|
|
350
356
|
wrappedSymbol: 'WETH',
|
|
@@ -198,6 +198,7 @@ function getFactoryPoolsDataFromApi(isCrypto) {
|
|
|
198
198
|
var cryptoCoinNames = pool.coins.map(function (c) { return c.symbol === nativeToken.symbol ? nativeToken.wrappedSymbol : c.symbol; });
|
|
199
199
|
var underlyingCoinNames = pool.coins.map(function (c) { return c.symbol === nativeToken.wrappedSymbol ? nativeToken.symbol : c.symbol; });
|
|
200
200
|
var underlyingCoinAddresses = coinAddresses.map(function (addr) { return addr === nativeToken.wrappedAddress ? constants_1.NATIVE_TOKEN_ADDRESS : addr; });
|
|
201
|
+
var isPlain = !coinAddresses.includes(nativeToken.wrappedAddress);
|
|
201
202
|
var isMeta = _this.chainId === 137 && coinAddresses[1].toLowerCase() === atricrypto3Lp;
|
|
202
203
|
if (isMeta) {
|
|
203
204
|
var basePoolId = "atricrypto3";
|
|
@@ -245,6 +246,7 @@ function getFactoryPoolsDataFromApi(isCrypto) {
|
|
|
245
246
|
token_address: pool.lpTokenAddress.toLowerCase(),
|
|
246
247
|
gauge_address: pool.gaugeAddress ? pool.gaugeAddress.toLowerCase() : ethers_1.ethers.constants.AddressZero,
|
|
247
248
|
is_crypto: true,
|
|
249
|
+
is_plain: isPlain,
|
|
248
250
|
is_factory: true,
|
|
249
251
|
underlying_coins: underlyingCoinNames,
|
|
250
252
|
wrapped_coins: cryptoCoinNames,
|
|
@@ -407,6 +407,7 @@ function getCryptoFactoryPoolData() {
|
|
|
407
407
|
token_address: tokenAddresses[i],
|
|
408
408
|
gauge_address: gaugeAddresses[i],
|
|
409
409
|
is_crypto: true,
|
|
410
|
+
is_plain: underlyingCoinAddresses[i].toString() === coinAddresses[i].toString(),
|
|
410
411
|
is_factory: true,
|
|
411
412
|
underlying_coins: underlyingCoinAddresses[i].map(function (addr) { return coinAddressNameDict[addr]; }),
|
|
412
413
|
wrapped_coins: coinAddresses[i].map(function (addr) { return coinAddressNameDict[addr]; }),
|
package/lib/interfaces.d.ts
CHANGED
|
@@ -116,12 +116,17 @@ export interface IExtendedPoolDataFromApi {
|
|
|
116
116
|
export interface IRouteStep {
|
|
117
117
|
poolId: string;
|
|
118
118
|
poolAddress: string;
|
|
119
|
+
inputCoinAddress: string;
|
|
119
120
|
outputCoinAddress: string;
|
|
120
121
|
i: number;
|
|
121
122
|
j: number;
|
|
122
123
|
swapType: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
|
123
124
|
swapAddress: string;
|
|
124
125
|
}
|
|
126
|
+
export interface IRoute_ {
|
|
127
|
+
steps: IRouteStep[];
|
|
128
|
+
minTvl: number;
|
|
129
|
+
}
|
|
125
130
|
export interface IRoute {
|
|
126
131
|
steps: IRouteStep[];
|
|
127
132
|
_output: ethers.BigNumber;
|
package/lib/router.d.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import { IRouteStep } from "./interfaces";
|
|
2
|
+
export declare const NATIVE_TOKEN_ADDRESS = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
|
|
3
|
+
export declare const NATIVE_TOKENS: {
|
|
4
|
+
[index: number]: {
|
|
5
|
+
symbol: string;
|
|
6
|
+
wrappedSymbol: string;
|
|
7
|
+
wrappedAddress: string;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export declare const _findAllRoutesTheShorterTheBetter: (inputCoinAddress: string, outputCoinAddress: string) => Promise<IRouteStep[][]>;
|
|
11
|
+
export declare const _findAllRoutesTvl: (inputCoinAddress: string, outputCoinAddress: string) => Promise<IRouteStep[][]>;
|
|
2
12
|
export declare const _findAllRoutes: (inputCoinAddress: string, outputCoinAddress: string) => Promise<IRouteStep[][]>;
|
|
3
13
|
export declare const getBestRouteAndOutput: (inputCoin: string, outputCoin: string, amount: number | string) => Promise<{
|
|
4
14
|
route: IRouteStep[];
|
package/lib/router.js
CHANGED
|
@@ -59,7 +59,7 @@ 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.swap = exports.swapEstimateGas = exports.swapApprove = exports.swapApproveEstimateGas = exports.swapIsApproved = exports.swapPriceImpact = exports.swapExpected = exports.getBestRouteAndOutput = exports._findAllRoutes = void 0;
|
|
62
|
+
exports.swap = exports.swapEstimateGas = exports.swapApprove = exports.swapApproveEstimateGas = exports.swapIsApproved = exports.swapPriceImpact = exports.swapExpected = exports.getBestRouteAndOutput = exports._findAllRoutes = exports._findAllRoutesTvl = exports._findAllRoutesTheShorterTheBetter = exports.NATIVE_TOKENS = exports.NATIVE_TOKEN_ADDRESS = void 0;
|
|
63
63
|
var axios_1 = __importDefault(require("axios"));
|
|
64
64
|
var memoizee_1 = __importDefault(require("memoizee"));
|
|
65
65
|
var bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
@@ -67,15 +67,58 @@ var ethers_1 = require("ethers");
|
|
|
67
67
|
var curve_1 = require("./curve");
|
|
68
68
|
var utils_1 = require("./utils");
|
|
69
69
|
var pools_1 = require("./pools");
|
|
70
|
-
// TODO
|
|
71
|
-
|
|
70
|
+
// TODO Move to another place
|
|
71
|
+
exports.NATIVE_TOKEN_ADDRESS = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
|
|
72
|
+
exports.NATIVE_TOKENS = {
|
|
73
|
+
1: {
|
|
74
|
+
symbol: 'ETH',
|
|
75
|
+
wrappedSymbol: 'WETH',
|
|
76
|
+
wrappedAddress: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'.toLowerCase(),
|
|
77
|
+
},
|
|
78
|
+
10: {
|
|
79
|
+
symbol: 'ETH',
|
|
80
|
+
wrappedSymbol: 'WETH',
|
|
81
|
+
wrappedAddress: '0x4200000000000000000000000000000000000006'.toLowerCase(),
|
|
82
|
+
},
|
|
83
|
+
100: {
|
|
84
|
+
symbol: 'XDAi',
|
|
85
|
+
wrappedSymbol: 'WXDAI',
|
|
86
|
+
wrappedAddress: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d'.toLowerCase(),
|
|
87
|
+
},
|
|
88
|
+
137: {
|
|
89
|
+
symbol: 'MATIC',
|
|
90
|
+
wrappedSymbol: 'WMATIC',
|
|
91
|
+
wrappedAddress: '0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270'.toLowerCase(),
|
|
92
|
+
},
|
|
93
|
+
250: {
|
|
94
|
+
symbol: 'FTM',
|
|
95
|
+
wrappedSymbol: 'WFTM',
|
|
96
|
+
wrappedAddress: '0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83'.toLowerCase(),
|
|
97
|
+
},
|
|
98
|
+
1284: {
|
|
99
|
+
symbol: 'GLMR',
|
|
100
|
+
wrappedSymbol: 'WGLMR',
|
|
101
|
+
wrappedAddress: '0xAcc15dC74880C9944775448304B263D191c6077F'.toLowerCase(),
|
|
102
|
+
},
|
|
103
|
+
43114: {
|
|
104
|
+
symbol: 'AVAX',
|
|
105
|
+
wrappedSymbol: 'WAVAX',
|
|
106
|
+
wrappedAddress: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7'.toLowerCase(),
|
|
107
|
+
},
|
|
108
|
+
42161: {
|
|
109
|
+
symbol: 'ETH',
|
|
110
|
+
wrappedSymbol: 'WETH',
|
|
111
|
+
wrappedAddress: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1'.toLowerCase(),
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
var MAX_ROUTES_FOR_ONE_COIN = 3;
|
|
72
115
|
// Inspired by Dijkstra's algorithm
|
|
73
|
-
var
|
|
74
|
-
var ALL_POOLS, basePoolsSet, _i, ALL_POOLS_1, pool, basePoolIds, markedCoins, curCoins, nextCoins, routes, step, _a, curCoins_1, inCoin, _b, ALL_POOLS_2, _c, poolId, poolData, wrapped_coin_addresses, underlying_coin_addresses, base_pool, meta_coin_addresses, token_address, is_lending, inCoinIndexes, j, swapType, _d, _e, inCoinRoute, swapType, _f, _h, inCoinRoute, j, tvl, _j, swapType, _k, _l, inCoinRoute, poolAddress, j, tvl, _m, swapType, _o, _p, inCoinRoute
|
|
75
|
-
var
|
|
76
|
-
var
|
|
77
|
-
return __generator(this, function (
|
|
78
|
-
switch (
|
|
116
|
+
var _findAllRoutesTheShorterTheBetter = function (inputCoinAddress, outputCoinAddress) { return __awaiter(void 0, void 0, void 0, function () {
|
|
117
|
+
var ALL_POOLS, basePoolsSet, _i, ALL_POOLS_1, pool, basePoolIds, markedCoins, curCoins, nextCoins, routes, step, _a, curCoins_1, inCoin, _b, ALL_POOLS_2, _c, poolId, poolData, wrapped_coin_addresses, underlying_coin_addresses, base_pool, meta_coin_addresses, token_address, is_lending, inCoinIndexes, j, swapType, _d, _e, inCoinRoute, swapType, _f, _h, inCoinRoute, j, tvl, _j, swapType, _k, _l, inCoinRoute, poolAddress, j, tvl, _m, hasEth, swapType, _o, _p, inCoinRoute;
|
|
118
|
+
var _q;
|
|
119
|
+
var _r, _s, _t, _u, _v, _w;
|
|
120
|
+
return __generator(this, function (_x) {
|
|
121
|
+
switch (_x.label) {
|
|
79
122
|
case 0:
|
|
80
123
|
inputCoinAddress = inputCoinAddress.toLowerCase();
|
|
81
124
|
outputCoinAddress = outputCoinAddress.toLowerCase();
|
|
@@ -90,35 +133,35 @@ var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __a
|
|
|
90
133
|
markedCoins = [];
|
|
91
134
|
curCoins = [inputCoinAddress];
|
|
92
135
|
nextCoins = new Set();
|
|
93
|
-
routes = (
|
|
94
|
-
|
|
95
|
-
|
|
136
|
+
routes = (_q = {},
|
|
137
|
+
_q[inputCoinAddress] = [[]],
|
|
138
|
+
_q);
|
|
96
139
|
step = 0;
|
|
97
|
-
|
|
140
|
+
_x.label = 1;
|
|
98
141
|
case 1:
|
|
99
|
-
if (!(step < 4)) return [3 /*break*/,
|
|
142
|
+
if (!(step < 4)) return [3 /*break*/, 15];
|
|
100
143
|
_a = 0, curCoins_1 = curCoins;
|
|
101
|
-
|
|
144
|
+
_x.label = 2;
|
|
102
145
|
case 2:
|
|
103
|
-
if (!(_a < curCoins_1.length)) return [3 /*break*/,
|
|
146
|
+
if (!(_a < curCoins_1.length)) return [3 /*break*/, 13];
|
|
104
147
|
inCoin = curCoins_1[_a];
|
|
105
148
|
_b = 0, ALL_POOLS_2 = ALL_POOLS;
|
|
106
|
-
|
|
149
|
+
_x.label = 3;
|
|
107
150
|
case 3:
|
|
108
|
-
if (!(_b < ALL_POOLS_2.length)) return [3 /*break*/,
|
|
151
|
+
if (!(_b < ALL_POOLS_2.length)) return [3 /*break*/, 12];
|
|
109
152
|
_c = ALL_POOLS_2[_b], poolId = _c[0], poolData = _c[1];
|
|
110
153
|
wrapped_coin_addresses = poolData.wrapped_coin_addresses.map(function (a) { return a.toLowerCase(); });
|
|
111
154
|
underlying_coin_addresses = poolData.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); });
|
|
112
155
|
base_pool = poolData.is_meta ? curve_1.curve.constants.POOLS_DATA[poolData.base_pool] : null;
|
|
113
156
|
meta_coin_addresses = base_pool ? base_pool.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); }) : [];
|
|
114
157
|
token_address = poolData.token_address.toLowerCase();
|
|
115
|
-
is_lending = (
|
|
158
|
+
is_lending = (_r = poolData.is_lending) !== null && _r !== void 0 ? _r : false;
|
|
116
159
|
inCoinIndexes = {
|
|
117
160
|
wrapped_coin: wrapped_coin_addresses.indexOf(inCoin),
|
|
118
161
|
underlying_coin: underlying_coin_addresses.indexOf(inCoin),
|
|
119
162
|
meta_coin: meta_coin_addresses ? meta_coin_addresses.indexOf(inCoin) : -1,
|
|
120
163
|
};
|
|
121
|
-
//
|
|
164
|
+
// LP -> underlying coin "swaps" (actually remove_liquidity_one_coin)
|
|
122
165
|
if (basePoolIds.includes(poolId) && inCoin === token_address) {
|
|
123
166
|
for (j = 0; j < underlying_coin_addresses.length; j++) {
|
|
124
167
|
// If this coin already marked or will be marked on the current step, no need to consider it on the next step
|
|
@@ -130,10 +173,11 @@ var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __a
|
|
|
130
173
|
swapType = poolId === 'aave' ? 10 : 9;
|
|
131
174
|
for (_d = 0, _e = routes[inCoin]; _d < _e.length; _d++) {
|
|
132
175
|
inCoinRoute = _e[_d];
|
|
133
|
-
routes[underlying_coin_addresses[j]] = ((
|
|
176
|
+
routes[underlying_coin_addresses[j]] = ((_s = routes[underlying_coin_addresses[j]]) !== null && _s !== void 0 ? _s : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
134
177
|
{
|
|
135
178
|
poolId: poolId,
|
|
136
179
|
poolAddress: poolData.swap_address,
|
|
180
|
+
inputCoinAddress: inCoin,
|
|
137
181
|
outputCoinAddress: underlying_coin_addresses[j],
|
|
138
182
|
i: 0,
|
|
139
183
|
j: j,
|
|
@@ -145,21 +189,22 @@ var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __a
|
|
|
145
189
|
nextCoins.add(underlying_coin_addresses[j]);
|
|
146
190
|
}
|
|
147
191
|
}
|
|
148
|
-
//
|
|
192
|
+
// Underlying coin -> LP "swaps" (actually add_liquidity)
|
|
149
193
|
if (basePoolIds.includes(poolId) && underlying_coin_addresses.includes(inCoin)) {
|
|
150
194
|
// If this coin already marked or will be marked on the current step, no need to consider it on the next step
|
|
151
195
|
if (markedCoins.includes(token_address) || curCoins.includes(token_address))
|
|
152
|
-
return [3 /*break*/,
|
|
196
|
+
return [3 /*break*/, 11];
|
|
153
197
|
// Looking for outputCoinAddress only on the final step
|
|
154
198
|
if (step === 3 && token_address !== outputCoinAddress)
|
|
155
|
-
return [3 /*break*/,
|
|
199
|
+
return [3 /*break*/, 11];
|
|
156
200
|
swapType = is_lending ? 8 : underlying_coin_addresses.length === 2 ? 6 : 7;
|
|
157
201
|
for (_f = 0, _h = routes[inCoin]; _f < _h.length; _f++) {
|
|
158
202
|
inCoinRoute = _h[_f];
|
|
159
|
-
routes[token_address] = ((
|
|
203
|
+
routes[token_address] = ((_t = routes[token_address]) !== null && _t !== void 0 ? _t : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
160
204
|
{
|
|
161
205
|
poolId: poolId,
|
|
162
206
|
poolAddress: poolData.swap_address,
|
|
207
|
+
inputCoinAddress: inCoin,
|
|
163
208
|
outputCoinAddress: token_address,
|
|
164
209
|
i: underlying_coin_addresses.indexOf(inCoin),
|
|
165
210
|
j: 0,
|
|
@@ -172,34 +217,35 @@ var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __a
|
|
|
172
217
|
}
|
|
173
218
|
// No input coin in this pool --> skip
|
|
174
219
|
if (inCoinIndexes.wrapped_coin === -1 && inCoinIndexes.underlying_coin === -1 && inCoinIndexes.meta_coin === -1)
|
|
175
|
-
return [3 /*break*/,
|
|
220
|
+
return [3 /*break*/, 11];
|
|
176
221
|
if (!(inCoinIndexes.wrapped_coin >= 0 && !poolData.is_fake)) return [3 /*break*/, 7];
|
|
177
222
|
j = 0;
|
|
178
|
-
|
|
223
|
+
_x.label = 4;
|
|
179
224
|
case 4:
|
|
180
225
|
if (!(j < wrapped_coin_addresses.length)) return [3 /*break*/, 7];
|
|
181
226
|
// If this coin already marked or will be marked on the current step, no need to consider it on the next step
|
|
182
227
|
if (markedCoins.includes(wrapped_coin_addresses[j]) || curCoins.includes(wrapped_coin_addresses[j]))
|
|
183
228
|
return [3 /*break*/, 6];
|
|
229
|
+
// Native swaps spend less gas
|
|
230
|
+
if (wrapped_coin_addresses[j] !== outputCoinAddress && wrapped_coin_addresses[j] === exports.NATIVE_TOKENS[curve_1.curve.chainId].wrappedAddress)
|
|
231
|
+
return [3 /*break*/, 6];
|
|
184
232
|
// Looking for outputCoinAddress only on the final step
|
|
185
233
|
if (step === 3 && wrapped_coin_addresses[j] !== outputCoinAddress)
|
|
186
234
|
return [3 /*break*/, 6];
|
|
187
235
|
_j = Number;
|
|
188
236
|
return [4 /*yield*/, ((0, pools_1.getPool)(poolId)).stats.totalLiquidity()];
|
|
189
237
|
case 5:
|
|
190
|
-
tvl = _j.apply(void 0, [
|
|
238
|
+
tvl = _j.apply(void 0, [_x.sent()]);
|
|
191
239
|
if (tvl === 0)
|
|
192
240
|
return [3 /*break*/, 6];
|
|
193
|
-
// Skip imbalanced pools
|
|
194
|
-
if (IMBALANCED_POOLS.includes(poolId))
|
|
195
|
-
return [3 /*break*/, 6];
|
|
196
241
|
swapType = poolData.is_crypto ? 3 : 1;
|
|
197
242
|
for (_k = 0, _l = routes[inCoin]; _k < _l.length; _k++) {
|
|
198
243
|
inCoinRoute = _l[_k];
|
|
199
|
-
routes[wrapped_coin_addresses[j]] = ((
|
|
244
|
+
routes[wrapped_coin_addresses[j]] = ((_u = routes[wrapped_coin_addresses[j]]) !== null && _u !== void 0 ? _u : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
200
245
|
{
|
|
201
246
|
poolId: poolId,
|
|
202
247
|
poolAddress: poolData.swap_address,
|
|
248
|
+
inputCoinAddress: inCoin,
|
|
203
249
|
outputCoinAddress: wrapped_coin_addresses[j],
|
|
204
250
|
i: inCoinIndexes.wrapped_coin,
|
|
205
251
|
j: j,
|
|
@@ -209,16 +255,16 @@ var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __a
|
|
|
209
255
|
], false)]);
|
|
210
256
|
}
|
|
211
257
|
nextCoins.add(wrapped_coin_addresses[j]);
|
|
212
|
-
|
|
258
|
+
_x.label = 6;
|
|
213
259
|
case 6:
|
|
214
260
|
j++;
|
|
215
261
|
return [3 /*break*/, 4];
|
|
216
262
|
case 7:
|
|
217
|
-
poolAddress = (poolData.is_crypto && poolData.is_meta) || (base_pool
|
|
263
|
+
poolAddress = (poolData.is_crypto && poolData.is_meta) || ((base_pool === null || base_pool === void 0 ? void 0 : base_pool.is_lending) && poolData.is_factory) ?
|
|
218
264
|
poolData.deposit_address : poolData.swap_address;
|
|
219
265
|
if (!(!poolData.is_plain && inCoinIndexes.underlying_coin >= 0)) return [3 /*break*/, 11];
|
|
220
266
|
j = 0;
|
|
221
|
-
|
|
267
|
+
_x.label = 8;
|
|
222
268
|
case 8:
|
|
223
269
|
if (!(j < underlying_coin_addresses.length)) return [3 /*break*/, 11];
|
|
224
270
|
// Don't swap metacoins since they can be swapped directly in base pool
|
|
@@ -233,19 +279,18 @@ var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __a
|
|
|
233
279
|
_m = Number;
|
|
234
280
|
return [4 /*yield*/, ((0, pools_1.getPool)(poolId)).stats.totalLiquidity()];
|
|
235
281
|
case 9:
|
|
236
|
-
tvl = _m.apply(void 0, [
|
|
282
|
+
tvl = _m.apply(void 0, [_x.sent()]);
|
|
237
283
|
if (tvl === 0)
|
|
238
284
|
return [3 /*break*/, 10];
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
return [3 /*break*/, 10];
|
|
242
|
-
swapType = poolData.is_crypto && (poolData.is_fake || poolData.is_meta) ? 4 : poolData.is_crypto ? 3 : 2;
|
|
285
|
+
hasEth = (inCoin === exports.NATIVE_TOKEN_ADDRESS || underlying_coin_addresses[j] === exports.NATIVE_TOKEN_ADDRESS);
|
|
286
|
+
swapType = ((base_pool === null || base_pool === void 0 ? void 0 : base_pool.is_lending) && poolData.is_factory) ? 5 : hasEth ? 3 : poolData.is_crypto ? 4 : 2;
|
|
243
287
|
for (_o = 0, _p = routes[inCoin]; _o < _p.length; _o++) {
|
|
244
288
|
inCoinRoute = _p[_o];
|
|
245
|
-
routes[underlying_coin_addresses[j]] = ((
|
|
289
|
+
routes[underlying_coin_addresses[j]] = ((_v = routes[underlying_coin_addresses[j]]) !== null && _v !== void 0 ? _v : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
246
290
|
{
|
|
247
291
|
poolId: poolId,
|
|
248
292
|
poolAddress: poolAddress,
|
|
293
|
+
inputCoinAddress: inCoin,
|
|
249
294
|
outputCoinAddress: underlying_coin_addresses[j],
|
|
250
295
|
i: inCoinIndexes.underlying_coin,
|
|
251
296
|
j: j,
|
|
@@ -255,103 +300,393 @@ var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __a
|
|
|
255
300
|
], false)]);
|
|
256
301
|
}
|
|
257
302
|
nextCoins.add(underlying_coin_addresses[j]);
|
|
258
|
-
|
|
303
|
+
_x.label = 10;
|
|
259
304
|
case 10:
|
|
260
305
|
j++;
|
|
261
306
|
return [3 /*break*/, 8];
|
|
262
307
|
case 11:
|
|
263
|
-
if (!(inCoinIndexes.wrapped_coin === 0 && meta_coin_addresses.length > 0 && !poolData.is_fake)) return [3 /*break*/, 15];
|
|
264
|
-
j = 0;
|
|
265
|
-
_5.label = 12;
|
|
266
|
-
case 12:
|
|
267
|
-
if (!(j < meta_coin_addresses.length)) return [3 /*break*/, 15];
|
|
268
|
-
// If this coin already marked or will be marked on the current step, no need to consider it on the next step
|
|
269
|
-
if (markedCoins.includes(meta_coin_addresses[j]) || curCoins.includes(meta_coin_addresses[j]))
|
|
270
|
-
return [3 /*break*/, 14];
|
|
271
|
-
// Looking for outputCoinAddress only on the final step
|
|
272
|
-
if (step === 3 && meta_coin_addresses[j] !== outputCoinAddress)
|
|
273
|
-
return [3 /*break*/, 14];
|
|
274
|
-
_q = Number;
|
|
275
|
-
return [4 /*yield*/, ((0, pools_1.getPool)(poolId)).stats.totalLiquidity()];
|
|
276
|
-
case 13:
|
|
277
|
-
tvl = _q.apply(void 0, [_5.sent()]);
|
|
278
|
-
if (tvl === 0)
|
|
279
|
-
return [3 /*break*/, 14];
|
|
280
|
-
// Skip imbalanced pools
|
|
281
|
-
if (IMBALANCED_POOLS.includes(poolId))
|
|
282
|
-
return [3 /*break*/, 14];
|
|
283
|
-
swapType = (base_pool && base_pool.is_meta && poolData.is_factory) ? 5 : poolData.is_crypto ? 4 : 2;
|
|
284
|
-
for (_r = 0, _s = routes[inCoin]; _r < _s.length; _r++) {
|
|
285
|
-
inCoinRoute = _s[_r];
|
|
286
|
-
routes[meta_coin_addresses[j]] = ((_2 = routes[meta_coin_addresses[j]]) !== null && _2 !== void 0 ? _2 : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
287
|
-
{
|
|
288
|
-
poolId: poolId,
|
|
289
|
-
poolAddress: poolAddress,
|
|
290
|
-
outputCoinAddress: meta_coin_addresses[j],
|
|
291
|
-
i: inCoinIndexes.wrapped_coin,
|
|
292
|
-
j: j + 1,
|
|
293
|
-
swapType: swapType,
|
|
294
|
-
swapAddress: swapType === 5 ? poolData.swap_address : ethers_1.ethers.constants.AddressZero,
|
|
295
|
-
},
|
|
296
|
-
], false)]);
|
|
297
|
-
}
|
|
298
|
-
nextCoins.add(meta_coin_addresses[j]);
|
|
299
|
-
_5.label = 14;
|
|
300
|
-
case 14:
|
|
301
|
-
j++;
|
|
302
|
-
return [3 /*break*/, 12];
|
|
303
|
-
case 15:
|
|
304
|
-
if (!(inCoinIndexes.meta_coin >= 0 && !poolData.is_fake)) return [3 /*break*/, 17];
|
|
305
|
-
// If this coin already marked or will be marked on the current step, no need to consider it on the next step
|
|
306
|
-
if (markedCoins.includes(wrapped_coin_addresses[0]) || curCoins.includes(wrapped_coin_addresses[0]))
|
|
307
|
-
return [3 /*break*/, 17];
|
|
308
|
-
// Looking for outputCoinAddress only on the final step
|
|
309
|
-
if (step === 3 && wrapped_coin_addresses[0] !== outputCoinAddress)
|
|
310
|
-
return [3 /*break*/, 17];
|
|
311
|
-
_t = Number;
|
|
312
|
-
return [4 /*yield*/, ((0, pools_1.getPool)(poolId)).stats.totalLiquidity()];
|
|
313
|
-
case 16:
|
|
314
|
-
tvl = _t.apply(void 0, [_5.sent()]);
|
|
315
|
-
if (tvl === 0)
|
|
316
|
-
return [3 /*break*/, 17];
|
|
317
|
-
// Skip imbalanced pools
|
|
318
|
-
if (IMBALANCED_POOLS.includes(poolId))
|
|
319
|
-
return [3 /*break*/, 17];
|
|
320
|
-
swapType = (base_pool && base_pool.is_meta && poolData.is_factory) ? 5 : poolData.is_crypto ? 4 : 2;
|
|
321
|
-
for (_u = 0, _v = routes[inCoin]; _u < _v.length; _u++) {
|
|
322
|
-
inCoinRoute = _v[_u];
|
|
323
|
-
routes[wrapped_coin_addresses[0]] = ((_3 = routes[wrapped_coin_addresses[0]]) !== null && _3 !== void 0 ? _3 : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
324
|
-
{
|
|
325
|
-
poolId: poolId,
|
|
326
|
-
poolAddress: poolAddress,
|
|
327
|
-
outputCoinAddress: wrapped_coin_addresses[0],
|
|
328
|
-
i: inCoinIndexes.meta_coin + 1,
|
|
329
|
-
j: 0,
|
|
330
|
-
swapType: swapType,
|
|
331
|
-
swapAddress: swapType === 5 ? poolData.swap_address : ethers_1.ethers.constants.AddressZero,
|
|
332
|
-
},
|
|
333
|
-
], false)]);
|
|
334
|
-
nextCoins.add(wrapped_coin_addresses[0]);
|
|
335
|
-
}
|
|
336
|
-
_5.label = 17;
|
|
337
|
-
case 17:
|
|
338
308
|
_b++;
|
|
339
309
|
return [3 /*break*/, 3];
|
|
340
|
-
case
|
|
310
|
+
case 12:
|
|
341
311
|
_a++;
|
|
342
312
|
return [3 /*break*/, 2];
|
|
343
|
-
case
|
|
313
|
+
case 13:
|
|
344
314
|
// If target output coin is reached, search is finished. Assumption: the shorter route, the better.
|
|
345
315
|
if (outputCoinAddress in routes)
|
|
346
|
-
return [3 /*break*/,
|
|
316
|
+
return [3 /*break*/, 15];
|
|
347
317
|
markedCoins.push.apply(markedCoins, curCoins);
|
|
348
318
|
curCoins = Array.from(nextCoins);
|
|
349
319
|
nextCoins = new Set();
|
|
350
|
-
|
|
351
|
-
case
|
|
320
|
+
_x.label = 14;
|
|
321
|
+
case 14:
|
|
322
|
+
step++;
|
|
323
|
+
return [3 /*break*/, 1];
|
|
324
|
+
case 15: return [2 /*return*/, (_w = routes[outputCoinAddress]) !== null && _w !== void 0 ? _w : []];
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
}); };
|
|
328
|
+
exports._findAllRoutesTheShorterTheBetter = _findAllRoutesTheShorterTheBetter;
|
|
329
|
+
// Inspired by Dijkstra's algorithm
|
|
330
|
+
var _findAllRoutesTvl = function (inputCoinAddress, outputCoinAddress) { return __awaiter(void 0, void 0, void 0, function () {
|
|
331
|
+
var ALL_POOLS, basePoolsSet, _i, ALL_POOLS_3, pool, basePoolIds, curCoins, nextCoins, routes, step, _loop_1, _a, curCoins_2, inCoin;
|
|
332
|
+
var _b;
|
|
333
|
+
var _c, _d, _e, _f, _h;
|
|
334
|
+
return __generator(this, function (_j) {
|
|
335
|
+
switch (_j.label) {
|
|
336
|
+
case 0:
|
|
337
|
+
inputCoinAddress = inputCoinAddress.toLowerCase();
|
|
338
|
+
outputCoinAddress = outputCoinAddress.toLowerCase();
|
|
339
|
+
ALL_POOLS = Object.entries(__assign(__assign(__assign({}, curve_1.curve.constants.POOLS_DATA), curve_1.curve.constants.FACTORY_POOLS_DATA), curve_1.curve.constants.CRYPTO_FACTORY_POOLS_DATA));
|
|
340
|
+
basePoolsSet = new Set();
|
|
341
|
+
for (_i = 0, ALL_POOLS_3 = ALL_POOLS; _i < ALL_POOLS_3.length; _i++) {
|
|
342
|
+
pool = ALL_POOLS_3[_i];
|
|
343
|
+
if (pool[1].base_pool)
|
|
344
|
+
basePoolsSet.add(pool[1].base_pool);
|
|
345
|
+
}
|
|
346
|
+
basePoolIds = Array.from(basePoolsSet);
|
|
347
|
+
curCoins = [inputCoinAddress];
|
|
348
|
+
nextCoins = new Set();
|
|
349
|
+
routes = (_b = {},
|
|
350
|
+
_b[inputCoinAddress] = [{ steps: [], minTvl: Infinity }],
|
|
351
|
+
_b);
|
|
352
|
+
step = 0;
|
|
353
|
+
_j.label = 1;
|
|
354
|
+
case 1:
|
|
355
|
+
if (!(step < 4)) return [3 /*break*/, 7];
|
|
356
|
+
_loop_1 = function (inCoin) {
|
|
357
|
+
var _loop_2, _k, ALL_POOLS_4, _l, poolId, poolData;
|
|
358
|
+
return __generator(this, function (_m) {
|
|
359
|
+
switch (_m.label) {
|
|
360
|
+
case 0:
|
|
361
|
+
_loop_2 = function (poolId, poolData) {
|
|
362
|
+
var wrapped_coin_addresses, underlying_coin_addresses, base_pool, meta_coin_addresses, token_address, is_lending, inCoinIndexes, _loop_3, j, tvl_1, _o, swapType_1, newRoutes, routesByPoolIds_1, _loop_4, j, poolAddress, _loop_5, j;
|
|
363
|
+
return __generator(this, function (_p) {
|
|
364
|
+
switch (_p.label) {
|
|
365
|
+
case 0:
|
|
366
|
+
wrapped_coin_addresses = poolData.wrapped_coin_addresses.map(function (a) { return a.toLowerCase(); });
|
|
367
|
+
underlying_coin_addresses = poolData.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); });
|
|
368
|
+
base_pool = poolData.is_meta ? curve_1.curve.constants.POOLS_DATA[poolData.base_pool] : null;
|
|
369
|
+
meta_coin_addresses = base_pool ? base_pool.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); }) : [];
|
|
370
|
+
token_address = poolData.token_address.toLowerCase();
|
|
371
|
+
is_lending = (_c = poolData.is_lending) !== null && _c !== void 0 ? _c : false;
|
|
372
|
+
inCoinIndexes = {
|
|
373
|
+
wrapped_coin: wrapped_coin_addresses.indexOf(inCoin),
|
|
374
|
+
underlying_coin: underlying_coin_addresses.indexOf(inCoin),
|
|
375
|
+
meta_coin: meta_coin_addresses ? meta_coin_addresses.indexOf(inCoin) : -1,
|
|
376
|
+
};
|
|
377
|
+
// No input coin in this pool --> skip
|
|
378
|
+
if (inCoinIndexes.wrapped_coin === -1 && inCoinIndexes.underlying_coin === -1 && inCoinIndexes.meta_coin === -1 && inCoin !== token_address)
|
|
379
|
+
return [2 /*return*/, "continue"];
|
|
380
|
+
if (!(basePoolIds.includes(poolId) && inCoin === token_address)) return [3 /*break*/, 4];
|
|
381
|
+
_loop_3 = function (j) {
|
|
382
|
+
var outputCoinIdx, tvl, _q, swapType, newRoutes, routesByPoolIds;
|
|
383
|
+
return __generator(this, function (_r) {
|
|
384
|
+
switch (_r.label) {
|
|
385
|
+
case 0:
|
|
386
|
+
// Looking for outputCoinAddress only on the final step
|
|
387
|
+
if (step === 3 && underlying_coin_addresses[j] !== outputCoinAddress)
|
|
388
|
+
return [2 /*return*/, "continue"];
|
|
389
|
+
outputCoinIdx = underlying_coin_addresses.indexOf(outputCoinAddress);
|
|
390
|
+
if (outputCoinIdx >= 0 && j !== outputCoinIdx)
|
|
391
|
+
return [2 /*return*/, "continue"];
|
|
392
|
+
_q = Number;
|
|
393
|
+
return [4 /*yield*/, ((0, pools_1.getPool)(poolId)).stats.totalLiquidity()];
|
|
394
|
+
case 1:
|
|
395
|
+
tvl = _q.apply(void 0, [_r.sent()]);
|
|
396
|
+
swapType = poolId === 'aave' ? 10 : 9;
|
|
397
|
+
newRoutes = routes[inCoin].map(function (route) {
|
|
398
|
+
var routePoolIds = route.steps.map(function (s) { return s.poolId; });
|
|
399
|
+
// Steps <= 4
|
|
400
|
+
if (routePoolIds.length >= 4)
|
|
401
|
+
return { steps: [], minTvl: -1 };
|
|
402
|
+
// Exclude such cases as cvxeth -> tricrypto2 -> tricrypto2 -> susd
|
|
403
|
+
if (routePoolIds.includes(poolId))
|
|
404
|
+
return { steps: [], minTvl: -1 };
|
|
405
|
+
return {
|
|
406
|
+
steps: __spreadArray(__spreadArray([], route.steps, true), [
|
|
407
|
+
{
|
|
408
|
+
poolId: poolId,
|
|
409
|
+
poolAddress: poolData.swap_address,
|
|
410
|
+
inputCoinAddress: inCoin,
|
|
411
|
+
outputCoinAddress: underlying_coin_addresses[j],
|
|
412
|
+
i: 0,
|
|
413
|
+
j: j,
|
|
414
|
+
swapType: swapType,
|
|
415
|
+
swapAddress: ethers_1.ethers.constants.AddressZero,
|
|
416
|
+
},
|
|
417
|
+
], false),
|
|
418
|
+
minTvl: Math.min(tvl, route.minTvl),
|
|
419
|
+
};
|
|
420
|
+
});
|
|
421
|
+
routes[underlying_coin_addresses[j]] = __spreadArray(__spreadArray([], ((_d = routes[underlying_coin_addresses[j]]) !== null && _d !== void 0 ? _d : []), true), newRoutes, true);
|
|
422
|
+
routesByPoolIds = routes[underlying_coin_addresses[j]].map(function (r) { return r.steps.map(function (s) { return s.poolId; }).toString(); });
|
|
423
|
+
routes[underlying_coin_addresses[j]] = routes[underlying_coin_addresses[j]]
|
|
424
|
+
.filter(function (r) { return r.steps.length > 0; })
|
|
425
|
+
.filter(function (r) { return r.steps[0].inputCoinAddress === inputCoinAddress; }) // Truncated routes
|
|
426
|
+
.filter(function (r, i) { return routesByPoolIds.indexOf(r.steps.map(function (s) { return s.poolId; }).toString()) === i; }) // Route duplications
|
|
427
|
+
.sort(function (a, b) { return b.minTvl - a.minTvl || a.steps.length - b.steps.length; }).slice(0, MAX_ROUTES_FOR_ONE_COIN);
|
|
428
|
+
nextCoins.add(underlying_coin_addresses[j]);
|
|
429
|
+
return [2 /*return*/];
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
};
|
|
433
|
+
j = 0;
|
|
434
|
+
_p.label = 1;
|
|
435
|
+
case 1:
|
|
436
|
+
if (!(j < underlying_coin_addresses.length)) return [3 /*break*/, 4];
|
|
437
|
+
return [5 /*yield**/, _loop_3(j)];
|
|
438
|
+
case 2:
|
|
439
|
+
_p.sent();
|
|
440
|
+
_p.label = 3;
|
|
441
|
+
case 3:
|
|
442
|
+
j++;
|
|
443
|
+
return [3 /*break*/, 1];
|
|
444
|
+
case 4:
|
|
445
|
+
if (!(basePoolIds.includes(poolId) && inCoinIndexes.underlying_coin >= 0)) return [3 /*break*/, 6];
|
|
446
|
+
// Looking for outputCoinAddress only on the final step
|
|
447
|
+
if (step === 3 && token_address !== outputCoinAddress)
|
|
448
|
+
return [2 /*return*/, "continue"];
|
|
449
|
+
_o = Number;
|
|
450
|
+
return [4 /*yield*/, ((0, pools_1.getPool)(poolId)).stats.totalLiquidity()];
|
|
451
|
+
case 5:
|
|
452
|
+
tvl_1 = _o.apply(void 0, [_p.sent()]);
|
|
453
|
+
swapType_1 = is_lending ? 8 : underlying_coin_addresses.length === 2 ? 6 : 7;
|
|
454
|
+
newRoutes = routes[inCoin].map(function (route) {
|
|
455
|
+
var routePoolIds = route.steps.map(function (s) { return s.poolId; });
|
|
456
|
+
// Steps <= 4
|
|
457
|
+
if (routePoolIds.length >= 4)
|
|
458
|
+
return { steps: [], minTvl: -1 };
|
|
459
|
+
// Exclude such cases as cvxeth -> tricrypto2 -> tricrypto2 -> susd
|
|
460
|
+
if (routePoolIds.includes(poolId))
|
|
461
|
+
return { steps: [], minTvl: -1 };
|
|
462
|
+
return {
|
|
463
|
+
steps: __spreadArray(__spreadArray([], route.steps, true), [
|
|
464
|
+
{
|
|
465
|
+
poolId: poolId,
|
|
466
|
+
poolAddress: poolData.swap_address,
|
|
467
|
+
inputCoinAddress: inCoin,
|
|
468
|
+
outputCoinAddress: token_address,
|
|
469
|
+
i: underlying_coin_addresses.indexOf(inCoin),
|
|
470
|
+
j: 0,
|
|
471
|
+
swapType: swapType_1,
|
|
472
|
+
swapAddress: ethers_1.ethers.constants.AddressZero,
|
|
473
|
+
},
|
|
474
|
+
], false),
|
|
475
|
+
minTvl: Math.min(tvl_1, route.minTvl),
|
|
476
|
+
};
|
|
477
|
+
});
|
|
478
|
+
routes[token_address] = __spreadArray(__spreadArray([], ((_e = routes[token_address]) !== null && _e !== void 0 ? _e : []), true), newRoutes, true);
|
|
479
|
+
routesByPoolIds_1 = routes[token_address].map(function (r) { return r.steps.map(function (s) { return s.poolId; }).toString(); });
|
|
480
|
+
routes[token_address] = routes[token_address]
|
|
481
|
+
.filter(function (r) { return r.steps.length > 0; })
|
|
482
|
+
.filter(function (r) { return r.steps[0].inputCoinAddress === inputCoinAddress; }) // Truncated routes
|
|
483
|
+
.filter(function (r, i) { return routesByPoolIds_1.indexOf(r.steps.map(function (s) { return s.poolId; }).toString()) === i; }) // Route duplications
|
|
484
|
+
.sort(function (a, b) { return b.minTvl - a.minTvl || a.steps.length - b.steps.length; }).slice(0, MAX_ROUTES_FOR_ONE_COIN);
|
|
485
|
+
nextCoins.add(token_address);
|
|
486
|
+
_p.label = 6;
|
|
487
|
+
case 6:
|
|
488
|
+
if (!(inCoinIndexes.wrapped_coin >= 0 && !poolData.is_fake)) return [3 /*break*/, 10];
|
|
489
|
+
_loop_4 = function (j) {
|
|
490
|
+
var outputCoinIdx, tvl, _s, swapType, newRoutes, routesByPoolIds;
|
|
491
|
+
return __generator(this, function (_t) {
|
|
492
|
+
switch (_t.label) {
|
|
493
|
+
case 0:
|
|
494
|
+
if (j === inCoinIndexes.wrapped_coin)
|
|
495
|
+
return [2 /*return*/, "continue"];
|
|
496
|
+
// Native swaps spend less gas
|
|
497
|
+
if (wrapped_coin_addresses[j] !== outputCoinAddress && wrapped_coin_addresses[j] === exports.NATIVE_TOKENS[curve_1.curve.chainId].wrappedAddress)
|
|
498
|
+
return [2 /*return*/, "continue"];
|
|
499
|
+
// Looking for outputCoinAddress only on the final step
|
|
500
|
+
if (step === 3 && wrapped_coin_addresses[j] !== outputCoinAddress)
|
|
501
|
+
return [2 /*return*/, "continue"];
|
|
502
|
+
outputCoinIdx = wrapped_coin_addresses.indexOf(outputCoinAddress);
|
|
503
|
+
if (outputCoinIdx >= 0 && j !== outputCoinIdx)
|
|
504
|
+
return [2 /*return*/, "continue"];
|
|
505
|
+
_s = Number;
|
|
506
|
+
return [4 /*yield*/, ((0, pools_1.getPool)(poolId)).stats.totalLiquidity()];
|
|
507
|
+
case 1:
|
|
508
|
+
tvl = _s.apply(void 0, [_t.sent()]);
|
|
509
|
+
// Skip empty pools
|
|
510
|
+
if (tvl === 0)
|
|
511
|
+
return [2 /*return*/, "continue"];
|
|
512
|
+
swapType = poolData.is_crypto ? 3 : 1;
|
|
513
|
+
newRoutes = routes[inCoin].map(function (route) {
|
|
514
|
+
var routePoolIds = route.steps.map(function (s) { return s.poolId; });
|
|
515
|
+
// Steps <= 4
|
|
516
|
+
if (routePoolIds.length >= 4)
|
|
517
|
+
return { steps: [], minTvl: -1 };
|
|
518
|
+
// Exclude such cases as cvxeth -> tricrypto2 -> tricrypto2 -> susd
|
|
519
|
+
if (routePoolIds.includes(poolId))
|
|
520
|
+
return { steps: [], minTvl: -1 };
|
|
521
|
+
return {
|
|
522
|
+
steps: __spreadArray(__spreadArray([], route.steps, true), [
|
|
523
|
+
{
|
|
524
|
+
poolId: poolId,
|
|
525
|
+
poolAddress: poolData.swap_address,
|
|
526
|
+
inputCoinAddress: inCoin,
|
|
527
|
+
outputCoinAddress: wrapped_coin_addresses[j],
|
|
528
|
+
i: inCoinIndexes.wrapped_coin,
|
|
529
|
+
j: j,
|
|
530
|
+
swapType: swapType,
|
|
531
|
+
swapAddress: ethers_1.ethers.constants.AddressZero,
|
|
532
|
+
},
|
|
533
|
+
], false),
|
|
534
|
+
minTvl: Math.min(tvl, route.minTvl),
|
|
535
|
+
};
|
|
536
|
+
});
|
|
537
|
+
routes[wrapped_coin_addresses[j]] = __spreadArray(__spreadArray([], ((_f = routes[wrapped_coin_addresses[j]]) !== null && _f !== void 0 ? _f : []), true), newRoutes, true);
|
|
538
|
+
routesByPoolIds = routes[wrapped_coin_addresses[j]].map(function (r) { return r.steps.map(function (s) { return s.poolId; }).toString(); });
|
|
539
|
+
routes[wrapped_coin_addresses[j]] = routes[wrapped_coin_addresses[j]]
|
|
540
|
+
.filter(function (r) { return r.steps.length > 0; })
|
|
541
|
+
.filter(function (r) { return r.steps[0].inputCoinAddress === inputCoinAddress; }) // Truncated routes
|
|
542
|
+
.filter(function (r, i) { return routesByPoolIds.indexOf(r.steps.map(function (s) { return s.poolId; }).toString()) === i; }) // Route duplications
|
|
543
|
+
.sort(function (a, b) { return b.minTvl - a.minTvl || a.steps.length - b.steps.length; }).slice(0, MAX_ROUTES_FOR_ONE_COIN);
|
|
544
|
+
nextCoins.add(wrapped_coin_addresses[j]);
|
|
545
|
+
return [2 /*return*/];
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
};
|
|
549
|
+
j = 0;
|
|
550
|
+
_p.label = 7;
|
|
551
|
+
case 7:
|
|
552
|
+
if (!(j < wrapped_coin_addresses.length)) return [3 /*break*/, 10];
|
|
553
|
+
return [5 /*yield**/, _loop_4(j)];
|
|
554
|
+
case 8:
|
|
555
|
+
_p.sent();
|
|
556
|
+
_p.label = 9;
|
|
557
|
+
case 9:
|
|
558
|
+
j++;
|
|
559
|
+
return [3 /*break*/, 7];
|
|
560
|
+
case 10:
|
|
561
|
+
poolAddress = (poolData.is_crypto && poolData.is_meta) || ((base_pool === null || base_pool === void 0 ? void 0 : base_pool.is_lending) && poolData.is_factory) ?
|
|
562
|
+
poolData.deposit_address : poolData.swap_address;
|
|
563
|
+
if (!(!poolData.is_plain && inCoinIndexes.underlying_coin >= 0)) return [3 /*break*/, 14];
|
|
564
|
+
_loop_5 = function (j) {
|
|
565
|
+
var outputCoinIdx, tvl, _u, hasEth, swapType, newRoutes, routesByPoolIds;
|
|
566
|
+
return __generator(this, function (_v) {
|
|
567
|
+
switch (_v.label) {
|
|
568
|
+
case 0:
|
|
569
|
+
if (j === inCoinIndexes.underlying_coin)
|
|
570
|
+
return [2 /*return*/, "continue"];
|
|
571
|
+
// Don't swap metacoins since they can be swapped directly in base pool
|
|
572
|
+
if (inCoinIndexes.meta_coin >= 0 && meta_coin_addresses.includes(underlying_coin_addresses[j]))
|
|
573
|
+
return [2 /*return*/, "continue"];
|
|
574
|
+
// Looking for outputCoinAddress only on the final step
|
|
575
|
+
if (step === 3 && underlying_coin_addresses[j] !== outputCoinAddress)
|
|
576
|
+
return [2 /*return*/, "continue"];
|
|
577
|
+
outputCoinIdx = underlying_coin_addresses.indexOf(outputCoinAddress);
|
|
578
|
+
if (outputCoinIdx >= 0 && j !== outputCoinIdx)
|
|
579
|
+
return [2 /*return*/, "continue"];
|
|
580
|
+
_u = Number;
|
|
581
|
+
return [4 /*yield*/, ((0, pools_1.getPool)(poolId)).stats.totalLiquidity()];
|
|
582
|
+
case 1:
|
|
583
|
+
tvl = _u.apply(void 0, [_v.sent()]);
|
|
584
|
+
if (tvl === 0)
|
|
585
|
+
return [2 /*return*/, "continue"];
|
|
586
|
+
hasEth = (inCoin === exports.NATIVE_TOKEN_ADDRESS || underlying_coin_addresses[j] === exports.NATIVE_TOKEN_ADDRESS);
|
|
587
|
+
swapType = ((base_pool === null || base_pool === void 0 ? void 0 : base_pool.is_lending) && poolData.is_factory) ? 5 : hasEth ? 3 : poolData.is_crypto ? 4 : 2;
|
|
588
|
+
newRoutes = routes[inCoin].map(function (route) {
|
|
589
|
+
var routePoolIds = route.steps.map(function (s) { return s.poolId; });
|
|
590
|
+
// Steps <= 4
|
|
591
|
+
if (routePoolIds.length >= 4)
|
|
592
|
+
return { steps: [], minTvl: -1 };
|
|
593
|
+
// Exclude such cases as cvxeth -> tricrypto2 -> tricrypto2 -> susd
|
|
594
|
+
if (routePoolIds.includes(poolId))
|
|
595
|
+
return { steps: [], minTvl: -1 };
|
|
596
|
+
return {
|
|
597
|
+
steps: __spreadArray(__spreadArray([], route.steps, true), [
|
|
598
|
+
{
|
|
599
|
+
poolId: poolId,
|
|
600
|
+
poolAddress: poolAddress,
|
|
601
|
+
inputCoinAddress: inCoin,
|
|
602
|
+
outputCoinAddress: underlying_coin_addresses[j],
|
|
603
|
+
i: inCoinIndexes.underlying_coin,
|
|
604
|
+
j: j,
|
|
605
|
+
swapType: swapType,
|
|
606
|
+
swapAddress: swapType === 5 ? poolData.swap_address : ethers_1.ethers.constants.AddressZero,
|
|
607
|
+
},
|
|
608
|
+
], false),
|
|
609
|
+
minTvl: Math.min(tvl, route.minTvl),
|
|
610
|
+
};
|
|
611
|
+
});
|
|
612
|
+
routes[underlying_coin_addresses[j]] = __spreadArray(__spreadArray([], ((_h = routes[underlying_coin_addresses[j]]) !== null && _h !== void 0 ? _h : []), true), newRoutes, true);
|
|
613
|
+
routesByPoolIds = routes[underlying_coin_addresses[j]].map(function (r) { return r.steps.map(function (s) { return s.poolId; }).toString(); });
|
|
614
|
+
routes[underlying_coin_addresses[j]] = routes[underlying_coin_addresses[j]]
|
|
615
|
+
.filter(function (r) { return r.steps.length > 0; })
|
|
616
|
+
.filter(function (r) { return r.steps[0].inputCoinAddress === inputCoinAddress; }) // Truncated routes
|
|
617
|
+
.filter(function (r, i) { return routesByPoolIds.indexOf(r.steps.map(function (s) { return s.poolId; }).toString()) === i; }) // Route duplications
|
|
618
|
+
.sort(function (a, b) { return b.minTvl - a.minTvl || a.steps.length - b.steps.length; }).slice(0, MAX_ROUTES_FOR_ONE_COIN);
|
|
619
|
+
nextCoins.add(underlying_coin_addresses[j]);
|
|
620
|
+
return [2 /*return*/];
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
};
|
|
624
|
+
j = 0;
|
|
625
|
+
_p.label = 11;
|
|
626
|
+
case 11:
|
|
627
|
+
if (!(j < underlying_coin_addresses.length)) return [3 /*break*/, 14];
|
|
628
|
+
return [5 /*yield**/, _loop_5(j)];
|
|
629
|
+
case 12:
|
|
630
|
+
_p.sent();
|
|
631
|
+
_p.label = 13;
|
|
632
|
+
case 13:
|
|
633
|
+
j++;
|
|
634
|
+
return [3 /*break*/, 11];
|
|
635
|
+
case 14: return [2 /*return*/];
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
};
|
|
639
|
+
_k = 0, ALL_POOLS_4 = ALL_POOLS;
|
|
640
|
+
_m.label = 1;
|
|
641
|
+
case 1:
|
|
642
|
+
if (!(_k < ALL_POOLS_4.length)) return [3 /*break*/, 4];
|
|
643
|
+
_l = ALL_POOLS_4[_k], poolId = _l[0], poolData = _l[1];
|
|
644
|
+
return [5 /*yield**/, _loop_2(poolId, poolData)];
|
|
645
|
+
case 2:
|
|
646
|
+
_m.sent();
|
|
647
|
+
_m.label = 3;
|
|
648
|
+
case 3:
|
|
649
|
+
_k++;
|
|
650
|
+
return [3 /*break*/, 1];
|
|
651
|
+
case 4: return [2 /*return*/];
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
};
|
|
655
|
+
_a = 0, curCoins_2 = curCoins;
|
|
656
|
+
_j.label = 2;
|
|
657
|
+
case 2:
|
|
658
|
+
if (!(_a < curCoins_2.length)) return [3 /*break*/, 5];
|
|
659
|
+
inCoin = curCoins_2[_a];
|
|
660
|
+
return [5 /*yield**/, _loop_1(inCoin)];
|
|
661
|
+
case 3:
|
|
662
|
+
_j.sent();
|
|
663
|
+
_j.label = 4;
|
|
664
|
+
case 4:
|
|
665
|
+
_a++;
|
|
666
|
+
return [3 /*break*/, 2];
|
|
667
|
+
case 5:
|
|
668
|
+
curCoins = Array.from(nextCoins);
|
|
669
|
+
nextCoins = new Set();
|
|
670
|
+
_j.label = 6;
|
|
671
|
+
case 6:
|
|
352
672
|
step++;
|
|
353
673
|
return [3 /*break*/, 1];
|
|
354
|
-
case
|
|
674
|
+
case 7: return [2 /*return*/, routes[outputCoinAddress] ? routes[outputCoinAddress].map(function (r) { return r.steps; }) : []];
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
}); };
|
|
678
|
+
exports._findAllRoutesTvl = _findAllRoutesTvl;
|
|
679
|
+
var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __awaiter(void 0, void 0, void 0, function () {
|
|
680
|
+
var routes;
|
|
681
|
+
return __generator(this, function (_a) {
|
|
682
|
+
switch (_a.label) {
|
|
683
|
+
case 0: return [4 /*yield*/, (0, exports._findAllRoutesTvl)(inputCoinAddress, outputCoinAddress)];
|
|
684
|
+
case 1:
|
|
685
|
+
routes = _a.sent();
|
|
686
|
+
if (routes.length > 0)
|
|
687
|
+
return [2 /*return*/, routes];
|
|
688
|
+
return [4 /*yield*/, (0, exports._findAllRoutesTheShorterTheBetter)(inputCoinAddress, outputCoinAddress)];
|
|
689
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
355
690
|
}
|
|
356
691
|
});
|
|
357
692
|
}); };
|