@curvefi/api 2.66.30 → 2.66.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/boosting.d.ts +33 -32
- package/lib/boosting.js +320 -252
- package/lib/cached.d.ts +4 -3
- package/lib/cached.js +63 -19
- package/lib/constants/utils.d.ts +14 -1
- package/lib/constants/utils.js +21 -6
- package/lib/curve.d.ts +5 -5
- package/lib/curve.js +21 -38
- package/lib/dao.d.ts +32 -31
- package/lib/dao.js +420 -350
- package/lib/external-api.d.ts +1 -1
- package/lib/external-api.js +2 -2
- package/lib/factory/common.d.ts +2 -1
- package/lib/factory/common.js +1 -1
- package/lib/factory/deploy.d.ts +46 -45
- package/lib/factory/deploy.js +630 -551
- package/lib/factory/factory-api.d.ts +3 -2
- package/lib/factory/factory-api.js +22 -23
- package/lib/factory/factory-crypto.d.ts +1 -1
- package/lib/factory/factory-crypto.js +12 -15
- package/lib/factory/factory-tricrypto.d.ts +1 -1
- package/lib/factory/factory-tricrypto.js +14 -15
- package/lib/factory/factory-twocrypto.d.ts +1 -1
- package/lib/factory/factory-twocrypto.js +12 -13
- package/lib/factory/factory.d.ts +4 -3
- package/lib/factory/factory.js +21 -24
- package/lib/index.d.ts +413 -104
- package/lib/index.js +253 -257
- package/lib/interfaces.d.ts +2 -0
- package/lib/pools/PoolTemplate.d.ts +13 -12
- package/lib/pools/PoolTemplate.js +279 -285
- package/lib/pools/mixins/common.js +2 -2
- package/lib/pools/mixins/depositBalancedAmountsMixins.d.ts +12 -4
- package/lib/pools/mixins/depositBalancedAmountsMixins.js +1 -15
- package/lib/pools/mixins/depositMixins.d.ts +25 -5
- package/lib/pools/mixins/depositMixins.js +38 -76
- package/lib/pools/mixins/depositWrappedMixins.d.ts +10 -2
- package/lib/pools/mixins/depositWrappedMixins.js +17 -33
- package/lib/pools/mixins/poolBalancesMixin.d.ts +6 -2
- package/lib/pools/mixins/poolBalancesMixin.js +3 -5
- package/lib/pools/mixins/swapMixins.d.ts +20 -4
- package/lib/pools/mixins/swapMixins.js +36 -70
- package/lib/pools/mixins/swapWrappedMixins.d.ts +19 -4
- package/lib/pools/mixins/swapWrappedMixins.js +32 -60
- package/lib/pools/mixins/withdrawExpectedMixins.d.ts +12 -4
- package/lib/pools/mixins/withdrawExpectedMixins.js +6 -11
- package/lib/pools/mixins/withdrawImbalanceMixins.d.ts +20 -4
- package/lib/pools/mixins/withdrawImbalanceMixins.js +26 -53
- package/lib/pools/mixins/withdrawImbalanceWrappedMixins.d.ts +10 -2
- package/lib/pools/mixins/withdrawImbalanceWrappedMixins.js +12 -27
- package/lib/pools/mixins/withdrawMixins.d.ts +25 -5
- package/lib/pools/mixins/withdrawMixins.js +33 -67
- package/lib/pools/mixins/withdrawOneCoinExpectedMixins.d.ts +12 -4
- package/lib/pools/mixins/withdrawOneCoinExpectedMixins.js +8 -13
- package/lib/pools/mixins/withdrawOneCoinMixins.d.ts +25 -5
- package/lib/pools/mixins/withdrawOneCoinMixins.js +32 -66
- package/lib/pools/mixins/withdrawOneCoinWrappedExpectedMixins.d.ts +6 -2
- package/lib/pools/mixins/withdrawOneCoinWrappedExpectedMixins.js +4 -7
- package/lib/pools/mixins/withdrawOneCoinWrappedMixins.d.ts +10 -2
- package/lib/pools/mixins/withdrawOneCoinWrappedMixins.js +13 -29
- package/lib/pools/mixins/withdrawWrappedMixins.d.ts +10 -2
- package/lib/pools/mixins/withdrawWrappedMixins.js +14 -28
- package/lib/pools/poolConstructor.d.ts +2 -1
- package/lib/pools/poolConstructor.js +27 -28
- package/lib/pools/subClasses/corePool.d.ts +4 -1
- package/lib/pools/subClasses/corePool.js +5 -7
- package/lib/pools/subClasses/gaugePool.d.ts +5 -3
- package/lib/pools/subClasses/gaugePool.js +19 -18
- package/lib/pools/subClasses/statsPool.d.ts +2 -0
- package/lib/pools/subClasses/statsPool.js +22 -10
- package/lib/pools/subClasses/walletPool.d.ts +2 -1
- package/lib/pools/subClasses/walletPool.js +6 -6
- package/lib/pools/utils.d.ts +7 -6
- package/lib/pools/utils.js +316 -297
- package/lib/route-graph.worker.d.ts +2 -2
- package/lib/route-graph.worker.js +4 -6
- package/lib/router.d.ts +12 -11
- package/lib/router.js +331 -295
- package/lib/utils.d.ts +34 -33
- package/lib/utils.js +481 -435
- package/package.json +1 -1
package/lib/router.js
CHANGED
|
@@ -7,21 +7,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import memoize from "memoizee";
|
|
11
10
|
import { ethers } from "ethers";
|
|
12
|
-
import {
|
|
11
|
+
import { OLD_CHAINS } from "./curve.js";
|
|
13
12
|
import { _cutZeros, _get_price_impact, _get_small_x, _getCoinAddresses, _getCoinDecimals, _getUsdRate, BN, DIGas, ensureAllowance, ensureAllowanceEstimateGas, ETH_ADDRESS, fromBN, getGasPriceFromL1, getTxCostsUsd, hasAllowance, isEth, parseUnits, runWorker, smartNumber, toBN, } from "./utils.js";
|
|
14
13
|
import { getPool } from "./pools/index.js";
|
|
15
14
|
import { _getAmplificationCoefficientsFromApi } from "./pools/utils.js";
|
|
16
15
|
import { L2Networks } from "./constants/L2Networks.js";
|
|
17
16
|
import { routeFinderWorker, routeFinderWorkerCode } from "./route-finder.worker.js";
|
|
18
17
|
import { routeGraphWorker, routeGraphWorkerCode } from "./route-graph.worker.js";
|
|
18
|
+
import { memoizeMethod } from "./constants/utils";
|
|
19
19
|
const MAX_STEPS = 5;
|
|
20
20
|
const ROUTE_LENGTH = (MAX_STEPS * 2) + 1;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
21
|
+
function _getTVL(poolId) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () { return Number(yield getPool.call(this, poolId).stats.totalLiquidityMemoized()); });
|
|
23
|
+
}
|
|
25
24
|
function entriesToDictAsync(entries, mapper) {
|
|
26
25
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27
26
|
const result = {};
|
|
@@ -34,24 +33,26 @@ function mapDict(dict, mapper) {
|
|
|
34
33
|
Object.entries(dict).forEach(([key, value]) => result[key] = mapper(key, value));
|
|
35
34
|
return result;
|
|
36
35
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
});
|
|
36
|
+
function _buildRouteGraphImpl(chainId, isLiteChain) {
|
|
37
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
const constants = this.constants;
|
|
39
|
+
const allPools = Object.entries(this.getPoolsData()).filter(([id]) => !["crveth", "y", "busd", "pax"].includes(id));
|
|
40
|
+
const amplificationCoefficientDict = yield _getAmplificationCoefficientsFromApi.call(this);
|
|
41
|
+
const poolTvlDict = yield entriesToDictAsync(allPools, _getTVL.bind(this));
|
|
42
|
+
const input = { constants, chainId, isLiteChain, allPools, amplificationCoefficientDict, poolTvlDict };
|
|
43
|
+
return runWorker(routeGraphWorkerCode, routeGraphWorker, Object.assign({ type: 'createRouteGraph' }, input));
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function _findRoutes(inputCoinAddress, outputCoinAddress) {
|
|
47
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
const _buildRouteGraph = memoizeMethod(this, '_buildRouteGraph', _buildRouteGraphImpl);
|
|
49
|
+
const routerGraph = yield _buildRouteGraph.call(this, this.chainId, this.isLiteChain); // It's important to pass chainId to not use cache from another network
|
|
50
|
+
// extract only the fields we need for the worker
|
|
51
|
+
const poolData = mapDict(this.getPoolsData(), (_, { is_lending, wrapped_coin_addresses, underlying_coin_addresses, token_address }) => ({ is_lending, wrapped_coin_addresses, underlying_coin_addresses, token_address }));
|
|
52
|
+
const input = { inputCoinAddress, outputCoinAddress, routerGraph, poolData };
|
|
53
|
+
return runWorker(routeFinderWorkerCode, routeFinderWorker, Object.assign({ type: 'findRoutes' }, input));
|
|
54
|
+
});
|
|
55
|
+
}
|
|
55
56
|
const _getRouteKey = (route, inputCoinAddress, outputCoinAddress) => {
|
|
56
57
|
const sortedCoins = [inputCoinAddress, outputCoinAddress].sort();
|
|
57
58
|
let key = `${sortedCoins[0]}-->`;
|
|
@@ -61,8 +62,8 @@ const _getRouteKey = (route, inputCoinAddress, outputCoinAddress) => {
|
|
|
61
62
|
key += sortedCoins[1];
|
|
62
63
|
return key;
|
|
63
64
|
};
|
|
64
|
-
|
|
65
|
-
if (OLD_CHAINS.includes(
|
|
65
|
+
function _getExchangeArgs(route) {
|
|
66
|
+
if (OLD_CHAINS.includes(this.chainId)) {
|
|
66
67
|
let _route = [];
|
|
67
68
|
if (route.length > 0)
|
|
68
69
|
_route.push(route[0].inputCoinAddress);
|
|
@@ -81,13 +82,13 @@ const _getExchangeArgs = (route) => {
|
|
|
81
82
|
_secondBasePools.push(routeStep.secondBasePool);
|
|
82
83
|
_secondBaseTokens.push(routeStep.secondBaseToken);
|
|
83
84
|
}
|
|
84
|
-
_route = _route.concat(Array(ROUTE_LENGTH - _route.length).fill(
|
|
85
|
+
_route = _route.concat(Array(ROUTE_LENGTH - _route.length).fill(this.constants.ZERO_ADDRESS));
|
|
85
86
|
_swapParams = _swapParams.concat(Array(MAX_STEPS - _swapParams.length).fill([0, 0, 0, 0, 0]));
|
|
86
|
-
_pools = _pools.concat(Array(MAX_STEPS - _pools.length).fill(
|
|
87
|
-
_basePools = _basePools.concat(Array(MAX_STEPS - _basePools.length).fill(
|
|
88
|
-
_baseTokens = _baseTokens.concat(Array(MAX_STEPS - _baseTokens.length).fill(
|
|
89
|
-
_secondBasePools = _secondBasePools.concat(Array(MAX_STEPS - _secondBasePools.length).fill(
|
|
90
|
-
_secondBaseTokens = _secondBaseTokens.concat(Array(MAX_STEPS - _secondBaseTokens.length).fill(
|
|
87
|
+
_pools = _pools.concat(Array(MAX_STEPS - _pools.length).fill(this.constants.ZERO_ADDRESS));
|
|
88
|
+
_basePools = _basePools.concat(Array(MAX_STEPS - _basePools.length).fill(this.constants.ZERO_ADDRESS));
|
|
89
|
+
_baseTokens = _baseTokens.concat(Array(MAX_STEPS - _baseTokens.length).fill(this.constants.ZERO_ADDRESS));
|
|
90
|
+
_secondBasePools = _secondBasePools.concat(Array(MAX_STEPS - _secondBasePools.length).fill(this.constants.ZERO_ADDRESS));
|
|
91
|
+
_secondBaseTokens = _secondBaseTokens.concat(Array(MAX_STEPS - _secondBaseTokens.length).fill(this.constants.ZERO_ADDRESS));
|
|
91
92
|
return { _route, _swapParams, _pools, _basePools, _baseTokens, _secondBasePools, _secondBaseTokens };
|
|
92
93
|
}
|
|
93
94
|
else { // RouterNgPoolsOnly
|
|
@@ -99,299 +100,334 @@ const _getExchangeArgs = (route) => {
|
|
|
99
100
|
_route.push(routeStep.swapAddress, routeStep.outputCoinAddress);
|
|
100
101
|
_swapParams.push(routeStep.swapParams.slice(0, 4));
|
|
101
102
|
}
|
|
102
|
-
_route = _route.concat(Array(ROUTE_LENGTH - _route.length).fill(
|
|
103
|
+
_route = _route.concat(Array(ROUTE_LENGTH - _route.length).fill(this.constants.ZERO_ADDRESS));
|
|
103
104
|
_swapParams = _swapParams.concat(Array(MAX_STEPS - _swapParams.length).fill([0, 0, 0, 0]));
|
|
104
105
|
return { _route, _swapParams };
|
|
105
106
|
}
|
|
106
|
-
}
|
|
107
|
+
}
|
|
107
108
|
const _estimatedGasForDifferentRoutesCache = {};
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
let gasPromise;
|
|
118
|
-
const { _route, _swapParams, _pools } = _getExchangeArgs(route);
|
|
119
|
-
if ((((_a = _estimatedGasForDifferentRoutesCache[routeKey]) === null || _a === void 0 ? void 0 : _a.time) || 0) + 3600000 < Date.now()) {
|
|
120
|
-
if (_pools) {
|
|
121
|
-
gasPromise = contract.exchange.estimateGas(_route, _swapParams, _amount, 0, _pools, Object.assign(Object.assign({}, curve.constantOptions), { value }));
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
gasPromise = contract.exchange.estimateGas(_route, _swapParams, _amount, 0, Object.assign(Object.assign({}, curve.constantOptions), { value }));
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
gasPromise = Promise.resolve(_estimatedGasForDifferentRoutesCache[routeKey].gas);
|
|
129
|
-
}
|
|
130
|
-
gasPromises.push(gasPromise);
|
|
131
|
-
}
|
|
132
|
-
try {
|
|
133
|
-
const _gasAmounts = yield Promise.all(gasPromises);
|
|
134
|
-
routes.forEach((route, i) => {
|
|
109
|
+
function _estimateGasForDifferentRoutes(routes, inputCoinAddress, outputCoinAddress, _amount) {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
var _a;
|
|
112
|
+
inputCoinAddress = inputCoinAddress.toLowerCase();
|
|
113
|
+
outputCoinAddress = outputCoinAddress.toLowerCase();
|
|
114
|
+
const contract = this.contracts[this.constants.ALIASES.router].contract;
|
|
115
|
+
const gasPromises = [];
|
|
116
|
+
const value = isEth(inputCoinAddress) ? _amount : this.parseUnits("0");
|
|
117
|
+
for (const route of routes) {
|
|
135
118
|
const routeKey = _getRouteKey(route, inputCoinAddress, outputCoinAddress);
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
const [inputCoinDecimals, outputCoinDecimals] = _getCoinDecimals(inputCoinAddress, outputCoinAddress);
|
|
146
|
-
const _amount = parseUnits(amount, inputCoinDecimals);
|
|
147
|
-
if (_amount === curve.parseUnits("0"))
|
|
148
|
-
return [];
|
|
149
|
-
const routesRaw = (yield _findRoutes(inputCoinAddress, outputCoinAddress)).map((route) => ({ route, _output: curve.parseUnits("0"), outputUsd: 0, txCostUsd: 0 }));
|
|
150
|
-
const routes = [];
|
|
151
|
-
try {
|
|
152
|
-
const calls = [];
|
|
153
|
-
const multicallContract = curve.contracts[curve.constants.ALIASES.router].multicallContract;
|
|
154
|
-
for (const r of routesRaw) {
|
|
155
|
-
const { _route, _swapParams, _pools } = _getExchangeArgs(r.route);
|
|
156
|
-
if (_pools) {
|
|
157
|
-
calls.push(multicallContract.get_dy(_route, _swapParams, _amount, _pools));
|
|
119
|
+
let gasPromise;
|
|
120
|
+
const { _route, _swapParams, _pools } = _getExchangeArgs.call(this, route);
|
|
121
|
+
if ((((_a = _estimatedGasForDifferentRoutesCache[routeKey]) === null || _a === void 0 ? void 0 : _a.time) || 0) + 3600000 < Date.now()) {
|
|
122
|
+
if (_pools) {
|
|
123
|
+
gasPromise = contract.exchange.estimateGas(_route, _swapParams, _amount, 0, _pools, Object.assign(Object.assign({}, this.constantOptions), { value }));
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
gasPromise = contract.exchange.estimateGas(_route, _swapParams, _amount, 0, Object.assign(Object.assign({}, this.constantOptions), { value }));
|
|
127
|
+
}
|
|
158
128
|
}
|
|
159
129
|
else {
|
|
160
|
-
|
|
130
|
+
gasPromise = Promise.resolve(_estimatedGasForDifferentRoutesCache[routeKey].gas);
|
|
161
131
|
}
|
|
132
|
+
gasPromises.push(gasPromise);
|
|
162
133
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
134
|
+
try {
|
|
135
|
+
const _gasAmounts = yield Promise.all(gasPromises);
|
|
136
|
+
routes.forEach((route, i) => {
|
|
137
|
+
const routeKey = _getRouteKey(route, inputCoinAddress, outputCoinAddress);
|
|
138
|
+
_estimatedGasForDifferentRoutesCache[routeKey] = { 'gas': _gasAmounts[i], 'time': Date.now() };
|
|
139
|
+
});
|
|
140
|
+
return _gasAmounts.map((_g) => smartNumber(_g));
|
|
167
141
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const contract = curve.contracts[curve.constants.ALIASES.router].contract;
|
|
188
|
-
const _outputs = [];
|
|
189
|
-
for (const r of routesRaw) {
|
|
190
|
-
const { _route, _swapParams, _pools } = _getExchangeArgs(r.route);
|
|
191
|
-
try {
|
|
142
|
+
catch ( // No allowance
|
|
143
|
+
_b) { // No allowance
|
|
144
|
+
return routes.map(() => 0);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function _getBestRouteImpl(inputCoinAddress, outputCoinAddress, amount) {
|
|
149
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
const [inputCoinDecimals, outputCoinDecimals] = _getCoinDecimals.call(this, inputCoinAddress, outputCoinAddress);
|
|
151
|
+
const _amount = parseUnits(amount, inputCoinDecimals);
|
|
152
|
+
if (_amount === this.parseUnits("0"))
|
|
153
|
+
return [];
|
|
154
|
+
const routesRaw = (yield _findRoutes.call(this, inputCoinAddress, outputCoinAddress)).map((route) => ({ route, _output: this.parseUnits("0"), outputUsd: 0, txCostUsd: 0 }));
|
|
155
|
+
const routes = [];
|
|
156
|
+
try {
|
|
157
|
+
const calls = [];
|
|
158
|
+
const multicallContract = this.contracts[this.constants.ALIASES.router].multicallContract;
|
|
159
|
+
for (const r of routesRaw) {
|
|
160
|
+
const { _route, _swapParams, _pools } = _getExchangeArgs.call(this, r.route);
|
|
192
161
|
if (_pools) {
|
|
193
|
-
|
|
162
|
+
calls.push(multicallContract.get_dy(_route, _swapParams, _amount, _pools));
|
|
194
163
|
}
|
|
195
164
|
else {
|
|
196
|
-
|
|
165
|
+
calls.push(multicallContract.get_dy(_route, _swapParams, _amount));
|
|
197
166
|
}
|
|
198
167
|
}
|
|
199
|
-
|
|
200
|
-
|
|
168
|
+
const _outputAmounts = yield this.multicallProvider.all(calls);
|
|
169
|
+
for (let i = 0; i < _outputAmounts.length; i++) {
|
|
170
|
+
routesRaw[i]._output = _outputAmounts[i];
|
|
171
|
+
routes.push(routesRaw[i]);
|
|
201
172
|
}
|
|
202
173
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
174
|
+
catch (_a) {
|
|
175
|
+
// const promises = [];
|
|
176
|
+
// const contract = this.contracts[this.constants.ALIASES.router].contract;
|
|
177
|
+
// for (const r of routesRaw) {
|
|
178
|
+
// const { _route, _swapParams, _pools } = _getExchangeArgs(r.route);
|
|
179
|
+
// promises.push(contract.get_dy(_route, _swapParams, _amount, _pools, this.constantOptions));
|
|
180
|
+
// }
|
|
181
|
+
//
|
|
182
|
+
// const res = await Promise.allSettled(promises);
|
|
183
|
+
//
|
|
184
|
+
// for (let i = 0; i < res.length; i++) {
|
|
185
|
+
// if (res[i].status === 'rejected') {
|
|
186
|
+
// console.log(`Route ${(routesRaw[i].route.map((s) => s.poolId)).join(" --> ")} is unavailable`);
|
|
187
|
+
// continue;
|
|
188
|
+
// }
|
|
189
|
+
// routesRaw[i]._output = (res[i] as PromiseFulfilledResult<bigint>).value;
|
|
190
|
+
// routes.push(routesRaw[i]);
|
|
191
|
+
// }
|
|
192
|
+
const contract = this.contracts[this.constants.ALIASES.router].contract;
|
|
193
|
+
const _outputs = [];
|
|
194
|
+
for (const r of routesRaw) {
|
|
195
|
+
const { _route, _swapParams, _pools } = _getExchangeArgs.call(this, r.route);
|
|
196
|
+
try {
|
|
197
|
+
if (_pools) {
|
|
198
|
+
_outputs.push(yield contract.get_dy(_route, _swapParams, _amount, _pools, this.constantOptions));
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
_outputs.push(yield contract.get_dy(_route, _swapParams, _amount, this.constantOptions));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch (_b) {
|
|
205
|
+
_outputs.push(this.parseUnits('-1', 0));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
for (let i = 0; i < _outputs.length; i++) {
|
|
209
|
+
if (_outputs[i] < 0) {
|
|
210
|
+
console.log(`Route ${(routesRaw[i].route.map((s) => s.poolId)).join(" --> ")} is unavailable`);
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
routesRaw[i]._output = _outputs[i];
|
|
214
|
+
routes.push(routesRaw[i]);
|
|
207
215
|
}
|
|
208
|
-
routesRaw[i]._output = _outputs[i];
|
|
209
|
-
routes.push(routesRaw[i]);
|
|
210
216
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
217
|
+
if (routes.length === 0)
|
|
218
|
+
return [];
|
|
219
|
+
if (routes.length === 1)
|
|
220
|
+
return routes[0].route;
|
|
221
|
+
const [gasAmounts, outputCoinUsdRate, gasData, ethUsdRate] = yield Promise.all([
|
|
222
|
+
_estimateGasForDifferentRoutes.call(this, routes.map((r) => r.route), inputCoinAddress, outputCoinAddress, _amount),
|
|
223
|
+
_getUsdRate.call(this, outputCoinAddress),
|
|
224
|
+
fetch("https://api.curve.finance/api/getGas").then((res) => res.json()),
|
|
225
|
+
_getUsdRate.call(this, ETH_ADDRESS),
|
|
226
|
+
]);
|
|
227
|
+
const gasPrice = gasData.data.gas.standard;
|
|
228
|
+
const expectedAmounts = (routes).map((route) => Number(this.formatUnits(route._output, outputCoinDecimals)));
|
|
229
|
+
const expectedAmountsUsd = expectedAmounts.map((a) => a * outputCoinUsdRate);
|
|
230
|
+
const L1GasPrice = L2Networks.includes(this.chainId) ? yield getGasPriceFromL1.call(this) : 0;
|
|
231
|
+
const txCostsUsd = gasAmounts.map((a) => getTxCostsUsd(ethUsdRate, gasPrice, a, L1GasPrice));
|
|
232
|
+
routes.forEach((route, i) => {
|
|
233
|
+
route.outputUsd = expectedAmountsUsd[i];
|
|
234
|
+
route.txCostUsd = txCostsUsd[i];
|
|
235
|
+
});
|
|
236
|
+
return routes.reduce((route1, route2) => {
|
|
237
|
+
const diff = (route1.outputUsd - route1.txCostUsd) - (route2.outputUsd - route2.txCostUsd);
|
|
238
|
+
if (diff > 0)
|
|
239
|
+
return route1;
|
|
240
|
+
if (diff === 0 && route1.route.length < route2.route.length)
|
|
241
|
+
return route1;
|
|
242
|
+
return route2;
|
|
243
|
+
}).route;
|
|
230
244
|
});
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
maxAge: 15 * 1000, // 15s
|
|
255
|
-
});
|
|
245
|
+
}
|
|
246
|
+
function _getBestRoute(inputCoinAddress, outputCoinAddress, amount) {
|
|
247
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
248
|
+
return memoizeMethod(this, '_getBestRoute', _getBestRouteImpl).call(this, inputCoinAddress, outputCoinAddress, amount);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
function _getOutputForRouteImpl(route, _amount) {
|
|
252
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
253
|
+
const contract = this.contracts[this.constants.ALIASES.router].contract;
|
|
254
|
+
const { _route, _swapParams, _pools } = _getExchangeArgs.call(this, route);
|
|
255
|
+
if (_pools) {
|
|
256
|
+
return yield contract.get_dy(_route, _swapParams, _amount, _pools, this.constantOptions);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
return yield contract.get_dy(_route, _swapParams, _amount, this.constantOptions);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
function _getOutputForRoute(route, _amount) {
|
|
264
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
265
|
+
return memoizeMethod(this, '_getOutputForRoute', _getOutputForRouteImpl).call(this, route, _amount);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
256
268
|
const _routesCache = {};
|
|
257
|
-
|
|
258
|
-
const [inputCoinAddress, outputCoinAddress] = _getCoinAddresses(inputCoin, outputCoin);
|
|
269
|
+
function _getBestRouteAndOutput(inputCoin, outputCoin, amount) {
|
|
270
|
+
const [inputCoinAddress, outputCoinAddress] = _getCoinAddresses.call(this, inputCoin, outputCoin);
|
|
259
271
|
const key = `${inputCoinAddress}-${outputCoinAddress}-${amount}`;
|
|
260
272
|
if (!(key in _routesCache))
|
|
261
273
|
throw Error("You must call getBestRouteAndOutput first");
|
|
262
274
|
return _routesCache[key];
|
|
263
|
-
}
|
|
264
|
-
export
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
export
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const { route, output } = _getBestRouteAndOutput(inputCoinAddress, outputCoinAddress, amount);
|
|
306
|
-
const _amount = parseUnits(amount, inputCoinDecimals);
|
|
307
|
-
const _output = parseUnits(output, outputCoinDecimals);
|
|
308
|
-
const smallAmountIntBN = _get_small_x(_amount, _output, inputCoinDecimals, outputCoinDecimals);
|
|
309
|
-
const amountIntBN = toBN(_amount, 0);
|
|
310
|
-
if (smallAmountIntBN.gte(amountIntBN))
|
|
311
|
-
return 0;
|
|
312
|
-
const contract = curve.contracts[curve.constants.ALIASES.router].contract;
|
|
313
|
-
let _smallAmount = fromBN(smallAmountIntBN.div(Math.pow(10, inputCoinDecimals)), inputCoinDecimals);
|
|
314
|
-
const { _route, _swapParams, _pools } = _getExchangeArgs(route);
|
|
315
|
-
let _smallOutput;
|
|
316
|
-
try {
|
|
317
|
-
if (_pools) {
|
|
318
|
-
_smallOutput = yield contract.get_dy(_route, _swapParams, _smallAmount, _pools, curve.constantOptions);
|
|
275
|
+
}
|
|
276
|
+
export function getBestRouteAndOutput(inputCoin, outputCoin, amount) {
|
|
277
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
278
|
+
const [inputCoinAddress, outputCoinAddress] = _getCoinAddresses.call(this, inputCoin, outputCoin);
|
|
279
|
+
const [inputCoinDecimals, outputCoinDecimals] = _getCoinDecimals.call(this, inputCoinAddress, outputCoinAddress);
|
|
280
|
+
const route = yield _getBestRoute.call(this, inputCoinAddress, outputCoinAddress, amount); // 5 minutes cache
|
|
281
|
+
if (route.length === 0)
|
|
282
|
+
return { route, output: '0.0' };
|
|
283
|
+
const _output = yield _getOutputForRoute.call(this, route, parseUnits(amount, inputCoinDecimals)); // 15 seconds cache, so we call it to get fresh output estimation
|
|
284
|
+
_routesCache[`${inputCoinAddress}-${outputCoinAddress}-${amount}`] = {
|
|
285
|
+
route,
|
|
286
|
+
output: this.formatUnits(_output + BigInt(1), outputCoinDecimals),
|
|
287
|
+
timestamp: Date.now(),
|
|
288
|
+
};
|
|
289
|
+
return { route, output: this.formatUnits(_output + BigInt(1), outputCoinDecimals) };
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
export function getArgs(route) {
|
|
293
|
+
return _getExchangeArgs.call(this, route);
|
|
294
|
+
}
|
|
295
|
+
export function swapExpected(inputCoin, outputCoin, amount) {
|
|
296
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
297
|
+
return (yield getBestRouteAndOutput.call(this, inputCoin, outputCoin, amount))['output'];
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
export function swapRequired(inputCoin, outputCoin, outAmount) {
|
|
301
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
302
|
+
const [inputCoinAddress, outputCoinAddress] = _getCoinAddresses.call(this, inputCoin, outputCoin);
|
|
303
|
+
const [inputCoinDecimals, outputCoinDecimals] = _getCoinDecimals.call(this, inputCoinAddress, outputCoinAddress);
|
|
304
|
+
const _outAmount = parseUnits(outAmount, outputCoinDecimals);
|
|
305
|
+
const p1 = (yield _getUsdRate.call(this, inputCoinAddress)) || 1;
|
|
306
|
+
const p2 = (yield _getUsdRate.call(this, outputCoinAddress)) || 1;
|
|
307
|
+
const approximateRequiredAmount = Number(outAmount) * p2 / p1;
|
|
308
|
+
const route = yield _getBestRoute.call(this, inputCoinAddress, outputCoinAddress, approximateRequiredAmount);
|
|
309
|
+
const contract = this.contracts[this.constants.ALIASES.router].contract;
|
|
310
|
+
const { _route, _swapParams, _pools, _basePools, _baseTokens, _secondBasePools, _secondBaseTokens } = _getExchangeArgs.call(this, route);
|
|
311
|
+
let _required;
|
|
312
|
+
if ("get_dx(address[11],uint256[5][5],uint256,address[5],address[5],address[5],address[5],address[5])" in contract) {
|
|
313
|
+
_required = yield contract.get_dx(_route, _swapParams, _outAmount, _pools, _basePools, _baseTokens, _secondBasePools, _secondBaseTokens, this.constantOptions);
|
|
314
|
+
}
|
|
315
|
+
else if (_pools) {
|
|
316
|
+
_required = yield contract.get_dx(_route, _swapParams, _outAmount, _pools, _basePools, _baseTokens, this.constantOptions);
|
|
319
317
|
}
|
|
320
318
|
else {
|
|
321
|
-
|
|
319
|
+
_required = yield contract.get_dx(_route, _swapParams, _outAmount, this.constantOptions);
|
|
322
320
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
321
|
+
return this.formatUnits(_required, inputCoinDecimals);
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
export function swapPriceImpact(inputCoin, outputCoin, amount) {
|
|
325
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
326
|
+
const [inputCoinAddress, outputCoinAddress] = _getCoinAddresses.call(this, inputCoin, outputCoin);
|
|
327
|
+
const [inputCoinDecimals, outputCoinDecimals] = _getCoinDecimals.call(this, inputCoinAddress, outputCoinAddress);
|
|
328
|
+
const { route, output } = _getBestRouteAndOutput.call(this, inputCoinAddress, outputCoinAddress, amount);
|
|
329
|
+
const _amount = parseUnits(amount, inputCoinDecimals);
|
|
330
|
+
const _output = parseUnits(output, outputCoinDecimals);
|
|
331
|
+
const smallAmountIntBN = _get_small_x(_amount, _output, inputCoinDecimals, outputCoinDecimals);
|
|
332
|
+
const amountIntBN = toBN(_amount, 0);
|
|
333
|
+
if (smallAmountIntBN.gte(amountIntBN))
|
|
334
|
+
return 0;
|
|
335
|
+
const contract = this.contracts[this.constants.ALIASES.router].contract;
|
|
336
|
+
let _smallAmount = fromBN(smallAmountIntBN.div(Math.pow(10, inputCoinDecimals)), inputCoinDecimals);
|
|
337
|
+
const { _route, _swapParams, _pools } = _getExchangeArgs.call(this, route);
|
|
338
|
+
let _smallOutput;
|
|
339
|
+
try {
|
|
340
|
+
if (_pools) {
|
|
341
|
+
_smallOutput = yield contract.get_dy(_route, _swapParams, _smallAmount, _pools, this.constantOptions);
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
_smallOutput = yield contract.get_dy(_route, _swapParams, _smallAmount, this.constantOptions);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
catch (_a) {
|
|
348
|
+
_smallAmount = this.parseUnits("1", inputCoinDecimals); // Dirty hack
|
|
349
|
+
if (_pools) {
|
|
350
|
+
_smallOutput = yield contract.get_dy(_route, _swapParams, _smallAmount, _pools, this.constantOptions);
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
_smallOutput = yield contract.get_dy(_route, _swapParams, _smallAmount, this.constantOptions);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
const priceImpactBN = _get_price_impact(_amount, _output, _smallAmount, _smallOutput, inputCoinDecimals, outputCoinDecimals);
|
|
357
|
+
return Number(_cutZeros(priceImpactBN.toFixed(4)));
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
export function swapIsApproved(inputCoin, amount) {
|
|
361
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
362
|
+
return yield hasAllowance.call(this, [inputCoin], [amount], this.signerAddress, this.constants.ALIASES.router);
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
export function swapApproveEstimateGas(inputCoin, amount) {
|
|
366
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
367
|
+
return yield ensureAllowanceEstimateGas.call(this, [inputCoin], [amount], this.constants.ALIASES.router);
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
export function swapApprove(inputCoin, amount) {
|
|
371
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
372
|
+
return yield ensureAllowance.call(this, [inputCoin], [amount], this.constants.ALIASES.router);
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
export function swapEstimateGas(inputCoin, outputCoin, amount) {
|
|
376
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
377
|
+
const [inputCoinAddress, outputCoinAddress] = _getCoinAddresses.call(this, inputCoin, outputCoin);
|
|
378
|
+
const [inputCoinDecimals] = _getCoinDecimals.call(this, inputCoinAddress, outputCoinAddress);
|
|
379
|
+
const { route } = _getBestRouteAndOutput.call(this, inputCoinAddress, outputCoinAddress, amount);
|
|
380
|
+
if (route.length === 0)
|
|
381
|
+
return 0;
|
|
382
|
+
const _amount = parseUnits(amount, inputCoinDecimals);
|
|
383
|
+
const [gas] = yield _estimateGasForDifferentRoutes.call(this, [route], inputCoinAddress, outputCoinAddress, _amount);
|
|
384
|
+
return gas;
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
export function swap(inputCoin_1, outputCoin_1, amount_1) {
|
|
388
|
+
return __awaiter(this, arguments, void 0, function* (inputCoin, outputCoin, amount, slippage = 0.5) {
|
|
389
|
+
const [inputCoinAddress, outputCoinAddress] = _getCoinAddresses.call(this, inputCoin, outputCoin);
|
|
390
|
+
const [inputCoinDecimals, outputCoinDecimals] = _getCoinDecimals.call(this, inputCoinAddress, outputCoinAddress);
|
|
391
|
+
yield swapApprove.call(this, inputCoin, amount);
|
|
392
|
+
const { route, output } = _getBestRouteAndOutput.call(this, inputCoinAddress, outputCoinAddress, amount);
|
|
393
|
+
if (route.length === 0) {
|
|
394
|
+
throw new Error("This pair can't be exchanged");
|
|
395
|
+
}
|
|
396
|
+
const { _route, _swapParams, _pools } = _getExchangeArgs.call(this, route);
|
|
397
|
+
const _amount = parseUnits(amount, inputCoinDecimals);
|
|
398
|
+
const minRecvAmountBN = BN(output).times(100 - slippage).div(100);
|
|
399
|
+
const _minRecvAmount = fromBN(minRecvAmountBN, outputCoinDecimals);
|
|
400
|
+
const contract = this.contracts[this.constants.ALIASES.router].contract;
|
|
401
|
+
const value = isEth(inputCoinAddress) ? _amount : this.parseUnits("0");
|
|
402
|
+
yield this.updateFeeData();
|
|
326
403
|
if (_pools) {
|
|
327
|
-
|
|
404
|
+
const gasLimit = (DIGas(yield contract.exchange.estimateGas(_route, _swapParams, _amount, _minRecvAmount, _pools, Object.assign(Object.assign({}, this.constantOptions), { value })))) * (this.chainId === 1 ? this.parseUnits("130", 0) : this.parseUnits("160", 0)) / this.parseUnits("100", 0);
|
|
405
|
+
return yield contract.exchange(_route, _swapParams, _amount, _minRecvAmount, _pools, Object.assign(Object.assign({}, this.options), { value, gasLimit }));
|
|
328
406
|
}
|
|
329
407
|
else {
|
|
330
|
-
|
|
408
|
+
const gasLimit = (DIGas(yield contract.exchange.estimateGas(_route, _swapParams, _amount, _minRecvAmount, Object.assign(Object.assign({}, this.constantOptions), { value })))) * this.parseUnits("160", 0) / this.parseUnits("100", 0);
|
|
409
|
+
return yield contract.exchange(_route, _swapParams, _amount, _minRecvAmount, Object.assign(Object.assign({}, this.options), { value, gasLimit }));
|
|
331
410
|
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
if (route.length === 0)
|
|
350
|
-
return 0;
|
|
351
|
-
const _amount = parseUnits(amount, inputCoinDecimals);
|
|
352
|
-
const [gas] = yield _estimateGasForDifferentRoutes([route], inputCoinAddress, outputCoinAddress, _amount);
|
|
353
|
-
return gas;
|
|
354
|
-
});
|
|
355
|
-
export const swap = (inputCoin_1, outputCoin_1, amount_1, ...args_1) => __awaiter(void 0, [inputCoin_1, outputCoin_1, amount_1, ...args_1], void 0, function* (inputCoin, outputCoin, amount, slippage = 0.5) {
|
|
356
|
-
const [inputCoinAddress, outputCoinAddress] = _getCoinAddresses(inputCoin, outputCoin);
|
|
357
|
-
const [inputCoinDecimals, outputCoinDecimals] = _getCoinDecimals(inputCoinAddress, outputCoinAddress);
|
|
358
|
-
yield swapApprove(inputCoin, amount);
|
|
359
|
-
const { route, output } = _getBestRouteAndOutput(inputCoinAddress, outputCoinAddress, amount);
|
|
360
|
-
if (route.length === 0) {
|
|
361
|
-
throw new Error("This pair can't be exchanged");
|
|
362
|
-
}
|
|
363
|
-
const { _route, _swapParams, _pools } = _getExchangeArgs(route);
|
|
364
|
-
const _amount = parseUnits(amount, inputCoinDecimals);
|
|
365
|
-
const minRecvAmountBN = BN(output).times(100 - slippage).div(100);
|
|
366
|
-
const _minRecvAmount = fromBN(minRecvAmountBN, outputCoinDecimals);
|
|
367
|
-
const contract = curve.contracts[curve.constants.ALIASES.router].contract;
|
|
368
|
-
const value = isEth(inputCoinAddress) ? _amount : curve.parseUnits("0");
|
|
369
|
-
yield curve.updateFeeData();
|
|
370
|
-
if (_pools) {
|
|
371
|
-
const gasLimit = (DIGas(yield contract.exchange.estimateGas(_route, _swapParams, _amount, _minRecvAmount, _pools, Object.assign(Object.assign({}, curve.constantOptions), { value })))) * (curve.chainId === 1 ? curve.parseUnits("130", 0) : curve.parseUnits("160", 0)) / curve.parseUnits("100", 0);
|
|
372
|
-
return yield contract.exchange(_route, _swapParams, _amount, _minRecvAmount, _pools, Object.assign(Object.assign({}, curve.options), { value, gasLimit }));
|
|
373
|
-
}
|
|
374
|
-
else {
|
|
375
|
-
const gasLimit = (DIGas(yield contract.exchange.estimateGas(_route, _swapParams, _amount, _minRecvAmount, Object.assign(Object.assign({}, curve.constantOptions), { value })))) * curve.parseUnits("160", 0) / curve.parseUnits("100", 0);
|
|
376
|
-
return yield contract.exchange(_route, _swapParams, _amount, _minRecvAmount, Object.assign(Object.assign({}, curve.options), { value, gasLimit }));
|
|
377
|
-
}
|
|
378
|
-
});
|
|
379
|
-
export const getSwappedAmount = (tx, outputCoin) => __awaiter(void 0, void 0, void 0, function* () {
|
|
380
|
-
const [outputCoinAddress] = _getCoinAddresses(outputCoin);
|
|
381
|
-
const [outputCoinDecimals] = _getCoinDecimals(outputCoinAddress);
|
|
382
|
-
const txInfo = yield tx.wait();
|
|
383
|
-
if (txInfo === null)
|
|
384
|
-
return '0.0';
|
|
385
|
-
let res;
|
|
386
|
-
for (let i = 1; i <= txInfo.logs.length; i++) {
|
|
387
|
-
try {
|
|
388
|
-
const abiCoder = ethers.AbiCoder.defaultAbiCoder();
|
|
389
|
-
res = abiCoder.decode([`address[${ROUTE_LENGTH}]`, `uint256[${MAX_STEPS}][${MAX_STEPS}]`, `address[${MAX_STEPS}]`, 'uint256', 'uint256'], ethers.dataSlice(txInfo.logs[txInfo.logs.length - i].data, 0));
|
|
390
|
-
break;
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
export function getSwappedAmount(tx, outputCoin) {
|
|
414
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
415
|
+
const [outputCoinAddress] = _getCoinAddresses.call(this, outputCoin);
|
|
416
|
+
const [outputCoinDecimals] = _getCoinDecimals.call(this, outputCoinAddress);
|
|
417
|
+
const txInfo = yield tx.wait();
|
|
418
|
+
if (txInfo === null)
|
|
419
|
+
return '0.0';
|
|
420
|
+
let res;
|
|
421
|
+
for (let i = 1; i <= txInfo.logs.length; i++) {
|
|
422
|
+
try {
|
|
423
|
+
const abiCoder = ethers.AbiCoder.defaultAbiCoder();
|
|
424
|
+
res = abiCoder.decode([`address[${ROUTE_LENGTH}]`, `uint256[${MAX_STEPS}][${MAX_STEPS}]`, `address[${MAX_STEPS}]`, 'uint256', 'uint256'], ethers.dataSlice(txInfo.logs[txInfo.logs.length - i].data, 0));
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
catch (_a) { }
|
|
391
428
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
});
|
|
429
|
+
if (res === undefined)
|
|
430
|
+
return '0.0';
|
|
431
|
+
return this.formatUnits(res[res.length - 1], outputCoinDecimals);
|
|
432
|
+
});
|
|
433
|
+
}
|