Skip to content

bug(monad): vm.setEvmVersion leaves reserve policy stale #16143

Description

@haythemsellami

Component

Forge / EVM

Affected version

The Monad integration proposed in #15343 at 40f293806e535762cabe33c70aa465c8e7b47918, using monad-revm at 8ba4a51b221357105465cbe6d410906d3f12baeb.

Description

Crossing Monad hardforks through vm.setEvmVersion updates the configuration, instructions, precompiles, and frame memory policy, but it does not update spec-derived policy already captured by the transaction's ReserveBalanceTracker.

The tracker captures values including the recent-code-hash behavior and MonadNine's created-and-selfdestructed-account exemption during transaction initialization. Its existing rebase operation updates chain context and tracked accounts but not those hardfork-derived flags. Foundry's runtime transition currently only rebuilds MonadCfgEnv.

This means a transaction initialized under MonadEight can execute MonadNine instructions and precompiles while reserve enforcement still applies MonadEight policy.

Reproduction

  1. Start a Forge test transaction under MonadEight.
  2. Pre-fund a deterministic CREATE2 destination.
  3. Call vm.setEvmVersion("MonadNine").
  4. Deploy constructor code to that destination that self-destructs during initialization.
  5. Query dippedIntoReserve() at 0x0000000000000000000000000000000000001001.

The transitioned execution reports a reserve violation. Running the same operation from a transaction initialized directly under MonadNine applies the created-and-selfdestructed exemption and does not report the violation.

Expected behavior

Runtime hardfork transitions should update every spec-dependent execution policy. Execution reached through Eight→Nine should match execution initialized directly under Nine, and transitions in both directions should remain coherent.

Suggested fix

Add a monad-revm tracker reconfiguration hook that updates spec-derived flags and recomputes already tracked accounts without resetting transaction sender, gas, or chain-context invariants. Invoke it whenever the Monad EVM observes a runtime spec transition, alongside instruction and precompile selection.

The Foundry integration should pin the corresponding monad-revm fix and add a vm.setEvmVersion regression. Dependency tests should cover Eight→Nine, Nine→Eight, and Nine→Eight→Nine transitions, including the created-and-selfdestructed case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions