Skip to content

Detect fee-token implementation upgrades and auto-deactivate (L2TokenRegistry) #993

@curryxbo

Description

@curryxbo

Background

Morph lets users pay gas in ERC20 fee tokens. During EVM execution we rely on the token contract's transfer and/or read user balances directly from a registered storage slot (balanceSlot in L2TokenRegistry). Both depend on assumptions about the token captured at registration time (storage layout, behavior).

Fee tokens are not controlled by Morph. If a registered token is an upgradeable proxy, the project can upgrade the implementation after registration — changing the storage layout (the registered balanceSlot then points to the wrong slot → wrong balance reads → fee-accounting corruption) or its behavior. Registration is onlyOwner, but that only vets the token at the moment of registration; there is no constraint or detection afterward.

Goal

  1. Record an implementation fingerprint per fee token at registration.
  2. Detect when a token's implementation changes.
  3. On detected change, auto-deactivate the token (TokenInfo.isActive = false) — fail closed, stop using it for gas payment.
  4. Re-activation requires a manual re-audit (owner action after review).

Open design points (for tech design)

  • Fingerprint choice is non-trivial: extcodehash(tokenAddress) does not catch proxy upgrades (the proxy's own bytecode is unchanged; only the implementation slot changes). Catching upgrades requires resolving the implementation (e.g. EIP-1967 impl slot → extcodehash(impl)), which is proxy-pattern-specific and not generically resolvable (UUPS / transparent / beacon / diamond / custom slots, and can be deliberately hidden). Must define the policy for tokens whose implementation can't be reliably resolved (reject at registration vs accept with monitoring).
  • Detection timing / location: on-chain at use-time vs off-chain monitor triggering deactivation; on-chain check cost.
  • balanceSlot reliance: consider restricting direct slot reads to non-upgradeable / fingerprint-pinned tokens, with standard transfer/balanceOf as fallback.
  • Existing mechanism to reuse: TokenInfo.isActive, batchUpdateTokenStatus, isTokenActive.

Non-goals

  • Preventing project teams from upgrading their own token contracts (outside Morph's control).

Metadata

Metadata

Assignees

Labels

No labels
No labels
No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions