Monad network reference
Vessel runs on Monad. This page collects the network facts a user, keeper, or integrator needs before sending a transaction. Every value below was read at the named primary source on 2026-08-29; the source list is in the page footer.
Vessel is deployed on Monad testnet only. The mainnet column is here because the same rules apply there and because integrators routinely need both.
Networks
| Mainnet | Testnet | |
|---|---|---|
| Chain ID | 143 (0x8F) | 10143 (0x279F) |
| Native currency | MON, 18 decimals | MON, 18 decimals |
| Primary RPC | https://rpc.monad.xyz | https://testnet-rpc.monad.xyz |
| Explorer (MonadVision) | monadvision.com | testnet.monadvision.com |
| Explorer (Monadscan) | monadscan.com | testnet.monadscan.com |
| Faucet | n/a | faucet.monad.xyz |
| App hub | n/a | testnet.monad.xyz |
Chain IDs are triple-agreed across docs.monad.xyz, the viem chain definitions, and ethereum-lists/chains.
Network version at time of writing: v0.15.2 / MONAD_NINE. Testnet was reset from genesis on 2025-12-16; any testnet history, address, or explorer link from before that date refers to a chain that no longer exists.
viem and ethereum-lists still list testnet.monadexplorer.com as the testnet explorer. Current docs.monad.xyz does not reference it. This page ships the docs.monad.xyz set: MonadVision and Monadscan on both networks.
RPC endpoints
Mainnet
| Endpoint | Operator | Limits |
|---|---|---|
https://rpc.monad.xyz | QuickNode (primary) | 25 rps, batch 100 |
https://rpc1.monad.xyz | Alchemy | UNVERIFIED — PENDING GATE-0 |
https://rpc2.monad.xyz | Goldsky | UNVERIFIED — PENDING GATE-0 |
https://rpc3.monad.xyz | Ankr | UNVERIFIED — PENDING GATE-0 |
https://rpc-mainnet.monadinfra.com | Monad Infra | UNVERIFIED — PENDING GATE-0 |
WebSocket (wss://) variants exist for all five mainnet endpoints. The source states their existence; it does not publish separate rate limits for them.
Testnet
| Endpoint | Limits |
|---|---|
https://testnet-rpc.monad.xyz (primary, archive) | 50 rps, batch 100; 25 rps for eth_call and eth_estimateGas |
https://rpc.ankr.com/monad_testnet | UNVERIFIED — PENDING GATE-0 |
https://rpc-testnet.monadinfra.com | UNVERIFIED — PENDING GATE-0 |
Testnet WebSocket endpoints: wss://testnet-rpc.monad.xyz and wss://rpc-testnet.monadinfra.com.
A keeper polling Vessel state against the primary testnet RPC should size its loop against the 25 rps eth_call ceiling, not the 50 rps headline figure. The full provider directory, 16 providers on mainnet and 15 on testnet, is at docs.monad.xyz/tooling-and-infra/rpc-providers.
# Confirm you are talking to the right chain
cast chain-id --rpc-url https://testnet-rpc.monad.xyz # 10143
cast chain-id --rpc-url https://rpc.monad.xyz # 143
Blocks and finality
Block time is 300ms. Speculative finality is 300ms; full finality is 600ms.
The Vessel litepaper cites 400ms blocks and 800ms finality. Those figures predate the current network and are stale; the numbers above are from current docs.monad.xyz.
Monad exposes four block states. They map onto the standard JSON-RPC block tags as follows.
| Block state | RPC tag | Meaning |
|---|---|---|
| Proposed | latest | Speculative; the leader has proposed the block |
| Voted | safe | Validator-backed |
| Finalized | finalized | Irreversible |
| Verified | (after finalized) | Execution outputs verified |
Use finalized for anything irreversible: crediting a deposit, releasing a Hull redemption, marking a keeper job as done, or triggering an off-chain action on a Vessel event. latest is fine for display and for simulation.
Two consequences of Monad's asynchronous execution:
- Consensus validates against a state view delayed by three blocks (
D=3). A newly funded account cannot send a transaction until its funding is three blocks old, roughly 1.2 seconds. Scripts that fund a fresh keeper wallet and immediately transact from it will fail on the first attempt. eth_callandeth_estimateGassimulate against speculative state and return accurate results.
Parallel execution is optimistic-concurrency under the hood; results are identical to serial Ethereum semantics. No contract changes are required and Vessel makes none for this reason.
Gas
From docs.monad.xyz, verbatim: "In Monad, the gas charged for a transaction is the gas limit set in the transaction, rather than the gas used in the course of execution."
gas_paid = gas_limit × price_per_gas. This exists because of asynchronous execution: the leader builds the block before executing it, so actual consumption is unknown at inclusion time, and charging the limit prevents under-priced-compute denial of service.
What this means in practice:
- A keeper must fund its wallet against the gas limits it sets, not against historical
gasUsed. A rebalance that uses 400k gas but is sent with a 2M limit costs 2M. - An integrator estimating the cost of Vessel calls from receipts'
gasUsedwill underfund. Estimate from the limit you intend to set. - If
eth_estimateGasreverts, some wallets fall back to a very large default limit. On Ethereum that is harmless; on Monad the user pays the entire limit. A failed estimate followed by a blind send costs real money.
Parameters, all from docs.monad.xyz and matching MONSKILLS v0.7.2:
| Parameter | Value |
|---|---|
| Block gas limit | 200M |
| Per-transaction gas limit | 30M |
| Minimum base fee | 100 MON-gwei |
| Base fee target | 160M gas per block (80% of capacity) |
| Native MON transfer | exactly 21,000 gas |
Pricing is EIP-1559 type-2: price_per_gas = min(base + priority, max). Transactions are ordered by a priority gas auction, descending total gas price.
The base fee controller rises more slowly and falls more quickly than Ethereum's (max_step = 1/28, beta = 0.96). A burst of demand takes longer to push fees up and fees recover sooner afterwards. Do not port fee-bump heuristics tuned for Ethereum without re-testing them.
Two rules for anyone writing transaction code against Vessel:
- A native MON transfer always costs 21,000 gas. Hardcode it; do not call
eth_estimateGasfor it. - Keep estimation buffers small, at or under about 10%. Every unit of buffer is paid, whether or not it is used.
Cold-access repricing
Cold state access is priced higher than on Ethereum. Warm access is unchanged.
| Access | Monad | Ethereum |
|---|---|---|
| Cold account access | 10,100 | 2,600 |
| Cold storage access | 8,100 | 2,100 |
| Warm access | 100 | 100 |
This affects BALANCE, EXTCODE*, CALL*, SELFDESTRUCT, SLOAD, and SSTORE. A Vessel operation that touches many cold slots (a rebalance reading tranche NAVs, reserve, and venue state for the first time in a block) will estimate noticeably higher than the same bytecode on Ethereum. That is expected, not a bug.
Precompile repricing
| Precompile | Monad | Multiple of Ethereum |
|---|---|---|
| ecRecover | 6,000 | 2× |
| ecAdd | 300 | 2× |
| ecMul | 30,000 | 5× |
| ecPairing | 225,000 | 5× |
| blake2f | (2×) | 2× |
| point evaluation | 200,000 | 4× |
The source gives blake2f as a 2× multiple without an absolute figure.
Full reference: docs.monad.xyz/developer-essentials/gas-pricing.
Other limits and behaviours
- Reserve balance. Every EOA carries a 10 MON reserve floor. Accounts below it are limited to roughly one transaction per 1.2 seconds. Keeper wallets should hold well above 10 MON, and the balance alert threshold should sit above the floor, not at zero.
- Contract size. Maximum contract size is 128kb, larger than Ethereum's 24kb. Vessel's contract sizes are not published UNVERIFIED — PENDING GATE-0; the repository contains no contracts as of 2026-08-29.
eth_sendRawTransactionSync. Monad returns the transaction receipt in the send call itself. A keeper can use it to skip the submit-then-poll loop. Treat the returned receipt with the same finality discipline as any other: it is speculative until the block reachesfinalized.
Contract verification
Vessel's testnet contracts are not yet published, so there is nothing to verify today. When they are, the procedure is Monad's standard one. The guide, with Foundry and Hardhat sub-guides, is at docs.monad.xyz/guides/verify-smart-contract. The MonadVision path uses Sourcify and needs no API key:
forge verify-contract <addr> <name> --chain 10143 --verifier sourcify \
--verifier-url https://sourcify-api-monad.blockvision.org/
Use --chain 143 for mainnet. The Monadscan path uses --verifier etherscan with an API key. foundry.toml needs metadata = true, metadata_hash = "none", and use_literal_content = true. The verify command can print errors even when verification succeeded; confirm on the explorer before concluding it failed.
To check whether any address holds code:
cast code <addr> --rpc-url https://testnet-rpc.monad.xyz
Sources
- docs.monad.xyz/developer-essentials/network-information for chain IDs, endpoints, explorers, and network version
- docs.monad.xyz/developer-essentials/gas-pricing for every gas figure on this page
- docs.monad.xyz for block states and asynchronous execution
- docs.monad.xyz/guides/verify-smart-contract for contract verification