Predeploy contracts deployed at fixed addresses on Optimism L2 that provide essential system functionality including gas pricing, message passing, fee collection, whitelist management, and L1 block information.
Contract Path: L2/predeploys/OVM_GasPriceOracle.sol
Predeploy Address: 0x420000000000000000000000000000000000000F
Provides L1 gas pricing data for calculating the L1 portion of transaction fees on L2.
contract OVM_GasPriceOracle {
function gasPrice() external view returns (uint256);
function l1BaseFee() external view returns (uint256);
function overhead() external view returns (uint256);
function scalar() external view returns (uint256);
function decimals() external view returns (uint256);
function getL1Fee(bytes memory _data) external view returns (uint256);
function getL1GasUsed(bytes memory _data) external view returns (uint256);
// Owner functions
function setGasPrice(uint256 _gasPrice) external;
function setL1BaseFee(uint256 _baseFee) external;
function setOverhead(uint256 _overhead) external;
function setScalar(uint256 _scalar) external;
function setDecimals(uint256 _decimals) external;
}Returns the current L2 gas price.
Returns: uint256 - Current L2 gas price in wei
Returns the L1 base fee used for L1 cost calculations.
Returns: uint256 - L1 base fee in wei
Returns the overhead value used in L1 cost calculation.
Returns: uint256 - Overhead value
Returns the scalar value used to scale L1 costs.
Returns: uint256 - Scalar value
Returns the number of decimals used in scalar calculations.
Returns: uint256 - Number of decimals
Calculates the L1 data fee for a given transaction.
Parameters:
_data (bytes): Transaction data to calculate fee forReturns: uint256 - L1 fee in wei
Usage:
// Calculate L1 fee for transaction data
bytes memory txData = abi.encodeWithSignature("transfer(address,uint256)", to, amount);
uint256 l1Fee = oracle.getL1Fee(txData);Calculates the L1 gas usage for transaction data.
Parameters:
_data (bytes): Transaction data to calculate gas forReturns: uint256 - L1 gas units used
Sets the L2 gas price (owner only).
Parameters:
_gasPrice (uint256): New L2 gas price in weiSets the L1 base fee (owner only).
Parameters:
_baseFee (uint256): New L1 base fee in weiSets the overhead value (owner only).
Parameters:
_overhead (uint256): New overhead valueSets the scalar value (owner only).
Parameters:
_scalar (uint256): New scalar valueSets the decimals value (owner only).
Parameters:
_decimals (uint256): New decimals valueevent GasPriceUpdated(uint256 _gasPrice);
event L1BaseFeeUpdated(uint256 _l1BaseFee);
event OverheadUpdated(uint256 _overhead);
event ScalarUpdated(uint256 _scalar);
event DecimalsUpdated(uint256 _decimals);Contract Path: L2/predeploys/OVM_L2ToL1MessagePasser.sol
Predeploy Address: 0x4200000000000000000000000000000000000000
Passes messages from L2 to L1 by storing them in the L2 state for inclusion in withdrawal proofs.
contract OVM_L2ToL1MessagePasser {
function passMessageToL1(bytes memory _message) external;
function sentMessages(bytes32 _msgHash) external view returns (bool);
}Passes a message from L2 to L1 by storing it for proof generation.
Parameters:
_message (bytes): Message data to pass to L1Events Emitted:
L2ToL1Message(uint256 _nonce, address _sender, bytes _data)Usage:
// Pass message to L1
bytes memory message = abi.encode(recipient, amount, data);
messagePasser.passMessageToL1(message);Checks if a message hash has been sent.
Parameters:
_msgHash (bytes32): Hash of the message to checkReturns: bool - True if message was sent
event L2ToL1Message(
uint256 indexed _nonce,
address indexed _sender,
bytes _data
);Contract Path: L2/predeploys/OVM_SequencerFeeVault.sol
Predeploy Address: 0x4200000000000000000000000000000000000011
Collects sequencer fees and facilitates withdrawal to L1 when a threshold is reached.
constructor(address _recipient);Parameters:
_recipient (address): L1 address to receive withdrawn feescontract OVM_SequencerFeeVault {
function withdraw() external;
function l1FeeWallet() external view returns (address);
}Withdraws collected fees to L1 when the threshold balance is reached.
Usage:
// Anyone can trigger withdrawal if threshold is met
vault.withdraw();Returns the L1 address that receives withdrawn fees.
Returns: address - L1 recipient address
Contract Path: L2/predeploys/OVM_DeployerWhitelist.sol
Predeploy Address: 0x4200000000000000000000000000000000000002
Manages the deployment whitelist when contract deployment restrictions are enabled.
contract OVM_DeployerWhitelist {
function enableArbitraryContractDeployment() external;
function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external;
function setOwner(address _newOwner) external;
function isDeployerAllowed(address _deployer) external view returns (bool);
function owner() external view returns (address);
function arbitraryContractDeploymentAllowed() external view returns (bool);
}Permanently disables the whitelist, allowing anyone to deploy contracts (owner only).
Sets the whitelist status for a specific deployer (owner only).
Parameters:
_deployer (address): Address to set whitelist status for_isWhitelisted (bool): Whether the deployer should be whitelistedTransfers ownership of the whitelist (owner only).
Parameters:
_newOwner (address): New owner addressChecks if a deployer is allowed to deploy contracts.
Parameters:
_deployer (address): Address to checkReturns: bool - True if deployment is allowed
Usage:
// Check if deployment is allowed
require(
whitelist.isDeployerAllowed(msg.sender),
"Deployment not allowed"
);event OwnerChanged(address oldOwner, address newOwner);
event WhitelistStatusChanged(address deployer, bool whitelisted);
event WhitelistDisabled(address oldOwner);Contract Path: L2/predeploys/OVM_L1BlockNumber.sol
Predeploy Address: 0x4200000000000000000000000000000000000013
Provides the current L1 block number to L2 contracts.
contract OVM_L1BlockNumber {
function getL1BlockNumber() external view returns (uint256);
}Returns the latest L1 block number known to L2.
Returns: uint256 - Current L1 block number
Usage:
// Get current L1 block number
uint256 l1BlockNumber = l1BlockNumber.getL1BlockNumber();Contract Path: L2/predeploys/WETH9.sol
Predeploy Address: 0x4200000000000000000000000000000000000006
Standard Wrapped Ether contract deployed on L2.
contract WETH9 {
function deposit() external payable;
function withdraw(uint256 wad) external;
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
// Standard ERC20 functions
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}Deposits ETH and mints WETH tokens.
Usage:
// Deposit 1 ETH and receive 1 WETH
weth.deposit{value: 1 ether}();Burns WETH tokens and returns ETH.
Parameters:
wad (uint256): Amount of WETH to burn and withdraw as ETHUsage:
// Withdraw 1 ETH by burning 1 WETH
weth.withdraw(1 ether);event Deposit(address indexed dst, uint256 wad);
event Withdrawal(address indexed src, uint256 wad);Contract Path: L2/predeploys/OVM_ETH.sol
Predeploy Address: 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000 (disabled)
Native ETH representation on L2 (currently disabled in favor of WETH9).
contract OVM_ETH {
// Extends L2StandardERC20
function mint(address _to, uint256 _amount) external;
function burn(address _from, uint256 _amount) external;
// Standard ERC20 functions inherited from L2StandardERC20
}Note: This contract is currently disabled and replaced by WETH9 at address 0x4200000000000000000000000000000000000006.
contract FeeCalculator {
IOVMGasPriceOracle constant oracle = IOVMGasPriceOracle(0x420000000000000000000000000000000000000F);
function calculateTotalFee(bytes memory txData, uint256 gasUsed)
external
view
returns (uint256)
{
uint256 l2Fee = gasUsed * oracle.gasPrice();
uint256 l1Fee = oracle.getL1Fee(txData);
return l2Fee + l1Fee;
}
function estimateL1Cost(bytes memory callData) external view returns (uint256) {
return oracle.getL1Fee(callData);
}
}contract L2Notifier {
address constant MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;
function sendNotificationToL1(address recipient, uint256 value) external {
bytes memory message = abi.encode(recipient, value, block.timestamp);
// This will be included in the L2 state for withdrawal proof
IOVMMessagePasser(MESSAGE_PASSER).passMessageToL1(message);
}
}contract DeploymentManager {
address constant WHITELIST = 0x4200000000000000000000000000000000000002;
modifier onlyAllowedDeployer() {
require(
IOVMDeployerWhitelist(WHITELIST).isDeployerAllowed(msg.sender),
"Deployment not permitted"
);
_;
}
function deployContract(bytes memory bytecode)
external
onlyAllowedDeployer
returns (address)
{
address deployed;
assembly {
deployed := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
}
return deployed;
}
}contract WETHManager {
IWETH9 constant weth = IWETH9(0x4200000000000000000000000000000000000006);
function wrapETH() external payable {
weth.deposit{value: msg.value}();
weth.transfer(msg.sender, msg.value);
}
function unwrapWETH(uint256 amount) external {
weth.transferFrom(msg.sender, address(this), amount);
weth.withdraw(amount);
payable(msg.sender).transfer(amount);
}
}contract TimeBasedContract {
address constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;
function getL1BlockInfo() external view returns (uint256) {
return IOVMBlockNumber(L1_BLOCK_NUMBER).getL1BlockNumber();
}
function isL1BlockRecent(uint256 maxAge) external view returns (bool) {
uint256 currentL1Block = IOVMBlockNumber(L1_BLOCK_NUMBER).getL1BlockNumber();
return (currentL1Block >= maxAge);
}
}