Opcode Summary
| Property | Value |
|---|---|
| Opcode | 0x41 |
| Mnemonic | COINBASE |
| Gas | 2 |
| Stack Input | (none) |
| Stack Output | block.coinbase (address, zero-padded to 32 bytes) |
| Behavior | Pushes the 20-byte address of the current block’s beneficiary (the validator/proposer that produced the block) onto the stack. Post-merge, this is the fee recipient address configured by the validator. The COINBASE address is warm since the Shanghai hard fork (EIP-3651), meaning it can be accessed or transferred to without paying the 2600-gas cold access surcharge. |
Threat Surface
COINBASE exposes the identity of the block producer to smart contract execution. Unlike most other environmental opcodes (NUMBER, TIMESTAMP, BASEFEE), COINBASE returns an address rather than a numeric value, making it uniquely dangerous because it can be used as a recipient for ETH transfers, a key for access control checks, and a seed for pseudo-random number generation — all of which are exploitable.
The threat surface centers on four properties:
-
COINBASE is validator-controlled input. The block proposer freely chooses the fee recipient address. A validator can set it to any 20-byte address — an EOA, a smart contract, or even
address(0). Contracts that rely onblock.coinbasefor any logic effectively trust the block producer to provide a well-behaved value. Post-merge, this extends to the entire validator set (~1M validators on mainnet), any of whom could be adversarial or compromised. -
MEV searchers use COINBASE for direct validator payments. The Flashbots ecosystem established
block.coinbase.transfer()as the standard mechanism for MEV searchers to bribe validators. These payments bypass the gas fee market entirely, creating an opaque economic layer that depends on the correctness of the COINBASE value. When the COINBASE address is a smart contract (not an EOA), these transfers trigger code execution viareceive()orfallback(), introducing reentrancy risk into every MEV payment. -
Post-Shanghai, COINBASE is warm (EIP-3651). Before Shanghai, the first interaction with
block.coinbasein a transaction cost 2600 gas (cold access). EIP-3651 makes the address warm from transaction start, reducing the first access to 100 gas. This was designed to make direct ETH payments to validators cheaper, but it also means any contract can cheaply probeblock.coinbase— reading its balance, code size, or code — without the gas penalty that would have previously discouraged such patterns. -
COINBASE semantics differ radically on L2s. On OP Stack chains (Optimism, Base),
block.coinbaseis hardcoded to the SequencerFeeVault predeploy address, not a rotating validator address. On Arbitrum, it returns the sequencer’s configured address. Contracts deployed across L1 and L2s that useblock.coinbasefor logic will behave differently, and the L2 sequencer’s fixed address creates a predictable, non-rotating value that compounds the risks of access control and randomness attacks.
Smart Contract Threats
T1: Validator-Controlled Value Used for Contract Logic (High)
block.coinbase is set by the block proposer with zero constraints. Any smart contract that branches on the COINBASE value — for routing payments, selecting behavior, or comparing against a known address — hands control of that logic to the validator. This is exploitable in multiple ways:
-
Conditional execution bypass. A contract that checks
if (block.coinbase == expectedMiner)to gate functionality can be bypassed by any validator who sets their fee recipient toexpectedMiner. Post-merge, validators configure fee recipients in their client settings; changing it is trivial. -
Oracle-like trust without oracle guarantees. Contracts that read
block.coinbaseto determine “who produced this block” and then apply trust assumptions (e.g., “the block producer is honest, so this value is reliable”) conflate block production authority with data integrity. The validator controls the value but has no economic incentive to set it to any particular address — only to the address where they want to receive fees. -
MEV-aware contracts with flawed assumptions. Protocols that attempt to detect MEV activity by checking whether
block.coinbasematches a known builder address (e.g., Flashbots builder) are trivially fooled. Any validator can set their fee recipient to the Flashbots builder address, or a builder can change their address at any time.
Why it matters: Any branching logic on block.coinbase is effectively controllable by the block producer, creating a privileged-input vulnerability in every contract that uses it for decisions.
T2: MEV Bribe Payments via block.coinbase.transfer() (High)
The Flashbots ecosystem standardized block.coinbase.transfer(amount) as the mechanism for MEV searchers to pay validators for block inclusion priority. This pattern is pervasive in searcher contracts, DEX arbitrage bots, and liquidation bots. The risks include:
-
Reentrancy via contract-based validators. When
block.coinbaseis a smart contract (e.g., a smart contract wallet, a fee-splitting contract, or a malicious contract),block.coinbase.transfer()with Solidity < 0.8.0 forwards 2300 gas (enough for basic operations), whileblock.coinbase.call{value: amount}("")forwards all remaining gas. A malicious validator contract can reenter the searcher’s contract during the payment, potentially draining profits or manipulating state. Flashbots documentation explicitly warns about this risk. -
Failed payment reverts the entire bundle. MEV searcher contracts typically call
block.coinbase.transfer()at the end of their execution to pay the validator. If the transfer fails (e.g., the validator’s contractreceive()function reverts), the entire transaction reverts, including the profitable trade. A malicious validator can selectively cause searcher payments to fail by deploying a reverting contract as their fee recipient. -
Payment validation bypass. Searcher contracts often validate profitability with a pattern like
require(balance_after - balance_before >= minProfit); block.coinbase.transfer(bribe). If the validator can manipulate the execution context (e.g., through MEV-Boost relay manipulation), the profitability check may pass in simulation but fail in actual execution, or the validator can extract the profit without including the searcher’s back-run transaction.
Why it matters: Direct validator payments via COINBASE are the backbone of Ethereum’s $1B+ annual MEV economy. Every searcher contract that pays block.coinbase is exposed to reentrancy, revert griefing, and relay-level manipulation.
T3: Using COINBASE for Randomness (Critical)
Using block.coinbase as a source of entropy is fundamentally broken. The block proposer knows the COINBASE value before the block is finalized and can choose or change it at will:
-
Predictable by the proposer. The validator sets the fee recipient address before proposing the block. Any contract that uses
keccak256(abi.encodePacked(block.coinbase, ...))for randomness allows the proposer to precompute all possible outcomes and choose the address that produces the desired result. -
Predictable by MEV searchers. In the PBS (Proposer-Builder Separation) model, builders construct blocks and know the COINBASE value. Searchers who submit bundles to builders also know the builder’s address and can predict the COINBASE value for any block they target.
-
Static on L2s. On Optimism/Base,
block.coinbasereturns the same SequencerFeeVault address for every block, making it a constant rather than a source of entropy. Contracts using COINBASE for randomness on these chains produce deterministic, predictable results. -
Combinable with other predictable block variables. Developers sometimes combine
block.coinbasewithblock.timestamp,block.number, orblock.prevrandaoin a hash, assuming the combination is unpredictable. But the block producer controls or knows all of these values before committing to the block.
Why it matters: On-chain gambling, NFT minting order, lotteries, and any random selection mechanism using COINBASE are riggable by the block producer. The Fomo3D exploit (2018) demonstrated that miners will actively manipulate block-level variables when sufficient value is at stake.
T4: Block Proposer Spoofing on L2s (Medium)
L2 chains assign COINBASE values differently from L1, creating cross-chain semantic divergence:
-
Fixed sequencer address on OP Stack. On Optimism, Base, and other OP Stack chains,
block.coinbaseis hardcoded to the SequencerFeeVault predeploy address (0x4200000000000000000000000000000000000011). Contracts deployed on these chains that checkblock.coinbasealways see the same value, making COINBASE-based access control either permanently open or permanently closed depending on the hardcoded address. -
Sequencer-controlled on Arbitrum. On Arbitrum, the centralized sequencer sets the COINBASE value. Unlike L1 where each block may have a different proposer, the Arbitrum sequencer is a single entity that can set COINBASE to any address for any block, giving the sequencer operator unilateral control over all COINBASE-dependent logic.
-
Cross-chain deployment hazards. A contract that works correctly on L1 (where COINBASE rotates across validators) may fail on L2 (where COINBASE is static). Conversely, a contract that hardcodes L2’s known sequencer address as a trusted party will break if the L2 changes its sequencer configuration or decentralizes its sequencer set.
Why it matters: Multi-chain deployment is standard practice in DeFi. Contracts that use COINBASE must account for radically different semantics across chains or risk silent failures.
T5: COINBASE-Based Access Control (Critical)
Using block.coinbase to gate access (e.g., require(msg.sender == block.coinbase)) is a severe vulnerability:
-
Validator impersonation is free. Any validator can set their fee recipient to the address that the contract checks against. If the contract gates a privileged function with
require(msg.sender == block.coinbase), any validator can call that function by (1) setting their fee recipient to their own address and (2) including a transaction calling the function in their block. The “access control” is effectively “are you a block proposer who included your own transaction?” -
MEV searcher exploitation. In the MEV-Boost/PBS model, searchers submit bundles to builders, and builders set
block.coinbaseto their fee recipient. A searcher can construct a bundle that calls a COINBASE-gated function and submit it to a builder whose address matches the expected value. The builder includes the bundle, and the access control passes. -
Assumes COINBASE is trustworthy. The pattern
require(msg.sender == block.coinbase)is sometimes used to restrict functions to “only the miner/validator.” But post-merge, the proposer doesn’t execute the transactions — the builder does. The COINBASE address is the proposer’s fee recipient, not the entity that ordered transactions. This semantic gap means the “only-miner” assumption no longer holds.
Why it matters: COINBASE-based access control provides zero security guarantees. Any sufficiently motivated attacker with validator access (32 ETH stake) can bypass it, and MEV infrastructure makes it exploitable without even running a validator.
Protocol-Level Threats
P1: Warm COINBASE Address Since Shanghai — EIP-3651 (Low)
EIP-3651 (Shanghai, April 2023) makes the COINBASE address warm at the start of every transaction. Before this change, the first BALANCE, EXTCODESIZE, EXTCODECOPY, or CALL to block.coinbase cost 2600 gas (cold access per EIP-2929). Now it costs 100 gas.
Security implications:
-
Lower cost for COINBASE probing. Contracts can cheaply read the code size, balance, or code of the validator’s fee recipient address. This enables gas-efficient on-chain fingerprinting of validators (e.g., “is this validator using a smart contract wallet?”).
-
Reduced cost for MEV payments. The primary motivation for EIP-3651 was reducing gas costs for
block.coinbase.transfer()patterns used by MEV searchers. This makes the MEV bribe economy more gas-efficient, which is neutral for security but worth noting as it entrenches the pattern of direct COINBASE payments. -
Access list interactions. Since COINBASE is always warm, explicitly including it in a transaction’s access list (EIP-2930) is redundant but harmless. Contracts that dynamically build access lists should not assume COINBASE is cold.
P2: MEV/PBS Implications — Builder vs. Proposer Identity (Medium)
Under Ethereum’s current PBS architecture (MEV-Boost), block construction is separated from block proposal:
-
COINBASE reflects the proposer, not the builder. The
block.coinbasevalue is the proposer’s (validator’s) configured fee recipient. The builder, who actually orders transactions and extracts MEV, has a separate address. Contracts that assume COINBASE identifies “who ordered these transactions” are wrong — it identifies “who gets the priority fees and base fee.” -
Builder address is invisible on-chain. There is no EVM opcode to retrieve the builder’s address. Contracts cannot distinguish blocks built by Flashbots vs. bloXroute vs. other builders by examining on-chain data alone. This makes any on-chain MEV detection strategy based on COINBASE unreliable.
-
ePBS will change the economics. Enhanced PBS (EIP-7732) will enshrine builder auctions in the protocol. Builders will become staked entities, and the relationship between builder payments and COINBASE may evolve. Contracts hardcoding assumptions about COINBASE semantics may break under future protocol changes.
Edge Cases
| Edge Case | Behavior | Security Implication |
|---|---|---|
| COINBASE on OP Stack L2s (Optimism, Base) | Returns the SequencerFeeVault predeploy address (0x4200...0011) for every block | COINBASE is a constant, not a rotating value. Randomness is zero-entropy; access control is static. |
| COINBASE on Arbitrum | Returns the sequencer’s configured fee recipient address | Single centralized sequencer controls the value for all blocks; changes only when sequencer config changes. |
COINBASE in DELEGATECALL | Returns the same block.coinbase as the parent context (block-level, not call-level) | No change across delegatecall boundaries; COINBASE is a block property, not a message property. |
COINBASE == address(0) | Technically possible if the validator sets fee recipient to zero address | ETH transfers to address(0) burn ETH. Contracts checking require(block.coinbase != address(0)) may reject blocks from validators with zero-address fee recipients. |
| COINBASE is a smart contract | The fee recipient can be any address, including a contract with arbitrary code | block.coinbase.transfer() triggers receive() or fallback(), enabling reentrancy. EXTCODESIZE(block.coinbase) returns non-zero. |
| MEV builder address vs. proposer address | COINBASE is the proposer’s fee recipient; the builder’s address is not exposed via any opcode | Contracts cannot determine the builder. On-chain MEV attribution based on COINBASE is unreliable post-PBS. |
| COINBASE after Shanghai (EIP-3651) | Address is warm from transaction start; first access costs 100 gas instead of 2600 | Cheaper to probe validator address properties (balance, code, code size). No more cold-access penalty for MEV payments. |
| Pre-merge vs. post-merge | Pre-merge: miner’s etherbase. Post-merge: validator’s fee recipient. | Semantic shift from “proof-of-work miner” to “proof-of-stake proposer.” Same opcode, different trust model. |
Real-World Exploits
Exploit 1: Fomo3D — Miner Manipulation of Block Variables to Win Jackpot (~$3M, August 2018)
Root cause: The Fomo3D game’s round timer could be exploited by a player who could prevent other players’ transactions from being included in blocks. While the attack primarily relied on gas manipulation rather than block.coinbase directly, it demonstrated that block producers will actively exploit block-level control when sufficient value is at stake.
Details: Fomo3D was a game where the last player to buy a “key” before a countdown timer expired won the pot. The timer reset with each key purchase. The attacker deployed smart contracts that conditionally consumed massive amounts of gas (up to 4.2M gas per transaction via assert() failures) to fill blocks and prevent other players’ key purchases from being included. The attack contracts checked block.coinbase and game state to decide when to activate, coordinating with multiple mining pools (SparkPool, Nanopool, Ethermine, BitClubPool) that unknowingly prioritized the attacker’s high-fee transactions.
The attacker held the last key purchase while flooding blocks with gas-consuming transactions for approximately 11 consecutive blocks, preventing timer resets. The timer expired with the attacker as the last buyer, winning 10,469.66 ETH (~$3M at the time).
COINBASE’s role: The attack contracts used block.coinbase as part of their conditional logic to determine whether to activate the gas-consuming attack based on which mining pool was producing the block. More broadly, the exploit proved that block-level variables (COINBASE, TIMESTAMP, gas limits) are manipulable inputs that game-theoretically rational miners/validators will exploit.
Impact: ~$3M jackpot stolen. Established the precedent that block producers are active adversaries for any contract logic depending on block-level variables.
References:
Exploit 2: MEV-Boost Relay Attack — Rogue Validator Steals $25M from Sandwich Bots (April 2023)
Root cause: A vulnerability in the Flashbots mev-boost-relay allowed a malicious validator to view block contents after signing a block header, enabling them to extract and front-run MEV bot transactions.
Details: On April 3, 2023, a malicious validator (“Sandwich the Ripper,” address 0x3c98...8eb) exploited a flaw in the MEV-Boost relay. The attack was premeditated — the attacker began preparations on March 17, 2023, by purchasing tokens (STG, AAVE, CRV, BIT, MKR, UNI) with small amounts of ETH to identify which MEV bots would respond with sandwich attacks.
The exploit worked because the relay disclosed block bodies to proposers after they signed a block header, even when the header was invalid. The malicious validator used this access to see the sandwich bots’ transactions, then replaced the bots’ back-run transactions with their own, effectively reverse-sandwiching the sandwich bots. The attacker extracted ~13.4M WETH, 1.8M WBTC, and $1.7M DAI.
COINBASE’s role: The attacker was the block proposer — their address was block.coinbase for the exploited block (16964664). The sandwich bots’ contracts paid bribes to block.coinbase via direct transfer, routing the bribe payments directly to the attacker. The attacker then used their proposer privilege (block content visibility) to steal the bots’ profitable trades. The COINBASE payment mechanism ensured the attacker profited from both the bribe payments and the stolen trades.
Impact: ~$25M stolen from MEV sandwich bots in a single block. Exposed fundamental trust assumptions in the MEV-Boost relay architecture. Flashbots patched the relay to not disclose block bodies until the block was committed.
References:
- BlockSec: Harvesting MEV Bots by Exploiting Vulnerabilities in Flashbots Relay
- SolidityScan: MEV Bot Hack Analysis
- CoinDesk: Ethereum Bot Gets Attacked for $20M
Exploit 3: On-Chain Gambling Contracts Exploited via Predictable block.coinbase (2017-2019, Recurring)
Root cause: Multiple Ethereum gambling and lottery contracts used block.coinbase (often combined with block.timestamp, block.number, and blockhash) as a source of randomness for determining winners. Miners could predict or influence the outcomes.
Details: During 2017-2019, dozens of on-chain gambling DApps used patterns like:
uint256 random = uint256(keccak256(abi.encodePacked(
block.coinbase, block.timestamp, block.difficulty, block.number
)));Miners could choose whether to publish a block based on whether the “random” result was favorable. Since miners know block.coinbase (it’s their own address), block.timestamp (within a ~15-second range they control), and block.difficulty (deterministic), they could precompute the randomness for any block they produce. The OWASP Smart Contract Top 10 (SC08: Insecure Randomness) explicitly lists block.coinbase as an insecure randomness source.
Multiple gambling contracts were drained by miners or MEV-aware bots that computed the “random” outcome before transaction inclusion and only submitted bets when the outcome was profitable.
COINBASE’s role: block.coinbase was a key entropy source that was fully known to the block producer. Even in combination with other block variables, the resulting “randomness” was deterministic for anyone with block production rights.
Impact: Cumulative losses across multiple gambling DApps in the hundreds of ETH range. Led to the adoption of Chainlink VRF and commit-reveal schemes as industry-standard randomness solutions.
References:
Attack Scenarios
Scenario A: COINBASE-Based Access Control Bypass
// Vulnerable: Only the block producer should call this
contract VulnerableMinerReward {
mapping(address => uint256) public rewards;
function claimBlockReward() external {
// VULNERABLE: Any validator can set their fee recipient
// to their own address and include this call in their block
require(msg.sender == block.coinbase, "only block producer");
rewards[msg.sender] += 1 ether;
}
}
// Attack: Validator sets fee_recipient = their_address in client config,
// then includes a transaction calling claimBlockReward() in their block.
// msg.sender == block.coinbase is trivially satisfied.
// Cost: only the 32 ETH validator stake to propose blocks.Scenario B: Reentrancy via block.coinbase.call (MEV Payment)
contract VulnerableSearcher {
function executeArbitrage(
address buyDex,
address sellDex,
address token,
uint256 amount
) external {
uint256 balanceBefore = address(this).balance;
// Execute the arbitrage trade
_buy(buyDex, token, amount);
_sell(sellDex, token);
uint256 profit = address(this).balance - balanceBefore;
require(profit > 0, "no profit");
// VULNERABLE: If block.coinbase is a contract, this gives
// execution control to the validator's contract, which can
// reenter executeArbitrage() or call other functions
uint256 bribe = profit / 2;
(bool ok,) = block.coinbase.call{value: bribe}("");
require(ok, "bribe failed");
}
// Attacker (validator with a contract as fee recipient):
// The validator's contract reenters executeArbitrage() during
// the bribe payment, or calls a withdraw function on the searcher
// contract before the profit accounting completes.
}
contract MaliciousValidator {
VulnerableSearcher target;
receive() external payable {
// Reenter during bribe payment
if (address(target).balance > 0) {
target.executeArbitrage(/* ... */);
}
}
}Scenario C: COINBASE as Broken Randomness
contract VulnerableLottery {
uint256 public pot;
address[] public players;
function enter() external payable {
require(msg.value == 0.1 ether);
players.push(msg.sender);
}
function draw() external {
require(players.length >= 10);
// VULNERABLE: block.coinbase is known to the block producer.
// Combined with other block variables, the hash is fully
// predictable to the validator proposing this block.
uint256 seed = uint256(keccak256(abi.encodePacked(
block.coinbase,
block.timestamp,
block.prevrandao
)));
uint256 winnerIndex = seed % players.length;
payable(players[winnerIndex]).transfer(address(this).balance);
delete players;
}
// Attack: A validator enters the lottery, then waits until they
// are scheduled to propose a block. They precompute the seed for
// every possible fee_recipient address and choose one that makes
// them the winner. They include the draw() transaction in their block.
}Scenario D: L2 COINBASE Static Value Exploit
// Contract assumes COINBASE rotates like L1
contract MultiChainGovernance {
mapping(address => bool) public hasVotedThisBlock;
function vote(uint256 proposalId) external {
// Intended: use block.coinbase as a per-block entropy source
// to prevent ballot stuffing (different "random" seed each block)
bytes32 voteSlot = keccak256(abi.encodePacked(
block.coinbase, proposalId
));
require(!usedSlots[voteSlot], "slot used");
usedSlots[voteSlot] = true;
_recordVote(msg.sender, proposalId);
}
mapping(bytes32 => bool) usedSlots;
// On L1: block.coinbase changes per block, so voteSlot varies.
// On Optimism/Base: block.coinbase is ALWAYS the SequencerFeeVault
// address, so voteSlot is deterministic per proposalId.
// Only one vote per proposalId is ever possible -- governance is broken.
}Mitigations
| Threat | Mitigation | Implementation |
|---|---|---|
| T1: Validator-controlled value in logic | Never branch contract logic on block.coinbase | Remove all conditional checks against block.coinbase; use msg.sender or signed messages for identity |
| T2: Reentrancy via COINBASE payment | Use transfer() (2300 gas limit) or reentrancy guards | block.coinbase.transfer(amount) limits gas; add OpenZeppelin ReentrancyGuard to searcher contracts |
| T2: Failed bribe reverts bundle | Wrap COINBASE payment in try/catch or use low-level call with failure tolerance | (bool ok,) = block.coinbase.call{value: bribe}(""); // don't require(ok) if bribe failure is acceptable |
| T3: COINBASE for randomness | Use verifiable randomness (Chainlink VRF) or commit-reveal schemes | Chainlink VRF v2+ for provably fair randomness; commit-reveal with user-provided entropy for lower-stakes use cases |
| T4: L2 COINBASE divergence | Abstract block.coinbase access behind a chain-aware wrapper | Check block.chainid and use chain-specific logic; never assume COINBASE rotates across chains |
| T5: COINBASE-based access control | Replace with proper access control (msg.sender, roles, multi-sig) | OpenZeppelin AccessControl or Ownable; never use block.coinbase as an identity primitive |
| T2: Smart contract COINBASE | Check if COINBASE is a contract before transferring | if (block.coinbase.code.length > 0) { /* handle contract case */ } or always use transfer() with 2300 gas |
| General: MEV bribe safety | Use proven MEV payment patterns from Flashbots | Follow Flashbots’ recommended coinbase payment patterns; cap bribe amounts; validate profitability before and after payment |
Compiler/EIP-Based Protections
- EIP-3651 (Warm COINBASE, Shanghai 2023): Makes COINBASE warm from transaction start. Reduces gas cost for COINBASE interactions but does not change security semantics. Contracts no longer need to include COINBASE in EIP-2930 access lists.
- EIP-4399 / PREVRANDAO (Paris, The Merge): Replaced
block.difficultywithblock.prevrandaoas a source of in-protocol randomness. While not directly related to COINBASE, contracts should useblock.prevrandao(or better, Chainlink VRF) instead of COINBASE for any entropy needs. - Chainlink VRF v2+: Industry-standard solution for provably fair on-chain randomness. Eliminates the need to use any block-level variable (COINBASE, TIMESTAMP, PREVRANDAO) for entropy.
- Solidity >= 0.8.0:
block.coinbaseis typed asaddress payable, allowing direct.transfer()and.send()without casting. The 2300-gas stipend limit on.transfer()provides a natural reentrancy barrier for COINBASE payments.
Severity Summary
| Threat ID | Category | Severity | Likelihood | Real-World Precedent |
|---|---|---|---|---|
| T1 | Smart Contract | High | Medium | Fomo3D miner manipulation ($3M) |
| T2 | Smart Contract | High | High | MEV-Boost relay attack ($25M from bots), Flashbots reentrancy warnings |
| T3 | Smart Contract | Critical | High | Dozens of gambling DApps drained (2017-2019), OWASP SC08 |
| T4 | Smart Contract | Medium | Medium | L2 COINBASE semantic divergence (ongoing cross-chain deployment issue) |
| T5 | Smart Contract | Critical | Medium | No single large exploit, but trivially exploitable by any validator (32 ETH) |
| P1 | Protocol | Low | N/A | EIP-3651 gas reduction (Shanghai) |
| P2 | Protocol | Medium | Medium | PBS builder/proposer identity confusion; ePBS roadmap changes |
Related Opcodes
| Opcode | Relationship |
|---|---|
| BLOCKHASH (0x40) | Returns the hash of a recent block (up to 256 blocks ago). Like COINBASE, sometimes misused for randomness. BLOCKHASH is not known to the proposer in advance (unlike COINBASE), but it is predictable to MEV searchers within the same block. |
| TIMESTAMP (0x42) | Returns the current block’s timestamp. Like COINBASE, set by the block proposer within protocol constraints (~15s range). Commonly combined with COINBASE in broken randomness patterns. |
| NUMBER (0x43) | Returns the current block number. Deterministic and predictable. Often combined with COINBASE in pseudo-randomness schemes. |
| PREVRANDAO (0x44) | Returns the previous block’s RANDAO mix (replaced DIFFICULTY post-merge). Provides better entropy than COINBASE but is still biasable by the proposer (they can choose not to propose). Preferred over COINBASE for any randomness need. |
| BASEFEE (0x48) | Returns the current block’s base fee. Another block-level value set by the protocol (not the proposer). Unlike COINBASE, BASEFEE is deterministic from the parent block and cannot be manipulated by the proposer. |