{"compiler":{"version":"0.8.9+commit.e5eed63a"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_l2Router","type":"address"},{"internalType":"address","name":"_l1Lpt","type":"address"},{"internalType":"address","name":"_l2Lpt","type":"address"},{"internalType":"address","name":"_l2LPTDataCache","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_l1Token","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"DepositFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_l1Counterpart","type":"address"}],"name":"L1CounterpartUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","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":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"TxToL1","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_l1Token","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_l2ToL1Id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_exitNum","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"WithdrawalInitiated","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"l1Token","type":"address"}],"name":"calculateL2TokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"counterpartGateway","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"finalizeInboundTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","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":"getOutboundCalldata","outputs":[{"internalType":"bytes","name":"outboundCalldata","type":"bytes"}],"stateMutability":"pure","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":[],"name":"l1Counterpart","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l1Lpt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2LPTDataCache","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2Lpt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2Router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"outboundTransfer","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"outboundTransfer","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"address","name":"_l1Counterpart","type":"address"}],"name":"setCounterpart","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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"the contract can be paused by the governor which will prevent any outbound transfers but pausing the contract does not affect inbound transfers (tokens coming from L1)","kind":"dev","methods":{"finalizeInboundTransfer(address,address,address,uint256,bytes)":{"details":"can only accept txs coming directly from L1 LPT Gateway data param is unused because no additional data is allowed from L1","params":{"_amount":"Amount of tokens transferred","_from":"Address of the sender on L1","_l1Token":"L1 Address of LPT","_to":"Recepient address on L2"}},"getOutboundCalldata(address,address,address,uint256,bytes)":{"details":"encodes the target function with its params which will be called on L1 when the message is received on L1"},"getRoleAdmin(bytes32)":{"details":"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}."},"grantRole(bytes32,address)":{"details":"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."},"hasRole(bytes32,address)":{"details":"Returns `true` if `account` has been granted `role`."},"outboundTransfer(address,address,uint256,bytes)":{"details":"no additional callhook data is allowed","params":{"_amount":"Amount of tokens to burn","_data":"Contains sender and additional data to send to L1","_l1Token":"L1 Address of LPT","_to":"Recipient address on L1"},"returns":{"_0":"ID of the withdraw tx"}},"outboundTransfer(address,address,uint256,uint256,uint256,bytes)":{"details":"no additional callhook data is allowed","params":{"_amount":"Amount of tokens to burn","_data":"Contains sender and additional data (always zero) to send to L1","_l1Token":"L1 Address of LPT","_to":"Recipient address on L1"},"returns":{"_0":"ID of the withdraw tx"}},"paused()":{"details":"Returns true if the contract is paused, and false otherwise."},"renounceRole(bytes32,address)":{"details":"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`."},"revokeRole(bytes32,address)":{"details":"Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role."},"setCounterpart(address)":{"details":"Only address with the governor role is allowed to change the value of l1Counterpart","params":{"_l1Counterpart":"L1 Address of the counterpart"}},"supportsInterface(bytes4)":{"details":"See {IERC165-supportsInterface}."}},"title":"L2LPTGateway","version":1},"userdoc":{"kind":"user","methods":{"calculateL2TokenAddress(address)":{"notice":"returns address of L2 version of LPT"},"counterpartGateway()":{"notice":"returns address of L1 LPT Gateway"},"finalizeInboundTransfer(address,address,address,uint256,bytes)":{"notice":"Receives token amount from L1 and mints the equivalent tokens to the receiving address"},"getOutboundCalldata(address,address,address,uint256,bytes)":{"notice":"Creates calldata required to send tx to L1"},"outboundTransfer(address,address,uint256,bytes)":{"notice":"Burns L2 tokens and sends a message to L1 The tokens will be received on L1 only after the wait period (7 days) is over"},"outboundTransfer(address,address,uint256,uint256,uint256,bytes)":{"notice":"Burns L2 tokens and sends a message to L1 The tokens will be received on L1 only after the wait period (7 days) is over"},"setCounterpart(address)":{"notice":"Sets address of companion L1LPTGateway"}},"notice":"Manages inbound and outbound transfers of LPT between Arbitrum Rollup and L1","version":1}},"settings":{"compilationTarget":{"contracts/L2/gateway/L2LPTGateway.sol":"L2LPTGateway"},"evmVersion":"london","libraries":{},"metadata":{"bytecodeHash":"ipfs","useLiteralContent":true},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"@openzeppelin/contracts/access/AccessControl.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n    struct RoleData {\n        mapping(address => bool) members;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with a standardized message including the required role.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     *\n     * _Available since v4.1._\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role, _msgSender());\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view override returns (bool) {\n        return _roles[role].members[account];\n    }\n\n    /**\n     * @dev Revert with a standard message if `account` is missing `role`.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     */\n    function _checkRole(bytes32 role, address account) internal view {\n        if (!hasRole(role, account)) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        \"AccessControl: account \",\n                        Strings.toHexString(uint160(account), 20),\n                        \" is missing role \",\n                        Strings.toHexString(uint256(role), 32)\n                    )\n                )\n            );\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override {\n        require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event. Note that unlike {grantRole}, this function doesn't perform any\n     * checks on the calling account.\n     *\n     * [WARNING]\n     * ====\n     * This function should only be called from the constructor when setting\n     * up the initial roles for the system.\n     *\n     * Using this function in any other way is effectively circumventing the admin\n     * system imposed by {AccessControl}.\n     * ====\n     *\n     * NOTE: This function is deprecated in favor of {_grantRole}.\n     */\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * Internal function without access restriction.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual {\n        if (!hasRole(role, account)) {\n            _roles[role].members[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * Internal function without access restriction.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual {\n        if (hasRole(role, account)) {\n            _roles[role].members[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n        }\n    }\n}\n","keccak256":"0xb9a137b317dc4806805f2259686186c0c053c32d80fe9c15ecdbf2eb1cf52849","license":"MIT"},"@openzeppelin/contracts/access/IAccessControl.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) external;\n}\n","keccak256":"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57","license":"MIT"},"@openzeppelin/contracts/security/Pausable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    bool private _paused;\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    constructor() {\n        _paused = false;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        require(!paused(), \"Pausable: paused\");\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        require(paused(), \"Pausable: not paused\");\n        _;\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n}\n","keccak256":"0xe68ed7fb8766ed1e888291f881e36b616037f852b37d96877045319ad298ba87","license":"MIT"},"@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n","keccak256":"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7","license":"MIT"},"@openzeppelin/contracts/utils/Strings.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        // Inspired by OraclizeAPI's implementation - MIT licence\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n        if (value == 0) {\n            return \"0\";\n        }\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return \"0x00\";\n        }\n        uint256 temp = value;\n        uint256 length = 0;\n        while (temp != 0) {\n            length++;\n            temp >>= 8;\n        }\n        return toHexString(value, length);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _HEX_SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n}\n","keccak256":"0x32c202bd28995dd20c4347b7c6467a6d3241c74c8ad3edcbb610cd9205916c45","license":"MIT"},"@openzeppelin/contracts/utils/introspection/ERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n","keccak256":"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b","license":"MIT"},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n","keccak256":"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1","license":"MIT"},"contracts/ControlledGateway.sol":{"content":"//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport {Pausable} from \"@openzeppelin/contracts/security/Pausable.sol\";\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\n\n/**\n * @title ControlledGateway\n * @notice Base Contract for both L1 and L2 LPT gateways. Provides AccessControl.\n * Gateways can be paused by the admin to stop outgoing token migrations\n */\ncontract ControlledGateway is AccessControl, Pausable {\n    address public immutable l1Lpt;\n    address public immutable l2Lpt;\n\n    constructor(address _l1Lpt, address _l2Lpt) {\n        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);\n\n        l1Lpt = _l1Lpt;\n        l2Lpt = _l2Lpt;\n    }\n\n    function pause() external onlyRole(DEFAULT_ADMIN_ROLE) {\n        _pause();\n    }\n\n    function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) {\n        _unpause();\n    }\n}\n","keccak256":"0xf17a5db4b19585d848d60c6d38c09938275a767f59c1918d9f65a40d97c26841","license":"MIT"},"contracts/L1/gateway/IL1LPTGateway.sol":{"content":"//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\ninterface IL1LPTGateway {\n    event DepositInitiated(\n        address _l1Token,\n        address indexed _from,\n        address indexed _to,\n        uint256 indexed _sequenceNumber,\n        uint256 _amount\n    );\n\n    event WithdrawalFinalized(\n        address _l1Token,\n        address indexed _from,\n        address indexed _to,\n        uint256 indexed _exitNum,\n        uint256 _amount\n    );\n\n    function outboundTransfer(\n        address _l1Token,\n        address _to,\n        uint256 _amount,\n        uint256 _maxGas,\n        uint256 _gasPriceBid,\n        bytes calldata _data\n    ) external payable returns (bytes memory);\n\n    function finalizeInboundTransfer(\n        address _token,\n        address _from,\n        address _to,\n        uint256 _amount,\n        bytes calldata _data\n    ) external;\n\n    // if token is not supported this should return 0x0 address\n    function calculateL2TokenAddress(address l1Token)\n        external\n        view\n        returns (address);\n\n    // used by router\n    function counterpartGateway() external view returns (address);\n}\n","keccak256":"0x3d47adc8ef84079e4bcc5bfd3cf7929794cc5fa443e188119438688ebeeaa57e","license":"MIT"},"contracts/L2/gateway/IL2LPTGateway.sol":{"content":"//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\ninterface IL2LPTGateway {\n    event DepositFinalized(\n        address indexed _l1Token,\n        address indexed _from,\n        address indexed _to,\n        uint256 _amount\n    );\n\n    event WithdrawalInitiated(\n        address _l1Token,\n        address indexed _from,\n        address indexed _to,\n        uint256 indexed _l2ToL1Id,\n        uint256 _exitNum,\n        uint256 _amount\n    );\n\n    function outboundTransfer(\n        address _token,\n        address _to,\n        uint256 _amount,\n        bytes calldata _data\n    ) external returns (bytes memory);\n\n    function finalizeInboundTransfer(\n        address _token,\n        address _from,\n        address _to,\n        uint256 _amount,\n        bytes calldata _data\n    ) external;\n\n    // if token is not supported this should return 0x0 address\n    function calculateL2TokenAddress(address _l1Token)\n        external\n        view\n        returns (address);\n\n    // used by router\n    function counterpartGateway() external view returns (address);\n}\n","keccak256":"0x536e2e1380bedaf69662181b2f20c22e975eb19b284f08c319edb2e80900629d","license":"MIT"},"contracts/L2/gateway/L2ArbitrumMessenger.sol":{"content":"//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport {IArbSys} from \"../../arbitrum/IArbSys.sol\";\n\nabstract contract L2ArbitrumMessenger {\n    event TxToL1(\n        address indexed _from,\n        address indexed _to,\n        uint256 indexed _id,\n        bytes _data\n    );\n\n    function sendTxToL1(\n        address user,\n        address to,\n        bytes memory data\n    ) internal returns (uint256) {\n        // note: this method doesn't support sending ether to L1 together with a call\n        uint256 id = IArbSys(address(100)).sendTxToL1(to, data);\n        emit TxToL1(user, to, id, data);\n        return id;\n    }\n\n    modifier onlyL1Counterpart(address l1Counterpart) {\n        require(\n            msg.sender == applyL1ToL2Alias(l1Counterpart),\n            \"ONLY_COUNTERPART_GATEWAY\"\n        );\n        _;\n    }\n\n    uint160 internal constant OFFSET =\n        uint160(0x1111000000000000000000000000000000001111);\n\n    // l1 addresses are transformed durng l1->l2 calls\n    function applyL1ToL2Alias(address l1Address)\n        internal\n        pure\n        returns (address l2Address)\n    {\n        l2Address = address(uint160(l1Address) + OFFSET);\n    }\n}\n","keccak256":"0x869e551fffb21ebfa4a74084da87eaeac241d0a172b5e6c04b1f3573af2847cd","license":"MIT"},"contracts/L2/gateway/L2LPTGateway.sol":{"content":"//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport {ControlledGateway} from \"../../ControlledGateway.sol\";\nimport {L2ArbitrumMessenger} from \"./L2ArbitrumMessenger.sol\";\nimport {IL2LPTGateway} from \"./IL2LPTGateway.sol\";\nimport {IL1LPTGateway} from \"../../L1/gateway/IL1LPTGateway.sol\";\n\ninterface Mintable {\n    function mint(address _to, uint256 _amount) external;\n\n    function burnFrom(address _from, uint256 _amount) external;\n}\n\ninterface IL2LPTDataCache {\n    function increaseL2SupplyFromL1(uint256 _amount) external;\n\n    function decreaseL2SupplyFromL1(uint256 _amount) external;\n}\n\n/**\n * @title L2LPTGateway\n * @notice Manages inbound and outbound transfers of LPT between Arbitrum Rollup and L1\n * @dev the contract can be paused by the governor which will prevent any outbound transfers\n * but pausing the contract does not affect inbound transfers (tokens coming from L1)\n */\ncontract L2LPTGateway is IL2LPTGateway, ControlledGateway, L2ArbitrumMessenger {\n    address public immutable l2Router;\n    address public immutable l2LPTDataCache;\n\n    address public l1Counterpart;\n\n    event L1CounterpartUpdate(address _l1Counterpart);\n\n    constructor(\n        address _l2Router,\n        address _l1Lpt,\n        address _l2Lpt,\n        address _l2LPTDataCache\n    ) ControlledGateway(_l1Lpt, _l2Lpt) {\n        l2Router = _l2Router;\n        l2LPTDataCache = _l2LPTDataCache;\n\n        _pause();\n    }\n\n    /**\n     * @notice Sets address of companion L1LPTGateway\n     * @dev Only address with the governor role is allowed to change the value of l1Counterpart\n     * @param _l1Counterpart L1 Address of the counterpart\n     */\n    function setCounterpart(address _l1Counterpart)\n        external\n        onlyRole(DEFAULT_ADMIN_ROLE)\n    {\n        l1Counterpart = _l1Counterpart;\n        emit L1CounterpartUpdate(_l1Counterpart);\n    }\n\n    /**\n     * @notice Burns L2 tokens and sends a message to L1\n     * The tokens will be received on L1 only after the wait period (7 days) is over\n     * @dev no additional callhook data is allowed\n     * @param _l1Token L1 Address of LPT\n     * @param _to Recipient address on L1\n     * @param _amount Amount of tokens to burn\n     * @param _data Contains sender and additional data to send to L1\n     * @return ID of the withdraw tx\n     */\n    function outboundTransfer(\n        address _l1Token,\n        address _to,\n        uint256 _amount,\n        bytes calldata _data\n    ) external override returns (bytes memory) {\n        return outboundTransfer(_l1Token, _to, _amount, 0, 0, _data);\n    }\n\n    /**\n     * @notice Burns L2 tokens and sends a message to L1\n     * The tokens will be received on L1 only after the wait period (7 days) is over\n     * @dev no additional callhook data is allowed\n     * @param _l1Token L1 Address of LPT\n     * @param _to Recipient address on L1\n     * @param _amount Amount of tokens to burn\n     * @param _data Contains sender and additional data (always zero) to send to L1\n     * @return ID of the withdraw tx\n     */\n    function outboundTransfer(\n        address _l1Token,\n        address _to,\n        uint256 _amount,\n        uint256, // maxGas\n        uint256, // gasPriceBid\n        bytes calldata _data\n    ) public whenNotPaused returns (bytes memory) {\n        require(_l1Token == l1Lpt, \"TOKEN_NOT_LPT\");\n        require(_amount > 0, \"INVALID_ZERO_AMOUNT\");\n\n        (address from, bytes memory extraData) = parseOutboundData(_data);\n        require(extraData.length == 0, \"CALL_HOOK_DATA_NOT_ALLOWED\");\n\n        // from needs to approve this contract to burn the amount first\n        Mintable(l2Lpt).burnFrom(from, _amount);\n        IL2LPTDataCache(l2LPTDataCache).decreaseL2SupplyFromL1(_amount);\n\n        uint256 id = sendTxToL1(\n            from,\n            l1Counterpart,\n            getOutboundCalldata(_l1Token, from, _to, _amount, extraData)\n        );\n\n        // we don't need to track exitNums (b/c we have no fast exits) so we always use 0\n        emit WithdrawalInitiated(_l1Token, from, _to, id, 0, _amount);\n\n        return abi.encode(id);\n    }\n\n    /**\n     * @notice Receives token amount from L1 and mints the equivalent tokens to the receiving address\n     * @dev can only accept txs coming directly from L1 LPT Gateway\n     * data param is unused because no additional data is allowed from L1\n     * @param _l1Token L1 Address of LPT\n     * @param _from Address of the sender on L1\n     * @param _to Recepient address on L2\n     * @param _amount Amount of tokens transferred\n     */\n    function finalizeInboundTransfer(\n        address _l1Token,\n        address _from,\n        address _to,\n        uint256 _amount,\n        bytes calldata // data -- unused\n    ) external override onlyL1Counterpart(l1Counterpart) {\n        require(_l1Token == l1Lpt, \"TOKEN_NOT_LPT\");\n\n        Mintable(l2Lpt).mint(_to, _amount);\n        IL2LPTDataCache(l2LPTDataCache).increaseL2SupplyFromL1(_amount);\n\n        emit DepositFinalized(_l1Token, _from, _to, _amount);\n    }\n\n    /**\n     * @notice Decodes calldata required for migration of tokens\n     * @dev extraData can be left empty\n     * @param data Encoded callhook data\n     * @return from Sender of the tx\n     * @return extraData Any other data sent to L1\n     */\n    function parseOutboundData(bytes memory data)\n        private\n        view\n        returns (address from, bytes memory extraData)\n    {\n        if (msg.sender == l2Router) {\n            (from, extraData) = abi.decode(data, (address, bytes));\n        } else {\n            from = msg.sender;\n            extraData = data;\n        }\n    }\n\n    /**\n     * @notice returns address of L1 LPT Gateway\n     */\n    function counterpartGateway() external view override returns (address) {\n        return l1Counterpart;\n    }\n\n    /**\n     * @notice returns address of L2 version of LPT\n     */\n    function calculateL2TokenAddress(address l1Token)\n        external\n        view\n        override\n        returns (address)\n    {\n        if (l1Token != l1Lpt) {\n            return address(0);\n        }\n\n        return l2Lpt;\n    }\n\n    /**\n     * @notice Creates calldata required to send tx to L1\n     * @dev encodes the target function with its params which\n     * will be called on L1 when the message is received on L1\n     */\n    function getOutboundCalldata(\n        address token,\n        address from,\n        address to,\n        uint256 amount,\n        bytes memory data\n    ) public pure returns (bytes memory outboundCalldata) {\n        outboundCalldata = abi.encodeWithSelector(\n            IL1LPTGateway.finalizeInboundTransfer.selector,\n            token,\n            from,\n            to,\n            amount,\n            abi.encode(0, data) // we don't need to track exitNums (b/c we have no fast exits) so we always use 0\n        );\n    }\n}\n","keccak256":"0xb0daec5d264065627bba7b2d18448d86c7500147f4e59ce2654a61db11541c8c","license":"MIT"},"contracts/arbitrum/IArbSys.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity 0.8.9;\n\n/**\n * @title Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064. Exposes a variety of system-level functionality.\n */\ninterface IArbSys {\n    /**\n     * @notice Get internal version number identifying an ArbOS build\n     * @return version number as int\n     */\n    function arbOSVersion() external pure returns (uint256);\n\n    function arbChainID() external view returns (uint256);\n\n    /**\n     * @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0)\n     * @return block number as int\n     */\n    function arbBlockNumber() external view returns (uint256);\n\n    /**\n     * @notice Send given amount of Eth to dest from sender.\n     * This is a convenience function, which is equivalent to calling sendTxToL1 with empty calldataForL1.\n     * @param destination recipient address on L1\n     * @return unique identifier for this L2-to-L1 transaction.\n     */\n    function withdrawEth(address destination)\n        external\n        payable\n        returns (uint256);\n\n    /**\n     * @notice Send a transaction to L1\n     * @param destination recipient address on L1\n     * @param calldataForL1 (optional) calldata for L1 contract call\n     * @return a unique identifier for this L2-to-L1 transaction.\n     */\n    function sendTxToL1(address destination, bytes calldata calldataForL1)\n        external\n        payable\n        returns (uint256);\n\n    /**\n     * @notice get the number of transactions issued by the given external account or the account sequence number of the given contract\n     * @param account target account\n     * @return the number of transactions issued by the given external account or the account sequence number of the given contract\n     */\n    function getTransactionCount(address account)\n        external\n        view\n        returns (uint256);\n\n    /**\n     * @notice get the value of target L2 storage slot\n     * This function is only callable from address 0 to prevent contracts from being able to call it\n     * @param account target account\n     * @param index target index of storage slot\n     * @return stotage value for the given account at the given index\n     */\n    function getStorageAt(address account, uint256 index)\n        external\n        view\n        returns (uint256);\n\n    /**\n     * @notice check if current call is coming from l1\n     * @return true if the caller of this was called directly from L1\n     */\n    function isTopLevelCall() external view returns (bool);\n\n    event EthWithdrawal(address indexed destAddr, uint256 amount);\n\n    event L2ToL1Transaction(\n        address caller,\n        address indexed destination,\n        uint256 indexed uniqueId,\n        uint256 indexed batchNumber,\n        uint256 indexInBatch,\n        uint256 arbBlockNum,\n        uint256 ethBlockNum,\n        uint256 timestamp,\n        uint256 callvalue,\n        bytes data\n    );\n}\n","keccak256":"0xeafce4b664922441749c64794de5a3ca5e21f19c23355069cea0b2bb41651b41","license":"Apache-2.0"}},"version":1}