Skip to content

fix(phantom): normalize EIP-1474 hex quantities so yields approvals don't reject#12360

Merged
kaladinlight merged 1 commit into
developfrom
fix/ss-5675-phantom-yields-approvals
May 19, 2026
Merged

fix(phantom): normalize EIP-1474 hex quantities so yields approvals don't reject#12360
kaladinlight merged 1 commit into
developfrom
fix/ss-5675-phantom-yields-approvals

Conversation

@kaladinlight
Copy link
Copy Markdown
Member

@kaladinlight kaladinlight commented May 19, 2026

Description

Phantom strictly enforces EIP-1474 hex QUANTITY encoding — no leading zeros except 0x0 itself — and rejects non-compact hex with a generic Missing or invalid parameters error (code -32000). MetaMask silently normalizes, which is why yields approvals worked there but not on Phantom: yield.xyz returns padded hex like 0x054e0840 and the client was passing it through unchanged.

Changes:

  • packages/hdwallet-phantom/src/ethereum.ts — normalize all hex QUANTITY fields (value, gasLimit, maxFeePerGas, maxPriorityFeePerGas, gasPrice) via ethers v5's hexValue before invoking phantom.request({ method: 'eth_sendTransaction' }).
  • src/lib/yieldxyz/executeTransaction.tstoHexOrDefault was short-circuiting on isHex and preserving non-compact input verbatim. Always re-encode through BigInt/toHex so the output is EIP-1474 compact.
  • packages/hdwallet-core/src/ethereum.ts — tighten the EIP-1559 variant of ETHSignTx to require both maxFeePerGas and maxPriorityFeePerGas (matches the existing NetworkFees discriminator). Enables proper discriminated-union narrowing at callsites.
  • Added missing maxPriorityFeePerGas to the EIP-1559 ethSendTx tests in coinbase, metamask-multichain, vultisig, and phantom adapters — surfaced by the tighter type.
  • Updated executeTransaction.test.ts expectations that codified the buggy non-compact output; added a regression test for the leading-zero case.

Issue (if applicable)

closes #12350

SS-5675

Risk

High Risk PRs Require 2 approvals

High risk. Touches hdwallet-core (the ETHSignTx type) and the EVM transaction send path in hdwallet-phantom. Type tightening surfaced three previously-incorrect adapter tests but does not change runtime behavior for any production construction site (all already pair both EIP-1559 fields). yield.xyz EVM execute path is also touched (toHexOrDefault semantics).

What protocols, transaction types, wallets or contract interactions might be affected by this PR?

  • Wallets: Phantom (EVM) — behavior changed (now compliant). MetaMask / Ledger / KeepKey / Coinbase / Vultisig / WalletConnect / Native — no runtime change.
  • Transaction types: all EIP-1559 transactions through hdwallet-phantom, all EVM transactions originating from yield.xyz flows.
  • Contract interactions: any approval / deposit via the Yields feature on EVM chains.

Testing

Engineering

Repro (without this fix): connect Phantom on Ethereum mainnet, attempt a yields deposit on USDC (Aave V3 or similar). Approval popup never appears, console shows error signing & broadcasting tx originating from ethereum.ts:50 → Phantom's bundle throws Missing or invalid parameters on maxPriorityFeePerGas.

With this fix:

  • Yields approval + deposit on Phantom for USDC on Ethereum, USDC on Polygon, USDT on Ethereum (the chains/tokens called out in the ticket).
  • Regression: yields approval + deposit on MetaMask (and any other EVM wallet you have handy) to confirm the toHexOrDefault change didn't break paths that previously worked.
  • Regression: a normal swap on Phantom (the swapper path uses a different fee-construction route — confirm still works).
  • Unit tests: pnpm --filter @shapeshiftoss/hdwallet-phantom test, pnpm --filter @shapeshiftoss/hdwallet-core test, and the yieldxyz tests in the web app.

Build order if testing locally: pnpm --filter @shapeshiftoss/hdwallet-core build then pnpm --filter @shapeshiftoss/hdwallet-phantom build (both packages resolve via dist/).

Operations

  • 🏁 My feature is behind a flag and doesn't require operations testing (yet)

QA on a preview build:

  1. Open the app on a preview deployment with Phantom installed.
  2. Connect Phantom, switch to Ethereum mainnet.
  3. Navigate to Yields, find a USDC opportunity (e.g. Aave V3).
  4. Attempt a small deposit (~5 USDC). The Phantom popup should appear for the approval step, then the deposit step.
  5. Repeat on Polygon (USDC) and Ethereum (USDT).
  6. As a regression check, also test a normal swap on Phantom on one EVM chain to confirm no regression at the wallet layer.

Screenshots (if applicable)

n/a

Summary by CodeRabbit

  • Bug Fixes
    • Improved Ethereum transaction processing with enhanced validation of transaction fee parameters
    • Refined hexadecimal value formatting for better wallet compatibility and transaction reliability
    • Enhanced transaction handling across wallet implementations to prevent incomplete fee submissions

