@paraswap/dex-lib 2.34.0 → 2.35.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.
Files changed (69) hide show
  1. package/build/abi/api3-proxy.json +46 -0
  2. package/build/abi/api3-server-v1.json +463 -0
  3. package/build/abi/quick-perps/fast-price-events.json +70 -0
  4. package/build/abi/quick-perps/fast-price-feed.json +741 -0
  5. package/build/abi/quick-perps/reader.json +313 -0
  6. package/build/abi/quick-perps/vault-price-feed.json +323 -0
  7. package/build/abi/quick-perps/vault.json +1953 -0
  8. package/build/composed-event-subscriber.js +8 -2
  9. package/build/composed-event-subscriber.js.map +1 -1
  10. package/build/config.js +2 -2
  11. package/build/dex/index.js +2 -0
  12. package/build/dex/index.js.map +1 -1
  13. package/build/dex/quick-perps/config.d.ts +11 -0
  14. package/build/dex/quick-perps/config.js +27 -0
  15. package/build/dex/quick-perps/config.js.map +1 -0
  16. package/build/dex/quick-perps/fast-price-feed.d.ts +26 -0
  17. package/build/dex/quick-perps/fast-price-feed.js +176 -0
  18. package/build/dex/quick-perps/fast-price-feed.js.map +1 -0
  19. package/build/dex/quick-perps/pool.d.ts +21 -0
  20. package/build/dex/quick-perps/pool.js +210 -0
  21. package/build/dex/quick-perps/pool.js.map +1 -0
  22. package/build/dex/quick-perps/quick-perps.d.ts +52 -0
  23. package/build/dex/quick-perps/quick-perps.js +205 -0
  24. package/build/dex/quick-perps/quick-perps.js.map +1 -0
  25. package/build/dex/quick-perps/types.d.ts +98 -0
  26. package/build/dex/quick-perps/types.js +3 -0
  27. package/build/dex/quick-perps/types.js.map +1 -0
  28. package/build/dex/quick-perps/usdq.d.ts +15 -0
  29. package/build/dex/quick-perps/usdq.js +61 -0
  30. package/build/dex/quick-perps/usdq.js.map +1 -0
  31. package/build/dex/quick-perps/vault-price-feed.d.ts +43 -0
  32. package/build/dex/quick-perps/vault-price-feed.js +194 -0
  33. package/build/dex/quick-perps/vault-price-feed.js.map +1 -0
  34. package/build/dex/quick-perps/vault-utils.d.ts +8 -0
  35. package/build/dex/quick-perps/vault-utils.js +41 -0
  36. package/build/dex/quick-perps/vault-utils.js.map +1 -0
  37. package/build/dex/quick-perps/vault.d.ts +46 -0
  38. package/build/dex/quick-perps/vault.js +166 -0
  39. package/build/dex/quick-perps/vault.js.map +1 -0
  40. package/build/lib/api3-feed.d.ts +26 -0
  41. package/build/lib/api3-feed.js +82 -0
  42. package/build/lib/api3-feed.js.map +1 -0
  43. package/package.json +1 -1
  44. package/src/abi/api3-proxy.json +46 -0
  45. package/src/abi/api3-server-v1.json +463 -0
  46. package/src/abi/quick-perps/fast-price-events.json +70 -0
  47. package/src/abi/quick-perps/fast-price-feed.json +741 -0
  48. package/src/abi/quick-perps/reader.json +313 -0
  49. package/src/abi/quick-perps/vault-price-feed.json +323 -0
  50. package/src/abi/quick-perps/vault.json +1953 -0
  51. package/src/composed-event-subscriber.ts +16 -11
  52. package/src/config.ts +2 -2
  53. package/src/dex/index.ts +2 -0
  54. package/src/dex/quick-perps/config.ts +31 -0
  55. package/src/dex/quick-perps/fast-price-feed.ts +279 -0
  56. package/src/dex/quick-perps/pool.ts +372 -0
  57. package/src/dex/quick-perps/quick-perps-e2e.test.ts +65 -0
  58. package/src/dex/quick-perps/quick-perps-events.test.ts +101 -0
  59. package/src/dex/quick-perps/quick-perps-integration.test.ts +153 -0
  60. package/src/dex/quick-perps/quick-perps.ts +292 -0
  61. package/src/dex/quick-perps/types.ts +97 -0
  62. package/src/dex/quick-perps/usdq.ts +83 -0
  63. package/src/dex/quick-perps/vault-price-feed.ts +322 -0
  64. package/src/dex/quick-perps/vault-utils.ts +53 -0
  65. package/src/dex/quick-perps/vault.ts +290 -0
  66. package/src/lib/api3-feed.ts +140 -0
  67. package/tests/constants-e2e.ts +29 -0
  68. package/tests/tenderly-simulation.ts +46 -2
  69. package/tests/utils-e2e.ts +18 -10
