@paraswap/dex-lib 2.35.6 → 2.35.7-multiple-dex-base-chain.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.
Files changed (44) hide show
  1. package/build/abi/aerodrome/aerodrome-pool-factory.json +586 -0
  2. package/build/config.js +2 -2
  3. package/build/dex/balancer-v2/config.js +9 -1
  4. package/build/dex/balancer-v2/config.js.map +1 -1
  5. package/build/dex/index.js +2 -0
  6. package/build/dex/index.js.map +1 -1
  7. package/build/dex/maverick-v1/config.js +9 -0
  8. package/build/dex/maverick-v1/config.js.map +1 -1
  9. package/build/dex/maverick-v1/maverick-v1.js.map +1 -1
  10. package/build/dex/pancakeswap-v3/config.js +17 -0
  11. package/build/dex/pancakeswap-v3/config.js.map +1 -1
  12. package/build/dex/solidly/config.js +13 -0
  13. package/build/dex/solidly/config.js.map +1 -1
  14. package/build/dex/solidly/forks-override/aerodrome.d.ts +14 -0
  15. package/build/dex/solidly/forks-override/aerodrome.js +48 -0
  16. package/build/dex/solidly/forks-override/aerodrome.js.map +1 -0
  17. package/build/dex/solidly/solidly.js +1 -0
  18. package/build/dex/solidly/solidly.js.map +1 -1
  19. package/build/dex/uniswap-v3/config.js +12 -0
  20. package/build/dex/uniswap-v3/config.js.map +1 -1
  21. package/build/dex/woo-fi-v2/config.js +13 -0
  22. package/build/dex/woo-fi-v2/config.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/abi/aerodrome/aerodrome-pool-factory.json +586 -0
  25. package/src/config.ts +2 -2
  26. package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +122 -1
  27. package/src/dex/balancer-v2/config.ts +10 -1
  28. package/src/dex/index.ts +2 -0
  29. package/src/dex/maverick-v1/config.ts +10 -0
  30. package/src/dex/maverick-v1/maverick-v1-e2e.test.ts +121 -1
  31. package/src/dex/maverick-v1/maverick-v1.ts +1 -0
  32. package/src/dex/pancakeswap-v3/config.ts +19 -0
  33. package/src/dex/pancakeswap-v3/pancakeswap-v3-e2e.test.ts +120 -0
  34. package/src/dex/solidly/config.ts +14 -0
  35. package/src/dex/solidly/forks-override/aerodrome.ts +57 -0
  36. package/src/dex/solidly/solidly-e2e.test.ts +24 -0
  37. package/src/dex/solidly/solidly.ts +1 -0
  38. package/src/dex/uniswap-v3/config.ts +13 -0
  39. package/src/dex/uniswap-v3/uniswap-v3-e2e.test.ts +25 -4
  40. package/src/dex/uniswap-v3/uniswap-v3-integration.test.ts +142 -0
  41. package/src/dex/woo-fi-v2/config.ts +13 -0
  42. package/src/dex/woo-fi-v2/woo-fi-v2-e2e.test.ts +64 -0
  43. package/tests/constants-e2e.ts +30 -0
  44. package/tests/utils-e2e.ts +1 -0
@@ -2,7 +2,7 @@ import dotenv from 'dotenv';
2
2
  dotenv.config();
3
3
 
4
4
  import { testE2E } from '../../../tests/utils-e2e';
5
- import { Holders, Tokens } from '../../../tests/constants-e2e';
5
+ import { Holders, NativeTokenSymbols, Tokens } from '../../../tests/constants-e2e';
6
6
  import { ContractMethod, Network, SwapSide } from '../../constants';
7
7
  import { StaticJsonRpcProvider } from '@ethersproject/providers';
8
8
 
@@ -10,6 +10,105 @@ import { generateConfig } from '../../config';
10
10
 
11
11
  jest.setTimeout(50 * 1000);
12
12
 
