Descout
News··5 min read

Base Denim is live: Flashblocks retired, B20 executor rules reach holders

Base said Nov. 5 that Denim is live on mainnet; B20 tokens with an executor allowlist now revert direct holder transfers with PolicyForbids.

Drafted by the Descout article deskHow this was made
Share:
Base Denim is live: Flashblocks retired, B20 executor rules reach holders - Analysis and insights

Base said on Nov. 5 that its Denim upgrade is live on mainnet. The @base announcement, posted at 20:02 UTC, reads "Base Denim is officially live on mainnet" and lists native 200ms blocks, BaseTime for millisecond precision and B20 improvements. The @buildonbase release article calls Denim Base's fourth upgrade and says it replaces Flashblocks with five complete canonical blocks every second.

Our Oct. 20 preview guide covers the block cadence, the BaseTime fields and the Flashblocks migration table. This piece covers what the activation post and the docs add: what contract owners should check, and three B20 changes the preview could not detail. Denim follows Cobalt, which added validity transactions and the B20 compliance tools.

What stopped, and what has not finished

According to the release article, Base no longer produces Flashblocks streams, and the "pending" block tag no longer returns a preconfirmed state. Apps that consumed Flashblocks are told to move to canonical block and RPC streams, with the mapping in Base's Migrate From Flashblocks page.

Base also states that including a transaction in a 200ms block does not make it final. As with every Base block, it becomes safe when its batch is posted to the layer-1 chain it settles on and final when that chain finalizes the batch.

Contract logic that counts blocks

Base says block.number now advances ten times faster in wall-clock time, while block.timestamp is unchanged and still moves in whole seconds. The 200ms Native Blocks spec lists the patterns that shrink or speed up:

  • timelocks, cooldowns and exit delays written as block.number - start >= N
  • vesting, emission and difficulty schedules measured in blocks
  • per-block rate limits or caps that reset when block.number changes
  • deadlines set as expirationBlock = block.number + N
  • governance voting delay and period in blocks, including ERC20Votes with the default block-number clock()
  • fixed-cardinality TWAP oracles, which can cover as little as half the wall-clock history before long observe() lookbacks revert

Base's advice is to replace block-count durations with block.timestamp comparisons where a contract can be redeployed or upgraded. Where a block count is governance-tunable, the spec says to multiply block-count durations, "such as timelocks, deadlines, and voting periods," by ten to keep their wall-clock length, and to divide per-block caps by ten to keep their per-second limit. For immutable block counts, it says to assess the impact and plan a migration. That spec page still carried its pre-activation warning banner when we read it on Nov. 6, so its schedule language predates the launch.

B20: three changes

The release article says Denim makes B20 tokens safer for users and gives issuers simpler compliance controls. The details sit in three changelog entries.

Holder transfers now face the executor policy. B20's TRANSFER_EXECUTOR_POLICY is an allowlist of who may initiate a transfer, built for issuers of restricted securities that route every transfer through a transfer agent. Before Denim, the changelog says, transfer never consulted it, and transferFrom skipped the check when msg.sender == from. After Denim the policy is checked on msg.sender for every transfer path. In Base's example, a holder who is not on the allowlist and calls transfer directly now gets a revert with PolicyForbids. Tokens that never set an executor policy keep the always-allow default and see no change. An issuer who wants holders to keep initiating their own transfers has to add them, or a policy covering them, to the allowlist. Base adds that the issuer chooses whether to set an executor policy and who is on it, and that Base does not decide who may initiate transfers.

Policies can be inverted. Cobalt let issuers combine policies with AND and OR. Per the changelog, Denim reserves bit 63 of a policy ID as an invert flag, and a new view, invertedPolicyId, toggles it. Members stay on the base policy, so one list can act as an allowlist in one scope and an exclusion in another. Base's example is a transfer policy of "KYC AND NOT sanctioned," built from a KYC list and the inverse of a sanctions list the compliance provider maintains. Existing policy IDs behave as before.

The token's own address is no longer a valid recipient. Per the changelog, a transfer, mint or seizure to the B20 token's own address now reverts with InvalidReceiver, the error already used for the zero address. A B20 token is a precompile with no holder key, so units credited to it could not be spent by anyone. Balances that reached the token address before Denim can be moved with seizeWithMemo(address(token), treasury, amount, memo), and only if the issuer opted into seize functionality for the token. Self-sends, sends to other B20 tokens, approvals and burns are unaffected.

Who has to act

The release article's impact list is short. Users need to do nothing. App and wallet developers who use Flashblocks or the "pending" tag migrate to canonical block subscriptions and the latest block. Contract developers audit logic that converts block counts to time. Issuers with a restrictive executor policy update their allowlists, and treat the token's own address as an invalid recipient in their tooling.

Base's legal note on the announcement says Base provides neutral protocol infrastructure and that B20 tokens are issued and administered by their respective issuers, including Coinbase for its own assets.

Share: