Field notes
What a Solidity developer changes on Monad, and what they leave alone
The bytecode can stay. The habits cannot. Twelve-second blocks, a gas limit that is only a ceiling, and an archive node that is always there are Ethereum assumptions. None of them is true here.
MONAF Desk · 25 October 2026 · 9 min
- EVM
- No new compiler
- 30M
- Transaction gas cap
- 300 ms
- A block is not a minute
- 143
- Test the chain you mean
Monad’s promise to a developer is that you do not learn a new language. Contracts compiled for the EVM deploy. You do not annotate storage to help the parallel executor. The scheduler discovers conflicts by running the code. Cancun-era opcodes, including transient storage, are part of the machine. If your deployment story starts with a new compiler, you are not on this chain’s design. If it ends there, you have missed the part that bites.
Time, gas, and the logs
block.timestamp moves with the slot. A cooldown written as “two blocks” is about 600 milliseconds, not twenty-four seconds. A deadline written as a Unix time plus a generous minute is still fine. A deadline written as a small number of blocks because that felt like a minute on Ethereum is now a blink, and your users will expire inside the confirmation spinner. Gas is the sharper change. The transaction cap is 30 million gas. The block cap is 150 million. And the sender pays the limit, not the used gas, so a script that sets the cap “to be safe” is setting the fee. Estimate, then set the limit next to the estimate.
eth_getLogs across a huge range will fail or get you rate-limited. The public endpoints publish their budgets: on the order of 15 to 25 requests a second for the busiest named providers, and batch caps as low as one on the Foundation host. A backfill that worked against a private Ethereum archive will not work unchanged against rpc.monad.xyz. Historical eth_call is a feature of specific hosts, rpc2 and the Foundation endpoint among the ones the docs mark, not of “Monad” as a whole. If your indexer needs yesterday’s state, pick the host that serves it, and cache. Do not poll the head on a one-second timer and call yourself live. That timer is three blocks late before it starts.
The contract is portable. The operations manual is not. Rewrite the manual.
What you still test
Parallel execution does not change the result you must test. The committed state is a serial state. Two transactions that write the same slot will replay, and your unit test should still assume they might be ordered either way the block orders them. What changes is the load test. A hot slot, a noisy oracle, a log query, a gas limit copied from a mainnet Ethereum script: those are the failures. Fork the chain id you mean, 143, and read a receipt from it before you announce that the deploy “worked”. A deploy that succeeded on a testnet with a different id has not touched this money.