@paraswap/dex-lib 2.14.1 → 2.14.3-3pool-enable.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/abi/maverick/pool.json +913 -0
- package/build/abi/maverick/router.json +703 -0
- package/build/dex/curve-v1/config.js +19 -19
- package/build/dex/curve-v1/config.js.map +1 -1
- package/build/dex/curve-v1-factory/config.js +2 -5
- package/build/dex/curve-v1-factory/config.js.map +1 -1
- package/build/dex/generic-rfq/e2e-test-config.d.ts +9 -0
- package/build/dex/generic-rfq/e2e-test-config.js +33 -0
- package/build/dex/generic-rfq/e2e-test-config.js.map +1 -0
- package/build/dex/generic-rfq/rate-fetcher.js +2 -0
- package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
- package/build/dex/generic-rfq/validators.d.ts +1 -1
- package/build/dex/generic-rfq/validators.js +36 -26
- package/build/dex/generic-rfq/validators.js.map +1 -1
- package/build/dex/maverick/config.d.ts +4 -0
- package/build/dex/maverick/config.js +20 -0
- package/build/dex/maverick/config.js.map +1 -0
- package/build/dex/maverick/maverick-math/maverick-pool-math.d.ts +67 -0
- package/build/dex/maverick/maverick-math/maverick-pool-math.js +406 -0
- package/build/dex/maverick/maverick-math/maverick-pool-math.js.map +1 -0
- package/build/dex/maverick/maverick-math/maverick-sol-math.d.ts +17 -0
- package/build/dex/maverick/maverick-math/maverick-sol-math.js +139 -0
- package/build/dex/maverick/maverick-math/maverick-sol-math.js.map +1 -0
- package/build/dex/maverick/maverick-pool.d.ts +41 -0
- package/build/dex/maverick/maverick-pool.js +130 -0
- package/build/dex/maverick/maverick-pool.js.map +1 -0
- package/build/dex/maverick/maverick.d.ts +42 -0
- package/build/dex/maverick/maverick.js +174 -0
- package/build/dex/maverick/maverick.js.map +1 -0
- package/build/dex/maverick/subgraph-queries.d.ts +4 -0
- package/build/dex/maverick/subgraph-queries.js +114 -0
- package/build/dex/maverick/subgraph-queries.js.map +1 -0
- package/build/dex/maverick/types.d.ts +46 -0
- package/build/dex/maverick/types.js +3 -0
- package/build/dex/maverick/types.js.map +1 -0
- package/build/lib/fetcher/fetcher.js +3 -0
- package/build/lib/fetcher/fetcher.js.map +1 -1
- package/package.json +1 -1
- package/src/dex/curve-v1/config.ts +19 -19
- package/src/dex/curve-v1/curve-v1-e2e.test.ts +89 -0
- package/src/dex/curve-v1-factory/config.ts +2 -5
- package/src/dex/generic-rfq/e2e-test-config.ts +37 -0
- package/src/dex/generic-rfq/generic-rfq-e2e.test.ts +63 -258
- package/src/dex/generic-rfq/generic-rfq-local-e2e.test.ts +121 -0
- package/src/dex/generic-rfq/rate-fetcher.ts +2 -0
- package/src/dex/generic-rfq/validators.test.ts +6 -32
- package/src/dex/generic-rfq/validators.ts +57 -32
- package/src/lib/fetcher/fetcher.ts +6 -0
- package/tests/constants-e2e.ts +12 -0
- package/tests/utils-e2e.ts +59 -48
|
@@ -112,10 +112,11 @@ describe('GenericRFQ Validator test', () => {
|
|
|
112
112
|
},
|
|
113
113
|
};
|
|
114
114
|
|
|
115
|
-
const
|
|
115
|
+
const pricesNegativeSpread = {
|
|
116
116
|
prices: {
|
|
117
117
|
'WETH/DAI': {
|
|
118
118
|
bids: [
|
|
119
|
+
['1337.425240000000000000', '1.166200000000000000'],
|
|
119
120
|
['1333.024812000000000000', '1.166200000000000000'],
|
|
120
121
|
['1333.425240000000000000', '1.166200000000000000'],
|
|
121
122
|
['1332.624384000000000000', '1.166200000000000000'],
|
|
@@ -135,29 +136,6 @@ describe('GenericRFQ Validator test', () => {
|
|
|
135
136
|
},
|
|
136
137
|
};
|
|
137
138
|
|
|
138
|
-
const pricesInvalidAskNotSortedAsc = {
|
|
139
|
-
prices: {
|
|
140
|
-
'WETH/DAI': {
|
|
141
|
-
bids: [
|
|
142
|
-
['1333.425240000000000000', '1.166200000000000000'],
|
|
143
|
-
['1333.024812000000000000', '1.166200000000000000'],
|
|
144
|
-
['1332.624384000000000000', '1.166200000000000000'],
|
|
145
|
-
['1332.223956000000000000', '1.166200000000000000'],
|
|
146
|
-
['1331.823528000000000000', '1.166200000000000000'],
|
|
147
|
-
['1331.423100000000000000', '1.169000000000000000'],
|
|
148
|
-
],
|
|
149
|
-
asks: [
|
|
150
|
-
['1337.146033000000000000', '1.166200000000000000'],
|
|
151
|
-
['1336.745410000000000000', '1.166200000000000000'],
|
|
152
|
-
['1337.546656000000000000', '1.166200000000000000'],
|
|
153
|
-
['1337.947279000000000000', '1.166200000000000000'],
|
|
154
|
-
['1338.347902000000000000', '1.166200000000000000'],
|
|
155
|
-
['1338.748525000000000000', '1.169000000000000000'],
|
|
156
|
-
],
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
|
|
161
139
|
const noPrices = {
|
|
162
140
|
prices: {
|
|
163
141
|
'WETH/DAI': {},
|
|
@@ -200,12 +178,6 @@ describe('GenericRFQ Validator test', () => {
|
|
|
200
178
|
|
|
201
179
|
it('Price test', () => {
|
|
202
180
|
expect(() => validateAndCast(prices, pricesResponse)).not.toThrowError();
|
|
203
|
-
expect(() =>
|
|
204
|
-
validateAndCast(pricesInvalidBidsNotSortedDesc, pricesResponse),
|
|
205
|
-
).toThrowError();
|
|
206
|
-
expect(() =>
|
|
207
|
-
validateAndCast(pricesInvalidAskNotSortedAsc, pricesResponse),
|
|
208
|
-
).toThrowError();
|
|
209
181
|
expect(() =>
|
|
210
182
|
validateAndCast(noPrices, pricesResponse),
|
|
211
183
|
).not.toThrowError();
|
|
@@ -218,6 +190,9 @@ describe('GenericRFQ Validator test', () => {
|
|
|
218
190
|
expect(() =>
|
|
219
191
|
validateAndCast(onlyAsks, pricesResponse),
|
|
220
192
|
).not.toThrowError();
|
|
193
|
+
expect(() =>
|
|
194
|
+
validateAndCast(pricesNegativeSpread, pricesResponse),
|
|
195
|
+
).toThrowError('the maximum bid is higher than minimum ask');
|
|
221
196
|
});
|
|
222
197
|
});
|
|
223
198
|
|
|
@@ -261,11 +236,10 @@ describe('GenericRFQ Validator test', () => {
|
|
|
261
236
|
},
|
|
262
237
|
};
|
|
263
238
|
|
|
264
|
-
it('
|
|
239
|
+
it('Order test', () => {
|
|
265
240
|
expect(() =>
|
|
266
241
|
validateAndCast(order, firmRateResponseValidator),
|
|
267
242
|
).not.toThrowError();
|
|
268
|
-
// expect(() => validateAndCast(invalidBlacklist, blacklistResponseValidator)).toThrowError();
|
|
269
243
|
});
|
|
270
244
|
});
|
|
271
245
|
});
|
|
@@ -56,7 +56,7 @@ const stringNumberValidator = (
|
|
|
56
56
|
return value;
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
const
|
|
59
|
+
const pricesValidator = joi
|
|
60
60
|
.array()
|
|
61
61
|
.items(
|
|
62
62
|
joi
|
|
@@ -66,47 +66,58 @@ const pricesValidatorWithoutSorting = joi
|
|
|
66
66
|
);
|
|
67
67
|
|
|
68
68
|
const ext: joi.Extension = {
|
|
69
|
-
type: '
|
|
70
|
-
base:
|
|
69
|
+
type: 'validatedPrices',
|
|
70
|
+
base: joi.object({
|
|
71
|
+
bids: pricesValidator,
|
|
72
|
+
asks: pricesValidator,
|
|
73
|
+
}),
|
|
71
74
|
rules: {
|
|
72
|
-
|
|
73
|
-
validate: (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
bidsLowerThanAsks: {
|
|
76
|
+
validate: (
|
|
77
|
+
values: { bids: string[]; asks: string[] },
|
|
78
|
+
helpers: CustomHelpers,
|
|
79
|
+
) => {
|
|
80
|
+
if (
|
|
81
|
+
!values.bids ||
|
|
82
|
+
!values.asks ||
|
|
83
|
+
values.bids.length === 0 ||
|
|
84
|
+
values.asks.length === 0
|
|
85
|
+
) {
|
|
86
|
+
return values;
|
|
87
|
+
}
|
|
88
|
+
const maxBid = values.bids
|
|
89
|
+
.map(numbers => new BigNumber(numbers[0]))
|
|
90
|
+
.reduce(
|
|
91
|
+
(previousValue, currentValue) =>
|
|
92
|
+
currentValue.gte(previousValue) ? currentValue : previousValue,
|
|
93
|
+
new BigNumber(0),
|
|
94
|
+
);
|
|
95
|
+
const minAsk = values.asks
|
|
96
|
+
.map(numbers => new BigNumber(numbers[0]))
|
|
97
|
+
.reduce(
|
|
98
|
+
(previousValue, currentValue) =>
|
|
99
|
+
currentValue.lte(previousValue) ? currentValue : previousValue,
|
|
100
|
+
new BigNumber('123456789012345678901234567890'),
|
|
101
|
+
);
|
|
102
|
+
return maxBid < minAsk
|
|
79
103
|
? values
|
|
80
104
|
: helpers.message({
|
|
81
|
-
custom:
|
|
82
|
-
});
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
desc: {
|
|
86
|
-
validate: (values: string[][], helpers: CustomHelpers) => {
|
|
87
|
-
const prices = values.map(numbers => new BigNumber(numbers[0]));
|
|
88
|
-
const isAscOrder = prices.every(
|
|
89
|
-
(x, i) => i === 0 || x.lte(prices[i - 1]),
|
|
90
|
-
);
|
|
91
|
-
return isAscOrder
|
|
92
|
-
? values
|
|
93
|
-
: helpers.message({
|
|
94
|
-
custom: `array is not desc sorted ${JSON.stringify(values)}`,
|
|
105
|
+
custom: 'the maximum bid is higher than minimum ask',
|
|
95
106
|
});
|
|
96
107
|
},
|
|
97
108
|
},
|
|
98
109
|
},
|
|
99
110
|
};
|
|
100
111
|
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
export const priceValidator = joi.object({
|
|
104
|
-
bids: pricesArrayValidator.sortedArray().desc(),
|
|
105
|
-
asks: pricesArrayValidator.sortedArray().asc(),
|
|
106
|
-
});
|
|
112
|
+
export const priceValidator = joi.extend(ext);
|
|
107
113
|
|
|
108
114
|
export const pricesResponse = joi.object({
|
|
109
|
-
prices: joi
|
|
115
|
+
prices: joi
|
|
116
|
+
.object()
|
|
117
|
+
.pattern(
|
|
118
|
+
joi.string().min(1),
|
|
119
|
+
priceValidator.validatedPrices().bidsLowerThanAsks(),
|
|
120
|
+
),
|
|
110
121
|
});
|
|
111
122
|
|
|
112
123
|
export const validateAndCast = <T>(
|
|
@@ -171,12 +182,26 @@ const stringStartWithHex0x = (
|
|
|
171
182
|
return value;
|
|
172
183
|
};
|
|
173
184
|
|
|
185
|
+
const mustBeAugustusSwapper = (
|
|
186
|
+
value: string,
|
|
187
|
+
helpers: CustomHelpers,
|
|
188
|
+
): string | ErrorReport => {
|
|
189
|
+
const allowedTakers = [
|
|
190
|
+
'0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57'.toLowerCase(),
|
|
191
|
+
];
|
|
192
|
+
return allowedTakers.includes(value.toLowerCase())
|
|
193
|
+
? value
|
|
194
|
+
: helpers.message({
|
|
195
|
+
custom: `"order.taker" must be any of ${JSON.stringify(allowedTakers)}`,
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
|
|
174
199
|
export const orderWithSignatureValidator = joi
|
|
175
200
|
.object({
|
|
176
201
|
nonceAndMeta: joi.string().custom(stringPositiveBigIntValidator),
|
|
177
202
|
expiry: joi.number().min(0),
|
|
178
203
|
maker: addressSchema.required(),
|
|
179
|
-
taker: addressSchema.required(),
|
|
204
|
+
taker: addressSchema.required().custom(mustBeAugustusSwapper),
|
|
180
205
|
makerAsset: addressSchema.required(),
|
|
181
206
|
takerAsset: addressSchema.required(),
|
|
182
207
|
makerAmount: joi
|
|
@@ -76,6 +76,12 @@ export default class Fetcher<T> {
|
|
|
76
76
|
.map((_, i) => i)
|
|
77
77
|
.filter(i => results[i] instanceof Error);
|
|
78
78
|
|
|
79
|
+
results.map(result => {
|
|
80
|
+
this.logger.info(
|
|
81
|
+
'Results Data:',
|
|
82
|
+
JSON.stringify((result as any).data, null, 4).substring(0, 500),
|
|
83
|
+
);
|
|
84
|
+
});
|
|
79
85
|
failures.forEach(i => {
|
|
80
86
|
this.logger.warn(
|
|
81
87
|
`failed polling ${this.requests[i].info.requestOptions.url} ${results[i]}`,
|
package/tests/constants-e2e.ts
CHANGED
|
@@ -50,6 +50,8 @@ export const Tokens: {
|
|
|
50
50
|
USDT: {
|
|
51
51
|
address: '0xdac17f958d2ee523a2206206994597c13d831ec7',
|
|
52
52
|
decimals: 6,
|
|
53
|
+
addBalance: balancesFn,
|
|
54
|
+
addAllowance: allowedFn,
|
|
53
55
|
},
|
|
54
56
|
STETH: {
|
|
55
57
|
address: '0xae7ab96520de3a18e5e111b5eaab095312d7fe84',
|
|
@@ -474,6 +476,14 @@ export const Tokens: {
|
|
|
474
476
|
address: '0x74b23882a30290451A17c44f4F05243b6b58C76d',
|
|
475
477
|
decimals: 18,
|
|
476
478
|
},
|
|
479
|
+
GDAI: {
|
|
480
|
+
address: '0x07E6332dD090D287d3489245038daF987955DCFB',
|
|
481
|
+
decimals: 18,
|
|
482
|
+
},
|
|
483
|
+
GUSDC: {
|
|
484
|
+
address: '0xe578C856933D8e1082740bf7661e379Aa2A30b26',
|
|
485
|
+
decimals: 6,
|
|
486
|
+
},
|
|
477
487
|
},
|
|
478
488
|
[Network.BSC]: {
|
|
479
489
|
POPS: {
|
|
@@ -905,6 +915,8 @@ export const Holders: {
|
|
|
905
915
|
TOR: '0x70de4b5ed310fd93da3c0bae824fb99cb4d44dd8',
|
|
906
916
|
BOO: '0xf778f4d7a14a8cb73d5261f9c61970ef4e7d7842',
|
|
907
917
|
ETH: '0xf48883940b4056801de30f12b934dcea90133ee6',
|
|
918
|
+
GUSDC: '0x894d774a293f8aa3d23d67815d4cadb5319c1094',
|
|
919
|
+
GDAI: '0x0e2ed73f9c1409e2b36fe6c46e60d4557b7c2ac0',
|
|
908
920
|
},
|
|
909
921
|
[Network.BSC]: {
|
|
910
922
|
DAI: '0xf68a4b64162906eff0ff6ae34e2bb1cd42fef62d',
|
package/tests/utils-e2e.ts
CHANGED
|
@@ -299,6 +299,7 @@ export type TestParamE2E = {
|
|
|
299
299
|
destTokenBalanceOverrides?: Record<Address, string>;
|
|
300
300
|
destTokenAllowanceOverrides?: Record<Address, string>;
|
|
301
301
|
sleepMs?: number;
|
|
302
|
+
skipTenderly?: boolean;
|
|
302
303
|
};
|
|
303
304
|
|
|
304
305
|
const makeFakeTransferToSenderAddress = (
|
|
@@ -332,14 +333,19 @@ export async function newTestE2E({
|
|
|
332
333
|
limitOrderProvider,
|
|
333
334
|
transferFees,
|
|
334
335
|
sleepMs,
|
|
336
|
+
skipTenderly,
|
|
335
337
|
}: TestParamE2E) {
|
|
338
|
+
const useTenderly = !skipTenderly;
|
|
336
339
|
const amount = BigInt(_amount);
|
|
337
340
|
const twiceAmount = BigInt(_amount) * 2n;
|
|
338
|
-
|
|
339
|
-
|
|
341
|
+
let ts: TenderlySimulation | undefined = undefined;
|
|
342
|
+
if (useTenderly) {
|
|
343
|
+
ts = new TenderlySimulation(network);
|
|
344
|
+
await ts.setup();
|
|
345
|
+
}
|
|
340
346
|
|
|
341
|
-
if (adapterBytecode) {
|
|
342
|
-
const deployTx = await ts.simulate(
|
|
347
|
+
if (useTenderly && adapterBytecode) {
|
|
348
|
+
const deployTx = await (ts as TenderlySimulation).simulate(
|
|
343
349
|
deployAdapterParams(adapterBytecode, network),
|
|
344
350
|
);
|
|
345
351
|
|
|
@@ -354,13 +360,13 @@ export async function newTestE2E({
|
|
|
354
360
|
'gas',
|
|
355
361
|
);
|
|
356
362
|
|
|
357
|
-
const whitelistTx = await ts.simulate(
|
|
363
|
+
const whitelistTx = await (ts as TenderlySimulation).simulate(
|
|
358
364
|
whiteListAdapterParams(adapterAddress, network),
|
|
359
365
|
);
|
|
360
366
|
expect(whitelistTx.success).toEqual(true);
|
|
361
367
|
}
|
|
362
368
|
|
|
363
|
-
if (thirdPartyAddress) {
|
|
369
|
+
if (useTenderly && thirdPartyAddress) {
|
|
364
370
|
const stateOverrides: StateOverrides = {
|
|
365
371
|
networkID: `${network}`,
|
|
366
372
|
stateOverrides: {},
|
|
@@ -377,43 +383,15 @@ export async function newTestE2E({
|
|
|
377
383
|
: (BigInt(MAX_UINT) / 4n).toString(),
|
|
378
384
|
);
|
|
379
385
|
|
|
380
|
-
await ts.simulate(giftTx, stateOverrides);
|
|
386
|
+
await (ts as TenderlySimulation).simulate(giftTx, stateOverrides);
|
|
381
387
|
}
|
|
382
388
|
|
|
383
|
-
const stateOverrides: StateOverrides = {
|
|
384
|
-
networkID: `${network}`,
|
|
385
|
-
stateOverrides: {},
|
|
386
|
-
};
|
|
387
|
-
srcToken.applyOverrides(stateOverrides);
|
|
388
|
-
destToken.applyOverrides(stateOverrides);
|
|
389
|
-
|
|
390
|
-
if (swapSide === SwapSide.SELL) {
|
|
391
|
-
srcToken
|
|
392
|
-
.addBalance(senderAddress, twiceAmount.toString())
|
|
393
|
-
.addAllowance(
|
|
394
|
-
senderAddress,
|
|
395
|
-
config.tokenTransferProxyAddress,
|
|
396
|
-
amount.toString(),
|
|
397
|
-
);
|
|
398
|
-
} else {
|
|
399
|
-
srcToken
|
|
400
|
-
.addBalance(senderAddress, MAX_UINT)
|
|
401
|
-
.addAllowance(
|
|
402
|
-
senderAddress,
|
|
403
|
-
config.tokenTransferProxyAddress,
|
|
404
|
-
(BigInt(MAX_UINT) / 8n).toString(),
|
|
405
|
-
);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
srcToken.applyOverrides(stateOverrides);
|
|
409
|
-
destToken.applyOverrides(stateOverrides);
|
|
410
|
-
|
|
411
389
|
const useAPI = testingEndpoint && !poolIdentifiers;
|
|
412
390
|
// The API currently doesn't allow for specifying poolIdentifiers
|
|
413
391
|
const paraswap: IParaSwapSDK = new LocalParaswapSDK(
|
|
414
392
|
network,
|
|
415
393
|
dexKey,
|
|
416
|
-
|
|
394
|
+
'',
|
|
417
395
|
limitOrderProvider,
|
|
418
396
|
);
|
|
419
397
|
|
|
@@ -449,19 +427,52 @@ export async function newTestE2E({
|
|
|
449
427
|
senderAddress,
|
|
450
428
|
);
|
|
451
429
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
430
|
+
if (useTenderly) {
|
|
431
|
+
const stateOverrides: StateOverrides = {
|
|
432
|
+
networkID: `${network}`,
|
|
433
|
+
stateOverrides: {},
|
|
434
|
+
};
|
|
435
|
+
srcToken.applyOverrides(stateOverrides);
|
|
436
|
+
destToken.applyOverrides(stateOverrides);
|
|
437
|
+
|
|
438
|
+
if (swapSide === SwapSide.SELL) {
|
|
439
|
+
srcToken
|
|
440
|
+
.addBalance(senderAddress, twiceAmount.toString())
|
|
441
|
+
.addAllowance(
|
|
442
|
+
senderAddress,
|
|
443
|
+
config.tokenTransferProxyAddress,
|
|
444
|
+
amount.toString(),
|
|
445
|
+
);
|
|
446
|
+
} else {
|
|
447
|
+
srcToken
|
|
448
|
+
.addBalance(senderAddress, MAX_UINT)
|
|
449
|
+
.addAllowance(
|
|
450
|
+
senderAddress,
|
|
451
|
+
config.tokenTransferProxyAddress,
|
|
452
|
+
(BigInt(MAX_UINT) / 8n).toString(),
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
srcToken.applyOverrides(stateOverrides);
|
|
457
|
+
destToken.applyOverrides(stateOverrides);
|
|
458
|
+
|
|
459
|
+
const swapTx = await (ts as TenderlySimulation).simulate(
|
|
460
|
+
swapParams,
|
|
461
|
+
stateOverrides,
|
|
462
462
|
);
|
|
463
|
-
|
|
464
|
-
|
|
463
|
+
console.log(`${srcToken.address}_${destToken.address}_${dexKey!}`);
|
|
464
|
+
// Only log gas estimate if testing against API
|
|
465
|
+
if (useAPI)
|
|
466
|
+
console.log(
|
|
467
|
+
`Gas Estimate API: ${priceRoute.gasCost}, Simulated: ${
|
|
468
|
+
swapTx!.gasUsed
|
|
469
|
+
}, Difference: ${
|
|
470
|
+
parseInt(priceRoute.gasCost) - parseInt(swapTx!.gasUsed)
|
|
471
|
+
}`,
|
|
472
|
+
);
|
|
473
|
+
console.log(`Tenderly URL: ${swapTx!.tenderlyUrl}`);
|
|
474
|
+
expect(swapTx!.success).toEqual(true);
|
|
475
|
+
}
|
|
465
476
|
} finally {
|
|
466
477
|
if (paraswap.releaseResources) {
|
|
467
478
|
await paraswap.releaseResources();
|