Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Multichain Info
N/A
Loading...
Loading
Contract Name:
L2ToL1MessagePasser
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 999999 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// 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 { require(false, "Withdrawals are disabled"); 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) { // nosemgrep: sol-style-use-abi-encodecall 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) { // nosemgrep: sol-style-use-abi-encodecall 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. function encodeSetL1BlockValuesInterop( 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("setL1BlockValuesInterop()")); return abi.encodePacked( functionSignature, _baseFeeScalar, _blobBaseFeeScalar, _sequenceNumber, _timestamp, _number, _baseFee, _blobBaseFee, _hash, _batcherHash ); } }
// 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 ) ); } /// @notice Generates a unique hash for cross l2 messages. This hash is used to identify /// the message and ensure it is not relayed more than once. /// @param _destination Chain ID of the destination chain. /// @param _source Chain ID of the source chain. /// @param _nonce Unique nonce associated with the message to prevent replay attacks. /// @param _sender Address of the user who originally sent the message. /// @param _target Address of the contract or wallet that the message is targeting on the destination chain. /// @param _message The message payload to be relayed to the target on the destination chain. /// @return Hash of the encoded message parameters, used to uniquely identify the message. function hashL2toL2CrossDomainMessage( uint256 _destination, uint256 _source, uint256 _nonce, address _sender, address _target, bytes memory _message ) internal pure returns (bytes32) { return keccak256(abi.encode(_destination, _source, _nonce, _sender, _target, _message)); } }
// 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; } /// @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 } }
// 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.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", "libraries": {}, "metadata": { "bytecodeHash": "none", "useLiteralContent": false }, "optimizer": { "enabled": true, "runs": 999999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "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/", "@solady-v0.0.245/=lib/solady-v0.0.245/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[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasLimit","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes32","name":"withdrawalHash","type":"bytes32"}],"name":"MessagePassed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawerBalanceBurnt","type":"event"},{"inputs":[],"name":"MESSAGE_VERSION","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"initiateWithdrawal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"messageNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"sentMessages","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b506104a1806100206000396000f3fe6080604052600436106100695760003560e01c806382e3702d1161004357806382e3702d1461012a578063c2b3e5ac1461016a578063ecc704281461017d57600080fd5b80633f827a5a1461009257806344df8e70146100bf57806354fd4d50146100d457600080fd5b3661008d5761008b33620186a0604051806020016040528060008152506101e2565b005b600080fd5b34801561009e57600080fd5b506100a7600181565b60405161ffff90911681526020015b60405180910390f35b3480156100cb57600080fd5b5061008b610248565b3480156100e057600080fd5b5061011d6040518060400160405280600c81526020017f312e312e312d626574612e31000000000000000000000000000000000000000081525081565b6040516100b69190610326565b34801561013657600080fd5b5061015a610145366004610340565b60006020819052908152604090205460ff1681565b60405190151581526020016100b6565b61008b610178366004610388565b6101e2565b34801561018957600080fd5b506101d46001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016100b6565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f5769746864726177616c73206172652064697361626c65640000000000000000604482015260640160405180910390fd5b4761025281610280565b60405181907f7967de617a5ac1cc7eba2d6f37570a0135afa950d8bb77cdd35f0d0b4e85a16f90600090a250565b8060405161028d906102af565b6040518091039082f09050801580156102aa573d6000803e3d6000fd5b505050565b60088061048d83390190565b6000815180845260005b818110156102e1576020818501810151868301820152016102c5565b818111156102f3576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061033960208301846102bb565b9392505050565b60006020828403121561035257600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561039d57600080fd5b833573ffffffffffffffffffffffffffffffffffffffff811681146103c157600080fd5b925060208401359150604084013567ffffffffffffffff808211156103e557600080fd5b818601915086601f8301126103f957600080fd5b81358181111561040b5761040b610359565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561045157610451610359565b8160405282815289602084870101111561046a57600080fd5b826020860160208301376000602084830101528095505050505050925092509256fe608060405230fffea164736f6c634300080f000a
Deployed Bytecode
0x6080604052600436106100695760003560e01c806382e3702d1161004357806382e3702d1461012a578063c2b3e5ac1461016a578063ecc704281461017d57600080fd5b80633f827a5a1461009257806344df8e70146100bf57806354fd4d50146100d457600080fd5b3661008d5761008b33620186a0604051806020016040528060008152506101e2565b005b600080fd5b34801561009e57600080fd5b506100a7600181565b60405161ffff90911681526020015b60405180910390f35b3480156100cb57600080fd5b5061008b610248565b3480156100e057600080fd5b5061011d6040518060400160405280600c81526020017f312e312e312d626574612e31000000000000000000000000000000000000000081525081565b6040516100b69190610326565b34801561013657600080fd5b5061015a610145366004610340565b60006020819052908152604090205460ff1681565b60405190151581526020016100b6565b61008b610178366004610388565b6101e2565b34801561018957600080fd5b506101d46001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016100b6565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f5769746864726177616c73206172652064697361626c65640000000000000000604482015260640160405180910390fd5b4761025281610280565b60405181907f7967de617a5ac1cc7eba2d6f37570a0135afa950d8bb77cdd35f0d0b4e85a16f90600090a250565b8060405161028d906102af565b6040518091039082f09050801580156102aa573d6000803e3d6000fd5b505050565b60088061048d83390190565b6000815180845260005b818110156102e1576020818501810151868301820152016102c5565b818111156102f3576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061033960208301846102bb565b9392505050565b60006020828403121561035257600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561039d57600080fd5b833573ffffffffffffffffffffffffffffffffffffffff811681146103c157600080fd5b925060208401359150604084013567ffffffffffffffff808211156103e557600080fd5b818601915086601f8301126103f957600080fd5b81358181111561040b5761040b610359565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561045157610451610359565b8160405282815289602084870101111561046a57600080fd5b826020860160208301376000602084830101528095505050505050925092509256fe608060405230fffea164736f6c634300080f000a
Loading...
Loading
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.