Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- L2StandardBridge
- Optimization enabled
- true
- Compiler version
- v0.8.9+commit.e5eed63a
- Optimization runs
- 10000
- EVM Version
- default
- Verified at
- 2023-06-27T08:29:43.392369Z
contracts/L2/messaging/L2StandardBridge.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /* Interface Imports */ import { IL1StandardBridge } from "../../L1/messaging/IL1StandardBridge.sol"; import { IL1ERC20Bridge } from "../../L1/messaging/IL1ERC20Bridge.sol"; import { IL2ERC20Bridge } from "./IL2ERC20Bridge.sol"; /* Library Imports */ import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol"; import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; /* Contract Imports */ import { IL2StandardERC20 } from "../../standards/IL2StandardERC20.sol"; /** * @title L2StandardBridge * @dev The L2 Standard bridge is a contract which works together with the L1 Standard bridge to * enable ETH and ERC20 transitions between L1 and L2. * This contract acts as a minter for new tokens when it hears about deposits into the L1 Standard * bridge. * This contract also acts as a burner of the tokens intended for withdrawal, informing the L1 * bridge to release L1 funds. */ contract L2StandardBridge is IL2ERC20Bridge, CrossDomainEnabled { /******************************** * External Contract References * ********************************/ address public l1TokenBridge; /*************** * Constructor * ***************/ /** * @param _l2CrossDomainMessenger Cross-domain messenger used by this contract. * @param _l1TokenBridge Address of the L1 bridge deployed to the main chain. */ constructor(address _l2CrossDomainMessenger, address _l1TokenBridge) CrossDomainEnabled(_l2CrossDomainMessenger) { l1TokenBridge = _l1TokenBridge; } /*************** * Withdrawing * ***************/ /** * @inheritdoc IL2ERC20Bridge */ function withdraw( address _l2Token, uint256 _amount, uint32 _l1Gas, bytes calldata _data ) external virtual { _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _l1Gas, _data); } /** * @inheritdoc IL2ERC20Bridge */ function withdrawTo( address _l2Token, address _to, uint256 _amount, uint32 _l1Gas, bytes calldata _data ) external virtual { _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _l1Gas, _data); } /** * @dev Performs the logic for withdrawals by burning the token and informing * the L1 token Gateway of the withdrawal. * @param _l2Token Address of L2 token where withdrawal is initiated. * @param _from Account to pull the withdrawal from on L2. * @param _to Account to give the withdrawal to on L1. * @param _amount Amount of the token to withdraw. * @param _l1Gas Unused, but included for potential forward compatibility considerations. * @param _data Optional data to forward to L1. This data is provided * solely as a convenience for external contracts. Aside from enforcing a maximum * length, these contracts provide no guarantees about its content. */ function _initiateWithdrawal( address _l2Token, address _from, address _to, uint256 _amount, uint32 _l1Gas, bytes calldata _data ) internal { // When a withdrawal is initiated, we burn the withdrawer's funds to prevent subsequent L2 // usage // slither-disable-next-line reentrancy-events IL2StandardERC20(_l2Token).burn(msg.sender, _amount); // Construct calldata for l1TokenBridge.finalizeERC20Withdrawal(_to, _amount) // slither-disable-next-line reentrancy-events address l1Token = IL2StandardERC20(_l2Token).l1Token(); bytes memory message; if (_l2Token == Lib_PredeployAddresses.OVM_ETH) { message = abi.encodeWithSelector( IL1StandardBridge.finalizeETHWithdrawal.selector, _from, _to, _amount, _data ); } else { message = abi.encodeWithSelector( IL1ERC20Bridge.finalizeERC20Withdrawal.selector, l1Token, _l2Token, _from, _to, _amount, _data ); } // Send message up to L1 bridge // slither-disable-next-line reentrancy-events sendCrossDomainMessage(l1TokenBridge, _l1Gas, message); // slither-disable-next-line reentrancy-events emit WithdrawalInitiated(l1Token, _l2Token, msg.sender, _to, _amount, _data); } /************************************ * Cross-chain Function: Depositing * ************************************/ /** * @inheritdoc IL2ERC20Bridge */ function finalizeDeposit( address _l1Token, address _l2Token, address _from, address _to, uint256 _amount, bytes calldata _data ) external virtual onlyFromCrossDomainAccount(l1TokenBridge) { // Check the target token is compliant and // verify the deposited token on L1 matches the L2 deposited token representation here if ( // slither-disable-next-line reentrancy-events ERC165Checker.supportsInterface(_l2Token, 0x1d1d8b63) && _l1Token == IL2StandardERC20(_l2Token).l1Token() ) { // When a deposit is finalized, we credit the account on L2 with the same amount of // tokens. // slither-disable-next-line reentrancy-events IL2StandardERC20(_l2Token).mint(_to, _amount); // slither-disable-next-line reentrancy-events emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _data); } else { // Either the L2 token which is being deposited-into disagrees about the correct address // of its L1 token, or does not support the correct interface. // This should only happen if there is a malicious L2 token, or if a user somehow // specified the wrong L2 token address to deposit into. // In either case, we stop the process here and construct a withdrawal // message so that users can get their funds out in some cases. // There is no way to prevent malicious token contracts altogether, but this does limit // user error and mitigate some forms of malicious contract behavior. bytes memory message = abi.encodeWithSelector( IL1ERC20Bridge.finalizeERC20Withdrawal.selector, _l1Token, _l2Token, _to, // switched the _to and _from here to bounce back the deposit to the sender _from, _amount, _data ); // Send message up to L1 bridge // slither-disable-next-line reentrancy-events sendCrossDomainMessage(l1TokenBridge, 0, message); // slither-disable-next-line reentrancy-events emit DepositFailed(_l1Token, _l2Token, _from, _to, _amount, _data); } } }
@openzeppelin/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
@openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
@openzeppelin/contracts/utils/introspection/ERC165Checker.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface, */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return _supportsERC165Interface(account, type(IERC165).interfaceId) && !_supportsERC165Interface(account, _INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && _supportsERC165Interface(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. * * _Available since v3.4._ */ function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in _interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!_supportsERC165Interface(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * Interface identification is specified in ERC-165. */ function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) { bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId); (bool success, bytes memory result) = account.staticcall{gas: 30000}(encodedParams); if (result.length < 32) return false; return success && abi.decode(result, (bool)); } }
contracts/standards/IL2StandardERC20.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface IL2StandardERC20 is IERC20, IERC165 { function l1Token() external returns (address); function mint(address _to, uint256 _amount) external; function burn(address _from, uint256 _amount) external; event Mint(address indexed _account, uint256 _amount); event Burn(address indexed _account, uint256 _amount); }
contracts/L1/messaging/IL1ERC20Bridge.sol
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.9.0; /** * @title IL1ERC20Bridge */ interface IL1ERC20Bridge { /********** * Events * **********/ event ERC20DepositInitiated( address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256 _amount, bytes _data ); event ERC20WithdrawalFinalized( address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256 _amount, bytes _data ); /******************** * Public Functions * ********************/ /** * @dev get the address of the corresponding L2 bridge contract. * @return Address of the corresponding L2 bridge contract. */ function l2TokenBridge() external returns (address); /** * @dev deposit an amount of the ERC20 to the caller's balance on L2. * @param _l1Token Address of the L1 ERC20 we are depositing * @param _l2Token Address of the L1 respective L2 ERC20 * @param _amount Amount of the ERC20 to deposit * @param _l2Gas Gas limit required to complete the deposit on L2. * @param _data Optional data to forward to L2. This data is provided * solely as a convenience for external contracts. Aside from enforcing a maximum * length, these contracts provide no guarantees about its content. */ function depositERC20( address _l1Token, address _l2Token, uint256 _amount, uint32 _l2Gas, bytes calldata _data ) external; /** * @dev deposit an amount of ERC20 to a recipient's balance on L2. * @param _l1Token Address of the L1 ERC20 we are depositing * @param _l2Token Address of the L1 respective L2 ERC20 * @param _to L2 address to credit the withdrawal to. * @param _amount Amount of the ERC20 to deposit. * @param _l2Gas Gas limit required to complete the deposit on L2. * @param _data Optional data to forward to L2. This data is provided * solely as a convenience for external contracts. Aside from enforcing a maximum * length, these contracts provide no guarantees about its content. */ function depositERC20To( address _l1Token, address _l2Token, address _to, uint256 _amount, uint32 _l2Gas, bytes calldata _data ) external; /************************* * Cross-chain Functions * *************************/ /** * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the * L1 ERC20 token. * This call will fail if the initialized withdrawal from L2 has not been finalized. * * @param _l1Token Address of L1 token to finalizeWithdrawal for. * @param _l2Token Address of L2 token where withdrawal was initiated. * @param _from L2 address initiating the transfer. * @param _to L1 address to credit the withdrawal to. * @param _amount Amount of the ERC20 to deposit. * @param _data Data provided by the sender on L2. This data is provided * solely as a convenience for external contracts. Aside from enforcing a maximum * length, these contracts provide no guarantees about its content. */ function finalizeERC20Withdrawal( address _l1Token, address _l2Token, address _from, address _to, uint256 _amount, bytes calldata _data ) external; }
contracts/L1/messaging/IL1StandardBridge.sol
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.9.0; import "./IL1ERC20Bridge.sol"; /** * @title IL1StandardBridge */ interface IL1StandardBridge is IL1ERC20Bridge { /********** * Events * **********/ event ETHDepositInitiated( address indexed _from, address indexed _to, uint256 _amount, bytes _data ); event ETHWithdrawalFinalized( address indexed _from, address indexed _to, uint256 _amount, bytes _data ); /******************** * Public Functions * ********************/ /** * @dev Deposit an amount of the ETH to the caller's balance on L2. * @param _l2Gas Gas limit required to complete the deposit on L2. * @param _data Optional data to forward to L2. This data is provided * solely as a convenience for external contracts. Aside from enforcing a maximum * length, these contracts provide no guarantees about its content. */ function depositETH(uint32 _l2Gas, bytes calldata _data) external payable; /** * @dev Deposit an amount of ETH to a recipient's balance on L2. * @param _to L2 address to credit the withdrawal to. * @param _l2Gas Gas limit required to complete the deposit on L2. * @param _data Optional data to forward to L2. This data is provided * solely as a convenience for external contracts. Aside from enforcing a maximum * length, these contracts provide no guarantees about its content. */ function depositETHTo( address _to, uint32 _l2Gas, bytes calldata _data ) external payable; /************************* * Cross-chain Functions * *************************/ /** * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the * L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called * before the withdrawal is finalized. * @param _from L2 address initiating the transfer. * @param _to L1 address to credit the withdrawal to. * @param _amount Amount of the ERC20 to deposit. * @param _data Optional data to forward to L2. This data is provided * solely as a convenience for external contracts. Aside from enforcing a maximum * length, these contracts provide no guarantees about its content. */ function finalizeETHWithdrawal( address _from, address _to, uint256 _amount, bytes calldata _data ) external; }
contracts/L2/messaging/IL2ERC20Bridge.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /** * @title IL2ERC20Bridge */ interface IL2ERC20Bridge { /********** * Events * **********/ event WithdrawalInitiated( address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256 _amount, bytes _data ); event DepositFinalized( address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256 _amount, bytes _data ); event DepositFailed( address indexed _l1Token, address indexed _l2Token, address indexed _from, address _to, uint256 _amount, bytes _data ); /******************** * Public Functions * ********************/ /** * @dev get the address of the corresponding L1 bridge contract. * @return Address of the corresponding L1 bridge contract. */ function l1TokenBridge() external returns (address); /** * @dev initiate a withdraw of some tokens to the caller's account on L1 * @param _l2Token Address of L2 token where withdrawal was initiated. * @param _amount Amount of the token to withdraw. * param _l1Gas Unused, but included for potential forward compatibility considerations. * @param _data Optional data to forward to L1. This data is provided * solely as a convenience for external contracts. Aside from enforcing a maximum * length, these contracts provide no guarantees about its content. */ function withdraw( address _l2Token, uint256 _amount, uint32 _l1Gas, bytes calldata _data ) external; /** * @dev initiate a withdraw of some token to a recipient's account on L1. * @param _l2Token Address of L2 token where withdrawal is initiated. * @param _to L1 adress to credit the withdrawal to. * @param _amount Amount of the token to withdraw. * param _l1Gas Unused, but included for potential forward compatibility considerations. * @param _data Optional data to forward to L1. This data is provided * solely as a convenience for external contracts. Aside from enforcing a maximum * length, these contracts provide no guarantees about its content. */ function withdrawTo( address _l2Token, address _to, uint256 _amount, uint32 _l1Gas, bytes calldata _data ) external; /************************* * Cross-chain Functions * *************************/ /** * @dev Complete a deposit from L1 to L2, and credits funds to the recipient's balance of this * L2 token. This call will fail if it did not originate from a corresponding deposit in * L1StandardTokenBridge. * @param _l1Token Address for the l1 token this is called with * @param _l2Token Address for the l2 token this is called with * @param _from Account to pull the deposit from on L2. * @param _to Address to receive the withdrawal at * @param _amount Amount of the token to withdraw * @param _data Data provider by the sender on L1. This data is provided * solely as a convenience for external contracts. Aside from enforcing a maximum * length, these contracts provide no guarantees about its content. */ function finalizeDeposit( address _l1Token, address _l2Token, address _from, address _to, uint256 _amount, bytes calldata _data ) external; }
contracts/libraries/bridge/CrossDomainEnabled.sol
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.9.0; /* Interface Imports */ import { ICrossDomainMessenger } from "./ICrossDomainMessenger.sol"; /** * @title CrossDomainEnabled * @dev Helper contract for contracts performing cross-domain communications * * Compiler used: defined by inheriting contract */ contract CrossDomainEnabled { /************* * Variables * *************/ // Messenger contract used to send and recieve messages from the other domain. address public messenger; /*************** * Constructor * ***************/ /** * @param _messenger Address of the CrossDomainMessenger on the current layer. */ constructor(address _messenger) { messenger = _messenger; } /********************** * Function Modifiers * **********************/ /** * Enforces that the modified function is only callable by a specific cross-domain account. * @param _sourceDomainAccount The only account on the originating domain which is * authenticated to call this function. */ modifier onlyFromCrossDomainAccount(address _sourceDomainAccount) { require( msg.sender == address(getCrossDomainMessenger()), "OVM_XCHAIN: messenger contract unauthenticated" ); require( getCrossDomainMessenger().xDomainMessageSender() == _sourceDomainAccount, "OVM_XCHAIN: wrong sender of cross-domain message" ); _; } /********************** * Internal Functions * **********************/ /** * Gets the messenger, usually from storage. This function is exposed in case a child contract * needs to override. * @return The address of the cross-domain messenger contract which should be used. */ function getCrossDomainMessenger() internal virtual returns (ICrossDomainMessenger) { return ICrossDomainMessenger(messenger); } /**q * Sends a message to an account on another domain * @param _crossDomainTarget The intended recipient on the destination domain * @param _message The data to send to the target (usually calldata to a function with * `onlyFromCrossDomainAccount()`) * @param _gasLimit The gasLimit for the receipt of the message on the target domain. */ function sendCrossDomainMessage( address _crossDomainTarget, uint32 _gasLimit, bytes memory _message ) internal { // slither-disable-next-line reentrancy-events, reentrancy-benign getCrossDomainMessenger().sendMessage(_crossDomainTarget, _message, _gasLimit); } }
contracts/libraries/bridge/ICrossDomainMessenger.sol
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.9.0; /** * @title ICrossDomainMessenger */ interface ICrossDomainMessenger { /********** * Events * **********/ event SentMessage( address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit ); event RelayedMessage(bytes32 indexed msgHash); event FailedRelayedMessage(bytes32 indexed msgHash); event RelayedFastMessage( address indexed target, address sender, bytes message, uint256 messageNonce ); event FailedRelayedFastMessage( address indexed target, address sender, bytes message, uint256 messageNonce ); /************* * Variables * *************/ function xDomainMessageSender() external view returns (address); /******************** * Public Functions * ********************/ /** * Sends a cross domain message to the target messenger. * @param _target Target contract address. * @param _message Message to send to the target. * @param _gasLimit Gas limit for the provided message. */ function sendMessage( address _target, bytes calldata _message, uint32 _gasLimit ) external; }
contracts/libraries/constants/Lib_PredeployAddresses.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /** * @title Lib_PredeployAddresses */ library Lib_PredeployAddresses { address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000; address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001; address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002; address payable internal constant OVM_ETH = payable(0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000); address internal constant L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000007; address internal constant LIB_ADDRESS_MANAGER = 0x4200000000000000000000000000000000000008; address internal constant PROXY_EOA = 0x4200000000000000000000000000000000000009; address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010; address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011; address internal constant L2_STANDARD_TOKEN_FACTORY = 0x4200000000000000000000000000000000000012; address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013; }
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":10000,"enabled":true},"metadata":{"useLiteralContent":true},"libraries":{}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_l2CrossDomainMessenger","internalType":"address"},{"type":"address","name":"_l1TokenBridge","internalType":"address"}]},{"type":"event","name":"DepositFailed","inputs":[{"type":"address","name":"_l1Token","internalType":"address","indexed":true},{"type":"address","name":"_l2Token","internalType":"address","indexed":true},{"type":"address","name":"_from","internalType":"address","indexed":true},{"type":"address","name":"_to","internalType":"address","indexed":false},{"type":"uint256","name":"_amount","internalType":"uint256","indexed":false},{"type":"bytes","name":"_data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"DepositFinalized","inputs":[{"type":"address","name":"_l1Token","internalType":"address","indexed":true},{"type":"address","name":"_l2Token","internalType":"address","indexed":true},{"type":"address","name":"_from","internalType":"address","indexed":true},{"type":"address","name":"_to","internalType":"address","indexed":false},{"type":"uint256","name":"_amount","internalType":"uint256","indexed":false},{"type":"bytes","name":"_data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"WithdrawalInitiated","inputs":[{"type":"address","name":"_l1Token","internalType":"address","indexed":true},{"type":"address","name":"_l2Token","internalType":"address","indexed":true},{"type":"address","name":"_from","internalType":"address","indexed":true},{"type":"address","name":"_to","internalType":"address","indexed":false},{"type":"uint256","name":"_amount","internalType":"uint256","indexed":false},{"type":"bytes","name":"_data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"finalizeDeposit","inputs":[{"type":"address","name":"_l1Token","internalType":"address"},{"type":"address","name":"_l2Token","internalType":"address"},{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"l1TokenBridge","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"messenger","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"address","name":"_l2Token","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"uint32","name":"_l1Gas","internalType":"uint32"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawTo","inputs":[{"type":"address","name":"_l2Token","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"uint32","name":"_l1Gas","internalType":"uint32"},{"type":"bytes","name":"_data","internalType":"bytes"}]}]
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100675760003560e01c80633cb747bf116100505780633cb747bf146100ca578063662a633a146100ea578063a3a79548146100fd57600080fd5b806332b7006d1461006c57806336c717c114610081575b600080fd5b61007f61007a366004610d0f565b610110565b005b6001546100a19073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6000546100a19073ffffffffffffffffffffffffffffffffffffffff1681565b61007f6100f8366004610d80565b610126565b61007f61010b366004610e18565b6106c1565b61011f853333878787876106d8565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661015e60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461021d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e7469636174656400000000000000000000000000000000000060648201526084015b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661025360005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b15801561029857600080fd5b505afa1580156102ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d09190610e9b565b73ffffffffffffffffffffffffffffffffffffffff1614610373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610214565b61039d877f1d1d8b6300000000000000000000000000000000000000000000000000000000610a32565b801561045357508673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156103ec57600080fd5b505af1158015610400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104249190610e9b565b73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16145b15610567576040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152602482018690528816906340c10f1990604401600060405180830381600087803b1580156104c857600080fd5b505af11580156104dc573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898888888860405161055a9493929190610f08565b60405180910390a46106b7565b600063a9f9e67560e01b8989888a89898960405160240161058e9796959493929190610f3e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001549091506106339073ffffffffffffffffffffffffffffffffffffffff16600083610a57565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f7ea89a4591614515571c2b51f5ea06494056f261c10ab1ed8c03c7590d87bce0898989896040516106ad9493929190610f08565b60405180910390a4505b5050505050505050565b6106d0863387878787876106d8565b505050505050565b6040517f9dc29fac0000000000000000000000000000000000000000000000000000000081523360048201526024810185905273ffffffffffffffffffffffffffffffffffffffff881690639dc29fac90604401600060405180830381600087803b15801561074657600080fd5b505af115801561075a573d6000803e3d6000fd5b5050505060008773ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156107a857600080fd5b505af11580156107bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e09190610e9b565b9050606073ffffffffffffffffffffffffffffffffffffffff891673deaddeaddeaddeaddeaddeaddeaddeaddead000014156108d5576040517f1532ec340000000000000000000000000000000000000000000000000000000090610851908a908a908a9089908990602401610f9b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050610994565b6040517fa9f9e67500000000000000000000000000000000000000000000000000000000906109149084908c908c908c908c908b908b90602401610f3e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290505b6001546109b89073ffffffffffffffffffffffffffffffffffffffff168683610a57565b3373ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e8a8a89896040516106ad9493929190610f08565b6000610a3d83610ae8565b8015610a4e5750610a4e8383610b4c565b90505b92915050565b6000546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b90610ab190869085908790600401611016565b600060405180830381600087803b158015610acb57600080fd5b505af1158015610adf573d6000803e3d6000fd5b50505050505050565b6000610b14827f01ffc9a700000000000000000000000000000000000000000000000000000000610b4c565b8015610a515750610b45827fffffffff00000000000000000000000000000000000000000000000000000000610b4c565b1592915050565b604080517fffffffff00000000000000000000000000000000000000000000000000000000831660248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a7000000000000000000000000000000000000000000000000000000001790529051600091908290819073ffffffffffffffffffffffffffffffffffffffff87169061753090610c06908690611092565b6000604051808303818686fa925050503d8060008114610c42576040519150601f19603f3d011682016040523d82523d6000602084013e610c47565b606091505b5091509150602081511015610c625760009350505050610a51565b818015610c7e575080806020019051810190610c7e91906110ae565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610caa57600080fd5b50565b803563ffffffff81168114610cc157600080fd5b919050565b60008083601f840112610cd857600080fd5b50813567ffffffffffffffff811115610cf057600080fd5b602083019150836020828501011115610d0857600080fd5b9250929050565b600080600080600060808688031215610d2757600080fd5b8535610d3281610c88565b945060208601359350610d4760408701610cad565b9250606086013567ffffffffffffffff811115610d6357600080fd5b610d6f88828901610cc6565b969995985093965092949392505050565b600080600080600080600060c0888a031215610d9b57600080fd5b8735610da681610c88565b96506020880135610db681610c88565b95506040880135610dc681610c88565b94506060880135610dd681610c88565b93506080880135925060a088013567ffffffffffffffff811115610df957600080fd5b610e058a828b01610cc6565b989b979a50959850939692959293505050565b60008060008060008060a08789031215610e3157600080fd5b8635610e3c81610c88565b95506020870135610e4c81610c88565b945060408701359350610e6160608801610cad565b9250608087013567ffffffffffffffff811115610e7d57600080fd5b610e8989828a01610cc6565b979a9699509497509295939492505050565b600060208284031215610ead57600080fd5b8151610eb881610c88565b9392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000610c7e606083018486610ebf565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a0830152610f8e60c083018486610ebf565b9998505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015260806060830152610fdb608083018486610ebf565b979650505050505050565b60005b83811015611001578181015183820152602001610fe9565b83811115611010576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260008351806060840152611051816080850160208801610fe6565b63ffffffff93909316604083015250601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160160800192915050565b600082516110a4818460208701610fe6565b9190910192915050565b6000602082840312156110c057600080fd5b81518015158114610eb857600080fdfea26469706673582212205f3ac360c4ef8ef69ee44fa77569ecf24678ca6e4e5bd57fefd8b8c3b4d4f0cd64736f6c63430008090033