The promise of Ethereum's modular future is "write once, deploy anywhere." Developers are led to believe that if a smart contract works on Ethereum Mainnet, it will function identically on Optimism, Arbitrum, Base, or Moonbeam. This assumption is false and dangerous.
"EVM-equivalence" is a spectrum, not a binary state. Layer 2 networks (L2s) and sidechains are distinct operating environments with unique architectural decisions meant to optimize for speed and cost. These optimizations frequently break standard assumptions made by Solidity developers, leading to silent failures and critical vulnerabilities when porting code from Mainnet.
A contract audited for Ethereum Mainnet is not audited for an L2 deployment.
1. The Opcode Minefield
Fundamental context variables behave differently across chains. Relying on them for program logic is a primary source of cross-chain bugs.
- block.difficulty / block.prevrandao: On Mainnet post-Merge, this relates to the beacon chain's randomness. On Optimistic rollups, there is no mining or Proof-of-Stake consensus mechanism at the execution layer. Consequently, this opcode often returns a constant value (e.g., 0 or 1) or an outdated L1 value. Contracts using this for pseudo-randomness or timing checks will become deterministic and exploitable on L2s.
- block.coinbase: On Mainnet, this is the address of the validator building the block, often used to reward block proposers. On L2s with centralized sequencers, this address is often fixed to the sequencer's address. Mechanics rewarding msg.sender or specific actors via coinbase will fail to distribute rewards correctly.
- block.number vs. block.timestamp: L2 block times are significantly faster than Mainnet's 12 seconds (often sub-second). Time-Weighted Average Price (TWAP) oracles and governance timelocks calculated in block numbers on Mainnet will execute exponentially faster on L2s, breaking financial models and security delays.
2. Precompile Divergence
Ethereum Mainnet reserves addresses 0x01 through 0x09 for precompiled contracts (e.g., ecrecover, sha256, identity). L2s utilize higher address spaces for their own system contracts, such as bridges and gas price oracles.
Critical differences arise in how these are handled:
- Missing Precompiles: A specific cryptographic precompile available on Mainnet might not exist on a given L2 or sidechain.
- Modified Behavior: Some L2s modify the behavior of standard precompiles for efficiency.
- Silent Failure: The EVM standard dictates that a call to an empty address returns success (true) with no data. If your code calls a precompile that doesn't exist on the target L2, it won't revert. It will silently return empty data, which your contract might interpret as a valid result (e.g., cryptographic validation returning 0x0 and passing a check).
3. The Death of SELFDESTRUCT
The SELFDESTRUCT opcode is actively being deprecated on Ethereum Mainnet due to state bloat issues. However, many L2s have already altered or disabled its functionality entirely.
On several major L2 networks, executing SELFDESTRUCT will terminate the contract but will not transfer the remaining ETH balance to the target address. The funds are effectively burnt.
Contracts relying on SELFDESTRUCT for emergency exit mechanisms, architectural upgrades, or final fund retrieval will permanently lock user assets upon deployment to these networks. This is a catastrophic, irreversible failure mode.
Conclusion
Treating L2s as faster clones of Ethereum is a strategic error. They are separate environments requiring dedicated attention. Every target deployment chain demands its own comprehensive test suite and security review focused on that specific chain's documentation and quirks. If you do not test against the specific L2's execution environment, you are not testing at all.