@@ -0,0 +1,140 @@
1
+ import { DeepReadonly } from 'ts-essentials';
2
+ import { PartialEventSubscriber } from '../composed-event-subscriber';
3
+ import {
4
+ Address,
5
+ BlockHeader,
6
+ Log,
7
+ Logger,
8
+ MultiCallInput,
9
+ MultiCallOutput,
10
+ } from '../types';
11
+ import { Lens } from '../lens';
12
+ import { Interface } from '@ethersproject/abi';
13
+ import ProxyABI from '../abi/api3-proxy.json';
14
+ import Api3ServerV1ABI from '../abi/api3-server-v1.json';
15
+
16
+ export type Api3FeedSubscriberState = {
17
+ value: bigint;
18
+ timestamp: bigint;
19
+ };
20
+
21
+ export class Api3FeedSubscriber<State> extends PartialEventSubscriber<
22
+ State,
23
+ Api3FeedSubscriberState
24
+ > {
25
+ static readonly proxyInterface = new Interface(ProxyABI);
26
+ static readonly api3ServerV1Iface = new Interface(Api3ServerV1ABI);
27
+ static readonly ANSWER_UPDATED_SIGNED_DATA =
28
+ Api3FeedSubscriber.api3ServerV1Iface.getEventTopic(
29
+ 'UpdatedBeaconWithSignedData',
30
+ );
31
+ static readonly ANSWER_UPDATED_BEACON_SET_DATA =
32
+ Api3FeedSubscriber.api3ServerV1Iface.getEventTopic(
33
+ 'UpdatedBeaconSetWithBeacons',
34
+ );
35
+
36
+ constructor(
37
+ private proxy: Address,
38
+ api3Server: Address,
39
+ private dataFeedId: string,
40
+ lens: Lens<DeepReadonly<State>, DeepReadonly<Api3FeedSubscriberState>>,
41
+ logger: Logger,
42
+ ) {
43
+ super([api3Server], lens, logger);
44
+ }
45
+
46
+ static getApi3ServerV1MultiCallInput(proxy: Address): MultiCallInput {
47
+ return {
48
+ target: proxy,
49
+ callData:
50
+ Api3FeedSubscriber.proxyInterface.encodeFunctionData('api3ServerV1'),
51
+ };
52
+ }
53
+
54
+ static getDataFeedId(proxy: Address): MultiCallInput {
55
+ return {
56
+ target: proxy,
57
+ callData:
58
+ Api3FeedSubscriber.proxyInterface.encodeFunctionData('dataFeedId'),
59
+ };
60
+ }
61
+
62
+ static decodeDataFeedId(multicallOutput: MultiCallOutput) {
63
+ return Api3FeedSubscriber.proxyInterface.decodeFunctionResult(
64
+ 'dataFeedId',
65
+ multicallOutput,
66
+ )[0];
67
+ }
68
+
69
+ static decodeApi3ServerV1Result(multicallOutput: MultiCallOutput): Address {
70
+ return Api3FeedSubscriber.proxyInterface.decodeFunctionResult(
71
+ 'api3ServerV1',
72
+ multicallOutput,
73
+ )[0];
74
+ }
75
+
76
+ public processLog(
77
+ state: DeepReadonly<Api3FeedSubscriberState>,
78
+ log: Readonly<Log>,
79
+ blockHeader: Readonly<BlockHeader>,
80
+ ): DeepReadonly<Api3FeedSubscriberState> | null {
81
+ if (log.topics[0] === Api3FeedSubscriber.ANSWER_UPDATED_SIGNED_DATA) {
82
+ const decoded = Api3FeedSubscriber.api3ServerV1Iface.decodeEventLog(
83
+ 'UpdatedBeaconWithSignedData',
84
+ log.data,
85
+ log.topics,
86
+ );
87
+
88
+ if (decoded.beaconId !== this.dataFeedId) return null;
89
+
90
+ return {
91
+ value: BigInt(decoded.value.toString()),
92
+ timestamp: BigInt(decoded.timestamp.toString()),
93
+ };
94
+ } else if (
95
+ log.topics[0] === Api3FeedSubscriber.ANSWER_UPDATED_BEACON_SET_DATA
96
+ ) {
97
+ const decoded = Api3FeedSubscriber.api3ServerV1Iface.decodeEventLog(
98
+ 'UpdatedBeaconSetWithBeacons',
99
+ log.data,
100
+ log.topics,
101
+ );
102
+
103
+ if (decoded.beaconSetId !== this.dataFeedId) return null;
104
+
105
+ return {
106
+ value: BigInt(decoded.value.toString()),
107
+ timestamp: BigInt(decoded.timestamp.toString()),
108
+ };
109
+ } else {
110
+ return null;
111
+ }
112
+ }
113
+
114
+ public getGenerateStateMultiCallInputs(): MultiCallInput[] {
115
+ return [
116
+ {
117
+ target: this.proxy,
118
+ callData: Api3FeedSubscriber.proxyInterface.encodeFunctionData('read'),
119
+ },
120
+ ];
121
+ }
122
+
123
+ public generateState(
124
+ multicallOutputs: MultiCallOutput[],
125
+ blockNumber?: number | 'latest',
126
+ ): DeepReadonly<Api3FeedSubscriberState> {
127
+ const decoded = Api3FeedSubscriber.proxyInterface.decodeFunctionResult(
128
+ 'read',
129
+ multicallOutputs[0],
130
+ );
131
+ return {
132
+ value: BigInt(decoded.value.toString()),
133
+ timestamp: BigInt(decoded.timestamp.toString()),
134
+ };
135
+ }
136
+
137
+ public getLatestData(state: DeepReadonly<State>): bigint {
138
+ return this.lens.get()(state).value;
139
+ }
140
+ }
@@ -861,6 +861,28 @@ export const Tokens: {
861
861
  decimals: 8,
862
862
  },
