Skip to content

fix(blue-sdk-viem): avoid deployless EIP-5267 reverts#528

Closed
prd-carapulse[bot] wants to merge 1 commit intomainfrom
fix/gettoken-eip5267-deployless
Closed

fix(blue-sdk-viem): avoid deployless EIP-5267 reverts#528
prd-carapulse[bot] wants to merge 1 commit intomainfrom
fix/gettoken-eip5267-deployless

Conversation

@prd-carapulse
Copy link
Copy Markdown
Contributor

@prd-carapulse prd-carapulse bot commented Mar 16, 2026

Summary

Fix @morpho-org/blue-sdk-viem's deployless GetToken.query() helper so it does not revert on valid ERC-20s that implement EIP-5267.

This was causing the consumer app to emit RpcRequestError: execution reverted for deployless token fetches even though the underlying token RPC calls were succeeding.

User-facing impact

This addresses the Sentry issue reported from morpho-consumer:

The failure was noisy because fetchToken() would first attempt the deployless helper, hit a revert, and then fall back to non-deployless reads. So users often still got the right token metadata, but only after an avoidable reverted eth_call that was surfacing in Sentry.

Root cause

The failing selector in Sentry was the deployless helper selector:

  • 0x287861f9GetToken.query(address,bool)

I reproduced the issue on the Morpho cached mainnet RPC and on a forked Anvil instance at block 24,671,815 using the exact token that appeared in the failing trace:

  • token: 0xD11c452fc99cF405034ee446803b6F6c1F6d5ED8 (Treehouse ETH / tETH)

Direct calls to the token all succeed:

  • name()Treehouse ETH
  • symbol()tETH
  • decimals()18
  • eip712Domain()
    • fields = 0x0f
    • name = "Treehouse ETH"
    • version = "1"
    • chainId = 1
    • verifyingContract = token
    • salt = 0x0
    • extensions = []

The old deployless GetToken bytecode still reverted after eip712Domain() returned successfully. Tracing showed that the revert happened inside the helper's local decode/copy path for:

try IERC20Permit(address(token)).eip712Domain() returns (Eip5267Domain memory eip5267Domain)

So this was not:

  • an RPC/provider problem
  • a broken tETH implementation
  • a bad eip712Domain() response

It was a deployless helper decode issue triggered by valid EIP-5267 return data.

Fix

Instead of decoding eip712Domain() through Solidity's try ... returns (Eip5267Domain memory) path, GetToken now:

  1. performs a raw staticcall to eip712Domain()
  2. abi.decodes the returndata locally as
    (bytes1, string, string, uint256, address, bytes32, uint256[])
  3. reconstructs the Eip5267Domain struct in the response

This keeps the query ABI and the TypeScript SDK API unchanged, but avoids the buggy deployless decode path that was reverting.

Why this approach

I intentionally kept the change narrow:

  • no public SDK API change
  • no query ABI shape change
  • no fallback-only workaround
  • no consumer-side suppression of the failure

That means callers still get the single deployless token read, but without the spurious revert.

Tests added / tightened

Strengthened existing coverage

The existing EIP-5267 token test now uses:

{ deployless: "force" }

This is important because the previous test could still pass if deployless reverted and the implementation silently fell back to non-deployless reads.

New regression test

Added a regression test pinned to the failing mainnet era:

  • fork block: 24,671,815
  • token: Treehouse ETH (0xD11c452fc99cF405034ee446803b6F6c1F6d5ED8)
  • mode: deployless: "force"

This fails on the old helper bytecode and passes with this patch.

Validation

Manual onchain validation

Reproduced and validated on a mainnet fork built from the Morpho cached RPC:

  1. deploy old/new GetToken helper bytecode to local Anvil
  2. call query(tETH, false)
  3. confirm:
    • old helper reverts after eip712Domain()
    • patched helper returns the full token struct successfully

Automated validation

MAINNET_RPC_URL="$(/home/node/.openclaw/skills/foundry-evm-debug/scripts/rpc-url.sh 1)" \
  corepack pnpm test --run packages/blue-sdk-viem/test/Token.test.ts

corepack pnpm --dir packages/blue-sdk-viem build

Both passed locally.

Notes

I kept this PR scoped to GetToken, which is the helper involved in the reported Sentry issue. If we see the same pattern elsewhere, we should audit any other deployless helpers that decode Eip5267Domain through the same Solidity path.

Copy link
Copy Markdown
Collaborator

@Rubilmax Rubilmax left a comment

Choose a reason for hiding this comment

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

Probably affects other cases with try/catch in deployless?

@Rubilmax
Copy link
Copy Markdown
Collaborator

Superseded by #531, which preserves the same patch with a signed commit.

@Rubilmax Rubilmax closed this Mar 19, 2026
auto-merge was automatically disabled March 19, 2026 09:57

Pull request was closed

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