Review Change Stack

…on't reject

Phantom strictly enforces EIP-1474 hex QUANTITY encoding — no leading
zeros except 0x0 itself — and rejects non-compact hex with a generic
"Missing or invalid parameters" error. MetaMask silently normalizes,
which is why yields approvals worked there but not on Phantom (yield.xyz
returns padded hex like 0x054e0840 that the client passed through).

- Normalize all hex fields in hdwallet-phantom ethSendTx via ethers hexValue.
- Make toHexOrDefault always re-encode through BigInt; it was short-
  circuiting on isHex and preserving non-compact input verbatim.
- Tighten the ETHSignTx EIP-1559 variant to require both maxFeePerGas
  and maxPriorityFeePerGas so discriminated-union narrowing actually
  works at callsites.
- Add missing maxPriorityFeePerGas to coinbase/metamask-multichain/
  vultisig/phantom adapter tests that the tightened type surfaced.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kaladinlight kaladinlight requested a review from a team as a code owner May 19, 2026 19:48
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 838989e8-956e-4edc-af30-6c6d16b184f8

📥 Commits

Reviewing files that changed from the base of the PR and between a068e0f and adfeaa5.

📒 Files selected for processing (8)
  • packages/hdwallet-coinbase/src/coinbase.test.ts
  • packages/hdwallet-core/src/ethereum.ts
  • packages/hdwallet-metamask-multichain/src/shapeshift-multichain.test.ts
  • packages/hdwallet-phantom/src/ethereum.ts
  • packages/hdwallet-phantom/src/phantom.test.ts
  • packages/hdwallet-vultisig/src/vultisig.test.ts
  • src/lib/yieldxyz/executeTransaction.test.ts
  • src/lib/yieldxyz/executeTransaction.ts

📝 Walkthrough

Walkthrough

This PR addresses Phantom wallet approval failures on EVM deposits by enforcing EIP-1559 fee parameter requirements in the core type contract, implementing proper hex encoding and fee logic in the Phantom wallet, and normalizing hex output to strip leading zeros that Phantom rejects.

Changes

EIP-1559 Requirements and Phantom Wallet Fix

Layer / File(s) Summary
Core EIP-1559 Fee Parameter Contract and Test Updates
packages/hdwallet-core/src/ethereum.ts, packages/hdwallet-coinbase/src/coinbase.test.ts, packages/hdwallet-metamask-multichain/src/shapeshift-multichain.test.ts, packages/hdwallet-phantom/src/phantom.test.ts, packages/hdwallet-vultisig/src/vultisig.test.ts
ETHSignTx EIP-1559 variant now requires maxFeePerGas and maxPriorityFeePerGas as required Hex fields instead of optional. Wallet test suites across Coinbase, MetaMask MultiChain, Phantom, and Vultisig updated to pass both required fee parameters in ethSendTx test inputs.
Phantom Wallet Implementation: Hex Encoding and EIP-1559 Logic
packages/hdwallet-phantom/src/ethereum.ts
Phantom wallet now imports hexValue and hex-encodes value and gasLimit fields in the transaction object. EIP-1559 fee logic updated to use the EIP-1559 form only when both maxFeePerGas and maxPriorityFeePerGas are present; otherwise falls back to gasPrice.
Hex Normalization Utility and Test Coverage
src/lib/yieldxyz/executeTransaction.ts, src/lib/yieldxyz/executeTransaction.test.ts
toHexOrDefault function refactored to normalize hex strings by routing through BigInt and toHex, ensuring leading zeros are stripped per EIP-1474 (Phantom rejects padded hex). Test suite updated to verify compact hex preservation and leading-zero stripping. Transaction fixture expectations adjusted for ETH rETH and AVAX sAVAX tests to match normalized hex output.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A phantom transaction takes wing,
With both fee fields, EIP-1559 can sing!
Hex values compact, no padded zeros here,
The approval succeeds, the path is now clear! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: normalizing EIP-1474 hex quantities to prevent Phantom wallet rejections during yield approvals.
Linked Issues check ✅ Passed All code changes directly address issue #12350: normalizing hex QUANTITY fields to EIP-1474 compact format, tightening EIP-1559 type requirements, and updating tests accordingly.
Out of Scope Changes check ✅ Passed All changes are scoped to the stated objectives: hex normalization in Phantom integration, yield transaction execution, core EIP-1559 types, and corresponding test updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ss-5675-phantom-yields-approvals

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kaladinlight kaladinlight merged commit 6d723d9 into develop May 19, 2026
6 checks passed
@kaladinlight kaladinlight deleted the fix/ss-5675-phantom-yields-approvals branch May 19, 2026 20:11
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.

Approvals for evm deposits on yeilds failing on Phantom wallet

1 participant