Skip to content

Conversation

NikolasHaimerl
Copy link
Contributor

Fix WETH/ETH Symbol Resolution

Linear: ACX-4369

📝 Summary

This pull request addresses a bug where the swap/approval endpoint was incorrectly resolving the symbol for wrapped native tokens (like WETH) as the native token symbol (e.g., ETH). This was happening on chains like Base and Linea where the wrapped native token address is also present in the TOKEN_SYMBOLS_MAP under the ETH symbol.

🔧 Changes

  • Modified the getTokenByAddress function in api/_utils.ts to correctly resolve the token symbol in cases of ambiguity between ETH and WETH.
  • Added a comprehensive test suite for getTokenByAddress to ensure the correct symbol is returned for all supported chains.

💭 Rationale

The root cause of this issue lies in the @across-protocol/constants package, where some wrapped native token addresses are associated with both ETH and WETH symbols. The getTokenByAddress function was not deterministically picking the correct symbol, sometimes defaulting to ETH when it should have been WETH.

This pull request implements a solution that prioritises WETH when a token address is associated with both symbols. This is a robust solution because it correctly handles the ambiguity in the constants file and ensures that the correct token symbol is used throughout the application.

The alternative of fixing the constants file is not feasible as it is an external dependency. This solution provides a local fix that is both effective and maintainable.

Copy link

linear bot commented Oct 1, 2025

Copy link

vercel bot commented Oct 1, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
app-frontend-v3 Ready Ready Preview Comment Oct 3, 2025 1:02pm
sepolia-frontend-v3 Ready Ready Preview Comment Oct 3, 2025 1:02pm

});

test("should return WETH for Base and Linea", async () => {
const params = {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: I also didn't specify it in the ticket but what happens if you set the zero address as the inputToken? It seems that this also resolves to the wrong token information. But as above we can tackle this in a separate PR/issue

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. If the inputToken has a zero address, then neither ETH nor WETH will be found as a token, as neither of them specifies the zero address anywhere. I think that the native token aspect is handled here and it get's resolved as WETH in the case of native ETH.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@dohaki dohaki left a comment

Choose a reason for hiding this comment

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

Nice work! While reviewing I noticed two cases that were not covered in the Linear issue. We can tackle them separately

// See: https://www.npmjs.com/package/@across-protocol/constants
// This can cause issues when resolving the token.
// To fix this, we will check if there is a WETH match and prioritize it over the ETH match.
const wethMatch = matches.find(([symbol]) => symbol === "WETH");
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: We didn't specify it in the ticket but now that I review this, this bug happens for all native tokens, e.g. XPL, GHO. So this fix will not work for them 🤔 We can tackle this is in a separte PR/issue though

Copy link
Contributor Author

Choose a reason for hiding this comment

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

});

test("should return WETH for Base and Linea", async () => {
const params = {
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: I also didn't specify it in the ticket but what happens if you set the zero address as the inputToken? It seems that this also resolves to the wrong token information. But as above we can tackle this in a separate PR/issue

@NikolasHaimerl NikolasHaimerl merged commit d57e2a1 into master Oct 6, 2025
10 checks passed
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.

2 participants