863
863
  },
864
+ [Network.ZKEVM]: {
865
+ ETH: {
866
+ address: ETHER_ADDRESS,
867
+ decimals: 18,
868
+ },
869
+ WETH: {
870
+ address: '0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9',
871
+ decimals: 18,
872
+ },
873
+ MATIC: {
874
+ address: '0xa2036f0538221a77a3937f1379699f44945018d0',
875
+ decimals: 18,
876
+ },
877
+ WBTC: {
878
+ address: '0xea034fb02eb1808c2cc3adbc15f447b93cbe08e1',
879
+ decimals: 8,
880
+ },
881
+ USDC: {
882
+ address: '0xa8ce8aee21bc2a48a5ef670afcc9274c7bbbc035',
883
+ decimals: 6,
884
+ },
885
+ },
864
886
  };
865
887
 
866
888
  export const Holders: {
@@ -1073,6 +1095,13 @@ export const Holders: {
1073
1095
  rETH: '0x4c2e69e58b14de9afedfb94319519ce34e087283',
1074
1096
  WBTC: '0xb9c8f0d3254007ee4b98970b94544e473cd610ec',
1075
1097
  },
1098
+ [Network.ZKEVM]: {
1099
+ ETH: '0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9',
1100
+ WETH: '0xc44ad482f24fd750caeba387d2726d8653f8c4bb',
1101
+ MATIC: '0x8f2a1450c040b3c19efe9676165d8f30d8280019',
1102
+ WBTC: '0x99b31498b0a1dae01fc3433e3cb60f095340935c',
1103
+ USDC: '0x99b31498b0a1dae01fc3433e3cb60f095340935c',
1104
+ },
1076
1105
  };
1077
1106
 
