{"file_path":"contracts/TokenGovernor.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\nimport {AccessControlDefaultAdminRules} from\n\"@openzeppelin/contracts/access/extensions/AccessControlDefaultAdminRules.sol\";\nimport {IAccessControlEnumerable} from \"@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol\";\nimport {IERC20, SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n\nimport {IChecker} from \"./interfaces/IChecker.sol\";\nimport {IGovernedToken} from \"./interfaces/IGovernedToken.sol\";\nimport {ITokenGovernor} from \"./interfaces/ITokenGovernor.sol\";\n\n/**\n * @title TokenGovernor\n * @dev Governance contract for managing a Token with permissioned functions.\n * It implements the IExternalMinter interface and provides access control for various roles.\n * This contract allows for minting, burning, freezing, unfreezing, pausing,\n * unpausing, and transferring ownership of the governed token.\n * Each permissioned function has its own role for granular access control.\n * It also allows for a checker contract to validate minting and burning operations.\n */\ncontract TokenGovernor is AccessControlDefaultAdminRules, ITokenGovernor {\n    using SafeERC20 for IERC20;\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    // Role definitions\n    bytes32 public constant override MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n    bytes32 public constant override BRIDGE_MINTER_OR_BURNER_ROLE = keccak256(\"BRIDGE_MINTER_OR_BURNER_ROLE\");\n    bytes32 public constant override BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n    bytes32 public constant override FREEZER_ROLE = keccak256(\"FREEZER_ROLE\");\n    bytes32 public constant override UNFREEZER_ROLE = keccak256(\"UNFREEZER_ROLE\");\n    bytes32 public constant override PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n    bytes32 public constant override UNPAUSER_ROLE = keccak256(\"UNPAUSER_ROLE\");\n    bytes32 public constant override RECOVERY_ROLE = keccak256(\"RECOVERY_ROLE\");\n    bytes32 public constant override CHECKER_ADMIN_ROLE = keccak256(\"CHECKER_ADMIN_ROLE\");\n\n    // Token being governed (immutable)\n    IGovernedToken internal immutable i_token;\n\n    // Checker contract\n    address internal s_checker;\n\n    mapping(bytes32 role => EnumerableSet.AddressSet) private _roleMembers;\n\n    /**\n     * @dev Constructor sets up the initial admin roles and token address (immutable),\n     * and initializes the initial delay and default admin.\n     * @param token The address of the token contract to be governed\n     * @param initialDelay The initial delay for the contract\n     * @param initialDefaultAdmin The address of the initial default admin\n     */\n    constructor(address token, uint48 initialDelay, address initialDefaultAdmin)\n    AccessControlDefaultAdminRules(initialDelay, initialDefaultAdmin)\n    {\n        if (token == address(0)) revert ZeroAddressNotAllowed();\n\n        i_token = IGovernedToken(token);\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) public view virtual returns (address) {\n        return _roleMembers[role].at(index);\n    }\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) public view virtual returns (uint256) {\n        return _roleMembers[role].length();\n    }\n\n    /**\n     * @dev Return all accounts that have `role`\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function getRoleMembers(bytes32 role) public view virtual returns (address[] memory) {\n        return _roleMembers[role].values();\n    }\n\n    /*\n     * @dev Get the address of the token contract\n     * @return Address of the token contract\n     */\n    function getToken() external view override returns (address) {\n        return address(i_token);\n    }\n\n    /**\n     * @dev Get the address of the checker contract\n     * @return Address of the checker contract\n     */\n    function getChecker() external view override returns (address) {\n        return s_checker;\n    }\n\n    /**\n     * @dev Get all admins (holders of DEFAULT_ADMIN_ROLE)\n     * @return Array of admin addresses\n     */\n    function getAdmins() external view override returns (address[] memory) {\n        return getRoleMembers(DEFAULT_ADMIN_ROLE);\n    }\n\n    /**\n     * @dev Get all addresses with MINTER_ROLE\n     * @return Array of minter addresses\n     */\n    function getMinters() external view override returns (address[] memory) {\n        return getRoleMembers(MINTER_ROLE);\n    }\n\n    /**\n     * @dev Get all addresses with BRIDGE_MINTER_ROLE\n     * @return Array of bridge minter addresses\n     */\n    function getBridgeMintersOrBurners() external view override returns (address[] memory) {\n        return getRoleMembers(BRIDGE_MINTER_OR_BURNER_ROLE);\n    }\n\n    /**\n     * @dev Get all addresses with BURNER_ROLE\n     * @return Array of burner addresses\n     */\n    function getBurners() external view override returns (address[] memory) {\n        return getRoleMembers(BURNER_ROLE);\n    }\n\n    /**\n     * @dev Get all addresses with FREEZER_ROLE\n     * @return Array of freezer addresses\n     */\n    function getFreezers() external view override returns (address[] memory) {\n        return getRoleMembers(FREEZER_ROLE);\n    }\n\n    /**\n     * @dev Get all addresses with UNFREEZER_ROLE\n     * @return Array of unfreezer addresses\n     */\n    function getUnfreezers() external view override returns (address[] memory) {\n        return getRoleMembers(UNFREEZER_ROLE);\n    }\n\n    /**\n     * @dev Get all addresses with PAUSER_ROLE\n     * @return Array of pauser addresses\n     */\n    function getPausers() external view override returns (address[] memory) {\n        return getRoleMembers(PAUSER_ROLE);\n    }\n\n    /**\n     * @dev Get all addresses with UNPAUSER_ROLE\n     * @return Array of unpauser addresses\n     */\n    function getUnpausers() external view override returns (address[] memory) {\n        return getRoleMembers(UNPAUSER_ROLE);\n    }\n\n    /**\n     * @dev Get all addresses with RECOVERY_ROLE\n     * @return Array of recovery manager addresses\n     */\n    function getRecoveryManagers() external view override returns (address[] memory) {\n        return getRoleMembers(RECOVERY_ROLE);\n    }\n\n    /**\n     * @dev Get all addresses with CHECKER_ADMIN_ROLE\n     * @return Array of checker admin addresses\n     */\n    function getCheckerAdmins() external view override returns (address[] memory) {\n        return getRoleMembers(CHECKER_ADMIN_ROLE);\n    }\n\n    /**\n     * @dev Check the current balance of the governed token held by this contract\n     * @return Balance of the token\n     */\n    function getTokenBalance() external view override returns (uint256) {\n        return i_token.balanceOf(address(this));\n    }\n\n    /**\n     * @dev Set the checker contract address (requires CHECKER_ADMIN_ROLE)\n     * @param newChecker The address of the new checker contract\n     */\n    function setChecker(address newChecker) external override onlyRole(CHECKER_ADMIN_ROLE) {\n        address oldChecker = s_checker;\n        s_checker = newChecker;\n        emit CheckerUpdated(oldChecker, newChecker);\n    }\n\n    // ===========================================================\n    // =============== Token passthrough functions ===============\n    // ===========================================================\n\n    /**\n     * @dev Mint new tokens and transfer them to the caller (requires MINTER_ROLE or BRIDGE_MINTER_ROLE)\n     * @param amount Amount of tokens to mint\n     * @return True if successful\n     */\n    function mint(uint256 amount) external override returns (bool) {\n        _mint( /* recipient = */ msg.sender, amount);\n        return true;\n    }\n\n    /**\n     * @dev Mint tokens to a specific address (requires MINTER_ROLE or BRIDGE_MINTER_ROLE)\n     * @param recipient Address to receive the minted tokens\n     * @param amount Amount of tokens to mint\n     * @return True if successful\n     */\n    function mint(address recipient, uint256 amount) external override returns (bool) {\n        _mint(recipient, amount);\n        return true;\n    }\n\n    /**\n     * @dev Burn tokens from the caller (requires BURNER_ROLE).\n     * The sender must have approved this contract to spend the tokens\n     * @param amount Amount of tokens to burn\n     * @return True if successful\n     */\n    function burn(uint256 amount) external override returns (bool) {\n        _burn( /* from = */ msg.sender, amount);\n        return true;\n    }\n\n    /**\n     * @dev Burn tokens from a specific address (requires BURNER_ROLE)\n     * @param from Address to burn tokens from. Must have an approval set on this contract\n     * @param amount Amount of tokens to burn\n     * @return True if successful\n     */\n    function burnFrom(address from, uint256 amount) external override returns (bool) {\n        _burn(from, amount);\n        return true;\n    }\n\n    /**\n     * @dev Add an address to frozen state (requires FREEZER_ROLE)\n     * @param account Address to freeze\n     */\n    function freeze(address account) external override onlyRole(FREEZER_ROLE) {\n        _freeze(account);\n    }\n\n    /**\n     * @dev Add a list of addresses to frozen state (requires FREEZER_ROLE)\n     * @param accounts List of addresses to freeze\n     */\n    function batchFreeze(address[] calldata accounts) external override onlyRole(FREEZER_ROLE) {\n        for (uint256 i = 0; i < accounts.length; i++) {\n            _freeze(accounts[i]);\n        }\n    }\n\n    /**\n     * @dev Remove an address from frozen state (requires UNFREEZER_ROLE)\n     * @param account Address to unfreeze\n     */\n    function unfreeze(address account) external override onlyRole(UNFREEZER_ROLE) {\n        _unfreeze(account);\n    }\n\n    /**\n     * @dev Remove a list of addresses from frozen state (requires UNFREEZER_ROLE)\n     * @param accounts List of addresses to unfreeze\n     */\n    function batchUnfreeze(address[] calldata accounts) external override onlyRole(UNFREEZER_ROLE) {\n        for (uint256 i = 0; i < accounts.length; i++) {\n            _unfreeze(accounts[i]);\n        }\n    }\n\n    /**\n     * @dev Pause all token transfers (requires PAUSER_ROLE)\n     */\n    function pause() external override onlyRole(PAUSER_ROLE) {\n        i_token.pause();\n        emit ContractPaused(msg.sender);\n    }\n\n    /**\n     * @dev Unpause token transfers (requires UNPAUSER_ROLE)\n     */\n    function unpause() external override onlyRole(UNPAUSER_ROLE) {\n        i_token.unpause();\n        emit ContractUnpaused(msg.sender);\n    }\n\n    /**\n     * @dev Begin transfer of ownership (requires DEFAULT_ADMIN_ROLE)\n     * @param newOwner Address of the new owner\n     */\n    function transferOwnership(address newOwner) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n        i_token.transferOwnership(newOwner);\n        emit OwnershipTransferred(msg.sender, newOwner);\n    }\n\n    /**\n     * @dev Complete transfer of ownership (requires DEFAULT_ADMIN_ROLE)\n     */\n    function acceptOwnership() external override onlyRole(DEFAULT_ADMIN_ROLE) {\n        i_token.acceptOwnership();\n        emit OwnershipAccepted(msg.sender);\n    }\n\n    /**\n     * @dev Emergency recovery of tokens accidentally sent to this contract (requires RECOVERY_ROLE)\n     * @param token Address of token to recover\n     * @param recipient Address to receive the tokens\n     * @param amount Amount to recover\n     */\n    function recoverERC20(address token, address recipient, uint256 amount) external override onlyRole(RECOVERY_ROLE) {\n        if (recipient == address(0)) revert ZeroAddressNotAllowed();\n        IERC20(token).safeTransfer(recipient, amount);\n        emit TokensRecovered(msg.sender, token, recipient, amount);\n    }\n\n    /**\n     * @dev Emergency recovery of tokens sent to the governed token contract (requires RECOVERY_ROLE)\n     * @param token Address of token to recover\n     * @param recipient Address to receive the tokens\n     * @param amount Amount to recover\n     */\n    function recoverGovernedTokenERC20(address token, address recipient, uint256 amount)\n    external\n    override\n    onlyRole(RECOVERY_ROLE)\n    {\n        i_token.recoverERC20(token, recipient, amount);\n        emit GovernedTokensRecovered(msg.sender, token, recipient, amount);\n    }\n\n    /**\n     * @dev Drains the tokens from a frozen account (requires DEFAULT_ADMIN_ROLE)\n     * @param account Address to drain tokens from\n     */\n    function drainFrozenAccount(address account) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n        _drainFrozenAccount(account);\n    }\n\n    /**\n     * @dev Drains the tokens from a list of frozen accounts (requires DEFAULT_ADMIN_ROLE)\n     * @param accounts List of addresses to drain tokens from\n     */\n    function batchDrainFrozenAccounts(address[] calldata accounts) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n        for (uint256 i = 0; i < accounts.length; i++) {\n            _drainFrozenAccount(accounts[i]);\n        }\n    }\n\n    /**\n     * @dev Execute a custom function call on the token (requires DEFAULT_ADMIN_ROLE)\n     * This allows for calling any function not explicitly defined in this contract.\n     * Any native token sent with the call will be forwarded to the token contract.\n     * @param data Function call data\n     * @return returnData The data returned by the call\n     */\n    function executeTokenFunction(bytes calldata data)\n    external\n    payable\n    override\n    onlyRole(DEFAULT_ADMIN_ROLE)\n    returns (bytes memory)\n    {\n        (bool success, bytes memory returnData) = address(i_token).call{value: msg.value}(data);\n        if (!success) revert CallFailed(returnData);\n\n        emit TokenFunctionExecuted(msg.sender, data, returnData);\n\n        return returnData;\n    }\n\n    // ==================================================\n    // =============== Internal Functions ===============\n    // ==================================================\n\n    /**\n     * @dev Internal function to mint tokens with checker validation and role verification\n     * @param recipient Address to receive the minted tokens (can not be this contract)\n     * @param amount Amount of tokens to mint\n     */\n    function _mint(address recipient, uint256 amount) internal {\n        // Check that the caller has either MINTER_ROLE or BRIDGE_MINTER_OR_BURNER_ROLE\n        // and that the recipient is not this contract\n        bool isBridge = hasRole(BRIDGE_MINTER_OR_BURNER_ROLE, msg.sender);\n        if (!isBridge && !hasRole(MINTER_ROLE, msg.sender)) revert OnlyMinterOrBridge();\n        if (recipient == address(this)) revert InvalidRecipient();\n\n        // Run checker if it is set\n        address checker = s_checker;\n        if (checker != address(0)) {\n            IChecker(checker).checkMint(recipient, amount, msg.sender, isBridge);\n        }\n\n        _tokenMint(recipient, amount);\n\n        if (isBridge) {\n            emit BridgeMint(msg.sender, recipient, amount);\n        } else {\n            emit NativeMint(msg.sender, recipient, amount);\n        }\n    }\n\n    /**\n     * @dev Internal function to burn tokens with checker validation and role verification\n     * @param from Address whose tokens are being burned\n     * @param amount Amount of tokens to burn\n     */\n    function _burn(address from, uint256 amount) internal {\n        // Check that the caller has either BURNER_ROLE or BRIDGE_MINTER_OR_BURNER_ROLE\n        bool isBridge = hasRole(BRIDGE_MINTER_OR_BURNER_ROLE, msg.sender);\n        if (!isBridge && !hasRole(BURNER_ROLE, msg.sender)) revert OnlyBurnerOrBridge();\n        if (from == address(this)) revert InvalidFrom();\n\n        // Run checker if it is set\n        address checker = s_checker;\n        if (checker != address(0)) {\n            IChecker(checker).checkBurn(from, amount, msg.sender, isBridge);\n        }\n\n        _tokenBurn(from, amount);\n\n        if (isBridge) {\n            emit BridgeBurn(msg.sender, from, amount);\n        } else {\n            emit NativeBurn(msg.sender, from, amount);\n        }\n    }\n\n    /**\n     * @dev Internal function to freeze an account\n     * @param account Address to freeze\n     */\n    function _freeze(address account) internal {\n        i_token.freeze(account);\n        emit AccountFrozen(msg.sender, account);\n    }\n\n    /**\n     * @dev Internal function to remove an account from frozen state\n     * @param account Address to unfreeze\n     */\n    function _unfreeze(address account) internal {\n        i_token.unfreeze(account);\n        emit AccountUnfrozen(msg.sender, account);\n    }\n\n    /**\n     * @dev Internal function to drain tokens from a frozen account\n     * @param account Address to drain tokens from\n     */\n    function _drainFrozenAccount(address account) internal {\n        i_token.drain(account);\n        emit FrozenAccountDrained(msg.sender, account);\n    }\n\n    /**\n     * @dev Internal function to mint tokens directly to a recipient\n     * In this case, mint the token to this contract and then transfer it to the recipient\n     * @param recipient Address to receive the minted tokens\n     * @param amount Amount of tokens to mint\n     */\n    function _tokenMint(address recipient, uint256 amount) internal virtual {\n        if (!i_token.mint(amount)) revert MintFailed();\n        IERC20(i_token).safeTransfer(recipient, amount);\n    }\n\n    /**\n     * @dev Internal function to burn tokens from a specific address\n     * In this case, transfer the tokens from the address to this contract and then burn them,\n     * This requires the `from` address to have approved this contract to spend the tokens.\n     * @param from Address whose tokens are being burned\n     * @param amount Amount of tokens to burn\n     */\n    function _tokenBurn(address from, uint256 amount) internal virtual {\n        IERC20(i_token).safeTransferFrom(from, address(this), amount);\n        if (!i_token.burn(amount)) revert BurnFailed();\n    }\n\n    /**\n     * @dev Overload {AccessControlDefaultAdminRules-_grantRole} to track enumerable memberships\n     */\n    function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {\n        bool granted = super._grantRole(role, account);\n        if (granted) {\n            _roleMembers[role].add(account);\n        }\n        return granted;\n    }\n\n    /**\n     * @dev Overload {AccessControlDefaultAdminRules-_revokeRole} to track enumerable memberships\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {\n        bool revoked = super._revokeRole(role, account);\n        if (revoked) {\n            _roleMembers[role].remove(account);\n        }\n        return revoked;\n    }\n}\n","deployed_bytecode":"0x6080604052600436106103a25760003560e01c80638456cb59116101e7578063ca15c8731161010d578063d5c85140116100a0578063e78a14f51161006f578063e78a14f514610aad578063f2fde38b14610ac2578063fb1bb9de14610ae2578063fcedb9e514610b1657600080fd5b8063d5c8514014610a31578063d602b9fd14610a46578063e0c0906f14610a5b578063e63ab1e914610a7957600080fd5b8063cf880f4c116100dc578063cf880f4c1461099d578063d22224a9146109bd578063d5391393146109dd578063d547741f14610a1157600080fd5b8063ca15c87314610930578063cc8463c814610950578063cefc142914610965578063cf6eefb71461097a57600080fd5b80639ddc3f5c11610185578063a3246ad311610154578063a3246ad3146108c6578063a6cc8d40146108e6578063c35f7c62146108fb578063c721e8c01461091057600080fd5b80639ddc3f5c14610859578063a0712d681461086e578063a1eda53c1461088e578063a217fddf146108b157600080fd5b80638d1fdf2f116101c15780638d1fdf2f146107e45780638da5cb5b146108045780639010d07c1461081957806391d148541461083957600080fd5b80638456cb591461079c57806384ef8ffc146107b157806386fe8b43146107cf57600080fd5b806331993a1c116102cc57806360ea92081161026a57806379ba50971161023957806379ba50971461073d57806379cc6790146107525780638118efda1461077257806382b2e2571461078757600080fd5b806360ea9208146106c8578063634e93da146106e8578063649a5ec7146107085780636b32810b1461072857600080fd5b80633f4ba83a116102a65780633f4ba83a1461065357806340c10f191461066857806342966c681461068857806345c8b1a6146106a857600080fd5b806331993a1c146105fc57806331ae450b1461061e57806336568abe1461063357600080fd5b806321df0da7116103445780632c92ba9c116103135780632c92ba9c1461057a5780632dbc9db91461059a5780632f2ff15d146105ba578063312963e5146105da57600080fd5b806321df0da7146104b8578063248a9ca3146104f4578063248e6c0814610524578063282c51f31461054657600080fd5b806306a85f0f1161038057806306a85f0f1461043d5780630aa6220b1461045f5780631171bda9146104765780631e42b8b11461049657600080fd5b806301ffc9a7146103a7578063022d63fb146103dd5780630568b3da146103fc575b600080fd5b3480156103b357600080fd5b506103c76103c236600461289d565b610b36565b6040516103d491906128d0565b60405180910390f35b3480156103e957600080fd5b50620697805b6040516103d491906128ec565b34801561040857600080fd5b506104307fb9f997e9b8b4ceb22077d832bcbf6f751de391a9ad51c4c81e58db4b9214f8e381565b6040516103d49190612900565b34801561044957600080fd5b50610430600080516020612eec83398151915281565b34801561046b57600080fd5b50610474610b61565b005b34801561048257600080fd5b50610474610491366004612944565b610b77565b3480156104a257600080fd5b506104ab610c25565b6040516103d491906129fa565b3480156104c457600080fd5b507f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d5b6040516103d49190612a0b565b34801561050057600080fd5b5061043061050f366004612a19565b60009081526020819052604090206001015490565b34801561053057600080fd5b50610430600080516020612f2c83398151915281565b34801561055257600080fd5b506104307f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b34801561058657600080fd5b50610474610595366004612a3a565b610c43565b3480156105a657600080fd5b506104746105b5366004612aad565b610c5b565b3480156105c657600080fd5b506104746105d5366004612af5565b610cbb565b3480156105e657600080fd5b50610430600080516020612f0c83398151915281565b34801561060857600080fd5b50610430600080516020612f4c83398151915281565b34801561062a57600080fd5b506104ab610ce3565b34801561063f57600080fd5b5061047461064e366004612af5565b610cef565b34801561065f57600080fd5b50610474610d97565b34801561067457600080fd5b506103c7610683366004612b32565b610e62565b34801561069457600080fd5b506103c76106a3366004612a19565b610e77565b3480156106b457600080fd5b506104746106c3366004612a3a565b610e8b565b3480156106d457600080fd5b506104746106e3366004612aad565b610eac565b3480156106f457600080fd5b50610474610703366004612a3a565b610f06565b34801561071457600080fd5b50610474610723366004612b7e565b610f1a565b34801561073457600080fd5b506104ab610f2e565b34801561074957600080fd5b50610474610f59565b34801561075e57600080fd5b506103c761076d366004612b32565b611005565b34801561077e57600080fd5b506104ab611011565b34801561079357600080fd5b5061043061102a565b3480156107a857600080fd5b506104746110ba565b3480156107bd57600080fd5b506002546001600160a01b03166104e7565b3480156107db57600080fd5b506104ab611185565b3480156107f057600080fd5b506104746107ff366004612a3a565b6111b0565b34801561081057600080fd5b506104e76111d1565b34801561082557600080fd5b506104e7610834366004612b9f565b6111e5565b34801561084557600080fd5b506103c7610854366004612af5565b611204565b34801561086557600080fd5b506104ab61122d565b34801561087a57600080fd5b506103c7610889366004612a19565b611258565b34801561089a57600080fd5b506108a3611264565b6040516103d4929190612bc1565b3480156108bd57600080fd5b50610430600081565b3480156108d257600080fd5b506104ab6108e1366004612a19565b6112b8565b3480156108f257600080fd5b506104ab6112d2565b34801561090757600080fd5b506104ab6112fd565b34801561091c57600080fd5b5061047461092b366004612944565b611316565b34801561093c57600080fd5b5061043061094b366004612a19565b6113fd565b34801561095c57600080fd5b506103ef611414565b34801561097157600080fd5b50610474611473565b34801561098657600080fd5b5061098f6114b3565b6040516103d4929190612bdc565b3480156109a957600080fd5b506104746109b8366004612a3a565b6114d4565b3480156109c957600080fd5b506104746109d8366004612aad565b611551565b3480156109e957600080fd5b506104307f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b348015610a1d57600080fd5b50610474610a2c366004612af5565b61159e565b348015610a3d57600080fd5b506104ab6115c6565b348015610a5257600080fd5b506104746115f1565b348015610a6757600080fd5b506003546001600160a01b03166104e7565b348015610a8557600080fd5b506104307f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b348015610ab957600080fd5b506104ab611604565b348015610ace57600080fd5b50610474610add366004612a3a565b61161d565b348015610aee57600080fd5b506104307f427da25fe773164f88948d3e215c94b6554e2ed5e5f203a821c9f2f6131cf75a81565b610b29610b24366004612c35565b6116e0565b6040516103d49190612cc9565b60006001600160e01b03198216635a05180f60e01b1480610b5b5750610b5b826117e0565b92915050565b6000610b6c81611805565b610b7461180f565b50565b600080516020612f4c833981519152610b8f81611805565b6001600160a01b038316610bb6576040516342bcdf7f60e11b815260040160405180910390fd5b610bca6001600160a01b038516848461181c565b826001600160a01b0316846001600160a01b0316336001600160a01b03167fa2231b10d9b4e4166c8a827c99f97691b05aa88fb04e009a4e499005b5c50fcc85604051610c179190612900565b60405180910390a450505050565b6060610c3e600080516020612f4c8339815191526112b8565b905090565b6000610c4e81611805565b610c5782611879565b5050565b600080516020612f2c833981519152610c7381611805565b60005b82811015610cb557610cad848483818110610c9357610c93612cda565b9050602002016020810190610ca89190612a3a565b611930565b600101610c76565b50505050565b81610cd957604051631fe1e13d60e11b815260040160405180910390fd5b610c5782826119e7565b6060610c3e60006112b8565b81158015610d0a57506002546001600160a01b038281169116145b15610d8d57600080610d1a6114b3565b90925090506001600160a01b038216151580610d3c575065ffffffffffff8116155b80610d4f57504265ffffffffffff821610155b15610d7857806040516319ca5ebb60e01b8152600401610d6f91906128ec565b60405180910390fd5b50506001805465ffffffffffff60a01b191690555b610c578282611a0c565b7f427da25fe773164f88948d3e215c94b6554e2ed5e5f203a821c9f2f6131cf75a610dc181611805565b7f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d6001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e1c57600080fd5b505af1158015610e30573d6000803e3d6000fd5b50506040513392507f5b65b0c1363b3003db9bcc5e1fd8805a6d6bf5bf6dc9d3431ee4494cd7d117669150600090a250565b6000610e6e8383611a3f565b50600192915050565b6000610e833383611bff565b506001919050565b600080516020612f2c833981519152610ea381611805565b610c5782611930565b600080516020612eec833981519152610ec481611805565b60005b82811015610cb557610efe848483818110610ee457610ee4612cda565b9050602002016020810190610ef99190612a3a565b611da4565b600101610ec7565b6000610f1181611805565b610c5782611e5b565b6000610f2581611805565b610c5782611ec9565b6060610c3e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66112b8565b6000610f6481611805565b7f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d6001600160a01b03166379ba50976040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610fbf57600080fd5b505af1158015610fd3573d6000803e3d6000fd5b50506040513392507fb27970c1714b28277b78cc17ac2fe9556e7f048cd48358cffe3dc7d547608fdc9150600090a250565b6000610e6e8383611bff565b6060610c3e600080516020612eec8339815191526112b8565b6040516370a0823160e01b81526000906001600160a01b037f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d16906370a0823190611079903090600401612a0b565b602060405180830381865afa158015611096573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3e9190612cfb565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6110e481611805565b7f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d6001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561113f57600080fd5b505af1158015611153573d6000803e3d6000fd5b50506040513392507f81990fd9a5c552b8e3677917d8a03c07678f0d2cb68f88b634aca2022e9bd19f9150600090a250565b6060610c3e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486112b8565b600080516020612eec8339815191526111c881611805565b610c5782611da4565b6000610c3e6002546001600160a01b031690565b60008281526004602052604081206111fd9083611f30565b9392505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6060610c3e7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6112b8565b6000610e833383611a3f565b600254600090600160d01b900465ffffffffffff16801515801561129057504265ffffffffffff821610155b61129c576000806112b0565b600254600160a01b900465ffffffffffff16815b915091509091565b6000818152600460205260409020606090610b5b90611f3c565b6060610c3e7f427da25fe773164f88948d3e215c94b6554e2ed5e5f203a821c9f2f6131cf75a6112b8565b6060610c3e600080516020612f0c8339815191526112b8565b600080516020612f4c83398151915261132e81611805565b604051631171bda960e01b81526001600160a01b037f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d1690631171bda99061137e90879087908790600401612d1c565b600060405180830381600087803b15801561139857600080fd5b505af11580156113ac573d6000803e3d6000fd5b50505050826001600160a01b0316846001600160a01b0316336001600160a01b03167f42f446384ff78c62bf2caa065e680c6010e2f54857d15bee828d6c7d5735389385604051610c179190612900565b6000818152600460205260408120610b5b90611f49565b600254600090600160d01b900465ffffffffffff16801515801561143f57504265ffffffffffff8216105b61145a57600154600160d01b900465ffffffffffff1661146d565b600254600160a01b900465ffffffffffff165b91505090565b600061147d6114b3565b509050336001600160a01b038216146114ab5733604051636116401160e11b8152600401610d6f9190612a0b565b610b74611f53565b6001546001600160a01b03811691600160a01b90910465ffffffffffff1690565b7fb9f997e9b8b4ceb22077d832bcbf6f751de391a9ad51c4c81e58db4b9214f8e36114fe81611805565b600380546001600160a01b038481166001600160a01b0319831681179093556040519116919082907f35631e65f3bb46b57c2cfadf0d2ca3f08e6cbab52c2ff987b5328c9b37d45ea390600090a3505050565b600061155c81611805565b60005b82811015610cb55761159684848381811061157c5761157c612cda565b90506020020160208101906115919190612a3a565b611879565b60010161155f565b816115bc57604051631fe1e13d60e11b815260040160405180910390fd5b610c578282611fe4565b6060610c3e7fb9f997e9b8b4ceb22077d832bcbf6f751de391a9ad51c4c81e58db4b9214f8e36112b8565b60006115fc81611805565b610b74612009565b6060610c3e600080516020612f2c8339815191526112b8565b600061162881611805565b60405163f2fde38b60e01b81526001600160a01b037f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d169063f2fde38b90611674908590600401612a0b565b600060405180830381600087803b15801561168e57600080fd5b505af11580156116a2573d6000803e3d6000fd5b50506040516001600160a01b03851692503391507f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b606060006116ed81611805565b6000807f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d6001600160a01b031634878760405161172b929190612d63565b60006040518083038185875af1925050503d8060008114611768576040519150601f19603f3d011682016040523d82523d6000602084013e61176d565b606091505b509150915081611792578060405163a5fa8d2b60e01b8152600401610d6f9190612cc9565b336001600160a01b03167f3f341ef37380014c90cd66348f1e20455df1b642e6a3445f39dd66f88110cc658787846040516117cf93929190612d93565b60405180910390a295945050505050565b60006001600160e01b031982166318a4c3c360e11b1480610b5b5750610b5b82612014565b610b748133612049565b61181a600080612074565b565b61187483846001600160a01b031663a9059cbb8585604051602401611842929190612dc2565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050612134565b505050565b604051637672989960e11b81526001600160a01b037f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d169063ece53132906118c5908490600401612a0b565b600060405180830381600087803b1580156118df57600080fd5b505af11580156118f3573d6000803e3d6000fd5b50506040516001600160a01b03841692503391507f8e535556a0a95ee3befe296cf986f7bf7d88881991e46f517c4b477c0ea6938590600090a350565b6040516322e458d360e11b81526001600160a01b037f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d16906345c8b1a69061197c908490600401612a0b565b600060405180830381600087803b15801561199657600080fd5b505af11580156119aa573d6000803e3d6000fd5b50506040516001600160a01b03841692503391507fe19c610e04dba2019efcfb0f9455fad3af646853bb02abad2a452db1fd47c32790600090a350565b600082815260208190526040902060010154611a0281611805565b610cb5838361219c565b6001600160a01b0381163314611a355760405163334bd91960e11b815260040160405180910390fd5b61187482826121d1565b6000611a59600080516020612f0c83398151915233611204565b905080158015611a905750611a8e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633611204565b155b15611aae576040516363e660e560e11b815260040160405180910390fd5b306001600160a01b03841603611ad757604051634e46966960e11b815260040160405180910390fd5b6003546001600160a01b03168015611b4e57604051637d1aee2360e11b81526001600160a01b0382169063fa35dc4690611b1b908790879033908890600401612ddd565b600060405180830381600087803b158015611b3557600080fd5b505af1158015611b49573d6000803e3d6000fd5b505050505b611b5884846121fe565b8115611bae57836001600160a01b0316336001600160a01b03167fc3b8ae385c02b938fbbbd694d1da0761f755ee2c942f26bbfc6723c986d31b9b85604051611ba19190612900565b60405180910390a3610cb5565b836001600160a01b0316336001600160a01b03167fc8a07fbf83d1ff93486eea14a0676adef77c8c95fa79c85cd7bba0d10204102f85604051611bf19190612900565b60405180910390a350505050565b6000611c19600080516020612f0c83398151915233611204565b905080158015611c505750611c4e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84833611204565b155b15611c6e576040516306e5da9160e11b815260040160405180910390fd5b306001600160a01b03841603611c975760405163104ca12160e11b815260040160405180910390fd5b6003546001600160a01b03168015611d0e57604051633a60702360e01b81526001600160a01b03821690633a60702390611cdb908790879033908890600401612ddd565b600060405180830381600087803b158015611cf557600080fd5b505af1158015611d09573d6000803e3d6000fd5b505050505b611d1884846122dd565b8115611d6157836001600160a01b0316336001600160a01b03167fabf8a0bc0c6341b64dfa026a551cda9d3beb0e0525758303026bacbc11ad1d8c85604051611ba19190612900565b836001600160a01b0316336001600160a01b03167f76bf0a63dad9216ecf94a5b1fdefa2c44ed7c809fe0028c4c2ce064b151c903f85604051611bf19190612900565b604051638d1fdf2f60e01b81526001600160a01b037f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d1690638d1fdf2f90611df0908490600401612a0b565b600060405180830381600087803b158015611e0a57600080fd5b505af1158015611e1e573d6000803e3d6000fd5b50506040516001600160a01b03841692503391507f2a3de20682fb291f444b5c1469d7e0950c558ce3dadf97163687873e29bcf4ae90600090a350565b6000611e65611414565b611e6e426123be565b611e789190612e28565b9050611e8482826123f0565b816001600160a01b03167f3377dc44241e779dd06afab5b788a35ca5f3b778836e2990bdb26a2a4b2e5ed682604051611ebd91906128ec565b60405180910390a25050565b6000611ed48261246f565b611edd426123be565b611ee79190612e28565b9050611ef38282612074565b7ff1038c18cf84a56e432fdbfaf746924b7ea511dfe03a6506a0ceba4888788d9b8282604051611f24929190612bc1565b60405180910390a15050565b60006111fd83836124b7565b606060006111fd836124e1565b6000610b5b825490565b600080611f5e6114b3565b91509150611f738165ffffffffffff16151590565b1580611f8757504265ffffffffffff821610155b15611fa757806040516319ca5ebb60e01b8152600401610d6f91906128ec565b611fc36000611fbe6002546001600160a01b031690565b6121d1565b50611fcf60008361219c565b5050600180546001600160d01b031916905550565b600082815260208190526040902060010154611fff81611805565b610cb583836121d1565b61181a6000806123f0565b60006001600160e01b03198216637965db0b60e01b1480610b5b57506301ffc9a760e01b6001600160e01b0319831614610b5b565b6120538282611204565b610c5757808260405163e2517d3f60e01b8152600401610d6f929190612dc2565b600254600160d01b900465ffffffffffff1680156120f7574265ffffffffffff821610156120cd57600254600180546001600160d01b0316600160a01b90920465ffffffffffff16600160d01b029190911790556120f7565b6040517f2b1fa2edafe6f7b9e97c1a9e0c3660e645beb2dcaa2d45bdbf9beaf5472e1ec590600090a15b50600280546001600160a01b0316600160a01b65ffffffffffff948516026001600160d01b031617600160d01b9290931691909102919091179055565b600080602060008451602086016000885af180612157576040513d6000823e3d81fd5b50506000513d9150811561216f57806001141561217c565b6001600160a01b0384163b155b15610cb55783604051635274afe760e01b8152600401610d6f9190612a0b565b6000806121a9848461253d565b905080156111fd5760008481526004602052604090206121c990846125a5565b509392505050565b6000806121de84846125ba565b905080156111fd5760008481526004602052604090206121c990846125f7565b60405163140e25ad60e31b81526001600160a01b037f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d169063a0712d689061224a908490600401612900565b6020604051808303816000875af1158015612269573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228d9190612e5d565b6122a95760405162ec6f7b60e31b815260040160405180910390fd5b610c576001600160a01b037f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d16838361181c565b6123126001600160a01b037f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d1683308461260c565b604051630852cd8d60e31b81526001600160a01b037f0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d16906342966c689061235e908490600401612900565b6020604051808303816000875af115801561237d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a19190612e5d565b610c5757604051631bc5aabf60e21b815260040160405180910390fd5b600065ffffffffffff8211156123ec576030826040516306dfcc6560e41b8152600401610d6f929190612e92565b5090565b60006123fa6114b3565b6001805465ffffffffffff8616600160a01b026001600160d01b03199091166001600160a01b03881617179055915061243c90508165ffffffffffff16151590565b15611874576040517f8886ebfc4259abdbc16601dd8fb5678e54878f47b3c34836cfc51154a960510990600090a1505050565b60008061247a611414565b90508065ffffffffffff168365ffffffffffff16116124a25761249d8382612ea0565b6111fd565b6111fd65ffffffffffff841662069780612634565b60008260000182815481106124ce576124ce612cda565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561253157602002820191906000526020600020905b81548152602001906001019080831161251d575b50505050509050919050565b60008261259b5760006125586002546001600160a01b031690565b6001600160a01b03161461257f57604051631fe1e13d60e11b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0384161790555b6111fd8383612644565b60006111fd836001600160a01b0384166126d6565b6000821580156125d757506002546001600160a01b038381169116145b156125ed57600280546001600160a01b03191690555b6111fd838361271d565b60006111fd836001600160a01b038416612788565b610cb584856001600160a01b03166323b872dd86868660405160240161184293929190612d1c565b60008282188284100282186111fd565b60006126508383611204565b6126ce576000838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556126863390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610b5b565b506000610b5b565b60008181526001830160205260408120546126ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b5b565b60006127298383611204565b156126ce576000838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610b5b565b600081815260018301602052604081205480156128715760006127ac600183612ec2565b85549091506000906127c090600190612ec2565b90508082146128255760008660000182815481106127e0576127e0612cda565b906000526020600020015490508087600001848154811061280357612803612cda565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061283657612836612ed5565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610b5b565b6000915050610b5b565b6001600160e01b031981165b8114610b7457600080fd5b8035610b5b8161287b565b6000602082840312156128b2576128b2600080fd5b60006128be8484612892565b949350505050565b8015155b82525050565b60208101610b5b82846128c6565b65ffffffffffff81166128ca565b60208101610b5b82846128de565b806128ca565b60208101610b5b82846128fa565b60006001600160a01b038216610b5b565b6128878161290e565b8035610b5b8161291f565b80612887565b8035610b5b81612933565b60008060006060848603121561295c5761295c600080fd5b60006129688686612928565b935050602061297986828701612928565b925050604061298a86828701612939565b9150509250925092565b6128ca8161290e565b60006129a98383612994565b505060200190565b60006129bb825190565b80845260209384019383018060005b838110156129ef5781516129de888261299d565b9750602083019250506001016129ca565b509495945050505050565b602080825281016111fd81846129b1565b60208101610b5b8284612994565b600060208284031215612a2e57612a2e600080fd5b60006128be8484612939565b600060208284031215612a4f57612a4f600080fd5b60006128be8484612928565b60008083601f840112612a7057612a70600080fd5b50813567ffffffffffffffff811115612a8b57612a8b600080fd5b602083019150836020820283011115612aa657612aa6600080fd5b9250929050565b60008060208385031215612ac357612ac3600080fd5b823567ffffffffffffffff811115612add57612add600080fd5b612ae985828601612a5b565b92509250509250929050565b60008060408385031215612b0b57612b0b600080fd5b6000612b178585612939565b9250506020612b2885828601612928565b9150509250929050565b60008060408385031215612b4857612b48600080fd5b6000612b548585612928565b9250506020612b2885828601612939565b65ffffffffffff8116612887565b8035610b5b81612b65565b600060208284031215612b9357612b93600080fd5b60006128be8484612b73565b60008060408385031215612bb557612bb5600080fd5b6000612b548585612939565b60408101612bcf82856128de565b6111fd60208301846128de565b60408101612bcf8285612994565b60008083601f840112612bff57612bff600080fd5b50813567ffffffffffffffff811115612c1a57612c1a600080fd5b602083019150836001820283011115612aa657612aa6600080fd5b60008060208385031215612c4b57612c4b600080fd5b823567ffffffffffffffff811115612c6557612c65600080fd5b612ae985828601612bea565b60005b83811015612c8c578181015183820152602001612c74565b50506000910152565b6000612c9f825190565b808452602084019350612cb6818560208601612c71565b601f19601f8201165b9093019392505050565b602080825281016111fd8184612c95565b634e487b7160e01b600052603260045260246000fd5b8051610b5b81612933565b600060208284031215612d1057612d10600080fd5b60006128be8484612cf0565b60608101612d2a8286612994565b612d376020830185612994565b6128be60408301846128fa565b82818337506000910152565b6000612d5d838584612d44565b50500190565b60006128be828486612d50565b8183526000602084019350612d86838584612d44565b601f19601f840116612cbf565b60408082528101612da5818587612d70565b90508181036020830152612db98184612c95565b95945050505050565b60408101612dd08285612994565b6111fd60208301846128fa565b60808101612deb8287612994565b612df860208301866128fa565b612e056040830185612994565b612db960608301846128c6565b634e487b7160e01b600052601160045260246000fd5b65ffffffffffff918216919081169082820190811115610b5b57610b5b612e12565b801515612887565b8051610b5b81612e4a565b600060208284031215612e7257612e72600080fd5b60006128be8484612e52565b600060ff8216610b5b565b6128ca81612e7e565b60408101612dd08285612e89565b65ffffffffffff918216919081169082820390811115610b5b57610b5b612e12565b81810381811115610b5b57610b5b612e12565b634e487b7160e01b600052603160045260246000fdfe92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d363ac950b4e2512fad4244af0109db80898a61d13325e9e992206b6f9cf76056ff93e02eaefb22229c9fa4ecb927d4a3b0bd2d30b1af650a970c5a95ba1f96906ea0acf805600123ef007091da3b3ffb39474074c656c127aa68cb0ffec232a8ff8a2646970667358221220929d0312c448f30f4fb2d68ee6e1f896317de33d0f1d0cf80e25253d6a2fe38f64736f6c63430008180033","optimization_enabled":false,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"paris","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":true,"cse":true,"deduplicate":true,"inliner":true,"jumpdestRemover":true,"orderLiterals":true,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false},"runs":200},"remappings":[]},"optimization_runs":null,"sourcify_repo_url":"https://repo.sourcify.dev/contracts/full_match/1/0xEE9B1A09AEDAceD9dCDA74964EA447feb93861C2/","decoded_constructor_args":[["0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d",{"internalType":"address","name":"token","type":"address"}],["259200",{"internalType":"uint48","name":"initialDelay","type":"uint48"}],["0x0D190B74308669E8f4fE7DBCe3466169B285289d",{"internalType":"address","name":"initialDefaultAdmin","type":"address"}]],"compiler_version":"0.8.24+commit.e11b9ed9","is_verified_via_verifier_alliance":false,"verified_at":"2025-05-22T04:12:20.708525Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60a06040523480156200001157600080fd5b506040516200337c3803806200337c8339810160408190526200003491620002e4565b81816001600160a01b0381166200006c576000604051636116401160e11b81526004016200006391906200034d565b60405180910390fd5b600180546001600160d01b0316600160d01b65ffffffffffff85160217905562000098600082620000d7565b5050506001600160a01b038316620000c3576040516342bcdf7f60e11b815260040160405180910390fd5b50506001600160a01b03166080526200035d565b600080620000e6848462000114565b905080156200010b57600084815260046020526040902062000109908462000181565b505b90505b92915050565b60008262000175576000620001316002546001600160a01b031690565b6001600160a01b0316146200015957604051631fe1e13d60e11b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0384161790555b6200010b838362000198565b60006200010b836001600160a01b03841662000246565b6000828152602081815260408083206001600160a01b038516845290915281205460ff166200023d576000838152602081815260408083206001600160a01b03861684529091529020805460ff19166001179055620001f43390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45060016200010e565b5060006200010e565b60008181526001830160205260408120546200023d575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200010e565b60006001600160a01b0382166200010e565b620002ac816200028f565b8114620002b857600080fd5b50565b80516200010e81620002a1565b65ffffffffffff8116620002ac565b80516200010e81620002c8565b600080600060608486031215620002fe57620002fe600080fd5b60006200030c8686620002bb565b93505060206200031f86828701620002d7565b92505060406200033286828701620002bb565b9150509250925092565b62000347816200028f565b82525050565b602081016200010e82846200033c565b608051612fa1620003db600039600081816104c701528181610dc301528181610f6601528181611044015281816110e6015281816113450152818161163f015281816116f2015281816118900152818161194701528181611dbb01528181612215015281816122b6015281816122ea01526123290152612fa16000f3fe6080604052600436106103a25760003560e01c80638456cb59116101e7578063ca15c8731161010d578063d5c85140116100a0578063e78a14f51161006f578063e78a14f514610aad578063f2fde38b14610ac2578063fb1bb9de14610ae2578063fcedb9e514610b1657600080fd5b8063d5c8514014610a31578063d602b9fd14610a46578063e0c0906f14610a5b578063e63ab1e914610a7957600080fd5b8063cf880f4c116100dc578063cf880f4c1461099d578063d22224a9146109bd578063d5391393146109dd578063d547741f14610a1157600080fd5b8063ca15c87314610930578063cc8463c814610950578063cefc142914610965578063cf6eefb71461097a57600080fd5b80639ddc3f5c11610185578063a3246ad311610154578063a3246ad3146108c6578063a6cc8d40146108e6578063c35f7c62146108fb578063c721e8c01461091057600080fd5b80639ddc3f5c14610859578063a0712d681461086e578063a1eda53c1461088e578063a217fddf146108b157600080fd5b80638d1fdf2f116101c15780638d1fdf2f146107e45780638da5cb5b146108045780639010d07c1461081957806391d148541461083957600080fd5b80638456cb591461079c57806384ef8ffc146107b157806386fe8b43146107cf57600080fd5b806331993a1c116102cc57806360ea92081161026a57806379ba50971161023957806379ba50971461073d57806379cc6790146107525780638118efda1461077257806382b2e2571461078757600080fd5b806360ea9208146106c8578063634e93da146106e8578063649a5ec7146107085780636b32810b1461072857600080fd5b80633f4ba83a116102a65780633f4ba83a1461065357806340c10f191461066857806342966c681461068857806345c8b1a6146106a857600080fd5b806331993a1c146105fc57806331ae450b1461061e57806336568abe1461063357600080fd5b806321df0da7116103445780632c92ba9c116103135780632c92ba9c1461057a5780632dbc9db91461059a5780632f2ff15d146105ba578063312963e5146105da57600080fd5b806321df0da7146104b8578063248a9ca3146104f4578063248e6c0814610524578063282c51f31461054657600080fd5b806306a85f0f1161038057806306a85f0f1461043d5780630aa6220b1461045f5780631171bda9146104765780631e42b8b11461049657600080fd5b806301ffc9a7146103a7578063022d63fb146103dd5780630568b3da146103fc575b600080fd5b3480156103b357600080fd5b506103c76103c236600461289d565b610b36565b6040516103d491906128d0565b60405180910390f35b3480156103e957600080fd5b50620697805b6040516103d491906128ec565b34801561040857600080fd5b506104307fb9f997e9b8b4ceb22077d832bcbf6f751de391a9ad51c4c81e58db4b9214f8e381565b6040516103d49190612900565b34801561044957600080fd5b50610430600080516020612eec83398151915281565b34801561046b57600080fd5b50610474610b61565b005b34801561048257600080fd5b50610474610491366004612944565b610b77565b3480156104a257600080fd5b506104ab610c25565b6040516103d491906129fa565b3480156104c457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516103d49190612a0b565b34801561050057600080fd5b5061043061050f366004612a19565b60009081526020819052604090206001015490565b34801561053057600080fd5b50610430600080516020612f2c83398151915281565b34801561055257600080fd5b506104307f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b34801561058657600080fd5b50610474610595366004612a3a565b610c43565b3480156105a657600080fd5b506104746105b5366004612aad565b610c5b565b3480156105c657600080fd5b506104746105d5366004612af5565b610cbb565b3480156105e657600080fd5b50610430600080516020612f0c83398151915281565b34801561060857600080fd5b50610430600080516020612f4c83398151915281565b34801561062a57600080fd5b506104ab610ce3565b34801561063f57600080fd5b5061047461064e366004612af5565b610cef565b34801561065f57600080fd5b50610474610d97565b34801561067457600080fd5b506103c7610683366004612b32565b610e62565b34801561069457600080fd5b506103c76106a3366004612a19565b610e77565b3480156106b457600080fd5b506104746106c3366004612a3a565b610e8b565b3480156106d457600080fd5b506104746106e3366004612aad565b610eac565b3480156106f457600080fd5b50610474610703366004612a3a565b610f06565b34801561071457600080fd5b50610474610723366004612b7e565b610f1a565b34801561073457600080fd5b506104ab610f2e565b34801561074957600080fd5b50610474610f59565b34801561075e57600080fd5b506103c761076d366004612b32565b611005565b34801561077e57600080fd5b506104ab611011565b34801561079357600080fd5b5061043061102a565b3480156107a857600080fd5b506104746110ba565b3480156107bd57600080fd5b506002546001600160a01b03166104e7565b3480156107db57600080fd5b506104ab611185565b3480156107f057600080fd5b506104746107ff366004612a3a565b6111b0565b34801561081057600080fd5b506104e76111d1565b34801561082557600080fd5b506104e7610834366004612b9f565b6111e5565b34801561084557600080fd5b506103c7610854366004612af5565b611204565b34801561086557600080fd5b506104ab61122d565b34801561087a57600080fd5b506103c7610889366004612a19565b611258565b34801561089a57600080fd5b506108a3611264565b6040516103d4929190612bc1565b3480156108bd57600080fd5b50610430600081565b3480156108d257600080fd5b506104ab6108e1366004612a19565b6112b8565b3480156108f257600080fd5b506104ab6112d2565b34801561090757600080fd5b506104ab6112fd565b34801561091c57600080fd5b5061047461092b366004612944565b611316565b34801561093c57600080fd5b5061043061094b366004612a19565b6113fd565b34801561095c57600080fd5b506103ef611414565b34801561097157600080fd5b50610474611473565b34801561098657600080fd5b5061098f6114b3565b6040516103d4929190612bdc565b3480156109a957600080fd5b506104746109b8366004612a3a565b6114d4565b3480156109c957600080fd5b506104746109d8366004612aad565b611551565b3480156109e957600080fd5b506104307f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b348015610a1d57600080fd5b50610474610a2c366004612af5565b61159e565b348015610a3d57600080fd5b506104ab6115c6565b348015610a5257600080fd5b506104746115f1565b348015610a6757600080fd5b506003546001600160a01b03166104e7565b348015610a8557600080fd5b506104307f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b348015610ab957600080fd5b506104ab611604565b348015610ace57600080fd5b50610474610add366004612a3a565b61161d565b348015610aee57600080fd5b506104307f427da25fe773164f88948d3e215c94b6554e2ed5e5f203a821c9f2f6131cf75a81565b610b29610b24366004612c35565b6116e0565b6040516103d49190612cc9565b60006001600160e01b03198216635a05180f60e01b1480610b5b5750610b5b826117e0565b92915050565b6000610b6c81611805565b610b7461180f565b50565b600080516020612f4c833981519152610b8f81611805565b6001600160a01b038316610bb6576040516342bcdf7f60e11b815260040160405180910390fd5b610bca6001600160a01b038516848461181c565b826001600160a01b0316846001600160a01b0316336001600160a01b03167fa2231b10d9b4e4166c8a827c99f97691b05aa88fb04e009a4e499005b5c50fcc85604051610c179190612900565b60405180910390a450505050565b6060610c3e600080516020612f4c8339815191526112b8565b905090565b6000610c4e81611805565b610c5782611879565b5050565b600080516020612f2c833981519152610c7381611805565b60005b82811015610cb557610cad848483818110610c9357610c93612cda565b9050602002016020810190610ca89190612a3a565b611930565b600101610c76565b50505050565b81610cd957604051631fe1e13d60e11b815260040160405180910390fd5b610c5782826119e7565b6060610c3e60006112b8565b81158015610d0a57506002546001600160a01b038281169116145b15610d8d57600080610d1a6114b3565b90925090506001600160a01b038216151580610d3c575065ffffffffffff8116155b80610d4f57504265ffffffffffff821610155b15610d7857806040516319ca5ebb60e01b8152600401610d6f91906128ec565b60405180910390fd5b50506001805465ffffffffffff60a01b191690555b610c578282611a0c565b7f427da25fe773164f88948d3e215c94b6554e2ed5e5f203a821c9f2f6131cf75a610dc181611805565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e1c57600080fd5b505af1158015610e30573d6000803e3d6000fd5b50506040513392507f5b65b0c1363b3003db9bcc5e1fd8805a6d6bf5bf6dc9d3431ee4494cd7d117669150600090a250565b6000610e6e8383611a3f565b50600192915050565b6000610e833383611bff565b506001919050565b600080516020612f2c833981519152610ea381611805565b610c5782611930565b600080516020612eec833981519152610ec481611805565b60005b82811015610cb557610efe848483818110610ee457610ee4612cda565b9050602002016020810190610ef99190612a3a565b611da4565b600101610ec7565b6000610f1181611805565b610c5782611e5b565b6000610f2581611805565b610c5782611ec9565b6060610c3e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66112b8565b6000610f6481611805565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166379ba50976040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610fbf57600080fd5b505af1158015610fd3573d6000803e3d6000fd5b50506040513392507fb27970c1714b28277b78cc17ac2fe9556e7f048cd48358cffe3dc7d547608fdc9150600090a250565b6000610e6e8383611bff565b6060610c3e600080516020612eec8339815191526112b8565b6040516370a0823160e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190611079903090600401612a0b565b602060405180830381865afa158015611096573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3e9190612cfb565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6110e481611805565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561113f57600080fd5b505af1158015611153573d6000803e3d6000fd5b50506040513392507f81990fd9a5c552b8e3677917d8a03c07678f0d2cb68f88b634aca2022e9bd19f9150600090a250565b6060610c3e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486112b8565b600080516020612eec8339815191526111c881611805565b610c5782611da4565b6000610c3e6002546001600160a01b031690565b60008281526004602052604081206111fd9083611f30565b9392505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6060610c3e7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6112b8565b6000610e833383611a3f565b600254600090600160d01b900465ffffffffffff16801515801561129057504265ffffffffffff821610155b61129c576000806112b0565b600254600160a01b900465ffffffffffff16815b915091509091565b6000818152600460205260409020606090610b5b90611f3c565b6060610c3e7f427da25fe773164f88948d3e215c94b6554e2ed5e5f203a821c9f2f6131cf75a6112b8565b6060610c3e600080516020612f0c8339815191526112b8565b600080516020612f4c83398151915261132e81611805565b604051631171bda960e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631171bda99061137e90879087908790600401612d1c565b600060405180830381600087803b15801561139857600080fd5b505af11580156113ac573d6000803e3d6000fd5b50505050826001600160a01b0316846001600160a01b0316336001600160a01b03167f42f446384ff78c62bf2caa065e680c6010e2f54857d15bee828d6c7d5735389385604051610c179190612900565b6000818152600460205260408120610b5b90611f49565b600254600090600160d01b900465ffffffffffff16801515801561143f57504265ffffffffffff8216105b61145a57600154600160d01b900465ffffffffffff1661146d565b600254600160a01b900465ffffffffffff165b91505090565b600061147d6114b3565b509050336001600160a01b038216146114ab5733604051636116401160e11b8152600401610d6f9190612a0b565b610b74611f53565b6001546001600160a01b03811691600160a01b90910465ffffffffffff1690565b7fb9f997e9b8b4ceb22077d832bcbf6f751de391a9ad51c4c81e58db4b9214f8e36114fe81611805565b600380546001600160a01b038481166001600160a01b0319831681179093556040519116919082907f35631e65f3bb46b57c2cfadf0d2ca3f08e6cbab52c2ff987b5328c9b37d45ea390600090a3505050565b600061155c81611805565b60005b82811015610cb55761159684848381811061157c5761157c612cda565b90506020020160208101906115919190612a3a565b611879565b60010161155f565b816115bc57604051631fe1e13d60e11b815260040160405180910390fd5b610c578282611fe4565b6060610c3e7fb9f997e9b8b4ceb22077d832bcbf6f751de391a9ad51c4c81e58db4b9214f8e36112b8565b60006115fc81611805565b610b74612009565b6060610c3e600080516020612f2c8339815191526112b8565b600061162881611805565b60405163f2fde38b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f2fde38b90611674908590600401612a0b565b600060405180830381600087803b15801561168e57600080fd5b505af11580156116a2573d6000803e3d6000fd5b50506040516001600160a01b03851692503391507f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b606060006116ed81611805565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031634878760405161172b929190612d63565b60006040518083038185875af1925050503d8060008114611768576040519150601f19603f3d011682016040523d82523d6000602084013e61176d565b606091505b509150915081611792578060405163a5fa8d2b60e01b8152600401610d6f9190612cc9565b336001600160a01b03167f3f341ef37380014c90cd66348f1e20455df1b642e6a3445f39dd66f88110cc658787846040516117cf93929190612d93565b60405180910390a295945050505050565b60006001600160e01b031982166318a4c3c360e11b1480610b5b5750610b5b82612014565b610b748133612049565b61181a600080612074565b565b61187483846001600160a01b031663a9059cbb8585604051602401611842929190612dc2565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050612134565b505050565b604051637672989960e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ece53132906118c5908490600401612a0b565b600060405180830381600087803b1580156118df57600080fd5b505af11580156118f3573d6000803e3d6000fd5b50506040516001600160a01b03841692503391507f8e535556a0a95ee3befe296cf986f7bf7d88881991e46f517c4b477c0ea6938590600090a350565b6040516322e458d360e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906345c8b1a69061197c908490600401612a0b565b600060405180830381600087803b15801561199657600080fd5b505af11580156119aa573d6000803e3d6000fd5b50506040516001600160a01b03841692503391507fe19c610e04dba2019efcfb0f9455fad3af646853bb02abad2a452db1fd47c32790600090a350565b600082815260208190526040902060010154611a0281611805565b610cb5838361219c565b6001600160a01b0381163314611a355760405163334bd91960e11b815260040160405180910390fd5b61187482826121d1565b6000611a59600080516020612f0c83398151915233611204565b905080158015611a905750611a8e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633611204565b155b15611aae576040516363e660e560e11b815260040160405180910390fd5b306001600160a01b03841603611ad757604051634e46966960e11b815260040160405180910390fd5b6003546001600160a01b03168015611b4e57604051637d1aee2360e11b81526001600160a01b0382169063fa35dc4690611b1b908790879033908890600401612ddd565b600060405180830381600087803b158015611b3557600080fd5b505af1158015611b49573d6000803e3d6000fd5b505050505b611b5884846121fe565b8115611bae57836001600160a01b0316336001600160a01b03167fc3b8ae385c02b938fbbbd694d1da0761f755ee2c942f26bbfc6723c986d31b9b85604051611ba19190612900565b60405180910390a3610cb5565b836001600160a01b0316336001600160a01b03167fc8a07fbf83d1ff93486eea14a0676adef77c8c95fa79c85cd7bba0d10204102f85604051611bf19190612900565b60405180910390a350505050565b6000611c19600080516020612f0c83398151915233611204565b905080158015611c505750611c4e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84833611204565b155b15611c6e576040516306e5da9160e11b815260040160405180910390fd5b306001600160a01b03841603611c975760405163104ca12160e11b815260040160405180910390fd5b6003546001600160a01b03168015611d0e57604051633a60702360e01b81526001600160a01b03821690633a60702390611cdb908790879033908890600401612ddd565b600060405180830381600087803b158015611cf557600080fd5b505af1158015611d09573d6000803e3d6000fd5b505050505b611d1884846122dd565b8115611d6157836001600160a01b0316336001600160a01b03167fabf8a0bc0c6341b64dfa026a551cda9d3beb0e0525758303026bacbc11ad1d8c85604051611ba19190612900565b836001600160a01b0316336001600160a01b03167f76bf0a63dad9216ecf94a5b1fdefa2c44ed7c809fe0028c4c2ce064b151c903f85604051611bf19190612900565b604051638d1fdf2f60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690638d1fdf2f90611df0908490600401612a0b565b600060405180830381600087803b158015611e0a57600080fd5b505af1158015611e1e573d6000803e3d6000fd5b50506040516001600160a01b03841692503391507f2a3de20682fb291f444b5c1469d7e0950c558ce3dadf97163687873e29bcf4ae90600090a350565b6000611e65611414565b611e6e426123be565b611e789190612e28565b9050611e8482826123f0565b816001600160a01b03167f3377dc44241e779dd06afab5b788a35ca5f3b778836e2990bdb26a2a4b2e5ed682604051611ebd91906128ec565b60405180910390a25050565b6000611ed48261246f565b611edd426123be565b611ee79190612e28565b9050611ef38282612074565b7ff1038c18cf84a56e432fdbfaf746924b7ea511dfe03a6506a0ceba4888788d9b8282604051611f24929190612bc1565b60405180910390a15050565b60006111fd83836124b7565b606060006111fd836124e1565b6000610b5b825490565b600080611f5e6114b3565b91509150611f738165ffffffffffff16151590565b1580611f8757504265ffffffffffff821610155b15611fa757806040516319ca5ebb60e01b8152600401610d6f91906128ec565b611fc36000611fbe6002546001600160a01b031690565b6121d1565b50611fcf60008361219c565b5050600180546001600160d01b031916905550565b600082815260208190526040902060010154611fff81611805565b610cb583836121d1565b61181a6000806123f0565b60006001600160e01b03198216637965db0b60e01b1480610b5b57506301ffc9a760e01b6001600160e01b0319831614610b5b565b6120538282611204565b610c5757808260405163e2517d3f60e01b8152600401610d6f929190612dc2565b600254600160d01b900465ffffffffffff1680156120f7574265ffffffffffff821610156120cd57600254600180546001600160d01b0316600160a01b90920465ffffffffffff16600160d01b029190911790556120f7565b6040517f2b1fa2edafe6f7b9e97c1a9e0c3660e645beb2dcaa2d45bdbf9beaf5472e1ec590600090a15b50600280546001600160a01b0316600160a01b65ffffffffffff948516026001600160d01b031617600160d01b9290931691909102919091179055565b600080602060008451602086016000885af180612157576040513d6000823e3d81fd5b50506000513d9150811561216f57806001141561217c565b6001600160a01b0384163b155b15610cb55783604051635274afe760e01b8152600401610d6f9190612a0b565b6000806121a9848461253d565b905080156111fd5760008481526004602052604090206121c990846125a5565b509392505050565b6000806121de84846125ba565b905080156111fd5760008481526004602052604090206121c990846125f7565b60405163140e25ad60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a0712d689061224a908490600401612900565b6020604051808303816000875af1158015612269573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228d9190612e5d565b6122a95760405162ec6f7b60e31b815260040160405180910390fd5b610c576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016838361181c565b6123126001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001683308461260c565b604051630852cd8d60e31b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342966c689061235e908490600401612900565b6020604051808303816000875af115801561237d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a19190612e5d565b610c5757604051631bc5aabf60e21b815260040160405180910390fd5b600065ffffffffffff8211156123ec576030826040516306dfcc6560e41b8152600401610d6f929190612e92565b5090565b60006123fa6114b3565b6001805465ffffffffffff8616600160a01b026001600160d01b03199091166001600160a01b03881617179055915061243c90508165ffffffffffff16151590565b15611874576040517f8886ebfc4259abdbc16601dd8fb5678e54878f47b3c34836cfc51154a960510990600090a1505050565b60008061247a611414565b90508065ffffffffffff168365ffffffffffff16116124a25761249d8382612ea0565b6111fd565b6111fd65ffffffffffff841662069780612634565b60008260000182815481106124ce576124ce612cda565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561253157602002820191906000526020600020905b81548152602001906001019080831161251d575b50505050509050919050565b60008261259b5760006125586002546001600160a01b031690565b6001600160a01b03161461257f57604051631fe1e13d60e11b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0384161790555b6111fd8383612644565b60006111fd836001600160a01b0384166126d6565b6000821580156125d757506002546001600160a01b038381169116145b156125ed57600280546001600160a01b03191690555b6111fd838361271d565b60006111fd836001600160a01b038416612788565b610cb584856001600160a01b03166323b872dd86868660405160240161184293929190612d1c565b60008282188284100282186111fd565b60006126508383611204565b6126ce576000838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556126863390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610b5b565b506000610b5b565b60008181526001830160205260408120546126ce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b5b565b60006127298383611204565b156126ce576000838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610b5b565b600081815260018301602052604081205480156128715760006127ac600183612ec2565b85549091506000906127c090600190612ec2565b90508082146128255760008660000182815481106127e0576127e0612cda565b906000526020600020015490508087600001848154811061280357612803612cda565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061283657612836612ed5565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610b5b565b6000915050610b5b565b6001600160e01b031981165b8114610b7457600080fd5b8035610b5b8161287b565b6000602082840312156128b2576128b2600080fd5b60006128be8484612892565b949350505050565b8015155b82525050565b60208101610b5b82846128c6565b65ffffffffffff81166128ca565b60208101610b5b82846128de565b806128ca565b60208101610b5b82846128fa565b60006001600160a01b038216610b5b565b6128878161290e565b8035610b5b8161291f565b80612887565b8035610b5b81612933565b60008060006060848603121561295c5761295c600080fd5b60006129688686612928565b935050602061297986828701612928565b925050604061298a86828701612939565b9150509250925092565b6128ca8161290e565b60006129a98383612994565b505060200190565b60006129bb825190565b80845260209384019383018060005b838110156129ef5781516129de888261299d565b9750602083019250506001016129ca565b509495945050505050565b602080825281016111fd81846129b1565b60208101610b5b8284612994565b600060208284031215612a2e57612a2e600080fd5b60006128be8484612939565b600060208284031215612a4f57612a4f600080fd5b60006128be8484612928565b60008083601f840112612a7057612a70600080fd5b50813567ffffffffffffffff811115612a8b57612a8b600080fd5b602083019150836020820283011115612aa657612aa6600080fd5b9250929050565b60008060208385031215612ac357612ac3600080fd5b823567ffffffffffffffff811115612add57612add600080fd5b612ae985828601612a5b565b92509250509250929050565b60008060408385031215612b0b57612b0b600080fd5b6000612b178585612939565b9250506020612b2885828601612928565b9150509250929050565b60008060408385031215612b4857612b48600080fd5b6000612b548585612928565b9250506020612b2885828601612939565b65ffffffffffff8116612887565b8035610b5b81612b65565b600060208284031215612b9357612b93600080fd5b60006128be8484612b73565b60008060408385031215612bb557612bb5600080fd5b6000612b548585612939565b60408101612bcf82856128de565b6111fd60208301846128de565b60408101612bcf8285612994565b60008083601f840112612bff57612bff600080fd5b50813567ffffffffffffffff811115612c1a57612c1a600080fd5b602083019150836001820283011115612aa657612aa6600080fd5b60008060208385031215612c4b57612c4b600080fd5b823567ffffffffffffffff811115612c6557612c65600080fd5b612ae985828601612bea565b60005b83811015612c8c578181015183820152602001612c74565b50506000910152565b6000612c9f825190565b808452602084019350612cb6818560208601612c71565b601f19601f8201165b9093019392505050565b602080825281016111fd8184612c95565b634e487b7160e01b600052603260045260246000fd5b8051610b5b81612933565b600060208284031215612d1057612d10600080fd5b60006128be8484612cf0565b60608101612d2a8286612994565b612d376020830185612994565b6128be60408301846128fa565b82818337506000910152565b6000612d5d838584612d44565b50500190565b60006128be828486612d50565b8183526000602084019350612d86838584612d44565b601f19601f840116612cbf565b60408082528101612da5818587612d70565b90508181036020830152612db98184612c95565b95945050505050565b60408101612dd08285612994565b6111fd60208301846128fa565b60808101612deb8287612994565b612df860208301866128fa565b612e056040830185612994565b612db960608301846128c6565b634e487b7160e01b600052601160045260246000fd5b65ffffffffffff918216919081169082820190811115610b5b57610b5b612e12565b801515612887565b8051610b5b81612e4a565b600060208284031215612e7257612e72600080fd5b60006128be8484612e52565b600060ff8216610b5b565b6128ca81612e7e565b60408101612dd08285612e89565b65ffffffffffff918216919081169082820390811115610b5b57610b5b612e12565b81810381811115610b5b57610b5b612e12565b634e487b7160e01b600052603160045260246000fdfe92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d363ac950b4e2512fad4244af0109db80898a61d13325e9e992206b6f9cf76056ff93e02eaefb22229c9fa4ecb927d4a3b0bd2d30b1af650a970c5a95ba1f96906ea0acf805600123ef007091da3b3ffb39474074c656c127aa68cb0ffec232a8ff8a2646970667358221220929d0312c448f30f4fb2d68ee6e1f896317de33d0f1d0cf80e25253d6a2fe38f64736f6c634300081800330000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d000000000000000000000000000000000000000000000000000000000003f4800000000000000000000000000d190b74308669e8f4fe7dbce3466169b285289d","name":"TokenGovernor","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"paris","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":true,"additional_sources":[{"file_path":"@openzeppelin/contracts/access/AccessControl.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"./IAccessControl.sol\";\nimport {Context} from \"../utils/Context.sol\";\nimport {ERC165} from \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n    struct RoleData {\n        mapping(address account => bool) hasRole;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 role => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with an {AccessControlUnauthorizedAccount} error including the required role.\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n        return _roles[role].hasRole[account];\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n     * is missing `role`.\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert AccessControlUnauthorizedAccount(account, role);\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n        if (callerConfirmation != _msgSender()) {\n            revert AccessControlBadConfirmation();\n        }\n\n        _revokeRole(role, callerConfirmation);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n        if (!hasRole(role, account)) {\n            _roles[role].hasRole[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n        if (hasRole(role, account)) {\n            _roles[role].hasRole[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/access/IAccessControl.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/IAccessControl.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev External interface of AccessControl declared to support ERC-165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev The `account` is missing a role.\n     */\n    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n    /**\n     * @dev The caller of a function is not the expected one.\n     *\n     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n     */\n    error AccessControlBadConfirmation();\n\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).\n     * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) external;\n}\n"},{"file_path":"@openzeppelin/contracts/access/extensions/AccessControlDefaultAdminRules.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/AccessControlDefaultAdminRules.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControlDefaultAdminRules} from \"./IAccessControlDefaultAdminRules.sol\";\nimport {AccessControl, IAccessControl} from \"../AccessControl.sol\";\nimport {SafeCast} from \"../../utils/math/SafeCast.sol\";\nimport {Math} from \"../../utils/math/Math.sol\";\nimport {IERC5313} from \"../../interfaces/IERC5313.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows specifying special rules to manage\n * the `DEFAULT_ADMIN_ROLE` holder, which is a sensitive role with special permissions\n * over other roles that may potentially have privileged rights in the system.\n *\n * If a specific role doesn't have an admin role assigned, the holder of the\n * `DEFAULT_ADMIN_ROLE` will have the ability to grant it and revoke it.\n *\n * This contract implements the following risk mitigations on top of {AccessControl}:\n *\n * * Only one account holds the `DEFAULT_ADMIN_ROLE` since deployment until it's potentially renounced.\n * * Enforces a 2-step process to transfer the `DEFAULT_ADMIN_ROLE` to another account.\n * * Enforces a configurable delay between the two steps, with the ability to cancel before the transfer is accepted.\n * * The delay can be changed by scheduling, see {changeDefaultAdminDelay}.\n * * It is not possible to use another role to manage the `DEFAULT_ADMIN_ROLE`.\n *\n * Example usage:\n *\n * ```solidity\n * contract MyToken is AccessControlDefaultAdminRules {\n *   constructor() AccessControlDefaultAdminRules(\n *     3 days,\n *     msg.sender // Explicit initial `DEFAULT_ADMIN_ROLE` holder\n *    ) {}\n * }\n * ```\n */\nabstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRules, IERC5313, AccessControl {\n    // pending admin pair read/written together frequently\n    address private _pendingDefaultAdmin;\n    uint48 private _pendingDefaultAdminSchedule; // 0 == unset\n\n    uint48 private _currentDelay;\n    address private _currentDefaultAdmin;\n\n    // pending delay pair read/written together frequently\n    uint48 private _pendingDelay;\n    uint48 private _pendingDelaySchedule; // 0 == unset\n\n    /**\n     * @dev Sets the initial values for {defaultAdminDelay} and {defaultAdmin} address.\n     */\n    constructor(uint48 initialDelay, address initialDefaultAdmin) {\n        if (initialDefaultAdmin == address(0)) {\n            revert AccessControlInvalidDefaultAdmin(address(0));\n        }\n        _currentDelay = initialDelay;\n        _grantRole(DEFAULT_ADMIN_ROLE, initialDefaultAdmin);\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControlDefaultAdminRules).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC5313-owner}.\n     */\n    function owner() public view virtual returns (address) {\n        return defaultAdmin();\n    }\n\n    ///\n    /// Override AccessControl role management\n    ///\n\n    /**\n     * @dev See {AccessControl-grantRole}. Reverts for `DEFAULT_ADMIN_ROLE`.\n     */\n    function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\n        if (role == DEFAULT_ADMIN_ROLE) {\n            revert AccessControlEnforcedDefaultAdminRules();\n        }\n        super.grantRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-revokeRole}. Reverts for `DEFAULT_ADMIN_ROLE`.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\n        if (role == DEFAULT_ADMIN_ROLE) {\n            revert AccessControlEnforcedDefaultAdminRules();\n        }\n        super.revokeRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-renounceRole}.\n     *\n     * For the `DEFAULT_ADMIN_ROLE`, it only allows renouncing in two steps by first calling\n     * {beginDefaultAdminTransfer} to the `address(0)`, so it's required that the {pendingDefaultAdmin} schedule\n     * has also passed when calling this function.\n     *\n     * After its execution, it will not be possible to call `onlyRole(DEFAULT_ADMIN_ROLE)` functions.\n     *\n     * NOTE: Renouncing `DEFAULT_ADMIN_ROLE` will leave the contract without a {defaultAdmin},\n     * thereby disabling any functionality that is only available for it, and the possibility of reassigning a\n     * non-administrated role.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\n        if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {\n            (address newDefaultAdmin, uint48 schedule) = pendingDefaultAdmin();\n            if (newDefaultAdmin != address(0) || !_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) {\n                revert AccessControlEnforcedDefaultAdminDelay(schedule);\n            }\n            delete _pendingDefaultAdminSchedule;\n        }\n        super.renounceRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-_grantRole}.\n     *\n     * For `DEFAULT_ADMIN_ROLE`, it only allows granting if there isn't already a {defaultAdmin} or if the\n     * role has been previously renounced.\n     *\n     * NOTE: Exposing this function through another mechanism may make the `DEFAULT_ADMIN_ROLE`\n     * assignable again. Make sure to guarantee this is the expected behavior in your implementation.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {\n        if (role == DEFAULT_ADMIN_ROLE) {\n            if (defaultAdmin() != address(0)) {\n                revert AccessControlEnforcedDefaultAdminRules();\n            }\n            _currentDefaultAdmin = account;\n        }\n        return super._grantRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-_revokeRole}.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {\n        if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {\n            delete _currentDefaultAdmin;\n        }\n        return super._revokeRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-_setRoleAdmin}. Reverts for `DEFAULT_ADMIN_ROLE`.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual override {\n        if (role == DEFAULT_ADMIN_ROLE) {\n            revert AccessControlEnforcedDefaultAdminRules();\n        }\n        super._setRoleAdmin(role, adminRole);\n    }\n\n    ///\n    /// AccessControlDefaultAdminRules accessors\n    ///\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function defaultAdmin() public view virtual returns (address) {\n        return _currentDefaultAdmin;\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function pendingDefaultAdmin() public view virtual returns (address newAdmin, uint48 schedule) {\n        return (_pendingDefaultAdmin, _pendingDefaultAdminSchedule);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function defaultAdminDelay() public view virtual returns (uint48) {\n        uint48 schedule = _pendingDelaySchedule;\n        return (_isScheduleSet(schedule) && _hasSchedulePassed(schedule)) ? _pendingDelay : _currentDelay;\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function pendingDefaultAdminDelay() public view virtual returns (uint48 newDelay, uint48 schedule) {\n        schedule = _pendingDelaySchedule;\n        return (_isScheduleSet(schedule) && !_hasSchedulePassed(schedule)) ? (_pendingDelay, schedule) : (0, 0);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function defaultAdminDelayIncreaseWait() public view virtual returns (uint48) {\n        return 5 days;\n    }\n\n    ///\n    /// AccessControlDefaultAdminRules public and internal setters for defaultAdmin/pendingDefaultAdmin\n    ///\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function beginDefaultAdminTransfer(address newAdmin) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _beginDefaultAdminTransfer(newAdmin);\n    }\n\n    /**\n     * @dev See {beginDefaultAdminTransfer}.\n     *\n     * Internal function without access restriction.\n     */\n    function _beginDefaultAdminTransfer(address newAdmin) internal virtual {\n        uint48 newSchedule = SafeCast.toUint48(block.timestamp) + defaultAdminDelay();\n        _setPendingDefaultAdmin(newAdmin, newSchedule);\n        emit DefaultAdminTransferScheduled(newAdmin, newSchedule);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function cancelDefaultAdminTransfer() public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _cancelDefaultAdminTransfer();\n    }\n\n    /**\n     * @dev See {cancelDefaultAdminTransfer}.\n     *\n     * Internal function without access restriction.\n     */\n    function _cancelDefaultAdminTransfer() internal virtual {\n        _setPendingDefaultAdmin(address(0), 0);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function acceptDefaultAdminTransfer() public virtual {\n        (address newDefaultAdmin, ) = pendingDefaultAdmin();\n        if (_msgSender() != newDefaultAdmin) {\n            // Enforce newDefaultAdmin explicit acceptance.\n            revert AccessControlInvalidDefaultAdmin(_msgSender());\n        }\n        _acceptDefaultAdminTransfer();\n    }\n\n    /**\n     * @dev See {acceptDefaultAdminTransfer}.\n     *\n     * Internal function without access restriction.\n     */\n    function _acceptDefaultAdminTransfer() internal virtual {\n        (address newAdmin, uint48 schedule) = pendingDefaultAdmin();\n        if (!_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) {\n            revert AccessControlEnforcedDefaultAdminDelay(schedule);\n        }\n        _revokeRole(DEFAULT_ADMIN_ROLE, defaultAdmin());\n        _grantRole(DEFAULT_ADMIN_ROLE, newAdmin);\n        delete _pendingDefaultAdmin;\n        delete _pendingDefaultAdminSchedule;\n    }\n\n    ///\n    /// AccessControlDefaultAdminRules public and internal setters for defaultAdminDelay/pendingDefaultAdminDelay\n    ///\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function changeDefaultAdminDelay(uint48 newDelay) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _changeDefaultAdminDelay(newDelay);\n    }\n\n    /**\n     * @dev See {changeDefaultAdminDelay}.\n     *\n     * Internal function without access restriction.\n     */\n    function _changeDefaultAdminDelay(uint48 newDelay) internal virtual {\n        uint48 newSchedule = SafeCast.toUint48(block.timestamp) + _delayChangeWait(newDelay);\n        _setPendingDelay(newDelay, newSchedule);\n        emit DefaultAdminDelayChangeScheduled(newDelay, newSchedule);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function rollbackDefaultAdminDelay() public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _rollbackDefaultAdminDelay();\n    }\n\n    /**\n     * @dev See {rollbackDefaultAdminDelay}.\n     *\n     * Internal function without access restriction.\n     */\n    function _rollbackDefaultAdminDelay() internal virtual {\n        _setPendingDelay(0, 0);\n    }\n\n    /**\n     * @dev Returns the amount of seconds to wait after the `newDelay` will\n     * become the new {defaultAdminDelay}.\n     *\n     * The value returned guarantees that if the delay is reduced, it will go into effect\n     * after a wait that honors the previously set delay.\n     *\n     * See {defaultAdminDelayIncreaseWait}.\n     */\n    function _delayChangeWait(uint48 newDelay) internal view virtual returns (uint48) {\n        uint48 currentDelay = defaultAdminDelay();\n\n        // When increasing the delay, we schedule the delay change to occur after a period of \"new delay\" has passed, up\n        // to a maximum given by defaultAdminDelayIncreaseWait, by default 5 days. For example, if increasing from 1 day\n        // to 3 days, the new delay will come into effect after 3 days. If increasing from 1 day to 10 days, the new\n        // delay will come into effect after 5 days. The 5 day wait period is intended to be able to fix an error like\n        // using milliseconds instead of seconds.\n        //\n        // When decreasing the delay, we wait the difference between \"current delay\" and \"new delay\". This guarantees\n        // that an admin transfer cannot be made faster than \"current delay\" at the time the delay change is scheduled.\n        // For example, if decreasing from 10 days to 3 days, the new delay will come into effect after 7 days.\n        return\n            newDelay > currentDelay\n                ? uint48(Math.min(newDelay, defaultAdminDelayIncreaseWait())) // no need to safecast, both inputs are uint48\n                : currentDelay - newDelay;\n    }\n\n    ///\n    /// Private setters\n    ///\n\n    /**\n     * @dev Setter of the tuple for pending admin and its schedule.\n     *\n     * May emit a DefaultAdminTransferCanceled event.\n     */\n    function _setPendingDefaultAdmin(address newAdmin, uint48 newSchedule) private {\n        (, uint48 oldSchedule) = pendingDefaultAdmin();\n\n        _pendingDefaultAdmin = newAdmin;\n        _pendingDefaultAdminSchedule = newSchedule;\n\n        // An `oldSchedule` from `pendingDefaultAdmin()` is only set if it hasn't been accepted.\n        if (_isScheduleSet(oldSchedule)) {\n            // Emit for implicit cancellations when another default admin was scheduled.\n            emit DefaultAdminTransferCanceled();\n        }\n    }\n\n    /**\n     * @dev Setter of the tuple for pending delay and its schedule.\n     *\n     * May emit a DefaultAdminDelayChangeCanceled event.\n     */\n    function _setPendingDelay(uint48 newDelay, uint48 newSchedule) private {\n        uint48 oldSchedule = _pendingDelaySchedule;\n\n        if (_isScheduleSet(oldSchedule)) {\n            if (_hasSchedulePassed(oldSchedule)) {\n                // Materialize a virtual delay\n                _currentDelay = _pendingDelay;\n            } else {\n                // Emit for implicit cancellations when another delay was scheduled.\n                emit DefaultAdminDelayChangeCanceled();\n            }\n        }\n\n        _pendingDelay = newDelay;\n        _pendingDelaySchedule = newSchedule;\n    }\n\n    ///\n    /// Private helpers\n    ///\n\n    /**\n     * @dev Defines if an `schedule` is considered set. For consistency purposes.\n     */\n    function _isScheduleSet(uint48 schedule) private pure returns (bool) {\n        return schedule != 0;\n    }\n\n    /**\n     * @dev Defines if an `schedule` is considered passed. For consistency purposes.\n     */\n    function _hasSchedulePassed(uint48 schedule) private view returns (bool) {\n        return schedule < block.timestamp;\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/access/extensions/IAccessControlDefaultAdminRules.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/extensions/IAccessControlDefaultAdminRules.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"../IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlDefaultAdminRules declared to support ERC-165 detection.\n */\ninterface IAccessControlDefaultAdminRules is IAccessControl {\n    /**\n     * @dev The new default admin is not a valid default admin.\n     */\n    error AccessControlInvalidDefaultAdmin(address defaultAdmin);\n\n    /**\n     * @dev At least one of the following rules was violated:\n     *\n     * - The `DEFAULT_ADMIN_ROLE` must only be managed by itself.\n     * - The `DEFAULT_ADMIN_ROLE` must only be held by one account at the time.\n     * - Any `DEFAULT_ADMIN_ROLE` transfer must be in two delayed steps.\n     */\n    error AccessControlEnforcedDefaultAdminRules();\n\n    /**\n     * @dev The delay for transferring the default admin delay is enforced and\n     * the operation must wait until `schedule`.\n     *\n     * NOTE: `schedule` can be 0 indicating there's no transfer scheduled.\n     */\n    error AccessControlEnforcedDefaultAdminDelay(uint48 schedule);\n\n    /**\n     * @dev Emitted when a {defaultAdmin} transfer is started, setting `newAdmin` as the next\n     * address to become the {defaultAdmin} by calling {acceptDefaultAdminTransfer} only after `acceptSchedule`\n     * passes.\n     */\n    event DefaultAdminTransferScheduled(address indexed newAdmin, uint48 acceptSchedule);\n\n    /**\n     * @dev Emitted when a {pendingDefaultAdmin} is reset if it was never accepted, regardless of its schedule.\n     */\n    event DefaultAdminTransferCanceled();\n\n    /**\n     * @dev Emitted when a {defaultAdminDelay} change is started, setting `newDelay` as the next\n     * delay to be applied between default admin transfer after `effectSchedule` has passed.\n     */\n    event DefaultAdminDelayChangeScheduled(uint48 newDelay, uint48 effectSchedule);\n\n    /**\n     * @dev Emitted when a {pendingDefaultAdminDelay} is reset if its schedule didn't pass.\n     */\n    event DefaultAdminDelayChangeCanceled();\n\n    /**\n     * @dev Returns the address of the current `DEFAULT_ADMIN_ROLE` holder.\n     */\n    function defaultAdmin() external view returns (address);\n\n    /**\n     * @dev Returns a tuple of a `newAdmin` and an accept schedule.\n     *\n     * After the `schedule` passes, the `newAdmin` will be able to accept the {defaultAdmin} role\n     * by calling {acceptDefaultAdminTransfer}, completing the role transfer.\n     *\n     * A zero value only in `acceptSchedule` indicates no pending admin transfer.\n     *\n     * NOTE: A zero address `newAdmin` means that {defaultAdmin} is being renounced.\n     */\n    function pendingDefaultAdmin() external view returns (address newAdmin, uint48 acceptSchedule);\n\n    /**\n     * @dev Returns the delay required to schedule the acceptance of a {defaultAdmin} transfer started.\n     *\n     * This delay will be added to the current timestamp when calling {beginDefaultAdminTransfer} to set\n     * the acceptance schedule.\n     *\n     * NOTE: If a delay change has been scheduled, it will take effect as soon as the schedule passes, making this\n     * function returns the new delay. See {changeDefaultAdminDelay}.\n     */\n    function defaultAdminDelay() external view returns (uint48);\n\n    /**\n     * @dev Returns a tuple of `newDelay` and an effect schedule.\n     *\n     * After the `schedule` passes, the `newDelay` will get into effect immediately for every\n     * new {defaultAdmin} transfer started with {beginDefaultAdminTransfer}.\n     *\n     * A zero value only in `effectSchedule` indicates no pending delay change.\n     *\n     * NOTE: A zero value only for `newDelay` means that the next {defaultAdminDelay}\n     * will be zero after the effect schedule.\n     */\n    function pendingDefaultAdminDelay() external view returns (uint48 newDelay, uint48 effectSchedule);\n\n    /**\n     * @dev Starts a {defaultAdmin} transfer by setting a {pendingDefaultAdmin} scheduled for acceptance\n     * after the current timestamp plus a {defaultAdminDelay}.\n     *\n     * Requirements:\n     *\n     * - Only can be called by the current {defaultAdmin}.\n     *\n     * Emits a DefaultAdminRoleChangeStarted event.\n     */\n    function beginDefaultAdminTransfer(address newAdmin) external;\n\n    /**\n     * @dev Cancels a {defaultAdmin} transfer previously started with {beginDefaultAdminTransfer}.\n     *\n     * A {pendingDefaultAdmin} not yet accepted can also be cancelled with this function.\n     *\n     * Requirements:\n     *\n     * - Only can be called by the current {defaultAdmin}.\n     *\n     * May emit a DefaultAdminTransferCanceled event.\n     */\n    function cancelDefaultAdminTransfer() external;\n\n    /**\n     * @dev Completes a {defaultAdmin} transfer previously started with {beginDefaultAdminTransfer}.\n     *\n     * After calling the function:\n     *\n     * - `DEFAULT_ADMIN_ROLE` should be granted to the caller.\n     * - `DEFAULT_ADMIN_ROLE` should be revoked from the previous holder.\n     * - {pendingDefaultAdmin} should be reset to zero values.\n     *\n     * Requirements:\n     *\n     * - Only can be called by the {pendingDefaultAdmin}'s `newAdmin`.\n     * - The {pendingDefaultAdmin}'s `acceptSchedule` should've passed.\n     */\n    function acceptDefaultAdminTransfer() external;\n\n    /**\n     * @dev Initiates a {defaultAdminDelay} update by setting a {pendingDefaultAdminDelay} scheduled for getting\n     * into effect after the current timestamp plus a {defaultAdminDelay}.\n     *\n     * This function guarantees that any call to {beginDefaultAdminTransfer} done between the timestamp this\n     * method is called and the {pendingDefaultAdminDelay} effect schedule will use the current {defaultAdminDelay}\n     * set before calling.\n     *\n     * The {pendingDefaultAdminDelay}'s effect schedule is defined in a way that waiting until the schedule and then\n     * calling {beginDefaultAdminTransfer} with the new delay will take at least the same as another {defaultAdmin}\n     * complete transfer (including acceptance).\n     *\n     * The schedule is designed for two scenarios:\n     *\n     * - When the delay is changed for a larger one the schedule is `block.timestamp + newDelay` capped by\n     * {defaultAdminDelayIncreaseWait}.\n     * - When the delay is changed for a shorter one, the schedule is `block.timestamp + (current delay - new delay)`.\n     *\n     * A {pendingDefaultAdminDelay} that never got into effect will be canceled in favor of a new scheduled change.\n     *\n     * Requirements:\n     *\n     * - Only can be called by the current {defaultAdmin}.\n     *\n     * Emits a DefaultAdminDelayChangeScheduled event and may emit a DefaultAdminDelayChangeCanceled event.\n     */\n    function changeDefaultAdminDelay(uint48 newDelay) external;\n\n    /**\n     * @dev Cancels a scheduled {defaultAdminDelay} change.\n     *\n     * Requirements:\n     *\n     * - Only can be called by the current {defaultAdmin}.\n     *\n     * May emit a DefaultAdminDelayChangeCanceled event.\n     */\n    function rollbackDefaultAdminDelay() external;\n\n    /**\n     * @dev Maximum time in seconds for an increase to {defaultAdminDelay} (that is scheduled using {changeDefaultAdminDelay})\n     * to take effect. Default to 5 days.\n     *\n     * When the {defaultAdminDelay} is scheduled to be increased, it goes into effect after the new delay has passed with\n     * the purpose of giving enough time for reverting any accidental change (i.e. using milliseconds instead of seconds)\n     * that may lock the contract. However, to avoid excessive schedules, the wait is capped by this function and it can\n     * be overrode for a custom {defaultAdminDelay} increase scheduling.\n     *\n     * IMPORTANT: Make sure to add a reasonable amount of time while overriding this value, otherwise,\n     * there's a risk of setting a high new delay that goes into effect almost immediately without the\n     * possibility of human intervention in the case of an input error (eg. set milliseconds instead of seconds).\n     */\n    function defaultAdminDelayIncreaseWait() external view returns (uint48);\n}\n"},{"file_path":"@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/extensions/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"../IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC-165 detection.\n */\ninterface IAccessControlEnumerable is IAccessControl {\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n"},{"file_path":"@openzeppelin/contracts/interfaces/IERC1363.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},{"file_path":"@openzeppelin/contracts/interfaces/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},{"file_path":"@openzeppelin/contracts/interfaces/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},{"file_path":"@openzeppelin/contracts/interfaces/IERC5313.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5313.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface for the Light Contract Ownership Standard.\n *\n * A standardized minimal interface required to identify an account that controls a contract\n */\ninterface IERC5313 {\n    /**\n     * @dev Gets the address of the owner.\n     */\n    function owner() external view returns (address);\n}\n"},{"file_path":"@openzeppelin/contracts/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},{"file_path":"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     *\n     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            // bubble errors\n            if iszero(success) {\n                let ptr := mload(0x40)\n                returndatacopy(ptr, 0, returndatasize())\n                revert(ptr, returndatasize())\n            }\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n\n        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        bool success;\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/utils/Context.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/utils/Panic.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/utils/introspection/ERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/utils/introspection/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},{"file_path":"@openzeppelin/contracts/utils/math/Math.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with an success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n            // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2²⁵⁶ + prod0.\n            uint256 prod0 = x * y; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= prod1) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {\n        for (uint256 i = 0; i < byteArray.length; ++i) {\n            if (byteArray[i] != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        uint256 exp;\n        unchecked {\n            exp = 128 * SafeCast.toUint(value > (1 << 128) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 64 * SafeCast.toUint(value > (1 << 64) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 32 * SafeCast.toUint(value > (1 << 32) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 16 * SafeCast.toUint(value > (1 << 16) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 8 * SafeCast.toUint(value > (1 << 8) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 4 * SafeCast.toUint(value > (1 << 4) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 2 * SafeCast.toUint(value > (1 << 2) - 1);\n            value >>= exp;\n            result += exp;\n\n            result += SafeCast.toUint(value > 1);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        uint256 isGt;\n        unchecked {\n            isGt = SafeCast.toUint(value > (1 << 128) - 1);\n            value >>= isGt * 128;\n            result += isGt * 16;\n\n            isGt = SafeCast.toUint(value > (1 << 64) - 1);\n            value >>= isGt * 64;\n            result += isGt * 8;\n\n            isGt = SafeCast.toUint(value > (1 << 32) - 1);\n            value >>= isGt * 32;\n            result += isGt * 4;\n\n            isGt = SafeCast.toUint(value > (1 << 16) - 1);\n            value >>= isGt * 16;\n            result += isGt * 2;\n\n            result += SafeCast.toUint(value > (1 << 8) - 1);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/utils/math/SafeCast.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev An uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n\n    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/utils/structs/EnumerableSet.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(bytes32 value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n}\n"},{"file_path":"contracts/interfaces/IChecker.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @dev Minimal interface for the Checker contract\n */\ninterface IChecker {\n    function checkMint(address account, uint256 amount, address minter, bool isBridge) external;\n    function checkBurn(address account, uint256 amount, address burner, bool isBridge) external;\n}\n"},{"file_path":"contracts/interfaces/IExternalMinter.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IExternalMinter {\n    function getToken() external view returns (address);\n    function mint(address recipient, uint256 amount) external returns (bool);\n    function burn(uint256 amount) external returns (bool);\n}\n"},{"file_path":"contracts/interfaces/IGovernedToken.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IGovernedToken is IERC20 {\n    event Mint(address indexed caller, address indexed to, uint256 amount);\n    event Burn(address indexed caller, address indexed from, uint256 amount);\n    event Freeze(address indexed caller, address indexed account);\n    event Unfreeze(address indexed caller, address indexed account);\n\n    function mint(uint256 amount) external returns (bool);\n    function burn(uint256 amount) external returns (bool);\n    function freeze(address account) external;\n    function unfreeze(address account) external;\n    function pause() external;\n    function unpause() external;\n    function drain(address account) external;\n    function recoverERC20(address token, address recipient, uint256 amount) external;\n    function transferOwnership(address newOwner) external;\n    function acceptOwnership() external;\n}\n"},{"file_path":"contracts/interfaces/ITokenGovernor.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IExternalMinter} from \"./IExternalMinter.sol\";\n\ninterface ITokenGovernor is IExternalMinter {\n    error ZeroAddressNotAllowed();\n    error CallFailed(bytes error);\n    error OnlyMinterOrBridge();\n    error OnlyBurnerOrBridge();\n    error MintFailed();\n    error BurnFailed();\n    error InvalidRecipient();\n    error InvalidFrom();\n\n    event CheckerUpdated(address indexed previousChecker, address indexed newChecker);\n    event NativeMint(address indexed caller, address indexed recipient, uint256 amount);\n    event BridgeMint(address indexed caller, address indexed recipient, uint256 amount);\n    event NativeBurn(address indexed caller, address indexed from, uint256 amount);\n    event BridgeBurn(address indexed caller, address indexed from, uint256 amount);\n    event AccountFrozen(address indexed caller, address indexed account);\n    event AccountUnfrozen(address indexed caller, address indexed account);\n    event ContractPaused(address indexed caller);\n    event ContractUnpaused(address indexed caller);\n    event OwnershipTransferred(address indexed caller, address indexed newOwner);\n    event OwnershipAccepted(address indexed caller);\n    event TokensRecovered(\n        address indexed caller, address indexed tokenAddress, address indexed recipient, uint256 amount\n    );\n    event GovernedTokensRecovered(\n        address indexed caller, address indexed token, address indexed recipient, uint256 amount\n    );\n    event FrozenAccountDrained(address indexed caller, address indexed account);\n    event TokenFunctionExecuted(address indexed caller, bytes data, bytes returnData);\n\n    function MINTER_ROLE() external view returns (bytes32);\n    function BRIDGE_MINTER_OR_BURNER_ROLE() external view returns (bytes32);\n    function BURNER_ROLE() external view returns (bytes32);\n    function FREEZER_ROLE() external view returns (bytes32);\n    function UNFREEZER_ROLE() external view returns (bytes32);\n    function PAUSER_ROLE() external view returns (bytes32);\n    function UNPAUSER_ROLE() external view returns (bytes32);\n    function RECOVERY_ROLE() external view returns (bytes32);\n    function CHECKER_ADMIN_ROLE() external view returns (bytes32);\n    function getChecker() external view returns (address);\n    function getAdmins() external view returns (address[] memory);\n    function getMinters() external view returns (address[] memory);\n    function getBridgeMintersOrBurners() external view returns (address[] memory);\n    function getBurners() external view returns (address[] memory);\n    function getFreezers() external view returns (address[] memory);\n    function getUnfreezers() external view returns (address[] memory);\n    function getPausers() external view returns (address[] memory);\n    function getUnpausers() external view returns (address[] memory);\n    function getRecoveryManagers() external view returns (address[] memory);\n    function getCheckerAdmins() external view returns (address[] memory);\n    function getTokenBalance() external view returns (uint256);\n    function setChecker(address newChecker) external;\n    function mint(uint256 amount) external returns (bool);\n    function burnFrom(address from, uint256 amount) external returns (bool);\n    function freeze(address account) external;\n    function batchFreeze(address[] calldata accounts) external;\n    function unfreeze(address account) external;\n    function batchUnfreeze(address[] calldata accounts) external;\n    function pause() external;\n    function unpause() external;\n    function transferOwnership(address newOwner) external;\n    function acceptOwnership() external;\n    function recoverERC20(address token, address recipient, uint256 amount) external;\n    function recoverGovernedTokenERC20(address token, address recipient, uint256 amount) external;\n    function drainFrozenAccount(address account) external;\n    function batchDrainFrozenAccounts(address[] calldata accounts) external;\n    function executeTokenFunction(bytes calldata data) external payable returns (bytes memory returnData);\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint48","name":"initialDelay","type":"uint48"},{"internalType":"address","name":"initialDefaultAdmin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"uint48","name":"schedule","type":"uint48"}],"name":"AccessControlEnforcedDefaultAdminDelay","type":"error"},{"inputs":[],"name":"AccessControlEnforcedDefaultAdminRules","type":"error"},{"inputs":[{"internalType":"address","name":"defaultAdmin","type":"address"}],"name":"AccessControlInvalidDefaultAdmin","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"BurnFailed","type":"error"},{"inputs":[{"internalType":"bytes","name":"error","type":"bytes"}],"name":"CallFailed","type":"error"},{"inputs":[],"name":"InvalidFrom","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"MintFailed","type":"error"},{"inputs":[],"name":"OnlyBurnerOrBridge","type":"error"},{"inputs":[],"name":"OnlyMinterOrBridge","type":"error"},{"inputs":[{"internalType":"uint8","name":"bits","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintDowncast","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountUnfrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BridgeBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BridgeMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousChecker","type":"address"},{"indexed":true,"internalType":"address","name":"newChecker","type":"address"}],"name":"CheckerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"}],"name":"ContractPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"}],"name":"ContractUnpaused","type":"event"},{"anonymous":false,"inputs":[],"name":"DefaultAdminDelayChangeCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint48","name":"newDelay","type":"uint48"},{"indexed":false,"internalType":"uint48","name":"effectSchedule","type":"uint48"}],"name":"DefaultAdminDelayChangeScheduled","type":"event"},{"anonymous":false,"inputs":[],"name":"DefaultAdminTransferCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"},{"indexed":false,"internalType":"uint48","name":"acceptSchedule","type":"uint48"}],"name":"DefaultAdminTransferScheduled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"FrozenAccountDrained","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"GovernedTokensRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NativeBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NativeMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"}],"name":"OwnershipAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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":"caller","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"TokenFunctionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensRecovered","type":"event"},{"inputs":[],"name":"BRIDGE_MINTER_OR_BURNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BURNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CHECKER_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FREEZER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECOVERY_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNFREEZER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNPAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptDefaultAdminTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"batchDrainFrozenAccounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"batchFreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"batchUnfreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"beginDefaultAdminTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelDefaultAdminTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"newDelay","type":"uint48"}],"name":"changeDefaultAdminDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultAdminDelay","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultAdminDelayIncreaseWait","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"drainFrozenAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeTokenFunction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"freeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAdmins","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBridgeMintersOrBurners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBurners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChecker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCheckerAdmins","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFreezers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinters","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPausers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRecoveryManagers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"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":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMembers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnfreezers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnpausers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"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":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pendingDefaultAdmin","outputs":[{"internalType":"address","name":"newAdmin","type":"address"},{"internalType":"uint48","name":"schedule","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingDefaultAdminDelay","outputs":[{"internalType":"uint48","name":"newDelay","type":"uint48"},{"internalType":"uint48","name":"schedule","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverGovernedTokenERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rollbackDefaultAdminDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newChecker","type":"address"}],"name":"setChecker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unfreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":"0x0000000000000000000000008d0d000ee44948fc98c9b98a4fa4921476f08b0d000000000000000000000000000000000000000000000000000000000003f4800000000000000000000000000d190b74308669e8f4fe7dbce3466169b285289d"}