13
+ function testForNetwork(
14
+ network: Network,
15
+ dexKey: string,
16
+ tokenASymbol: string,
17
+ tokenBSymbol: string,
18
+ tokenAAmount: string,
19
+ tokenBAmount: string,
20
+ nativeTokenAmount: string,
21
+ slippage?: number | undefined,
22
+ ) {
23
+ const provider = new StaticJsonRpcProvider(
24
+ generateConfig(network).privateHttpProvider,
25
+ network,
26
+ );
27
+ const tokens = Tokens[network];
28
+ const holders = Holders[network];
29
+ const nativeTokenSymbol = NativeTokenSymbols[network];
30
+
31
+ const sideToContractMethods = new Map([
32
+ [
33
+ SwapSide.SELL,
34
+ [
35
+ ContractMethod.simpleSwap,
36
+ ContractMethod.multiSwap,
37
+ ContractMethod.megaSwap,
38
+ ],
39
+ ],
40
+ [
41
+ SwapSide.BUY,
42
+ [
43
+ ContractMethod.simpleBuy,
44
+ ContractMethod.buy,
45
+ ],
46
+ ],
47
+ ]);
48
+
49
+ describe(`${network}`, () => {
50
+ sideToContractMethods.forEach((contractMethods, side) =>
51
+ describe(`${side}`, () => {
52
+ contractMethods.forEach((contractMethod: ContractMethod) => {
53
+ describe(`${contractMethod}`, () => {
54
+ it(`${nativeTokenSymbol} -> ${tokenASymbol}`, async () => {
55
+ await testE2E(
56
+ tokens[nativeTokenSymbol],
57
+ tokens[tokenASymbol],
58
+ holders[nativeTokenSymbol],
59
+ side === SwapSide.SELL ? nativeTokenAmount : tokenAAmount,
60
+ side,
61
+ dexKey,
62
+ contractMethod,
63
+ network,
64
+ provider,
65
+ undefined,
66
+ undefined,
67
+ undefined,
68
+ slippage,
69
+ );
70
+ });
71
+ it(`${tokenASymbol} -> ${nativeTokenSymbol}`, async () => {
72
+ await testE2E(
73
+ tokens[tokenASymbol],
74
+ tokens[nativeTokenSymbol],
75
+ holders[tokenASymbol],
76
+ side === SwapSide.SELL ? tokenAAmount : nativeTokenAmount,
77
+ side,
78
+ dexKey,
79
+ contractMethod,
80
+ network,
81
+ provider,
82
+ undefined,
83
+ undefined,
84
+ undefined,
85
+ slippage,
86
+ );
87
+ });
88
+ it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => {
89
+ await testE2E(
90
+ tokens[tokenASymbol],
91
+ tokens[tokenBSymbol],
92
+ holders[tokenASymbol],
93
+ side === SwapSide.SELL ? tokenAAmount : tokenBAmount,
94
+ side,
95
+ dexKey,
96
+ contractMethod,
97
+ network,
98
+ provider,
99
+ undefined,
100
+ undefined,
101
+ undefined,
102
+ slippage,
103
+ );
104
+ });
105
+ });
106
+ });
107
+ }),
108
+ );
109
+ });
110
+ }
111
+
13
112
  describe('BalancerV2 E2E', () => {
14
113
  describe('BalancerV2 MAINNET', () => {
15
114
  const dexKey = 'BalancerV2';
@@ -1195,6 +1294,28 @@ describe('BalancerV2 E2E', () => {
1195
1294
  });
1196
1295
  });
1197
1296
 
1297
+ describe('BalancerV2 Base', () => {
1298
+ const dexKey = 'BalancerV2';
1299
+ const network = Network.BASE;
1300
+
1301
+ const tokenASymbol: string = 'USDC';
1302
+ const tokenBSymbol: string = 'GOLD';
1303
+
1304
+ const tokenAAmount: string = '11110010';
1305
+ const tokenBAmount: string = '210000000000000000000';
1306
+ const nativeTokenAmount = '1000000000000000000';
1307
+
1308
+ testForNetwork(
1309
+ network,
1310
+ dexKey,
1311
+ tokenASymbol,
1312
+ tokenBSymbol,
1313
+ tokenAAmount,
1314
+ tokenBAmount,
1315
+ nativeTokenAmount,
1316
+ );
1317
+ });
1318
+
1198
1319
  describe('BeetsFi OPTIMISM', () => {
1199
1320
  const dexKey = 'BeetsFi';
1200
1321
  const network = Network.OPTIMISM;
@@ -23,7 +23,12 @@ export const BalancerConfig: DexConfigMap<DexParams> = {
23
23
  subgraphURL:
24
24
  'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-avalanche-v2',
25
25
  vaultAddress: '0xBA12222222228d8Ba445958a75a0704d566BF2C8',
26
- }
26
+ },
27
+ [Network.BASE]: {
28
+ subgraphURL:
29
+ 'https://api.studio.thegraph.com/query/24660/balancer-base-v2/version/latest',
30
+ vaultAddress: '0xBA12222222228d8Ba445958a75a0704d566BF2C8',
31
+ },
27
32
  },
28
33
  BeetsFi: {
29
34
  [Network.FANTOM]: {
@@ -71,5 +76,9 @@ export const Adapters: Record<number, AdapterMappings> = {
71
76
  [Network.AVALANCHE]: {
72
77
  [SwapSide.SELL]: [{ name: 'AvalancheAdapter01', index: 8 }],
73
78
  [SwapSide.BUY]: [{ name: 'AvalancheBuyAdapter', index: 7 }],
79
+ },
80
+ [Network.BASE]: {
81
+ [SwapSide.SELL]: [{ name: 'BaseAdapter01', index: 4 }],
82
+ [SwapSide.BUY]: [{ name: 'BaseBuyAdapter', index: 3 }],
74
83
  }
75
84
  };
package/src/dex/index.ts CHANGED
@@ -47,6 +47,7 @@ import { Thena } from './solidly/forks-override/thena';
47
47
  import { Chronos } from './solidly/forks-override/chronos';
48
48
  import { Velodrome } from './solidly/forks-override/velodrome';
49
49
  import { VelodromeV2 } from './solidly/forks-override/velodromeV2';
50
+ import { Aerodrome } from './solidly/forks-override/aerodrome';
50
51
  import { SpiritSwapV2 } from './solidly/forks-override/spiritSwapV2';
51
52
  import { Synthetix } from './synthetix/synthetix';
52
53
  import { Cone } from './solidly/forks-override/cone';
@@ -134,6 +135,7 @@ const Dexes = [
134
135
  Chronos,
135
136
  Velodrome,
136
137
  VelodromeV2,
138
+ Aerodrome,
137
139
  Cone,
138
140
  SoliSnek,
139
141
  Equalizer,
@@ -14,6 +14,12 @@ export const MaverickV1Config: DexConfigMap<DexParams> = {
14
14
  routerAddress: '0x4a585e0f7c18e2c414221d6402652d5e0990e5f8',
15
15
  poolInspectorAddress: '0xaA5BF61a664109e959D69C38734d4EA7dF74e456',
16
16
  },
17
+ [Network.BASE]: {
18
+ subgraphURL:
19
+ 'https://api.studio.thegraph.com/query/42519/maverick-base/version/latest',
20
+ routerAddress: '0x32AED3Bce901DA12ca8489788F3A99fCe1056e14',
21
+ poolInspectorAddress: '0x65A3AD03Be97619284bA7AA1E3Ca05638B9d6364',
22
+ },
17
23
  },
18
24
  };
19
25
 
@@ -22,4 +28,8 @@ export const Adapters: Record<number, AdapterMappings> = {
22
28
  [SwapSide.SELL]: [{ name: 'Adapter04', index: 2 }],
23
29
  [SwapSide.BUY]: [{ name: 'BuyAdapter', index: 8 }],
24
30
  },
31
+ [Network.BASE]: {
32
+ [SwapSide.SELL]: [{ name: 'BaseAdapter01', index: 2 }],
33
+ [SwapSide.BUY]: [{ name: 'BaseBuyAdapter', index: 2 }],
34
+ },
25
35
  };
@@ -11,10 +11,109 @@ import { Network, ContractMethod, SwapSide } from '../../constants';
11
11
  import { StaticJsonRpcProvider } from '@ethersproject/providers';
12
12
  import { generateConfig } from '../../config';
13
13
 
14
+ function testForNetwork(
15
+ network: Network,
16
+ dexKey: string,
17
+ tokenASymbol: string,
18
+ tokenBSymbol: string,
19
+ tokenAAmount: string,
20
+ tokenBAmount: string,
21
+ nativeTokenAmount: string,
22
+ slippage?: number | undefined,
23
+ ) {
24
+ const provider = new StaticJsonRpcProvider(
25
+ generateConfig(network).privateHttpProvider,
26
+ network,
27
+ );
28
+ const tokens = Tokens[network];
29
+ const holders = Holders[network];
30
+ const nativeTokenSymbol = NativeTokenSymbols[network];
31
+
32
+ const sideToContractMethods = new Map([
33
+ [
34
+ SwapSide.SELL,
35
+ [
36
+ ContractMethod.simpleSwap,
37
+ ContractMethod.multiSwap,
38
+ ContractMethod.megaSwap,
39
+ ],
40
+ ],
41
+ [
42
+ SwapSide.BUY,
43
+ [
44
+ ContractMethod.simpleBuy,
45
+ ContractMethod.buy,
46
+ ],
47
+ ],
48
+ ]);
49
+
50
+ describe(`${network}`, () => {
51
+ sideToContractMethods.forEach((contractMethods, side) =>
52
+ describe(`${side}`, () => {
53
+ contractMethods.forEach((contractMethod: ContractMethod) => {
54
+ describe(`${contractMethod}`, () => {
55
+ it(`${nativeTokenSymbol} -> ${tokenASymbol}`, async () => {
56
+ await testE2E(
57
+ tokens[nativeTokenSymbol],
58
+ tokens[tokenASymbol],
59
+ holders[nativeTokenSymbol],
60
+ side === SwapSide.SELL ? nativeTokenAmount : tokenAAmount,
61
+ side,
62
+ dexKey,
63
+ contractMethod,
64
+ network,
65
+ provider,
66
+ undefined,
67
+ undefined,
68
+ undefined,
69
+ slippage,
70
+ );
71
+ });
72
+ it(`${tokenASymbol} -> ${nativeTokenSymbol}`, async () => {
73
+ await testE2E(
74
+ tokens[tokenASymbol],
75
+ tokens[nativeTokenSymbol],
76
+ holders[tokenASymbol],
77
+ side === SwapSide.SELL ? tokenAAmount : nativeTokenAmount,
78
+ side,
79
+ dexKey,
80
+ contractMethod,
81
+ network,
82
+ provider,
83
+ undefined,
84
+ undefined,
85
+ undefined,
86
+ slippage,
87
+ );
88
+ });
89
+ it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => {
90
+ await testE2E(
91
+ tokens[tokenASymbol],
92
+ tokens[tokenBSymbol],
93
+ holders[tokenASymbol],
94
+ side === SwapSide.SELL ? tokenAAmount : tokenBAmount,
95
+ side,
96
+ dexKey,
97
+ contractMethod,
98
+ network,
99
+ provider,
100
+ undefined,
101
+ undefined,
102
+ undefined,
103
+ slippage,
104
+ );
105
+ });
106
+ });
107
+ });
108
+ }),
109
+ );
110
+ });
111
+ }
112
+
14
113
  describe('MaverickV1 E2E', () => {
15
114
  const dexKey = 'MaverickV1';
16
115
 
17
- describe('MaverickV1 MAINNET', () => {
116
+ describe('MAINNET', () => {
18
117
  const network = Network.MAINNET;
19
118
  const tokens = Tokens[network];
20
119
  const holders = Holders[network];
@@ -121,4 +220,25 @@ describe('MaverickV1 E2E', () => {
121
220
  );
122
221
  });
123
222
  });
223
+
224
+ describe('BASE', () => {
225
+ const network = Network.BASE;
226
+
227
+ const tokenASymbol: string = 'USDbC';
228
+ const tokenBSymbol: string = 'MAV';
229
+
230
+ const tokenAAmount: string = '1111100000';
231
+ const tokenBAmount: string = '1100000000000000000';
232
+ const nativeTokenAmount = '100000000000000000';
233
+
234
+ testForNetwork(
235
+ network,
236
+ dexKey,
237
+ tokenASymbol,
238
+ tokenBSymbol,
239
+ tokenAAmount,
240
+ tokenBAmount,
241
+ nativeTokenAmount,
242
+ );
243
+ });
124
244
  });
@@ -78,6 +78,7 @@ export class MaverickV1
78
78
 
79
79
  async setupEventPools(blockNumber: number) {
80
80
  const pools = await this.fetchAllSubgraphPools();
81
+
81
82
  await Promise.all(
82
83
  pools.map(async (pool: any) => {
83
84
  const eventPool = new MaverickV1EventPool(
@@ -53,6 +53,21 @@ export const PancakeswapV3Config: DexConfigMap<DexParams> = {
53
53
  subgraphURL:
54
54
  'https://api.studio.thegraph.com/query/45376/exchange-v3-arbitrum/version/latest',
55
55
  },
56
+ [Network.BASE]: {
57
+ factory: '0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865',
58
+ deployer: '0x41ff9AA7e16B8B1a8a8dc4f0eFacd93D02d071c9',
59
+ quoter: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997',
60
+ router: '0x1b81D678ffb9C0263b24A97847620C99d213eB14',
61
+ supportedFees: PANCAKE_SUPPORTED_FEES,
62
+ stateMulticall: '0xeBF40A40CA3D4310Bf53048F48e860656e1D7C81',
63
+ uniswapMulticall: '0x091e99cb1C49331a94dD62755D168E941AbD0693',
64
+ chunksCount: 10,
65
+ initRetryFrequency: 30,
66
+ initHash:
67
+ '0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2',
68
+ subgraphURL:
69
+ 'https://api.studio.thegraph.com/query/45376/exchange-v3-base/version/latest',
70
+ },
56
71
  },
57
72
  };
58
73
 
@@ -69,4 +84,8 @@ export const Adapters: Record<number, AdapterMappings> = {
69
84
  [SwapSide.SELL]: [{ name: 'ArbitrumAdapter01', index: 3 }],
70
85
  [SwapSide.BUY]: [{ name: 'ArbitrumBuyAdapter', index: 2 }],
71
86
  },
87
+ [Network.BASE]: {
88
+ [SwapSide.SELL]: [{ name: 'BaseAdapter01', index: 1 }],
89
+ [SwapSide.BUY]: [{ name: 'BaseBuyAdapter', index: 1 }],
90
+ },
72
91
  };
@@ -11,6 +11,105 @@ import { Network, ContractMethod, SwapSide } from '../../constants';
11
11
  import { StaticJsonRpcProvider } from '@ethersproject/providers';
12
12
  import { generateConfig } from '../../config';
13
13
 
14
+ function testForNetwork(
15
+ network: Network,
16
+ dexKey: string,
17
+ tokenASymbol: string,
18
+ tokenBSymbol: string,
19
+ tokenAAmount: string,
20
+ tokenBAmount: string,
21
+ nativeTokenAmount: string,
22
+ slippage?: number | undefined,
23
+ ) {
24
+ const provider = new StaticJsonRpcProvider(
25
+ generateConfig(network).privateHttpProvider,
26
+ network,
27
+ );
28
+ const tokens = Tokens[network];
29
+ const holders = Holders[network];
30
+ const nativeTokenSymbol = NativeTokenSymbols[network];
31
+
32
+ const sideToContractMethods = new Map([
33
+ [
34
+ SwapSide.SELL,
35
+ [
36
+ ContractMethod.simpleSwap,
37
+ ContractMethod.multiSwap,
38
+ ContractMethod.megaSwap,
39
+ ],
40
+ ],
41
+ [
42
+ SwapSide.BUY,
43
+ [
44
+ ContractMethod.simpleBuy,
45
+ ContractMethod.buy,
46
+ ],
47
+ ],
48
+ ]);
49
+
50
+ describe(`${network}`, () => {
51
+ sideToContractMethods.forEach((contractMethods, side) =>
52
+ describe(`${side}`, () => {
53
+ contractMethods.forEach((contractMethod: ContractMethod) => {
54
+ describe(`${contractMethod}`, () => {
55
+ it(`${nativeTokenSymbol} -> ${tokenASymbol}`, async () => {
56
+ await testE2E(
57
+ tokens[nativeTokenSymbol],
58
+ tokens[tokenASymbol],
59
+ holders[nativeTokenSymbol],
60
+ side === SwapSide.SELL ? nativeTokenAmount : tokenAAmount,
61
+ side,
62
+ dexKey,
63
+ contractMethod,
64
+ network,
65
+ provider,
66
+ undefined,
67
+ undefined,
68
+ undefined,
69
+ slippage,
70
+ );
71
+ });
72
+ it(`${tokenASymbol} -> ${nativeTokenSymbol}`, async () => {
73
+ await testE2E(
74
+ tokens[tokenASymbol],
75
+ tokens[nativeTokenSymbol],
76
+ holders[tokenASymbol],
77
+ side === SwapSide.SELL ? tokenAAmount : nativeTokenAmount,
78
+ side,
79
+ dexKey,
80
+ contractMethod,
81
+ network,
82
+ provider,
83
+ undefined,
84
+ undefined,
85
+ undefined,
86
+ slippage,
87
+ );
88
+ });
89
+ it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => {
90
+ await testE2E(
91
+ tokens[tokenASymbol],
92
+ tokens[tokenBSymbol],
93
+ holders[tokenASymbol],
94
+ side === SwapSide.SELL ? tokenAAmount : tokenBAmount,
95
+ side,
96
+ dexKey,
97
+ contractMethod,
98
+ network,
99
+ provider,
100
+ undefined,
101
+ undefined,
102
+ undefined,
103
+ slippage,
104
+ );
105
+ });
106
+ });
107
+ });
108
+ }),
109
+ );
110
+ });
111
+ }
112
+
14
113
  describe('PancakeswapV3 E2E', () => {
15
114
  const dexKey = 'PancakeswapV3';
16
115
 
@@ -307,4 +406,25 @@ describe('PancakeswapV3 E2E', () => {
307
406
  }),
308
407
  );
309
408
  });
409
+
410
+ describe('PancakeswapV3 Base', () => {
411
+ const network = Network.BASE;
412
+
413
+ const tokenASymbol: string = 'USDbC';
414
+ const tokenBSymbol: string = 'DAI';
415
+
416
+ const tokenAAmount: string = '11111000000';
417
+ const tokenBAmount: string = '210000000000000000';
418
+ const nativeTokenAmount = '110000000000000000000';
419
+
420
+ testForNetwork(
421
+ network,
422
+ dexKey,
423
+ tokenASymbol,
424
+ tokenBSymbol,
425
+ tokenAAmount,
426
+ tokenBAmount,
427
+ nativeTokenAmount,
428
+ );
429
+ });
310
430
  });
