Overview
ETH Balance
ETH Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Initialize | 17835144 | 1309 days ago | IN | 0 ETH | 0.000040983645 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 107551967 | 950 days ago | 0 ETH | ||||
| 107549714 | 950 days ago | 0 ETH | ||||
| 107523557 | 950 days ago | 0 ETH | ||||
| 107521262 | 950 days ago | 0 ETH | ||||
| 107511283 | 951 days ago | 0 ETH | ||||
| 107510442 | 951 days ago | 0 ETH | ||||
| 107473612 | 951 days ago | 0 ETH | ||||
| 107472118 | 951 days ago | 0 ETH | ||||
| 107456082 | 952 days ago | 0 ETH | ||||
| 107435190 | 952 days ago | 0 ETH | ||||
| 107430930 | 952 days ago | 0 ETH | ||||
| 107423887 | 953 days ago | 0 ETH | ||||
| 107390154 | 953 days ago | 0 ETH | ||||
| 107375621 | 954 days ago | 0 ETH | ||||
| 107370791 | 954 days ago | 0 ETH | ||||
| 107366573 | 954 days ago | 0 ETH | ||||
| 107365924 | 954 days ago | 0 ETH | ||||
| 107364224 | 954 days ago | 0 ETH | ||||
| 107362002 | 954 days ago | 0 ETH | ||||
| 107348620 | 954 days ago | 0 ETH | ||||
| 107339727 | 955 days ago | 0 ETH | ||||
| 107329689 | 955 days ago | 0 ETH | ||||
| 107314344 | 955 days ago | 0 ETH | ||||
| 107271257 | 956 days ago | 0 ETH | ||||
| 107269069 | 956 days ago | 0 ETH |
Cross-Chain Transactions
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-FileCopyrightText: 2022 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; import {IL1ERC20Bridge} from "./interfaces/IL1ERC20Bridge.sol"; import {IL2ERC20Bridge} from "./interfaces/IL2ERC20Bridge.sol"; import {IERC20Bridged} from "../token/interfaces/IERC20Bridged.sol"; import {BridgingManager} from "../BridgingManager.sol"; import {BridgeableTokens} from "../BridgeableTokens.sol"; import {CrossDomainEnabled} from "./CrossDomainEnabled.sol"; /// @author psirex /// @notice The L2 token bridge works with the L1 token bridge to enable ERC20 token bridging /// between L1 and L2. It acts as a minter for new tokens when it hears about /// deposits into the L1 token bridge. It also acts as a burner of the tokens /// intended for withdrawal, informing the L1 bridge to release L1 funds. Additionally, adds /// the methods for bridging management: enabling and disabling withdrawals/deposits contract L2ERC20TokenBridge is IL2ERC20Bridge, BridgingManager, BridgeableTokens, CrossDomainEnabled { /// @inheritdoc IL2ERC20Bridge address public immutable l1TokenBridge; /// @param messenger_ L2 messenger address being used for cross-chain communications /// @param l1TokenBridge_ Address of the corresponding L1 bridge /// @param l1Token_ Address of the bridged token in the L1 chain /// @param l2Token_ Address of the token minted on the L2 chain when token bridged constructor( address messenger_, address l1TokenBridge_, address l1Token_, address l2Token_ ) CrossDomainEnabled(messenger_) BridgeableTokens(l1Token_, l2Token_) { l1TokenBridge = l1TokenBridge_; } /// @inheritdoc IL2ERC20Bridge function withdraw( address l2Token_, uint256 amount_, uint32 l1Gas_, bytes calldata data_ ) external whenWithdrawalsEnabled onlySupportedL2Token(l2Token_) { _initiateWithdrawal(msg.sender, msg.sender, amount_, l1Gas_, data_); } /// @inheritdoc IL2ERC20Bridge function withdrawTo( address l2Token_, address to_, uint256 amount_, uint32 l1Gas_, bytes calldata data_ ) external whenWithdrawalsEnabled onlySupportedL2Token(l2Token_) { _initiateWithdrawal(msg.sender, to_, amount_, l1Gas_, data_); } /// @inheritdoc IL2ERC20Bridge function finalizeDeposit( address l1Token_, address l2Token_, address from_, address to_, uint256 amount_, bytes calldata data_ ) external whenDepositsEnabled onlySupportedL1Token(l1Token_) onlySupportedL2Token(l2Token_) onlyFromCrossDomainAccount(l1TokenBridge) { IERC20Bridged(l2Token_).bridgeMint(to_, amount_); emit DepositFinalized(l1Token_, l2Token_, from_, to_, amount_, data_); } /// @notice Performs the logic for withdrawals by burning the token and informing /// the L1 token Gateway of the withdrawal /// @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 from_, address to_, uint256 amount_, uint32 l1Gas_, bytes calldata data_ ) internal { IERC20Bridged(l2Token).bridgeBurn(from_, amount_); bytes memory message = abi.encodeWithSelector( IL1ERC20Bridge.finalizeERC20Withdrawal.selector, l1Token, l2Token, from_, to_, amount_, data_ ); sendCrossDomainMessage(l1TokenBridge, l1Gas_, message); emit WithdrawalInitiated(l1Token, l2Token, from_, to_, amount_, data_); } }
// SPDX-FileCopyrightText: 2022 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; /// @notice The L1 Standard bridge locks bridged tokens on the L1 side, sends deposit messages /// on the L2 side, and finalizes token withdrawals from L2. interface IL1ERC20Bridge { 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 ); /// @notice get the address of the corresponding L2 bridge contract. /// @return Address of the corresponding L2 bridge contract. function l2TokenBridge() external returns (address); /// @notice 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; /// @notice 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; /// @notice Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the /// L1 ERC20 token. /// @dev 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; }
// SPDX-FileCopyrightText: 2022 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; /// @notice The L2 token bridge works with the L1 token bridge to enable ERC20 token bridging /// between L1 and L2. It acts as a minter for new tokens when it hears about /// deposits into the L1 token bridge. It also acts as a burner of the tokens /// intended for withdrawal, informing the L1 bridge to release L1 funds. interface IL2ERC20Bridge { 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 ); /// @notice Returns the address of the corresponding L1 bridge contract function l1TokenBridge() external returns (address); /// @notice Initiates 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; /// @notice Initiates 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; /// @notice Completes 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; }
// SPDX-FileCopyrightText: 2022 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /// @author psirex /// @notice Extends the ERC20 functionality that allows the bridge to mint/burn tokens interface IERC20Bridged is IERC20 { /// @notice Returns bridge which can mint and burn tokens on L2 function bridge() external view returns (address); /// @notice Creates amount_ tokens and assigns them to account_, increasing the total supply /// @param account_ An address of the account to mint tokens /// @param amount_ An amount of tokens to mint function bridgeMint(address account_, uint256 amount_) external; /// @notice Destroys amount_ tokens from account_, reducing the total supply /// @param account_ An address of the account to burn tokens /// @param amount_ An amount of tokens to burn function bridgeBurn(address account_, uint256 amount_) external; }
// SPDX-FileCopyrightText: 2022 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; /// @author psirex /// @notice Contains administrative methods to retrieve and control the state of the bridging contract BridgingManager is AccessControl { /// @dev Stores the state of the bridging /// @param isInitialized Shows whether the contract is initialized or not /// @param isDepositsEnabled Stores the state of the deposits /// @param isWithdrawalsEnabled Stores the state of the withdrawals struct State { bool isInitialized; bool isDepositsEnabled; bool isWithdrawalsEnabled; } bytes32 public constant DEPOSITS_ENABLER_ROLE = keccak256("BridgingManager.DEPOSITS_ENABLER_ROLE"); bytes32 public constant DEPOSITS_DISABLER_ROLE = keccak256("BridgingManager.DEPOSITS_DISABLER_ROLE"); bytes32 public constant WITHDRAWALS_ENABLER_ROLE = keccak256("BridgingManager.WITHDRAWALS_ENABLER_ROLE"); bytes32 public constant WITHDRAWALS_DISABLER_ROLE = keccak256("BridgingManager.WITHDRAWALS_DISABLER_ROLE"); /// @dev The location of the slot with State bytes32 private constant STATE_SLOT = keccak256("BridgingManager.bridgingState"); /// @notice Initializes the contract to grant DEFAULT_ADMIN_ROLE to the admin_ address /// @dev This method might be called only once /// @param admin_ Address of the account to grant the DEFAULT_ADMIN_ROLE function initialize(address admin_) external { State storage s = _loadState(); if (s.isInitialized) { revert ErrorAlreadyInitialized(); } _setupRole(DEFAULT_ADMIN_ROLE, admin_); s.isInitialized = true; emit Initialized(admin_); } /// @notice Returns whether the contract is initialized or not function isInitialized() public view returns (bool) { return _loadState().isInitialized; } /// @notice Returns whether the deposits are enabled or not function isDepositsEnabled() public view returns (bool) { return _loadState().isDepositsEnabled; } /// @notice Returns whether the withdrawals are enabled or not function isWithdrawalsEnabled() public view returns (bool) { return _loadState().isWithdrawalsEnabled; } /// @notice Enables the deposits if they are disabled function enableDeposits() external onlyRole(DEPOSITS_ENABLER_ROLE) { if (isDepositsEnabled()) { revert ErrorDepositsEnabled(); } _loadState().isDepositsEnabled = true; emit DepositsEnabled(msg.sender); } /// @notice Disables the deposits if they aren't disabled yet function disableDeposits() external whenDepositsEnabled onlyRole(DEPOSITS_DISABLER_ROLE) { _loadState().isDepositsEnabled = false; emit DepositsDisabled(msg.sender); } /// @notice Enables the withdrawals if they are disabled function enableWithdrawals() external onlyRole(WITHDRAWALS_ENABLER_ROLE) { if (isWithdrawalsEnabled()) { revert ErrorWithdrawalsEnabled(); } _loadState().isWithdrawalsEnabled = true; emit WithdrawalsEnabled(msg.sender); } /// @notice Disables the withdrawals if they aren't disabled yet function disableWithdrawals() external whenWithdrawalsEnabled onlyRole(WITHDRAWALS_DISABLER_ROLE) { _loadState().isWithdrawalsEnabled = false; emit WithdrawalsDisabled(msg.sender); } /// @dev Returns the reference to the slot with State struct function _loadState() private pure returns (State storage r) { bytes32 slot = STATE_SLOT; assembly { r.slot := slot } } /// @dev Validates that deposits are enabled modifier whenDepositsEnabled() { if (!isDepositsEnabled()) { revert ErrorDepositsDisabled(); } _; } /// @dev Validates that withdrawals are enabled modifier whenWithdrawalsEnabled() { if (!isWithdrawalsEnabled()) { revert ErrorWithdrawalsDisabled(); } _; } event DepositsEnabled(address indexed enabler); event DepositsDisabled(address indexed disabler); event WithdrawalsEnabled(address indexed enabler); event WithdrawalsDisabled(address indexed disabler); event Initialized(address indexed admin); error ErrorDepositsEnabled(); error ErrorDepositsDisabled(); error ErrorWithdrawalsEnabled(); error ErrorWithdrawalsDisabled(); error ErrorAlreadyInitialized(); }
// SPDX-FileCopyrightText: 2022 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; /// @author psirex /// @notice Contains the logic for validation of tokens used in the bridging process contract BridgeableTokens { /// @notice Address of the bridged token in the L1 chain address public immutable l1Token; /// @notice Address of the token minted on the L2 chain when token bridged address public immutable l2Token; /// @param l1Token_ Address of the bridged token in the L1 chain /// @param l2Token_ Address of the token minted on the L2 chain when token bridged constructor(address l1Token_, address l2Token_) { l1Token = l1Token_; l2Token = l2Token_; } /// @dev Validates that passed l1Token_ is supported by the bridge modifier onlySupportedL1Token(address l1Token_) { if (l1Token_ != l1Token) { revert ErrorUnsupportedL1Token(); } _; } /// @dev Validates that passed l2Token_ is supported by the bridge modifier onlySupportedL2Token(address l2Token_) { if (l2Token_ != l2Token) { revert ErrorUnsupportedL2Token(); } _; } /// @dev validates that account_ is not zero address modifier onlyNonZeroAccount(address account_) { if (account_ == address(0)) { revert ErrorAccountIsZeroAddress(); } _; } error ErrorUnsupportedL1Token(); error ErrorUnsupportedL2Token(); error ErrorAccountIsZeroAddress(); }
// SPDX-FileCopyrightText: 2022 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; import {ICrossDomainMessenger} from "./interfaces/ICrossDomainMessenger.sol"; /// @dev Helper contract for contracts performing cross-domain communications contract CrossDomainEnabled { /// @notice Messenger contract used to send and receive messages from the other domain ICrossDomainMessenger public immutable messenger; /// @param messenger_ Address of the CrossDomainMessenger on the current layer constructor(address messenger_) { messenger = ICrossDomainMessenger(messenger_); } /// @dev Sends a message to an account on another domain /// @param crossDomainTarget_ Intended recipient on the destination domain /// @param message_ Data to send to the target (usually calldata to a function with /// `onlyFromCrossDomainAccount()`) /// @param gasLimit_ gasLimit for the receipt of the message on the target domain. function sendCrossDomainMessage( address crossDomainTarget_, uint32 gasLimit_, bytes memory message_ ) internal { messenger.sendMessage(crossDomainTarget_, message_, gasLimit_); } /// @dev 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_) { if (msg.sender != address(messenger)) { revert ErrorUnauthorizedMessenger(); } if (messenger.xDomainMessageSender() != sourceDomainAccount_) { revert ErrorWrongCrossDomainSender(); } _; } error ErrorUnauthorizedMessenger(); error ErrorWrongCrossDomainSender(); }
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControl.sol)
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with a standardized message including the required role.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*
* _Available since v4.1._
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
/**
* @dev Revert with a standard message if `_msgSender()` is missing `role`.
* Overriding this function changes the behavior of the {onlyRole} modifier.
*
* Format of the revert message is described in {_checkRole}.
*
* _Available since v4.6._
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Revert with a standard message if `account` is missing `role`.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(uint160(account), 20),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*
* NOTE: This function is deprecated in favor of {_grantRole}.
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Grants `role` to `account`.
*
* Internal function without access restriction.
*/
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
/**
* @dev Revokes `role` from `account`.
*
* Internal function without access restriction.
*/
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
pragma solidity ^0.8.0;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
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);
}// SPDX-FileCopyrightText: 2022 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; interface ICrossDomainMessenger { function xDomainMessageSender() external view returns (address); /// 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; }
{
"optimizer": {
"enabled": true,
"runs": 100000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"messenger_","type":"address"},{"internalType":"address","name":"l1TokenBridge_","type":"address"},{"internalType":"address","name":"l1Token_","type":"address"},{"internalType":"address","name":"l2Token_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ErrorAccountIsZeroAddress","type":"error"},{"inputs":[],"name":"ErrorAlreadyInitialized","type":"error"},{"inputs":[],"name":"ErrorDepositsDisabled","type":"error"},{"inputs":[],"name":"ErrorDepositsEnabled","type":"error"},{"inputs":[],"name":"ErrorUnauthorizedMessenger","type":"error"},{"inputs":[],"name":"ErrorUnsupportedL1Token","type":"error"},{"inputs":[],"name":"ErrorUnsupportedL2Token","type":"error"},{"inputs":[],"name":"ErrorWithdrawalsDisabled","type":"error"},{"inputs":[],"name":"ErrorWithdrawalsEnabled","type":"error"},{"inputs":[],"name":"ErrorWrongCrossDomainSender","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_l1Token","type":"address"},{"indexed":true,"internalType":"address","name":"_l2Token","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"DepositFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_l1Token","type":"address"},{"indexed":true,"internalType":"address","name":"_l2Token","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"DepositFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"disabler","type":"address"}],"name":"DepositsDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"enabler","type":"address"}],"name":"DepositsEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_l1Token","type":"address"},{"indexed":true,"internalType":"address","name":"_l2Token","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"WithdrawalInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"disabler","type":"address"}],"name":"WithdrawalsDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"enabler","type":"address"}],"name":"WithdrawalsEnabled","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSITS_DISABLER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSITS_ENABLER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WITHDRAWALS_DISABLER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WITHDRAWALS_ENABLER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"l1Token_","type":"address"},{"internalType":"address","name":"l2Token_","type":"address"},{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"finalizeDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isDepositsEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWithdrawalsEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l1Token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l1TokenBridge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2Token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messenger","outputs":[{"internalType":"contract ICrossDomainMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"l2Token_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint32","name":"l1Gas_","type":"uint32"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"l2Token_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint32","name":"l1Gas_","type":"uint32"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"withdrawTo","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6101006040523480156200001257600080fd5b506040516200212d3803806200212d833981016040819052620000359162000075565b6001600160a01b03918216608052811660a05291821660c0521660e052620000d2565b80516001600160a01b03811681146200007057600080fd5b919050565b600080600080608085870312156200008c57600080fd5b620000978562000058565b9350620000a76020860162000058565b9250620000b76040860162000058565b9150620000c76060860162000058565b905092959194509250565b60805160a05160c05160e051611fbf6200016e6000396000818161024c015281816109cf01526113f40152600081816102c201528181610a0601528181610a7601526116b30152600081816102e90152818161060c0152818161094a01528181610cca015281816112ad015281816113360152611433015260008181610447015281816108c401528181611315015261146a0152611fbf6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80636f18bd22116100ee578063ad960ce111610097578063d547741f11610071578063d547741f1461047c578063e3b523e31461048f578063e8bac93b146104b6578063fadcc54a146104be57600080fd5b8063ad960ce11461043a578063c01e1bd614610442578063c4d66de81461046957600080fd5b8063a217fddf116100c8578063a217fddf14610417578063a3a795481461041f578063ac67e1af1461043257600080fd5b80636f18bd22146103855780638d7601c0146103ac57806391d14854146103d357600080fd5b8063392e53cd1161015b5780635777bf50116101355780635777bf501461030b5780635e4c57a41461033a5780635ed2c22014610342578063662a633a1461037257600080fd5b8063392e53cd146102935780633cb747bf146102bd57806356eff267146102e457600080fd5b806332b7006d1161018c57806332b7006d1461022157806336568abe1461023457806336c717c11461024757600080fd5b806301ffc9a7146101b3578063248a9ca3146101db5780632f2ff15d1461020c575b600080fd5b6101c66101c1366004611964565b6104e5565b60405190151581526020015b60405180910390f35b6101fe6101e93660046119a6565b60009081526020819052604090206001015490565b6040519081526020016101d2565b61021f61021a3660046119e1565b61057e565b005b61021f61022f366004611a73565b6105a8565b61021f6102423660046119e1565b6106a5565b61026e7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5460ff166101c6565b61026e7f000000000000000000000000000000000000000000000000000000000000000081565b61026e7f000000000000000000000000000000000000000000000000000000000000000081565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba54610100900460ff166101c6565b61021f61075d565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5462010000900460ff166101c6565b61021f610380366004611ae4565b610861565b6101fe7f63f736f21cb2943826cd50b191eb054ebbea670e4e962d0527611f830cd399d681565b6101fe7f94a954c0bc99227eddbc0715a62a7e1056ed8784cd719c2303b685683908857c81565b6101c66103e13660046119e1565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b6101fe600081565b61021f61042d366004611b7c565b610c66565b61021f610d64565b61021f610e63565b61026e7f000000000000000000000000000000000000000000000000000000000000000081565b61021f610477366004611bff565b610f63565b61021f61048a3660046119e1565b611039565b6101fe7f9ab8816a3dc0b3849ec1ac00483f6ec815b07eee2fd766a353311c823ad59d0d81565b61021f61105e565b6101fe7f4b43b36766bde12c5e9cbbc37d15f8d1f769f08f54720ab370faeb4ce893753a81565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061057857507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60008281526020819052604090206001015461059981611164565b6105a38383611171565b505050565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5462010000900460ff16610609576040517f77d195b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461068f576040517f6251ce6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61069d333387878787611261565b505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116331461074f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b61075982826114e5565b5050565b7f4b43b36766bde12c5e9cbbc37d15f8d1f769f08f54720ab370faeb4ce893753a61078781611164565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba54610100900460ff16156107e8576040517f4f2c8be200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010017905560405133907fc36a428b063177e3f28b3b5d340c08f77827847b2ee30114ccf0c40e519c420a90600090a250565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba54610100900460ff166108c1576040517fa185a6b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b867f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610947576040517ffe15603f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b867f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109cd576040517f6251ce6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610a5d576040517ff95a18f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610adf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b039190611c1c565b73ffffffffffffffffffffffffffffffffffffffff1614610b50576040517fe36e2eb200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f8c2a993e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018890528a1690638c2a993e90604401600060405180830381600087803b158015610bc057600080fd5b505af1158015610bd4573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898a8a8a8a604051610c529493929190611c82565b60405180910390a450505050505050505050565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5462010000900460ff16610cc7576040517f77d195b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d4d576040517f6251ce6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d5b338787878787611261565b50505050505050565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba54610100900460ff16610dc4576040517fa185a6b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f63f736f21cb2943826cd50b191eb054ebbea670e4e962d0527611f830cd399d6610dee81611164565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405133907f9ca4d309bbfd23c65db3dc38c1712862f5812c7139937e2655de86e803f73bb990600090a250565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5462010000900460ff16610ec4576040517f77d195b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f94a954c0bc99227eddbc0715a62a7e1056ed8784cd719c2303b685683908857c610eee81611164565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff16905560405133907f644eeba8ede48fefc32ada09fb240c5f6c0f06507ab1d296d5af41f1521d9fcb90600090a250565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba805460ff1615610fc0576040517f66a02dea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610fcb60008361159c565b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117815560405173ffffffffffffffffffffffffffffffffffffffff8316907f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e690600090a25050565b60008281526020819052604090206001015461105481611164565b6105a383836114e5565b7f9ab8816a3dc0b3849ec1ac00483f6ec815b07eee2fd766a353311c823ad59d0d61108881611164565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5462010000900460ff16156110ea576040517ff74ad25400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff166201000017905560405133907fb2ed3603bd9051f0182ebfb75f12a21059b4d31b578a2a05c8d0245e9e2d320490600090a250565b61116e81336115a6565b50565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166107595760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556112033390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6040517f74f4f54700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018690527f000000000000000000000000000000000000000000000000000000000000000016906374f4f54790604401600060405180830381600087803b1580156112f157600080fd5b505af1158015611305573d6000803e3d6000fd5b50505050600063a9f9e67560e01b7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000089898988886040516024016113709796959493929190611cc2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905061141a7f00000000000000000000000000000000000000000000000000000000000000008583611676565b8673ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e898988886040516114d49493929190611c82565b60405180910390a450505050505050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156107595760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6107598282611171565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610759576115fc8173ffffffffffffffffffffffffffffffffffffffff16601461171a565b61160783602061171a565b604051602001611618929190611d4f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825261074691600401611e1a565b6040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690633dbb202b906116ec90869085908790600401611e2d565b600060405180830381600087803b15801561170657600080fd5b505af1158015610d5b573d6000803e3d6000fd5b60606000611729836002611ea1565b611734906002611ede565b67ffffffffffffffff81111561174c5761174c611ef6565b6040519080825280601f01601f191660200182016040528015611776576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106117ad576117ad611f25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061181057611810611f25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061184c846002611ea1565b611857906001611ede565b90505b60018111156118f4577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061189857611898611f25565b1a60f81b8282815181106118ae576118ae611f25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936118ed81611f54565b905061185a565b50831561195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610746565b9392505050565b60006020828403121561197657600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461195d57600080fd5b6000602082840312156119b857600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461116e57600080fd5b600080604083850312156119f457600080fd5b823591506020830135611a06816119bf565b809150509250929050565b803563ffffffff81168114611a2557600080fd5b919050565b60008083601f840112611a3c57600080fd5b50813567ffffffffffffffff811115611a5457600080fd5b602083019150836020828501011115611a6c57600080fd5b9250929050565b600080600080600060808688031215611a8b57600080fd5b8535611a96816119bf565b945060208601359350611aab60408701611a11565b9250606086013567ffffffffffffffff811115611ac757600080fd5b611ad388828901611a2a565b969995985093965092949392505050565b600080600080600080600060c0888a031215611aff57600080fd5b8735611b0a816119bf565b96506020880135611b1a816119bf565b95506040880135611b2a816119bf565b94506060880135611b3a816119bf565b93506080880135925060a088013567ffffffffffffffff811115611b5d57600080fd5b611b698a828b01611a2a565b989b979a50959850939692959293505050565b60008060008060008060a08789031215611b9557600080fd5b8635611ba0816119bf565b95506020870135611bb0816119bf565b945060408701359350611bc560608801611a11565b9250608087013567ffffffffffffffff811115611be157600080fd5b611bed89828a01611a2a565b979a9699509497509295939492505050565b600060208284031215611c1157600080fd5b813561195d816119bf565b600060208284031215611c2e57600080fd5b815161195d816119bf565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000611cb8606083018486611c39565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a0830152611d1260c083018486611c39565b9998505050505050505050565b60005b83811015611d3a578181015183820152602001611d22565b83811115611d49576000848401525b50505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611d87816017850160208801611d1f565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351611dc4816028840160208801611d1f565b01602801949350505050565b60008151808452611de8816020860160208601611d1f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061195d6020830184611dd0565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000611e5c6060830185611dd0565b905063ffffffff83166040830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611ed957611ed9611e72565b500290565b60008219821115611ef157611ef1611e72565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081611f6357611f63611e72565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212206d065a0824683b4fdcd6ceb8613fe303c31f956e48f2eaded83309c2668c345a64736f6c634300080a0033000000000000000000000000420000000000000000000000000000000000000700000000000000000000000076943c0d61395d8f2edf9060e1533529cae05de60000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca00000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101ae5760003560e01c80636f18bd22116100ee578063ad960ce111610097578063d547741f11610071578063d547741f1461047c578063e3b523e31461048f578063e8bac93b146104b6578063fadcc54a146104be57600080fd5b8063ad960ce11461043a578063c01e1bd614610442578063c4d66de81461046957600080fd5b8063a217fddf116100c8578063a217fddf14610417578063a3a795481461041f578063ac67e1af1461043257600080fd5b80636f18bd22146103855780638d7601c0146103ac57806391d14854146103d357600080fd5b8063392e53cd1161015b5780635777bf50116101355780635777bf501461030b5780635e4c57a41461033a5780635ed2c22014610342578063662a633a1461037257600080fd5b8063392e53cd146102935780633cb747bf146102bd57806356eff267146102e457600080fd5b806332b7006d1161018c57806332b7006d1461022157806336568abe1461023457806336c717c11461024757600080fd5b806301ffc9a7146101b3578063248a9ca3146101db5780632f2ff15d1461020c575b600080fd5b6101c66101c1366004611964565b6104e5565b60405190151581526020015b60405180910390f35b6101fe6101e93660046119a6565b60009081526020819052604090206001015490565b6040519081526020016101d2565b61021f61021a3660046119e1565b61057e565b005b61021f61022f366004611a73565b6105a8565b61021f6102423660046119e1565b6106a5565b61026e7f00000000000000000000000076943c0d61395d8f2edf9060e1533529cae05de681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5460ff166101c6565b61026e7f000000000000000000000000420000000000000000000000000000000000000781565b61026e7f0000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb81565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba54610100900460ff166101c6565b61021f61075d565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5462010000900460ff166101c6565b61021f610380366004611ae4565b610861565b6101fe7f63f736f21cb2943826cd50b191eb054ebbea670e4e962d0527611f830cd399d681565b6101fe7f94a954c0bc99227eddbc0715a62a7e1056ed8784cd719c2303b685683908857c81565b6101c66103e13660046119e1565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b6101fe600081565b61021f61042d366004611b7c565b610c66565b61021f610d64565b61021f610e63565b61026e7f0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca081565b61021f610477366004611bff565b610f63565b61021f61048a3660046119e1565b611039565b6101fe7f9ab8816a3dc0b3849ec1ac00483f6ec815b07eee2fd766a353311c823ad59d0d81565b61021f61105e565b6101fe7f4b43b36766bde12c5e9cbbc37d15f8d1f769f08f54720ab370faeb4ce893753a81565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061057857507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60008281526020819052604090206001015461059981611164565b6105a38383611171565b505050565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5462010000900460ff16610609576040517f77d195b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b847f0000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461068f576040517f6251ce6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61069d333387878787611261565b505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116331461074f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b61075982826114e5565b5050565b7f4b43b36766bde12c5e9cbbc37d15f8d1f769f08f54720ab370faeb4ce893753a61078781611164565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba54610100900460ff16156107e8576040517f4f2c8be200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010017905560405133907fc36a428b063177e3f28b3b5d340c08f77827847b2ee30114ccf0c40e519c420a90600090a250565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba54610100900460ff166108c1576040517fa185a6b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b867f0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610947576040517ffe15603f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b867f0000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109cd576040517f6251ce6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000076943c0d61395d8f2edf9060e1533529cae05de63373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000042000000000000000000000000000000000000071614610a5d576040517ff95a18f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000420000000000000000000000000000000000000773ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610adf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b039190611c1c565b73ffffffffffffffffffffffffffffffffffffffff1614610b50576040517fe36e2eb200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f8c2a993e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018890528a1690638c2a993e90604401600060405180830381600087803b158015610bc057600080fd5b505af1158015610bd4573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898a8a8a8a604051610c529493929190611c82565b60405180910390a450505050505050505050565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5462010000900460ff16610cc7576040517f77d195b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b857f0000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d4d576040517f6251ce6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d5b338787878787611261565b50505050505050565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba54610100900460ff16610dc4576040517fa185a6b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f63f736f21cb2943826cd50b191eb054ebbea670e4e962d0527611f830cd399d6610dee81611164565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405133907f9ca4d309bbfd23c65db3dc38c1712862f5812c7139937e2655de86e803f73bb990600090a250565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5462010000900460ff16610ec4576040517f77d195b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f94a954c0bc99227eddbc0715a62a7e1056ed8784cd719c2303b685683908857c610eee81611164565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff16905560405133907f644eeba8ede48fefc32ada09fb240c5f6c0f06507ab1d296d5af41f1521d9fcb90600090a250565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba805460ff1615610fc0576040517f66a02dea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610fcb60008361159c565b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117815560405173ffffffffffffffffffffffffffffffffffffffff8316907f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e690600090a25050565b60008281526020819052604090206001015461105481611164565b6105a383836114e5565b7f9ab8816a3dc0b3849ec1ac00483f6ec815b07eee2fd766a353311c823ad59d0d61108881611164565b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba5462010000900460ff16156110ea576040517ff74ad25400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f013e929b381f2fbbac854bd18fb8231dc73c4a2eab0d4cbb4db9436b6ff9b2ba80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff166201000017905560405133907fb2ed3603bd9051f0182ebfb75f12a21059b4d31b578a2a05c8d0245e9e2d320490600090a250565b61116e81336115a6565b50565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166107595760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556112033390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6040517f74f4f54700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018690527f0000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb16906374f4f54790604401600060405180830381600087803b1580156112f157600080fd5b505af1158015611305573d6000803e3d6000fd5b50505050600063a9f9e67560e01b7f0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca07f0000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb89898988886040516024016113709796959493929190611cc2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905061141a7f00000000000000000000000076943c0d61395d8f2edf9060e1533529cae05de68583611676565b8673ffffffffffffffffffffffffffffffffffffffff167f0000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb73ffffffffffffffffffffffffffffffffffffffff167f0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e898988886040516114d49493929190611c82565b60405180910390a450505050505050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156107595760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6107598282611171565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610759576115fc8173ffffffffffffffffffffffffffffffffffffffff16601461171a565b61160783602061171a565b604051602001611618929190611d4f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825261074691600401611e1a565b6040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000042000000000000000000000000000000000000071690633dbb202b906116ec90869085908790600401611e2d565b600060405180830381600087803b15801561170657600080fd5b505af1158015610d5b573d6000803e3d6000fd5b60606000611729836002611ea1565b611734906002611ede565b67ffffffffffffffff81111561174c5761174c611ef6565b6040519080825280601f01601f191660200182016040528015611776576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106117ad576117ad611f25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061181057611810611f25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061184c846002611ea1565b611857906001611ede565b90505b60018111156118f4577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061189857611898611f25565b1a60f81b8282815181106118ae576118ae611f25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936118ed81611f54565b905061185a565b50831561195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610746565b9392505050565b60006020828403121561197657600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461195d57600080fd5b6000602082840312156119b857600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461116e57600080fd5b600080604083850312156119f457600080fd5b823591506020830135611a06816119bf565b809150509250929050565b803563ffffffff81168114611a2557600080fd5b919050565b60008083601f840112611a3c57600080fd5b50813567ffffffffffffffff811115611a5457600080fd5b602083019150836020828501011115611a6c57600080fd5b9250929050565b600080600080600060808688031215611a8b57600080fd5b8535611a96816119bf565b945060208601359350611aab60408701611a11565b9250606086013567ffffffffffffffff811115611ac757600080fd5b611ad388828901611a2a565b969995985093965092949392505050565b600080600080600080600060c0888a031215611aff57600080fd5b8735611b0a816119bf565b96506020880135611b1a816119bf565b95506040880135611b2a816119bf565b94506060880135611b3a816119bf565b93506080880135925060a088013567ffffffffffffffff811115611b5d57600080fd5b611b698a828b01611a2a565b989b979a50959850939692959293505050565b60008060008060008060a08789031215611b9557600080fd5b8635611ba0816119bf565b95506020870135611bb0816119bf565b945060408701359350611bc560608801611a11565b9250608087013567ffffffffffffffff811115611be157600080fd5b611bed89828a01611a2a565b979a9699509497509295939492505050565b600060208284031215611c1157600080fd5b813561195d816119bf565b600060208284031215611c2e57600080fd5b815161195d816119bf565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000611cb8606083018486611c39565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a0830152611d1260c083018486611c39565b9998505050505050505050565b60005b83811015611d3a578181015183820152602001611d22565b83811115611d49576000848401525b50505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611d87816017850160208801611d1f565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351611dc4816028840160208801611d1f565b01602801949350505050565b60008151808452611de8816020860160208601611d1f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061195d6020830184611dd0565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000611e5c6060830185611dd0565b905063ffffffff83166040830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611ed957611ed9611e72565b500290565b60008219821115611ef157611ef1611e72565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081611f6357611f63611e72565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212206d065a0824683b4fdcd6ceb8613fe303c31f956e48f2eaded83309c2668c345a64736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000420000000000000000000000000000000000000700000000000000000000000076943c0d61395d8f2edf9060e1533529cae05de60000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca00000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb
-----Decoded View---------------
Arg [0] : messenger_ (address): 0x4200000000000000000000000000000000000007
Arg [1] : l1TokenBridge_ (address): 0x76943C0D61395d8F2edF9060e1533529cAe05dE6
Arg [2] : l1Token_ (address): 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0
Arg [3] : l2Token_ (address): 0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000004200000000000000000000000000000000000007
Arg [1] : 00000000000000000000000076943c0d61395d8f2edf9060e1533529cae05de6
Arg [2] : 0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0
Arg [3] : 0000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb
Net Worth in USD
Net Worth in ETH
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.