@paraswap/dex-lib 4.8.34 → 4.8.35

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 (45) hide show
  1. package/build/abi/pancakeswap-infinity/cl-pool-manager.json +80 -0
  2. package/build/dex/fluid-dex/fluid-dex.js.map +1 -1
  3. package/build/dex/pancakeswap-infinity/config.d.ts +3 -0
  4. package/build/dex/pancakeswap-infinity/config.js +14 -0
  5. package/build/dex/pancakeswap-infinity/config.js.map +1 -0
  6. package/build/dex/pancakeswap-infinity/encoder.d.ts +4 -0
  7. package/build/dex/pancakeswap-infinity/encoder.js +205 -0
  8. package/build/dex/pancakeswap-infinity/encoder.js.map +1 -0
  9. package/build/dex/pancakeswap-infinity/pancakeswap-infinity.d.ts +21 -0
  10. package/build/dex/pancakeswap-infinity/pancakeswap-infinity.js +102 -0
  11. package/build/dex/pancakeswap-infinity/pancakeswap-infinity.js.map +1 -0
  12. package/build/dex/pancakeswap-infinity/subgraph.d.ts +7 -0
  13. package/build/dex/pancakeswap-infinity/subgraph.js +64 -0
  14. package/build/dex/pancakeswap-infinity/subgraph.js.map +1 -0
  15. package/build/dex/pancakeswap-infinity/types.d.ts +31 -0
  16. package/build/dex/pancakeswap-infinity/types.js +3 -0
  17. package/build/dex/pancakeswap-infinity/types.js.map +1 -0
  18. package/build/dex/pancakeswap-v3/scripts/measure-calc-time.d.ts +1 -0
  19. package/build/dex/pancakeswap-v3/scripts/measure-calc-time.js +203 -0
  20. package/build/dex/pancakeswap-v3/scripts/measure-calc-time.js.map +1 -0
  21. package/build/dex/solidly-v3/contract-math/native-bridge.d.ts +26 -0
  22. package/build/dex/solidly-v3/contract-math/native-bridge.js +96 -0
  23. package/build/dex/solidly-v3/contract-math/native-bridge.js.map +1 -0
  24. package/build/dex/solidly-v3/scripts/measure-calc-time.d.ts +1 -0
  25. package/build/dex/solidly-v3/scripts/measure-calc-time.js +203 -0
  26. package/build/dex/solidly-v3/scripts/measure-calc-time.js.map +1 -0
  27. package/build/dex/uniswap-v3/contract-math/native-bridge.d.ts +52 -1
  28. package/build/dex/uniswap-v3/contract-math/native-bridge.js +27 -3
  29. package/build/dex/uniswap-v3/contract-math/native-bridge.js.map +1 -1
  30. package/build/dex/uniswap-v3/scripts/bench-e2e.d.ts +1 -0
  31. package/build/dex/uniswap-v3/scripts/bench-e2e.js +85 -0
  32. package/build/dex/uniswap-v3/scripts/bench-e2e.js.map +1 -0
  33. package/build/dex/uniswap-v3/scripts/bench-parallel.d.ts +1 -0
  34. package/build/dex/uniswap-v3/scripts/bench-parallel.js +192 -0
  35. package/build/dex/uniswap-v3/scripts/bench-parallel.js.map +1 -0
  36. package/build/dex/uniswap-v4/contract-math/native-bridge.d.ts +40 -0
  37. package/build/dex/uniswap-v4/contract-math/native-bridge.js +74 -0
  38. package/build/dex/uniswap-v4/contract-math/native-bridge.js.map +1 -0
  39. package/build/dex/uniswap-v4/scripts/test-rust-correctness.d.ts +1 -0
  40. package/build/dex/uniswap-v4/scripts/test-rust-correctness.js +167 -0
  41. package/build/dex/uniswap-v4/scripts/test-rust-correctness.js.map +1 -0
  42. package/build/index.d.ts +1 -0
  43. package/build/index.js +3 -1
  44. package/build/index.js.map +1 -1
  45. package/package.json +2 -2
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queryAvailablePoolsForToken = queryAvailablePoolsForToken;
4
+ const SUBGRAPH_TIMEOUT = 30 * 1000;
5
+ const POOL_MIN_TVL_USD = 10_000;
6
+ async function queryAvailablePoolsForToken(dexHelper, logger, dexKey, subgraphUrl, tokenAddress, limit) {
7
+ const poolsQuery = `query ($token: Bytes!, $count: Int, $minTVL: Int!) {
8
+ pools0: pools(
9
+ where: {
10
+ token0: $token
11
+ liquidity_gt: 0
12
+ totalValueLockedUSD_gte: $minTVL
13
+ }
14
+ orderBy: totalValueLockedUSD
15
+ orderDirection: desc
16
+ first: $count
17
+ ) {
18
+ id
19
+ totalValueLockedUSD
20
+ token0 {
21
+ address: id
22
+ decimals
23
+ }
24
+ token1 {
25
+ address: id
26
+ decimals
27
+ }
28
+ }
29
+ pools1: pools(
30
+ where: {
31
+ token1: $token
32
+ liquidity_gt: 0
33
+ totalValueLockedUSD_gte: $minTVL
34
+ }
35
+ orderBy: totalValueLockedUSD
36
+ orderDirection: desc
37
+ first: $count
38
+ ) {
39
+ id
40
+ totalValueLockedUSD
41
+ token0 {
42
+ address: id
43
+ decimals
44
+ }
45
+ token1 {
46
+ address: id
47
+ decimals
48
+ }
49
+ }
50
+ }`;
51
+ const res = await dexHelper.httpRequest.querySubgraph(subgraphUrl, {
52
+ query: poolsQuery,
53
+ variables: {
54
+ token: tokenAddress,
55
+ count: limit,
56
+ minTVL: POOL_MIN_TVL_USD,
57
+ },
58
+ }, { timeout: SUBGRAPH_TIMEOUT });
59
+ if (res.errors && res.errors.length) {
60
+ throw new Error(res.errors[0].message);
61
+ }
62
+ return res.data;
63
+ }
64
+ //# sourceMappingURL=subgraph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subgraph.js","sourceRoot":"","sources":["../../../src/dex/pancakeswap-infinity/subgraph.ts"],"names":[],"mappings":";;AAOA,kEAgFC;AAnFD,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC;AACnC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEzB,KAAK,UAAU,2BAA2B,CAC/C,SAAqB,EACrB,MAAc,EACd,MAAc,EACd,WAAmB,EACnB,YAAoB,EACpB,KAAa;IAKb,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2CjB,CAAC;IAEH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,aAAa,CAOnD,WAAW,EACX;QACE,KAAK,EAAE,UAAU;QACjB,SAAS,EAAE;YACT,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,gBAAgB;SACzB;KACF,EACD,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAC9B,CAAC;IAEF,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { Address } from '../../types';
2
+ export type DexParams = {
3
+ clPoolManager: Address;
4
+ router: Address;
5
+ subgraphURL: string;
6
+ };
7
+ export type SubgraphConnectorPool = {
8
+ id: string;
9
+ totalValueLockedUSD: string;
10
+ token0: {
11
+ address: string;
12
+ decimals: string;
13
+ };
14
+ token1: {
15
+ address: string;
16
+ decimals: string;
17
+ };
18
+ };
19
+ export type PoolKey = {
20
+ currency0: string;
21
+ currency1: string;
22
+ hooks: string;
23
+ poolManager: string;
24
+ fee: number;
25
+ parameters: string;
26
+ };
27
+ export type PancakeSwapInfinityData = {
28
+ poolKey: PoolKey;
29
+ zeroForOne: boolean;
30
+ hookData?: string;
31
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/dex/pancakeswap-infinity/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ /*
37
+ * Benchmark: PancakeSwap V3 queryOutputs — JS vs Rust native addon.
38
+ * Verifies correctness and measures per-pool performance.
39
+ */
40
+ const dotenv = __importStar(require("dotenv"));
41
+ dotenv.config();
42
+ const log4js_1 = require("../../../lib/log4js");
43
+ const constants_1 = require("../../../constants");
44
+ const dex_helper_1 = require("../../../dex-helper");
45
+ const pancakeswap_v3_math_1 = require("../contract-math/pancakeswap-v3-math");
46
+ const pancakeswap_v3_1 = require("../pancakeswap-v3");
47
+ const perf_hooks_1 = require("perf_hooks");
48
+ const native_bridge_1 = require("../../uniswap-v3/contract-math/native-bridge");
49
+ const utils_1 = require("../../../utils");
50
+ const logger = (0, log4js_1.getLogger)('PancakeSwapV3Benchmark');
51
+ const runsNumber = 1000;
52
+ const network = constants_1.Network.MAINNET;
53
+ const dexHelper = new dex_helper_1.DummyDexHelper(network);
54
+ const dex = new pancakeswap_v3_1.PancakeswapV3(network, 'PancakeswapV3', dexHelper);
55
+ const side = constants_1.SwapSide.SELL;
56
+ const pairs = [
57
+ {
58
+ name: 'USDC/WETH',
59
+ src: {
60
+ address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
61
+ decimals: 6,
62
+ },
63
+ dest: {
64
+ address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
65
+ decimals: 18,
66
+ },
67
+ },
68
+ {
69
+ name: 'WETH/USDT',
70
+ src: {
71
+ address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
72
+ decimals: 18,
73
+ },
74
+ dest: {
75
+ address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
76
+ decimals: 6,
77
+ },
78
+ },
79
+ {
80
+ name: 'WBTC/WETH',
81
+ src: {
82
+ address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
83
+ decimals: 8,
84
+ },
85
+ dest: {
86
+ address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
87
+ decimals: 18,
88
+ },
89
+ },
90
+ ];
91
+ function generateAmounts(decimals) {
92
+ const unit = (0, utils_1.getBigIntPow)(decimals);
93
+ const amounts = [0n];
94
+ for (let i = 1; i <= 50; i++)
95
+ amounts.push(unit * BigInt(i * 100));
96
+ amounts.push(unit * 100000n, unit * 1000000n, unit * 10000000n);
97
+ return amounts;
98
+ }
99
+ const sortTokens = (a, b) => [a, b].sort((x, y) => (x < y ? -1 : 1));
100
+ function printStats(measures, label) {
101
+ const sorted = [...measures].sort((a, b) => a - b);
102
+ const avg = sorted.reduce((a, b) => a + b) / sorted.length;
103
+ const p50 = sorted[Math.floor(sorted.length * 0.5)];
104
+ const p95 = sorted[Math.floor(sorted.length * 0.95)];
105
+ const p99 = sorted[Math.floor(sorted.length * 0.99)];
106
+ const max = sorted[sorted.length - 1];
107
+ logger.info(` [${label}] avg=${avg.toFixed(3)}ms | p50=${p50.toFixed(3)}ms | ` +
108
+ `p95=${p95.toFixed(3)}ms | p99=${p99.toFixed(3)}ms | max=${max.toFixed(3)}ms`);
109
+ }
110
+ async function benchmarkPair(pair, blockNumber) {
111
+ const { name, src, dest } = pair;
112
+ const amounts = generateAmounts(src.decimals);
113
+ const [token0] = sortTokens(src.address.toLowerCase(), dest.address.toLowerCase());
114
+ const zeroForOne = token0 === src.address.toLowerCase();
115
+ logger.info(`\n${'='.repeat(60)}`);
116
+ logger.info(`PAIR: ${name} (${amounts.length} amounts, ${runsNumber} runs)`);
117
+ logger.info(`${'='.repeat(60)}\n`);
118
+ await dex.getPricesVolume(src, dest, amounts, side, blockNumber);
119
+ const poolEntries = Object.entries(dex.eventPools)
120
+ .filter(([key]) => {
121
+ const [s0, s1] = sortTokens(src.address.toLowerCase(), dest.address.toLowerCase());
122
+ return key.includes(s0) && key.includes(s1);
123
+ })
124
+ .filter(([, ep]) => ep != null)
125
+ .map(([key, ep]) => ({
126
+ key: key.split('_').pop(),
127
+ pool: ep,
128
+ state: ep.getState(blockNumber),
129
+ }))
130
+ .filter(p => p.state !== null);
131
+ if (!poolEntries.length) {
132
+ logger.warn(` No pools found for ${name}`);
133
+ return;
134
+ }
135
+ logger.info(` Pools: ${poolEntries.map(p => `fee=${p.key}`).join(', ')}\n`);
136
+ for (const p of poolEntries) {
137
+ const ticks = Object.keys(p.state.ticks).length;
138
+ logger.info(` fee=${p.key}: ${ticks} ticks, liquidity=${p.state.liquidity}`);
139
+ }
140
+ logger.info('');
141
+ logger.info(' --- JS ---');
142
+ for (const pool of poolEntries) {
143
+ const measures = [];
144
+ for (let i = 0; i < runsNumber; i++) {
145
+ const start = perf_hooks_1.performance.now();
146
+ pancakeswap_v3_math_1.pancakeswapV3Math.queryOutputs(pool.state, amounts, zeroForOne, side);
147
+ measures.push(perf_hooks_1.performance.now() - start);
148
+ }
149
+ printStats(measures, `JS fee=${pool.key}`);
150
+ }
151
+ if (native_bridge_1.nativeAddonAvailable) {
152
+ logger.info(' --- Rust ---');
153
+ for (const pool of poolEntries) {
154
+ const handle = (0, native_bridge_1.createRustHandle)(pool.state, 'pancakeswap_v3');
155
+ if (!handle) {
156
+ logger.warn(` Failed to create Rust handle for fee=${pool.key}`);
157
+ continue;
158
+ }
159
+ const measures = [];
160
+ for (let i = 0; i < runsNumber; i++) {
161
+ const start = perf_hooks_1.performance.now();
162
+ handle.queryOutputs(amounts, zeroForOne, 0);
163
+ measures.push(perf_hooks_1.performance.now() - start);
164
+ }
165
+ printStats(measures, `Rust fee=${pool.key}`);
166
+ // Correctness
167
+ const jsResult = pancakeswap_v3_math_1.pancakeswapV3Math.queryOutputs(pool.state, amounts, zeroForOne, side);
168
+ const rustResult = handle.queryOutputs(amounts, zeroForOne, 0);
169
+ let mismatches = 0;
170
+ for (let k = 0; k < amounts.length; k++) {
171
+ if (jsResult.outputs[k] !== rustResult.outputs[k]) {
172
+ mismatches++;
173
+ if (mismatches <= 3) {
174
+ logger.error(` MISMATCH fee=${pool.key} amount[${k}]=${amounts[k]} ` +
175
+ `js=${jsResult.outputs[k]} rust=${rustResult.outputs[k]}`);
176
+ }
177
+ }
178
+ }
179
+ logger.info(mismatches === 0
180
+ ? ` fee=${pool.key}: all ${amounts.length} outputs match ✓`
181
+ : ` fee=${pool.key}: ${mismatches}/${amounts.length} MISMATCHES`);
182
+ }
183
+ }
184
+ else {
185
+ logger.info(' Rust addon not available');
186
+ }
187
+ }
188
+ (async function main() {
189
+ logger.info(`PancakeSwap V3 benchmark (${runsNumber} runs)\n`);
190
+ const blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
191
+ logger.info(`Block: ${blockNumber}`);
192
+ for (const pair of pairs) {
193
+ try {
194
+ await benchmarkPair(pair, blockNumber);
195
+ }
196
+ catch (e) {
197
+ logger.error(`Failed ${pair.name}:`, e);
198
+ }
199
+ }
200
+ logger.info('\nDone.');
201
+ process.exit(0);
202
+ })();
203
+ //# sourceMappingURL=measure-calc-time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measure-calc-time.js","sourceRoot":"","sources":["../../../../src/dex/pancakeswap-v3/scripts/measure-calc-time.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { DeepReadonly } from 'ts-essentials';
2
+ import { PoolState } from '../types';
3
+ import { RustPoolRegistryType } from '../../uniswap-v3/contract-math/native-bridge';
4
+ export { RustPoolRegistryType };
5
+ export declare const nativeAddonAvailable: boolean;
6
+ export declare const useNativeMath: boolean;
7
+ export type RustPoolHandleType = {
8
+ queryOutputs(amounts: bigint[], zeroForOne: boolean, side: number): {
9
+ outputs: bigint[];
10
+ tickCounts: number[];
11
+ };
12
+ };
13
+ /**
14
+ * Create a RustPoolHandle from a Solidly V3 PoolState.
15
+ * Returns null if the native addon is not available.
16
+ */
17
+ export declare function createSolidlyRustHandle(state: DeepReadonly<PoolState>): RustPoolHandleType | null;
18
+ /**
19
+ * Create a RustPoolRegistry for batch parallel queries.
20
+ * Returns null if the native addon is not available.
21
+ */
22
+ export declare function createSolidlyRegistry(): RustPoolRegistryType | null;
23
+ /**
24
+ * Register a Solidly V3 pool in the registry using Solidly-specific state mapping.
25
+ */
26
+ export declare function solidlyRegistrySetPool(registry: RustPoolRegistryType, key: string, state: DeepReadonly<PoolState>): void;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useNativeMath = exports.nativeAddonAvailable = void 0;
4
+ exports.createSolidlyRustHandle = createSolidlyRustHandle;
5
+ exports.createSolidlyRegistry = createSolidlyRegistry;
6
+ exports.solidlyRegistrySetPool = solidlyRegistrySetPool;
7
+ // Try to load the native Rust addon
8
+ let nativeAddon = null;
9
+ try {
10
+ nativeAddon = require('../../../../native/index.js');
11
+ }
12
+ catch {
13
+ // Native addon not available — JS fallback will be used
14
+ }
15
+ exports.nativeAddonAvailable = nativeAddon !== null;
16
+ // Allow forcing JS backend via env var
17
+ exports.useNativeMath = exports.nativeAddonAvailable && process.env.PARASWAP_V3_MATH !== 'js';
18
+ /**
19
+ * Convert a Solidly V3 PoolState to the init format expected by the Rust addon.
20
+ * Solidly V3 differs from Uniswap V3:
21
+ * - fee is in slot0 (not a top-level field)
22
+ * - no feeProtocol in slot0
23
+ * - no oracle observations
24
+ */
25
+ function toRustInit(state) {
26
+ const tickBitmap = Object.entries(state.tickBitmap).map(([key, value]) => ({
27
+ key: Number(key),
28
+ value,
29
+ }));
30
+ const ticks = Object.entries(state.ticks).map(([key, info]) => ({
31
+ key: Number(key),
32
+ liquidityGross: info.liquidityGross,
33
+ liquidityNet: info.liquidityNet,
34
+ }));
35
+ return {
36
+ variant: 'solidly_v3',
37
+ bitmapRange: 12, // TICK_BITMAP_BUFFER(8) + TICK_BITMAP_TO_USE(4)
38
+ blockTimestamp: state.blockTimestamp,
39
+ tickSpacing: state.tickSpacing,
40
+ fee: state.slot0.fee,
41
+ sqrtPriceX96: state.slot0.sqrtPriceX96,
42
+ tick: state.slot0.tick,
43
+ observationIndex: 0,
44
+ observationCardinality: 0,
45
+ observationCardinalityNext: 0,
46
+ feeProtocol: 0n,
47
+ liquidity: state.liquidity,
48
+ maxLiquidityPerTick: state.maxLiquidityPerTick,
49
+ startTickBitmap: state.startTickBitmap,
50
+ lowestKnownTick: state.lowestKnownTick,
51
+ highestKnownTick: state.highestKnownTick,
52
+ tickBitmap,
53
+ ticks,
54
+ observations: [],
55
+ };
56
+ }
57
+ /**
58
+ * Create a RustPoolHandle from a Solidly V3 PoolState.
59
+ * Returns null if the native addon is not available.
60
+ */
61
+ function createSolidlyRustHandle(state) {
62
+ if (!exports.nativeAddonAvailable)
63
+ return null;
64
+ try {
65
+ return nativeAddon.RustPoolHandle.create(toRustInit(state));
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ /**
72
+ * Create a RustPoolRegistry for batch parallel queries.
73
+ * Returns null if the native addon is not available.
74
+ */
75
+ function createSolidlyRegistry() {
76
+ if (!exports.nativeAddonAvailable)
77
+ return null;
78
+ try {
79
+ return new nativeAddon.RustPoolRegistry();
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ }
85
+ /**
86
+ * Register a Solidly V3 pool in the registry using Solidly-specific state mapping.
87
+ */
88
+ function solidlyRegistrySetPool(registry, key, state) {
89
+ try {
90
+ registry.setPool(key, toRustInit(state));
91
+ }
92
+ catch {
93
+ // silently skip — pool will use JS fallback
94
+ }
95
+ }
96
+ //# sourceMappingURL=native-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-bridge.js","sourceRoot":"","sources":["../../../../src/dex/solidly-v3/contract-math/native-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ /*
37
+ * Benchmark: Solidly V3 queryOutputs — JS vs Rust native addon.
38
+ * Verifies correctness and measures per-pool performance.
39
+ */
40
+ const dotenv = __importStar(require("dotenv"));
41
+ dotenv.config();
42
+ const log4js_1 = require("../../../lib/log4js");
43
+ const constants_1 = require("../../../constants");
44
+ const dex_helper_1 = require("../../../dex-helper");
45
+ const uniswap_v3_math_1 = require("../contract-math/uniswap-v3-math");
46
+ const solidly_v3_1 = require("../solidly-v3");
47
+ const perf_hooks_1 = require("perf_hooks");
48
+ const native_bridge_1 = require("../contract-math/native-bridge");
49
+ const utils_1 = require("../../../utils");
50
+ const logger = (0, log4js_1.getLogger)('SolidlyV3Benchmark');
51
+ const runsNumber = 1000;
52
+ const network = constants_1.Network.MAINNET;
53
+ const dexHelper = new dex_helper_1.DummyDexHelper(network);
54
+ const dex = new solidly_v3_1.SolidlyV3(network, 'SolidlyV3', dexHelper);
55
+ const side = constants_1.SwapSide.SELL;
56
+ const pairs = [
57
+ {
58
+ name: 'USDC/WETH',
59
+ src: {
60
+ address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
61
+ decimals: 6,
62
+ },
63
+ dest: {
64
+ address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
65
+ decimals: 18,
66
+ },
67
+ },
68
+ {
69
+ name: 'USDC/USDT',
70
+ src: {
71
+ address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
72
+ decimals: 6,
73
+ },
74
+ dest: {
75
+ address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
76
+ decimals: 6,
77
+ },
78
+ },
79
+ {
80
+ name: 'WBTC/WETH',
81
+ src: {
82
+ address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
83
+ decimals: 8,
84
+ },
85
+ dest: {
86
+ address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
87
+ decimals: 18,
88
+ },
89
+ },
90
+ ];
91
+ function generateAmounts(decimals) {
92
+ const unit = (0, utils_1.getBigIntPow)(decimals);
93
+ const amounts = [0n];
94
+ for (let i = 1; i <= 50; i++)
95
+ amounts.push(unit * BigInt(i * 100));
96
+ amounts.push(unit * 100000n, unit * 1000000n, unit * 10000000n);
97
+ return amounts;
98
+ }
99
+ const sortTokens = (a, b) => [a, b].sort((x, y) => (x < y ? -1 : 1));
100
+ function printStats(measures, label) {
101
+ const sorted = [...measures].sort((a, b) => a - b);
102
+ const avg = sorted.reduce((a, b) => a + b) / sorted.length;
103
+ const p50 = sorted[Math.floor(sorted.length * 0.5)];
104
+ const p95 = sorted[Math.floor(sorted.length * 0.95)];
105
+ const p99 = sorted[Math.floor(sorted.length * 0.99)];
106
+ const max = sorted[sorted.length - 1];
107
+ logger.info(` [${label}] avg=${avg.toFixed(3)}ms | p50=${p50.toFixed(3)}ms | ` +
108
+ `p95=${p95.toFixed(3)}ms | p99=${p99.toFixed(3)}ms | max=${max.toFixed(3)}ms`);
109
+ }
110
+ async function benchmarkPair(pair, blockNumber) {
111
+ const { name, src, dest } = pair;
112
+ const amounts = generateAmounts(src.decimals);
113
+ const [token0] = sortTokens(src.address.toLowerCase(), dest.address.toLowerCase());
114
+ const zeroForOne = token0 === src.address.toLowerCase();
115
+ logger.info(`\n${'='.repeat(60)}`);
116
+ logger.info(`PAIR: ${name} (${amounts.length} amounts, ${runsNumber} runs)`);
117
+ logger.info(`${'='.repeat(60)}\n`);
118
+ await dex.getPricesVolume(src, dest, amounts, side, blockNumber);
119
+ const poolEntries = Object.entries(dex.eventPools)
120
+ .filter(([key]) => {
121
+ const [s0, s1] = sortTokens(src.address.toLowerCase(), dest.address.toLowerCase());
122
+ return key.includes(s0) && key.includes(s1);
123
+ })
124
+ .filter(([, ep]) => ep != null)
125
+ .map(([key, ep]) => ({
126
+ key: key.split('_').pop(),
127
+ pool: ep,
128
+ state: ep.getState(blockNumber),
129
+ }))
130
+ .filter(p => p.state !== null);
131
+ if (!poolEntries.length) {
132
+ logger.warn(` No pools found for ${name}`);
133
+ return;
134
+ }
135
+ logger.info(` Pools: ${poolEntries.map(p => `tickSpacing=${p.key}`).join(', ')}\n`);
136
+ for (const p of poolEntries) {
137
+ const ticks = Object.keys(p.state.ticks).length;
138
+ logger.info(` tickSpacing=${p.key}: ${ticks} ticks, fee=${p.state.slot0.fee}, liquidity=${p.state.liquidity}`);
139
+ }
140
+ logger.info('');
141
+ logger.info(' --- JS ---');
142
+ for (const pool of poolEntries) {
143
+ const measures = [];
144
+ for (let i = 0; i < runsNumber; i++) {
145
+ const start = perf_hooks_1.performance.now();
146
+ uniswap_v3_math_1.uniswapV3Math.queryOutputs(pool.state, amounts, zeroForOne, side);
147
+ measures.push(perf_hooks_1.performance.now() - start);
148
+ }
149
+ printStats(measures, `JS ts=${pool.key}`);
150
+ }
151
+ if (native_bridge_1.nativeAddonAvailable) {
152
+ logger.info(' --- Rust ---');
153
+ for (const pool of poolEntries) {
154
+ const handle = (0, native_bridge_1.createSolidlyRustHandle)(pool.state);
155
+ if (!handle) {
156
+ logger.warn(` Failed to create Rust handle for ts=${pool.key}`);
157
+ continue;
158
+ }
159
+ const measures = [];
160
+ for (let i = 0; i < runsNumber; i++) {
161
+ const start = perf_hooks_1.performance.now();
162
+ handle.queryOutputs(amounts, zeroForOne, 0);
163
+ measures.push(perf_hooks_1.performance.now() - start);
164
+ }
165
+ printStats(measures, `Rust ts=${pool.key}`);
166
+ // Correctness
167
+ const jsResult = uniswap_v3_math_1.uniswapV3Math.queryOutputs(pool.state, amounts, zeroForOne, side);
168
+ const rustResult = handle.queryOutputs(amounts, zeroForOne, 0);
169
+ let mismatches = 0;
170
+ for (let k = 0; k < amounts.length; k++) {
171
+ if (jsResult.outputs[k] !== rustResult.outputs[k]) {
172
+ mismatches++;
173
+ if (mismatches <= 3) {
174
+ logger.error(` MISMATCH ts=${pool.key} amount[${k}]=${amounts[k]} ` +
175
+ `js=${jsResult.outputs[k]} rust=${rustResult.outputs[k]}`);
176
+ }
177
+ }
178
+ }
179
+ logger.info(mismatches === 0
180
+ ? ` ts=${pool.key}: all ${amounts.length} outputs match ✓`
181
+ : ` ts=${pool.key}: ${mismatches}/${amounts.length} MISMATCHES`);
182
+ }
183
+ }
184
+ else {
185
+ logger.info(' Rust addon not available');
186
+ }
187
+ }
188
+ (async function main() {
189
+ logger.info(`Solidly V3 benchmark (${runsNumber} runs)\n`);
190
+ const blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
191
+ logger.info(`Block: ${blockNumber}`);
192
+ for (const pair of pairs) {
193
+ try {
194
+ await benchmarkPair(pair, blockNumber);
195
+ }
196
+ catch (e) {
197
+ logger.error(`Failed ${pair.name}:`, e);
198
+ }
199
+ }
200
+ logger.info('\nDone.');
201
+ process.exit(0);
202
+ })();
203
+ //# sourceMappingURL=measure-calc-time.js.map