@@ -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',
@@ -182,4 +193,7 @@ export const Adapters: Record<number, AdapterMappings> = {
182
193
  [Network.ARBITRUM]: {
183
194
  [SwapSide.SELL]: [{ name: 'ArbitrumAdapter02', index: 1 }], // chronos, ramses
184
195
  },
196
+ [Network.BASE]: {
197
+ [SwapSide.SELL]: [{ name: 'BaseAdapter01', index: 3 }], // aerodrome
198
+ }
185
199
  };
@@ -0,0 +1,57 @@
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 { Address, 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(
20
+ network,
21
+ dexKey,
22
+ dexHelper,
23
+ );
24
+
25
+ this.factory = new dexHelper.web3Provider.eth.Contract(
26
+ AerodromeFactoryABI as any,
27
+ SolidlyConfig[dexKey][network].factoryAddress,
28
+ );
29
+ }
30
+
31
+ async findSolidlyPair(from: Token, to: Token, stable: boolean) {
32
+ if (from.address.toLowerCase() === to.address.toLowerCase()) return null;
33
+ const [token0, token1] =
34
+ from.address.toLowerCase() < to.address.toLowerCase()
35
+ ? [from, to]
36
+ : [to, from];
37
+
38
+ const typePostfix = this.poolPostfix(stable);
39
+ const key = `${token0.address.toLowerCase()}-${token1.address.toLowerCase()}-${typePostfix}`;
40
+ let pair = this.pairs[key];
41
+ if (pair) return pair;
42
+
43
+ let exchange = await this.factory.methods
44
+ // Solidly has additional boolean parameter "StablePool"
45
+ // At first we look for uniswap-like volatile pool
46
+ .getPool(token0.address, token1.address, stable)
47
+ .call();
48
+
49
+ if (exchange === NULL_ADDRESS) {
50
+ pair = { token0, token1, stable };
51
+ } else {
52
+ pair = { token0, token1, exchange, stable };
53
+ }
54
+ this.pairs[key] = pair;
55
+ return pair;
56
+ }
57
+ }
@@ -1404,4 +1404,28 @@ 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
+ });
1407
1431
  });
@@ -75,6 +75,7 @@ export class Solidly extends UniswapV2 {
75
75
  'Chronos',
76
76
  'Ramses',
77
77
  'Equalizer',
78
+ 'Aerodrome',
78
79
  ]),
79
80
  );
80
81
 
@@ -210,6 +210,19 @@ 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:
224
+ 'https://api.studio.thegraph.com/query/32073/v3-base/v0.0.1',
225
+ },
213
226
  },
214
227
  ChronosV3: {
215
228
  [Network.ARBITRUM]: {