Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SequencerFeeVault
Compiler Version
v0.8.15+commit.e14f2714
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { FeeVault } from "src/universal/FeeVault.sol";
/// @custom:proxied true
/// @custom:predeploy 0x4200000000000000000000000000000000000011
/// @title SequencerFeeVault
/// @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during
/// transaction processing and block production.
contract SequencerFeeVault is FeeVault, ISemver {
/// @custom:semver 1.5.0-beta.2
string public constant version = "1.5.0-beta.2";
/// @notice Constructs the SequencerFeeVault contract.
/// @param _recipient Wallet that will receive the fees.
/// @param _minWithdrawalAmount Minimum balance for withdrawals.
/// @param _withdrawalNetwork Network which the recipient will receive fees on.
constructor(
address _recipient,
uint256 _minWithdrawalAmount,
WithdrawalNetwork _withdrawalNetwork
)
FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork)
{ }
/// @custom:legacy
/// @notice Legacy getter for the recipient address.
/// @return The recipient address.
function l1FeeWallet() public view returns (address) {
return RECIPIENT;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Types } from "src/libraries/Types.sol";
import { Hashing } from "src/libraries/Hashing.sol";
import { Encoding } from "src/libraries/Encoding.sol";
import { Burn } from "src/libraries/Burn.sol";
import { ISemver } from "src/universal/interfaces/ISemver.sol";
/// @custom:proxied true
/// @custom:predeploy 0x4200000000000000000000000000000000000016
/// @title L2ToL1MessagePasser
/// @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from
/// L2 to L1 can be stored. The storage root of this contract is pulled up to the top level
/// of the L2 output to reduce the cost of proving the existence of sent messages.
contract L2ToL1MessagePasser is ISemver {
/// @notice The L1 gas limit set when eth is withdrawn using the receive() function.
uint256 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;
/// @notice The current message version identifier.
uint16 public constant MESSAGE_VERSION = 1;
/// @notice Includes the message hashes for all withdrawals
mapping(bytes32 => bool) public sentMessages;
/// @notice A unique value hashed with each withdrawal.
uint240 internal msgNonce;
/// @notice Emitted any time a withdrawal is initiated.
/// @param nonce Unique value corresponding to each withdrawal.
/// @param sender The L2 account address which initiated the withdrawal.
/// @param target The L1 account address the call will be send to.
/// @param value The ETH value submitted for withdrawal, to be forwarded to the target.
/// @param gasLimit The minimum amount of gas that must be provided when withdrawing.
/// @param data The data to be forwarded to the target on L1.
/// @param withdrawalHash The hash of the withdrawal.
event MessagePassed(
uint256 indexed nonce,
address indexed sender,
address indexed target,
uint256 value,
uint256 gasLimit,
bytes data,
bytes32 withdrawalHash
);
/// @notice Emitted when the balance of this contract is burned.
/// @param amount Amount of ETh that was burned.
event WithdrawerBalanceBurnt(uint256 indexed amount);
/// @custom:semver 1.1.1-beta.1
string public constant version = "1.1.1-beta.1";
/// @notice Allows users to withdraw ETH by sending directly to this contract.
receive() external payable {
initiateWithdrawal(msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(""));
}
/// @notice Removes all ETH held by this contract from the state. Used to prevent the amount of
/// ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to
/// create a contract and self-destruct it to itself. Anyone can call this function. Not
/// incentivized since this function is very cheap.
function burn() external {
uint256 balance = address(this).balance;
Burn.eth(balance);
emit WithdrawerBalanceBurnt(balance);
}
/// @notice Sends a message from L2 to L1.
/// @param _target Address to call on L1 execution.
/// @param _gasLimit Minimum gas limit for executing the message on L1.
/// @param _data Data to forward to L1 target.
function initiateWithdrawal(address _target, uint256 _gasLimit, bytes memory _data) public payable {
bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({
nonce: messageNonce(),
sender: msg.sender,
target: _target,
value: msg.value,
gasLimit: _gasLimit,
data: _data
})
);
sentMessages[withdrawalHash] = true;
emit MessagePassed(messageNonce(), msg.sender, _target, msg.value, _gasLimit, _data, withdrawalHash);
unchecked {
++msgNonce;
}
}
/// @notice Retrieves the next message nonce. Message version will be added to the upper two
/// bytes of the message nonce. Message version allows us to treat messages as having
/// different structures.
/// @return Nonce of the next message to be sent, with added message version.
function messageNonce() public view returns (uint256) {
return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
/// @title Burn
/// @notice Utilities for burning stuff.
library Burn {
/// @notice Burns a given amount of ETH.
/// @param _amount Amount of ETH to burn.
function eth(uint256 _amount) internal {
new Burner{ value: _amount }();
}
/// @notice Burns a given amount of gas.
/// @param _amount Amount of gas to burn.
function gas(uint256 _amount) internal view {
uint256 i = 0;
uint256 initialGas = gasleft();
while (initialGas - gasleft() < _amount) {
++i;
}
}
}
/// @title Burner
/// @notice Burner self-destructs on creation and sends all ETH to itself, removing all ETH given to
/// the contract from the circulating supply. Self-destructing is the only way to remove ETH
/// from the circulating supply.
contract Burner {
constructor() payable {
selfdestruct(payable(address(this)));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { Types } from "src/libraries/Types.sol";
import { Hashing } from "src/libraries/Hashing.sol";
import { RLPWriter } from "src/libraries/rlp/RLPWriter.sol";
/// @title Encoding
/// @notice Encoding handles Optimism's various different encoding schemes.
library Encoding {
/// @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent
/// to the L2 system. Useful for searching for a deposit in the L2 system. The
/// transaction is prefixed with 0x7e to identify its EIP-2718 type.
/// @param _tx User deposit transaction to encode.
/// @return RLP encoded L2 deposit transaction.
function encodeDepositTransaction(Types.UserDepositTransaction memory _tx) internal pure returns (bytes memory) {
bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);
bytes[] memory raw = new bytes[](8);
raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));
raw[1] = RLPWriter.writeAddress(_tx.from);
raw[2] = _tx.isCreation ? RLPWriter.writeBytes("") : RLPWriter.writeAddress(_tx.to);
raw[3] = RLPWriter.writeUint(_tx.mint);
raw[4] = RLPWriter.writeUint(_tx.value);
raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));
raw[6] = RLPWriter.writeBool(false);
raw[7] = RLPWriter.writeBytes(_tx.data);
return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));
}
/// @notice Encodes the cross domain message based on the version that is encoded into the
/// message nonce.
/// @param _nonce Message nonce with version encoded into the first two bytes.
/// @param _sender Address of the sender of the message.
/// @param _target Address of the target of the message.
/// @param _value ETH value to send to the target.
/// @param _gasLimit Gas limit to use for the message.
/// @param _data Data to send with the message.
/// @return Encoded cross domain message.
function encodeCrossDomainMessage(
uint256 _nonce,
address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
bytes memory _data
)
internal
pure
returns (bytes memory)
{
(, uint16 version) = decodeVersionedNonce(_nonce);
if (version == 0) {
return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);
} else if (version == 1) {
return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);
} else {
revert("Encoding: unknown cross domain message version");
}
}
/// @notice Encodes a cross domain message based on the V0 (legacy) encoding.
/// @param _target Address of the target of the message.
/// @param _sender Address of the sender of the message.
/// @param _data Data to send with the message.
/// @param _nonce Message nonce.
/// @return Encoded cross domain message.
function encodeCrossDomainMessageV0(
address _target,
address _sender,
bytes memory _data,
uint256 _nonce
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSignature("relayMessage(address,address,bytes,uint256)", _target, _sender, _data, _nonce);
}
/// @notice Encodes a cross domain message based on the V1 (current) encoding.
/// @param _nonce Message nonce.
/// @param _sender Address of the sender of the message.
/// @param _target Address of the target of the message.
/// @param _value ETH value to send to the target.
/// @param _gasLimit Gas limit to use for the message.
/// @param _data Data to send with the message.
/// @return Encoded cross domain message.
function encodeCrossDomainMessageV1(
uint256 _nonce,
address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
bytes memory _data
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSignature(
"relayMessage(uint256,address,address,uint256,uint256,bytes)",
_nonce,
_sender,
_target,
_value,
_gasLimit,
_data
);
}
/// @notice Adds a version number into the first two bytes of a message nonce.
/// @param _nonce Message nonce to encode into.
/// @param _version Version number to encode into the message nonce.
/// @return Message nonce with version encoded into the first two bytes.
function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {
uint256 nonce;
assembly {
nonce := or(shl(240, _version), _nonce)
}
return nonce;
}
/// @notice Pulls the version out of a version-encoded nonce.
/// @param _nonce Message nonce with version encoded into the first two bytes.
/// @return Nonce without encoded version.
/// @return Version of the message.
function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {
uint240 nonce;
uint16 version;
assembly {
nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
version := shr(240, _nonce)
}
return (nonce, version);
}
/// @notice Returns an appropriately encoded call to L1Block.setL1BlockValuesEcotone
/// @param baseFeeScalar L1 base fee Scalar
/// @param blobBaseFeeScalar L1 blob base fee Scalar
/// @param sequenceNumber Number of L2 blocks since epoch start.
/// @param timestamp L1 timestamp.
/// @param number L1 blocknumber.
/// @param baseFee L1 base fee.
/// @param blobBaseFee L1 blob base fee.
/// @param hash L1 blockhash.
/// @param batcherHash Versioned hash to authenticate batcher by.
function encodeSetL1BlockValuesEcotone(
uint32 baseFeeScalar,
uint32 blobBaseFeeScalar,
uint64 sequenceNumber,
uint64 timestamp,
uint64 number,
uint256 baseFee,
uint256 blobBaseFee,
bytes32 hash,
bytes32 batcherHash
)
internal
pure
returns (bytes memory)
{
bytes4 functionSignature = bytes4(keccak256("setL1BlockValuesEcotone()"));
return abi.encodePacked(
functionSignature,
baseFeeScalar,
blobBaseFeeScalar,
sequenceNumber,
timestamp,
number,
baseFee,
blobBaseFee,
hash,
batcherHash
);
}
/// @notice Returns an appropriately encoded call to L1Block.setL1BlockValuesInterop
/// @param _baseFeeScalar L1 base fee Scalar
/// @param _blobBaseFeeScalar L1 blob base fee Scalar
/// @param _sequenceNumber Number of L2 blocks since epoch start.
/// @param _timestamp L1 timestamp.
/// @param _number L1 blocknumber.
/// @param _baseFee L1 base fee.
/// @param _blobBaseFee L1 blob base fee.
/// @param _hash L1 blockhash.
/// @param _batcherHash Versioned hash to authenticate batcher by.
/// @param _dependencySet Array of the chain IDs in the interop dependency set.
function encodeSetL1BlockValuesInterop(
uint32 _baseFeeScalar,
uint32 _blobBaseFeeScalar,
uint64 _sequenceNumber,
uint64 _timestamp,
uint64 _number,
uint256 _baseFee,
uint256 _blobBaseFee,
bytes32 _hash,
bytes32 _batcherHash,
uint256[] memory _dependencySet
)
internal
pure
returns (bytes memory)
{
require(_dependencySet.length <= type(uint8).max, "Encoding: dependency set length is too large");
// Check that the batcher hash is just the address with 0 padding to the left for version 0.
require(uint160(uint256(_batcherHash)) == uint256(_batcherHash), "Encoding: invalid batcher hash");
bytes4 functionSignature = bytes4(keccak256("setL1BlockValuesInterop()"));
return abi.encodePacked(
functionSignature,
_baseFeeScalar,
_blobBaseFeeScalar,
_sequenceNumber,
_timestamp,
_number,
_baseFee,
_blobBaseFee,
_hash,
_batcherHash,
uint8(_dependencySet.length),
_dependencySet
);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { Types } from "src/libraries/Types.sol";
import { Encoding } from "src/libraries/Encoding.sol";
/// @title Hashing
/// @notice Hashing handles Optimism's various different hashing schemes.
library Hashing {
/// @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a
/// given deposit is sent to the L2 system. Useful for searching for a deposit in the L2
/// system.
/// @param _tx User deposit transaction to hash.
/// @return Hash of the RLP encoded L2 deposit transaction.
function hashDepositTransaction(Types.UserDepositTransaction memory _tx) internal pure returns (bytes32) {
return keccak256(Encoding.encodeDepositTransaction(_tx));
}
/// @notice Computes the deposit transaction's "source hash", a value that guarantees the hash
/// of the L2 transaction that corresponds to a deposit is unique and is
/// deterministically generated from L1 transaction data.
/// @param _l1BlockHash Hash of the L1 block where the deposit was included.
/// @param _logIndex The index of the log that created the deposit transaction.
/// @return Hash of the deposit transaction's "source hash".
function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex) internal pure returns (bytes32) {
bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));
return keccak256(abi.encode(bytes32(0), depositId));
}
/// @notice Hashes the cross domain message based on the version that is encoded into the
/// message nonce.
/// @param _nonce Message nonce with version encoded into the first two bytes.
/// @param _sender Address of the sender of the message.
/// @param _target Address of the target of the message.
/// @param _value ETH value to send to the target.
/// @param _gasLimit Gas limit to use for the message.
/// @param _data Data to send with the message.
/// @return Hashed cross domain message.
function hashCrossDomainMessage(
uint256 _nonce,
address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
bytes memory _data
)
internal
pure
returns (bytes32)
{
(, uint16 version) = Encoding.decodeVersionedNonce(_nonce);
if (version == 0) {
return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);
} else if (version == 1) {
return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);
} else {
revert("Hashing: unknown cross domain message version");
}
}
/// @notice Hashes a cross domain message based on the V0 (legacy) encoding.
/// @param _target Address of the target of the message.
/// @param _sender Address of the sender of the message.
/// @param _data Data to send with the message.
/// @param _nonce Message nonce.
/// @return Hashed cross domain message.
function hashCrossDomainMessageV0(
address _target,
address _sender,
bytes memory _data,
uint256 _nonce
)
internal
pure
returns (bytes32)
{
return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));
}
/// @notice Hashes a cross domain message based on the V1 (current) encoding.
/// @param _nonce Message nonce.
/// @param _sender Address of the sender of the message.
/// @param _target Address of the target of the message.
/// @param _value ETH value to send to the target.
/// @param _gasLimit Gas limit to use for the message.
/// @param _data Data to send with the message.
/// @return Hashed cross domain message.
function hashCrossDomainMessageV1(
uint256 _nonce,
address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
bytes memory _data
)
internal
pure
returns (bytes32)
{
return keccak256(Encoding.encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data));
}
/// @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract
/// @param _tx Withdrawal transaction to hash.
/// @return Hashed withdrawal transaction.
function hashWithdrawal(Types.WithdrawalTransaction memory _tx) internal pure returns (bytes32) {
return keccak256(abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data));
}
/// @notice Hashes the various elements of an output root proof into an output root hash which
/// can be used to check if the proof is valid.
/// @param _outputRootProof Output root proof which should hash to an output root.
/// @return Hashed output root proof.
function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof) internal pure returns (bytes32) {
return keccak256(
abi.encode(
_outputRootProof.version,
_outputRootProof.stateRoot,
_outputRootProof.messagePasserStorageRoot,
_outputRootProof.latestBlockhash
)
);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title Predeploys
/// @notice Contains constant addresses for protocol contracts that are pre-deployed to the L2 system.
// This excludes the preinstalls (non-protocol contracts).
library Predeploys {
/// @notice Number of predeploy-namespace addresses reserved for protocol usage.
uint256 internal constant PREDEPLOY_COUNT = 2048;
/// @custom:legacy
/// @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated
/// L2ToL1MessagePasser contract instead.
address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;
/// @custom:legacy
/// @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger
/// or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.
/// Not embedded into new OP-Stack chains.
address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;
/// @custom:legacy
/// @notice Address of the DeployerWhitelist predeploy. No longer active.
address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;
/// @notice Address of the canonical WETH contract.
address internal constant WETH = 0x4200000000000000000000000000000000000006;
/// @notice Address of the L2CrossDomainMessenger predeploy.
address internal constant L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000007;
/// @notice Address of the GasPriceOracle predeploy. Includes fee information
/// and helpers for computing the L1 portion of the transaction fee.
address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F;
/// @notice Address of the L2StandardBridge predeploy.
address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;
//// @notice Address of the SequencerFeeWallet predeploy.
address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;
/// @notice Address of the OptimismMintableERC20Factory predeploy.
address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY = 0x4200000000000000000000000000000000000012;
/// @custom:legacy
/// @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy
/// instead, which exposes more information about the L1 state.
address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;
/// @notice Address of the L2ERC721Bridge predeploy.
address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014;
/// @notice Address of the L1Block predeploy.
address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;
/// @notice Address of the L2ToL1MessagePasser predeploy.
address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;
/// @notice Address of the OptimismMintableERC721Factory predeploy.
address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY = 0x4200000000000000000000000000000000000017;
/// @notice Address of the ProxyAdmin predeploy.
address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;
/// @notice Address of the BaseFeeVault predeploy.
address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;
/// @notice Address of the L1FeeVault predeploy.
address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;
/// @notice Address of the SchemaRegistry predeploy.
address internal constant SCHEMA_REGISTRY = 0x4200000000000000000000000000000000000020;
/// @notice Address of the EAS predeploy.
address internal constant EAS = 0x4200000000000000000000000000000000000021;
/// @notice Address of the GovernanceToken predeploy.
address internal constant GOVERNANCE_TOKEN = 0x4200000000000000000000000000000000000042;
/// @custom:legacy
/// @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the
/// state trie as of the Bedrock upgrade. Contract has been locked and write functions
/// can no longer be accessed.
address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;
/// @notice Address of the CrossL2Inbox predeploy.
address internal constant CROSS_L2_INBOX = 0x4200000000000000000000000000000000000022;
/// @notice Address of the L2ToL2CrossDomainMessenger predeploy.
address internal constant L2_TO_L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000023;
/// @notice Address of the SuperchainWETH predeploy.
address internal constant SUPERCHAIN_WETH = 0x4200000000000000000000000000000000000024;
/// @notice Address of the ETHLiquidity predeploy.
address internal constant ETH_LIQUIDITY = 0x4200000000000000000000000000000000000025;
/// TODO: Add correct predeploy address for OptimismSuperchainERC20Factory
/// @notice Address of the OptimismSuperchainERC20Factory predeploy.
address internal constant OPTIMISM_SUPERCHAIN_ERC20_FACTORY = 0x4200000000000000000000000000000000000026;
/// @notice Returns the name of the predeploy at the given address.
function getName(address _addr) internal pure returns (string memory out_) {
require(isPredeployNamespace(_addr), "Predeploys: address must be a predeploy");
if (_addr == LEGACY_MESSAGE_PASSER) return "LegacyMessagePasser";
if (_addr == L1_MESSAGE_SENDER) return "L1MessageSender";
if (_addr == DEPLOYER_WHITELIST) return "DeployerWhitelist";
if (_addr == WETH) return "WETH";
if (_addr == L2_CROSS_DOMAIN_MESSENGER) return "L2CrossDomainMessenger";
if (_addr == GAS_PRICE_ORACLE) return "GasPriceOracle";
if (_addr == L2_STANDARD_BRIDGE) return "L2StandardBridge";
if (_addr == SEQUENCER_FEE_WALLET) return "SequencerFeeVault";
if (_addr == OPTIMISM_MINTABLE_ERC20_FACTORY) return "OptimismMintableERC20Factory";
if (_addr == L1_BLOCK_NUMBER) return "L1BlockNumber";
if (_addr == L2_ERC721_BRIDGE) return "L2ERC721Bridge";
if (_addr == L1_BLOCK_ATTRIBUTES) return "L1Block";
if (_addr == L2_TO_L1_MESSAGE_PASSER) return "L2ToL1MessagePasser";
if (_addr == OPTIMISM_MINTABLE_ERC721_FACTORY) return "OptimismMintableERC721Factory";
if (_addr == PROXY_ADMIN) return "ProxyAdmin";
if (_addr == BASE_FEE_VAULT) return "BaseFeeVault";
if (_addr == L1_FEE_VAULT) return "L1FeeVault";
if (_addr == SCHEMA_REGISTRY) return "SchemaRegistry";
if (_addr == EAS) return "EAS";
if (_addr == GOVERNANCE_TOKEN) return "GovernanceToken";
if (_addr == LEGACY_ERC20_ETH) return "LegacyERC20ETH";
if (_addr == CROSS_L2_INBOX) return "CrossL2Inbox";
if (_addr == L2_TO_L2_CROSS_DOMAIN_MESSENGER) return "L2ToL2CrossDomainMessenger";
if (_addr == SUPERCHAIN_WETH) return "SuperchainWETH";
if (_addr == ETH_LIQUIDITY) return "ETHLiquidity";
if (_addr == OPTIMISM_SUPERCHAIN_ERC20_FACTORY) return "OptimismSuperchainERC20Factory";
revert("Predeploys: unnamed predeploy");
}
/// @notice Returns true if the predeploy is not proxied.
function notProxied(address _addr) internal pure returns (bool) {
return _addr == GOVERNANCE_TOKEN || _addr == WETH;
}
/// @notice Returns true if the address is a defined predeploy that is embedded into new OP-Stack chains.
function isSupportedPredeploy(address _addr, bool _useInterop) internal pure returns (bool) {
return _addr == LEGACY_MESSAGE_PASSER || _addr == DEPLOYER_WHITELIST || _addr == WETH
|| _addr == L2_CROSS_DOMAIN_MESSENGER || _addr == GAS_PRICE_ORACLE || _addr == L2_STANDARD_BRIDGE
|| _addr == SEQUENCER_FEE_WALLET || _addr == OPTIMISM_MINTABLE_ERC20_FACTORY || _addr == L1_BLOCK_NUMBER
|| _addr == L2_ERC721_BRIDGE || _addr == L1_BLOCK_ATTRIBUTES || _addr == L2_TO_L1_MESSAGE_PASSER
|| _addr == OPTIMISM_MINTABLE_ERC721_FACTORY || _addr == PROXY_ADMIN || _addr == BASE_FEE_VAULT
|| _addr == L1_FEE_VAULT || _addr == SCHEMA_REGISTRY || _addr == EAS || _addr == GOVERNANCE_TOKEN
|| (_useInterop && _addr == CROSS_L2_INBOX) || (_useInterop && _addr == L2_TO_L2_CROSS_DOMAIN_MESSENGER)
|| (_useInterop && _addr == SUPERCHAIN_WETH) || (_useInterop && _addr == ETH_LIQUIDITY)
|| (_useInterop && _addr == OPTIMISM_SUPERCHAIN_ERC20_FACTORY);
}
function isPredeployNamespace(address _addr) internal pure returns (bool) {
return uint160(_addr) >> 11 == uint160(0x4200000000000000000000000000000000000000) >> 11;
}
/// @notice Function to compute the expected address of the predeploy implementation
/// in the genesis state.
function predeployToCodeNamespace(address _addr) internal pure returns (address) {
require(
isPredeployNamespace(_addr), "Predeploys: can only derive code-namespace address for predeploy addresses"
);
return address(
uint160(uint256(uint160(_addr)) & 0xffff | uint256(uint160(0xc0D3C0d3C0d3C0D3c0d3C0d3c0D3C0d3c0d30000)))
);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title SafeCall
/// @notice Perform low level safe calls
library SafeCall {
/// @notice Performs a low level call without copying any returndata.
/// @dev Passes no calldata to the call context.
/// @param _target Address to call
/// @param _gas Amount of gas to pass to the call
/// @param _value Amount of value to pass to the call
function send(address _target, uint256 _gas, uint256 _value) internal returns (bool success_) {
assembly {
success_ :=
call(
_gas, // gas
_target, // recipient
_value, // ether value
0, // inloc
0, // inlen
0, // outloc
0 // outlen
)
}
}
/// @notice Perform a low level call with all gas without copying any returndata
/// @param _target Address to call
/// @param _value Amount of value to pass to the call
function send(address _target, uint256 _value) internal returns (bool success_) {
success_ = send(_target, gasleft(), _value);
}
/// @notice Perform a low level call without copying any returndata
/// @param _target Address to call
/// @param _gas Amount of gas to pass to the call
/// @param _value Amount of value to pass to the call
/// @param _calldata Calldata to pass to the call
function call(
address _target,
uint256 _gas,
uint256 _value,
bytes memory _calldata
)
internal
returns (bool success_)
{
assembly {
success_ :=
call(
_gas, // gas
_target, // recipient
_value, // ether value
add(_calldata, 32), // inloc
mload(_calldata), // inlen
0, // outloc
0 // outlen
)
}
}
/// @notice Perform a low level call without copying any returndata
/// @param _target Address to call
/// @param _value Amount of value to pass to the call
/// @param _calldata Calldata to pass to the call
function call(address _target, uint256 _value, bytes memory _calldata) internal returns (bool success_) {
success_ = call({ _target: _target, _gas: gasleft(), _value: _value, _calldata: _calldata });
}
/// @notice Helper function to determine if there is sufficient gas remaining within the context
/// to guarantee that the minimum gas requirement for a call will be met as well as
/// optionally reserving a specified amount of gas for after the call has concluded.
/// @param _minGas The minimum amount of gas that may be passed to the target context.
/// @param _reservedGas Optional amount of gas to reserve for the caller after the execution
/// of the target context.
/// @return `true` if there is enough gas remaining to safely supply `_minGas` to the target
/// context as well as reserve `_reservedGas` for the caller after the execution of
/// the target context.
/// @dev !!!!! FOOTGUN ALERT !!!!!
/// 1.) The 40_000 base buffer is to account for the worst case of the dynamic cost of the
/// `CALL` opcode's `address_access_cost`, `positive_value_cost`, and
/// `value_to_empty_account_cost` factors with an added buffer of 5,700 gas. It is
/// still possible to self-rekt by initiating a withdrawal with a minimum gas limit
/// that does not account for the `memory_expansion_cost` & `code_execution_cost`
/// factors of the dynamic cost of the `CALL` opcode.
/// 2.) This function should *directly* precede the external call if possible. There is an
/// added buffer to account for gas consumed between this check and the call, but it
/// is only 5,700 gas.
/// 3.) Because EIP-150 ensures that a maximum of 63/64ths of the remaining gas in the call
/// frame may be passed to a subcontext, we need to ensure that the gas will not be
/// truncated.
/// 4.) Use wisely. This function is not a silver bullet.
function hasMinGas(uint256 _minGas, uint256 _reservedGas) internal view returns (bool) {
bool _hasMinGas;
assembly {
// Equation: gas × 63 = minGas × 64 + 63(40_000 + reservedGas)
_hasMinGas := iszero(lt(mul(gas(), 63), add(mul(_minGas, 64), mul(add(40000, _reservedGas), 63))))
}
return _hasMinGas;
}
/// @notice Perform a low level call without copying any returndata. This function
/// will revert if the call cannot be performed with the specified minimum
/// gas.
/// @param _target Address to call
/// @param _minGas The minimum amount of gas that may be passed to the call
/// @param _value Amount of value to pass to the call
/// @param _calldata Calldata to pass to the call
function callWithMinGas(
address _target,
uint256 _minGas,
uint256 _value,
bytes memory _calldata
)
internal
returns (bool)
{
bool _success;
bool _hasMinGas = hasMinGas(_minGas, 0);
assembly {
// Assertion: gasleft() >= (_minGas * 64) / 63 + 40_000
if iszero(_hasMinGas) {
// Store the "Error(string)" selector in scratch space.
mstore(0, 0x08c379a0)
// Store the pointer to the string length in scratch space.
mstore(32, 32)
// Store the string.
//
// SAFETY:
// - We pad the beginning of the string with two zero bytes as well as the
// length (24) to ensure that we override the free memory pointer at offset
// 0x40. This is necessary because the free memory pointer is likely to
// be greater than 1 byte when this function is called, but it is incredibly
// unlikely that it will be greater than 3 bytes. As for the data within
// 0x60, it is ensured that it is 0 due to 0x60 being the zero offset.
// - It's fine to clobber the free memory pointer, we're reverting.
mstore(88, 0x0000185361666543616c6c3a204e6f7420656e6f75676820676173)
// Revert with 'Error("SafeCall: Not enough gas")'
revert(28, 100)
}
// The call will be supplied at least ((_minGas * 64) / 63) gas due to the
// above assertion. This ensures that, in all circumstances (except for when the
// `_minGas` does not account for the `memory_expansion_cost` and `code_execution_cost`
// factors of the dynamic cost of the `CALL` opcode), the call will receive at least
// the minimum amount of gas specified.
_success :=
call(
gas(), // gas
_target, // recipient
_value, // ether value
add(_calldata, 32), // inloc
mload(_calldata), // inlen
0x00, // outloc
0x00 // outlen
)
}
return _success;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title Types
/// @notice Contains various types used throughout the Optimism contract system.
library Types {
/// @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1
/// timestamp that the output root is posted. This timestamp is used to verify that the
/// finalization period has passed since the output root was submitted.
/// @custom:field outputRoot Hash of the L2 output.
/// @custom:field timestamp Timestamp of the L1 block that the output root was submitted in.
/// @custom:field l2BlockNumber L2 block number that the output corresponds to.
struct OutputProposal {
bytes32 outputRoot;
uint128 timestamp;
uint128 l2BlockNumber;
}
/// @notice Struct representing the elements that are hashed together to generate an output root
/// which itself represents a snapshot of the L2 state.
/// @custom:field version Version of the output root.
/// @custom:field stateRoot Root of the state trie at the block of this output.
/// @custom:field messagePasserStorageRoot Root of the message passer storage trie.
/// @custom:field latestBlockhash Hash of the block this output was generated from.
struct OutputRootProof {
bytes32 version;
bytes32 stateRoot;
bytes32 messagePasserStorageRoot;
bytes32 latestBlockhash;
}
/// @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end
/// user (as opposed to a system deposit transaction generated by the system).
/// @custom:field from Address of the sender of the transaction.
/// @custom:field to Address of the recipient of the transaction.
/// @custom:field isCreation True if the transaction is a contract creation.
/// @custom:field value Value to send to the recipient.
/// @custom:field mint Amount of ETH to mint.
/// @custom:field gasLimit Gas limit of the transaction.
/// @custom:field data Data of the transaction.
/// @custom:field l1BlockHash Hash of the block the transaction was submitted in.
/// @custom:field logIndex Index of the log in the block the transaction was submitted in.
struct UserDepositTransaction {
address from;
address to;
bool isCreation;
uint256 value;
uint256 mint;
uint64 gasLimit;
bytes data;
bytes32 l1BlockHash;
uint256 logIndex;
}
/// @notice Struct representing a withdrawal transaction.
/// @custom:field nonce Nonce of the withdrawal transaction
/// @custom:field sender Address of the sender of the transaction.
/// @custom:field target Address of the recipient of the transaction.
/// @custom:field value Value to send to the recipient.
/// @custom:field gasLimit Gas limit of the transaction.
/// @custom:field data Data of the transaction.
struct WithdrawalTransaction {
uint256 nonce;
address sender;
address target;
uint256 value;
uint256 gasLimit;
bytes data;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @custom:attribution https://github.com/bakaoh/solidity-rlp-encode
/// @title RLPWriter
/// @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's
/// RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor
/// modifications to improve legibility.
library RLPWriter {
/// @notice RLP encodes a byte string.
/// @param _in The byte string to encode.
/// @return out_ The RLP encoded string in bytes.
function writeBytes(bytes memory _in) internal pure returns (bytes memory out_) {
if (_in.length == 1 && uint8(_in[0]) < 128) {
out_ = _in;
} else {
out_ = abi.encodePacked(_writeLength(_in.length, 128), _in);
}
}
/// @notice RLP encodes a list of RLP encoded byte byte strings.
/// @param _in The list of RLP encoded byte strings.
/// @return list_ The RLP encoded list of items in bytes.
function writeList(bytes[] memory _in) internal pure returns (bytes memory list_) {
list_ = _flatten(_in);
list_ = abi.encodePacked(_writeLength(list_.length, 192), list_);
}
/// @notice RLP encodes a string.
/// @param _in The string to encode.
/// @return out_ The RLP encoded string in bytes.
function writeString(string memory _in) internal pure returns (bytes memory out_) {
out_ = writeBytes(bytes(_in));
}
/// @notice RLP encodes an address.
/// @param _in The address to encode.
/// @return out_ The RLP encoded address in bytes.
function writeAddress(address _in) internal pure returns (bytes memory out_) {
out_ = writeBytes(abi.encodePacked(_in));
}
/// @notice RLP encodes a uint.
/// @param _in The uint256 to encode.
/// @return out_ The RLP encoded uint256 in bytes.
function writeUint(uint256 _in) internal pure returns (bytes memory out_) {
out_ = writeBytes(_toBinary(_in));
}
/// @notice RLP encodes a bool.
/// @param _in The bool to encode.
/// @return out_ The RLP encoded bool in bytes.
function writeBool(bool _in) internal pure returns (bytes memory out_) {
out_ = new bytes(1);
out_[0] = (_in ? bytes1(0x01) : bytes1(0x80));
}
/// @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.
/// @param _len The length of the string or the payload.
/// @param _offset 128 if item is string, 192 if item is list.
/// @return out_ RLP encoded bytes.
function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory out_) {
if (_len < 56) {
out_ = new bytes(1);
out_[0] = bytes1(uint8(_len) + uint8(_offset));
} else {
uint256 lenLen;
uint256 i = 1;
while (_len / i != 0) {
lenLen++;
i *= 256;
}
out_ = new bytes(lenLen + 1);
out_[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);
for (i = 1; i <= lenLen; i++) {
out_[i] = bytes1(uint8((_len / (256 ** (lenLen - i))) % 256));
}
}
}
/// @notice Encode integer in big endian binary form with no leading zeroes.
/// @param _x The integer to encode.
/// @return out_ RLP encoded bytes.
function _toBinary(uint256 _x) private pure returns (bytes memory out_) {
bytes memory b = abi.encodePacked(_x);
uint256 i = 0;
for (; i < 32; i++) {
if (b[i] != 0) {
break;
}
}
out_ = new bytes(32 - i);
for (uint256 j = 0; j < out_.length; j++) {
out_[j] = b[i++];
}
}
/// @custom:attribution https://github.com/Arachnid/solidity-stringutils
/// @notice Copies a piece of memory to another location.
/// @param _dest Destination location.
/// @param _src Source location.
/// @param _len Length of memory to copy.
function _memcpy(uint256 _dest, uint256 _src, uint256 _len) private pure {
uint256 dest = _dest;
uint256 src = _src;
uint256 len = _len;
for (; len >= 32; len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
uint256 mask;
unchecked {
mask = 256 ** (32 - len) - 1;
}
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
/// @custom:attribution https://github.com/sammayo/solidity-rlp-encoder
/// @notice Flattens a list of byte strings into one byte string.
/// @param _list List of byte strings to flatten.
/// @return out_ The flattened byte string.
function _flatten(bytes[] memory _list) private pure returns (bytes memory out_) {
if (_list.length == 0) {
return new bytes(0);
}
uint256 len;
uint256 i = 0;
for (; i < _list.length; i++) {
len += _list[i].length;
}
out_ = new bytes(len);
uint256 flattenedPtr;
assembly {
flattenedPtr := add(out_, 0x20)
}
for (i = 0; i < _list.length; i++) {
bytes memory item = _list[i];
uint256 listPtr;
assembly {
listPtr := add(item, 0x20)
}
_memcpy(flattenedPtr, listPtr, item.length);
flattenedPtr += _list[i].length;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol";
import { SafeCall } from "src/libraries/SafeCall.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
/// @title FeeVault
/// @notice The FeeVault contract contains the basic logic for the various different vault contracts
/// used to hold fee revenue generated by the L2 system.
abstract contract FeeVault {
/// @notice Enum representing where the FeeVault withdraws funds to.
/// @custom:value L1 FeeVault withdraws funds to L1.
/// @custom:value L2 FeeVault withdraws funds to L2.
enum WithdrawalNetwork {
L1,
L2
}
/// @notice Minimum balance before a withdrawal can be triggered.
/// Use the `minWithdrawalAmount()` getter as this is deprecated
/// and is subject to be removed in the future.
/// @custom:legacy
uint256 public immutable MIN_WITHDRAWAL_AMOUNT;
/// @notice Account that will receive the fees. Can be located on L1 or L2.
/// Use the `recipient()` getter as this is deprecated
/// and is subject to be removed in the future.
/// @custom:legacy
address public immutable RECIPIENT;
/// @notice Network which the recipient will receive fees on.
/// Use the `withdrawalNetwork()` getter as this is deprecated
/// and is subject to be removed in the future.
/// @custom:legacy
WithdrawalNetwork public immutable WITHDRAWAL_NETWORK;
/// @notice The minimum gas limit for the FeeVault withdrawal transaction.
uint32 internal constant WITHDRAWAL_MIN_GAS = 400_000;
/// @notice Total amount of wei processed by the contract.
uint256 public totalProcessed;
/// @notice Reserve extra slots in the storage layout for future upgrades.
uint256[48] private __gap;
/// @notice Emitted each time a withdrawal occurs. This event will be deprecated
/// in favor of the Withdrawal event containing the WithdrawalNetwork parameter.
/// @param value Amount that was withdrawn (in wei).
/// @param to Address that the funds were sent to.
/// @param from Address that triggered the withdrawal.
event Withdrawal(uint256 value, address to, address from);
/// @notice Emitted each time a withdrawal occurs.
/// @param value Amount that was withdrawn (in wei).
/// @param to Address that the funds were sent to.
/// @param from Address that triggered the withdrawal.
/// @param withdrawalNetwork Network which the to address will receive funds on.
event Withdrawal(uint256 value, address to, address from, WithdrawalNetwork withdrawalNetwork);
/// @param _recipient Wallet that will receive the fees.
/// @param _minWithdrawalAmount Minimum balance for withdrawals.
/// @param _withdrawalNetwork Network which the recipient will receive fees on.
constructor(address _recipient, uint256 _minWithdrawalAmount, WithdrawalNetwork _withdrawalNetwork) {
RECIPIENT = _recipient;
MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;
WITHDRAWAL_NETWORK = _withdrawalNetwork;
}
/// @notice Allow the contract to receive ETH.
receive() external payable { }
/// @notice Minimum balance before a withdrawal can be triggered.
function minWithdrawalAmount() public view returns (uint256 amount_) {
amount_ = MIN_WITHDRAWAL_AMOUNT;
}
/// @notice Account that will receive the fees. Can be located on L1 or L2.
function recipient() public view returns (address recipient_) {
recipient_ = RECIPIENT;
}
/// @notice Network which the recipient will receive fees on.
function withdrawalNetwork() public view returns (WithdrawalNetwork network_) {
network_ = WITHDRAWAL_NETWORK;
}
/// @notice Triggers a withdrawal of funds to the fee wallet on L1 or L2.
function withdraw() external {
require(
address(this).balance >= MIN_WITHDRAWAL_AMOUNT,
"FeeVault: withdrawal amount must be greater than minimum withdrawal amount"
);
uint256 value = address(this).balance;
totalProcessed += value;
emit Withdrawal(value, RECIPIENT, msg.sender);
emit Withdrawal(value, RECIPIENT, msg.sender, WITHDRAWAL_NETWORK);
if (WITHDRAWAL_NETWORK == WithdrawalNetwork.L2) {
bool success = SafeCall.send(RECIPIENT, value);
require(success, "FeeVault: failed to send ETH to L2 fee recipient");
} else {
L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{ value: value }({
_target: RECIPIENT,
_gasLimit: WITHDRAWAL_MIN_GAS,
_data: hex""
});
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title ISemver
/// @notice ISemver is a simple contract for ensuring that contracts are
/// versioned using semantic versioning.
interface ISemver {
/// @notice Getter for the semantic version of the contract. This is not
/// meant to be used onchain but instead meant to be used by offchain
/// tooling.
/// @return Semver contract version as a string.
function version() external view returns (string memory);
}{
"evmVersion": "london",
"metadata": {
"bytecodeHash": "none",
"useLiteralContent": false
},
"optimizer": {
"enabled": true,
"runs": 999999
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"remappings": [
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-v5/=lib/openzeppelin-contracts-v5/contracts/",
"@rari-capital/solmate/=lib/solmate/",
"@lib-keccak/=lib/lib-keccak/contracts/lib/",
"@solady/=lib/solady/src/",
"forge-std/=lib/forge-std/src/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"safe-contracts/=lib/safe-contracts/contracts/",
"kontrol-cheatcodes/=lib/kontrol-cheatcodes/src/",
"gelato/=lib/automate/contracts/",
"@solady-test/=lib/lib-keccak/lib/solady/test/",
"automate/=lib/automate/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts-v5/lib/erc4626-tests/",
"hardhat/=lib/automate/node_modules/hardhat/",
"lib-keccak/=lib/lib-keccak/contracts/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts-v5/=lib/openzeppelin-contracts-v5/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"prb-test/=lib/automate/lib/prb-test/src/",
"prb/-est/=lib/automate/lib/prb-test/src/",
"solady-v0.0.245/=lib/solady-v0.0.245/src/",
"solady/=lib/solady/",
"solmate/=lib/solmate/src/"
],
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_minWithdrawalAmount","type":"uint256"},{"internalType":"enum FeeVault.WithdrawalNetwork","name":"_withdrawalNetwork","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"from","type":"address"}],"name":"Withdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"enum FeeVault.WithdrawalNetwork","name":"withdrawalNetwork","type":"uint8"}],"name":"Withdrawal","type":"event"},{"inputs":[],"name":"MIN_WITHDRAWAL_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECIPIENT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WITHDRAWAL_NETWORK","outputs":[{"internalType":"enum FeeVault.WithdrawalNetwork","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l1FeeWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minWithdrawalAmount","outputs":[{"internalType":"uint256","name":"amount_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recipient","outputs":[{"internalType":"address","name":"recipient_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalProcessed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawalNetwork","outputs":[{"internalType":"enum FeeVault.WithdrawalNetwork","name":"network_","type":"uint8"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
6080604052600436106100b55760003560e01c80638312f14911610069578063d0e12f901161004e578063d0e12f901461024e578063d3e5792b14610282578063d4ff92181461018c57600080fd5b80638312f149146101fb57806384411d651461023857600080fd5b806354fd4d501161009a57806354fd4d501461013657806366d003ac1461018c57806382356d8a146101bf57600080fd5b80630d9019e1146100c15780633ccfd60b1461011f57600080fd5b366100bc57005b600080fd5b3480156100cd57600080fd5b506100f57f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a781565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561012b57600080fd5b506101346102b6565b005b34801561014257600080fd5b5061017f6040518060400160405280600c81526020017f312e352e302d626574612e32000000000000000000000000000000000000000081525081565b604051610116919061068c565b34801561019857600080fd5b507f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a76100f5565b3480156101cb57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000015b6040516101169190610769565b34801561020757600080fd5b507f0000000000000000000000000000000000000000000000008ac7230489e800005b604051908152602001610116565b34801561024457600080fd5b5061022a60005481565b34801561025a57600080fd5b506101ee7f000000000000000000000000000000000000000000000000000000000000000181565b34801561028e57600080fd5b5061022a7f0000000000000000000000000000000000000000000000008ac7230489e8000081565b7f0000000000000000000000000000000000000000000000008ac7230489e80000471015610391576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546103a7919061077d565b9091555050604080518281527f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a773ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a7337f000000000000000000000000000000000000000000000000000000000000000160405161049594939291906107bc565b60405180910390a160017f000000000000000000000000000000000000000000000000000000000000000160018111156104d1576104d16106ff565b036105955760006105027f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a783610664565b905080610591576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610388565b5050565b6040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a716600482015262061a80602482015260606044820152600060648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084016000604051808303818588803b15801561064857600080fd5b505af115801561065c573d6000803e3d6000fd5b505050505050565b6000610671835a84610678565b9392505050565b6000806000806000858888f1949350505050565b600060208083528351808285015260005b818110156106b95785810183015185820160400152820161069d565b818111156106cb576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110610765577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60208101610777828461072e565b92915050565b600082198211156107b7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff848116602083015283166040820152608081016107f4606083018461072e565b9594505050505056fea164736f6c634300080f000a
Deployed Bytecode
0x6080604052600436106100b55760003560e01c80638312f14911610069578063d0e12f901161004e578063d0e12f901461024e578063d3e5792b14610282578063d4ff92181461018c57600080fd5b80638312f149146101fb57806384411d651461023857600080fd5b806354fd4d501161009a57806354fd4d501461013657806366d003ac1461018c57806382356d8a146101bf57600080fd5b80630d9019e1146100c15780633ccfd60b1461011f57600080fd5b366100bc57005b600080fd5b3480156100cd57600080fd5b506100f57f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a781565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561012b57600080fd5b506101346102b6565b005b34801561014257600080fd5b5061017f6040518060400160405280600c81526020017f312e352e302d626574612e32000000000000000000000000000000000000000081525081565b604051610116919061068c565b34801561019857600080fd5b507f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a76100f5565b3480156101cb57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000015b6040516101169190610769565b34801561020757600080fd5b507f0000000000000000000000000000000000000000000000008ac7230489e800005b604051908152602001610116565b34801561024457600080fd5b5061022a60005481565b34801561025a57600080fd5b506101ee7f000000000000000000000000000000000000000000000000000000000000000181565b34801561028e57600080fd5b5061022a7f0000000000000000000000000000000000000000000000008ac7230489e8000081565b7f0000000000000000000000000000000000000000000000008ac7230489e80000471015610391576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546103a7919061077d565b9091555050604080518281527f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a773ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a7337f000000000000000000000000000000000000000000000000000000000000000160405161049594939291906107bc565b60405180910390a160017f000000000000000000000000000000000000000000000000000000000000000160018111156104d1576104d16106ff565b036105955760006105027f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a783610664565b905080610591576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610388565b5050565b6040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000045effbd799ab49122eeeab75b78d9c56a187f9a716600482015262061a80602482015260606044820152600060648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084016000604051808303818588803b15801561064857600080fd5b505af115801561065c573d6000803e3d6000fd5b505050505050565b6000610671835a84610678565b9392505050565b6000806000806000858888f1949350505050565b600060208083528351808285015260005b818110156106b95785810183015185820160400152820161069d565b818111156106cb576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110610765577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60208101610777828461072e565b92915050565b600082198211156107b7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff848116602083015283166040820152608081016107f4606083018461072e565b9594505050505056fea164736f6c634300080f000a
Deployed Bytecode Sourcemap
452:850:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1220:34:9;;;;;;;;;;;;;;;;;;190:42:11;178:55;;;160:74;;148:2;133:18;1220:34:9;;;;;;;;3978:895;;;;;;;;;;;;;:::i;:::-;;542:47:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;3597:101:9:-;;;;;;;;;;-1:-1:-1;3682:9:9;3597:101;;3770:124;;;;;;;;;;-1:-1:-1;3869:18:9;3770:124;;;;;;;:::i;3394:117::-;;;;;;;;;;-1:-1:-1;3483:21:9;3394:117;;;1777:25:11;;;1765:2;1750:18;3394:117:9;1631:177:11;1747:29:9;;;;;;;;;;;;;;;;1485:53;;;;;;;;;;;;;;;937:46;;;;;;;;;;;;;;;3978:895;4063:21;4038;:46;;4017:167;;;;;;;2015:2:11;4017:167:9;;;1997:21:11;2054:2;2034:18;;;2027:30;2093:34;2073:18;;;2066:62;2164:34;2144:18;;;2137:62;2236:12;2215:19;;;2208:41;2266:19;;4017:167:9;;;;;;;;;4195:13;4211:21;4195:37;;4260:5;4242:14;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;;4281:40:9;;;2785:25:11;;;4299:9:9;2829:42:11;2907:15;2902:2;2887:18;;2880:43;4310:10:9;2939:18:11;;;2932:43;4281:40:9;;;;;;;2773:2:11;4281:40:9;;;4336:60;4347:5;4354:9;4365:10;4377:18;4336:60;;;;;;;;;:::i;:::-;;;;;;;;4433:20;4411:18;:42;;;;;;;;:::i;:::-;;4407:460;;4469:12;4484:31;4498:9;4509:5;4484:13;:31::i;:::-;4469:46;;4537:7;4529:68;;;;;;;3710:2:11;4529:68:9;;;3692:21:11;3749:2;3729:18;;;3722:30;3788:34;3768:18;;;3761:62;3859:18;3839;;;3832:46;3895:19;;4529:68:9;3508:412:11;4529:68:9;4455:153;4007:866;3978:895::o;4407:460::-;4628:228;;;;;4193:42:11;4755:9:9;4181:55:11;4628:228:9;;;4163:74:11;1670:7:9;4253:18:11;;;4246:51;4333:2;4313:18;;;4306:30;-1:-1:-1;4352:18:11;;;4345:29;2990:42:5;;4628:83:9;;4720:5;;4391:19:11;;4628:228:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4007:866;3978:895::o;1063:140:6:-;1128:13;1164:32;1169:7;1178:9;1189:6;1164:4;:32::i;:::-;1153:43;1063:140;-1:-1:-1;;;1063:140:6:o;429:441::-;508:13;825:1;792;760;728;685:6;643:7;610:4;584:270;556:298;429:441;-1:-1:-1;;;;429:441:6:o;245:656:11:-;357:4;386:2;415;404:9;397:21;447:6;441:13;490:6;485:2;474:9;470:18;463:34;515:1;525:140;539:6;536:1;533:13;525:140;;;634:14;;;630:23;;624:30;600:17;;;619:2;596:26;589:66;554:10;;525:140;;;683:6;680:1;677:13;674:91;;;753:1;748:2;739:6;728:9;724:22;720:31;713:42;674:91;-1:-1:-1;817:2:11;805:15;822:66;801:88;786:104;;;;892:2;782:113;;245:656;-1:-1:-1;;;245:656:11:o;906:184::-;958:77;955:1;948:88;1055:4;1052:1;1045:15;1079:4;1076:1;1069:15;1095:302;1184:1;1177:5;1174:12;1164:200;;1220:77;1217:1;1210:88;1321:4;1318:1;1311:15;1349:4;1346:1;1339:15;1164:200;1373:18;;1095:302::o;1402:224::-;1556:2;1541:18;;1568:52;1545:9;1602:6;1568:52;:::i;:::-;1402:224;;;;:::o;2296:282::-;2336:3;2367:1;2363:6;2360:1;2357:13;2354:193;;;2403:77;2400:1;2393:88;2504:4;2501:1;2494:15;2532:4;2529:1;2522:15;2354:193;-1:-1:-1;2563:9:11;;2296:282::o;2986:517::-;3237:25;;;3281:42;3359:15;;;3354:2;3339:18;;3332:43;3411:15;;3406:2;3391:18;;3384:43;3224:3;3209:19;;3436:61;3493:2;3478:18;;3470:6;3436:61;:::i;:::-;2986:517;;;;;;;:::o
Swarm Source
none
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| WORLD | 100.00% | $3,104.61 | 0.000000000000001312 | <$0.000001 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.