@curvefi/api 1.22.0 → 1.24.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/README.md +98 -29
- package/lib/constants/abis/json/registry_exchange.json +30 -0
- package/lib/curve.js +128 -109
- package/lib/index.d.ts +10 -0
- package/lib/index.js +7 -0
- package/lib/interfaces.d.ts +16 -1
- package/lib/pools.d.ts +12 -1
- package/lib/pools.js +564 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -161,13 +161,12 @@ import curve from "@curvefi/api";
|
|
|
161
161
|
console.log(await curve.getBalances(['aDAI', 'aSUSD']));
|
|
162
162
|
// OR console.log(await curve.getBalances(['0x028171bCA77440897B824Ca71D1c56caC55b68A3', '0x6c5024cd4f8a59110119c56f8933403a539555eb']));
|
|
163
163
|
|
|
164
|
-
// [ '10000.
|
|
164
|
+
// [ '10000.00017727177059715', '10000.000080108429034461' ]
|
|
165
|
+
|
|
165
166
|
|
|
166
|
-
|
|
167
167
|
// --- Pool ---
|
|
168
168
|
|
|
169
169
|
const saave = new curve.Pool('saave');
|
|
170
|
-
|
|
171
170
|
|
|
172
171
|
// 1. Current address balances (signer balances)
|
|
173
172
|
|
|
@@ -175,40 +174,46 @@ import curve from "@curvefi/api";
|
|
|
175
174
|
// {
|
|
176
175
|
// lpToken: '0.0',
|
|
177
176
|
// gauge: '0.0',
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
//
|
|
177
|
+
// '0x6B175474E89094C44Da98b954EedeAC495271d0F': '10000.0',
|
|
178
|
+
// '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '10000.0',
|
|
179
|
+
// '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '10000.00017727177059715',
|
|
180
|
+
// '0x6c5024cd4f8a59110119c56f8933403a539555eb': '10000.000080108429034461'
|
|
182
181
|
// }
|
|
183
182
|
|
|
184
183
|
console.log(await saave.lpTokenBalances());
|
|
185
184
|
// { lpToken: '0.0', gauge: '0.0' }
|
|
186
185
|
|
|
187
186
|
console.log(await saave.underlyingCoinBalances());
|
|
188
|
-
// {
|
|
189
|
-
|
|
187
|
+
// {
|
|
188
|
+
// '0x6B175474E89094C44Da98b954EedeAC495271d0F': '10000.0',
|
|
189
|
+
// '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '10000.0'
|
|
190
|
+
// }
|
|
191
|
+
|
|
190
192
|
console.log(await saave.coinBalances());
|
|
191
|
-
// {
|
|
193
|
+
// {
|
|
194
|
+
// '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '10000.00017727177059715',
|
|
195
|
+
// '0x6c5024cd4f8a59110119c56f8933403a539555eb': '10000.000080108429034461'
|
|
196
|
+
// }
|
|
192
197
|
|
|
193
198
|
console.log(await saave.allCoinBalances());
|
|
194
199
|
// {
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
//
|
|
198
|
-
//
|
|
200
|
+
// '0x6B175474E89094C44Da98b954EedeAC495271d0F': '10000.0',
|
|
201
|
+
// '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '10000.0',
|
|
202
|
+
// '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '10000.00017727177059715',
|
|
203
|
+
// '0x6c5024cd4f8a59110119c56f8933403a539555eb': '10000.000080108429034461'
|
|
199
204
|
// }
|
|
200
205
|
|
|
201
|
-
|
|
206
|
+
|
|
202
207
|
// 2. For every method above you can specify the address
|
|
203
208
|
|
|
204
209
|
console.log(await saave.balances("0x0063046686E46Dc6F15918b61AE2B121458534a5"));
|
|
205
210
|
// {
|
|
206
211
|
// lpToken: '0.0',
|
|
207
212
|
// gauge: '0.0',
|
|
208
|
-
//
|
|
209
|
-
//
|
|
210
|
-
//
|
|
211
|
-
//
|
|
213
|
+
// '0x6B175474E89094C44Da98b954EedeAC495271d0F': '0.0',
|
|
214
|
+
// '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '0.0',
|
|
215
|
+
// '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '0.0',
|
|
216
|
+
// '0x6c5024cd4f8a59110119c56f8933403a539555eb': '0.0'
|
|
212
217
|
// }
|
|
213
218
|
|
|
214
219
|
// Or several addresses
|
|
@@ -217,21 +222,22 @@ import curve from "@curvefi/api";
|
|
|
217
222
|
// '0x0063046686E46Dc6F15918b61AE2B121458534a5': {
|
|
218
223
|
// lpToken: '0.0',
|
|
219
224
|
// gauge: '0.0',
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
//
|
|
225
|
+
// '0x6B175474E89094C44Da98b954EedeAC495271d0F': '0.0',
|
|
226
|
+
// '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '0.0',
|
|
227
|
+
// '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '0.0',
|
|
228
|
+
// '0x6c5024cd4f8a59110119c56f8933403a539555eb': '0.0'
|
|
224
229
|
// },
|
|
225
230
|
// '0x66aB6D9362d4F35596279692F0251Db635165871': {
|
|
226
231
|
// lpToken: '0.0',
|
|
227
232
|
// gauge: '0.0',
|
|
228
|
-
//
|
|
229
|
-
//
|
|
230
|
-
//
|
|
231
|
-
//
|
|
233
|
+
// '0x6B175474E89094C44Da98b954EedeAC495271d0F': '10000.0',
|
|
234
|
+
// '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '10000.0',
|
|
235
|
+
// '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '10000.00017727177059715',
|
|
236
|
+
// '0x6c5024cd4f8a59110119c56f8933403a539555eb': '10000.000080108429034461'
|
|
232
237
|
// }
|
|
233
238
|
// }
|
|
234
239
|
|
|
240
|
+
|
|
235
241
|
})()
|
|
236
242
|
```
|
|
237
243
|
|
|
@@ -494,7 +500,66 @@ import curve from "@curvefi/api";
|
|
|
494
500
|
})()
|
|
495
501
|
```
|
|
496
502
|
|
|
497
|
-
## Exchange
|
|
503
|
+
## Exchange
|
|
504
|
+
|
|
505
|
+
### Router exchange
|
|
506
|
+
|
|
507
|
+
```ts
|
|
508
|
+
import curve from "@curvefi/api";
|
|
509
|
+
|
|
510
|
+
(async () => {
|
|
511
|
+
await curve.init('JsonRpc', {}, { gasPrice: 0, chainId: 1 });
|
|
512
|
+
|
|
513
|
+
console.log(await curve.getBalances(['DAI', 'CRV']));
|
|
514
|
+
// [ '9900.0', '100049.744832225238317557' ]
|
|
515
|
+
|
|
516
|
+
const { route, output } = await curve.getBestRouteAndOutput('DAI', 'CRV', '1000');
|
|
517
|
+
// OR await curve.getBestPoolAndOutput('0x6B175474E89094C44Da98b954EedeAC495271d0F', '0xD533a949740bb3306d119CC777fa900bA034cd52', '10000');
|
|
518
|
+
const expected = await curve.routerExchangeExpected('DAI', 'CRV', '1000');
|
|
519
|
+
// OR await curve.exchangeExpected('0x6B175474E89094C44Da98b954EedeAC495271d0F', '0xD533a949740bb3306d119CC777fa900bA034cd52', '10000');
|
|
520
|
+
|
|
521
|
+
console.log(route, output, expected);
|
|
522
|
+
// route = [
|
|
523
|
+
// {
|
|
524
|
+
// poolId: '3pool',
|
|
525
|
+
// poolAddress: '0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7',
|
|
526
|
+
// outputCoinAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7',
|
|
527
|
+
// i: 0,
|
|
528
|
+
// j: 2,
|
|
529
|
+
// swapType: 1,
|
|
530
|
+
// swapAddress: '0x0000000000000000000000000000000000000000'
|
|
531
|
+
// },
|
|
532
|
+
// {
|
|
533
|
+
// poolId: 'tricrypto2',
|
|
534
|
+
// poolAddress: '0xD51a44d3FaE010294C616388b506AcdA1bfAAE46',
|
|
535
|
+
// outputCoinAddress: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
|
536
|
+
// i: 0,
|
|
537
|
+
// j: 2,
|
|
538
|
+
// swapType: 3,
|
|
539
|
+
// swapAddress: '0x0000000000000000000000000000000000000000'
|
|
540
|
+
// },
|
|
541
|
+
// {
|
|
542
|
+
// poolId: 'crveth',
|
|
543
|
+
// poolAddress: '0x8301AE4fc9c624d1D396cbDAa1ed877821D7C511',
|
|
544
|
+
// outputCoinAddress: '0xd533a949740bb3306d119cc777fa900ba034cd52',
|
|
545
|
+
// i: 0,
|
|
546
|
+
// j: 1,
|
|
547
|
+
// swapType: 3,
|
|
548
|
+
// swapAddress: '0x0000000000000000000000000000000000000000'
|
|
549
|
+
// }
|
|
550
|
+
// ]
|
|
551
|
+
//
|
|
552
|
+
// output = expected = 378.881631202862354937
|
|
553
|
+
|
|
554
|
+
await curve.routerExchange('DAI', 'CRV', '1000')
|
|
555
|
+
// OR await curve.exchange('0x6B175474E89094C44Da98b954EedeAC495271d0F', '0xD533a949740bb3306d119CC777fa900bA034cd52', '10000');
|
|
556
|
+
|
|
557
|
+
console.log(await curve.getBalances(['DAI', 'CRV']));
|
|
558
|
+
// [ '8900.0', '100428.626463428100672494' ]
|
|
559
|
+
})()
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Single-pool exchange
|
|
498
563
|
|
|
499
564
|
```ts
|
|
500
565
|
import curve from "@curvefi/api";
|
|
@@ -521,7 +586,7 @@ import curve from "@curvefi/api";
|
|
|
521
586
|
})()
|
|
522
587
|
```
|
|
523
588
|
|
|
524
|
-
|
|
589
|
+
### Cross-Asset Exchange
|
|
525
590
|
|
|
526
591
|
```ts
|
|
527
592
|
import curve from "@curvefi/api";
|
|
@@ -668,6 +733,10 @@ await pool.exchangeWrappedApprove("0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490",
|
|
|
668
733
|
|
|
669
734
|
### Exchange
|
|
670
735
|
```ts
|
|
736
|
+
// Router
|
|
737
|
+
await curve.routerExchangeisApproved("DAI", "0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3", "1000"); // DAI -> MIM
|
|
738
|
+
await curve.routerExchangeApprove("DAI", "0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3", "1000"); // DAI -> MIM
|
|
739
|
+
|
|
671
740
|
// Straight
|
|
672
741
|
await curve.exchangeisApproved("DAI", "0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3", "1000"); // DAI -> MIM
|
|
673
742
|
await curve.exchangeApprove("DAI", "0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3", "1000"); // DAI -> MIM
|
|
@@ -385,6 +385,36 @@
|
|
|
385
385
|
"stateMutability": "view",
|
|
386
386
|
"type": "function"
|
|
387
387
|
},
|
|
388
|
+
{
|
|
389
|
+
"gas": "278915",
|
|
390
|
+
"inputs": [
|
|
391
|
+
{
|
|
392
|
+
"name": "_route",
|
|
393
|
+
"type": "address[9]"
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
"name": "_swap_params",
|
|
397
|
+
"type": "uint256[3][4]"
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
"name": "_amount",
|
|
401
|
+
"type": "uint256"
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
"name": "_pools",
|
|
405
|
+
"type": "address[4]"
|
|
406
|
+
}
|
|
407
|
+
],
|
|
408
|
+
"name": "get_exchange_multiple_amount",
|
|
409
|
+
"outputs": [
|
|
410
|
+
{
|
|
411
|
+
"name": "",
|
|
412
|
+
"type": "uint256"
|
|
413
|
+
}
|
|
414
|
+
],
|
|
415
|
+
"stateMutability": "view",
|
|
416
|
+
"type": "function"
|
|
417
|
+
},
|
|
388
418
|
{
|
|
389
419
|
"gas": "2654",
|
|
390
420
|
"inputs": [
|
package/lib/curve.js
CHANGED
|
@@ -115,9 +115,9 @@ var Curve = /** @class */ (function () {
|
|
|
115
115
|
) {
|
|
116
116
|
if (options === void 0) { options = {}; }
|
|
117
117
|
return __awaiter(this, void 0, void 0, function () {
|
|
118
|
-
var cTokens, yTokens, ycTokens, aTokens, network, _a, customAbiTokens, _b, _i, _c, pool, _d, _e, coinAddr, _f, _g, coinAddr, _h, _j, coinAddr, _k, _l, rewardTokenAddr, addressProviderContract,
|
|
119
|
-
return __generator(this, function (
|
|
120
|
-
switch (
|
|
118
|
+
var cTokens, yTokens, ycTokens, aTokens, network, _a, customAbiTokens, _b, _i, _c, pool, _d, _e, coinAddr, _f, _g, coinAddr, _h, _j, coinAddr, _k, _l, rewardTokenAddr, _m, _o, _p, _q, _r, addressProviderContract, _s;
|
|
119
|
+
return __generator(this, function (_t) {
|
|
120
|
+
switch (_t.label) {
|
|
121
121
|
case 0:
|
|
122
122
|
// JsonRpc provider
|
|
123
123
|
if (providerType.toLowerCase() === 'JsonRpc'.toLowerCase()) {
|
|
@@ -160,8 +160,8 @@ var Curve = /** @class */ (function () {
|
|
|
160
160
|
if (_a) return [3 /*break*/, 2];
|
|
161
161
|
return [4 /*yield*/, this.provider._networkPromise];
|
|
162
162
|
case 1:
|
|
163
|
-
_a = (
|
|
164
|
-
|
|
163
|
+
_a = (_t.sent());
|
|
164
|
+
_t.label = 2;
|
|
165
165
|
case 2:
|
|
166
166
|
network = _a;
|
|
167
167
|
console.log("CURVE-JS IS CONNECTED TO NETWORK:", network);
|
|
@@ -217,75 +217,100 @@ var Curve = /** @class */ (function () {
|
|
|
217
217
|
this.multicallProvider = new ethcall_1.Provider();
|
|
218
218
|
return [4 /*yield*/, this.multicallProvider.init(this.provider)];
|
|
219
219
|
case 3:
|
|
220
|
-
|
|
220
|
+
_t.sent();
|
|
221
221
|
if (!this.signer) return [3 /*break*/, 5];
|
|
222
222
|
_b = this;
|
|
223
223
|
return [4 /*yield*/, this.signer.getAddress()];
|
|
224
224
|
case 4:
|
|
225
|
-
_b.signerAddress =
|
|
225
|
+
_b.signerAddress = _t.sent();
|
|
226
226
|
return [3 /*break*/, 6];
|
|
227
227
|
case 5:
|
|
228
228
|
this.signerAddress = '';
|
|
229
|
-
|
|
229
|
+
_t.label = 6;
|
|
230
230
|
case 6:
|
|
231
231
|
this.feeData = { gasPrice: options.gasPrice, maxFeePerGas: options.maxFeePerGas, maxPriorityFeePerGas: options.maxPriorityFeePerGas };
|
|
232
232
|
return [4 /*yield*/, this.updateFeeData()];
|
|
233
233
|
case 7:
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
234
|
+
_t.sent();
|
|
235
|
+
_i = 0, _c = Object.values(exports.POOLS_DATA);
|
|
236
|
+
_t.label = 8;
|
|
237
|
+
case 8:
|
|
238
|
+
if (!(_i < _c.length)) return [3 /*break*/, 13];
|
|
239
|
+
pool = _c[_i];
|
|
240
|
+
this.contracts[pool.swap_address] = {
|
|
241
|
+
contract: new ethers_1.Contract(pool.swap_address, pool.swap_abi, this.signer || this.provider),
|
|
242
|
+
multicallContract: new ethcall_1.Contract(pool.swap_address, pool.swap_abi),
|
|
243
|
+
};
|
|
244
|
+
this.contracts[pool.swap_address.toLowerCase()] = {
|
|
245
|
+
contract: new ethers_1.Contract(pool.swap_address, pool.swap_abi, this.signer || this.provider),
|
|
246
|
+
multicallContract: new ethcall_1.Contract(pool.swap_address, pool.swap_abi),
|
|
247
|
+
};
|
|
248
|
+
if (pool.token_address !== pool.swap_address) {
|
|
249
|
+
this.contracts[pool.token_address] = {
|
|
250
|
+
contract: new ethers_1.Contract(pool.token_address, ERC20_json_1.default, this.signer || this.provider),
|
|
251
|
+
multicallContract: new ethcall_1.Contract(pool.token_address, ERC20_json_1.default),
|
|
241
252
|
};
|
|
242
|
-
this.contracts[pool.
|
|
243
|
-
contract: new ethers_1.Contract(pool.
|
|
244
|
-
multicallContract: new ethcall_1.Contract(pool.
|
|
253
|
+
this.contracts[pool.token_address.toLowerCase()] = {
|
|
254
|
+
contract: new ethers_1.Contract(pool.token_address, ERC20_json_1.default, this.signer || this.provider),
|
|
255
|
+
multicallContract: new ethcall_1.Contract(pool.token_address, ERC20_json_1.default),
|
|
245
256
|
};
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
this.contracts[pool.
|
|
257
|
-
contract: new ethers_1.Contract(pool.
|
|
258
|
-
multicallContract: new ethcall_1.Contract(pool.
|
|
257
|
+
}
|
|
258
|
+
this.contracts[pool.gauge_address] = {
|
|
259
|
+
contract: new ethers_1.Contract(pool.gauge_address, pool.gauge_abi, this.signer || this.provider),
|
|
260
|
+
multicallContract: new ethcall_1.Contract(pool.gauge_address, pool.gauge_abi),
|
|
261
|
+
};
|
|
262
|
+
this.contracts[pool.gauge_address.toLowerCase()] = {
|
|
263
|
+
contract: new ethers_1.Contract(pool.gauge_address, pool.gauge_abi, this.signer || this.provider),
|
|
264
|
+
multicallContract: new ethcall_1.Contract(pool.gauge_address, pool.gauge_abi),
|
|
265
|
+
};
|
|
266
|
+
if (pool.deposit_address && this.contracts[pool.deposit_address] === undefined) {
|
|
267
|
+
this.contracts[pool.deposit_address] = {
|
|
268
|
+
contract: new ethers_1.Contract(pool.deposit_address, pool.deposit_abi, this.signer || this.provider),
|
|
269
|
+
multicallContract: new ethcall_1.Contract(pool.deposit_address, pool.deposit_abi),
|
|
259
270
|
};
|
|
260
|
-
this.contracts[pool.
|
|
261
|
-
contract: new ethers_1.Contract(pool.
|
|
262
|
-
multicallContract: new ethcall_1.Contract(pool.
|
|
271
|
+
this.contracts[pool.deposit_address.toLowerCase()] = {
|
|
272
|
+
contract: new ethers_1.Contract(pool.deposit_address, pool.deposit_abi, this.signer || this.provider),
|
|
273
|
+
multicallContract: new ethcall_1.Contract(pool.deposit_address, pool.deposit_abi),
|
|
263
274
|
};
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
275
|
+
}
|
|
276
|
+
for (_d = 0, _e = pool.underlying_coin_addresses; _d < _e.length; _d++) {
|
|
277
|
+
coinAddr = _e[_d];
|
|
278
|
+
this.contracts[coinAddr] = {
|
|
279
|
+
contract: new ethers_1.Contract(coinAddr, ERC20_json_1.default, this.signer || this.provider),
|
|
280
|
+
multicallContract: new ethcall_1.Contract(coinAddr, ERC20_json_1.default),
|
|
281
|
+
};
|
|
282
|
+
this.contracts[coinAddr.toLowerCase()] = {
|
|
283
|
+
contract: new ethers_1.Contract(coinAddr, ERC20_json_1.default, this.signer || this.provider),
|
|
284
|
+
multicallContract: new ethcall_1.Contract(coinAddr, ERC20_json_1.default),
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
for (_f = 0, _g = pool.coin_addresses; _f < _g.length; _f++) {
|
|
288
|
+
coinAddr = _g[_f];
|
|
289
|
+
if (customAbiTokens.includes(coinAddr))
|
|
290
|
+
continue;
|
|
291
|
+
this.contracts[coinAddr] = {
|
|
292
|
+
contract: new ethers_1.Contract(coinAddr, ERC20_json_1.default, this.signer || this.provider),
|
|
293
|
+
multicallContract: new ethcall_1.Contract(coinAddr, ERC20_json_1.default),
|
|
294
|
+
};
|
|
295
|
+
this.contracts[coinAddr.toLowerCase()] = {
|
|
296
|
+
contract: new ethers_1.Contract(coinAddr, ERC20_json_1.default, this.signer || this.provider),
|
|
297
|
+
multicallContract: new ethcall_1.Contract(coinAddr, ERC20_json_1.default),
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
// TODO add all coins
|
|
301
|
+
for (_h = 0, _j = pool.coin_addresses; _h < _j.length; _h++) {
|
|
302
|
+
coinAddr = _j[_h];
|
|
303
|
+
if (cTokens.includes(coinAddr)) {
|
|
276
304
|
this.contracts[coinAddr] = {
|
|
277
|
-
contract: new ethers_1.Contract(coinAddr,
|
|
278
|
-
multicallContract: new ethcall_1.Contract(coinAddr,
|
|
305
|
+
contract: new ethers_1.Contract(coinAddr, cERC20_json_1.default, this.signer || this.provider),
|
|
306
|
+
multicallContract: new ethcall_1.Contract(coinAddr, cERC20_json_1.default),
|
|
279
307
|
};
|
|
280
308
|
this.contracts[coinAddr.toLowerCase()] = {
|
|
281
|
-
contract: new ethers_1.Contract(coinAddr,
|
|
282
|
-
multicallContract: new ethcall_1.Contract(coinAddr,
|
|
309
|
+
contract: new ethers_1.Contract(coinAddr, cERC20_json_1.default, this.signer || this.provider),
|
|
310
|
+
multicallContract: new ethcall_1.Contract(coinAddr, cERC20_json_1.default),
|
|
283
311
|
};
|
|
284
312
|
}
|
|
285
|
-
|
|
286
|
-
coinAddr = _g[_f];
|
|
287
|
-
if (customAbiTokens.includes(coinAddr))
|
|
288
|
-
continue;
|
|
313
|
+
if (aTokens.includes(coinAddr)) {
|
|
289
314
|
this.contracts[coinAddr] = {
|
|
290
315
|
contract: new ethers_1.Contract(coinAddr, ERC20_json_1.default, this.signer || this.provider),
|
|
291
316
|
multicallContract: new ethcall_1.Contract(coinAddr, ERC20_json_1.default),
|
|
@@ -295,62 +320,56 @@ var Curve = /** @class */ (function () {
|
|
|
295
320
|
multicallContract: new ethcall_1.Contract(coinAddr, ERC20_json_1.default),
|
|
296
321
|
};
|
|
297
322
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
this.contracts[coinAddr] = {
|
|
303
|
-
contract: new ethers_1.Contract(coinAddr, cERC20_json_1.default, this.signer || this.provider),
|
|
304
|
-
multicallContract: new ethcall_1.Contract(coinAddr, cERC20_json_1.default),
|
|
305
|
-
};
|
|
306
|
-
this.contracts[coinAddr.toLowerCase()] = {
|
|
307
|
-
contract: new ethers_1.Contract(coinAddr, cERC20_json_1.default, this.signer || this.provider),
|
|
308
|
-
multicallContract: new ethcall_1.Contract(coinAddr, cERC20_json_1.default),
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
if (aTokens.includes(coinAddr)) {
|
|
312
|
-
this.contracts[coinAddr] = {
|
|
313
|
-
contract: new ethers_1.Contract(coinAddr, ERC20_json_1.default, this.signer || this.provider),
|
|
314
|
-
multicallContract: new ethcall_1.Contract(coinAddr, ERC20_json_1.default),
|
|
315
|
-
};
|
|
316
|
-
this.contracts[coinAddr.toLowerCase()] = {
|
|
317
|
-
contract: new ethers_1.Contract(coinAddr, ERC20_json_1.default, this.signer || this.provider),
|
|
318
|
-
multicallContract: new ethcall_1.Contract(coinAddr, ERC20_json_1.default),
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
if (yTokens.includes(coinAddr) || ycTokens.includes(coinAddr)) {
|
|
322
|
-
this.contracts[coinAddr] = {
|
|
323
|
-
contract: new ethers_1.Contract(coinAddr, yERC20_json_1.default, this.signer || this.provider),
|
|
324
|
-
multicallContract: new ethcall_1.Contract(coinAddr, yERC20_json_1.default),
|
|
325
|
-
};
|
|
326
|
-
this.contracts[coinAddr.toLowerCase()] = {
|
|
327
|
-
contract: new ethers_1.Contract(coinAddr, yERC20_json_1.default, this.signer || this.provider),
|
|
328
|
-
multicallContract: new ethcall_1.Contract(coinAddr, yERC20_json_1.default),
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
if (pool.reward_contract) {
|
|
333
|
-
this.contracts[pool.reward_contract] = {
|
|
334
|
-
contract: new ethers_1.Contract(pool.reward_contract, streamer_json_1.default, this.signer || this.provider),
|
|
335
|
-
multicallContract: new ethcall_1.Contract(pool.reward_contract, streamer_json_1.default),
|
|
336
|
-
};
|
|
337
|
-
this.contracts[pool.reward_contract.toLowerCase()] = {
|
|
338
|
-
contract: new ethers_1.Contract(pool.reward_contract, streamer_json_1.default, this.signer || this.provider),
|
|
339
|
-
multicallContract: new ethcall_1.Contract(pool.reward_contract, streamer_json_1.default),
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
for (_k = 0, _l = pool.reward_tokens || []; _k < _l.length; _k++) {
|
|
343
|
-
rewardTokenAddr = _l[_k];
|
|
344
|
-
this.contracts[rewardTokenAddr] = {
|
|
345
|
-
contract: new ethers_1.Contract(rewardTokenAddr, ERC20_json_1.default, this.signer || this.provider),
|
|
346
|
-
multicallContract: new ethcall_1.Contract(rewardTokenAddr, ERC20_json_1.default),
|
|
323
|
+
if (yTokens.includes(coinAddr) || ycTokens.includes(coinAddr)) {
|
|
324
|
+
this.contracts[coinAddr] = {
|
|
325
|
+
contract: new ethers_1.Contract(coinAddr, yERC20_json_1.default, this.signer || this.provider),
|
|
326
|
+
multicallContract: new ethcall_1.Contract(coinAddr, yERC20_json_1.default),
|
|
347
327
|
};
|
|
348
|
-
this.contracts[
|
|
349
|
-
contract: new ethers_1.Contract(
|
|
350
|
-
multicallContract: new ethcall_1.Contract(
|
|
328
|
+
this.contracts[coinAddr.toLowerCase()] = {
|
|
329
|
+
contract: new ethers_1.Contract(coinAddr, yERC20_json_1.default, this.signer || this.provider),
|
|
330
|
+
multicallContract: new ethcall_1.Contract(coinAddr, yERC20_json_1.default),
|
|
351
331
|
};
|
|
352
332
|
}
|
|
353
333
|
}
|
|
334
|
+
if (pool.reward_contract) {
|
|
335
|
+
this.contracts[pool.reward_contract] = {
|
|
336
|
+
contract: new ethers_1.Contract(pool.reward_contract, streamer_json_1.default, this.signer || this.provider),
|
|
337
|
+
multicallContract: new ethcall_1.Contract(pool.reward_contract, streamer_json_1.default),
|
|
338
|
+
};
|
|
339
|
+
this.contracts[pool.reward_contract.toLowerCase()] = {
|
|
340
|
+
contract: new ethers_1.Contract(pool.reward_contract, streamer_json_1.default, this.signer || this.provider),
|
|
341
|
+
multicallContract: new ethcall_1.Contract(pool.reward_contract, streamer_json_1.default),
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
_k = 0, _l = pool.reward_tokens || [];
|
|
345
|
+
_t.label = 9;
|
|
346
|
+
case 9:
|
|
347
|
+
if (!(_k < _l.length)) return [3 /*break*/, 12];
|
|
348
|
+
rewardTokenAddr = _l[_k];
|
|
349
|
+
this.contracts[rewardTokenAddr] = {
|
|
350
|
+
contract: new ethers_1.Contract(rewardTokenAddr, ERC20_json_1.default, this.signer || this.provider),
|
|
351
|
+
multicallContract: new ethcall_1.Contract(rewardTokenAddr, ERC20_json_1.default),
|
|
352
|
+
};
|
|
353
|
+
this.contracts[rewardTokenAddr.toLowerCase()] = {
|
|
354
|
+
contract: new ethers_1.Contract(rewardTokenAddr, ERC20_json_1.default, this.signer || this.provider),
|
|
355
|
+
multicallContract: new ethcall_1.Contract(rewardTokenAddr, ERC20_json_1.default),
|
|
356
|
+
};
|
|
357
|
+
_m = exports.DECIMALS_LOWER_CASE;
|
|
358
|
+
_o = rewardTokenAddr.toLowerCase();
|
|
359
|
+
_p = Number;
|
|
360
|
+
_r = (_q = ethers_1.ethers.utils).formatUnits;
|
|
361
|
+
return [4 /*yield*/, this.contracts[rewardTokenAddr].contract.decimals()];
|
|
362
|
+
case 10:
|
|
363
|
+
_m[_o] =
|
|
364
|
+
_p.apply(void 0, [_r.apply(_q, [_t.sent(), 0])]);
|
|
365
|
+
_t.label = 11;
|
|
366
|
+
case 11:
|
|
367
|
+
_k++;
|
|
368
|
+
return [3 /*break*/, 9];
|
|
369
|
+
case 12:
|
|
370
|
+
_i++;
|
|
371
|
+
return [3 /*break*/, 8];
|
|
372
|
+
case 13:
|
|
354
373
|
this.contracts[exports.ALIASES.crv] = {
|
|
355
374
|
contract: new ethers_1.Contract(exports.ALIASES.crv, ERC20_json_1.default, this.signer || this.provider),
|
|
356
375
|
multicallContract: new ethcall_1.Contract(exports.ALIASES.crv, ERC20_json_1.default),
|
|
@@ -384,10 +403,10 @@ var Curve = /** @class */ (function () {
|
|
|
384
403
|
multicallContract: new ethcall_1.Contract(exports.ALIASES.address_provider, address_provider_json_1.default),
|
|
385
404
|
};
|
|
386
405
|
addressProviderContract = this.contracts[exports.ALIASES.address_provider].contract;
|
|
387
|
-
|
|
406
|
+
_s = exports.ALIASES;
|
|
388
407
|
return [4 /*yield*/, addressProviderContract.get_address(2, this.constantOptions)];
|
|
389
|
-
case
|
|
390
|
-
|
|
408
|
+
case 14:
|
|
409
|
+
_s.registry_exchange = _t.sent();
|
|
391
410
|
this.contracts[exports.ALIASES.registry_exchange] = {
|
|
392
411
|
contract: new ethers_1.Contract(exports.ALIASES.registry_exchange, registry_exchange_json_1.default, this.signer || this.provider),
|
|
393
412
|
multicallContract: new ethcall_1.Contract(exports.ALIASES.registry_exchange, registry_exchange_json_1.default),
|
package/lib/index.d.ts
CHANGED
|
@@ -58,12 +58,22 @@ declare const curve: {
|
|
|
58
58
|
crossAssetExchangeApprove: (inputCoin: string, amount: string) => Promise<string[]>;
|
|
59
59
|
crossAssetExchange: (inputCoin: string, outputCoin: string, amount: string, maxSlippage?: number) => Promise<string>;
|
|
60
60
|
getUserPoolList: (address?: string | undefined) => Promise<string[]>;
|
|
61
|
+
getBestRouteAndOutput: (inputCoin: string, outputCoin: string, amount: string) => Promise<{
|
|
62
|
+
route: import("./interfaces").IRouteStep[];
|
|
63
|
+
output: string;
|
|
64
|
+
}>;
|
|
65
|
+
routerExchangeExpected: (inputCoin: string, outputCoin: string, amount: string) => Promise<string>;
|
|
66
|
+
routerExchangeIsApproved: (inputCoin: string, amount: string) => Promise<boolean>;
|
|
67
|
+
routerExchangeApprove: (inputCoin: string, amount: string) => Promise<string[]>;
|
|
68
|
+
routerExchange: (inputCoin: string, outputCoin: string, amount: string, maxSlippage?: number) => Promise<string>;
|
|
61
69
|
estimateGas: {
|
|
62
70
|
ensureAllowance: (coins: string[], amounts: string[], spender: string) => Promise<number>;
|
|
63
71
|
exchangeApprove: (inputCoin: string, outputCoin: string, amount: string) => Promise<number>;
|
|
64
72
|
exchange: (inputCoin: string, outputCoin: string, amount: string, maxSlippage?: number) => Promise<number>;
|
|
65
73
|
crossAssetExchangeApprove: (inputCoin: string, amount: string) => Promise<number>;
|
|
66
74
|
crossAssetExchange: (inputCoin: string, outputCoin: string, amount: string, maxSlippage?: number) => Promise<number>;
|
|
75
|
+
routerExchangeApprove: (inputCoin: string, amount: string) => Promise<number>;
|
|
76
|
+
routerExchange: (inputCoin: string, outputCoin: string, amount: string) => Promise<number>;
|
|
67
77
|
};
|
|
68
78
|
boosting: {
|
|
69
79
|
getCrv: (...addresses: string[] | string[][]) => Promise<string | import("./interfaces").DictInterface<string>>;
|
package/lib/index.js
CHANGED
|
@@ -115,12 +115,19 @@ var curve = {
|
|
|
115
115
|
crossAssetExchangeApprove: pools_1.crossAssetExchangeApprove,
|
|
116
116
|
crossAssetExchange: pools_1.crossAssetExchange,
|
|
117
117
|
getUserPoolList: pools_1.getUserPoolList,
|
|
118
|
+
getBestRouteAndOutput: pools_1.getBestRouteAndOutput,
|
|
119
|
+
routerExchangeExpected: pools_1.routerExchangeExpected,
|
|
120
|
+
routerExchangeIsApproved: pools_1.routerExchangeIsApproved,
|
|
121
|
+
routerExchangeApprove: pools_1.routerExchangeApprove,
|
|
122
|
+
routerExchange: pools_1.routerExchange,
|
|
118
123
|
estimateGas: {
|
|
119
124
|
ensureAllowance: utils_1.ensureAllowanceEstimateGas,
|
|
120
125
|
exchangeApprove: pools_1.exchangeApproveEstimateGas,
|
|
121
126
|
exchange: pools_1.exchangeEstimateGas,
|
|
122
127
|
crossAssetExchangeApprove: pools_1.crossAssetExchangeApproveEstimateGas,
|
|
123
128
|
crossAssetExchange: pools_1.crossAssetExchangeEstimateGas,
|
|
129
|
+
routerExchangeApprove: pools_1.routerExchangeApproveEstimateGas,
|
|
130
|
+
routerExchange: pools_1.routerExchangeEstimateGas,
|
|
124
131
|
},
|
|
125
132
|
boosting: {
|
|
126
133
|
getCrv: boosting_1.getCrv,
|
package/lib/interfaces.d.ts
CHANGED
|
@@ -134,9 +134,24 @@ export interface ISinglePoolSwapData {
|
|
|
134
134
|
poolAddress: string;
|
|
135
135
|
i: number;
|
|
136
136
|
j: number;
|
|
137
|
-
swapType: 1 | 2 | 3 | 4;
|
|
137
|
+
swapType: 1 | 2 | 3 | 4 | 5;
|
|
138
138
|
swapAddress: string;
|
|
139
139
|
}
|
|
140
140
|
export interface ISinglePoolSwapDataAndOutput extends ISinglePoolSwapData {
|
|
141
141
|
_output: ethers.BigNumber;
|
|
142
142
|
}
|
|
143
|
+
export interface IRouteStep {
|
|
144
|
+
poolId: string;
|
|
145
|
+
poolAddress: string;
|
|
146
|
+
outputCoinAddress: string;
|
|
147
|
+
i: number;
|
|
148
|
+
j: number;
|
|
149
|
+
swapType: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
|
150
|
+
swapAddress: string;
|
|
151
|
+
}
|
|
152
|
+
export interface IRoute {
|
|
153
|
+
steps: IRouteStep[];
|
|
154
|
+
_output: ethers.BigNumber;
|
|
155
|
+
outputUsd: number;
|
|
156
|
+
txCostUsd: number;
|
|
157
|
+
}
|
package/lib/pools.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ethers } from "ethers";
|
|
2
2
|
import BigNumber from 'bignumber.js';
|
|
3
|
-
import { DictInterface, RewardsApyInterface } from './interfaces';
|
|
3
|
+
import { DictInterface, IRouteStep, RewardsApyInterface } from './interfaces';
|
|
4
4
|
export declare class Pool {
|
|
5
5
|
id: string;
|
|
6
6
|
name: string;
|
|
@@ -254,3 +254,14 @@ export declare const crossAssetExchangeApprove: (inputCoin: string, amount: stri
|
|
|
254
254
|
export declare const crossAssetExchangeEstimateGas: (inputCoin: string, outputCoin: string, amount: string, maxSlippage?: number) => Promise<number>;
|
|
255
255
|
export declare const crossAssetExchange: (inputCoin: string, outputCoin: string, amount: string, maxSlippage?: number) => Promise<string>;
|
|
256
256
|
export declare const getUserPoolList: (address?: string | undefined) => Promise<string[]>;
|
|
257
|
+
export declare const _findAllRoutes: (inputCoinAddress: string, outputCoinAddress: string) => Promise<IRouteStep[][]>;
|
|
258
|
+
export declare const getBestRouteAndOutput: (inputCoin: string, outputCoin: string, amount: string) => Promise<{
|
|
259
|
+
route: IRouteStep[];
|
|
260
|
+
output: string;
|
|
261
|
+
}>;
|
|
262
|
+
export declare const routerExchangeExpected: (inputCoin: string, outputCoin: string, amount: string) => Promise<string>;
|
|
263
|
+
export declare const routerExchangeIsApproved: (inputCoin: string, amount: string) => Promise<boolean>;
|
|
264
|
+
export declare const routerExchangeApproveEstimateGas: (inputCoin: string, amount: string) => Promise<number>;
|
|
265
|
+
export declare const routerExchangeApprove: (inputCoin: string, amount: string) => Promise<string[]>;
|
|
266
|
+
export declare const routerExchangeEstimateGas: (inputCoin: string, outputCoin: string, amount: string) => Promise<number>;
|
|
267
|
+
export declare const routerExchange: (inputCoin: string, outputCoin: string, amount: string, maxSlippage?: number) => Promise<string>;
|
package/lib/pools.js
CHANGED
|
@@ -59,9 +59,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
59
59
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
60
60
|
};
|
|
61
61
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
62
|
-
exports.getUserPoolList = exports.crossAssetExchange = exports.crossAssetExchangeEstimateGas = exports.crossAssetExchangeApprove = exports.crossAssetExchangeApproveEstimateGas = exports.crossAssetExchangeIsApproved = exports.crossAssetExchangeExpected = exports.crossAssetExchangeOutputAndSlippage = exports._crossAssetExchangeInfo = exports._getSmallAmountForCoin = exports.crossAssetExchangeAvailable = exports.exchange = exports.exchangeEstimateGas = exports.exchangeApprove = exports.exchangeApproveEstimateGas = exports.exchangeIsApproved = exports.exchangeExpected = exports.getBestPoolAndOutput = exports.Pool = void 0;
|
|
62
|
+
exports.routerExchange = exports.routerExchangeEstimateGas = exports.routerExchangeApprove = exports.routerExchangeApproveEstimateGas = exports.routerExchangeIsApproved = exports.routerExchangeExpected = exports.getBestRouteAndOutput = exports._findAllRoutes = exports.getUserPoolList = exports.crossAssetExchange = exports.crossAssetExchangeEstimateGas = exports.crossAssetExchangeApprove = exports.crossAssetExchangeApproveEstimateGas = exports.crossAssetExchangeIsApproved = exports.crossAssetExchangeExpected = exports.crossAssetExchangeOutputAndSlippage = exports._crossAssetExchangeInfo = exports._getSmallAmountForCoin = exports.crossAssetExchangeAvailable = exports.exchange = exports.exchangeEstimateGas = exports.exchangeApprove = exports.exchangeApproveEstimateGas = exports.exchangeIsApproved = exports.exchangeExpected = exports.getBestPoolAndOutput = exports.Pool = void 0;
|
|
63
63
|
var axios_1 = __importDefault(require("axios"));
|
|
64
64
|
var ethers_1 = require("ethers");
|
|
65
|
+
var memoizee_1 = __importDefault(require("memoizee"));
|
|
65
66
|
var external_api_1 = require("./external-api");
|
|
66
67
|
var utils_1 = require("./utils");
|
|
67
68
|
var curve_1 = require("./curve");
|
|
@@ -2025,9 +2026,9 @@ var Pool = /** @class */ (function () {
|
|
|
2025
2026
|
switch (_a.label) {
|
|
2026
2027
|
case 0:
|
|
2027
2028
|
if (!(this.gauge === ethers_1.ethers.constants.AddressZero)) return [3 /*break*/, 2];
|
|
2028
|
-
return [4 /*yield*/, this._balances.apply(this, __spreadArray([__spreadArray(__spreadArray(['lpToken'], this.
|
|
2029
|
+
return [4 /*yield*/, this._balances.apply(this, __spreadArray([__spreadArray(__spreadArray(['lpToken'], this.underlyingCoinAddresses, true), this.coinAddresses, true), __spreadArray(__spreadArray([this.lpToken], this.underlyingCoinAddresses, true), this.coinAddresses, true)], addresses, false))];
|
|
2029
2030
|
case 1: return [2 /*return*/, _a.sent()];
|
|
2030
|
-
case 2: return [4 /*yield*/, this._balances.apply(this, __spreadArray([__spreadArray(__spreadArray(['lpToken', 'gauge'], this.
|
|
2031
|
+
case 2: return [4 /*yield*/, this._balances.apply(this, __spreadArray([__spreadArray(__spreadArray(['lpToken', 'gauge'], this.underlyingCoinAddresses, true), this.coinAddresses, true), __spreadArray(__spreadArray([this.lpToken, this.gauge], this.underlyingCoinAddresses, true), this.coinAddresses, true)], addresses, false))];
|
|
2031
2032
|
case 3: return [2 /*return*/, _a.sent()];
|
|
2032
2033
|
}
|
|
2033
2034
|
});
|
|
@@ -2059,7 +2060,7 @@ var Pool = /** @class */ (function () {
|
|
|
2059
2060
|
return __awaiter(_this, void 0, void 0, function () {
|
|
2060
2061
|
return __generator(this, function (_a) {
|
|
2061
2062
|
switch (_a.label) {
|
|
2062
|
-
case 0: return [4 /*yield*/, this._balances.apply(this, __spreadArray([this.
|
|
2063
|
+
case 0: return [4 /*yield*/, this._balances.apply(this, __spreadArray([this.underlyingCoinAddresses, this.underlyingCoinAddresses], addresses, false))];
|
|
2063
2064
|
case 1: return [2 /*return*/, _a.sent()];
|
|
2064
2065
|
}
|
|
2065
2066
|
});
|
|
@@ -2073,7 +2074,7 @@ var Pool = /** @class */ (function () {
|
|
|
2073
2074
|
return __awaiter(_this, void 0, void 0, function () {
|
|
2074
2075
|
return __generator(this, function (_a) {
|
|
2075
2076
|
switch (_a.label) {
|
|
2076
|
-
case 0: return [4 /*yield*/, this._balances.apply(this, __spreadArray([this.
|
|
2077
|
+
case 0: return [4 /*yield*/, this._balances.apply(this, __spreadArray([this.coinAddresses, this.coinAddresses], addresses, false))];
|
|
2077
2078
|
case 1: return [2 /*return*/, _a.sent()];
|
|
2078
2079
|
}
|
|
2079
2080
|
});
|
|
@@ -2087,7 +2088,7 @@ var Pool = /** @class */ (function () {
|
|
|
2087
2088
|
return __awaiter(_this, void 0, void 0, function () {
|
|
2088
2089
|
return __generator(this, function (_a) {
|
|
2089
2090
|
switch (_a.label) {
|
|
2090
|
-
case 0: return [4 /*yield*/, this._balances.apply(this, __spreadArray([__spreadArray(__spreadArray([], this.
|
|
2091
|
+
case 0: return [4 /*yield*/, this._balances.apply(this, __spreadArray([__spreadArray(__spreadArray([], this.underlyingCoinAddresses, true), this.coinAddresses, true), __spreadArray(__spreadArray([], this.underlyingCoinAddresses, true), this.coinAddresses, true)], addresses, false))];
|
|
2091
2092
|
case 1: return [2 /*return*/, _a.sent()];
|
|
2092
2093
|
}
|
|
2093
2094
|
});
|
|
@@ -4180,3 +4181,560 @@ var getUserPoolList = function (address) { return __awaiter(void 0, void 0, void
|
|
|
4180
4181
|
});
|
|
4181
4182
|
}); };
|
|
4182
4183
|
exports.getUserPoolList = getUserPoolList;
|
|
4184
|
+
// --------- Multi-Pool Exchange ---------
|
|
4185
|
+
// TODO make working or remove
|
|
4186
|
+
var IMBALANCED_POOLS = [];
|
|
4187
|
+
// Inspired by Dijkstra's algorithm
|
|
4188
|
+
var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __awaiter(void 0, void 0, void 0, function () {
|
|
4189
|
+
var ALL_POOLS, basePoolsSet, _i, ALL_POOLS_1, pool, basePoolIds, markedCoins, curCoins, nextCoins, routes, step, _a, curCoins_1, inCoin, _c, ALL_POOLS_2, _d, poolId, poolData, coin_addresses, underlying_coin_addresses, meta_coin_addresses, token_address, is_lending, inCoinIndexes, j, swapType, _e, _f, inCoinRoute, swapType, _h, _j, inCoinRoute, j, tvl, _k, swapType, _l, _m, inCoinRoute, poolAddress, j, tvl, _o, swapType, _p, _q, inCoinRoute, j, tvl, _r, swapType, _s, _t, inCoinRoute, tvl, _u, swapType, _v, _w, inCoinRoute;
|
|
4190
|
+
var _x;
|
|
4191
|
+
var _y, _z, _0, _1, _2, _3, _4, _5;
|
|
4192
|
+
return __generator(this, function (_6) {
|
|
4193
|
+
switch (_6.label) {
|
|
4194
|
+
case 0:
|
|
4195
|
+
inputCoinAddress = inputCoinAddress.toLowerCase();
|
|
4196
|
+
outputCoinAddress = outputCoinAddress.toLowerCase();
|
|
4197
|
+
ALL_POOLS = Object.entries(__assign(__assign(__assign({}, curve_1.POOLS_DATA), curve_1.curve.constants.FACTORY_POOLS_DATA), curve_1.curve.constants.CRYPTO_FACTORY_POOLS_DATA));
|
|
4198
|
+
basePoolsSet = new Set();
|
|
4199
|
+
for (_i = 0, ALL_POOLS_1 = ALL_POOLS; _i < ALL_POOLS_1.length; _i++) {
|
|
4200
|
+
pool = ALL_POOLS_1[_i];
|
|
4201
|
+
if (pool[1].base_pool)
|
|
4202
|
+
basePoolsSet.add(pool[1].base_pool);
|
|
4203
|
+
}
|
|
4204
|
+
basePoolIds = Array.from(basePoolsSet);
|
|
4205
|
+
markedCoins = [];
|
|
4206
|
+
curCoins = [inputCoinAddress];
|
|
4207
|
+
nextCoins = new Set();
|
|
4208
|
+
routes = (_x = {},
|
|
4209
|
+
_x[inputCoinAddress] = [[]],
|
|
4210
|
+
_x);
|
|
4211
|
+
step = 0;
|
|
4212
|
+
_6.label = 1;
|
|
4213
|
+
case 1:
|
|
4214
|
+
if (!(step < 4)) return [3 /*break*/, 21];
|
|
4215
|
+
_a = 0, curCoins_1 = curCoins;
|
|
4216
|
+
_6.label = 2;
|
|
4217
|
+
case 2:
|
|
4218
|
+
if (!(_a < curCoins_1.length)) return [3 /*break*/, 19];
|
|
4219
|
+
inCoin = curCoins_1[_a];
|
|
4220
|
+
_c = 0, ALL_POOLS_2 = ALL_POOLS;
|
|
4221
|
+
_6.label = 3;
|
|
4222
|
+
case 3:
|
|
4223
|
+
if (!(_c < ALL_POOLS_2.length)) return [3 /*break*/, 18];
|
|
4224
|
+
_d = ALL_POOLS_2[_c], poolId = _d[0], poolData = _d[1];
|
|
4225
|
+
coin_addresses = poolData.coin_addresses.map(function (a) { return a.toLowerCase(); });
|
|
4226
|
+
underlying_coin_addresses = poolData.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); });
|
|
4227
|
+
meta_coin_addresses = ((_y = poolData.meta_coin_addresses) === null || _y === void 0 ? void 0 : _y.map(function (a) { return a.toLowerCase(); })) || [];
|
|
4228
|
+
token_address = poolData.token_address.toLowerCase();
|
|
4229
|
+
is_lending = poolData.use_lending.includes(true);
|
|
4230
|
+
inCoinIndexes = {
|
|
4231
|
+
coin: coin_addresses.indexOf(inCoin),
|
|
4232
|
+
underlying_coin: underlying_coin_addresses.indexOf(inCoin),
|
|
4233
|
+
meta_coin: meta_coin_addresses ? meta_coin_addresses.indexOf(inCoin) : -1,
|
|
4234
|
+
};
|
|
4235
|
+
// Find all LP -> underlying coin "swaps" (actually remove_liquidity_one_coin)
|
|
4236
|
+
if (basePoolIds.includes(poolId) && inCoin === token_address) {
|
|
4237
|
+
for (j = 0; j < underlying_coin_addresses.length; j++) {
|
|
4238
|
+
// If this coin already marked or will be marked on the current step, no need to consider it on the next step
|
|
4239
|
+
if (markedCoins.includes(underlying_coin_addresses[j]) || curCoins.includes(underlying_coin_addresses[j]))
|
|
4240
|
+
continue;
|
|
4241
|
+
// Looking for outputCoinAddress only on the final step
|
|
4242
|
+
if (step === 3 && underlying_coin_addresses[j] !== outputCoinAddress)
|
|
4243
|
+
continue;
|
|
4244
|
+
swapType = poolId === 'aave' ? 10 : 9;
|
|
4245
|
+
for (_e = 0, _f = routes[inCoin]; _e < _f.length; _e++) {
|
|
4246
|
+
inCoinRoute = _f[_e];
|
|
4247
|
+
routes[underlying_coin_addresses[j]] = ((_z = routes[underlying_coin_addresses[j]]) !== null && _z !== void 0 ? _z : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
4248
|
+
{
|
|
4249
|
+
poolId: poolId,
|
|
4250
|
+
poolAddress: poolData.swap_address,
|
|
4251
|
+
outputCoinAddress: underlying_coin_addresses[j],
|
|
4252
|
+
i: 0,
|
|
4253
|
+
j: j,
|
|
4254
|
+
swapType: swapType,
|
|
4255
|
+
swapAddress: ethers_1.ethers.constants.AddressZero,
|
|
4256
|
+
},
|
|
4257
|
+
], false)]);
|
|
4258
|
+
}
|
|
4259
|
+
nextCoins.add(underlying_coin_addresses[j]);
|
|
4260
|
+
}
|
|
4261
|
+
}
|
|
4262
|
+
// Find all underlying coin -> LP "swaps" (actually add_liquidity)
|
|
4263
|
+
if (basePoolIds.includes(poolId) && underlying_coin_addresses.includes(inCoin)) {
|
|
4264
|
+
// If this coin already marked or will be marked on the current step, no need to consider it on the next step
|
|
4265
|
+
if (markedCoins.includes(token_address) || curCoins.includes(token_address))
|
|
4266
|
+
return [3 /*break*/, 17];
|
|
4267
|
+
// Looking for outputCoinAddress only on the final step
|
|
4268
|
+
if (step === 3 && token_address !== outputCoinAddress)
|
|
4269
|
+
return [3 /*break*/, 17];
|
|
4270
|
+
swapType = is_lending ? 8 : underlying_coin_addresses.length === 2 ? 6 : 7;
|
|
4271
|
+
for (_h = 0, _j = routes[inCoin]; _h < _j.length; _h++) {
|
|
4272
|
+
inCoinRoute = _j[_h];
|
|
4273
|
+
routes[token_address] = ((_0 = routes[token_address]) !== null && _0 !== void 0 ? _0 : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
4274
|
+
{
|
|
4275
|
+
poolId: poolId,
|
|
4276
|
+
poolAddress: poolData.swap_address,
|
|
4277
|
+
outputCoinAddress: token_address,
|
|
4278
|
+
i: underlying_coin_addresses.indexOf(inCoin),
|
|
4279
|
+
j: 0,
|
|
4280
|
+
swapType: swapType,
|
|
4281
|
+
swapAddress: ethers_1.ethers.constants.AddressZero,
|
|
4282
|
+
},
|
|
4283
|
+
], false)]);
|
|
4284
|
+
}
|
|
4285
|
+
nextCoins.add(token_address);
|
|
4286
|
+
}
|
|
4287
|
+
// No input coin in this pool --> skip
|
|
4288
|
+
if (inCoinIndexes.coin === -1 && inCoinIndexes.underlying_coin === -1 && inCoinIndexes.meta_coin === -1)
|
|
4289
|
+
return [3 /*break*/, 17];
|
|
4290
|
+
if (!(inCoinIndexes.coin >= 0 && poolId !== "atricrypto3")) return [3 /*break*/, 7];
|
|
4291
|
+
j = 0;
|
|
4292
|
+
_6.label = 4;
|
|
4293
|
+
case 4:
|
|
4294
|
+
if (!(j < coin_addresses.length)) return [3 /*break*/, 7];
|
|
4295
|
+
// If this coin already marked or will be marked on the current step, no need to consider it on the next step
|
|
4296
|
+
if (markedCoins.includes(coin_addresses[j]) || curCoins.includes(coin_addresses[j]))
|
|
4297
|
+
return [3 /*break*/, 6];
|
|
4298
|
+
// Looking for outputCoinAddress only on the final step
|
|
4299
|
+
if (step === 3 && coin_addresses[j] !== outputCoinAddress)
|
|
4300
|
+
return [3 /*break*/, 6];
|
|
4301
|
+
_k = Number;
|
|
4302
|
+
return [4 /*yield*/, (new Pool(poolId)).stats.getTotalLiquidity()];
|
|
4303
|
+
case 5:
|
|
4304
|
+
tvl = _k.apply(void 0, [_6.sent()]);
|
|
4305
|
+
if (tvl === 0)
|
|
4306
|
+
return [3 /*break*/, 6];
|
|
4307
|
+
// Skip imbalanced pools
|
|
4308
|
+
if (IMBALANCED_POOLS.includes(poolId))
|
|
4309
|
+
return [3 /*break*/, 6];
|
|
4310
|
+
swapType = poolData.is_crypto ? 3 : 1;
|
|
4311
|
+
for (_l = 0, _m = routes[inCoin]; _l < _m.length; _l++) {
|
|
4312
|
+
inCoinRoute = _m[_l];
|
|
4313
|
+
routes[coin_addresses[j]] = ((_1 = routes[coin_addresses[j]]) !== null && _1 !== void 0 ? _1 : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
4314
|
+
{
|
|
4315
|
+
poolId: poolId,
|
|
4316
|
+
poolAddress: poolData.swap_address,
|
|
4317
|
+
outputCoinAddress: coin_addresses[j],
|
|
4318
|
+
i: inCoinIndexes.coin,
|
|
4319
|
+
j: j,
|
|
4320
|
+
swapType: swapType,
|
|
4321
|
+
swapAddress: ethers_1.ethers.constants.AddressZero,
|
|
4322
|
+
},
|
|
4323
|
+
], false)]);
|
|
4324
|
+
}
|
|
4325
|
+
nextCoins.add(coin_addresses[j]);
|
|
4326
|
+
_6.label = 6;
|
|
4327
|
+
case 6:
|
|
4328
|
+
j++;
|
|
4329
|
+
return [3 /*break*/, 4];
|
|
4330
|
+
case 7:
|
|
4331
|
+
poolAddress = ["eurtusd", "xautusd", "atricrypto3"].includes(poolId) ||
|
|
4332
|
+
(curve_1.curve.chainId === 137 && poolData.is_factory) ? poolData.deposit_address : poolData.swap_address;
|
|
4333
|
+
if (!(coin_addresses.join("|") !== underlying_coin_addresses.join("|") && inCoinIndexes.underlying_coin >= 0)) return [3 /*break*/, 11];
|
|
4334
|
+
j = 0;
|
|
4335
|
+
_6.label = 8;
|
|
4336
|
+
case 8:
|
|
4337
|
+
if (!(j < underlying_coin_addresses.length)) return [3 /*break*/, 11];
|
|
4338
|
+
if (poolId === "atricrypto3" && inCoinIndexes.meta_coin >= 0 && meta_coin_addresses.includes(underlying_coin_addresses[j]))
|
|
4339
|
+
return [3 /*break*/, 10];
|
|
4340
|
+
// If this coin already marked or will be marked on the current step, no need to consider it on the next step
|
|
4341
|
+
if (markedCoins.includes(underlying_coin_addresses[j]) || curCoins.includes(underlying_coin_addresses[j]))
|
|
4342
|
+
return [3 /*break*/, 10];
|
|
4343
|
+
// Looking for outputCoinAddress only on the final step
|
|
4344
|
+
if (step === 3 && underlying_coin_addresses[j] !== outputCoinAddress)
|
|
4345
|
+
return [3 /*break*/, 10];
|
|
4346
|
+
_o = Number;
|
|
4347
|
+
return [4 /*yield*/, (new Pool(poolId)).stats.getTotalLiquidity()];
|
|
4348
|
+
case 9:
|
|
4349
|
+
tvl = _o.apply(void 0, [_6.sent()]);
|
|
4350
|
+
if (tvl === 0)
|
|
4351
|
+
return [3 /*break*/, 10];
|
|
4352
|
+
// Skip imbalanced pools
|
|
4353
|
+
if (IMBALANCED_POOLS.includes(poolId))
|
|
4354
|
+
return [3 /*break*/, 10];
|
|
4355
|
+
swapType = poolData.is_crypto && (poolData.is_fake || poolData.is_meta) ? 4 : poolData.is_crypto ? 3 : 2;
|
|
4356
|
+
for (_p = 0, _q = routes[inCoin]; _p < _q.length; _p++) {
|
|
4357
|
+
inCoinRoute = _q[_p];
|
|
4358
|
+
routes[underlying_coin_addresses[j]] = ((_2 = routes[underlying_coin_addresses[j]]) !== null && _2 !== void 0 ? _2 : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
4359
|
+
{
|
|
4360
|
+
poolId: poolId,
|
|
4361
|
+
poolAddress: poolAddress,
|
|
4362
|
+
outputCoinAddress: underlying_coin_addresses[j],
|
|
4363
|
+
i: inCoinIndexes.underlying_coin,
|
|
4364
|
+
j: j,
|
|
4365
|
+
swapType: swapType,
|
|
4366
|
+
swapAddress: ethers_1.ethers.constants.AddressZero,
|
|
4367
|
+
},
|
|
4368
|
+
], false)]);
|
|
4369
|
+
}
|
|
4370
|
+
nextCoins.add(underlying_coin_addresses[j]);
|
|
4371
|
+
_6.label = 10;
|
|
4372
|
+
case 10:
|
|
4373
|
+
j++;
|
|
4374
|
+
return [3 /*break*/, 8];
|
|
4375
|
+
case 11:
|
|
4376
|
+
if (!(inCoinIndexes.coin === 0 && meta_coin_addresses.length > 0 && poolId !== "atricrypto3")) return [3 /*break*/, 15];
|
|
4377
|
+
j = 0;
|
|
4378
|
+
_6.label = 12;
|
|
4379
|
+
case 12:
|
|
4380
|
+
if (!(j < meta_coin_addresses.length)) return [3 /*break*/, 15];
|
|
4381
|
+
// If this coin already marked or will be marked on the current step, no need to consider it on the next step
|
|
4382
|
+
if (markedCoins.includes(meta_coin_addresses[j]) || curCoins.includes(meta_coin_addresses[j]))
|
|
4383
|
+
return [3 /*break*/, 14];
|
|
4384
|
+
// Looking for outputCoinAddress only on the final step
|
|
4385
|
+
if (step === 3 && meta_coin_addresses[j] !== outputCoinAddress)
|
|
4386
|
+
return [3 /*break*/, 14];
|
|
4387
|
+
_r = Number;
|
|
4388
|
+
return [4 /*yield*/, (new Pool(poolId)).stats.getTotalLiquidity()];
|
|
4389
|
+
case 13:
|
|
4390
|
+
tvl = _r.apply(void 0, [_6.sent()]);
|
|
4391
|
+
if (tvl === 0)
|
|
4392
|
+
return [3 /*break*/, 14];
|
|
4393
|
+
// Skip imbalanced pools
|
|
4394
|
+
if (IMBALANCED_POOLS.includes(poolId))
|
|
4395
|
+
return [3 /*break*/, 14];
|
|
4396
|
+
swapType = (curve_1.curve.chainId === 137 && poolData.is_factory) ? 5 : poolData.is_crypto ? 4 : 2;
|
|
4397
|
+
for (_s = 0, _t = routes[inCoin]; _s < _t.length; _s++) {
|
|
4398
|
+
inCoinRoute = _t[_s];
|
|
4399
|
+
routes[meta_coin_addresses[j]] = ((_3 = routes[meta_coin_addresses[j]]) !== null && _3 !== void 0 ? _3 : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
4400
|
+
{
|
|
4401
|
+
poolId: poolId,
|
|
4402
|
+
poolAddress: poolAddress,
|
|
4403
|
+
outputCoinAddress: meta_coin_addresses[j],
|
|
4404
|
+
i: inCoinIndexes.coin,
|
|
4405
|
+
j: j + 1,
|
|
4406
|
+
swapType: swapType,
|
|
4407
|
+
swapAddress: swapType === 5 ? poolData.swap_address : ethers_1.ethers.constants.AddressZero,
|
|
4408
|
+
},
|
|
4409
|
+
], false)]);
|
|
4410
|
+
}
|
|
4411
|
+
nextCoins.add(meta_coin_addresses[j]);
|
|
4412
|
+
_6.label = 14;
|
|
4413
|
+
case 14:
|
|
4414
|
+
j++;
|
|
4415
|
+
return [3 /*break*/, 12];
|
|
4416
|
+
case 15:
|
|
4417
|
+
if (!(inCoinIndexes.meta_coin >= 0 && poolId !== "atricrypto3")) return [3 /*break*/, 17];
|
|
4418
|
+
// If this coin already marked or will be marked on the current step, no need to consider it on the next step
|
|
4419
|
+
if (markedCoins.includes(coin_addresses[0]) || curCoins.includes(coin_addresses[0]))
|
|
4420
|
+
return [3 /*break*/, 17];
|
|
4421
|
+
// Looking for outputCoinAddress only on the final step
|
|
4422
|
+
if (step === 3 && coin_addresses[0] !== outputCoinAddress)
|
|
4423
|
+
return [3 /*break*/, 17];
|
|
4424
|
+
_u = Number;
|
|
4425
|
+
return [4 /*yield*/, (new Pool(poolId)).stats.getTotalLiquidity()];
|
|
4426
|
+
case 16:
|
|
4427
|
+
tvl = _u.apply(void 0, [_6.sent()]);
|
|
4428
|
+
if (tvl === 0)
|
|
4429
|
+
return [3 /*break*/, 17];
|
|
4430
|
+
// Skip imbalanced pools
|
|
4431
|
+
if (IMBALANCED_POOLS.includes(poolId))
|
|
4432
|
+
return [3 /*break*/, 17];
|
|
4433
|
+
swapType = (curve_1.curve.chainId === 137 && poolData.is_factory) ? 5 : poolData.is_crypto ? 4 : 2;
|
|
4434
|
+
for (_v = 0, _w = routes[inCoin]; _v < _w.length; _v++) {
|
|
4435
|
+
inCoinRoute = _w[_v];
|
|
4436
|
+
routes[coin_addresses[0]] = ((_4 = routes[coin_addresses[0]]) !== null && _4 !== void 0 ? _4 : []).concat([__spreadArray(__spreadArray([], inCoinRoute, true), [
|
|
4437
|
+
{
|
|
4438
|
+
poolId: poolId,
|
|
4439
|
+
poolAddress: poolAddress,
|
|
4440
|
+
outputCoinAddress: coin_addresses[0],
|
|
4441
|
+
i: inCoinIndexes.meta_coin + 1,
|
|
4442
|
+
j: 0,
|
|
4443
|
+
swapType: swapType,
|
|
4444
|
+
swapAddress: swapType === 5 ? poolData.swap_address : ethers_1.ethers.constants.AddressZero,
|
|
4445
|
+
},
|
|
4446
|
+
], false)]);
|
|
4447
|
+
nextCoins.add(coin_addresses[0]);
|
|
4448
|
+
}
|
|
4449
|
+
_6.label = 17;
|
|
4450
|
+
case 17:
|
|
4451
|
+
_c++;
|
|
4452
|
+
return [3 /*break*/, 3];
|
|
4453
|
+
case 18:
|
|
4454
|
+
_a++;
|
|
4455
|
+
return [3 /*break*/, 2];
|
|
4456
|
+
case 19:
|
|
4457
|
+
// If target output coin is reached, search is finished. Assumption: the shorter route, the better.
|
|
4458
|
+
if (outputCoinAddress in routes)
|
|
4459
|
+
return [3 /*break*/, 21];
|
|
4460
|
+
markedCoins.push.apply(markedCoins, curCoins);
|
|
4461
|
+
curCoins = Array.from(nextCoins);
|
|
4462
|
+
nextCoins = new Set();
|
|
4463
|
+
_6.label = 20;
|
|
4464
|
+
case 20:
|
|
4465
|
+
step++;
|
|
4466
|
+
return [3 /*break*/, 1];
|
|
4467
|
+
case 21: return [2 /*return*/, (_5 = routes[outputCoinAddress]) !== null && _5 !== void 0 ? _5 : []];
|
|
4468
|
+
}
|
|
4469
|
+
});
|
|
4470
|
+
}); };
|
|
4471
|
+
exports._findAllRoutes = _findAllRoutes;
|
|
4472
|
+
var _getRouteKey = function (route, inputCoinAddress, outputCoinAddress) {
|
|
4473
|
+
var sortedCoins = [inputCoinAddress, outputCoinAddress].sort();
|
|
4474
|
+
var key = "".concat(sortedCoins[0], "-->");
|
|
4475
|
+
for (var _i = 0, _a = route.steps; _i < _a.length; _i++) {
|
|
4476
|
+
var routeStep = _a[_i];
|
|
4477
|
+
key += "".concat(routeStep.poolId, "-->");
|
|
4478
|
+
}
|
|
4479
|
+
key += sortedCoins[1];
|
|
4480
|
+
return key;
|
|
4481
|
+
};
|
|
4482
|
+
var _getExchangeMultipleArgs = function (inputCoinAddress, route) {
|
|
4483
|
+
var _route = [inputCoinAddress];
|
|
4484
|
+
var _swapParams = [];
|
|
4485
|
+
var _factorySwapAddresses = [];
|
|
4486
|
+
for (var _i = 0, _a = route.steps; _i < _a.length; _i++) {
|
|
4487
|
+
var routeStep = _a[_i];
|
|
4488
|
+
_route.push(routeStep.poolAddress, routeStep.outputCoinAddress);
|
|
4489
|
+
_swapParams.push([routeStep.i, routeStep.j, routeStep.swapType]);
|
|
4490
|
+
_factorySwapAddresses.push(routeStep.swapAddress);
|
|
4491
|
+
}
|
|
4492
|
+
_route = _route.concat(Array(9 - _route.length).fill(ethers_1.ethers.constants.AddressZero));
|
|
4493
|
+
_swapParams = _swapParams.concat(Array(4 - _swapParams.length).fill([0, 0, 0]));
|
|
4494
|
+
_factorySwapAddresses = _factorySwapAddresses.concat(Array(4 - _factorySwapAddresses.length).fill(ethers_1.ethers.constants.AddressZero));
|
|
4495
|
+
return { _route: _route, _swapParams: _swapParams, _factorySwapAddresses: _factorySwapAddresses };
|
|
4496
|
+
};
|
|
4497
|
+
var _estimatedGasForDifferentRoutesCache = {};
|
|
4498
|
+
var _estimateGasForDifferentRoutes = function (routes, inputCoinAddress, outputCoinAddress, _amount) { return __awaiter(void 0, void 0, void 0, function () {
|
|
4499
|
+
var contract, gasPromises, value, _i, routes_1, route, routeKey, gasPromise, _a, _route, _swapParams, _factorySwapAddresses, _gasAmounts_2, err_3;
|
|
4500
|
+
var _c;
|
|
4501
|
+
return __generator(this, function (_d) {
|
|
4502
|
+
switch (_d.label) {
|
|
4503
|
+
case 0:
|
|
4504
|
+
inputCoinAddress = inputCoinAddress.toLowerCase();
|
|
4505
|
+
outputCoinAddress = outputCoinAddress.toLowerCase();
|
|
4506
|
+
contract = curve_1.curve.contracts[curve_1.ALIASES.registry_exchange].contract;
|
|
4507
|
+
gasPromises = [];
|
|
4508
|
+
value = (0, utils_1.isEth)(inputCoinAddress) ? _amount : ethers_1.ethers.BigNumber.from(0);
|
|
4509
|
+
for (_i = 0, routes_1 = routes; _i < routes_1.length; _i++) {
|
|
4510
|
+
route = routes_1[_i];
|
|
4511
|
+
routeKey = _getRouteKey(route, inputCoinAddress, outputCoinAddress);
|
|
4512
|
+
gasPromise = void 0;
|
|
4513
|
+
_a = _getExchangeMultipleArgs(inputCoinAddress, route), _route = _a._route, _swapParams = _a._swapParams, _factorySwapAddresses = _a._factorySwapAddresses;
|
|
4514
|
+
if ((((_c = _estimatedGasForDifferentRoutesCache[routeKey]) === null || _c === void 0 ? void 0 : _c.time) || 0) + 3600000 < Date.now()) {
|
|
4515
|
+
gasPromise = contract.estimateGas.exchange_multiple(_route, _swapParams, _amount, 0, _factorySwapAddresses, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }));
|
|
4516
|
+
}
|
|
4517
|
+
else {
|
|
4518
|
+
gasPromise = Promise.resolve(_estimatedGasForDifferentRoutesCache[routeKey].gas);
|
|
4519
|
+
}
|
|
4520
|
+
gasPromises.push(gasPromise);
|
|
4521
|
+
}
|
|
4522
|
+
_d.label = 1;
|
|
4523
|
+
case 1:
|
|
4524
|
+
_d.trys.push([1, 3, , 4]);
|
|
4525
|
+
return [4 /*yield*/, Promise.all(gasPromises)];
|
|
4526
|
+
case 2:
|
|
4527
|
+
_gasAmounts_2 = _d.sent();
|
|
4528
|
+
routes.forEach(function (route, i) {
|
|
4529
|
+
var routeKey = _getRouteKey(route, inputCoinAddress, outputCoinAddress);
|
|
4530
|
+
_estimatedGasForDifferentRoutesCache[routeKey] = { 'gas': _gasAmounts_2[i], 'time': Date.now() };
|
|
4531
|
+
});
|
|
4532
|
+
return [2 /*return*/, _gasAmounts_2.map(function (_g) { return Number(ethers_1.ethers.utils.formatUnits(_g, 0)); })];
|
|
4533
|
+
case 3:
|
|
4534
|
+
err_3 = _d.sent();
|
|
4535
|
+
return [2 /*return*/, routes.map(function () { return 0; })];
|
|
4536
|
+
case 4: return [2 /*return*/];
|
|
4537
|
+
}
|
|
4538
|
+
});
|
|
4539
|
+
}); };
|
|
4540
|
+
var _getBestRouteAndOutput = (0, memoizee_1.default)(function (inputCoinAddress, outputCoinAddress, amount) { return __awaiter(void 0, void 0, void 0, function () {
|
|
4541
|
+
var _a, inputCoinDecimals, outputCoinDecimals, _amount, routesRaw, routes, calls, promises, multicallContract, contract, _i, routesRaw_1, route, _c, _route, _swapParams, _factorySwapAddresses, calls_1, multicallContract_1, _d, routesRaw_2, route, _e, _route, _swapParams, _factorySwapAddresses, _outputAmounts, i, err_4, promises_1, contract_1, _f, routesRaw_3, route, _h, _route, _swapParams, _factorySwapAddresses, res, i, _j, gasAmounts, outputCoinUsdRate, gasData, ethUsdRate, gasPrice, expectedAmounts, expectedAmountsUsd, txCostsUsd;
|
|
4542
|
+
return __generator(this, function (_k) {
|
|
4543
|
+
switch (_k.label) {
|
|
4544
|
+
case 0:
|
|
4545
|
+
_a = (0, utils_1._getCoinDecimals)(inputCoinAddress, outputCoinAddress), inputCoinDecimals = _a[0], outputCoinDecimals = _a[1];
|
|
4546
|
+
_amount = ethers_1.ethers.utils.parseUnits(amount.toString(), inputCoinDecimals);
|
|
4547
|
+
return [4 /*yield*/, (0, exports._findAllRoutes)(inputCoinAddress, outputCoinAddress)];
|
|
4548
|
+
case 1:
|
|
4549
|
+
routesRaw = (_k.sent()).map(function (steps) { return ({ steps: steps, _output: ethers_1.ethers.BigNumber.from(0), outputUsd: 0, txCostUsd: 0 }); });
|
|
4550
|
+
routes = [];
|
|
4551
|
+
calls = [];
|
|
4552
|
+
promises = [];
|
|
4553
|
+
multicallContract = curve_1.curve.contracts[curve_1.ALIASES.registry_exchange].multicallContract;
|
|
4554
|
+
contract = curve_1.curve.contracts[curve_1.ALIASES.registry_exchange].contract;
|
|
4555
|
+
for (_i = 0, routesRaw_1 = routesRaw; _i < routesRaw_1.length; _i++) {
|
|
4556
|
+
route = routesRaw_1[_i];
|
|
4557
|
+
_c = _getExchangeMultipleArgs(inputCoinAddress, route), _route = _c._route, _swapParams = _c._swapParams, _factorySwapAddresses = _c._factorySwapAddresses;
|
|
4558
|
+
calls.push(multicallContract.get_exchange_multiple_amount(_route, _swapParams, _amount, _factorySwapAddresses));
|
|
4559
|
+
promises.push(contract.get_exchange_multiple_amount(_route, _swapParams, _amount, _factorySwapAddresses, curve_1.curve.constantOptions));
|
|
4560
|
+
}
|
|
4561
|
+
_k.label = 2;
|
|
4562
|
+
case 2:
|
|
4563
|
+
_k.trys.push([2, 4, , 6]);
|
|
4564
|
+
calls_1 = [];
|
|
4565
|
+
multicallContract_1 = curve_1.curve.contracts[curve_1.ALIASES.registry_exchange].multicallContract;
|
|
4566
|
+
for (_d = 0, routesRaw_2 = routesRaw; _d < routesRaw_2.length; _d++) {
|
|
4567
|
+
route = routesRaw_2[_d];
|
|
4568
|
+
_e = _getExchangeMultipleArgs(inputCoinAddress, route), _route = _e._route, _swapParams = _e._swapParams, _factorySwapAddresses = _e._factorySwapAddresses;
|
|
4569
|
+
calls_1.push(multicallContract_1.get_exchange_multiple_amount(_route, _swapParams, _amount, _factorySwapAddresses));
|
|
4570
|
+
}
|
|
4571
|
+
return [4 /*yield*/, curve_1.curve.multicallProvider.all(calls_1)];
|
|
4572
|
+
case 3:
|
|
4573
|
+
_outputAmounts = _k.sent();
|
|
4574
|
+
for (i = 0; i < _outputAmounts.length; i++) {
|
|
4575
|
+
routesRaw[i]._output = _outputAmounts[i];
|
|
4576
|
+
routes.push(routesRaw[i]);
|
|
4577
|
+
}
|
|
4578
|
+
return [3 /*break*/, 6];
|
|
4579
|
+
case 4:
|
|
4580
|
+
err_4 = _k.sent();
|
|
4581
|
+
promises_1 = [];
|
|
4582
|
+
contract_1 = curve_1.curve.contracts[curve_1.ALIASES.registry_exchange].contract;
|
|
4583
|
+
for (_f = 0, routesRaw_3 = routesRaw; _f < routesRaw_3.length; _f++) {
|
|
4584
|
+
route = routesRaw_3[_f];
|
|
4585
|
+
_h = _getExchangeMultipleArgs(inputCoinAddress, route), _route = _h._route, _swapParams = _h._swapParams, _factorySwapAddresses = _h._factorySwapAddresses;
|
|
4586
|
+
promises_1.push(contract_1.get_exchange_multiple_amount(_route, _swapParams, _amount, _factorySwapAddresses, curve_1.curve.constantOptions));
|
|
4587
|
+
}
|
|
4588
|
+
return [4 /*yield*/, Promise.allSettled(promises_1)];
|
|
4589
|
+
case 5:
|
|
4590
|
+
res = _k.sent();
|
|
4591
|
+
for (i = 0; i < res.length; i++) {
|
|
4592
|
+
if (res[i].status === 'rejected') {
|
|
4593
|
+
console.log("Route ".concat((routesRaw[i].steps.map(function (s) { return s.poolId; })).join(" --> "), " is anavailable"));
|
|
4594
|
+
continue;
|
|
4595
|
+
}
|
|
4596
|
+
routesRaw[i]._output = res[i].value;
|
|
4597
|
+
routes.push(routesRaw[i]);
|
|
4598
|
+
}
|
|
4599
|
+
return [3 /*break*/, 6];
|
|
4600
|
+
case 6:
|
|
4601
|
+
if (routes.length === 0) {
|
|
4602
|
+
return [2 /*return*/, {
|
|
4603
|
+
steps: [],
|
|
4604
|
+
_output: ethers_1.ethers.BigNumber.from(0),
|
|
4605
|
+
outputUsd: 0,
|
|
4606
|
+
txCostUsd: 0,
|
|
4607
|
+
}];
|
|
4608
|
+
}
|
|
4609
|
+
if (routes.length === 1)
|
|
4610
|
+
return [2 /*return*/, routes[0]];
|
|
4611
|
+
return [4 /*yield*/, Promise.all([
|
|
4612
|
+
_estimateGasForDifferentRoutes(routes, inputCoinAddress, outputCoinAddress, _amount),
|
|
4613
|
+
(0, utils_1._getUsdRate)(outputCoinAddress),
|
|
4614
|
+
axios_1.default.get("https://api.curve.fi/api/getGas"),
|
|
4615
|
+
(0, utils_1._getUsdRate)(curve_1.curve.chainId === 137 ? curve_1.COINS.matic : curve_1.COINS.eth),
|
|
4616
|
+
])];
|
|
4617
|
+
case 7:
|
|
4618
|
+
_j = _k.sent(), gasAmounts = _j[0], outputCoinUsdRate = _j[1], gasData = _j[2], ethUsdRate = _j[3];
|
|
4619
|
+
gasPrice = gasData.data.data.gas.standard;
|
|
4620
|
+
expectedAmounts = (routes).map(function (route) { return Number(ethers_1.ethers.utils.formatUnits(route._output, outputCoinDecimals)); });
|
|
4621
|
+
expectedAmountsUsd = expectedAmounts.map(function (a) { return a * outputCoinUsdRate; });
|
|
4622
|
+
txCostsUsd = gasAmounts.map(function (a) { return ethUsdRate * a * gasPrice / 1e18; });
|
|
4623
|
+
routes.forEach(function (route, i) {
|
|
4624
|
+
route.outputUsd = expectedAmountsUsd[i];
|
|
4625
|
+
route.txCostUsd = txCostsUsd[i];
|
|
4626
|
+
});
|
|
4627
|
+
return [2 /*return*/, routes.reduce(function (route1, route2) { return (route1.outputUsd - route1.txCostUsd) - (route2.outputUsd - route2.txCostUsd) >= 0 ? route1 : route2; })];
|
|
4628
|
+
}
|
|
4629
|
+
});
|
|
4630
|
+
}); }, {
|
|
4631
|
+
promise: true,
|
|
4632
|
+
maxAge: 5 * 60 * 1000, // 5m
|
|
4633
|
+
});
|
|
4634
|
+
var getBestRouteAndOutput = function (inputCoin, outputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
|
|
4635
|
+
var _a, inputCoinAddress, outputCoinAddress, outputCoinDecimals, _c, steps, _output;
|
|
4636
|
+
return __generator(this, function (_d) {
|
|
4637
|
+
switch (_d.label) {
|
|
4638
|
+
case 0:
|
|
4639
|
+
_a = (0, utils_1._getCoinAddresses)(inputCoin, outputCoin), inputCoinAddress = _a[0], outputCoinAddress = _a[1];
|
|
4640
|
+
outputCoinDecimals = (0, utils_1._getCoinDecimals)(outputCoinAddress)[0];
|
|
4641
|
+
return [4 /*yield*/, _getBestRouteAndOutput(inputCoinAddress, outputCoinAddress, amount)];
|
|
4642
|
+
case 1:
|
|
4643
|
+
_c = _d.sent(), steps = _c.steps, _output = _c._output;
|
|
4644
|
+
return [2 /*return*/, { route: steps, output: ethers_1.ethers.utils.formatUnits(_output, outputCoinDecimals) }];
|
|
4645
|
+
}
|
|
4646
|
+
});
|
|
4647
|
+
}); };
|
|
4648
|
+
exports.getBestRouteAndOutput = getBestRouteAndOutput;
|
|
4649
|
+
var routerExchangeExpected = function (inputCoin, outputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
|
|
4650
|
+
return __generator(this, function (_a) {
|
|
4651
|
+
switch (_a.label) {
|
|
4652
|
+
case 0: return [4 /*yield*/, (0, exports.getBestRouteAndOutput)(inputCoin, outputCoin, amount)];
|
|
4653
|
+
case 1: return [2 /*return*/, (_a.sent())['output']];
|
|
4654
|
+
}
|
|
4655
|
+
});
|
|
4656
|
+
}); };
|
|
4657
|
+
exports.routerExchangeExpected = routerExchangeExpected;
|
|
4658
|
+
var routerExchangeIsApproved = function (inputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
|
|
4659
|
+
return __generator(this, function (_a) {
|
|
4660
|
+
switch (_a.label) {
|
|
4661
|
+
case 0: return [4 /*yield*/, (0, utils_1.hasAllowance)([inputCoin], [amount], curve_1.curve.signerAddress, curve_1.ALIASES.registry_exchange)];
|
|
4662
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
4663
|
+
}
|
|
4664
|
+
});
|
|
4665
|
+
}); };
|
|
4666
|
+
exports.routerExchangeIsApproved = routerExchangeIsApproved;
|
|
4667
|
+
var routerExchangeApproveEstimateGas = function (inputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
|
|
4668
|
+
return __generator(this, function (_a) {
|
|
4669
|
+
switch (_a.label) {
|
|
4670
|
+
case 0: return [4 /*yield*/, (0, utils_1.ensureAllowanceEstimateGas)([inputCoin], [amount], curve_1.ALIASES.registry_exchange)];
|
|
4671
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
4672
|
+
}
|
|
4673
|
+
});
|
|
4674
|
+
}); };
|
|
4675
|
+
exports.routerExchangeApproveEstimateGas = routerExchangeApproveEstimateGas;
|
|
4676
|
+
var routerExchangeApprove = function (inputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
|
|
4677
|
+
return __generator(this, function (_a) {
|
|
4678
|
+
switch (_a.label) {
|
|
4679
|
+
case 0: return [4 /*yield*/, (0, utils_1.ensureAllowance)([inputCoin], [amount], curve_1.ALIASES.registry_exchange)];
|
|
4680
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
4681
|
+
}
|
|
4682
|
+
});
|
|
4683
|
+
}); };
|
|
4684
|
+
exports.routerExchangeApprove = routerExchangeApprove;
|
|
4685
|
+
var routerExchangeEstimateGas = function (inputCoin, outputCoin, amount) { return __awaiter(void 0, void 0, void 0, function () {
|
|
4686
|
+
var _a, inputCoinAddress, outputCoinAddress, inputCoinDecimals, route, _amount, gas;
|
|
4687
|
+
return __generator(this, function (_c) {
|
|
4688
|
+
switch (_c.label) {
|
|
4689
|
+
case 0:
|
|
4690
|
+
_a = (0, utils_1._getCoinAddresses)(inputCoin, outputCoin), inputCoinAddress = _a[0], outputCoinAddress = _a[1];
|
|
4691
|
+
inputCoinDecimals = (0, utils_1._getCoinDecimals)(inputCoinAddress, outputCoinAddress)[0];
|
|
4692
|
+
return [4 /*yield*/, _getBestRouteAndOutput(inputCoinAddress, outputCoinAddress, amount)];
|
|
4693
|
+
case 1:
|
|
4694
|
+
route = _c.sent();
|
|
4695
|
+
_amount = ethers_1.ethers.utils.parseUnits(amount, inputCoinDecimals);
|
|
4696
|
+
return [4 /*yield*/, _estimateGasForDifferentRoutes([route], inputCoinAddress, outputCoinAddress, _amount)];
|
|
4697
|
+
case 2:
|
|
4698
|
+
gas = (_c.sent())[0];
|
|
4699
|
+
return [2 /*return*/, gas];
|
|
4700
|
+
}
|
|
4701
|
+
});
|
|
4702
|
+
}); };
|
|
4703
|
+
exports.routerExchangeEstimateGas = routerExchangeEstimateGas;
|
|
4704
|
+
var routerExchange = function (inputCoin, outputCoin, amount, maxSlippage) {
|
|
4705
|
+
if (maxSlippage === void 0) { maxSlippage = 0.01; }
|
|
4706
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
4707
|
+
var _a, inputCoinAddress, outputCoinAddress, _c, inputCoinDecimals, outputCoinDecimals, route, _d, _route, _swapParams, _factorySwapAddresses, _amount, minRecvAmountBN, _minRecvAmount, contract, value, gasLimit;
|
|
4708
|
+
return __generator(this, function (_e) {
|
|
4709
|
+
switch (_e.label) {
|
|
4710
|
+
case 0:
|
|
4711
|
+
_a = (0, utils_1._getCoinAddresses)(inputCoin, outputCoin), inputCoinAddress = _a[0], outputCoinAddress = _a[1];
|
|
4712
|
+
_c = (0, utils_1._getCoinDecimals)(inputCoinAddress, outputCoinAddress), inputCoinDecimals = _c[0], outputCoinDecimals = _c[1];
|
|
4713
|
+
return [4 /*yield*/, (0, exports.routerExchangeApprove)(inputCoin, amount)];
|
|
4714
|
+
case 1:
|
|
4715
|
+
_e.sent();
|
|
4716
|
+
return [4 /*yield*/, _getBestRouteAndOutput(inputCoinAddress, outputCoinAddress, amount)];
|
|
4717
|
+
case 2:
|
|
4718
|
+
route = _e.sent();
|
|
4719
|
+
if (route.steps.length === 0) {
|
|
4720
|
+
throw new Error("This pair can't be exchanged");
|
|
4721
|
+
}
|
|
4722
|
+
_d = _getExchangeMultipleArgs(inputCoinAddress, route), _route = _d._route, _swapParams = _d._swapParams, _factorySwapAddresses = _d._factorySwapAddresses;
|
|
4723
|
+
_amount = ethers_1.ethers.utils.parseUnits(amount, inputCoinDecimals);
|
|
4724
|
+
minRecvAmountBN = (0, utils_1.toBN)(route._output, outputCoinDecimals).times(1 - maxSlippage);
|
|
4725
|
+
_minRecvAmount = (0, utils_1.fromBN)(minRecvAmountBN, outputCoinDecimals);
|
|
4726
|
+
contract = curve_1.curve.contracts[curve_1.ALIASES.registry_exchange].contract;
|
|
4727
|
+
value = (0, utils_1.isEth)(inputCoinAddress) ? _amount : ethers_1.ethers.BigNumber.from(0);
|
|
4728
|
+
return [4 /*yield*/, curve_1.curve.updateFeeData()];
|
|
4729
|
+
case 3:
|
|
4730
|
+
_e.sent();
|
|
4731
|
+
return [4 /*yield*/, contract.estimateGas.exchange_multiple(_route, _swapParams, _amount, _minRecvAmount, _factorySwapAddresses, __assign(__assign({}, curve_1.curve.constantOptions), { value: value }))];
|
|
4732
|
+
case 4:
|
|
4733
|
+
gasLimit = (_e.sent()).mul(curve_1.curve.chainId === 1 ? 130 : 160).div(100);
|
|
4734
|
+
return [4 /*yield*/, contract.exchange_multiple(_route, _swapParams, _amount, _minRecvAmount, _factorySwapAddresses, __assign(__assign({}, curve_1.curve.options), { value: value, gasLimit: gasLimit }))];
|
|
4735
|
+
case 5: return [2 /*return*/, (_e.sent()).hash];
|
|
4736
|
+
}
|
|
4737
|
+
});
|
|
4738
|
+
});
|
|
4739
|
+
};
|
|
4740
|
+
exports.routerExchange = routerExchange;
|