Denim is a new upgrade on Base, the Ethereum layer-2 network, and it changes the speed at which the chain itself produces blocks. Base used to produce one canonical block every two seconds. A full canonical block now arrives every 200 milliseconds, or five blocks per second. The Base Engineering Team announced the change in a post dated November 5, 2026.
App users on Base don’t need to do anything, according to the team’s brief note. Their transactions are included in canonical blocks that arrive every 200ms. Denim also brings a separate change: a send made by mistake to a B20 token’s own address now fails, so those funds no longer get locked.
What changes on the chain
Base relied on Flashblocks before Denim to cover the two seconds between blocks. Flashblocks streamed pending-state updates for the block under construction, which let apps show a preview before the block landed. That preview could be left out of the block that actually landed, so apps displaying Flashblock state had to be prepared to roll it back.
Flashblocks are replaced by Denim. Every 200ms block is a real canonical block carrying the same guarantees as any other block on Base, which means reorgs caused by Flashblocks no longer happen. Base has stopped producing Flashblocks streams, and the “pending” block tag no longer returns a preconfirmed state.
Inclusion in a 200ms block does not make a transaction final. Like every Base block, it becomes safe once its batch is posted to Ethereum, and final once Ethereum finalizes that batch. Slots also can’t be skipped: the protocol validates that every block’s timestamp is exactly 200ms after its parent’s.
Millisecond time with BaseTime
Timestamps in Ethereum block headers are stored in whole seconds, and Denim leaves that as it is. At five blocks per second, five blocks in a row share one block.timestamp. A contract that compares timestamps therefore sees no time pass between four out of every five blocks, followed by a jump of a full second.
BaseTime supplies the missing milliseconds. Each Denim block includes a BaseTime metadata update at transaction index 1, directly after the L1 info deposit, and it writes the block’s sub-second part (0, 200, 400, 600 or 800) to a BaseTime predeploy. Since this happens before any user transactions, every contract in the block can read the full millisecond timestamp. The team lists auctions, order expiry and reward calculations as example uses.
An optional timestampMs field is added to block and header responses, and an optional blockTimestampMs is added to mined transactions, logs and receipt logs. The existing timestamp field stays the same, so clients that skip the new fields still work. Blocks from before Denim leave them out.
What builders need to check
Standard JSON-RPC methods, including eth_subscribe(“newHeads”), eth_getLogs, eth_call and eth_getTransactionReceipt, return 200ms state with no changes. According to the team, viem, ethers, Foundry and existing indexers all work without a Flashblocks client. Apps that relied on Flashblocks or the “pending” tag have to switch to canonical block subscriptions and the latest block.
Timing logic is the larger issue. Base now produces ten times as many blocks per second, so in any contract or offchain system that uses a block count as a duration, that duration drops to one tenth of what was intended. Where contracts can be redeployed or upgraded, the team recommends swapping block-count durations for block.timestamp comparisons, and multiplying governance-tunable block counts by ten. Bridges and proof flows that read historical block hashes through BLOCKHASH still get the same number of values, but that history now spans one tenth of the elapsed time.
On DeFi, the team says lending, trading and rewards protocols now have five chances per second to react. Liquidations can run in the first block after a price update, and interest accrual and reward streaming can operate at 200ms resolution.
B20 token changes
B20 tokens are also affected by Denim. A transfer, mint or seizure sent to the token’s own address now reverts with the existing InvalidReceiver error. Previously, tokens credited to that address stayed stuck unless the issuer seized them back.
Issuers who want every transfer started by an approved party, such as a transfer agent, use the TRANSFER_EXECUTOR_POLICY allowlist, and it is now checked on every transfer path. Before Denim, a holder could get around it by calling transfer directly. Nothing changes for tokens that never set an executor policy. Base says it is up to the issuer whether to set an executor policy and who goes on it. Issuers can now also invert any policy with a NOT operator, which joins the AND and OR operators introduced with the earlier Cobalt upgrade.





















STAY ALWAYS UP TO DATE