Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 975 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Stake And Bridge | 23568859 | 29 hrs ago | IN | 0.01 ETH | 0.00072402 | ||||
Stake And Bridge | 23557728 | 2 days ago | IN | 0.0005 ETH | 0.00019072 | ||||
Stake And Bridge | 23520627 | 7 days ago | IN | 0.01 ETH | 0.00082314 | ||||
Stake And Bridge | 23491933 | 11 days ago | IN | 0.001 ETH | 0.00095574 | ||||
Stake And Bridge | 23480417 | 13 days ago | IN | 0.0065 ETH | 0.00048111 | ||||
Stake And Bridge | 23476435 | 14 days ago | IN | 0.01 ETH | 0.00097711 | ||||
Stake And Bridge | 23449098 | 17 days ago | IN | 0.005 ETH | 0.00085054 | ||||
Stake And Bridge | 23383100 | 27 days ago | IN | 0.001 ETH | 0.00045486 | ||||
Stake And Bridge | 23360069 | 30 days ago | IN | 0.00095654 ETH | 0.00008592 | ||||
Stake And Bridge | 23345658 | 32 days ago | IN | 0.00250096 ETH | 0.0001447 | ||||
Stake And Bridge | 23317427 | 36 days ago | IN | 0.001 ETH | 0.00065912 | ||||
Stake And Bridge | 23317423 | 36 days ago | IN | 0.001 ETH | 0.00060136 | ||||
Stake And Bridge | 23317417 | 36 days ago | IN | 0.001 ETH | 0.00056877 | ||||
Stake And Bridge | 23308875 | 37 days ago | IN | 0.0012 ETH | 0.00011116 | ||||
Stake And Bridge | 23304947 | 38 days ago | IN | 0.001 ETH | 0.00011781 | ||||
Stake And Bridge | 23304344 | 38 days ago | IN | 0.001 ETH | 0.00012489 | ||||
Stake And Bridge | 23304283 | 38 days ago | IN | 0.0005 ETH | 0.0002453 | ||||
Stake And Bridge | 23267352 | 43 days ago | IN | 0.01 ETH | 0.00042598 | ||||
Stake And Bridge | 23267169 | 43 days ago | IN | 0.001 ETH | 0.00071363 | ||||
Stake And Bridge | 23267159 | 43 days ago | IN | 0.001 ETH | 0.00075437 | ||||
Stake And Bridge | 23267150 | 43 days ago | IN | 0.001 ETH | 0.00072388 | ||||
Stake And Bridge | 23267145 | 43 days ago | IN | 0.001 ETH | 0.00073435 | ||||
Stake And Bridge | 23234598 | 47 days ago | IN | 0.001 ETH | 0.00117367 | ||||
Stake And Bridge | 23218461 | 50 days ago | IN | 0.00798745 ETH | 0.00039875 | ||||
Stake And Bridge | 23216606 | 50 days ago | IN | 0.005 ETH | 0.00047732 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
Stake | 23568859 | 29 hrs ago | 0.01 ETH | ||||
Stake | 23557728 | 2 days ago | 0.0005 ETH | ||||
Stake | 23520627 | 7 days ago | 0.01 ETH | ||||
Stake | 23491933 | 11 days ago | 0.001 ETH | ||||
Stake | 23480417 | 13 days ago | 0.0065 ETH | ||||
Stake | 23476435 | 14 days ago | 0.01 ETH | ||||
Stake | 23449098 | 17 days ago | 0.005 ETH | ||||
Stake | 23383100 | 27 days ago | 0.001 ETH | ||||
Stake | 23360069 | 30 days ago | 0.00095654 ETH | ||||
Stake | 23345658 | 32 days ago | 0.00250096 ETH | ||||
Stake | 23317427 | 36 days ago | 0.001 ETH | ||||
Stake | 23317423 | 36 days ago | 0.001 ETH | ||||
Stake | 23317417 | 36 days ago | 0.001 ETH | ||||
Stake | 23308875 | 37 days ago | 0.0012 ETH | ||||
Stake | 23304947 | 38 days ago | 0.001 ETH | ||||
Stake | 23304344 | 38 days ago | 0.001 ETH | ||||
Stake | 23304283 | 38 days ago | 0.0005 ETH | ||||
Stake | 23267352 | 43 days ago | 0.01 ETH | ||||
Stake | 23267169 | 43 days ago | 0.001 ETH | ||||
Stake | 23267159 | 43 days ago | 0.001 ETH | ||||
Stake | 23267150 | 43 days ago | 0.001 ETH | ||||
Stake | 23267145 | 43 days ago | 0.001 ETH | ||||
Stake | 23234598 | 47 days ago | 0.001 ETH | ||||
Stake | 23218461 | 50 days ago | 0.00798745 ETH | ||||
Stake | 23216606 | 50 days ago | 0.005 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
BridgeMiddleware
Compiler Version
v0.8.27+commit.40a35a09
Optimization Enabled:
Yes with 100 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.27; import "../vendors/zksync/bridgehub/IBridgehub.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; import {ILiquidityManager} from "../interfaces/ILiquidityManager.sol"; import {IUSDVault} from "../interfaces/IUSDVault.sol"; import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; import {Swap} from "../core/Swap.sol"; contract BridgeMiddleware is AccessControl, ReentrancyGuard { using SafeERC20 for IERC20; // ERRORS // EVENTS event ShareMinted(address indexed sender, uint256 amount, uint256 shares); event CanonicalTxHash(bytes32 indexed canonicalTxHash); event Swept(address indexed token, address indexed to); event StakeAndBridge(address token, uint256 amount, uint256 ozUSDMinted, uint256 l2GasLimit, uint256 l2GasPerPubdataByteLimit, uint256 gasMinted); event TokenAllowed(address indexed token, bool allowed); // VARIABLES bytes32 public constant WITHDRAW_ROLE = keccak256("WITHDRAW_ROLE"); bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE"); address public immutable native; uint256 public immutable chainId; /// @notice address of the bridgeHub IBridgehub public immutable bridgeHub; ILiquidityManager public immutable liquidityManager; IUSDVault public immutable ozUSDVault; address public immutable univ3router; // 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 for mainnet mapping (address => bool) public isAllowedToken; // initialized with DAI underlying as allowed // modifiers modifier onlyAllowedToken(address token) { require(isAllowedToken[token], "onlyAllowedToken: token not allowed"); _; } constructor ( address _nativeCoin, uint256 _chainId, address _bridgeHub, address _admin, address _withdrawer, address _liquidityManager, address _ozUSDVault, address _univ3router ) { require(_nativeCoin != address(0), "BridgeWrap: native coin address is zero"); require(_bridgeHub != address(0), "BridgeWrap: bridgeHub address is zero"); require(_admin != address(0), "BridgeWrap: admin address is zero"); require(_withdrawer != address(0), "BridgeWrap: withdrawer address is zero"); require(_liquidityManager != address(0), "BridgeWrap: liquidity manager address is zero"); require(_ozUSDVault != address(0), "BridgeWrap: ozUSD vault address is zero"); require(_univ3router != address(0), "BridgeWrap: univ3 router address is zero"); native = _nativeCoin; chainId = _chainId; bridgeHub = IBridgehub(_bridgeHub); liquidityManager = ILiquidityManager(_liquidityManager); ozUSDVault = IUSDVault(_ozUSDVault); isAllowedToken[ozUSDVault.asset()] = true; univ3router = _univ3router; _grantRole(DEFAULT_ADMIN_ROLE, _admin); _grantRole(WITHDRAW_ROLE, _withdrawer); _grantRole(WITHDRAW_ROLE, _admin); _grantRole(OPERATOR_ROLE, _admin); } function stakeAndBridge(uint256 _l2GasLimit) external payable nonReentrant { uint256 sharesMinted = _stakeNative(msg.value); _bridgeNative(msg.sender, sharesMinted, _l2GasLimit, 800); emit StakeAndBridge(address(0), msg.value, 0, _l2GasLimit, 800, msg.value); } function stakeAndBridgeStable(address token, uint256 amount, uint256 _l2GasLimit) external payable nonReentrant { require(isAllowedToken[token], "BridgeWrap: token not allowed"); // get STABLE from user IERC20(token).safeTransferFrom(msg.sender, address(this), amount); // mint gas for layer2 payment uint256 gasCost = l2TransactionBaseCost(tx.gasprice, _l2GasLimit, 800); uint256 neededEth = _convertToEthAmount(gasCost); require (msg.value >= neededEth, "BridgeWrap: not enough ETH to cover the gas cost"); uint256 gasMinted = _stakeNative(neededEth); // check if token is not DAI, swap it in UniswapV3 with 0.01% tier fee pool with 0.1% maximum slippage if (token != ozUSDVault.asset()) { amount = _performSwap(token, amount); } // mint ozUSD uint256 ozUSDMinted = _stakeDai(amount); require(ozUSDMinted > 0, "BridgeWrap: ozUSD minted is zero"); // bridge ozUSD to L2 _bridgeErc20(msg.sender, address(ozUSDVault), ozUSDMinted, _l2GasLimit, 800, gasMinted); emit StakeAndBridge(token, amount, ozUSDMinted, _l2GasLimit, 800, gasMinted); // refund the remaining ETH to the user (bool success, ) = payable(msg.sender).call{value: msg.value - neededEth}(""); require(success, "BridgeWrap: refund failed"); } function allowToken(address token, bool allow) external onlyRole(OPERATOR_ROLE) { require(token != address(0), "allowToken: token cannot be zero address"); isAllowedToken[token] = allow; emit TokenAllowed(token, allow); } function sweepTokens(address token, address to) external onlyRole(WITHDRAW_ROLE) { IERC20(token).safeTransfer(to, IERC20(token).balanceOf(address(this))); emit Swept(token, to); } function recoverEth() external onlyRole(WITHDRAW_ROLE) { payable(msg.sender).transfer(address(this).balance); emit Swept(address(0), msg.sender); } /// @notice estimate the cost of L2 tx in base token. /// @param _l1GasPrice The gas price on L1 /// @param _l2GasLimit The estimated L2 gas limit /// @param _l2GasPerPubdataByteLimit The price for each pubdata byte in L2 gas /// @return The price of L2 gas in the base token function l2TransactionBaseCost(uint256 _l1GasPrice, uint256 _l2GasLimit, uint256 _l2GasPerPubdataByteLimit) public view returns (uint256) { return bridgeHub.l2TransactionBaseCost(chainId, _l1GasPrice, _l2GasLimit, _l2GasPerPubdataByteLimit); } /// @notice estimate the cost of L2 tx in ETH. /// @param _l1GasPrice The gas price on L1 /// @param _l2GasLimit The estimated L2 gas limit /// @param _l2GasPerPubdataByteLimit The price for each pubdata byte in L2 gas /// @return The price of L2 gas in the base token function l2TransactionEthCost(uint256 _l1GasPrice, uint256 _l2GasLimit, uint256 _l2GasPerPubdataByteLimit) external returns (uint256) { uint256 baseCost = l2TransactionBaseCost(_l1GasPrice, _l2GasLimit, _l2GasPerPubdataByteLimit); return _convertToEthAmount(baseCost); } function _convertToEthAmount(uint256 _baseTokenAmount) internal returns (uint256) { uint256 nativeCoinAmount = IERC20(native).totalSupply(); uint256 lmValue = liquidityManager.virtualBalance(); if (lmValue == 0) { return _baseTokenAmount; } return _baseTokenAmount * lmValue * 1_000_000 / (nativeCoinAmount * 950_000); // cover for swap slippage } function _bridgeNative ( address _l2Receiver, uint256 _amount, uint256 _l2GasLimit, uint256 _l2GasPerPubdataByteLimit ) internal returns (bytes32 canonicalTxHash) { uint256 txCost = l2TransactionBaseCost(tx.gasprice, _l2GasLimit, _l2GasPerPubdataByteLimit); require(_amount > txCost, "BridgeWrap: not enough to cover the tx cost"); bytes memory empty; IERC20(native).safeIncreaseAllowance(address(bridgeHub.sharedBridge()), _amount); canonicalTxHash = bridgeHub.requestL2TransactionDirect( L2TransactionRequestDirect({ chainId: chainId, mintValue: _amount, l2Contract: _l2Receiver, l2Value: _amount - txCost, l2Calldata: empty, l2GasLimit: _l2GasLimit, l2GasPerPubdataByteLimit: _l2GasPerPubdataByteLimit, factoryDeps: new bytes[](0), refundRecipient: _l2Receiver // refund to the receiver }) ); emit CanonicalTxHash(canonicalTxHash); } /// Bridge ERC20 from L1 (Ethereum) to L2 (hyperchain) function _bridgeErc20( address _l2Receiver, address _token, uint256 _amount, uint256 _l2GasLimit, uint256 _l2GasPerPubdataByteLimit, uint256 _l2GasMinted ) internal returns (bytes32 canonicalTxHash) { address sharedBridge = address(bridgeHub.sharedBridge()); IERC20(_token).approve(sharedBridge, _amount); IERC20(native).safeIncreaseAllowance(sharedBridge, _l2GasMinted); bytes memory callData = _getDepositL2Calldata(_l2Receiver, _token, _amount); canonicalTxHash = bridgeHub.requestL2TransactionTwoBridges( L2TransactionRequestTwoBridgesOuter({ chainId: chainId, mintValue: _l2GasMinted, l2Value: 0, l2GasLimit: _l2GasLimit, l2GasPerPubdataByteLimit: _l2GasPerPubdataByteLimit, refundRecipient: _l2Receiver, secondBridgeAddress: sharedBridge, secondBridgeValue: 0, secondBridgeCalldata: callData }) ); emit CanonicalTxHash(canonicalTxHash); } /// @notice Generate a calldata for calling the deposit finalization on the L2 bridge contract function _getDepositL2Calldata(address _l2Receiver, address _l1Token, uint256 _amount) internal pure returns (bytes memory) { return abi.encode(_l1Token, _amount, _l2Receiver); } function _stakeNative (uint256 amount) internal returns (uint256 sharesMinted){ sharesMinted = IERC20(native).balanceOf(address(this)); // send ETH to liquidity manager to get shares (ozETH) liquidityManager.stake{value: amount}(); sharesMinted = IERC20(native).balanceOf(address(this)) - sharesMinted; emit ShareMinted(msg.sender, amount, sharesMinted); } function _stakeDai (uint256 amount) internal returns (uint256) { // give allowance to the vault, this deposit is available only for DAI IERC20(ozUSDVault.asset()).safeIncreaseAllowance(address(ozUSDVault), amount); return ozUSDVault.deposit(amount, address(this)); } function _getAmountOutMin (uint256 amountIn, address tokenIn, address tokenOut) internal view returns (uint256) { uint decimalsIn = IERC20Metadata(tokenIn).decimals(); uint decimalsOut = IERC20Metadata(tokenOut).decimals(); return (amountIn * (10 ** decimalsOut) * 995) / (1000 * (10 ** decimalsIn)); // 0.5% slippage } function _performSwap (address token, uint256 amount) internal returns (uint256) { IERC20(token).safeIncreaseAllowance(univ3router, amount); return Swap.swap( univ3router, 100, // 0.01% type of pools - usable for stableCoins token, // allowed tokens (USDT / USDC) ozUSDVault.asset(), // DAI Token address(this), amount, _getAmountOutMin(amount, token, ozUSDVault.asset()) // slippage of max 0.5% ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // solhint-disable-next-line interface-starts-with-i interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); function getRoundData( uint80 _roundId ) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol) pragma solidity ^0.8.20; import {IAccessControl} from "./IAccessControl.sol"; import {Context} from "../utils/Context.sol"; import {ERC165} from "../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: * * ```solidity * 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}: * * ```solidity * 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. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address account => bool) hasRole; bytes32 adminRole; } mapping(bytes32 role => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with an {AccessControlUnauthorizedAccount} error including the required role. */ 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 returns (bool) { return _roles[role].hasRole[account]; } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()` * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier. */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account` * is missing `role`. */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert AccessControlUnauthorizedAccount(account, role); } } /** * @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 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. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual 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. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual 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 `callerConfirmation`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address callerConfirmation) public virtual { if (callerConfirmation != _msgSender()) { revert AccessControlBadConfirmation(); } _revokeRole(role, callerConfirmation); } /** * @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 Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual returns (bool) { if (!hasRole(role, account)) { _roles[role].hasRole[account] = true; emit RoleGranted(role, account, _msgSender()); return true; } else { return false; } } /** * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual returns (bool) { if (hasRole(role, account)) { _roles[role].hasRole[account] = false; emit RoleRevoked(role, account, _msgSender()); return true; } else { return false; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC-165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @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. */ 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. This account bears the admin role (for the granted role). * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}. */ 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 `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC165} from "./IERC165.sol"; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ 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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC1363} from "../../../interfaces/IERC1363.sol"; import {Address} from "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC-20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol) pragma solidity ^0.8.20; import {Errors} from "./Errors.sol"; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert Errors.InsufficientBalance(address(this).balance, amount); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert Errors.FailedCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {Errors.FailedCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case * of an unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {Errors.FailedCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly ("memory-safe") { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert Errors.FailedCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol) pragma solidity ^0.8.20; /** * @dev Collection of common custom errors used in multiple contracts * * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. * It is recommended to avoid relying on the error API for critical functionality. * * _Available since v5.1._ */ library Errors { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error InsufficientBalance(uint256 balance, uint256 needed); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedCall(); /** * @dev The deployment failed. */ error FailedDeployment(); /** * @dev A necessary precompile is missing. */ error MissingPrecompile(address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 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); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * 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[ERC 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-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at, * consider using {ReentrancyGuardTransient} instead. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.27; import {ISwapRouter} from "../vendors/Uniswap/ISwapRouter.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; library Swap { uint256 constant SLIPPAGE_TOLERANCE = 997_000; // 99.7% uint256 constant SCALE = 1_000_000; function approveAndSwap( address router, uint24 fee, address tokenIn, address tokenOut, address recipient, uint256 amountIn ) internal returns (uint256 amountOut) { IERC20(tokenIn).approve(router, amountIn); amountOut = swapWithMaximumSlippage( router, fee, tokenIn, tokenOut, recipient, amountIn ); } function swap( address router, uint24 fee, address tokenIn, address tokenOut, address recipient, uint256 amountIn, uint256 amountOutMinimum ) internal returns (uint256 amountOut) { ISwapRouter swapRouter = ISwapRouter(router); // Naively set amountOutMinimum to 0. In production, use an oracle or other data source to choose a safer value for amountOutMinimum. // We also set the sqrtPriceLimitx96 to be 0 to ensure we swap our exact input amount. ISwapRouter.ExactInputSingleParams memory params = ISwapRouter .ExactInputSingleParams({ tokenIn: tokenIn, tokenOut: tokenOut, fee: fee, recipient: recipient, // send back to the caller amountIn: amountIn, amountOutMinimum: amountOutMinimum, sqrtPriceLimitX96: 0 }); // The call to `exactInputSingle` executes the swap. amountOut = swapRouter.exactInputSingle(params); } function swapWithMaximumSlippage( address router, uint24 fee, address tokenIn, address tokenOut, address recipient, uint256 amountIn ) internal returns (uint256 amountOut) { uint256 tokenInDecimals = IERC20Metadata(tokenIn).decimals(); uint256 tokenOutDecimals = IERC20Metadata(tokenOut).decimals(); // Normalize amounts based on decimal differences uint256 normalizedAmountIn = amountIn; if (tokenOutDecimals > tokenInDecimals) { normalizedAmountIn = amountIn * (10 ** (tokenOutDecimals - tokenInDecimals)); } // Calculate minimum amount out with slippage uint256 amountOutMinimum = normalizedAmountIn * SLIPPAGE_TOLERANCE / SCALE; // If output token has fewer decimals, adjust the minimum amount if (tokenInDecimals > tokenOutDecimals) { amountOutMinimum = amountOutMinimum / (10 ** (tokenInDecimals - tokenOutDecimals)); } amountOut = swap( router, fee, tokenIn, tokenOut, recipient, amountIn, amountOutMinimum ); } function swapWithMaximumSlippageRETH( address router, uint24 fee, address tokenIn, address tokenOut, address recipient, uint256 amountIn, uint256 amountOutMinimum ) internal returns (uint256 amountOut) { amountOut = swap( router, fee, tokenIn, tokenOut, recipient, amountIn, amountOutMinimum ); } function _swapWithMultipleHops( ISwapRouter swapRouter, bytes calldata _path, address _recipient, uint256 _amountIn, uint256 _amountOutMinimum ) internal returns (uint256 amountOut){ ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({ path: _path, recipient: _recipient, amountIn: _amountIn, amountOutMinimum: _amountOutMinimum }); // The call to `exactInputSingle` executes the swap. amountOut = swapRouter.exactInput(params); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.27; interface ILiquidityManager { function stake() payable external; function virtualBalance() external returns (uint256); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.27; interface IUSDVault { function asset() external view returns (address); function deposit(uint256 assets, address receiver) external returns (uint256 shares); function depositToken(address token, uint256 assets, address receiver) external returns (uint256 shares); function queueWithdraw(uint256 shares) external returns (uint256 index, uint256 cliff); function queueWithdrawToken(uint256 shares, address token) external returns (uint256 index, uint256 cliff); function withdraw(uint256 index) external returns (uint256 amount); function setNewCliff (uint256 cliff) external; function canWithdraw(uint256 index) external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.27; interface ISwapRouter { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } struct ExactInputParams { bytes path; address recipient; uint256 amountIn; uint256 amountOutMinimum; } function exactInputSingle( ExactInputSingleParams calldata params ) external returns (uint256 amountOut); function exactInput( ExactInputParams calldata params ) external payable returns (uint256 amountOut); }
// SPDX-License-Identifier: MIT // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {IL1SharedBridge} from "./IL1SharedBridge.sol"; /// @title L1 Bridge contract legacy interface /// @author Matter Labs /// @custom:security-contact [email protected] /// @notice Legacy Bridge interface before hyperchain migration, used for backward compatibility with ZKsync Era interface IL1ERC20Bridge { event DepositInitiated( bytes32 indexed l2DepositTxHash, address indexed from, address indexed to, address l1Token, uint256 amount ); event WithdrawalFinalized(address indexed to, address indexed l1Token, uint256 amount); event ClaimedFailedDeposit(address indexed to, address indexed l1Token, uint256 amount); function isWithdrawalFinalized(uint256 _l2BatchNumber, uint256 _l2MessageIndex) external view returns (bool); function deposit( address _l2Receiver, address _l1Token, uint256 _amount, uint256 _l2TxGasLimit, uint256 _l2TxGasPerPubdataByte, address _refundRecipient ) external payable returns (bytes32 txHash); function deposit( address _l2Receiver, address _l1Token, uint256 _amount, uint256 _l2TxGasLimit, uint256 _l2TxGasPerPubdataByte ) external payable returns (bytes32 txHash); function claimFailedDeposit( address _depositSender, address _l1Token, bytes32 _l2TxHash, uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes32[] calldata _merkleProof ) external; function finalizeWithdrawal( uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes calldata _message, bytes32[] calldata _merkleProof ) external; function l2TokenAddress(address _l1Token) external view returns (address); function SHARED_BRIDGE() external view returns (IL1SharedBridge); function l2TokenBeacon() external view returns (address); function l2Bridge() external view returns (address); function depositAmount( address _account, address _l1Token, bytes32 _depositL2TxHash ) external returns (uint256 amount); function transferTokenToSharedBridge(address _token) external; }
// SPDX-License-Identifier: MIT // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {L2TransactionRequestTwoBridgesInner} from "../../bridgehub/IBridgehub.sol"; import {IBridgehub} from "../../bridgehub/IBridgehub.sol"; import {IL1ERC20Bridge} from "./IL1ERC20Bridge.sol"; /// @title L1 Bridge contract interface /// @author Matter Labs /// @custom:security-contact [email protected] interface IL1SharedBridge { /// @notice pendingAdmin is changed /// @dev Also emitted when new admin is accepted and in this case, `newPendingAdmin` would be zero address event NewPendingAdmin(address indexed oldPendingAdmin, address indexed newPendingAdmin); /// @notice Admin changed event NewAdmin(address indexed oldAdmin, address indexed newAdmin); event LegacyDepositInitiated( uint256 indexed chainId, bytes32 indexed l2DepositTxHash, address indexed from, address to, address l1Token, uint256 amount ); event BridgehubDepositInitiated( uint256 indexed chainId, bytes32 indexed txDataHash, address indexed from, address to, address l1Token, uint256 amount ); event BridgehubDepositBaseTokenInitiated( uint256 indexed chainId, address indexed from, address l1Token, uint256 amount ); event BridgehubDepositFinalized( uint256 indexed chainId, bytes32 indexed txDataHash, bytes32 indexed l2DepositTxHash ); event WithdrawalFinalizedSharedBridge( uint256 indexed chainId, address indexed to, address indexed l1Token, uint256 amount ); event ClaimedFailedDepositSharedBridge( uint256 indexed chainId, address indexed to, address indexed l1Token, uint256 amount ); function isWithdrawalFinalized( uint256 _chainId, uint256 _l2BatchNumber, uint256 _l2MessageIndex ) external view returns (bool); function depositLegacyErc20Bridge( address _msgSender, address _l2Receiver, address _l1Token, uint256 _amount, uint256 _l2TxGasLimit, uint256 _l2TxGasPerPubdataByte, address _refundRecipient ) external payable returns (bytes32 txHash); function claimFailedDepositLegacyErc20Bridge( address _depositSender, address _l1Token, uint256 _amount, bytes32 _l2TxHash, uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes32[] calldata _merkleProof ) external; function claimFailedDeposit( uint256 _chainId, address _depositSender, address _l1Token, uint256 _amount, bytes32 _l2TxHash, uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes32[] calldata _merkleProof ) external; function finalizeWithdrawalLegacyErc20Bridge( uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes calldata _message, bytes32[] calldata _merkleProof ) external returns (address l1Receiver, address l1Token, uint256 amount); function finalizeWithdrawal( uint256 _chainId, uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes calldata _message, bytes32[] calldata _merkleProof ) external; function setEraPostDiamondUpgradeFirstBatch(uint256 _eraPostDiamondUpgradeFirstBatch) external; function setEraPostLegacyBridgeUpgradeFirstBatch(uint256 _eraPostLegacyBridgeUpgradeFirstBatch) external; function setEraLegacyBridgeLastDepositTime( uint256 _eraLegacyBridgeLastDepositBatch, uint256 _eraLegacyBridgeLastDepositTxNumber ) external; function L1_WETH_TOKEN() external view returns (address); function BRIDGE_HUB() external view returns (IBridgehub); function legacyBridge() external view returns (IL1ERC20Bridge); function l2BridgeAddress(uint256 _chainId) external view returns (address); function depositHappened(uint256 _chainId, bytes32 _l2TxHash) external view returns (bytes32); /// data is abi encoded : /// address _l1Token, /// uint256 _amount, /// address _l2Receiver function bridgehubDeposit( uint256 _chainId, address _prevMsgSender, uint256 _l2Value, bytes calldata _data ) external payable returns (L2TransactionRequestTwoBridgesInner memory request); function bridgehubDepositBaseToken( uint256 _chainId, address _prevMsgSender, address _l1Token, uint256 _amount ) external payable; function bridgehubConfirmL2Transaction(uint256 _chainId, bytes32 _txDataHash, bytes32 _txHash) external; function receiveEth(uint256 _chainId) external payable; /// @notice Starts the transfer of admin rights. Only the current admin can propose a new pending one. /// @notice New admin can accept admin rights by calling `acceptAdmin` function. /// @param _newPendingAdmin Address of the new admin function setPendingAdmin(address _newPendingAdmin) external; /// @notice Accepts transfer of admin rights. Only pending admin can accept the role. function acceptAdmin() external; }
// SPDX-License-Identifier: MIT // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; import {IL1SharedBridge} from "../bridge/interfaces/IL1SharedBridge.sol"; import {L2Message, L2Log, TxStatus} from "../common/Messaging.sol"; struct L2TransactionRequestDirect { uint256 chainId; uint256 mintValue; address l2Contract; uint256 l2Value; bytes l2Calldata; uint256 l2GasLimit; uint256 l2GasPerPubdataByteLimit; bytes[] factoryDeps; address refundRecipient; } struct L2TransactionRequestTwoBridgesOuter { uint256 chainId; uint256 mintValue; uint256 l2Value; uint256 l2GasLimit; uint256 l2GasPerPubdataByteLimit; address refundRecipient; address secondBridgeAddress; uint256 secondBridgeValue; bytes secondBridgeCalldata; } struct L2TransactionRequestTwoBridgesInner { bytes32 magicValue; address l2Contract; bytes l2Calldata; bytes[] factoryDeps; bytes32 txDataHash; } interface IBridgehub { /// @notice pendingAdmin is changed /// @dev Also emitted when new admin is accepted and in this case, `newPendingAdmin` would be zero address event NewPendingAdmin(address indexed oldPendingAdmin, address indexed newPendingAdmin); /// @notice Admin changed event NewAdmin(address indexed oldAdmin, address indexed newAdmin); /// @notice Starts the transfer of admin rights. Only the current admin can propose a new pending one. /// @notice New admin can accept admin rights by calling `acceptAdmin` function. /// @param _newPendingAdmin Address of the new admin function setPendingAdmin(address _newPendingAdmin) external; /// @notice Accepts transfer of admin rights. Only pending admin can accept the role. function acceptAdmin() external; /// Getters function stateTransitionManagerIsRegistered(address _stateTransitionManager) external view returns (bool); function stateTransitionManager(uint256 _chainId) external view returns (address); function tokenIsRegistered(address _baseToken) external view returns (bool); function baseToken(uint256 _chainId) external view returns (address); function sharedBridge() external view returns (IL1SharedBridge); function getHyperchain(uint256 _chainId) external view returns (address); /// Mailbox forwarder function proveL2MessageInclusion( uint256 _chainId, uint256 _batchNumber, uint256 _index, L2Message calldata _message, bytes32[] calldata _proof ) external view returns (bool); function proveL2LogInclusion( uint256 _chainId, uint256 _batchNumber, uint256 _index, L2Log memory _log, bytes32[] calldata _proof ) external view returns (bool); function proveL1ToL2TransactionStatus( uint256 _chainId, bytes32 _l2TxHash, uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes32[] calldata _merkleProof, TxStatus _status ) external view returns (bool); function requestL2TransactionDirect( L2TransactionRequestDirect calldata _request ) external payable returns (bytes32 canonicalTxHash); function requestL2TransactionTwoBridges( L2TransactionRequestTwoBridgesOuter calldata _request ) external payable returns (bytes32 canonicalTxHash); function l2TransactionBaseCost( uint256 _chainId, uint256 _gasPrice, uint256 _l2GasLimit, uint256 _l2GasPerPubdataByteLimit ) external view returns (uint256); //// Registry function createNewChain( uint256 _chainId, address _stateTransitionManager, address _baseToken, uint256 _salt, address _admin, bytes calldata _initData ) external returns (uint256 chainId); function addStateTransitionManager(address _stateTransitionManager) external; function removeStateTransitionManager(address _stateTransitionManager) external; function addToken(address _token) external; function setSharedBridge(address _sharedBridge) external; event NewChain(uint256 indexed chainId, address stateTransitionManager, address indexed chainGovernance); }
// SPDX-License-Identifier: MIT // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; /// @dev The enum that represents the transaction execution status /// @param Failure The transaction execution failed /// @param Success The transaction execution succeeded enum TxStatus { Failure, Success } /// @dev The log passed from L2 /// @param l2ShardId The shard identifier, 0 - rollup, 1 - porter /// All other values are not used but are reserved for the future /// @param isService A boolean flag that is part of the log along with `key`, `value`, and `sender` address. /// This field is required formally but does not have any special meaning /// @param txNumberInBatch The L2 transaction number in a Batch, in which the log was sent /// @param sender The L2 address which sent the log /// @param key The 32 bytes of information that was sent in the log /// @param value The 32 bytes of information that was sent in the log // Both `key` and `value` are arbitrary 32-bytes selected by the log sender struct L2Log { uint8 l2ShardId; bool isService; uint16 txNumberInBatch; address sender; bytes32 key; bytes32 value; } /// @dev An arbitrary length message passed from L2 /// @notice Under the hood it is `L2Log` sent from the special system L2 contract /// @param txNumberInBatch The L2 transaction number in a Batch, in which the message was sent /// @param sender The address of the L2 account from which the message was passed /// @param data An arbitrary length message struct L2Message { uint16 txNumberInBatch; address sender; bytes data; } /// @dev Internal structure that contains the parameters for the writePriorityOp /// internal function. /// @param txId The id of the priority transaction. /// @param l2GasPrice The gas price for the l2 priority operation. /// @param expirationTimestamp The timestamp by which the priority operation must be processed by the operator. /// @param request The external calldata request for the priority operation. struct WritePriorityOpParams { uint256 txId; uint256 l2GasPrice; uint64 expirationTimestamp; BridgehubL2TransactionRequest request; } /// @dev Structure that includes all fields of the L2 transaction /// @dev The hash of this structure is the "canonical L2 transaction hash" and can /// be used as a unique identifier of a tx /// @param txType The tx type number, depending on which the L2 transaction can be /// interpreted differently /// @param from The sender's address. `uint256` type for possible address format changes /// and maintaining backward compatibility /// @param to The recipient's address. `uint256` type for possible address format changes /// and maintaining backward compatibility /// @param gasLimit The L2 gas limit for L2 transaction. Analog to the `gasLimit` on an /// L1 transactions /// @param gasPerPubdataByteLimit Maximum number of L2 gas that will cost one byte of pubdata /// (every piece of data that will be stored on L1 as calldata) /// @param maxFeePerGas The absolute maximum sender willing to pay per unit of L2 gas to get /// the transaction included in a Batch. Analog to the EIP-1559 `maxFeePerGas` on an L1 transactions /// @param maxPriorityFeePerGas The additional fee that is paid directly to the validator /// to incentivize them to include the transaction in a Batch. Analog to the EIP-1559 /// `maxPriorityFeePerGas` on an L1 transactions /// @param paymaster The address of the EIP-4337 paymaster, that will pay fees for the /// transaction. `uint256` type for possible address format changes and maintaining backward compatibility /// @param nonce The nonce of the transaction. For L1->L2 transactions it is the priority /// operation Id /// @param value The value to pass with the transaction /// @param reserved The fixed-length fields for usage in a future extension of transaction /// formats /// @param data The calldata that is transmitted for the transaction call /// @param signature An abstract set of bytes that are used for transaction authorization /// @param factoryDeps The set of L2 bytecode hashes whose preimages were shown on L1 /// @param paymasterInput The arbitrary-length data that is used as a calldata to the paymaster pre-call /// @param reservedDynamic The arbitrary-length field for usage in a future extension of transaction formats struct L2CanonicalTransaction { uint256 txType; uint256 from; uint256 to; uint256 gasLimit; uint256 gasPerPubdataByteLimit; uint256 maxFeePerGas; uint256 maxPriorityFeePerGas; uint256 paymaster; uint256 nonce; uint256 value; // In the future, we might want to add some // new fields to the struct. The `txData` struct // is to be passed to account and any changes to its structure // would mean a breaking change to these accounts. To prevent this, // we should keep some fields as "reserved" // It is also recommended that their length is fixed, since // it would allow easier proof integration (in case we will need // some special circuit for preprocessing transactions) uint256[4] reserved; bytes data; bytes signature; uint256[] factoryDeps; bytes paymasterInput; // Reserved dynamic type for the future use-case. Using it should be avoided, // But it is still here, just in case we want to enable some additional functionality bytes reservedDynamic; } /// @param sender The sender's address. /// @param contractAddressL2 The address of the contract on L2 to call. /// @param valueToMint The amount of base token that should be minted on L2 as the result of this transaction. /// @param l2Value The msg.value of the L2 transaction. /// @param l2Calldata The calldata for the L2 transaction. /// @param l2GasLimit The limit of the L2 gas for the L2 transaction /// @param l2GasPerPubdataByteLimit The price for a single pubdata byte in L2 gas. /// @param factoryDeps The array of L2 bytecodes that the tx depends on. /// @param refundRecipient The recipient of the refund for the transaction on L2. If the transaction fails, then /// this address will receive the `l2Value`. // solhint-disable-next-line gas-struct-packing struct BridgehubL2TransactionRequest { address sender; address contractL2; uint256 mintValue; uint256 l2Value; bytes l2Calldata; uint256 l2GasLimit; uint256 l2GasPerPubdataByteLimit; bytes[] factoryDeps; address refundRecipient; }
{ "optimizer": { "enabled": true, "runs": 100 }, "viaIR": true, "evmVersion": "paris", "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":"_nativeCoin","type":"address"},{"internalType":"uint256","name":"_chainId","type":"uint256"},{"internalType":"address","name":"_bridgeHub","type":"address"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_withdrawer","type":"address"},{"internalType":"address","name":"_liquidityManager","type":"address"},{"internalType":"address","name":"_ozUSDVault","type":"address"},{"internalType":"address","name":"_univ3router","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"canonicalTxHash","type":"bytes32"}],"name":"CanonicalTxHash","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":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"ShareMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ozUSDMinted","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"l2GasLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"l2GasPerPubdataByteLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasMinted","type":"uint256"}],"name":"StakeAndBridge","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Swept","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"bool","name":"allowed","type":"bool"}],"name":"TokenAllowed","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WITHDRAW_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"allow","type":"bool"}],"name":"allowToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bridgeHub","outputs":[{"internalType":"contract IBridgehub","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"","type":"address"}],"name":"isAllowedToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_l1GasPrice","type":"uint256"},{"internalType":"uint256","name":"_l2GasLimit","type":"uint256"},{"internalType":"uint256","name":"_l2GasPerPubdataByteLimit","type":"uint256"}],"name":"l2TransactionBaseCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_l1GasPrice","type":"uint256"},{"internalType":"uint256","name":"_l2GasLimit","type":"uint256"},{"internalType":"uint256","name":"_l2GasPerPubdataByteLimit","type":"uint256"}],"name":"l2TransactionEthCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"liquidityManager","outputs":[{"internalType":"contract ILiquidityManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"native","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ozUSDVault","outputs":[{"internalType":"contract IUSDVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recoverEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","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":"uint256","name":"_l2GasLimit","type":"uint256"}],"name":"stakeAndBridge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"_l2GasLimit","type":"uint256"}],"name":"stakeAndBridgeStable","outputs":[],"stateMutability":"payable","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":"token","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"sweepTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"univ3router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
610140806040523461027d5761010081612614803803809161002182856104e7565b83398101031261027d5761003481610520565b60208201519161004660408201610520565b9261005360608301610520565b9261006060808401610520565b9261006d60a08201610520565b9061008660e061007f60c08401610520565b9201610520565b60018055966001600160a01b03841615610492576001600160a01b031691821561043f576001600160a01b038716156103f0576001600160a01b0386161561039c576001600160a01b0316908115610341576001600160a01b03169182156102ec576001600160a01b038816156102965760049460209460805260a05260c05260e0528061010052604051928380926338d52e0f60e01b82525afa90811561028a57600091610240575b506001600160a01b03166000908152600260205260409020805460ff1916600117905561012092909252610181916101719061016b83610534565b506105b0565b5061017b816105b0565b5061066c565b50604051611eaf9081610705823960805181818161079c01528181610fbb015281816114b8015281816119220152611b58015260a051818181610324015281816107fa01528181611019015281816115fa01526116bb015260c0518181816103aa01528181610718015281816108d901528181610f5d0152818161163e01526116fd015260e0518181816112f5015281816119680152611ba901526101005181818161040a01526106320152610120518181816101ad0152610b7f0152f35b9190506020823d602011610282575b8161025c602093836104e7565b8101031261027d576101819361027461017193610520565b91925093610130565b600080fd5b3d915061024f565b6040513d6000823e3d90fd5b60405162461bcd60e51b815260206004820152602860248201527f427269646765577261703a20756e69763320726f757465722061646472657373604482015267206973207a65726f60c01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602760248201527f427269646765577261703a206f7a555344207661756c742061646472657373206044820152666973207a65726f60c81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602d60248201527f427269646765577261703a206c6971756964697479206d616e6167657220616460448201526c6472657373206973207a65726f60981b6064820152608490fd5b60405162461bcd60e51b815260206004820152602660248201527f427269646765577261703a20776974686472617765722061646472657373206960448201526573207a65726f60d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602160248201527f427269646765577261703a2061646d696e2061646472657373206973207a65726044820152606f60f81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f427269646765577261703a206272696467654875622061646472657373206973604482015264207a65726f60d81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602760248201527f427269646765577261703a206e617469766520636f696e2061646472657373206044820152666973207a65726f60c81b6064820152608490fd5b601f909101601f19168101906001600160401b0382119082101761050a57604052565b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b038216820361027d57565b6001600160a01b03811660009081526000805160206125f4833981519152602052604090205460ff166105aa576001600160a01b031660008181526000805160206125f483398151915260205260408120805460ff191660011790553391906000805160206125b48339815191528180a4600190565b50600090565b6001600160a01b03811660009081527f20be27040b8e00df40bca0df34743417f3574a156386188f7d7f14369e5ee82b602052604090205460ff166105aa576001600160a01b031660008181527f20be27040b8e00df40bca0df34743417f3574a156386188f7d7f14369e5ee82b60205260408120805460ff191660011790553391907f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec906000805160206125b48339815191529080a4600190565b6001600160a01b03811660009081526000805160206125d4833981519152602052604090205460ff166105aa576001600160a01b031660008181526000805160206125d483398151915260205260408120805460ff191660011790553391907f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929906000805160206125b48339815191529080a460019056fe608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a7146114e75750806311b0b42d146114a25780631609be1d14611391578063248a9ca3146113645780632f2ff15d1461132457806333827438146112df57806336568abe1461129957806340e53eb714610f195780634450c52b1461057d5780635bc35ae8146104395780636b318826146103f45780638a8ea613146103d95780638d66e8e41461039457806391d14854146103475780639a8a05921461030c578063a217fddf146102f0578063b473318e146102cf578063bcdb446b14610262578063cbe230c314610223578063d547741f146101dc578063dd6e011014610197578063e02023a11461015c5763f5b541a61461011c57600080fd5b346101575760003660031901126101575760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b600080fd5b346101575760003660031901126101575760206040517f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec8152f35b34610157576000366003190112610157576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610157576040366003190112610157576102216004356101fb611550565b9061021c61021782600052600060205260016040600020015490565b6117a3565b611869565b005b34610157576020366003190112610157576001600160a01b0361024461153a565b166000526002602052602060ff604060002054166040519015158152f35b346101575760003660031901126101575761027b611731565b6000808080478181156102c6575b3390f1156102ba573360007f84dc653e543190fda51ad370aa0334e146df4dc9a60dcc43bf1f005b37b785b38180a3005b6040513d6000823e3d90fd5b506108fc610289565b346101575760206102e86102e236611566565b916116a9565b604051908152f35b3461015757600036600319011261015757602060405160008152f35b346101575760003660031901126101575760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b3461015757604036600319011261015757610360611550565b600435600052600060205260406000209060018060a01b0316600052602052602060ff604060002054166040519015158152f35b34610157576000366003190112610157576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346101575760206102e86103ef6102e236611566565b611b43565b34610157576000366003190112610157576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346101575760403660031901126101575761045261153a565b60243590811515809203610157573360009081527fee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319f602052604090205460ff1615610544576001600160a01b03169081156104ee5760207f9a8e30a8658b96ab3f034ce4bac6806278b4aee5880ccdd1ac35e4ed5bb31d23918360005260028252604060002060ff1981541660ff8316179055604051908152a2005b60405162461bcd60e51b815260206004820152602860248201527f616c6c6f77546f6b656e3a20746f6b656e2063616e6e6f74206265207a65726f604482015267206164647265737360c01b6064820152608490fd5b63e2517d3f60e01b600052336004527f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92960245260446000fd5b60603660031901126101575761059161153a565b6024359061059d6118eb565b6001600160a01b038116600090815260026020526040902054829060ff1615610ed4576106036040516323b872dd60e01b6020820152336024820152306044820152826064820152606481526105f460848261159d565b6001600160a01b038416611c97565b6106126103ef6044353a6115eb565b91823410610e76576106238361190d565b6040516338d52e0f60e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169391929190602081600481885afa9081156102ba57600091610e57575b506001600160a01b0390811690831603610b7a575b506040516338d52e0f60e01b8152602081600481875afa80156102ba578487916106c793600091610b5b575b506001600160a01b0316611cf2565b604051636e553f6560e01b815260048101869052306024820152906020826044816000885af19182156102ba57600092610b24575b508115610ae05760405163070e40ef60e31b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156102ba57600091610ab1575b5060405163095ea7b360e01b81526001600160a01b0391909116600482018190526024820184905294906020816044816000865af180156102ba57610a74575b506020906107c985877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611cf2565b6040519082820152836040820152336060820152606081526107ec60808261159d565b6040516107f881611580565b7f0000000000000000000000000000000000000000000000000000000000000000815285838201526108d361010060408301926000845260608101946044358652608082019a6103208c5260a0830133815260c0840191825260e084019260008452858501526040519c8d9889986324fd57fb60e01b8a528b60048b0152865160248b01528b87015160448b01525160648a01525160848901525160a488015260018060a01b0390511660c487015260018060a01b0390511660e4860152516101048501520151610120610124840152610144830190611acf565b038160007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19384156102ba57600094610a30575b5093600080516020611e5a83398151915260c06000979588979561098d9589988998604051947fec4441362be16727d3342fcbac11e99fc9906b5e3621e58d90ec20bcd01dc53c8b80a26001600160a01b03168452602084015260408301526044356060830152610320608083015260a0820152a1346115de565b335af13d15610a2b573d67ffffffffffffffff8111610a1557604051906109be601f8201601f19166020018361159d565b8152600060203d92013e5b156109d45760018055005b60405162461bcd60e51b8152602060048201526019602482015278109c9a5919d955dc985c0e881c99599d5b990819985a5b1959603a1b6044820152606490fd5b634e487b7160e01b600052604160045260246000fd5b6109c9565b949093506020853d602011610a6c575b81610a4d6020938361159d565b8101031261015757935192600080516020611e5a833981519152610912565b3d9150610a40565b6020813d602011610aa9575b81610a8d6020938361159d565b8101031261015757519081151582036101575790506020610791565b3d9150610a80565b610ad3915060203d602011610ad9575b610acb818361159d565b8101906115bf565b87610751565b503d610ac1565b606460405162461bcd60e51b815260206004820152602060248201527f427269646765577261703a206f7a555344206d696e746564206973207a65726f6044820152fd5b90916020823d602011610b53575b81610b3f6020938361159d565b81010312610b5057505190866106fc565b80fd5b3d9150610b32565b610b74915060203d602011610ad957610acb818361159d565b896106b8565b9094507f0000000000000000000000000000000000000000000000000000000000000000610bb282826001600160a01b038916611cf2565b6040516338d52e0f60e01b8152602081600481885afa9081156102ba57600091610e38575b506040516338d52e0f60e01b8152602081600481895afa9081156102ba57600091610e19575b5060405163313ce56760e01b8152906020826004816001600160a01b038d165afa9182156102ba57600092610df4575b5060405163313ce56760e01b815290602090829060049082906001600160a01b03165afa80156102ba5760ff610c7091610c7693600091610dc5575b5016611e4b565b85611b10565b906103e38202918083046103e31490151715610daf5760ff610c989116611e4b565b806103e802906103e8820403610daf57610cb191611b23565b9260405160e0810181811067ffffffffffffffff821117610a155760409081526001600160a01b038a811683529384166020838101918252606484840181815230606087019081526080870197885260a087019a8b52600060c0880181815296516304e45aaf60e01b815297518a166004890152945189166024880152905162ffffff1660448701525187169085015293516084840152955160a483015251831660c4820152939092849260e49284929091165af19081156102ba57600091610d7d575b50938561068c565b90506020813d602011610da7575b81610d986020938361159d565b81010312610157575185610d75565b3d9150610d8b565b634e487b7160e01b600052601160045260246000fd5b610de7915060203d602011610ded575b610ddf818361159d565b810190611e32565b8c610c69565b503d610dd5565b6004919250610e11602091823d8411610ded57610ddf818361159d565b929150610c2d565b610e32915060203d602011610ad957610acb818361159d565b88610bfd565b610e51915060203d602011610ad957610acb818361159d565b87610bd7565b610e70915060203d602011610ad957610acb818361159d565b87610677565b60405162461bcd60e51b815260206004820152603060248201527f427269646765577261703a206e6f7420656e6f7567682045544820746f20636f60448201526f1d995c881d1a194819d85cc818dbdcdd60821b6064820152608490fd5b60405162461bcd60e51b815260206004820152601d60248201527f427269646765577261703a20746f6b656e206e6f7420616c6c6f7765640000006044820152606490fd5b602036600319011261015757600435610f306118eb565b610f393461190d565b90610f44813a6115eb565b91828111156112405760405163070e40ef60e31b8152907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316602083600481845afa9283156102ba57600195610fe084600496610fe694600091611221575b50898060a01b0316898060a01b037f000000000000000000000000000000000000000000000000000000000000000016611cf2565b836115de565b602092604051610ff6858261159d565b6000815260009761121c575b91849391955087906040519361101785611580565b7f0000000000000000000000000000000000000000000000000000000000000000855285850197885260408501903382526060860192835260808601926060845260a08701938b855260c0880191610320835260e089019384526101008901943386526040519c8d9a63d52471c160e01b8c528c60048d01525160248c01525160448b0152600160a01b6001900390511660648a01525160848901525160a48801610120905261014488016110cb91611acf565b935160c48801525160e487015251916023198682030161010487015282518082528782019188808360051b83010195019286915b8383106111e557505092516001600160a01b0316610124880152505050839003918391905af19182156111da578492611199575b5090600080516020611e5a8339815191529260c092604051927fec4441362be16727d3342fcbac11e99fc9906b5e3621e58d90ec20bcd01dc53c8780a28583523490830152846040830152606082015261032060808201523460a0820152a16001805580f35b91508082813d83116111d3575b6111b0818361159d565b810103126111cf57905190600080516020611e5a833981519152611133565b8380fd5b503d6111a6565b6040513d86823e3d90fd5b9398509396986001929650611206819296601f198682030187528a51611acf565b980193019301938b948a97948a999794936110ff565b611002565b61123a915060203d602011610ad957610acb818361159d565b8a610fab565b60405162461bcd60e51b815260206004820152602b60248201527f427269646765577261703a206e6f7420656e6f75676820746f20636f7665722060448201526a1d1a19481d1e0818dbdcdd60aa1b6064820152608490fd5b34610157576040366003190112610157576112b2611550565b336001600160a01b038216036112ce5761022190600435611869565b63334bd91960e11b60005260046000fd5b34610157576000366003190112610157576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015757604036600319011261015757610221600435611343611550565b9061135f61021782600052600060205260016040600020015490565b6117de565b346101575760203660031901126101575760206102e8600435600052600060205260016040600020015490565b34610157576040366003190112610157576113aa61153a565b6113b2611550565b906113bb611731565b6040516370a0823160e01b81523060048201526001600160a01b03919091169190602081602481865afa9081156102ba5760009161146e575b5060405163a9059cbb60e01b60208201526001600160a01b0383166024820152604481019190915261143d9061143781606481015b03601f19810183528261159d565b83611c97565b6001600160a01b0316907f84dc653e543190fda51ad370aa0334e146df4dc9a60dcc43bf1f005b37b785b3600080a3005b90506020813d60201161149a575b816114896020938361159d565b8101031261015757516114296113f4565b3d915061147c565b34610157576000366003190112610157576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610157576020366003190112610157576004359063ffffffff60e01b821680920361015757602091637965db0b60e01b8114908115611529575b5015158152f35b6301ffc9a760e01b14905083611522565b600435906001600160a01b038216820361015757565b602435906001600160a01b038216820361015757565b606090600319011261015757600435906024359060443590565b610120810190811067ffffffffffffffff821117610a1557604052565b90601f8019910116810190811067ffffffffffffffff821117610a1557604052565b9081602091031261015757516001600160a01b03811681036101575790565b91908203918211610daf57565b604051631c588c9d60e21b81527f000000000000000000000000000000000000000000000000000000000000000060048201526024810191909152604481019190915261032060648201526020816084817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156102ba5760009161167a575090565b90506020813d6020116116a1575b816116956020938361159d565b81010312610157575190565b3d9150611688565b919060405192631c588c9d60e21b84527f0000000000000000000000000000000000000000000000000000000000000000600485015260248401526044830152606482015260208160848160018060a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa9081156102ba5760009161167a575090565b3360009081527f20be27040b8e00df40bca0df34743417f3574a156386188f7d7f14369e5ee82b602052604090205460ff161561176a57565b63e2517d3f60e01b600052336004527f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec60245260446000fd5b60008181526020818152604080832033845290915290205460ff16156117c65750565b63e2517d3f60e01b6000523360045260245260446000fd5b6000818152602081815260408083206001600160a01b038616845290915290205460ff16611862576000818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b5050600090565b6000818152602081815260408083206001600160a01b038616845290915290205460ff1615611862576000818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b6002600154146118fc576002600155565b633ee5aeb560e01b60005260046000fd5b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692906000602082602481885afa918215611ac2578192611a8e575b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031694853b15611a8a57818596600460405180998193633a4b66f160e01b83525af1958615611a7f576024949596611a6a575b50602090604051948580926370a0823160e01b82523060048301525afa908115611a5e5790611a2a575b6119f592506115de565b916040519081528260208201527f7494e309a68e673da9e1de3ae72425566aad3afb6b7ea7d70a590042a3a3864960403392a2565b506020823d602011611a56575b81611a446020938361159d565b81010312610157576119f591516119eb565b3d9150611a37565b604051903d90823e3d90fd5b91611a78816020939461159d565b91906119c1565b6040513d84823e3d90fd5b5080fd5b9091506020813d602011611aba575b81611aaa6020938361159d565b81010312611a8a57519038611965565b3d9150611a9d565b50604051903d90823e3d90fd5b919082519283825260005b848110611afb575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201611ada565b81810292918115918404141715610daf57565b8115611b2d570490565b634e487b7160e01b600052601260045260246000fd5b6040516318160ddd60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156102ba57600091611c65575b5060405163dcd2af1760e01b815260208160048160007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156102ba57600091611c33575b508015611c2e57611bf39192611b10565b90620f4240820291808304620f42401490151715610daf57620e7ef0810290808204620e7ef01490151715610daf57611c2b91611b23565b90565b505090565b906020823d602011611c5d575b81611c4d6020938361159d565b81010312610b5057505138611be2565b3d9150611c40565b906020823d602011611c8f575b81611c7f6020938361159d565b81010312610b5057505138611b91565b3d9150611c72565b906000602091828151910182855af1156102ba576000513d611ce957506001600160a01b0381163b155b611cc85750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b60011415611cc1565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830181905294919390831691602085604481865afa9485156102ba57600095611dfe575b508401809411610daf5760405163095ea7b360e01b60208083019182526001600160a01b0393909316602483015260448083019690965294815293600090611d7f60648761159d565b85519082865af1903d6000519083611ddf575b50505015611d9f57505050565b611dd8611ddd936040519063095ea7b360e01b602083015260248201526000604482015260448152611dd260648261159d565b82611c97565b611c97565b565b91925090611df457503b15155b388080611d92565b6001915014611dec565b90946020823d602011611e2a575b81611e196020938361159d565b81010312610b505750519338611d36565b3d9150611e0c565b90816020910312610157575160ff811681036101575790565b604d8111610daf57600a0a9056fe5f87d560a81e5773771cbc043e287825a431c438dbe04f38a10dc4d381a0beb8a26469706673582212203466367c372b2ff3c218844e5d113e564f5f54394138259aab0626d8991af1f764736f6c634300081b00332f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0dee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb500000000000000000000000003f5be358fc2c4df88723a63148bd829b8aa5c910000000000000000000000000000000000000000000000000000000000000541000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52130000000000000000000000001c2cc2428736971cea04859c9b96f6b63d7110ae0000000000000000000000001c2cc2428736971cea04859c9b96f6b63d7110ae0000000000000000000000001c21d5b5bd5d2b859d1d5b12fd72db5ff7e98e920000000000000000000000003b5cc7d992f8ed1b4e1f9f660984adcd61fc1aca00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45
Deployed Bytecode
0x608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a7146114e75750806311b0b42d146114a25780631609be1d14611391578063248a9ca3146113645780632f2ff15d1461132457806333827438146112df57806336568abe1461129957806340e53eb714610f195780634450c52b1461057d5780635bc35ae8146104395780636b318826146103f45780638a8ea613146103d95780638d66e8e41461039457806391d14854146103475780639a8a05921461030c578063a217fddf146102f0578063b473318e146102cf578063bcdb446b14610262578063cbe230c314610223578063d547741f146101dc578063dd6e011014610197578063e02023a11461015c5763f5b541a61461011c57600080fd5b346101575760003660031901126101575760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b600080fd5b346101575760003660031901126101575760206040517f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec8152f35b34610157576000366003190112610157576040517f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b03168152602090f35b34610157576040366003190112610157576102216004356101fb611550565b9061021c61021782600052600060205260016040600020015490565b6117a3565b611869565b005b34610157576020366003190112610157576001600160a01b0361024461153a565b166000526002602052602060ff604060002054166040519015158152f35b346101575760003660031901126101575761027b611731565b6000808080478181156102c6575b3390f1156102ba573360007f84dc653e543190fda51ad370aa0334e146df4dc9a60dcc43bf1f005b37b785b38180a3005b6040513d6000823e3d90fd5b506108fc610289565b346101575760206102e86102e236611566565b916116a9565b604051908152f35b3461015757600036600319011261015757602060405160008152f35b346101575760003660031901126101575760206040517f00000000000000000000000000000000000000000000000000000000000005418152f35b3461015757604036600319011261015757610360611550565b600435600052600060205260406000209060018060a01b0316600052602052602060ff604060002054166040519015158152f35b34610157576000366003190112610157576040517f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52136001600160a01b03168152602090f35b346101575760206102e86103ef6102e236611566565b611b43565b34610157576000366003190112610157576040517f0000000000000000000000003b5cc7d992f8ed1b4e1f9f660984adcd61fc1aca6001600160a01b03168152602090f35b346101575760403660031901126101575761045261153a565b60243590811515809203610157573360009081527fee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319f602052604090205460ff1615610544576001600160a01b03169081156104ee5760207f9a8e30a8658b96ab3f034ce4bac6806278b4aee5880ccdd1ac35e4ed5bb31d23918360005260028252604060002060ff1981541660ff8316179055604051908152a2005b60405162461bcd60e51b815260206004820152602860248201527f616c6c6f77546f6b656e3a20746f6b656e2063616e6e6f74206265207a65726f604482015267206164647265737360c01b6064820152608490fd5b63e2517d3f60e01b600052336004527f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92960245260446000fd5b60603660031901126101575761059161153a565b6024359061059d6118eb565b6001600160a01b038116600090815260026020526040902054829060ff1615610ed4576106036040516323b872dd60e01b6020820152336024820152306044820152826064820152606481526105f460848261159d565b6001600160a01b038416611c97565b6106126103ef6044353a6115eb565b91823410610e76576106238361190d565b6040516338d52e0f60e01b81527f0000000000000000000000003b5cc7d992f8ed1b4e1f9f660984adcd61fc1aca6001600160a01b03169391929190602081600481885afa9081156102ba57600091610e57575b506001600160a01b0390811690831603610b7a575b506040516338d52e0f60e01b8152602081600481875afa80156102ba578487916106c793600091610b5b575b506001600160a01b0316611cf2565b604051636e553f6560e01b815260048101869052306024820152906020826044816000885af19182156102ba57600092610b24575b508115610ae05760405163070e40ef60e31b81526020816004817f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52136001600160a01b03165afa9081156102ba57600091610ab1575b5060405163095ea7b360e01b81526001600160a01b0391909116600482018190526024820184905294906020816044816000865af180156102ba57610a74575b506020906107c985877f00000000000000000000000003f5be358fc2c4df88723a63148bd829b8aa5c916001600160a01b0316611cf2565b6040519082820152836040820152336060820152606081526107ec60808261159d565b6040516107f881611580565b7f0000000000000000000000000000000000000000000000000000000000000541815285838201526108d361010060408301926000845260608101946044358652608082019a6103208c5260a0830133815260c0840191825260e084019260008452858501526040519c8d9889986324fd57fb60e01b8a528b60048b0152865160248b01528b87015160448b01525160648a01525160848901525160a488015260018060a01b0390511660c487015260018060a01b0390511660e4860152516101048501520151610120610124840152610144830190611acf565b038160007f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52136001600160a01b03165af19384156102ba57600094610a30575b5093600080516020611e5a83398151915260c06000979588979561098d9589988998604051947fec4441362be16727d3342fcbac11e99fc9906b5e3621e58d90ec20bcd01dc53c8b80a26001600160a01b03168452602084015260408301526044356060830152610320608083015260a0820152a1346115de565b335af13d15610a2b573d67ffffffffffffffff8111610a1557604051906109be601f8201601f19166020018361159d565b8152600060203d92013e5b156109d45760018055005b60405162461bcd60e51b8152602060048201526019602482015278109c9a5919d955dc985c0e881c99599d5b990819985a5b1959603a1b6044820152606490fd5b634e487b7160e01b600052604160045260246000fd5b6109c9565b949093506020853d602011610a6c575b81610a4d6020938361159d565b8101031261015757935192600080516020611e5a833981519152610912565b3d9150610a40565b6020813d602011610aa9575b81610a8d6020938361159d565b8101031261015757519081151582036101575790506020610791565b3d9150610a80565b610ad3915060203d602011610ad9575b610acb818361159d565b8101906115bf565b87610751565b503d610ac1565b606460405162461bcd60e51b815260206004820152602060248201527f427269646765577261703a206f7a555344206d696e746564206973207a65726f6044820152fd5b90916020823d602011610b53575b81610b3f6020938361159d565b81010312610b5057505190866106fc565b80fd5b3d9150610b32565b610b74915060203d602011610ad957610acb818361159d565b896106b8565b9094507f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45610bb282826001600160a01b038916611cf2565b6040516338d52e0f60e01b8152602081600481885afa9081156102ba57600091610e38575b506040516338d52e0f60e01b8152602081600481895afa9081156102ba57600091610e19575b5060405163313ce56760e01b8152906020826004816001600160a01b038d165afa9182156102ba57600092610df4575b5060405163313ce56760e01b815290602090829060049082906001600160a01b03165afa80156102ba5760ff610c7091610c7693600091610dc5575b5016611e4b565b85611b10565b906103e38202918083046103e31490151715610daf5760ff610c989116611e4b565b806103e802906103e8820403610daf57610cb191611b23565b9260405160e0810181811067ffffffffffffffff821117610a155760409081526001600160a01b038a811683529384166020838101918252606484840181815230606087019081526080870197885260a087019a8b52600060c0880181815296516304e45aaf60e01b815297518a166004890152945189166024880152905162ffffff1660448701525187169085015293516084840152955160a483015251831660c4820152939092849260e49284929091165af19081156102ba57600091610d7d575b50938561068c565b90506020813d602011610da7575b81610d986020938361159d565b81010312610157575185610d75565b3d9150610d8b565b634e487b7160e01b600052601160045260246000fd5b610de7915060203d602011610ded575b610ddf818361159d565b810190611e32565b8c610c69565b503d610dd5565b6004919250610e11602091823d8411610ded57610ddf818361159d565b929150610c2d565b610e32915060203d602011610ad957610acb818361159d565b88610bfd565b610e51915060203d602011610ad957610acb818361159d565b87610bd7565b610e70915060203d602011610ad957610acb818361159d565b87610677565b60405162461bcd60e51b815260206004820152603060248201527f427269646765577261703a206e6f7420656e6f7567682045544820746f20636f60448201526f1d995c881d1a194819d85cc818dbdcdd60821b6064820152608490fd5b60405162461bcd60e51b815260206004820152601d60248201527f427269646765577261703a20746f6b656e206e6f7420616c6c6f7765640000006044820152606490fd5b602036600319011261015757600435610f306118eb565b610f393461190d565b90610f44813a6115eb565b91828111156112405760405163070e40ef60e31b8152907f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52136001600160a01b0316602083600481845afa9283156102ba57600195610fe084600496610fe694600091611221575b50898060a01b0316898060a01b037f00000000000000000000000003f5be358fc2c4df88723a63148bd829b8aa5c9116611cf2565b836115de565b602092604051610ff6858261159d565b6000815260009761121c575b91849391955087906040519361101785611580565b7f0000000000000000000000000000000000000000000000000000000000000541855285850197885260408501903382526060860192835260808601926060845260a08701938b855260c0880191610320835260e089019384526101008901943386526040519c8d9a63d52471c160e01b8c528c60048d01525160248c01525160448b0152600160a01b6001900390511660648a01525160848901525160a48801610120905261014488016110cb91611acf565b935160c48801525160e487015251916023198682030161010487015282518082528782019188808360051b83010195019286915b8383106111e557505092516001600160a01b0316610124880152505050839003918391905af19182156111da578492611199575b5090600080516020611e5a8339815191529260c092604051927fec4441362be16727d3342fcbac11e99fc9906b5e3621e58d90ec20bcd01dc53c8780a28583523490830152846040830152606082015261032060808201523460a0820152a16001805580f35b91508082813d83116111d3575b6111b0818361159d565b810103126111cf57905190600080516020611e5a833981519152611133565b8380fd5b503d6111a6565b6040513d86823e3d90fd5b9398509396986001929650611206819296601f198682030187528a51611acf565b980193019301938b948a97948a999794936110ff565b611002565b61123a915060203d602011610ad957610acb818361159d565b8a610fab565b60405162461bcd60e51b815260206004820152602b60248201527f427269646765577261703a206e6f7420656e6f75676820746f20636f7665722060448201526a1d1a19481d1e0818dbdcdd60aa1b6064820152608490fd5b34610157576040366003190112610157576112b2611550565b336001600160a01b038216036112ce5761022190600435611869565b63334bd91960e11b60005260046000fd5b34610157576000366003190112610157576040517f0000000000000000000000001c21d5b5bd5d2b859d1d5b12fd72db5ff7e98e926001600160a01b03168152602090f35b3461015757604036600319011261015757610221600435611343611550565b9061135f61021782600052600060205260016040600020015490565b6117de565b346101575760203660031901126101575760206102e8600435600052600060205260016040600020015490565b34610157576040366003190112610157576113aa61153a565b6113b2611550565b906113bb611731565b6040516370a0823160e01b81523060048201526001600160a01b03919091169190602081602481865afa9081156102ba5760009161146e575b5060405163a9059cbb60e01b60208201526001600160a01b0383166024820152604481019190915261143d9061143781606481015b03601f19810183528261159d565b83611c97565b6001600160a01b0316907f84dc653e543190fda51ad370aa0334e146df4dc9a60dcc43bf1f005b37b785b3600080a3005b90506020813d60201161149a575b816114896020938361159d565b8101031261015757516114296113f4565b3d915061147c565b34610157576000366003190112610157576040517f00000000000000000000000003f5be358fc2c4df88723a63148bd829b8aa5c916001600160a01b03168152602090f35b34610157576020366003190112610157576004359063ffffffff60e01b821680920361015757602091637965db0b60e01b8114908115611529575b5015158152f35b6301ffc9a760e01b14905083611522565b600435906001600160a01b038216820361015757565b602435906001600160a01b038216820361015757565b606090600319011261015757600435906024359060443590565b610120810190811067ffffffffffffffff821117610a1557604052565b90601f8019910116810190811067ffffffffffffffff821117610a1557604052565b9081602091031261015757516001600160a01b03811681036101575790565b91908203918211610daf57565b604051631c588c9d60e21b81527f000000000000000000000000000000000000000000000000000000000000054160048201526024810191909152604481019190915261032060648201526020816084817f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52136001600160a01b03165afa9081156102ba5760009161167a575090565b90506020813d6020116116a1575b816116956020938361159d565b81010312610157575190565b3d9150611688565b919060405192631c588c9d60e21b84527f0000000000000000000000000000000000000000000000000000000000000541600485015260248401526044830152606482015260208160848160018060a01b037f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb5213165afa9081156102ba5760009161167a575090565b3360009081527f20be27040b8e00df40bca0df34743417f3574a156386188f7d7f14369e5ee82b602052604090205460ff161561176a57565b63e2517d3f60e01b600052336004527f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec60245260446000fd5b60008181526020818152604080832033845290915290205460ff16156117c65750565b63e2517d3f60e01b6000523360045260245260446000fd5b6000818152602081815260408083206001600160a01b038616845290915290205460ff16611862576000818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b5050600090565b6000818152602081815260408083206001600160a01b038616845290915290205460ff1615611862576000818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b6002600154146118fc576002600155565b633ee5aeb560e01b60005260046000fd5b6040516370a0823160e01b81523060048201527f00000000000000000000000003f5be358fc2c4df88723a63148bd829b8aa5c916001600160a01b031692906000602082602481885afa918215611ac2578192611a8e575b507f0000000000000000000000001c21d5b5bd5d2b859d1d5b12fd72db5ff7e98e926001600160a01b031694853b15611a8a57818596600460405180998193633a4b66f160e01b83525af1958615611a7f576024949596611a6a575b50602090604051948580926370a0823160e01b82523060048301525afa908115611a5e5790611a2a575b6119f592506115de565b916040519081528260208201527f7494e309a68e673da9e1de3ae72425566aad3afb6b7ea7d70a590042a3a3864960403392a2565b506020823d602011611a56575b81611a446020938361159d565b81010312610157576119f591516119eb565b3d9150611a37565b604051903d90823e3d90fd5b91611a78816020939461159d565b91906119c1565b6040513d84823e3d90fd5b5080fd5b9091506020813d602011611aba575b81611aaa6020938361159d565b81010312611a8a57519038611965565b3d9150611a9d565b50604051903d90823e3d90fd5b919082519283825260005b848110611afb575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201611ada565b81810292918115918404141715610daf57565b8115611b2d570490565b634e487b7160e01b600052601260045260246000fd5b6040516318160ddd60e01b81526020816004817f00000000000000000000000003f5be358fc2c4df88723a63148bd829b8aa5c916001600160a01b03165afa9081156102ba57600091611c65575b5060405163dcd2af1760e01b815260208160048160007f0000000000000000000000001c21d5b5bd5d2b859d1d5b12fd72db5ff7e98e926001600160a01b03165af19081156102ba57600091611c33575b508015611c2e57611bf39192611b10565b90620f4240820291808304620f42401490151715610daf57620e7ef0810290808204620e7ef01490151715610daf57611c2b91611b23565b90565b505090565b906020823d602011611c5d575b81611c4d6020938361159d565b81010312610b5057505138611be2565b3d9150611c40565b906020823d602011611c8f575b81611c7f6020938361159d565b81010312610b5057505138611b91565b3d9150611c72565b906000602091828151910182855af1156102ba576000513d611ce957506001600160a01b0381163b155b611cc85750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b60011415611cc1565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830181905294919390831691602085604481865afa9485156102ba57600095611dfe575b508401809411610daf5760405163095ea7b360e01b60208083019182526001600160a01b0393909316602483015260448083019690965294815293600090611d7f60648761159d565b85519082865af1903d6000519083611ddf575b50505015611d9f57505050565b611dd8611ddd936040519063095ea7b360e01b602083015260248201526000604482015260448152611dd260648261159d565b82611c97565b611c97565b565b91925090611df457503b15155b388080611d92565b6001915014611dec565b90946020823d602011611e2a575b81611e196020938361159d565b81010312610b505750519338611d36565b3d9150611e0c565b90816020910312610157575160ff811681036101575790565b604d8111610daf57600a0a9056fe5f87d560a81e5773771cbc043e287825a431c438dbe04f38a10dc4d381a0beb8a26469706673582212203466367c372b2ff3c218844e5d113e564f5f54394138259aab0626d8991af1f764736f6c634300081b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000003f5be358fc2c4df88723a63148bd829b8aa5c910000000000000000000000000000000000000000000000000000000000000541000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52130000000000000000000000001c2cc2428736971cea04859c9b96f6b63d7110ae0000000000000000000000001c2cc2428736971cea04859c9b96f6b63d7110ae0000000000000000000000001c21d5b5bd5d2b859d1d5b12fd72db5ff7e98e920000000000000000000000003b5cc7d992f8ed1b4e1f9f660984adcd61fc1aca00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45
-----Decoded View---------------
Arg [0] : _nativeCoin (address): 0x03F5BE358fc2C4DF88723a63148bd829B8AA5c91
Arg [1] : _chainId (uint256): 1345
Arg [2] : _bridgeHub (address): 0x303a465B659cBB0ab36eE643eA362c509EEb5213
Arg [3] : _admin (address): 0x1c2Cc2428736971cEa04859c9B96F6b63D7110aE
Arg [4] : _withdrawer (address): 0x1c2Cc2428736971cEa04859c9B96F6b63D7110aE
Arg [5] : _liquidityManager (address): 0x1c21d5B5bd5d2b859D1D5B12Fd72db5ff7e98E92
Arg [6] : _ozUSDVault (address): 0x3B5cc7D992F8ED1b4E1f9F660984adCd61fC1aCa
Arg [7] : _univ3router (address): 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 00000000000000000000000003f5be358fc2c4df88723a63148bd829b8aa5c91
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000541
Arg [2] : 000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb5213
Arg [3] : 0000000000000000000000001c2cc2428736971cea04859c9b96f6b63d7110ae
Arg [4] : 0000000000000000000000001c2cc2428736971cea04859c9b96f6b63d7110ae
Arg [5] : 0000000000000000000000001c21d5b5bd5d2b859d1d5b12fd72db5ff7e98e92
Arg [6] : 0000000000000000000000003b5cc7d992f8ed1b4e1f9f660984adcd61fc1aca
Arg [7] : 00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45
Loading...
Loading
Loading...
Loading

Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
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.