1078
1107
  export const SmartTokens = Object.keys(Tokens).reduce((acc, _network) => {
@@ -1,5 +1,7 @@
1
+ /* eslint-disable no-console */
1
2
  import axios from 'axios';
2
3
  import { Address } from '@paraswap/core';
4
+ import { Provider } from '@ethersproject/providers';
3
5
  import { TxObject } from '../src/types';
4
6
  import { StateOverrides, StateSimulateApiOverride } from './smart-tokens';
5
7
 
@@ -9,7 +11,50 @@ const TENDERLY_PROJECT = process.env.TENDERLY_PROJECT;
9
11
  const TENDERLY_FORK_ID = process.env.TENDERLY_FORK_ID;
10
12
  const TENDERLY_FORK_LAST_TX_ID = process.env.TENDERLY_FORK_LAST_TX_ID;
11
13
 
12
- export class TenderlySimulation {
14
+ export type SimulationResult = {
15
+ success: boolean;
16
+ gasUsed?: string;
17
+ url?: string;
18
+ transaction?: any;
19
+ };
20
+
21
+ export interface TransactionSimulator {
22
+ forkId: string;
23
+ setup(): Promise<void>;
24
+
25
+ simulate(
26
+ params: TxObject,
27
+ stateOverrides?: StateOverrides,
28
+ ): Promise<SimulationResult>;
29
+ }
30
+
31
+ export class EstimateGasSimulation implements TransactionSimulator {
32
+ forkId: string = '0';
33
+
34
+ constructor(private provider: Provider) {}
35
+
36
+ async setup() {}
37
+
38
+ async simulate(
39
+ params: TxObject,
40
+ _: StateOverrides,
41
+ ): Promise<SimulationResult> {
42
+ try {
43
+ const result = await this.provider.estimateGas(params);
44
+ return {
45
+ success: true,
46
+ gasUsed: result.toNumber().toString(),
47
+ };
48
+ } catch (e) {
49
+ console.error(`Estimate gas simulation failed:`, e);
50
+ return {
51
+ success: false,
52
+ };
53
+ }
54
+ }
55
+ }
56
+
57
+ export class TenderlySimulation implements TransactionSimulator {
13
58
  lastTx: string = '';
14
59
  forkId: string = '';
15
60
  maxGasLimit = 80000000;
@@ -118,7 +163,6 @@ export class TenderlySimulation {
118
163
  console.error(`TenderlySimulation_simulate:`, e);
119
164
  return {
120
165
  success: false,
121
- tenderlyUrl: '',
122
166
  };
123
167
  }
124
168
  }
@@ -5,7 +5,11 @@ import {
5
5
  IParaSwapSDK,
6
6
  LocalParaswapSDK,
7
7
  } from '../src/implementations/local-paraswap-sdk';
8
- import { TenderlySimulation } from './tenderly-simulation';
8
+ import {
9
+ EstimateGasSimulation,
10
+ TenderlySimulation,
11
+ TransactionSimulator,
12
+ } from './tenderly-simulation';
9
13
  import {
10
14
  SwapSide,
11
15
  ETHER_ADDRESS,
@@ -24,7 +28,7 @@ import {
24
28
  import Erc20ABI from '../src/abi/erc20.json';
25
29
  import AugustusABI from '../src/abi/augustus.json';
26
30
  import { generateConfig } from '../src/config';
27
- import { DummyLimitOrderProvider } from '../src/dex-helper';
31
+ import { DummyDexHelper, DummyLimitOrderProvider } from '../src/dex-helper';
28
32
  import { constructSimpleSDK, SimpleFetchSDK } from '@paraswap/sdk';
29
33
  import axios from 'axios';
30
34
  import { SmartToken, StateOverrides } from './smart-tokens';
@@ -268,16 +272,20 @@ export async function testE2E(
268
272
  // Specified in BPS: part of 10000
269
273
  slippage?: number,
270
274
  sleepMs?: number,
275
+ replaceTenderlyWithEstimateGas?: boolean,
271
276
  ) {
272
277
  const amount = BigInt(_amount);
273
- const ts = new TenderlySimulation(network);
278
+
279
+ const ts: TransactionSimulator = replaceTenderlyWithEstimateGas
280
+ ? new EstimateGasSimulation(new DummyDexHelper(network).provider)
281
+ : new TenderlySimulation(network);
274
282
  await ts.setup();
275
283
 
276
284
  if (srcToken.address.toLowerCase() !== ETHER_ADDRESS.toLowerCase()) {
277
285
  const allowanceTx = await ts.simulate(
278
286
  allowTokenTransferProxyParams(srcToken.address, senderAddress, network),
279
287
  );
280
- if (!allowanceTx.success) console.log(allowanceTx.tenderlyUrl);
288
+ if (!allowanceTx.success) console.log(allowanceTx.url);
281
289
  expect(allowanceTx!.success).toEqual(true);
282
290
  }
283
291
 
@@ -309,7 +317,7 @@ export async function testE2E(
309
317
  expect(deployTx.success).toEqual(true);
310
318
 
311
319
  const contractAddress =
312
- deployTx.transaction.transaction_info.contract_address;
320
+ deployTx.transaction?.transaction_info.contract_address;
313
321
  console.log(
314
322
  formatDeployMessage(
315
323
  'adapter',
@@ -384,15 +392,15 @@ export async function testE2E(
384
392
 
385
393
  const swapTx = await ts.simulate(swapParams);
386
394
  // Only log gas estimate if testing against API
387
- if (useAPI)
395
+ if (useAPI) {
396
+ const gasUsed = swapTx.gasUsed || '0';
388
397
  console.log(
389
398
  `Gas Estimate API: ${priceRoute.gasCost}, Simulated: ${
390
399
  swapTx!.gasUsed
391
- }, Difference: ${
392
- parseInt(priceRoute.gasCost) - parseInt(swapTx!.gasUsed)
393
- }`,
400
+ }, Difference: ${parseInt(priceRoute.gasCost) - parseInt(gasUsed)}`,
394
401
  );
395
- console.log(`Tenderly URL: ${swapTx!.tenderlyUrl}`);
402
+ }
403
+ console.log(`Tenderly URL: ${swapTx!.url}`);
396
404
  expect(swapTx!.success).toEqual(true);
397
405
  } finally {
398
406
  if (paraswap.releaseResources) {