@paraswap/dex-lib 2.35.3-quick-perps-proxy.2 → 2.35.3-quick-perps-proxy.4
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/config.js +39 -13
- package/build/config.js.map +1 -1
- package/build/constants.d.ts +2 -1
- package/build/constants.js +1 -0
- package/build/constants.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/generic-rfq/generic-rfq.d.ts +2 -1
- package/build/dex/generic-rfq/generic-rfq.js +5 -4
- package/build/dex/generic-rfq/generic-rfq.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/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 +29 -1
- package/build/dex/uniswap-v3/config.js.map +1 -1
- package/build/dex/weth/config.js +3 -0
- package/build/dex/weth/config.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.js +4 -1
- package/build/dex-helper/dummy-dex-helper.js.map +1 -1
- package/build/stateful-event-subscriber.d.ts +0 -1
- package/build/stateful-event-subscriber.js +2 -12
- package/build/stateful-event-subscriber.js.map +1 -1
- package/build/workers.d.ts +0 -0
- package/build/workers.js +2 -0
- package/build/workers.js.map +1 -0
- package/package.json +1 -1
- package/src/abi/aerodrome/aerodrome-pool-factory.json +586 -0
- package/src/config.ts +40 -14
- package/src/constants.ts +1 -0
- package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +120 -1
- package/src/dex/balancer-v2/config.ts +11 -2
- package/src/dex/generic-rfq/generic-rfq.ts +7 -4
- package/src/dex/hashflow/hashflow-e2e.test.ts +36 -3
- 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/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 +30 -1
- package/src/dex/uniswap-v3/uniswap-v3-e2e.test.ts +110 -0
- package/src/dex/uniswap-v3/uniswap-v3-integration.test.ts +140 -0
- package/src/dex/weth/config.ts +3 -0
- 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 +4 -1
- package/src/stateful-event-subscriber.ts +2 -12
- package/tests/constants-e2e.ts +47 -0
- package/tests/tenderly-simulation.ts +2 -2
- package/tests/utils-e2e.ts +3 -1
|
@@ -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
|
});
|
|
@@ -106,6 +106,19 @@ export const UniswapV3Config: DexConfigMap<DexParams> = {
|
|
|
106
106
|
subgraphURL:
|
|
107
107
|
'https://api.thegraph.com/subgraphs/name/lynnshaoyu/uniswap-v3-avax',
|
|
108
108
|
},
|
|
109
|
+
[Network.BASE]: {
|
|
110
|
+
factory: '0x33128a8fC17869897dcE68Ed026d694621f6FDfD',
|
|
111
|
+
quoter: '0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a',
|
|
112
|
+
router: '0xaeE2b8d4A154e36f479dAeCe3FB3e6c3c03d396E',
|
|
113
|
+
supportedFees: SUPPORTED_FEES,
|
|
114
|
+
stateMulticall: '0x7160f736c52e1e78e92FD4eE4D73e21A7Cf4F950',
|
|
115
|
+
uniswapMulticall: '0x091e99cb1C49331a94dD62755D168E941AbD0693',
|
|
116
|
+
chunksCount: 10,
|
|
117
|
+
initRetryFrequency: 10,
|
|
118
|
+
initHash: `0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54`,
|
|
119
|
+
subgraphURL:
|
|
120
|
+
'https://api.studio.thegraph.com/query/48211/uniswap-v3-base/version/latest',
|
|
121
|
+
},
|
|
109
122
|
},
|
|
110
123
|
SushiSwapV3: {
|
|
111
124
|
[Network.MAINNET]: {
|
|
@@ -197,6 +210,18 @@ export const UniswapV3Config: DexConfigMap<DexParams> = {
|
|
|
197
210
|
subgraphURL:
|
|
198
211
|
'https://api.thegraph.com/subgraphs/name/sushi-v3/v3-optimism',
|
|
199
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
|
+
},
|
|
200
225
|
},
|
|
201
226
|
ChronosV3: {
|
|
202
227
|
[Network.ARBITRUM]: {
|
|
@@ -220,7 +245,7 @@ export const UniswapV3Config: DexConfigMap<DexParams> = {
|
|
|
220
245
|
deployer: '0xb3e423ab9cE6C03D98326A3A2a0D7D96b0829f22',
|
|
221
246
|
quoter: '0xAA20EFF7ad2F523590dE6c04918DaAE0904E3b20',
|
|
222
247
|
router: '0xAA23611badAFB62D37E7295A682D21960ac85A90',
|
|
223
|
-
supportedFees: SUPPORTED_FEES,
|
|
248
|
+
supportedFees: [...SUPPORTED_FEES, 50n],
|
|
224
249
|
stateMulticall: '0x50EE4112Cab9c79812F23bE079aB3911395ACc8e',
|
|
225
250
|
stateMultiCallAbi: RamsesV2StateMulticallABI as AbiItem[],
|
|
226
251
|
uniswapMulticall: '0x1F98415757620B543A52E61c46B32eB19261F984',
|
|
@@ -283,4 +308,8 @@ export const Adapters: Record<number, AdapterMappings> = {
|
|
|
283
308
|
[SwapSide.SELL]: [{ name: 'AvalancheAdapter02', index: 5 }],
|
|
284
309
|
[SwapSide.BUY]: [{ name: 'AvalancheBuyAdapter', index: 6 }],
|
|
285
310
|
},
|
|
311
|
+
[Network.BASE]: {
|
|
312
|
+
[SwapSide.SELL]: [{ name: 'BaseAdapter01', index: 1 }],
|
|
313
|
+
[SwapSide.BUY]: [{ name: 'BaseBuyAdapter', index: 1 }],
|
|
314
|
+
},
|
|
286
315
|
};
|
|
@@ -403,6 +403,95 @@ describe('UniswapV3 E2E', () => {
|
|
|
403
403
|
);
|
|
404
404
|
});
|
|
405
405
|
|
|
406
|
+
describe('UniswapV3 Base', () => {
|
|
407
|
+
const network = Network.BASE;
|
|
408
|
+
const tokens = Tokens[network];
|
|
409
|
+
const holders = Holders[network];
|
|
410
|
+
const provider = new StaticJsonRpcProvider(
|
|
411
|
+
generateConfig(network).privateHttpProvider,
|
|
412
|
+
network,
|
|
413
|
+
);
|
|
414
|
+
|
|
415
|
+
const tokenASymbol: string = 'PRIME';
|
|
416
|
+
const tokenBSymbol: string = 'WETH';
|
|
417
|
+
const nativeTokenSymbol = NativeTokenSymbols[network];
|
|
418
|
+
|
|
419
|
+
const tokenAAmount: string = '1000000000000000000';
|
|
420
|
+
const tokenBAmount: string = '1000000000000000000';
|
|
421
|
+
const nativeTokenAmount = '1000000000000000000';
|
|
422
|
+
|
|
423
|
+
const sideToContractMethods = new Map([
|
|
424
|
+
[
|
|
425
|
+
SwapSide.SELL,
|
|
426
|
+
[
|
|
427
|
+
ContractMethod.simpleSwap,
|
|
428
|
+
ContractMethod.multiSwap,
|
|
429
|
+
ContractMethod.megaSwap,
|
|
430
|
+
],
|
|
431
|
+
],
|
|
432
|
+
[SwapSide.BUY, [ContractMethod.simpleBuy, ContractMethod.buy]],
|
|
433
|
+
]);
|
|
434
|
+
|
|
435
|
+
sideToContractMethods.forEach((contractMethods, side) =>
|
|
436
|
+
contractMethods.forEach((contractMethod: ContractMethod) => {
|
|
437
|
+
describe(`${contractMethod}`, () => {
|
|
438
|
+
it(`${network} ${side} ${contractMethod} ${nativeTokenSymbol} -> ${tokenASymbol}`, async () => {
|
|
439
|
+
await testE2E(
|
|
440
|
+
tokens[nativeTokenSymbol],
|
|
441
|
+
tokens[tokenASymbol],
|
|
442
|
+
holders[nativeTokenSymbol],
|
|
443
|
+
side === SwapSide.SELL ? nativeTokenAmount : tokenAAmount,
|
|
444
|
+
side,
|
|
445
|
+
dexKey,
|
|
446
|
+
contractMethod,
|
|
447
|
+
network,
|
|
448
|
+
provider,
|
|
449
|
+
);
|
|
450
|
+
});
|
|
451
|
+
it(`${network} ${side} ${contractMethod} ${tokenASymbol} -> ${nativeTokenSymbol}`, async () => {
|
|
452
|
+
await testE2E(
|
|
453
|
+
tokens[tokenASymbol],
|
|
454
|
+
tokens[nativeTokenSymbol],
|
|
455
|
+
holders[tokenASymbol],
|
|
456
|
+
side === SwapSide.SELL ? tokenAAmount : nativeTokenAmount,
|
|
457
|
+
side,
|
|
458
|
+
dexKey,
|
|
459
|
+
contractMethod,
|
|
460
|
+
network,
|
|
461
|
+
provider,
|
|
462
|
+
);
|
|
463
|
+
});
|
|
464
|
+
it(`${network} ${side} ${contractMethod} ${tokenBSymbol} -> ${tokenASymbol}`, async () => {
|
|
465
|
+
await testE2E(
|
|
466
|
+
tokens[tokenBSymbol],
|
|
467
|
+
tokens[tokenASymbol],
|
|
468
|
+
holders[tokenASymbol],
|
|
469
|
+
side === SwapSide.SELL ? tokenBAmount : tokenAAmount,
|
|
470
|
+
side,
|
|
471
|
+
dexKey,
|
|
472
|
+
contractMethod,
|
|
473
|
+
network,
|
|
474
|
+
provider,
|
|
475
|
+
);
|
|
476
|
+
});
|
|
477
|
+
it(`${network} ${side} ${contractMethod} ${tokenASymbol} -> ${tokenBSymbol}`, async () => {
|
|
478
|
+
await testE2E(
|
|
479
|
+
tokens[tokenASymbol],
|
|
480
|
+
tokens[tokenBSymbol],
|
|
481
|
+
holders[tokenASymbol],
|
|
482
|
+
side === SwapSide.SELL ? tokenAAmount : tokenBAmount,
|
|
483
|
+
side,
|
|
484
|
+
dexKey,
|
|
485
|
+
contractMethod,
|
|
486
|
+
network,
|
|
487
|
+
provider,
|
|
488
|
+
);
|
|
489
|
+
});
|
|
490
|
+
});
|
|
491
|
+
}),
|
|
492
|
+
);
|
|
493
|
+
});
|
|
494
|
+
|
|
406
495
|
describe('UniswapV3 Avalanche', () => {
|
|
407
496
|
const network = Network.AVALANCHE;
|
|
408
497
|
const tokens = Tokens[network];
|
|
@@ -999,5 +1088,26 @@ describe('UniswapV3 E2E', () => {
|
|
|
999
1088
|
nativeTokenAmount,
|
|
1000
1089
|
);
|
|
1001
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
|
+
});
|
|
1002
1112
|
});
|
|
1003
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
|
});
|
package/src/dex/weth/config.ts
CHANGED
|
@@ -64,6 +64,16 @@ export const WooFiV2Config: DexConfigMap<DexParams> = {
|
|
|
64
64
|
decimals: 6,
|
|
65
65
|
},
|
|
66
66
|
},
|
|
67
|
+
[Network.BASE]: {
|
|
68
|
+
wooPPV2Address: '0xb130a49065178465931d4f887056328CeA5D723f',
|
|
69
|
+
wooOracleV2Address: '0x2Fe5E5D341cFFa606a5d9DA1B6B646a381B0f7ec',
|
|
70
|
+
integrationHelperAddress: '0xC4E9B633685461E7B7A807D12a246C81f96F31B8',
|
|
71
|
+
// USDbC
|
|
72
|
+
quoteToken: {
|
|
73
|
+
address: '0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA',
|
|
74
|
+
decimals: 6,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
67
77
|
},
|
|
68
78
|
};
|
|
69
79
|
|
|
@@ -84,4 +94,7 @@ export const Adapters: Record<number, AdapterMappings> = {
|
|
|
84
94
|
[Network.AVALANCHE]: {
|
|
85
95
|
[SwapSide.SELL]: [{ name: 'AvalancheAdapter01', index: 12 }],
|
|
86
96
|
},
|
|
97
|
+
[Network.BASE]: {
|
|
98
|
+
[SwapSide.SELL]: [{ name: 'BaseAdapter01', index: 5 }],
|
|
99
|
+
},
|
|
87
100
|
};
|
|
@@ -213,4 +213,68 @@ describe('WooFiV2 E2E', () => {
|
|
|
213
213
|
tokenQuoteAmount,
|
|
214
214
|
);
|
|
215
215
|
});
|
|
216
|
+
|
|
217
|
+
describe('Base', () => {
|
|
218
|
+
const network = Network.BASE;
|
|
219
|
+
|
|
220
|
+
const baseATokenSymbol = 'USDbC';
|
|
221
|
+
const baseBTokenSymbol = 'ETH';
|
|
222
|
+
|
|
223
|
+
const tokenBaseAAmount = '100000000';
|
|
224
|
+
const tokenBaseBAmount = '1000000000000000000';
|
|
225
|
+
|
|
226
|
+
const tokens = Tokens[network];
|
|
227
|
+
const holders = Holders[network];
|
|
228
|
+
|
|
229
|
+
const provider = new StaticJsonRpcProvider(
|
|
230
|
+
generateConfig(network).privateHttpProvider,
|
|
231
|
+
network,
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
const sideToContractMethods = new Map([
|
|
235
|
+
[
|
|
236
|
+
SwapSide.SELL,
|
|
237
|
+
[
|
|
238
|
+
ContractMethod.simpleSwap,
|
|
239
|
+
ContractMethod.multiSwap,
|
|
240
|
+
ContractMethod.megaSwap,
|
|
241
|
+
],
|
|
242
|
+
],
|
|
243
|
+
]);
|
|
244
|
+
|
|
245
|
+
sideToContractMethods.forEach((contractMethods, side) =>
|
|
246
|
+
describe(`${side}`, () => {
|
|
247
|
+
contractMethods.forEach((contractMethod: ContractMethod) => {
|
|
248
|
+
describe(`${contractMethod}`, () => {
|
|
249
|
+
it(`${baseATokenSymbol} -> ${baseBTokenSymbol}`, async () => {
|
|
250
|
+
await testE2E(
|
|
251
|
+
tokens[baseATokenSymbol],
|
|
252
|
+
tokens[baseBTokenSymbol],
|
|
253
|
+
holders[baseATokenSymbol],
|
|
254
|
+
tokenBaseAAmount,
|
|
255
|
+
side,
|
|
256
|
+
dexKey,
|
|
257
|
+
contractMethod,
|
|
258
|
+
network,
|
|
259
|
+
provider,
|
|
260
|
+
);
|
|
261
|
+
});
|
|
262
|
+
it(`${baseBTokenSymbol} -> ${baseATokenSymbol}`, async () => {
|
|
263
|
+
await testE2E(
|
|
264
|
+
tokens[baseBTokenSymbol],
|
|
265
|
+
tokens[baseATokenSymbol],
|
|
266
|
+
holders[baseBTokenSymbol],
|
|
267
|
+
tokenBaseBAmount,
|
|
268
|
+
side,
|
|
269
|
+
dexKey,
|
|
270
|
+
contractMethod,
|
|
271
|
+
network,
|
|
272
|
+
provider,
|
|
273
|
+
);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
}),
|
|
278
|
+
);
|
|
279
|
+
});
|
|
216
280
|
});
|
|
@@ -41,6 +41,7 @@ class DummyCache implements ICache {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
async rawget(key: string): Promise<string | null> {
|
|
44
|
+
return this.storage[key] ? this.storage[key] : null;
|
|
44
45
|
return null;
|
|
45
46
|
}
|
|
46
47
|
|
|
@@ -49,10 +50,12 @@ class DummyCache implements ICache {
|
|
|
49
50
|
value: string,
|
|
50
51
|
ttl: number,
|
|
51
52
|
): Promise<string | null> {
|
|
52
|
-
|
|
53
|
+
this.storage[key] = value;
|
|
54
|
+
return 'OK';
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
async rawdel(key: string): Promise<void> {
|
|
58
|
+
delete this.storage[key];
|
|
56
59
|
return;
|
|
57
60
|
}
|
|
58
61
|
|