@paraswap/dex-lib 2.35.7-worker-pool.3 → 2.36.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/build/abi/aerodrome/aerodrome-pool-factory.json +586 -0
- package/build/abi/api3-proxy.json +7 -0
- package/build/config.js +2 -2
- package/build/dex/algebra/algebra.js +5 -4
- package/build/dex/algebra/algebra.js.map +1 -1
- package/build/dex/balancer-v2/config.js +10 -2
- package/build/dex/balancer-v2/config.js.map +1 -1
- package/build/dex/index.js +2 -0
- package/build/dex/index.js.map +1 -1
- package/build/dex/maverick-v1/config.js +9 -0
- package/build/dex/maverick-v1/config.js.map +1 -1
- package/build/dex/maverick-v1/maverick-v1.js +11 -2
- package/build/dex/maverick-v1/maverick-v1.js.map +1 -1
- package/build/dex/pancakeswap-v3/config.js +17 -0
- package/build/dex/pancakeswap-v3/config.js.map +1 -1
- package/build/dex/pancakeswap-v3/pancakeswap-v3.js +7 -6
- package/build/dex/pancakeswap-v3/pancakeswap-v3.js.map +1 -1
- package/build/dex/quick-perps/pool.js +21 -6
- package/build/dex/quick-perps/pool.js.map +1 -1
- package/build/dex/quick-perps/quick-perps.js +34 -28
- package/build/dex/quick-perps/quick-perps.js.map +1 -1
- package/build/dex/solidly/config.js +22 -1
- package/build/dex/solidly/config.js.map +1 -1
- package/build/dex/solidly/forks-override/aerodrome.d.ts +14 -0
- package/build/dex/solidly/forks-override/aerodrome.js +48 -0
- package/build/dex/solidly/forks-override/aerodrome.js.map +1 -0
- package/build/dex/solidly/solidly.js +1 -0
- package/build/dex/solidly/solidly.js.map +1 -1
- package/build/dex/uniswap-v3/config.js +12 -0
- package/build/dex/uniswap-v3/config.js.map +1 -1
- package/build/dex/uniswap-v3/uniswap-v3.js +5 -4
- package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
- package/build/dex/woo-fi-v2/config.js +13 -0
- package/build/dex/woo-fi-v2/config.js.map +1 -1
- package/build/dex-helper/dummy-dex-helper.d.ts +0 -1
- package/build/dex-helper/dummy-dex-helper.js +0 -3
- package/build/dex-helper/dummy-dex-helper.js.map +1 -1
- package/build/dex-helper/idex-helper.d.ts +0 -1
- package/build/lib/api3-feed.d.ts +4 -0
- package/build/lib/api3-feed.js +18 -0
- package/build/lib/api3-feed.js.map +1 -1
- package/package.json +1 -1
- package/src/abi/aerodrome/aerodrome-pool-factory.json +586 -0
- package/src/abi/api3-proxy.json +7 -0
- package/src/config.ts +2 -2
- package/src/dex/algebra/algebra.ts +10 -10
- package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +120 -1
- package/src/dex/balancer-v2/config.ts +11 -2
- package/src/dex/index.ts +2 -0
- package/src/dex/maverick-v1/config.ts +10 -0
- package/src/dex/maverick-v1/maverick-v1-e2e.test.ts +115 -1
- package/src/dex/maverick-v1/maverick-v1.ts +12 -2
- package/src/dex/pancakeswap-v3/config.ts +19 -0
- package/src/dex/pancakeswap-v3/pancakeswap-v3-e2e.test.ts +114 -0
- package/src/dex/pancakeswap-v3/pancakeswap-v3.ts +12 -12
- package/src/dex/quick-perps/pool.ts +42 -7
- package/src/dex/quick-perps/quick-perps-events.test.ts +0 -1
- package/src/dex/quick-perps/quick-perps.ts +45 -35
- package/src/dex/solidly/config.ts +24 -1
- package/src/dex/solidly/forks-override/aerodrome.ts +53 -0
- package/src/dex/solidly/solidly-e2e.test.ts +88 -0
- package/src/dex/solidly/solidly-integration.test.ts +66 -0
- package/src/dex/solidly/solidly.ts +1 -0
- package/src/dex/uniswap-v3/config.ts +12 -0
- package/src/dex/uniswap-v3/uniswap-v3-e2e.test.ts +24 -9
- package/src/dex/uniswap-v3/uniswap-v3-integration.test.ts +140 -0
- package/src/dex/uniswap-v3/uniswap-v3.ts +10 -10
- package/src/dex/woo-fi-v2/config.ts +13 -0
- package/src/dex/woo-fi-v2/woo-fi-v2-e2e.test.ts +64 -0
- package/src/dex-helper/dummy-dex-helper.ts +0 -15
- package/src/dex-helper/idex-helper.ts +0 -7
- package/src/lib/api3-feed.ts +35 -0
- package/tests/constants-e2e.ts +30 -0
- package/tests/utils-e2e.ts +1 -0
|
@@ -104,6 +104,7 @@ export class QuickPerpsEventPool extends ComposedEventSubscriber<PoolState> {
|
|
|
104
104
|
const evenState = this.getState(blockNumber);
|
|
105
105
|
if (evenState) return evenState;
|
|
106
106
|
const onChainState = await this.generateState(blockNumber);
|
|
107
|
+
this.logger.warn(`State is generated in RPC fallback call`);
|
|
107
108
|
this.setState(onChainState, blockNumber);
|
|
108
109
|
return onChainState;
|
|
109
110
|
}
|
|
@@ -283,7 +284,8 @@ export class QuickPerpsEventPool extends ComposedEventSubscriber<PoolState> {
|
|
|
283
284
|
for (let priceFeed of priceFeeds) {
|
|
284
285
|
const api3ServerAddressCallData =
|
|
285
286
|
Api3FeedSubscriber.getApi3ServerV1MultiCallInput(priceFeed);
|
|
286
|
-
const dataFeedIdCallData =
|
|
287
|
+
const dataFeedIdCallData =
|
|
288
|
+
Api3FeedSubscriber.getDapiNameHashMultiCallInput(priceFeed);
|
|
287
289
|
multiCallData.push(...[api3ServerAddressCallData, dataFeedIdCallData]);
|
|
288
290
|
multicallSlices.push([i, i + 2]);
|
|
289
291
|
i += 2;
|
|
@@ -315,24 +317,31 @@ export class QuickPerpsEventPool extends ComposedEventSubscriber<PoolState> {
|
|
|
315
317
|
await multiContract.methods.aggregate(multiCallData).call({}, blockNumber)
|
|
316
318
|
).returnData;
|
|
317
319
|
|
|
318
|
-
const
|
|
320
|
+
const api3ServerV1Prep: {
|
|
319
321
|
[address: string]: {
|
|
320
322
|
proxy: Address;
|
|
321
323
|
api3ServerV1: Address;
|
|
322
|
-
dataFeedId: string;
|
|
323
324
|
};
|
|
324
325
|
} = {};
|
|
326
|
+
const getFeedIdRequests: MultiCallInput[] = [];
|
|
327
|
+
|
|
325
328
|
for (let token of tokens) {
|
|
326
|
-
const [api3ServerAddressRes,
|
|
329
|
+
const [api3ServerAddressRes, dapiNameHashRes] = configResults.slice(
|
|
327
330
|
...multicallSlices.shift()!,
|
|
328
331
|
);
|
|
329
332
|
const serverV1Address =
|
|
330
333
|
Api3FeedSubscriber.decodeApi3ServerV1Result(api3ServerAddressRes);
|
|
331
|
-
const
|
|
332
|
-
|
|
334
|
+
const dapiNameHash =
|
|
335
|
+
Api3FeedSubscriber.decodeDapiNameHash(dapiNameHashRes);
|
|
336
|
+
getFeedIdRequests.push(
|
|
337
|
+
Api3FeedSubscriber.getFeedIdFromDapiNameHash(
|
|
338
|
+
serverV1Address,
|
|
339
|
+
dapiNameHash,
|
|
340
|
+
),
|
|
341
|
+
);
|
|
342
|
+
api3ServerV1Prep[token] = {
|
|
333
343
|
proxy: priceFeeds.shift(),
|
|
334
344
|
api3ServerV1: serverV1Address,
|
|
335
|
-
dataFeedId,
|
|
336
345
|
};
|
|
337
346
|
}
|
|
338
347
|
|
|
@@ -355,6 +364,32 @@ export class QuickPerpsEventPool extends ComposedEventSubscriber<PoolState> {
|
|
|
355
364
|
const vaultConfigResults = configResults.slice(...multicallSlices.shift()!);
|
|
356
365
|
const vaultConfig = Vault.getConfig(vaultConfigResults, tokens);
|
|
357
366
|
|
|
367
|
+
const feedIdResults = (
|
|
368
|
+
await multiContract.methods
|
|
369
|
+
.aggregate(getFeedIdRequests)
|
|
370
|
+
.call({}, blockNumber)
|
|
371
|
+
).returnData;
|
|
372
|
+
|
|
373
|
+
const api3ServerV1: {
|
|
374
|
+
[address: string]: {
|
|
375
|
+
proxy: Address;
|
|
376
|
+
api3ServerV1: Address;
|
|
377
|
+
dataFeedId: string;
|
|
378
|
+
};
|
|
379
|
+
} = {};
|
|
380
|
+
for (let [i, token] of tokens.entries()) {
|
|
381
|
+
const { proxy, api3ServerV1: api3ServerAddress } =
|
|
382
|
+
api3ServerV1Prep[token];
|
|
383
|
+
const dataFeedId = Api3FeedSubscriber.decodeFeedIdFromDapiNameHash(
|
|
384
|
+
feedIdResults[i],
|
|
385
|
+
);
|
|
386
|
+
api3ServerV1[token] = {
|
|
387
|
+
proxy,
|
|
388
|
+
api3ServerV1: api3ServerAddress,
|
|
389
|
+
dataFeedId,
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
358
393
|
return {
|
|
359
394
|
vaultAddress: dexParams.vault,
|
|
360
395
|
readerAddress: dexParams.reader,
|
|
@@ -117,45 +117,55 @@ export class QuickPerps extends SimpleExchange implements IDex<QuickPerpsData> {
|
|
|
117
117
|
limitPools?: string[],
|
|
118
118
|
): Promise<null | ExchangePrices<QuickPerpsData>> {
|
|
119
119
|
if (side === SwapSide.BUY || !this.pool) return null;
|
|
120
|
-
|
|
121
|
-
.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
120
|
+
try {
|
|
121
|
+
const srcAddress = this.dexHelper.config
|
|
122
|
+
.wrapETH(srcToken)
|
|
123
|
+
.address.toLowerCase();
|
|
124
|
+
const destAddress = this.dexHelper.config
|
|
125
|
+
.wrapETH(destToken)
|
|
126
|
+
.address.toLowerCase();
|
|
127
|
+
if (
|
|
128
|
+
srcAddress === destAddress ||
|
|
129
|
+
!(
|
|
130
|
+
this.supportedTokensMap[srcAddress] &&
|
|
131
|
+
this.supportedTokensMap[destAddress]
|
|
132
|
+
)
|
|
131
133
|
)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (limitPools && pools.some(p => !limitPools.includes(p))) return null;
|
|
134
|
+
return null;
|
|
135
|
+
const srcPoolIdentifier = `${this.dexKey}_${srcAddress}`;
|
|
136
|
+
const destPoolIdentifier = `${this.dexKey}_${destAddress}`;
|
|
137
|
+
const pools = [srcPoolIdentifier, destPoolIdentifier];
|
|
138
|
+
if (limitPools && pools.some(p => !limitPools.includes(p))) return null;
|
|
138
139
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
140
|
+
const unitVolume = getBigIntPow(srcToken.decimals);
|
|
141
|
+
const prices = await this.pool.getAmountOut(
|
|
142
|
+
srcAddress,
|
|
143
|
+
destAddress,
|
|
144
|
+
[unitVolume, ...amounts],
|
|
145
|
+
blockNumber,
|
|
146
|
+
);
|
|
146
147
|
|
|
147
|
-
|
|
148
|
+
if (!prices) return null;
|
|
148
149
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
150
|
+
return [
|
|
151
|
+
{
|
|
152
|
+
prices: prices.slice(1),
|
|
153
|
+
unit: prices[0],
|
|
154
|
+
gasCost: QuickPerpsGasCost,
|
|
155
|
+
exchange: this.dexKey,
|
|
156
|
+
data: {},
|
|
157
|
+
poolAddresses: [this.params.vault],
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
} catch (e) {
|
|
161
|
+
this.logger.error(
|
|
162
|
+
`Error_getPrices ${srcToken.symbol || srcToken.address}, ${
|
|
163
|
+
destToken.symbol || destToken.address
|
|
164
|
+
}, ${side}: `,
|
|
165
|
+
e,
|
|
166
|
+
);
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
159
169
|
}
|
|
160
170
|
|
|
161
171
|
// Returns estimated gas cost of calldata for this DEX in multiSwap
|
|
@@ -83,6 +83,17 @@ export const SolidlyConfig: DexConfigMap<DexParams> = {
|
|
|
83
83
|
feeCode: 0,
|
|
84
84
|
},
|
|
85
85
|
},
|
|
86
|
+
Aerodrome: {
|
|
87
|
+
[Network.BASE]: {
|
|
88
|
+
// There is no subgraph for Aerodrome
|
|
89
|
+
factoryAddress: '0x420DD381b31aEf6683db6B902084cB0FFECe40Da',
|
|
90
|
+
router: '0xDCf4EE5B700e2a5Fec458e06B763A4a3E3004494',
|
|
91
|
+
initCode:
|
|
92
|
+
'0x1a8f01f7eab324003d9388f229ea17991eee9c9d14586f429799f3656790eba0',
|
|
93
|
+
poolGasCost: 180 * 1000,
|
|
94
|
+
feeCode: 0,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
86
97
|
Cone: {
|
|
87
98
|
[Network.BSC]: {
|
|
88
99
|
subgraphURL: 'https://api.thegraph.com/subgraphs/name/cone-exchange/cone',
|
|
@@ -157,6 +168,15 @@ export const SolidlyConfig: DexConfigMap<DexParams> = {
|
|
|
157
168
|
feeCode: 0,
|
|
158
169
|
poolGasCost: 180 * 1000,
|
|
159
170
|
},
|
|
171
|
+
[Network.BASE]: {
|
|
172
|
+
factoryAddress: '0xed8db60acc29e14bc867a497d94ca6e3ceb5ec04',
|
|
173
|
+
router: '0xDCf4EE5B700e2a5Fec458e06B763A4a3E3004494',
|
|
174
|
+
initCode:
|
|
175
|
+
'0x7ba31a081e879b8e7f06d4e8bf5ee26b5c2680669c5701f4cdbdcde51727b275',
|
|
176
|
+
feeCode: 0,
|
|
177
|
+
feeFactor: 1e18,
|
|
178
|
+
poolGasCost: 180 * 1000,
|
|
179
|
+
},
|
|
160
180
|
},
|
|
161
181
|
};
|
|
162
182
|
|
|
@@ -165,7 +185,7 @@ export const Adapters: Record<number, AdapterMappings> = {
|
|
|
165
185
|
[SwapSide.SELL]: [{ name: 'PolygonAdapter02', index: 3 }], // dystopia
|
|
166
186
|
},
|
|
167
187
|
[Network.FANTOM]: {
|
|
168
|
-
[SwapSide.SELL]: [{ name: 'FantomAdapter01', index: 10 }], // solidly
|
|
188
|
+
[SwapSide.SELL]: [{ name: 'FantomAdapter01', index: 10 }], // solidly, spiritSwapV2, equalizer
|
|
169
189
|
},
|
|
170
190
|
[Network.OPTIMISM]: {
|
|
171
191
|
[SwapSide.SELL]: [{ name: 'OptimismAdapter01', index: 8 }], // velodrome
|
|
@@ -182,4 +202,7 @@ export const Adapters: Record<number, AdapterMappings> = {
|
|
|
182
202
|
[Network.ARBITRUM]: {
|
|
183
203
|
[SwapSide.SELL]: [{ name: 'ArbitrumAdapter02', index: 1 }], // chronos, ramses
|
|
184
204
|
},
|
|
205
|
+
[Network.BASE]: {
|
|
206
|
+
[SwapSide.SELL]: [{ name: 'BaseAdapter01', index: 3 }], // aerodrome, equalizer
|
|
207
|
+
},
|
|
185
208
|
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { VelodromeV2 } from './velodromeV2';
|
|
2
|
+
import { Network, NULL_ADDRESS } from '../../../constants';
|
|
3
|
+
import { getDexKeysWithNetwork } from '../../../utils';
|
|
4
|
+
import _ from 'lodash';
|
|
5
|
+
import { SolidlyConfig } from '../config';
|
|
6
|
+
import { Token } from '../../../types';
|
|
7
|
+
import { IDexHelper } from '../../../dex-helper';
|
|
8
|
+
import AerodromeFactoryABI from '../../../abi/aerodrome/aerodrome-pool-factory.json';
|
|
9
|
+
|
|
10
|
+
export class Aerodrome extends VelodromeV2 {
|
|
11
|
+
public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
|
|
12
|
+
getDexKeysWithNetwork(_.pick(SolidlyConfig, ['Aerodrome']));
|
|
13
|
+
|
|
14
|
+
constructor(
|
|
15
|
+
protected network: Network,
|
|
16
|
+
dexKey: string,
|
|
17
|
+
protected dexHelper: IDexHelper,
|
|
18
|
+
) {
|
|
19
|
+
super(network, dexKey, dexHelper);
|
|
20
|
+
|
|
21
|
+
this.factory = new dexHelper.web3Provider.eth.Contract(
|
|
22
|
+
AerodromeFactoryABI as any,
|
|
23
|
+
SolidlyConfig[dexKey][network].factoryAddress,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async findSolidlyPair(from: Token, to: Token, stable: boolean) {
|
|
28
|
+
if (from.address.toLowerCase() === to.address.toLowerCase()) return null;
|
|
29
|
+
const [token0, token1] =
|
|
30
|
+
from.address.toLowerCase() < to.address.toLowerCase()
|
|
31
|
+
? [from, to]
|
|
32
|
+
: [to, from];
|
|
33
|
+
|
|
34
|
+
const typePostfix = this.poolPostfix(stable);
|
|
35
|
+
const key = `${token0.address.toLowerCase()}-${token1.address.toLowerCase()}-${typePostfix}`;
|
|
36
|
+
let pair = this.pairs[key];
|
|
37
|
+
if (pair) return pair;
|
|
38
|
+
|
|
39
|
+
let exchange = await this.factory.methods
|
|
40
|
+
// Solidly has additional boolean parameter "StablePool"
|
|
41
|
+
// At first we look for uniswap-like volatile pool
|
|
42
|
+
.getPool(token0.address, token1.address, stable)
|
|
43
|
+
.call();
|
|
44
|
+
|
|
45
|
+
if (exchange === NULL_ADDRESS) {
|
|
46
|
+
pair = { token0, token1, stable };
|
|
47
|
+
} else {
|
|
48
|
+
pair = { token0, token1, exchange, stable };
|
|
49
|
+
}
|
|
50
|
+
this.pairs[key] = pair;
|
|
51
|
+
return pair;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -1404,4 +1404,92 @@ describe('Solidly E2E', () => {
|
|
|
1404
1404
|
);
|
|
1405
1405
|
});
|
|
1406
1406
|
});
|
|
1407
|
+
|
|
1408
|
+
describe('Base', () => {
|
|
1409
|
+
const network = Network.BASE;
|
|
1410
|
+
|
|
1411
|
+
describe('Aerodrome', () => {
|
|
1412
|
+
const dexKey = 'Aerodrome';
|
|
1413
|
+
const tokenASymbol: string = 'USDbC';
|
|
1414
|
+
const tokenBSymbol: string = 'DAI';
|
|
1415
|
+
|
|
1416
|
+
const tokenAAmount: string = '1111100000';
|
|
1417
|
+
const tokenBAmount: string = '100000000000000000';
|
|
1418
|
+
const nativeTokenAmount = '100000000000000000';
|
|
1419
|
+
|
|
1420
|
+
testForNetwork(
|
|
1421
|
+
network,
|
|
1422
|
+
dexKey,
|
|
1423
|
+
tokenASymbol,
|
|
1424
|
+
tokenBSymbol,
|
|
1425
|
+
tokenAAmount,
|
|
1426
|
+
tokenBAmount,
|
|
1427
|
+
nativeTokenAmount,
|
|
1428
|
+
);
|
|
1429
|
+
});
|
|
1430
|
+
|
|
1431
|
+
describe('Equalizer', () => {
|
|
1432
|
+
const dexKey = 'Equalizer';
|
|
1433
|
+
const network = Network.BASE;
|
|
1434
|
+
|
|
1435
|
+
const tokenASymbol: string = 'USDbC';
|
|
1436
|
+
const tokenAAmount: string = '1111100000';
|
|
1437
|
+
const nativeTokenAmount = '110000000000000000';
|
|
1438
|
+
|
|
1439
|
+
const provider = new StaticJsonRpcProvider(
|
|
1440
|
+
generateConfig(network).privateHttpProvider,
|
|
1441
|
+
network,
|
|
1442
|
+
);
|
|
1443
|
+
const tokens = Tokens[network];
|
|
1444
|
+
const holders = Holders[network];
|
|
1445
|
+
const nativeTokenSymbol = NativeTokenSymbols[network];
|
|
1446
|
+
|
|
1447
|
+
// TODO: Add any direct swap contractMethod name if it exists
|
|
1448
|
+
const sideToContractMethods = new Map([
|
|
1449
|
+
[
|
|
1450
|
+
SwapSide.SELL,
|
|
1451
|
+
[
|
|
1452
|
+
ContractMethod.simpleSwap,
|
|
1453
|
+
ContractMethod.multiSwap,
|
|
1454
|
+
ContractMethod.megaSwap,
|
|
1455
|
+
],
|
|
1456
|
+
],
|
|
1457
|
+
]);
|
|
1458
|
+
|
|
1459
|
+
sideToContractMethods.forEach((contractMethods, side) =>
|
|
1460
|
+
describe(`${side}`, () => {
|
|
1461
|
+
contractMethods.forEach((contractMethod: ContractMethod) => {
|
|
1462
|
+
describe(`${contractMethod}`, () => {
|
|
1463
|
+
it(`${nativeTokenSymbol} -> ${tokenASymbol}`, async () => {
|
|
1464
|
+
await testE2E(
|
|
1465
|
+
tokens[nativeTokenSymbol],
|
|
1466
|
+
tokens[tokenASymbol],
|
|
1467
|
+
holders[nativeTokenSymbol],
|
|
1468
|
+
side === SwapSide.SELL ? nativeTokenAmount : tokenAAmount,
|
|
1469
|
+
side,
|
|
1470
|
+
dexKey,
|
|
1471
|
+
contractMethod,
|
|
1472
|
+
network,
|
|
1473
|
+
provider,
|
|
1474
|
+
);
|
|
1475
|
+
});
|
|
1476
|
+
it(`${tokenASymbol} -> ${nativeTokenSymbol}`, async () => {
|
|
1477
|
+
await testE2E(
|
|
1478
|
+
tokens[tokenASymbol],
|
|
1479
|
+
tokens[nativeTokenSymbol],
|
|
1480
|
+
holders[tokenASymbol],
|
|
1481
|
+
side === SwapSide.SELL ? tokenAAmount : nativeTokenAmount,
|
|
1482
|
+
side,
|
|
1483
|
+
dexKey,
|
|
1484
|
+
contractMethod,
|
|
1485
|
+
network,
|
|
1486
|
+
provider,
|
|
1487
|
+
);
|
|
1488
|
+
});
|
|
1489
|
+
});
|
|
1490
|
+
});
|
|
1491
|
+
}),
|
|
1492
|
+
);
|
|
1493
|
+
});
|
|
1494
|
+
});
|
|
1407
1495
|
});
|
|
@@ -1202,4 +1202,70 @@ describe('Solidly integration tests', () => {
|
|
|
1202
1202
|
});
|
|
1203
1203
|
});
|
|
1204
1204
|
});
|
|
1205
|
+
|
|
1206
|
+
describe('Base', () => {
|
|
1207
|
+
const network = Network.BASE;
|
|
1208
|
+
const dexHelper = new DummyDexHelper(network);
|
|
1209
|
+
const checkOnChainPricing = constructCheckOnChainPricing(dexHelper);
|
|
1210
|
+
|
|
1211
|
+
describe('Equalizer', () => {
|
|
1212
|
+
const dexKey = 'Equalizer';
|
|
1213
|
+
const equalizer = new Equalizer(network, dexKey, dexHelper);
|
|
1214
|
+
|
|
1215
|
+
describe('UniswapV2 like pool', function () {
|
|
1216
|
+
const TokenASymbol = 'USDbC';
|
|
1217
|
+
const tokenA = Tokens[network][TokenASymbol];
|
|
1218
|
+
const TokenBSymbol = 'ETH';
|
|
1219
|
+
const tokenB = Tokens[network][TokenBSymbol];
|
|
1220
|
+
|
|
1221
|
+
const amounts = amounts18;
|
|
1222
|
+
|
|
1223
|
+
it('getPoolIdentifiers and getPricesVolume', async function () {
|
|
1224
|
+
const blocknumber = await dexHelper.web3Provider.eth.getBlockNumber();
|
|
1225
|
+
const pools = await equalizer.getPoolIdentifiers(
|
|
1226
|
+
tokenA,
|
|
1227
|
+
tokenB,
|
|
1228
|
+
SwapSide.SELL,
|
|
1229
|
+
blocknumber,
|
|
1230
|
+
);
|
|
1231
|
+
console.log(
|
|
1232
|
+
`${TokenASymbol} <> ${TokenBSymbol} Pool Identifiers: `,
|
|
1233
|
+
pools,
|
|
1234
|
+
);
|
|
1235
|
+
|
|
1236
|
+
expect(pools.length).toBeGreaterThan(0);
|
|
1237
|
+
|
|
1238
|
+
const poolPrices = await equalizer.getPricesVolume(
|
|
1239
|
+
tokenA,
|
|
1240
|
+
tokenB,
|
|
1241
|
+
amounts,
|
|
1242
|
+
SwapSide.SELL,
|
|
1243
|
+
blocknumber,
|
|
1244
|
+
pools,
|
|
1245
|
+
);
|
|
1246
|
+
console.log(
|
|
1247
|
+
`${TokenASymbol} <> ${TokenBSymbol} Pool Prices: `,
|
|
1248
|
+
poolPrices,
|
|
1249
|
+
);
|
|
1250
|
+
|
|
1251
|
+
expect(poolPrices).not.toBeNull();
|
|
1252
|
+
checkPoolPrices(poolPrices!, amounts, SwapSide.SELL, dexKey);
|
|
1253
|
+
|
|
1254
|
+
// Check if onchain pricing equals to calculated ones
|
|
1255
|
+
|
|
1256
|
+
for (const poolPrice of poolPrices || []) {
|
|
1257
|
+
await checkOnChainPricing(
|
|
1258
|
+
equalizer,
|
|
1259
|
+
'getAmountOut',
|
|
1260
|
+
blocknumber,
|
|
1261
|
+
poolPrice.prices,
|
|
1262
|
+
poolPrice.poolAddresses![0],
|
|
1263
|
+
tokenA.address,
|
|
1264
|
+
amounts,
|
|
1265
|
+
);
|
|
1266
|
+
}
|
|
1267
|
+
});
|
|
1268
|
+
});
|
|
1269
|
+
});
|
|
1270
|
+
});
|
|
1205
1271
|
});
|
|
@@ -210,6 +210,18 @@ export const UniswapV3Config: DexConfigMap<DexParams> = {
|
|
|
210
210
|
subgraphURL:
|
|
211
211
|
'https://api.thegraph.com/subgraphs/name/sushi-v3/v3-optimism',
|
|
212
212
|
},
|
|
213
|
+
[Network.BASE]: {
|
|
214
|
+
factory: '0xc35DADB65012eC5796536bD9864eD8773aBc74C4',
|
|
215
|
+
quoter: '0xb1E835Dc2785b52265711e17fCCb0fd018226a6e',
|
|
216
|
+
router: '0xCc0e85901f33D375FcdD9a888B05Df9616F68277',
|
|
217
|
+
supportedFees: SUPPORTED_FEES,
|
|
218
|
+
stateMulticall: '0x7160f736c52e1e78e92FD4eE4D73e21A7Cf4F950',
|
|
219
|
+
uniswapMulticall: '0x091e99cb1C49331a94dD62755D168E941AbD0693',
|
|
220
|
+
chunksCount: 10,
|
|
221
|
+
initRetryFrequency: 10,
|
|
222
|
+
initHash: `0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54`,
|
|
223
|
+
subgraphURL: 'https://api.studio.thegraph.com/query/32073/v3-base/v0.0.1',
|
|
224
|
+
},
|
|
213
225
|
},
|
|
214
226
|
ChronosV3: {
|
|
215
227
|
[Network.ARBITRUM]: {
|
|
@@ -424,18 +424,12 @@ describe('UniswapV3 E2E', () => {
|
|
|
424
424
|
[
|
|
425
425
|
SwapSide.SELL,
|
|
426
426
|
[
|
|
427
|
-
|
|
427
|
+
ContractMethod.simpleSwap,
|
|
428
428
|
ContractMethod.multiSwap,
|
|
429
|
-
|
|
430
|
-
],
|
|
431
|
-
],
|
|
432
|
-
[
|
|
433
|
-
SwapSide.BUY,
|
|
434
|
-
[
|
|
435
|
-
// ContractMethod.simpleBuy,
|
|
436
|
-
// ContractMethod.buy
|
|
429
|
+
ContractMethod.megaSwap,
|
|
437
430
|
],
|
|
438
431
|
],
|
|
432
|
+
[SwapSide.BUY, [ContractMethod.simpleBuy, ContractMethod.buy]],
|
|
439
433
|
]);
|
|
440
434
|
|
|
441
435
|
sideToContractMethods.forEach((contractMethods, side) =>
|
|
@@ -1094,5 +1088,26 @@ describe('UniswapV3 E2E', () => {
|
|
|
1094
1088
|
nativeTokenAmount,
|
|
1095
1089
|
);
|
|
1096
1090
|
});
|
|
1091
|
+
|
|
1092
|
+
describe('BASE', () => {
|
|
1093
|
+
const network = Network.BASE;
|
|
1094
|
+
|
|
1095
|
+
const tokenASymbol: string = 'USDbC';
|
|
1096
|
+
const tokenBSymbol: string = 'DAI';
|
|
1097
|
+
|
|
1098
|
+
const tokenAAmount: string = '111110000';
|
|
1099
|
+
const tokenBAmount: string = '110000000000000000';
|
|
1100
|
+
const nativeTokenAmount = '1100000000000000000';
|
|
1101
|
+
|
|
1102
|
+
testForNetwork(
|
|
1103
|
+
network,
|
|
1104
|
+
dexKey,
|
|
1105
|
+
tokenASymbol,
|
|
1106
|
+
tokenBSymbol,
|
|
1107
|
+
tokenAAmount,
|
|
1108
|
+
tokenBAmount,
|
|
1109
|
+
nativeTokenAmount,
|
|
1110
|
+
);
|
|
1111
|
+
});
|
|
1097
1112
|
});
|
|
1098
1113
|
});
|
|
@@ -959,4 +959,144 @@ describe('SushiSwapV3', () => {
|
|
|
959
959
|
expect(falseChecksCounter).toBeLessThan(poolPrices!.length);
|
|
960
960
|
});
|
|
961
961
|
});
|
|
962
|
+
|
|
963
|
+
describe('Base', () => {
|
|
964
|
+
let blockNumber: number;
|
|
965
|
+
let sushiSwapV3: UniswapV3;
|
|
966
|
+
let sushiSwapV3Mainnet: UniswapV3;
|
|
967
|
+
|
|
968
|
+
const network = Network.BASE;
|
|
969
|
+
const dexHelper = new DummyDexHelper(network);
|
|
970
|
+
const TokenASymbol = 'USDbC';
|
|
971
|
+
const TokenA = Tokens[network][TokenASymbol];
|
|
972
|
+
|
|
973
|
+
const TokenBSymbol = 'DAI';
|
|
974
|
+
const TokenB = Tokens[network][TokenBSymbol];
|
|
975
|
+
|
|
976
|
+
beforeEach(async () => {
|
|
977
|
+
blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
|
|
978
|
+
sushiSwapV3 = new UniswapV3(network, dexKey, dexHelper);
|
|
979
|
+
sushiSwapV3Mainnet = new UniswapV3(Network.MAINNET, dexKey, dexHelper);
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
it('getPoolIdentifiers and getPricesVolume SELL', async function () {
|
|
983
|
+
const amounts = [0n, BI_POWS[6], 2000000n];
|
|
984
|
+
|
|
985
|
+
const pools = await sushiSwapV3.getPoolIdentifiers(
|
|
986
|
+
TokenA,
|
|
987
|
+
TokenB,
|
|
988
|
+
SwapSide.SELL,
|
|
989
|
+
blockNumber,
|
|
990
|
+
);
|
|
991
|
+
console.log(
|
|
992
|
+
`${TokenASymbol} <> ${TokenBSymbol} Pool Identifiers: `,
|
|
993
|
+
pools,
|
|
994
|
+
);
|
|
995
|
+
|
|
996
|
+
expect(pools.length).toBeGreaterThan(0);
|
|
997
|
+
|
|
998
|
+
const poolPrices = await sushiSwapV3.getPricesVolume(
|
|
999
|
+
TokenA,
|
|
1000
|
+
TokenB,
|
|
1001
|
+
amounts,
|
|
1002
|
+
SwapSide.SELL,
|
|
1003
|
+
blockNumber,
|
|
1004
|
+
pools,
|
|
1005
|
+
);
|
|
1006
|
+
console.log(
|
|
1007
|
+
`${TokenASymbol} <> ${TokenBSymbol} Pool Prices: `,
|
|
1008
|
+
poolPrices,
|
|
1009
|
+
);
|
|
1010
|
+
|
|
1011
|
+
expect(poolPrices).not.toBeNull();
|
|
1012
|
+
checkPoolPrices(poolPrices!, amounts, SwapSide.SELL, dexKey);
|
|
1013
|
+
|
|
1014
|
+
let falseChecksCounter = 0;
|
|
1015
|
+
await Promise.all(
|
|
1016
|
+
poolPrices!.map(async price => {
|
|
1017
|
+
const fee = sushiSwapV3.eventPools[price.poolIdentifier!]!.feeCode;
|
|
1018
|
+
const res = await checkOnChainPricing(
|
|
1019
|
+
dexHelper,
|
|
1020
|
+
sushiSwapV3,
|
|
1021
|
+
'quoteExactInputSingle',
|
|
1022
|
+
blockNumber,
|
|
1023
|
+
'0xb1E835Dc2785b52265711e17fCCb0fd018226a6e',
|
|
1024
|
+
price.prices,
|
|
1025
|
+
TokenA.address,
|
|
1026
|
+
TokenB.address,
|
|
1027
|
+
fee,
|
|
1028
|
+
amounts,
|
|
1029
|
+
);
|
|
1030
|
+
if (res === false) falseChecksCounter++;
|
|
1031
|
+
}),
|
|
1032
|
+
);
|
|
1033
|
+
|
|
1034
|
+
expect(falseChecksCounter).toBeLessThan(poolPrices!.length);
|
|
1035
|
+
});
|
|
1036
|
+
|
|
1037
|
+
it('getPoolIdentifiers and getPricesVolume BUY', async function () {
|
|
1038
|
+
const amounts = [0n, BI_POWS[6], 2000000n];
|
|
1039
|
+
|
|
1040
|
+
const pools = await sushiSwapV3.getPoolIdentifiers(
|
|
1041
|
+
TokenA,
|
|
1042
|
+
TokenB,
|
|
1043
|
+
SwapSide.BUY,
|
|
1044
|
+
blockNumber,
|
|
1045
|
+
);
|
|
1046
|
+
console.log(
|
|
1047
|
+
`${TokenASymbol} <> ${TokenBSymbol} Pool Identifiers: `,
|
|
1048
|
+
pools,
|
|
1049
|
+
);
|
|
1050
|
+
|
|
1051
|
+
expect(pools.length).toBeGreaterThan(0);
|
|
1052
|
+
|
|
1053
|
+
const poolPrices = await sushiSwapV3.getPricesVolume(
|
|
1054
|
+
TokenA,
|
|
1055
|
+
TokenB,
|
|
1056
|
+
amounts,
|
|
1057
|
+
SwapSide.BUY,
|
|
1058
|
+
blockNumber,
|
|
1059
|
+
pools,
|
|
1060
|
+
);
|
|
1061
|
+
console.log(
|
|
1062
|
+
`${TokenASymbol} <> ${TokenBSymbol} Pool Prices: `,
|
|
1063
|
+
poolPrices,
|
|
1064
|
+
);
|
|
1065
|
+
|
|
1066
|
+
expect(poolPrices).not.toBeNull();
|
|
1067
|
+
checkPoolPrices(poolPrices!, amounts, SwapSide.SELL, dexKey);
|
|
1068
|
+
|
|
1069
|
+
let falseChecksCounter = 0;
|
|
1070
|
+
await Promise.all(
|
|
1071
|
+
poolPrices!.map(async price => {
|
|
1072
|
+
const fee = sushiSwapV3.eventPools[price.poolIdentifier!]!.feeCode;
|
|
1073
|
+
const res = await checkOnChainPricing(
|
|
1074
|
+
dexHelper,
|
|
1075
|
+
sushiSwapV3,
|
|
1076
|
+
'quoteExactOutputSingle',
|
|
1077
|
+
blockNumber,
|
|
1078
|
+
'0xb1E835Dc2785b52265711e17fCCb0fd018226a6e',
|
|
1079
|
+
price.prices,
|
|
1080
|
+
TokenA.address,
|
|
1081
|
+
TokenB.address,
|
|
1082
|
+
fee,
|
|
1083
|
+
amounts,
|
|
1084
|
+
);
|
|
1085
|
+
if (res === false) falseChecksCounter++;
|
|
1086
|
+
}),
|
|
1087
|
+
);
|
|
1088
|
+
|
|
1089
|
+
expect(falseChecksCounter).toBeLessThan(poolPrices!.length);
|
|
1090
|
+
});
|
|
1091
|
+
|
|
1092
|
+
it('getTopPoolsForToken', async function () {
|
|
1093
|
+
const poolLiquidity = await sushiSwapV3.getTopPoolsForToken(
|
|
1094
|
+
TokenB.address,
|
|
1095
|
+
10,
|
|
1096
|
+
);
|
|
1097
|
+
console.log(`${TokenASymbol} Top Pools:`, poolLiquidity);
|
|
1098
|
+
|
|
1099
|
+
checkPoolsLiquidity(poolLiquidity, TokenB.address, dexKey);
|
|
1100
|
+
});
|
|
1101
|
+
});
|
|
962
1102
|
});
|