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