ETH Price: $3,708.94 (-1.47%)

Transaction Decoder

Block:
22230522 at Apr-09-2025 09:42:11 AM +UTC
Transaction Fee:
0.0000344224364497 ETH $0.13
Gas Used:
46,612 Gas / 0.738488725 Gwei

Emitted Events:

Account State Difference:

  Address   Before After State Difference Code
0x3e542154...69b0119b1
0.000111339360357712 Eth
Nonce: 262
0.000076916923908012 Eth
Nonce: 263
0.0000344224364497
(beaverbuild)
19.959209261870040647 Eth19.959216510346476567 Eth0.00000724847643592
0xaDd8AbDE...023615A6a

Execution Trace

Cheezburger.transfer( to=0x4cb4a52A94aFFee0A511E16aBe692e4427cD0419, amount=1000000000000000000000 ) => ( True )
{"Cheezburger.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\n//\n//           ████████████████████\n//         ██                    ██\n//       ██    ██          ██      ██\n//     ██      ████        ████      ██\n//     ██            ████            ██\n//     ██                            ██\n//   ████████████████████████████████████\n//   ██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██\n//     ████████████████████████████████\n//   ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░██\n//     ██░░██░░░░██████░░░░░░██░░░░████\n//     ████  ████      ██████  ████  ██\n//     ██                            ██\n//       ████████████████████████████\n//\n// Cheezburger enables frictionless creation of tokens for a wide\n// range of use cases, including DAOs, utility tokens, community projects,\n// memecoins, and more. It presents three revolutionary concepts:\n//\n// - Social Tokens:          Enables permissionless, one-click launches for social profiles.\n// - Liquidity-Less Tokens:  Auto-generated liquidity removes the need for initial capital.\n// - Factory Model:          Enables free, fast, and gas-efficient deployments with configurable\n//                           settings, such as wallet caps, decaying premiums, and highly\n//                           customizable tokenomics for fair launches.\n//\n// Social and Liquidity-Less tokens will be available when the V3 pool is opened.\n//\n// ATTENTION: The only genuine deployer is chzb.eth.\n// Beware of scammers and follow official channels for more information.\n//\n// Read more on Cheezburger: https://cheezburger.lol\n//                           https://documentation.cheezburger.lol\n//\npragma solidity ^0.8.22;\n\nimport {SafeTransferLib} from \"./SafeTransferLib.sol\";\n\nimport {CheezburgerDeployerKit} from \"./CheezburgerDeployerKit.sol\";\nimport {ICheezburgerFactory} from \"./ICheezburgerFactory.sol\";\n\ncontract Cheezburger is CheezburgerDeployerKit {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    error TransferToZeroAddress(address from, address to);\n    error TransferToToken(address to);\n    error CannotReceiveEtherDirectly();\n    error EmptyAddressNotAllowed();\n    error SupplyAllocationExceeded();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    event GlobalSettingsChanged();\n    event SettingsChanged();\n    event PairingAmountsChanged();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    uint256 internal constant LIQUIDITY_FEE_WITHDRAWAL_ROLE = _ROLE_1;\n    uint256 internal constant CREATION_FEE_WITHDRAWAL_ROLE = _ROLE_2;\n    uint256 internal constant PAIRING_AMOUNT_SETTER_ROLE = _ROLE_3;\n    uint256 internal constant SETTINGS_SETTER_ROLE = _ROLE_4;\n\n    string private _name;\n    string private _symbol;\n\n    constructor(\n        TokenCustomization memory _customization,\n        address _factory,\n        address _router\n    ) {\n        if (_factory == address(0) || _router == address(0)) {\n            revert EmptyAddressNotAllowed();\n        }\n\n        _name = _customization.name;\n        _symbol = _customization.symbol;\n        _website = _customization.website;\n        _social = _customization.social;\n\n        _initializeOwner(msg.sender);\n        _mint(msg.sender, _customization.supply * (10 ** decimals()));\n        changeSettings(\n            SocialSettings({\n                pairingAmount: 0,\n                leftSideSupply: 1_000_000, // 1 million supply for each social token\n                openFeeWei: 0, // Zero fee at launch\n                poolCreatorFeePercentage: 4, // 4% of the fees to pool creator at launch\n                walletSettings: DynamicSettings({\n                    duration: 14 days, // Max wallet duration 2 weeks for each Social token\n                    percentStart: 300, // 3% starting wallet cap\n                    percentEnd: 4900 // 49% ending wallet cap\n                }),\n                feeSettings: DynamicSettings({\n                    duration: 1 days, // 1 day EAP duration for each Social token\n                    percentStart: 500, // 5% starting fee\n                    percentEnd: 200 // 2% ending fee\n                })\n            }),\n            TokenSettings({pairingAmount: 0, openFeeWei: 0})\n        );\n        changeGlobalSettings(\n            GlobalSettings({\n                factory: ICheezburgerFactory(_factory),\n                router: _router\n            })\n        );\n        // Keep it disabled until launch\n        // changePairingAmounts(totalSupply() / 33, totalSupply() / 33); // 3% mint for social and regular token launches\n    }\n\n    /// @dev Prevents direct Ether transfers to contract\n    receive() external payable {\n        revert CannotReceiveEtherDirectly();\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       ERC20 METADATA                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    function website() public view returns (string memory) {\n        return _website;\n    }\n\n    function social() public view returns (string memory) {\n        return _social;\n    }\n\n    /// @dev Returns the amount of tokens in existence minus liquidity pools burned tokens.\n    /// The total supply with liquidity pools can be calculated with totalSupply() + outOfCirculationTokens.\n    function totalSupply() public view override returns (uint256) {\n        unchecked {\n            return super.totalSupply() - outOfCirculationTokens;\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  PUBLIC UPDATE FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Burns `amount` tokens from the caller.\n    function burn(uint256 amount) external {\n        _burn(msg.sender, amount);\n    }\n\n    /// @dev Burns `amount` tokens from `account`, deducting from the caller\u0027s allowance.\n    function burnFrom(address account, uint256 amount) external {\n        _spendAllowance(account, msg.sender, amount);\n        _burn(account, amount);\n    }\n\n    /// @dev Allows to withdraw creation liquidity fees to a customized contract\n    function withdrawFeesOf(\n        uint256 _userId,\n        address _to\n    ) external onlyRoles(LIQUIDITY_FEE_WITHDRAWAL_ROLE) returns (uint256) {\n        return _withdrawFeesOf(_userId, _to);\n    }\n\n    /// @dev Allows to withdraw creation fees to a customized contract\n    function withdrawCreationFees()\n        external\n        onlyRoles(CREATION_FEE_WITHDRAWAL_ROLE)\n    {\n        return SafeTransferLib.forceSafeTransferAllETH(msg.sender);\n    }\n\n    /// @dev Allow to change global settings by the owner only\n    function changeGlobalSettings(\n        GlobalSettings memory _globalSettings\n    ) public onlyOwner {\n        globalSettings = _globalSettings;\n        emit GlobalSettingsChanged();\n    }\n\n    /// @dev Allow to change settings by the owner only or an authorized address\n    function changeSettings(\n        SocialSettings memory _socialSettings,\n        TokenSettings memory _tokenSettings\n    ) public onlyOwnerOrRoles(SETTINGS_SETTER_ROLE) {\n        // Pairing amounts cannot be changed here\n        socialSettings.leftSideSupply = _socialSettings.leftSideSupply;\n        socialSettings.openFeeWei = _socialSettings.openFeeWei;\n        socialSettings.poolCreatorFeePercentage = _socialSettings\n            .poolCreatorFeePercentage;\n        socialSettings.walletSettings = _socialSettings.walletSettings;\n        socialSettings.feeSettings = _socialSettings.feeSettings;\n        tokenSettings.openFeeWei = _tokenSettings.openFeeWei;\n        emit SettingsChanged();\n    }\n\n    /// @dev Allow to change pairing amounts for token and social settings by the owner only or an authorized address\n    function changePairingAmounts(\n        uint256 _socialPairingAmount,\n        uint256 _tokenPairingAmount\n    ) public onlyOwnerOrRoles(PAIRING_AMOUNT_SETTER_ROLE) {\n        uint256 maxSupplyPerCreation = totalSupply() / 25; // Capped to 4% of the supply\n        if (\n            _socialPairingAmount \u003e maxSupplyPerCreation ||\n            _tokenPairingAmount \u003e maxSupplyPerCreation\n        ) {\n            revert SupplyAllocationExceeded();\n        }\n        socialSettings.pairingAmount = _socialPairingAmount;\n        tokenSettings.pairingAmount = _tokenPairingAmount;\n        emit PairingAmountsChanged();\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     INTERNAL FUNCTIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual override {\n        super._beforeTokenTransfer(from, to, amount);\n\n        // Don\u0027t allow token transfers to the contract\n        if (from != address(0) \u0026\u0026 to == address(this)) {\n            revert TransferToToken(to);\n        }\n    }\n\n    function _afterTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual override {\n        super._afterTokenTransfer(from, to, amount);\n\n        // Must use burn() to burn tokens\n        if (to == address(0) \u0026\u0026 balanceOf(address(0)) \u003e 0) {\n            revert TransferToZeroAddress(from, to);\n        }\n    }\n}\n"},"CheezburgerDeployerKit.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\n//\n//           ████████████████████\n//         ██                    ██\n//       ██    ██          ██      ██\n//     ██      ████        ████      ██\n//     ██            ████            ██\n//     ██                            ██\n//   ████████████████████████████████████\n//   ██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██\n//     ████████████████████████████████\n//   ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░██\n//     ██░░██░░░░██████░░░░░░██░░░░████\n//     ████  ████      ██████  ████  ██\n//     ██                            ██\n//       ████████████████████████████\n//\npragma solidity ^0.8.22;\n\nimport {ERC20} from \"./ERC20.sol\";\nimport {LibString} from \"./LibString.sol\";\nimport {SafeTransferLib} from \"./SafeTransferLib.sol\";\nimport {OwnableRoles} from \"./OwnableRoles.sol\";\n\nimport {ReentrancyGuard} from \"./ReentrancyGuard.sol\";\nimport {ICheezburgerFactory} from \"./ICheezburgerFactory.sol\";\nimport {CheezburgerRegistry} from \"./CheezburgerRegistry.sol\";\n\nabstract contract CheezburgerDeployerKit is\n    ERC20,\n    CheezburgerRegistry,\n    ReentrancyGuard,\n    OwnableRoles\n{\n    using LibString for uint256;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    error EmptyNumericUserId();\n    error SocialNotOpened();\n    error UserIdNotFound();\n    error UserIdAlreadyExist(uint256 userId);\n    error IncorrectPoolOpeningFee(uint256 value, uint256 expected);\n    error SupplyOverflow();\n    error CannotUseCHZBNamespace();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STRUCT                            */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    struct GlobalSettings {\n        ICheezburgerFactory factory;\n        address router;\n    }\n\n    struct SocialSettings {\n        uint256 pairingAmount;\n        uint256 leftSideSupply;\n        uint256 openFeeWei;\n        uint8 poolCreatorFeePercentage;\n        DynamicSettings walletSettings;\n        DynamicSettings feeSettings;\n    }\n\n    struct TokenSettings {\n        uint256 pairingAmount;\n        uint256 openFeeWei;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    event SocialTokenDeployed(\n        uint256 indexed userId,\n        address indexed token,\n        uint256 indexed creationAmount,\n        uint256 currentOutOfCirculationSupply\n    );\n\n    event SocialTokenFeeWithdrawal(\n        address indexed pair,\n        address indexed to,\n        uint256 indexed amount\n    );\n\n    event LiquidityLessTokenDeployed(\n        address indexed token,\n        uint256 indexed creationAmount,\n        uint256 currentOutOfCirculationSupply\n    );\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    string internal _website;\n    string internal _social;\n    uint256 public outOfCirculationTokens;\n\n    uint256 internal constant NAMESPACE_ROLE = _ROLE_5;\n\n    GlobalSettings public globalSettings;\n    SocialSettings public socialSettings;\n    TokenSettings public tokenSettings;\n\n    mapping(uint256 =\u003e Token) public socialTokens;\n    mapping(address =\u003e uint256) public socialIds;\n\n    /// @dev Deploy a new social token using bootstrapped CHZB liquidity\n    /// @param userId User ID for the social token\n    /// @dev Can be deployed from another contract but for gas reasons we\u0027ll let it here\n    function deploySocialTokenWithCHZB(\n        uint256 userId\n    ) external payable nonReentrant returns (address) {\n        // Ensure userId is valid\n        if (userId == 0) {\n            revert EmptyNumericUserId();\n        }\n\n        // Ensure userId doesn\u0027t already exist\n        if (socialTokens[userId].leftSide != address(0)) {\n            revert UserIdAlreadyExist(userId);\n        }\n\n        // Half liquidity is burned\n        // Half is kept in the contract as a custodial\n        address[] memory feeAddresses = new address[](2);\n        feeAddresses[0] = address(0);\n        feeAddresses[1] = address(this);\n\n        // 50/50 fees split\n        uint8[] memory feePercentages = new uint8[](1);\n        feePercentages[0] = 50;\n\n        // Transform the user ID to string for name and symbol\n        string memory userIdString = userId.toString();\n\n        Token memory token = _deployWithCHZB(\n            TokenCustomization({\n                name: LibString.concat(userIdString, \" (Social)\"),\n                symbol: LibString.concat(\"CHZB-X-\", userIdString),\n                website: _website,\n                social: _social,\n                supply: socialSettings.leftSideSupply\n            }),\n            LiquiditySettings({\n                feeThresholdPercent: 2,\n                feeAddresses: feeAddresses,\n                feePercentages: feePercentages\n            }),\n            socialSettings.feeSettings,\n            socialSettings.walletSettings,\n            socialSettings.poolCreatorFeePercentage \u003e 0\n                ? ReferralSettings({\n                    feeReceiver: msg.sender,\n                    feePercentage: socialSettings.poolCreatorFeePercentage\n                })\n                : ReferralSettings({feeReceiver: address(0), feePercentage: 0}),\n            socialSettings.pairingAmount,\n            socialSettings.openFeeWei\n        );\n\n        // Register ID\n        socialTokens[userId] = token;\n        socialIds[token.leftSide] = userId;\n\n        emit SocialTokenDeployed(\n            userId,\n            token.leftSide,\n            socialSettings.pairingAmount,\n            outOfCirculationTokens\n        );\n\n        return address(token.leftSide);\n    }\n\n    /// @dev Deploy a new customized token with bootstrapped CHZB liquidity\n    function deployTokenWithCHZB(\n        TokenCustomization memory _customization,\n        LiquiditySettings memory _liquidity,\n        DynamicSettings memory _fee,\n        DynamicSettings memory _wallet,\n        ReferralSettings memory _referral\n    ) external payable nonReentrant returns (address) {\n        if (\n            LibString.startsWith(_customization.symbol, \"CHZB-\") \u0026\u0026\n            !hasAnyRole(msg.sender, NAMESPACE_ROLE)\n        ) {\n            revert CannotUseCHZBNamespace();\n        }\n\n        Token memory token = _deployWithCHZB(\n            _customization,\n            _liquidity,\n            _fee,\n            _wallet,\n            _referral,\n            tokenSettings.pairingAmount,\n            tokenSettings.openFeeWei\n        );\n\n        emit LiquidityLessTokenDeployed(\n            token.leftSide,\n            tokenSettings.pairingAmount,\n            outOfCirculationTokens\n        );\n\n        return address(token.leftSide);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     INTERNAL FUNCTIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    function _deployWithCHZB(\n        TokenCustomization memory _customization,\n        LiquiditySettings memory _liquidity,\n        DynamicSettings memory _fee,\n        DynamicSettings memory _wallet,\n        ReferralSettings memory _referral,\n        uint256 _pairingAmount,\n        uint256 _openingFee\n    ) private returns (Token memory) {\n        // Collect fee if any\n        if (msg.value != _openingFee) {\n            revert IncorrectPoolOpeningFee(msg.value, _openingFee);\n        }\n\n        // The tokens are used to pool with the token to give initial liquidity\n        // This have no impact on price and they cannot be withdrawn as they are burned\n        _mint(address(this), _pairingAmount);\n\n        // Approve the Factory to use the created CHZB\n        SafeTransferLib.safeApprove(\n            address(this),\n            address(globalSettings.factory),\n            _pairingAmount\n        );\n\n        // Create the token\n        address tokenAddress = globalSettings.factory.deployWithToken(\n            _customization,\n            globalSettings.router,\n            address(this),\n            _pairingAmount,\n            _liquidity,\n            _fee,\n            _wallet,\n            _referral\n        );\n\n        // Get token info\n        Token memory token = getToken(globalSettings.factory, tokenAddress);\n\n        // Burn liquidity\n        SafeTransferLib.safeTransferAll(address(token.pair), address(0));\n\n        // Update out of circulating supply data\n        unchecked {\n            if (totalSupply() \u003e totalSupply() + _pairingAmount) {\n                revert SupplyOverflow();\n            }\n            outOfCirculationTokens = outOfCirculationTokens + _pairingAmount;\n        }\n\n        return token;\n    }\n\n    /// @dev Allows to withdraw creation liquidity fees to a customized contract\n    function _withdrawFeesOf(\n        uint256 _userId,\n        address _to\n    ) internal returns (uint256) {\n        address pair = address(socialTokens[_userId].pair);\n        if (pair == address(0)) {\n            revert UserIdNotFound();\n        }\n        uint256 amount = SafeTransferLib.safeTransferAll(pair, _to);\n        emit SocialTokenFeeWithdrawal(pair, _to, amount);\n        return amount;\n    }\n}\n"},"CheezburgerRegistry.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.22;\n\nimport {ICheezburgerFactory} from \"./ICheezburgerFactory.sol\";\nimport {ICheezburger} from \"./ICheezburger.sol\";\nimport {CheezburgerStructs} from \"./CheezburgerStructs.sol\";\n\nabstract contract CheezburgerRegistry is CheezburgerStructs {\n    /// @dev Convert a socialTokens entry back to Token\n    function getSocialToken(\n        ICheezburger _chzb,\n        uint256 _id\n    ) internal view returns (Token memory) {\n        (\n            address _uniswapFactory,\n            address _uniswapRouter,\n            address _uniswapPair,\n            address _creator,\n            address _leftSide,\n            address _rightSide,\n            LiquiditySettings memory _liquidity,\n            DynamicSettings memory _fee,\n            DynamicSettings memory _wallet,\n            ReferralSettings memory _referral\n        ) = _chzb.socialTokens(_id);\n\n        return\n            Token({\n                factory: _uniswapFactory,\n                router: _uniswapRouter,\n                pair: _uniswapPair,\n                creator: _creator,\n                leftSide: _leftSide,\n                rightSide: _rightSide,\n                liquidity: _liquidity,\n                fee: _fee,\n                wallet: _wallet,\n                referral: _referral\n            });\n    }\n\n    /// @dev Convert a burgerRegistry entry back to Token\n    function getToken(\n        ICheezburgerFactory _factory,\n        address _pairedToken\n    ) internal view returns (Token memory) {\n        (\n            address _uniswapFactory,\n            address _uniswapRouter,\n            address _uniswapPair,\n            address _creator,\n            address _leftSide,\n            address _rightSide,\n            LiquiditySettings memory _liquidity,\n            DynamicSettings memory _fee,\n            DynamicSettings memory _wallet,\n            ReferralSettings memory _referral\n        ) = _factory.burgerRegistry(_pairedToken);\n\n        return\n            Token({\n                factory: _uniswapFactory,\n                router: _uniswapRouter,\n                pair: _uniswapPair,\n                creator: _creator,\n                leftSide: _leftSide,\n                rightSide: _rightSide,\n                liquidity: _liquidity,\n                fee: _fee,\n                wallet: _wallet,\n                referral: _referral\n            });\n    }\n}\n"},"CheezburgerStructs.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.22;\n\ninterface CheezburgerStructs {\n    /// @dev Settings and contracts for a token pair and its liquidity pool.\n    struct Token {\n        /// @dev The Uniswap factory contract\n        address factory;\n        /// @dev The Uniswap router contract\n        address router;\n        /// @dev The Uniswap pair contract\n        address pair;\n        /// @dev The token creator\n        address creator;\n        /// @dev The left side of the pair\n        address leftSide;\n        /// @dev The right side ERC20 token of the pair\n        address rightSide;\n        /// @dev Liquidity settings\n        LiquiditySettings liquidity;\n        /// @dev Dynamic fee settings\n        DynamicSettings fee;\n        /// @dev Dynamic wallet settings\n        DynamicSettings wallet;\n        /// @dev Referral settings\n        ReferralSettings referral;\n    }\n\n    /// @dev Settings for customizing the token\n    /// @param name The name of the token\n    /// @param symbol The symbol for the token\n    /// @param website The website associated with the token\n    /// @param social A social media link associated with the token\n    /// @param supply The max supply of the token\n    struct TokenCustomization {\n        string name;\n        string symbol;\n        string website;\n        string social;\n        uint256 supply;\n    }\n\n    /// @dev Settings for dynamic fees that change over time\n    /// @param duration The duration over which the rate changes\n    /// @param percentStart The starting percentage rate\n    /// @param percentEnd The ending percentage rate\n    struct DynamicSettings {\n        uint256 duration;\n        uint16 percentStart;\n        uint16 percentEnd;\n    }\n\n    /// @dev Settings for liquidity pool fees distributed to addresses\n    /// @param feeThresholdPercent The percentage threshold that triggers liquidity swaps\n    /// @param feeAddresses The addresses receiving distributed fee amounts\n    /// @param feePercentages The percentage fee amounts for each address\n    struct LiquiditySettings {\n        uint8 feeThresholdPercent;\n        address[] feeAddresses;\n        uint8[] feePercentages;\n    }\n\n    /// @dev Settings for referrals. Referrals get commissions from fees whenever people uses the factory to deploy their token.\n    /// @param feeReceiver The addresses receiving commissions\n    /// @param feePercentage The percentage fee\n    struct ReferralSettings {\n        address feeReceiver;\n        uint8 feePercentage;\n    }\n}\n"},"ECDSA.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Gas optimized ECDSA wrapper.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol)\n/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol)\n///\n/// @dev Note:\n/// - The recovery functions use the ecrecover precompile (0x1).\n/// - As of Solady version 0.0.68, the `recover` variants will revert upon recovery failure.\n///   This is for more safety by default.\n///   Use the `tryRecover` variants if you need to get the zero address back\n///   upon recovery failure instead.\n/// - As of Solady version 0.0.134, all `bytes signature` variants accept both\n///   regular 65-byte `(r, s, v)` and EIP-2098 `(r, vs)` short form signatures.\n///   See: https://eips.ethereum.org/EIPS/eip-2098\n///   This is for calldata efficiency on smart accounts prevalent on L2s.\n///\n/// WARNING! Do NOT use signatures as unique identifiers:\n/// - Use a nonce in the digest to prevent replay attacks on the same contract.\n/// - Use EIP-712 for the digest to prevent replay attacks across different chains and contracts.\n///   EIP-712 also enables readable signing of typed data for better user safety.\n/// This implementation does NOT check if a signature is non-malleable.\nlibrary ECDSA {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                        CUSTOM ERRORS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The signature is invalid.\n    error InvalidSignature();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                    RECOVERY OPERATIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Recovers the signer\u0027s address from a message digest `hash`, and the `signature`.\n    function recover(bytes32 hash, bytes memory signature) internal view returns (address result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := 1\n            let m := mload(0x40) // Cache the free memory pointer.\n            for {} 1 {} {\n                mstore(0x00, hash)\n                mstore(0x40, mload(add(signature, 0x20))) // `r`.\n                if eq(mload(signature), 64) {\n                    let vs := mload(add(signature, 0x40))\n                    mstore(0x20, add(shr(255, vs), 27)) // `v`.\n                    mstore(0x60, shr(1, shl(1, vs))) // `s`.\n                    break\n                }\n                if eq(mload(signature), 65) {\n                    mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`.\n                    mstore(0x60, mload(add(signature, 0x40))) // `s`.\n                    break\n                }\n                result := 0\n                break\n            }\n            result :=\n                mload(\n                    staticcall(\n                        gas(), // Amount of gas left for the transaction.\n                        result, // Address of `ecrecover`.\n                        0x00, // Start of input.\n                        0x80, // Size of input.\n                        0x01, // Start of output.\n                        0x20 // Size of output.\n                    )\n                )\n            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n            if iszero(returndatasize()) {\n                mstore(0x00, 0x8baa579f) // `InvalidSignature()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x60, 0) // Restore the zero slot.\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Recovers the signer\u0027s address from a message digest `hash`, and the `signature`.\n    function recoverCalldata(bytes32 hash, bytes calldata signature)\n        internal\n        view\n        returns (address result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := 1\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x00, hash)\n            for {} 1 {} {\n                if eq(signature.length, 64) {\n                    let vs := calldataload(add(signature.offset, 0x20))\n                    mstore(0x20, add(shr(255, vs), 27)) // `v`.\n                    mstore(0x40, calldataload(signature.offset)) // `r`.\n                    mstore(0x60, shr(1, shl(1, vs))) // `s`.\n                    break\n                }\n                if eq(signature.length, 65) {\n                    mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`.\n                    calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`.\n                    break\n                }\n                result := 0\n                break\n            }\n            result :=\n                mload(\n                    staticcall(\n                        gas(), // Amount of gas left for the transaction.\n                        result, // Address of `ecrecover`.\n                        0x00, // Start of input.\n                        0x80, // Size of input.\n                        0x01, // Start of output.\n                        0x20 // Size of output.\n                    )\n                )\n            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n            if iszero(returndatasize()) {\n                mstore(0x00, 0x8baa579f) // `InvalidSignature()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x60, 0) // Restore the zero slot.\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Recovers the signer\u0027s address from a message digest `hash`,\n    /// and the EIP-2098 short form signature defined by `r` and `vs`.\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x00, hash)\n            mstore(0x20, add(shr(255, vs), 27)) // `v`.\n            mstore(0x40, r)\n            mstore(0x60, shr(1, shl(1, vs))) // `s`.\n            result :=\n                mload(\n                    staticcall(\n                        gas(), // Amount of gas left for the transaction.\n                        1, // Address of `ecrecover`.\n                        0x00, // Start of input.\n                        0x80, // Size of input.\n                        0x01, // Start of output.\n                        0x20 // Size of output.\n                    )\n                )\n            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n            if iszero(returndatasize()) {\n                mstore(0x00, 0x8baa579f) // `InvalidSignature()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x60, 0) // Restore the zero slot.\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Recovers the signer\u0027s address from a message digest `hash`,\n    /// and the signature defined by `v`, `r`, `s`.\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)\n        internal\n        view\n        returns (address result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x00, hash)\n            mstore(0x20, and(v, 0xff))\n            mstore(0x40, r)\n            mstore(0x60, s)\n            result :=\n                mload(\n                    staticcall(\n                        gas(), // Amount of gas left for the transaction.\n                        1, // Address of `ecrecover`.\n                        0x00, // Start of input.\n                        0x80, // Size of input.\n                        0x01, // Start of output.\n                        0x20 // Size of output.\n                    )\n                )\n            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n            if iszero(returndatasize()) {\n                mstore(0x00, 0x8baa579f) // `InvalidSignature()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x60, 0) // Restore the zero slot.\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   TRY-RECOVER OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // WARNING!\n    // These functions will NOT revert upon recovery failure.\n    // Instead, they will return the zero address upon recovery failure.\n    // It is critical that the returned address is NEVER compared against\n    // a zero address (e.g. an uninitialized address variable).\n\n    /// @dev Recovers the signer\u0027s address from a message digest `hash`, and the `signature`.\n    function tryRecover(bytes32 hash, bytes memory signature)\n        internal\n        view\n        returns (address result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := 1\n            let m := mload(0x40) // Cache the free memory pointer.\n            for {} 1 {} {\n                mstore(0x00, hash)\n                mstore(0x40, mload(add(signature, 0x20))) // `r`.\n                if eq(mload(signature), 64) {\n                    let vs := mload(add(signature, 0x40))\n                    mstore(0x20, add(shr(255, vs), 27)) // `v`.\n                    mstore(0x60, shr(1, shl(1, vs))) // `s`.\n                    break\n                }\n                if eq(mload(signature), 65) {\n                    mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`.\n                    mstore(0x60, mload(add(signature, 0x40))) // `s`.\n                    break\n                }\n                result := 0\n                break\n            }\n            pop(\n                staticcall(\n                    gas(), // Amount of gas left for the transaction.\n                    result, // Address of `ecrecover`.\n                    0x00, // Start of input.\n                    0x80, // Size of input.\n                    0x40, // Start of output.\n                    0x20 // Size of output.\n                )\n            )\n            mstore(0x60, 0) // Restore the zero slot.\n            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n            result := mload(xor(0x60, returndatasize()))\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Recovers the signer\u0027s address from a message digest `hash`, and the `signature`.\n    function tryRecoverCalldata(bytes32 hash, bytes calldata signature)\n        internal\n        view\n        returns (address result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := 1\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x00, hash)\n            for {} 1 {} {\n                if eq(signature.length, 64) {\n                    let vs := calldataload(add(signature.offset, 0x20))\n                    mstore(0x20, add(shr(255, vs), 27)) // `v`.\n                    mstore(0x40, calldataload(signature.offset)) // `r`.\n                    mstore(0x60, shr(1, shl(1, vs))) // `s`.\n                    break\n                }\n                if eq(signature.length, 65) {\n                    mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`.\n                    calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`.\n                    break\n                }\n                result := 0\n                break\n            }\n            pop(\n                staticcall(\n                    gas(), // Amount of gas left for the transaction.\n                    result, // Address of `ecrecover`.\n                    0x00, // Start of input.\n                    0x80, // Size of input.\n                    0x40, // Start of output.\n                    0x20 // Size of output.\n                )\n            )\n            mstore(0x60, 0) // Restore the zero slot.\n            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n            result := mload(xor(0x60, returndatasize()))\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Recovers the signer\u0027s address from a message digest `hash`,\n    /// and the EIP-2098 short form signature defined by `r` and `vs`.\n    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs)\n        internal\n        view\n        returns (address result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x00, hash)\n            mstore(0x20, add(shr(255, vs), 27)) // `v`.\n            mstore(0x40, r)\n            mstore(0x60, shr(1, shl(1, vs))) // `s`.\n            pop(\n                staticcall(\n                    gas(), // Amount of gas left for the transaction.\n                    1, // Address of `ecrecover`.\n                    0x00, // Start of input.\n                    0x80, // Size of input.\n                    0x40, // Start of output.\n                    0x20 // Size of output.\n                )\n            )\n            mstore(0x60, 0) // Restore the zero slot.\n            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n            result := mload(xor(0x60, returndatasize()))\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Recovers the signer\u0027s address from a message digest `hash`,\n    /// and the signature defined by `v`, `r`, `s`.\n    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)\n        internal\n        view\n        returns (address result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x00, hash)\n            mstore(0x20, and(v, 0xff))\n            mstore(0x40, r)\n            mstore(0x60, s)\n            pop(\n                staticcall(\n                    gas(), // Amount of gas left for the transaction.\n                    1, // Address of `ecrecover`.\n                    0x00, // Start of input.\n                    0x80, // Size of input.\n                    0x40, // Start of output.\n                    0x20 // Size of output.\n                )\n            )\n            mstore(0x60, 0) // Restore the zero slot.\n            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n            result := mload(xor(0x60, returndatasize()))\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     HASHING OPERATIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns an Ethereum Signed Message, created from a `hash`.\n    /// This produces a hash corresponding to the one signed with the\n    /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign)\n    /// JSON-RPC method as part of EIP-191.\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x20, hash) // Store into scratch space for keccak256.\n            mstore(0x00, \"\\x00\\x00\\x00\\x00\\x19Ethereum Signed Message:\\n32\") // 28 bytes.\n            result := keccak256(0x04, 0x3c) // `32 * 2 - (32 - 28) = 60 = 0x3c`.\n        }\n    }\n\n    /// @dev Returns an Ethereum Signed Message, created from `s`.\n    /// This produces a hash corresponding to the one signed with the\n    /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign)\n    /// JSON-RPC method as part of EIP-191.\n    /// Note: Supports lengths of `s` up to 999999 bytes.\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let sLength := mload(s)\n            let o := 0x20\n            mstore(o, \"\\x19Ethereum Signed Message:\\n\") // 26 bytes, zero-right-padded.\n            mstore(0x00, 0x00)\n            // Convert the `s.length` to ASCII decimal representation: `base10(s.length)`.\n            for { let temp := sLength } 1 {} {\n                o := sub(o, 1)\n                mstore8(o, add(48, mod(temp, 10)))\n                temp := div(temp, 10)\n                if iszero(temp) { break }\n            }\n            let n := sub(0x3a, o) // Header length: `26 + 32 - o`.\n            // Throw an out-of-offset error (consumes all gas) if the header exceeds 32 bytes.\n            returndatacopy(returndatasize(), returndatasize(), gt(n, 0x20))\n            mstore(s, or(mload(0x00), mload(n))) // Temporarily store the header.\n            result := keccak256(add(s, sub(0x20, n)), add(n, sLength))\n            mstore(s, sLength) // Restore the length.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   EMPTY CALLDATA HELPERS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns an empty calldata bytes.\n    function emptySignature() internal pure returns (bytes calldata signature) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            signature.length := 0\n        }\n    }\n}\n"},"ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Simple ERC20 + EIP-2612 implementation.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)\n///\n/// @dev Note:\n/// - The ERC20 standard allows minting and transferring to and from the zero address,\n///   minting and transferring zero tokens, as well as self-approvals.\n///   For performance, this implementation WILL NOT revert for such actions.\n///   Please add any checks with overrides if desired.\n/// - The `permit` function uses the ecrecover precompile (0x1).\n///\n/// If you are overriding:\n/// - NEVER violate the ERC20 invariant:\n///   the total sum of all balances must be equal to `totalSupply()`.\n/// - Check that the overridden function is actually used in the function you want to\n///   change the behavior of. Much of the code has been manually inlined for performance.\nabstract contract ERC20 {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The total supply has overflowed.\n    error TotalSupplyOverflow();\n\n    /// @dev The allowance has overflowed.\n    error AllowanceOverflow();\n\n    /// @dev The allowance has underflowed.\n    error AllowanceUnderflow();\n\n    /// @dev Insufficient balance.\n    error InsufficientBalance();\n\n    /// @dev Insufficient allowance.\n    error InsufficientAllowance();\n\n    /// @dev The permit is invalid.\n    error InvalidPermit();\n\n    /// @dev The permit has expired.\n    error PermitExpired();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Emitted when `amount` tokens is transferred from `from` to `to`.\n    event Transfer(address indexed from, address indexed to, uint256 amount);\n\n    /// @dev Emitted when `amount` tokens is approved by `owner` to be used by `spender`.\n    event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n    /// @dev `keccak256(bytes(\"Transfer(address,address,uint256)\"))`.\n    uint256 private constant _TRANSFER_EVENT_SIGNATURE =\n        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;\n\n    /// @dev `keccak256(bytes(\"Approval(address,address,uint256)\"))`.\n    uint256 private constant _APPROVAL_EVENT_SIGNATURE =\n        0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The storage slot for the total supply.\n    uint256 private constant _TOTAL_SUPPLY_SLOT = 0x05345cdf77eb68f44c;\n\n    /// @dev The balance slot of `owner` is given by:\n    /// ```\n    ///     mstore(0x0c, _BALANCE_SLOT_SEED)\n    ///     mstore(0x00, owner)\n    ///     let balanceSlot := keccak256(0x0c, 0x20)\n    /// ```\n    uint256 private constant _BALANCE_SLOT_SEED = 0x87a211a2;\n\n    /// @dev The allowance slot of (`owner`, `spender`) is given by:\n    /// ```\n    ///     mstore(0x20, spender)\n    ///     mstore(0x0c, _ALLOWANCE_SLOT_SEED)\n    ///     mstore(0x00, owner)\n    ///     let allowanceSlot := keccak256(0x0c, 0x34)\n    /// ```\n    uint256 private constant _ALLOWANCE_SLOT_SEED = 0x7f5e9f20;\n\n    /// @dev The nonce slot of `owner` is given by:\n    /// ```\n    ///     mstore(0x0c, _NONCES_SLOT_SEED)\n    ///     mstore(0x00, owner)\n    ///     let nonceSlot := keccak256(0x0c, 0x20)\n    /// ```\n    uint256 private constant _NONCES_SLOT_SEED = 0x38377508;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev `(_NONCES_SLOT_SEED \u003c\u003c 16) | 0x1901`.\n    uint256 private constant _NONCES_SLOT_SEED_WITH_SIGNATURE_PREFIX = 0x383775081901;\n\n    /// @dev `keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\")`.\n    bytes32 private constant _DOMAIN_TYPEHASH =\n        0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n    /// @dev `keccak256(\"1\")`.\n    bytes32 private constant _VERSION_HASH =\n        0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;\n\n    /// @dev `keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\")`.\n    bytes32 private constant _PERMIT_TYPEHASH =\n        0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       ERC20 METADATA                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the name of the token.\n    function name() public view virtual returns (string memory);\n\n    /// @dev Returns the symbol of the token.\n    function symbol() public view virtual returns (string memory);\n\n    /// @dev Returns the decimals places of the token.\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           ERC20                            */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the amount of tokens in existence.\n    function totalSupply() public view virtual returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := sload(_TOTAL_SUPPLY_SLOT)\n        }\n    }\n\n    /// @dev Returns the amount of tokens owned by `owner`.\n    function balanceOf(address owner) public view virtual returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x0c, _BALANCE_SLOT_SEED)\n            mstore(0x00, owner)\n            result := sload(keccak256(0x0c, 0x20))\n        }\n    }\n\n    /// @dev Returns the amount of tokens that `spender` can spend on behalf of `owner`.\n    function allowance(address owner, address spender)\n        public\n        view\n        virtual\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x20, spender)\n            mstore(0x0c, _ALLOWANCE_SLOT_SEED)\n            mstore(0x00, owner)\n            result := sload(keccak256(0x0c, 0x34))\n        }\n    }\n\n    /// @dev Sets `amount` as the allowance of `spender` over the caller\u0027s tokens.\n    ///\n    /// Emits a {Approval} event.\n    function approve(address spender, uint256 amount) public virtual returns (bool) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the allowance slot and store the amount.\n            mstore(0x20, spender)\n            mstore(0x0c, _ALLOWANCE_SLOT_SEED)\n            mstore(0x00, caller())\n            sstore(keccak256(0x0c, 0x34), amount)\n            // Emit the {Approval} event.\n            mstore(0x00, amount)\n            log3(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, caller(), shr(96, mload(0x2c)))\n        }\n        return true;\n    }\n\n    /// @dev Transfer `amount` tokens from the caller to `to`.\n    ///\n    /// Requirements:\n    /// - `from` must at least have `amount`.\n    ///\n    /// Emits a {Transfer} event.\n    function transfer(address to, uint256 amount) public virtual returns (bool) {\n        _beforeTokenTransfer(msg.sender, to, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the balance slot and load its value.\n            mstore(0x0c, _BALANCE_SLOT_SEED)\n            mstore(0x00, caller())\n            let fromBalanceSlot := keccak256(0x0c, 0x20)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Compute the balance slot of `to`.\n            mstore(0x00, to)\n            let toBalanceSlot := keccak256(0x0c, 0x20)\n            // Add and store the updated balance of `to`.\n            // Will not overflow because the sum of all user balances\n            // cannot exceed the maximum uint256 value.\n            sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))\n            // Emit the {Transfer} event.\n            mstore(0x20, amount)\n            log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, caller(), shr(96, mload(0x0c)))\n        }\n        _afterTokenTransfer(msg.sender, to, amount);\n        return true;\n    }\n\n    /// @dev Transfers `amount` tokens from `from` to `to`.\n    ///\n    /// Note: Does not update the allowance if it is the maximum uint256 value.\n    ///\n    /// Requirements:\n    /// - `from` must at least have `amount`.\n    /// - The caller must have at least `amount` of allowance to transfer the tokens of `from`.\n    ///\n    /// Emits a {Transfer} event.\n    function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) {\n        _beforeTokenTransfer(from, to, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let from_ := shl(96, from)\n            // Compute the allowance slot and load its value.\n            mstore(0x20, caller())\n            mstore(0x0c, or(from_, _ALLOWANCE_SLOT_SEED))\n            let allowanceSlot := keccak256(0x0c, 0x34)\n            let allowance_ := sload(allowanceSlot)\n            // If the allowance is not the maximum uint256 value.\n            if add(allowance_, 1) {\n                // Revert if the amount to be transferred exceeds the allowance.\n                if gt(amount, allowance_) {\n                    mstore(0x00, 0x13be252b) // `InsufficientAllowance()`.\n                    revert(0x1c, 0x04)\n                }\n                // Subtract and store the updated allowance.\n                sstore(allowanceSlot, sub(allowance_, amount))\n            }\n            // Compute the balance slot and load its value.\n            mstore(0x0c, or(from_, _BALANCE_SLOT_SEED))\n            let fromBalanceSlot := keccak256(0x0c, 0x20)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Compute the balance slot of `to`.\n            mstore(0x00, to)\n            let toBalanceSlot := keccak256(0x0c, 0x20)\n            // Add and store the updated balance of `to`.\n            // Will not overflow because the sum of all user balances\n            // cannot exceed the maximum uint256 value.\n            sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))\n            // Emit the {Transfer} event.\n            mstore(0x20, amount)\n            log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, from_), shr(96, mload(0x0c)))\n        }\n        _afterTokenTransfer(from, to, amount);\n        return true;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          EIP-2612                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev For more performance, override to return the constant value\n    /// of `keccak256(bytes(name()))` if `name()` will never change.\n    function _constantNameHash() internal view virtual returns (bytes32 result) {}\n\n    /// @dev Returns the current nonce for `owner`.\n    /// This value is used to compute the signature for EIP-2612 permit.\n    function nonces(address owner) public view virtual returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the nonce slot and load its value.\n            mstore(0x0c, _NONCES_SLOT_SEED)\n            mstore(0x00, owner)\n            result := sload(keccak256(0x0c, 0x20))\n        }\n    }\n\n    /// @dev Sets `value` as the allowance of `spender` over the tokens of `owner`,\n    /// authorized by a signed approval by `owner`.\n    ///\n    /// Emits a {Approval} event.\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual {\n        bytes32 nameHash = _constantNameHash();\n        //  We simply calculate it on-the-fly to allow for cases where the `name` may change.\n        if (nameHash == bytes32(0)) nameHash = keccak256(bytes(name()));\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Revert if the block timestamp is greater than `deadline`.\n            if gt(timestamp(), deadline) {\n                mstore(0x00, 0x1a15a3cc) // `PermitExpired()`.\n                revert(0x1c, 0x04)\n            }\n            let m := mload(0x40) // Grab the free memory pointer.\n            // Clean the upper 96 bits.\n            owner := shr(96, shl(96, owner))\n            spender := shr(96, shl(96, spender))\n            // Compute the nonce slot and load its value.\n            mstore(0x0e, _NONCES_SLOT_SEED_WITH_SIGNATURE_PREFIX)\n            mstore(0x00, owner)\n            let nonceSlot := keccak256(0x0c, 0x20)\n            let nonceValue := sload(nonceSlot)\n            // Prepare the domain separator.\n            mstore(m, _DOMAIN_TYPEHASH)\n            mstore(add(m, 0x20), nameHash)\n            mstore(add(m, 0x40), _VERSION_HASH)\n            mstore(add(m, 0x60), chainid())\n            mstore(add(m, 0x80), address())\n            mstore(0x2e, keccak256(m, 0xa0))\n            // Prepare the struct hash.\n            mstore(m, _PERMIT_TYPEHASH)\n            mstore(add(m, 0x20), owner)\n            mstore(add(m, 0x40), spender)\n            mstore(add(m, 0x60), value)\n            mstore(add(m, 0x80), nonceValue)\n            mstore(add(m, 0xa0), deadline)\n            mstore(0x4e, keccak256(m, 0xc0))\n            // Prepare the ecrecover calldata.\n            mstore(0x00, keccak256(0x2c, 0x42))\n            mstore(0x20, and(0xff, v))\n            mstore(0x40, r)\n            mstore(0x60, s)\n            let t := staticcall(gas(), 1, 0, 0x80, 0x20, 0x20)\n            // If the ecrecover fails, the returndatasize will be 0x00,\n            // `owner` will be checked if it equals the hash at 0x00,\n            // which evaluates to false (i.e. 0), and we will revert.\n            // If the ecrecover succeeds, the returndatasize will be 0x20,\n            // `owner` will be compared against the returned address at 0x20.\n            if iszero(eq(mload(returndatasize()), owner)) {\n                mstore(0x00, 0xddafbaef) // `InvalidPermit()`.\n                revert(0x1c, 0x04)\n            }\n            // Increment and store the updated nonce.\n            sstore(nonceSlot, add(nonceValue, t)) // `t` is 1 if ecrecover succeeds.\n            // Compute the allowance slot and store the value.\n            // The `owner` is already at slot 0x20.\n            mstore(0x40, or(shl(160, _ALLOWANCE_SLOT_SEED), spender))\n            sstore(keccak256(0x2c, 0x34), value)\n            // Emit the {Approval} event.\n            log3(add(m, 0x60), 0x20, _APPROVAL_EVENT_SIGNATURE, owner, spender)\n            mstore(0x40, m) // Restore the free memory pointer.\n            mstore(0x60, 0) // Restore the zero pointer.\n        }\n    }\n\n    /// @dev Returns the EIP-712 domain separator for the EIP-2612 permit.\n    function DOMAIN_SEPARATOR() public view virtual returns (bytes32 result) {\n        bytes32 nameHash = _constantNameHash();\n        //  We simply calculate it on-the-fly to allow for cases where the `name` may change.\n        if (nameHash == bytes32(0)) nameHash = keccak256(bytes(name()));\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Grab the free memory pointer.\n            mstore(m, _DOMAIN_TYPEHASH)\n            mstore(add(m, 0x20), nameHash)\n            mstore(add(m, 0x40), _VERSION_HASH)\n            mstore(add(m, 0x60), chainid())\n            mstore(add(m, 0x80), address())\n            result := keccak256(m, 0xa0)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  INTERNAL MINT FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Mints `amount` tokens to `to`, increasing the total supply.\n    ///\n    /// Emits a {Transfer} event.\n    function _mint(address to, uint256 amount) internal virtual {\n        _beforeTokenTransfer(address(0), to, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let totalSupplyBefore := sload(_TOTAL_SUPPLY_SLOT)\n            let totalSupplyAfter := add(totalSupplyBefore, amount)\n            // Revert if the total supply overflows.\n            if lt(totalSupplyAfter, totalSupplyBefore) {\n                mstore(0x00, 0xe5cfe957) // `TotalSupplyOverflow()`.\n                revert(0x1c, 0x04)\n            }\n            // Store the updated total supply.\n            sstore(_TOTAL_SUPPLY_SLOT, totalSupplyAfter)\n            // Compute the balance slot and load its value.\n            mstore(0x0c, _BALANCE_SLOT_SEED)\n            mstore(0x00, to)\n            let toBalanceSlot := keccak256(0x0c, 0x20)\n            // Add and store the updated balance.\n            sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))\n            // Emit the {Transfer} event.\n            mstore(0x20, amount)\n            log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, 0, shr(96, mload(0x0c)))\n        }\n        _afterTokenTransfer(address(0), to, amount);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  INTERNAL BURN FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Burns `amount` tokens from `from`, reducing the total supply.\n    ///\n    /// Emits a {Transfer} event.\n    function _burn(address from, uint256 amount) internal virtual {\n        _beforeTokenTransfer(from, address(0), amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the balance slot and load its value.\n            mstore(0x0c, _BALANCE_SLOT_SEED)\n            mstore(0x00, from)\n            let fromBalanceSlot := keccak256(0x0c, 0x20)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Subtract and store the updated total supply.\n            sstore(_TOTAL_SUPPLY_SLOT, sub(sload(_TOTAL_SUPPLY_SLOT), amount))\n            // Emit the {Transfer} event.\n            mstore(0x00, amount)\n            log3(0x00, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, shl(96, from)), 0)\n        }\n        _afterTokenTransfer(from, address(0), amount);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                INTERNAL TRANSFER FUNCTIONS                 */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Moves `amount` of tokens from `from` to `to`.\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        _beforeTokenTransfer(from, to, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let from_ := shl(96, from)\n            // Compute the balance slot and load its value.\n            mstore(0x0c, or(from_, _BALANCE_SLOT_SEED))\n            let fromBalanceSlot := keccak256(0x0c, 0x20)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Compute the balance slot of `to`.\n            mstore(0x00, to)\n            let toBalanceSlot := keccak256(0x0c, 0x20)\n            // Add and store the updated balance of `to`.\n            // Will not overflow because the sum of all user balances\n            // cannot exceed the maximum uint256 value.\n            sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))\n            // Emit the {Transfer} event.\n            mstore(0x20, amount)\n            log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, from_), shr(96, mload(0x0c)))\n        }\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                INTERNAL ALLOWANCE FUNCTIONS                */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Updates the allowance of `owner` for `spender` based on spent `amount`.\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the allowance slot and load its value.\n            mstore(0x20, spender)\n            mstore(0x0c, _ALLOWANCE_SLOT_SEED)\n            mstore(0x00, owner)\n            let allowanceSlot := keccak256(0x0c, 0x34)\n            let allowance_ := sload(allowanceSlot)\n            // If the allowance is not the maximum uint256 value.\n            if add(allowance_, 1) {\n                // Revert if the amount to be transferred exceeds the allowance.\n                if gt(amount, allowance_) {\n                    mstore(0x00, 0x13be252b) // `InsufficientAllowance()`.\n                    revert(0x1c, 0x04)\n                }\n                // Subtract and store the updated allowance.\n                sstore(allowanceSlot, sub(allowance_, amount))\n            }\n        }\n    }\n\n    /// @dev Sets `amount` as the allowance of `spender` over the tokens of `owner`.\n    ///\n    /// Emits a {Approval} event.\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let owner_ := shl(96, owner)\n            // Compute the allowance slot and store the amount.\n            mstore(0x20, spender)\n            mstore(0x0c, or(owner_, _ALLOWANCE_SLOT_SEED))\n            sstore(keccak256(0x0c, 0x34), amount)\n            // Emit the {Approval} event.\n            mstore(0x00, amount)\n            log3(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, shr(96, owner_), shr(96, mload(0x2c)))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     HOOKS TO OVERRIDE                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Hook that is called before any transfer of tokens.\n    /// This includes minting and burning.\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /// @dev Hook that is called after any transfer of tokens.\n    /// This includes minting and burning.\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"},"ICheezburger.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.22;\n\nimport {CheezburgerStructs} from \"./CheezburgerStructs.sol\";\n\ninterface ICheezburger is CheezburgerStructs {\n    function socialTokens(\n        uint256 id\n    )\n        external\n        view\n        returns (\n            address,\n            address,\n            address,\n            address,\n            address,\n            address,\n            LiquiditySettings calldata,\n            DynamicSettings calldata,\n            DynamicSettings calldata,\n            ReferralSettings calldata\n        );\n\n    function withdrawFeesOf(\n        uint256 _userId,\n        address _to\n    ) external returns (uint256);\n}\n"},"ICheezburgerFactory.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.22;\n\nimport {CheezburgerStructs} from \"./CheezburgerStructs.sol\";\n\ninterface ICheezburgerFactory is CheezburgerStructs {\n    function deployWithToken(\n        TokenCustomization memory _customization,\n        address _router,\n        address _rightSide,\n        uint256 _rightSideAmount,\n        LiquiditySettings memory _liquidity,\n        DynamicSettings memory _fee,\n        DynamicSettings memory _wallet,\n        ReferralSettings memory _referral\n    ) external returns (address);\n\n    function burgerRegistry(\n        address token\n    )\n        external\n        view\n        returns (\n            address,\n            address,\n            address,\n            address,\n            address,\n            address,\n            LiquiditySettings calldata,\n            DynamicSettings calldata,\n            DynamicSettings calldata,\n            ReferralSettings calldata\n        );\n}\n"},"LibString.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Library for converting numbers into strings and other string operations.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol)\nlibrary LibString {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                        CUSTOM ERRORS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The `length` of the output is too small to contain all the hex digits.\n    error HexLengthInsufficient();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The constant returned when the `search` is not found in the string.\n    uint256 internal constant NOT_FOUND = type(uint256).max;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     DECIMAL OPERATIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the base 10 decimal representation of `value`.\n    function toString(uint256 value) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but\n            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.\n            // We will need 1 word for the trailing zeros padding, 1 word for the length,\n            // and 3 words for a maximum of 78 digits.\n            str := add(mload(0x40), 0x80)\n            // Update the free memory pointer to allocate.\n            mstore(0x40, add(str, 0x20))\n            // Zeroize the slot after the string.\n            mstore(str, 0)\n\n            // Cache the end of the memory to calculate the length later.\n            let end := str\n\n            let w := not(0) // Tsk.\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let temp := value } 1 {} {\n                str := add(str, w) // `sub(str, 1)`.\n                // Write the character to the pointer.\n                // The ASCII index of the \u00270\u0027 character is 48.\n                mstore8(str, add(48, mod(temp, 10)))\n                // Keep dividing `temp` until zero.\n                temp := div(temp, 10)\n                if iszero(temp) { break }\n            }\n\n            let length := sub(end, str)\n            // Move the pointer 32 bytes leftwards to make room for the length.\n            str := sub(str, 0x20)\n            // Store the length.\n            mstore(str, length)\n        }\n    }\n\n    /// @dev Returns the base 10 decimal representation of `value`.\n    function toString(int256 value) internal pure returns (string memory str) {\n        if (value \u003e= 0) {\n            return toString(uint256(value));\n        }\n        unchecked {\n            str = toString(uint256(-value));\n        }\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We still have some spare memory space on the left,\n            // as we have allocated 3 words (96 bytes) for up to 78 digits.\n            let length := mload(str) // Load the string length.\n            mstore(str, 0x2d) // Store the \u0027-\u0027 character.\n            str := sub(str, 1) // Move back the string pointer by a byte.\n            mstore(str, add(length, 1)) // Update the string length.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   HEXADECIMAL OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the hexadecimal representation of `value`,\n    /// left-padded to an input length of `length` bytes.\n    /// The output is prefixed with \"0x\" encoded using 2 hexadecimal digits per byte,\n    /// giving a total length of `length * 2 + 2` bytes.\n    /// Reverts if `length` is too small for the output to contain all the digits.\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value, length);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`,\n    /// left-padded to an input length of `length` bytes.\n    /// The output is prefixed with \"0x\" encoded using 2 hexadecimal digits per byte,\n    /// giving a total length of `length * 2` bytes.\n    /// Reverts if `length` is too small for the output to contain all the digits.\n    function toHexStringNoPrefix(uint256 value, uint256 length)\n        internal\n        pure\n        returns (string memory str)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We need 0x20 bytes for the trailing zeros padding, `length * 2` bytes\n            // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length.\n            // We add 0x20 to the total and round down to a multiple of 0x20.\n            // (0x20 + 0x20 + 0x02 + 0x20) = 0x62.\n            str := add(mload(0x40), and(add(shl(1, length), 0x42), not(0x1f)))\n            // Allocate the memory.\n            mstore(0x40, add(str, 0x20))\n            // Zeroize the slot after the string.\n            mstore(str, 0)\n\n            // Cache the end to calculate the length later.\n            let end := str\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            let start := sub(str, add(length, length))\n            let w := not(1) // Tsk.\n            let temp := value\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for {} 1 {} {\n                str := add(str, w) // `sub(str, 2)`.\n                mstore8(add(str, 1), mload(and(temp, 15)))\n                mstore8(str, mload(and(shr(4, temp), 15)))\n                temp := shr(8, temp)\n                if iszero(xor(str, start)) { break }\n            }\n\n            if temp {\n                // Store the function selector of `HexLengthInsufficient()`.\n                mstore(0x00, 0x2194895a)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n\n            // Compute the string\u0027s length.\n            let strLength := sub(end, str)\n            // Move the pointer and write the length.\n            str := sub(str, 0x20)\n            mstore(str, strLength)\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\" and encoded using 2 hexadecimal digits per byte.\n    /// As address are 20 bytes long, the output will left-padded to have\n    /// a length of `20 * 2 + 2` bytes.\n    function toHexString(uint256 value) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\".\n    /// The output excludes leading \"0\" from the `toHexString` output.\n    /// `0x00: \"0x0\", 0x01: \"0x1\", 0x12: \"0x12\", 0x123: \"0x123\"`.\n    function toMinimalHexString(uint256 value) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let o := eq(byte(0, mload(add(str, 0x20))), 0x30) // Whether leading zero is present.\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(add(str, o), 0x3078) // Write the \"0x\" prefix, accounting for leading zero.\n            str := sub(add(str, o), 2) // Move the pointer, accounting for leading zero.\n            mstore(str, sub(strLength, o)) // Write the length, accounting for leading zero.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output excludes leading \"0\" from the `toHexStringNoPrefix` output.\n    /// `0x00: \"0\", 0x01: \"1\", 0x12: \"12\", 0x123: \"123\"`.\n    function toMinimalHexStringNoPrefix(uint256 value) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let o := eq(byte(0, mload(add(str, 0x20))), 0x30) // Whether leading zero is present.\n            let strLength := mload(str) // Get the length.\n            str := add(str, o) // Move the pointer, accounting for leading zero.\n            mstore(str, sub(strLength, o)) // Write the length, accounting for leading zero.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    /// As address are 20 bytes long, the output will left-padded to have\n    /// a length of `20 * 2` bytes.\n    function toHexStringNoPrefix(uint256 value) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,\n            // 0x02 bytes for the prefix, and 0x40 bytes for the digits.\n            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0.\n            str := add(mload(0x40), 0x80)\n            // Allocate the memory.\n            mstore(0x40, add(str, 0x20))\n            // Zeroize the slot after the string.\n            mstore(str, 0)\n\n            // Cache the end to calculate the length later.\n            let end := str\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            let w := not(1) // Tsk.\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let temp := value } 1 {} {\n                str := add(str, w) // `sub(str, 2)`.\n                mstore8(add(str, 1), mload(and(temp, 15)))\n                mstore8(str, mload(and(shr(4, temp), 15)))\n                temp := shr(8, temp)\n                if iszero(temp) { break }\n            }\n\n            // Compute the string\u0027s length.\n            let strLength := sub(end, str)\n            // Move the pointer and write the length.\n            str := sub(str, 0x20)\n            mstore(str, strLength)\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\", encoded using 2 hexadecimal digits per byte,\n    /// and the alphabets are capitalized conditionally according to\n    /// https://eips.ethereum.org/EIPS/eip-55\n    function toHexStringChecksummed(address value) internal pure returns (string memory str) {\n        str = toHexString(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...`\n            let o := add(str, 0x22)\n            let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... `\n            let t := shl(240, 136) // `0b10001000 \u003c\u003c 240`\n            for { let i := 0 } 1 {} {\n                mstore(add(i, i), mul(t, byte(i, hashed)))\n                i := add(i, 1)\n                if eq(i, 20) { break }\n            }\n            mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask)))))\n            o := add(o, 0x20)\n            mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask)))))\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\" and encoded using 2 hexadecimal digits per byte.\n    function toHexString(address value) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(address value) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            str := mload(0x40)\n\n            // Allocate the memory.\n            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,\n            // 0x02 bytes for the prefix, and 0x28 bytes for the digits.\n            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80.\n            mstore(0x40, add(str, 0x80))\n\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            str := add(str, 2)\n            mstore(str, 40)\n\n            let o := add(str, 0x20)\n            mstore(add(o, 40), 0)\n\n            value := shl(96, value)\n\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let i := 0 } 1 {} {\n                let p := add(o, add(i, i))\n                let temp := byte(i, value)\n                mstore8(add(p, 1), mload(and(temp, 15)))\n                mstore8(p, mload(shr(4, temp)))\n                i := add(i, 1)\n                if eq(i, 20) { break }\n            }\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexString(bytes memory raw) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(raw);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let length := mload(raw)\n            str := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix.\n            mstore(str, add(length, length)) // Store the length of the output.\n\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            let o := add(str, 0x20)\n            let end := add(raw, length)\n\n            for {} iszero(eq(raw, end)) {} {\n                raw := add(raw, 1)\n                mstore8(add(o, 1), mload(and(mload(raw), 15)))\n                mstore8(o, mload(and(shr(4, mload(raw)), 15)))\n                o := add(o, 2)\n            }\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(0x40, add(o, 0x20)) // Allocate the memory.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   RUNE STRING OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the number of UTF characters in the string.\n    function runeCount(string memory s) internal pure returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if mload(s) {\n                mstore(0x00, div(not(0), 255))\n                mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506)\n                let o := add(s, 0x20)\n                let end := add(o, mload(s))\n                for { result := 1 } 1 { result := add(result, 1) } {\n                    o := add(o, byte(0, mload(shr(250, mload(o)))))\n                    if iszero(lt(o, end)) { break }\n                }\n            }\n        }\n    }\n\n    /// @dev Returns if this string is a 7-bit ASCII string.\n    /// (i.e. all characters codes are in [0..127])\n    function is7BitASCII(string memory s) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let mask := shl(7, div(not(0), 255))\n            result := 1\n            let n := mload(s)\n            if n {\n                let o := add(s, 0x20)\n                let end := add(o, n)\n                let last := mload(end)\n                mstore(end, 0)\n                for {} 1 {} {\n                    if and(mask, mload(o)) {\n                        result := 0\n                        break\n                    }\n                    o := add(o, 0x20)\n                    if iszero(lt(o, end)) { break }\n                }\n                mstore(end, last)\n            }\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   BYTE STRING OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // For performance and bytecode compactness, all indices of the following operations\n    // are byte (ASCII) offsets, not UTF character offsets.\n\n    /// @dev Returns `subject` all occurrences of `search` replaced with `replacement`.\n    function replace(string memory subject, string memory search, string memory replacement)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let subjectLength := mload(subject)\n            let searchLength := mload(search)\n            let replacementLength := mload(replacement)\n\n            subject := add(subject, 0x20)\n            search := add(search, 0x20)\n            replacement := add(replacement, 0x20)\n            result := add(mload(0x40), 0x20)\n\n            let subjectEnd := add(subject, subjectLength)\n            if iszero(gt(searchLength, subjectLength)) {\n                let subjectSearchEnd := add(sub(subjectEnd, searchLength), 1)\n                let h := 0\n                if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) }\n                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))\n                let s := mload(search)\n                for {} 1 {} {\n                    let t := mload(subject)\n                    // Whether the first `searchLength % 32` bytes of\n                    // `subject` and `search` matches.\n                    if iszero(shr(m, xor(t, s))) {\n                        if h {\n                            if iszero(eq(keccak256(subject, searchLength), h)) {\n                                mstore(result, t)\n                                result := add(result, 1)\n                                subject := add(subject, 1)\n                                if iszero(lt(subject, subjectSearchEnd)) { break }\n                                continue\n                            }\n                        }\n                        // Copy the `replacement` one word at a time.\n                        for { let o := 0 } 1 {} {\n                            mstore(add(result, o), mload(add(replacement, o)))\n                            o := add(o, 0x20)\n                            if iszero(lt(o, replacementLength)) { break }\n                        }\n                        result := add(result, replacementLength)\n                        subject := add(subject, searchLength)\n                        if searchLength {\n                            if iszero(lt(subject, subjectSearchEnd)) { break }\n                            continue\n                        }\n                    }\n                    mstore(result, t)\n                    result := add(result, 1)\n                    subject := add(subject, 1)\n                    if iszero(lt(subject, subjectSearchEnd)) { break }\n                }\n            }\n\n            let resultRemainder := result\n            result := add(mload(0x40), 0x20)\n            let k := add(sub(resultRemainder, result), sub(subjectEnd, subject))\n            // Copy the rest of the string one word at a time.\n            for {} lt(subject, subjectEnd) {} {\n                mstore(resultRemainder, mload(subject))\n                resultRemainder := add(resultRemainder, 0x20)\n                subject := add(subject, 0x20)\n            }\n            result := sub(result, 0x20)\n            let last := add(add(result, 0x20), k) // Zeroize the slot after the string.\n            mstore(last, 0)\n            mstore(0x40, add(last, 0x20)) // Allocate the memory.\n            mstore(result, k) // Store the length.\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `search` in `subject`,\n    /// searching from left to right, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.\n    function indexOf(string memory subject, string memory search, uint256 from)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for { let subjectLength := mload(subject) } 1 {} {\n                if iszero(mload(search)) {\n                    if iszero(gt(from, subjectLength)) {\n                        result := from\n                        break\n                    }\n                    result := subjectLength\n                    break\n                }\n                let searchLength := mload(search)\n                let subjectStart := add(subject, 0x20)\n\n                result := not(0) // Initialize to `NOT_FOUND`.\n\n                subject := add(subjectStart, from)\n                let end := add(sub(add(subjectStart, subjectLength), searchLength), 1)\n\n                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))\n                let s := mload(add(search, 0x20))\n\n                if iszero(and(lt(subject, end), lt(from, subjectLength))) { break }\n\n                if iszero(lt(searchLength, 0x20)) {\n                    for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {\n                        if iszero(shr(m, xor(mload(subject), s))) {\n                            if eq(keccak256(subject, searchLength), h) {\n                                result := sub(subject, subjectStart)\n                                break\n                            }\n                        }\n                        subject := add(subject, 1)\n                        if iszero(lt(subject, end)) { break }\n                    }\n                    break\n                }\n                for {} 1 {} {\n                    if iszero(shr(m, xor(mload(subject), s))) {\n                        result := sub(subject, subjectStart)\n                        break\n                    }\n                    subject := add(subject, 1)\n                    if iszero(lt(subject, end)) { break }\n                }\n                break\n            }\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `search` in `subject`,\n    /// searching from left to right.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.\n    function indexOf(string memory subject, string memory search)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        result = indexOf(subject, search, 0);\n    }\n\n    /// @dev Returns the byte index of the first location of `search` in `subject`,\n    /// searching from right to left, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.\n    function lastIndexOf(string memory subject, string memory search, uint256 from)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for {} 1 {} {\n                result := not(0) // Initialize to `NOT_FOUND`.\n                let searchLength := mload(search)\n                if gt(searchLength, mload(subject)) { break }\n                let w := result\n\n                let fromMax := sub(mload(subject), searchLength)\n                if iszero(gt(fromMax, from)) { from := fromMax }\n\n                let end := add(add(subject, 0x20), w)\n                subject := add(add(subject, 0x20), from)\n                if iszero(gt(subject, end)) { break }\n                // As this function is not too often used,\n                // we shall simply use keccak256 for smaller bytecode size.\n                for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {\n                    if eq(keccak256(subject, searchLength), h) {\n                        result := sub(subject, add(end, 1))\n                        break\n                    }\n                    subject := add(subject, w) // `sub(subject, 1)`.\n                    if iszero(gt(subject, end)) { break }\n                }\n                break\n            }\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `search` in `subject`,\n    /// searching from right to left.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.\n    function lastIndexOf(string memory subject, string memory search)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        result = lastIndexOf(subject, search, uint256(int256(-1)));\n    }\n\n    /// @dev Returns whether `subject` starts with `search`.\n    function startsWith(string memory subject, string memory search)\n        internal\n        pure\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let searchLength := mload(search)\n            // Just using keccak256 directly is actually cheaper.\n            // forgefmt: disable-next-item\n            result := and(\n                iszero(gt(searchLength, mload(subject))),\n                eq(\n                    keccak256(add(subject, 0x20), searchLength),\n                    keccak256(add(search, 0x20), searchLength)\n                )\n            )\n        }\n    }\n\n    /// @dev Returns whether `subject` ends with `search`.\n    function endsWith(string memory subject, string memory search)\n        internal\n        pure\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let searchLength := mload(search)\n            let subjectLength := mload(subject)\n            // Whether `search` is not longer than `subject`.\n            let withinRange := iszero(gt(searchLength, subjectLength))\n            // Just using keccak256 directly is actually cheaper.\n            // forgefmt: disable-next-item\n            result := and(\n                withinRange,\n                eq(\n                    keccak256(\n                        // `subject + 0x20 + max(subjectLength - searchLength, 0)`.\n                        add(add(subject, 0x20), mul(withinRange, sub(subjectLength, searchLength))),\n                        searchLength\n                    ),\n                    keccak256(add(search, 0x20), searchLength)\n                )\n            )\n        }\n    }\n\n    /// @dev Returns `subject` repeated `times`.\n    function repeat(string memory subject, uint256 times)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let subjectLength := mload(subject)\n            if iszero(or(iszero(times), iszero(subjectLength))) {\n                subject := add(subject, 0x20)\n                result := mload(0x40)\n                let output := add(result, 0x20)\n                for {} 1 {} {\n                    // Copy the `subject` one word at a time.\n                    for { let o := 0 } 1 {} {\n                        mstore(add(output, o), mload(add(subject, o)))\n                        o := add(o, 0x20)\n                        if iszero(lt(o, subjectLength)) { break }\n                    }\n                    output := add(output, subjectLength)\n                    times := sub(times, 1)\n                    if iszero(times) { break }\n                }\n                mstore(output, 0) // Zeroize the slot after the string.\n                let resultLength := sub(output, add(result, 0x20))\n                mstore(result, resultLength) // Store the length.\n                // Allocate the memory.\n                mstore(0x40, add(result, add(resultLength, 0x20)))\n            }\n        }\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).\n    /// `start` and `end` are byte offsets.\n    function slice(string memory subject, uint256 start, uint256 end)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let subjectLength := mload(subject)\n            if iszero(gt(subjectLength, end)) { end := subjectLength }\n            if iszero(gt(subjectLength, start)) { start := subjectLength }\n            if lt(start, end) {\n                result := mload(0x40)\n                let resultLength := sub(end, start)\n                mstore(result, resultLength)\n                subject := add(subject, start)\n                let w := not(0x1f)\n                // Copy the `subject` one word at a time, backwards.\n                for { let o := and(add(resultLength, 0x1f), w) } 1 {} {\n                    mstore(add(result, o), mload(add(subject, o)))\n                    o := add(o, w) // `sub(o, 0x20)`.\n                    if iszero(o) { break }\n                }\n                // Zeroize the slot after the string.\n                mstore(add(add(result, 0x20), resultLength), 0)\n                // Allocate memory for the length and the bytes,\n                // rounded up to a multiple of 32.\n                mstore(0x40, add(result, and(add(resultLength, 0x3f), w)))\n            }\n        }\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to the end of the string.\n    /// `start` is a byte offset.\n    function slice(string memory subject, uint256 start)\n        internal\n        pure\n        returns (string memory result)\n    {\n        result = slice(subject, start, uint256(int256(-1)));\n    }\n\n    /// @dev Returns all the indices of `search` in `subject`.\n    /// The indices are byte offsets.\n    function indicesOf(string memory subject, string memory search)\n        internal\n        pure\n        returns (uint256[] memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let subjectLength := mload(subject)\n            let searchLength := mload(search)\n\n            if iszero(gt(searchLength, subjectLength)) {\n                subject := add(subject, 0x20)\n                search := add(search, 0x20)\n                result := add(mload(0x40), 0x20)\n\n                let subjectStart := subject\n                let subjectSearchEnd := add(sub(add(subject, subjectLength), searchLength), 1)\n                let h := 0\n                if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) }\n                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))\n                let s := mload(search)\n                for {} 1 {} {\n                    let t := mload(subject)\n                    // Whether the first `searchLength % 32` bytes of\n                    // `subject` and `search` matches.\n                    if iszero(shr(m, xor(t, s))) {\n                        if h {\n                            if iszero(eq(keccak256(subject, searchLength), h)) {\n                                subject := add(subject, 1)\n                                if iszero(lt(subject, subjectSearchEnd)) { break }\n                                continue\n                            }\n                        }\n                        // Append to `result`.\n                        mstore(result, sub(subject, subjectStart))\n                        result := add(result, 0x20)\n                        // Advance `subject` by `searchLength`.\n                        subject := add(subject, searchLength)\n                        if searchLength {\n                            if iszero(lt(subject, subjectSearchEnd)) { break }\n                            continue\n                        }\n                    }\n                    subject := add(subject, 1)\n                    if iszero(lt(subject, subjectSearchEnd)) { break }\n                }\n                let resultEnd := result\n                // Assign `result` to the free memory pointer.\n                result := mload(0x40)\n                // Store the length of `result`.\n                mstore(result, shr(5, sub(resultEnd, add(result, 0x20))))\n                // Allocate memory for result.\n                // We allocate one more word, so this array can be recycled for {split}.\n                mstore(0x40, add(resultEnd, 0x20))\n            }\n        }\n    }\n\n    /// @dev Returns a arrays of strings based on the `delimiter` inside of the `subject` string.\n    function split(string memory subject, string memory delimiter)\n        internal\n        pure\n        returns (string[] memory result)\n    {\n        uint256[] memory indices = indicesOf(subject, delimiter);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let w := not(0x1f)\n            let indexPtr := add(indices, 0x20)\n            let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1)))\n            mstore(add(indicesEnd, w), mload(subject))\n            mstore(indices, add(mload(indices), 1))\n            let prevIndex := 0\n            for {} 1 {} {\n                let index := mload(indexPtr)\n                mstore(indexPtr, 0x60)\n                if iszero(eq(index, prevIndex)) {\n                    let element := mload(0x40)\n                    let elementLength := sub(index, prevIndex)\n                    mstore(element, elementLength)\n                    // Copy the `subject` one word at a time, backwards.\n                    for { let o := and(add(elementLength, 0x1f), w) } 1 {} {\n                        mstore(add(element, o), mload(add(add(subject, prevIndex), o)))\n                        o := add(o, w) // `sub(o, 0x20)`.\n                        if iszero(o) { break }\n                    }\n                    // Zeroize the slot after the string.\n                    mstore(add(add(element, 0x20), elementLength), 0)\n                    // Allocate memory for the length and the bytes,\n                    // rounded up to a multiple of 32.\n                    mstore(0x40, add(element, and(add(elementLength, 0x3f), w)))\n                    // Store the `element` into the array.\n                    mstore(indexPtr, element)\n                }\n                prevIndex := add(index, mload(delimiter))\n                indexPtr := add(indexPtr, 0x20)\n                if iszero(lt(indexPtr, indicesEnd)) { break }\n            }\n            result := indices\n            if iszero(mload(delimiter)) {\n                result := add(indices, 0x20)\n                mstore(result, sub(mload(indices), 2))\n            }\n        }\n    }\n\n    /// @dev Returns a concatenated string of `a` and `b`.\n    /// Cheaper than `string.concat()` and does not de-align the free memory pointer.\n    function concat(string memory a, string memory b)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let w := not(0x1f)\n            result := mload(0x40)\n            let aLength := mload(a)\n            // Copy `a` one word at a time, backwards.\n            for { let o := and(add(aLength, 0x20), w) } 1 {} {\n                mstore(add(result, o), mload(add(a, o)))\n                o := add(o, w) // `sub(o, 0x20)`.\n                if iszero(o) { break }\n            }\n            let bLength := mload(b)\n            let output := add(result, aLength)\n            // Copy `b` one word at a time, backwards.\n            for { let o := and(add(bLength, 0x20), w) } 1 {} {\n                mstore(add(output, o), mload(add(b, o)))\n                o := add(o, w) // `sub(o, 0x20)`.\n                if iszero(o) { break }\n            }\n            let totalLength := add(aLength, bLength)\n            let last := add(add(result, 0x20), totalLength)\n            // Zeroize the slot after the string.\n            mstore(last, 0)\n            // Stores the length.\n            mstore(result, totalLength)\n            // Allocate memory for the length and the bytes,\n            // rounded up to a multiple of 32.\n            mstore(0x40, and(add(last, 0x1f), w))\n        }\n    }\n\n    /// @dev Returns a copy of the string in either lowercase or UPPERCASE.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function toCase(string memory subject, bool toUpper)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let length := mload(subject)\n            if length {\n                result := add(mload(0x40), 0x20)\n                subject := add(subject, 1)\n                let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff)\n                let w := not(0)\n                for { let o := length } 1 {} {\n                    o := add(o, w)\n                    let b := and(0xff, mload(add(subject, o)))\n                    mstore8(add(result, o), xor(b, and(shr(b, flags), 0x20)))\n                    if iszero(o) { break }\n                }\n                result := mload(0x40)\n                mstore(result, length) // Store the length.\n                let last := add(add(result, 0x20), length)\n                mstore(last, 0) // Zeroize the slot after the string.\n                mstore(0x40, add(last, 0x20)) // Allocate the memory.\n            }\n        }\n    }\n\n    /// @dev Returns a string from a small bytes32 string.\n    /// `smallString` must be null terminated, or behavior will be undefined.\n    function fromSmallString(bytes32 smallString) internal pure returns (string memory result) {\n        if (smallString == bytes32(0)) return result;\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let n := 0\n            for {} 1 {} {\n                n := add(n, 1)\n                if iszero(byte(n, smallString)) { break } // Scan for \u0027\\0\u0027.\n            }\n            mstore(result, n)\n            let o := add(result, 0x20)\n            mstore(o, smallString)\n            mstore(add(o, n), 0)\n            mstore(0x40, add(result, 0x40))\n        }\n    }\n\n    /// @dev Returns a lowercased copy of the string.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function lower(string memory subject) internal pure returns (string memory result) {\n        result = toCase(subject, false);\n    }\n\n    /// @dev Returns an UPPERCASED copy of the string.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function upper(string memory subject) internal pure returns (string memory result) {\n        result = toCase(subject, true);\n    }\n\n    /// @dev Escapes the string to be used within HTML tags.\n    function escapeHTML(string memory s) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let end := add(s, mload(s))\n            result := add(mload(0x40), 0x20)\n            // Store the bytes of the packed offsets and strides into the scratch space.\n            // `packed = (stride \u003c\u003c 5) | offset`. Max offset is 20. Max stride is 6.\n            mstore(0x1f, 0x900094)\n            mstore(0x08, 0xc0000000a6ab)\n            // Store \"\u0026quot;\u0026amp;\u0026#39;\u0026lt;\u0026gt;\" into the scratch space.\n            mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b))\n            for {} iszero(eq(s, end)) {} {\n                s := add(s, 1)\n                let c := and(mload(s), 0xff)\n                // Not in `[\"\\\"\",\"\u0027\",\"\u0026\",\"\u003c\",\"\u003e\"]`.\n                if iszero(and(shl(c, 1), 0x500000c400000000)) {\n                    mstore8(result, c)\n                    result := add(result, 1)\n                    continue\n                }\n                let t := shr(248, mload(c))\n                mstore(result, mload(and(t, 0x1f)))\n                result := add(result, shr(5, t))\n            }\n            let last := result\n            mstore(last, 0) // Zeroize the slot after the string.\n            result := mload(0x40)\n            mstore(result, sub(last, add(result, 0x20))) // Store the length.\n            mstore(0x40, add(last, 0x20)) // Allocate the memory.\n        }\n    }\n\n    /// @dev Escapes the string to be used within double-quotes in a JSON.\n    /// If `addDoubleQuotes` is true, the result will be enclosed in double-quotes.\n    function escapeJSON(string memory s, bool addDoubleQuotes)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let end := add(s, mload(s))\n            result := add(mload(0x40), 0x20)\n            if addDoubleQuotes {\n                mstore8(result, 34)\n                result := add(1, result)\n            }\n            // Store \"\\\\u0000\" in scratch space.\n            // Store \"0123456789abcdef\" in scratch space.\n            // Also, store `{0x08:\"b\", 0x09:\"t\", 0x0a:\"n\", 0x0c:\"f\", 0x0d:\"r\"}`.\n            // into the scratch space.\n            mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672)\n            // Bitmask for detecting `[\"\\\"\",\"\\\\\"]`.\n            let e := or(shl(0x22, 1), shl(0x5c, 1))\n            for {} iszero(eq(s, end)) {} {\n                s := add(s, 1)\n                let c := and(mload(s), 0xff)\n                if iszero(lt(c, 0x20)) {\n                    if iszero(and(shl(c, 1), e)) {\n                        // Not in `[\"\\\"\",\"\\\\\"]`.\n                        mstore8(result, c)\n                        result := add(result, 1)\n                        continue\n                    }\n                    mstore8(result, 0x5c) // \"\\\\\".\n                    mstore8(add(result, 1), c)\n                    result := add(result, 2)\n                    continue\n                }\n                if iszero(and(shl(c, 1), 0x3700)) {\n                    // Not in `[\"\\b\",\"\\t\",\"\\n\",\"\\f\",\"\\d\"]`.\n                    mstore8(0x1d, mload(shr(4, c))) // Hex value.\n                    mstore8(0x1e, mload(and(c, 15))) // Hex value.\n                    mstore(result, mload(0x19)) // \"\\\\u00XX\".\n                    result := add(result, 6)\n                    continue\n                }\n                mstore8(result, 0x5c) // \"\\\\\".\n                mstore8(add(result, 1), mload(add(c, 8)))\n                result := add(result, 2)\n            }\n            if addDoubleQuotes {\n                mstore8(result, 34)\n                result := add(1, result)\n            }\n            let last := result\n            mstore(last, 0) // Zeroize the slot after the string.\n            result := mload(0x40)\n            mstore(result, sub(last, add(result, 0x20))) // Store the length.\n            mstore(0x40, add(last, 0x20)) // Allocate the memory.\n        }\n    }\n\n    /// @dev Escapes the string to be used within double-quotes in a JSON.\n    function escapeJSON(string memory s) internal pure returns (string memory result) {\n        result = escapeJSON(s, false);\n    }\n\n    /// @dev Returns whether `a` equals `b`.\n    function eq(string memory a, string memory b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b)))\n        }\n    }\n\n    /// @dev Returns whether `a` equals `b`. For small strings up to 32 bytes.\n    /// `b` must be null terminated, or behavior will be undefined.\n    function eqs(string memory a, bytes32 b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // These should be evaluated on compile time, as far as possible.\n            let x := and(b, add(not(b), 1))\n            let r := or(shl(8, iszero(b)), shl(7, iszero(iszero(shr(128, x)))))\n            r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x))))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\n            result := gt(eq(mload(a), sub(32, shr(3, r))), shr(r, xor(b, mload(add(a, 0x20)))))\n        }\n    }\n\n    /// @dev Packs a single string with its length into a single word.\n    /// Returns `bytes32(0)` if the length is zero or greater than 31.\n    function packOne(string memory a) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We don\u0027t need to zero right pad the string,\n            // since this is our own custom non-standard packing scheme.\n            result :=\n                mul(\n                    // Load the length and the bytes.\n                    mload(add(a, 0x1f)),\n                    // `length != 0 \u0026\u0026 length \u003c 32`. Abuses underflow.\n                    // Assumes that the length is valid and within the block gas limit.\n                    lt(sub(mload(a), 1), 0x1f)\n                )\n        }\n    }\n\n    /// @dev Unpacks a string packed using {packOne}.\n    /// Returns the empty string if `packed` is `bytes32(0)`.\n    /// If `packed` is not an output of {packOne}, the output behavior is undefined.\n    function unpackOne(bytes32 packed) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Grab the free memory pointer.\n            result := mload(0x40)\n            // Allocate 2 words (1 for the length, 1 for the bytes).\n            mstore(0x40, add(result, 0x40))\n            // Zeroize the length slot.\n            mstore(result, 0)\n            // Store the length and bytes.\n            mstore(add(result, 0x1f), packed)\n            // Right pad with zeroes.\n            mstore(add(add(result, 0x20), mload(result)), 0)\n        }\n    }\n\n    /// @dev Packs two strings with their lengths into a single word.\n    /// Returns `bytes32(0)` if combined length is zero or greater than 30.\n    function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let aLength := mload(a)\n            // We don\u0027t need to zero right pad the strings,\n            // since this is our own custom non-standard packing scheme.\n            result :=\n                mul(\n                    // Load the length and the bytes of `a` and `b`.\n                    or(\n                        shl(shl(3, sub(0x1f, aLength)), mload(add(a, aLength))),\n                        mload(sub(add(b, 0x1e), aLength))\n                    ),\n                    // `totalLength != 0 \u0026\u0026 totalLength \u003c 31`. Abuses underflow.\n                    // Assumes that the lengths are valid and within the block gas limit.\n                    lt(sub(add(aLength, mload(b)), 1), 0x1e)\n                )\n        }\n    }\n\n    /// @dev Unpacks strings packed using {packTwo}.\n    /// Returns the empty strings if `packed` is `bytes32(0)`.\n    /// If `packed` is not an output of {packTwo}, the output behavior is undefined.\n    function unpackTwo(bytes32 packed)\n        internal\n        pure\n        returns (string memory resultA, string memory resultB)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Grab the free memory pointer.\n            resultA := mload(0x40)\n            resultB := add(resultA, 0x40)\n            // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words.\n            mstore(0x40, add(resultB, 0x40))\n            // Zeroize the length slots.\n            mstore(resultA, 0)\n            mstore(resultB, 0)\n            // Store the lengths and bytes.\n            mstore(add(resultA, 0x1f), packed)\n            mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA))))\n            // Right pad with zeroes.\n            mstore(add(add(resultA, 0x20), mload(resultA)), 0)\n            mstore(add(add(resultB, 0x20), mload(resultB)), 0)\n        }\n    }\n\n    /// @dev Directly returns `a` without copying.\n    function directReturn(string memory a) internal pure {\n        assembly {\n            // Assumes that the string does not start from the scratch space.\n            let retStart := sub(a, 0x20)\n            let retSize := add(mload(a), 0x40)\n            // Right pad with zeroes. Just in case the string is produced\n            // by a method that doesn\u0027t zero right pad.\n            mstore(add(retStart, retSize), 0)\n            // Store the return offset.\n            mstore(retStart, 0x20)\n            // End the transaction, returning the string.\n            return(retStart, retSize)\n        }\n    }\n}\n"},"Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)\n///\n/// @dev Note:\n/// This implementation does NOT auto-initialize the owner to `msg.sender`.\n/// You MUST call the `_initializeOwner` in the constructor / initializer.\n///\n/// While the ownable portion follows\n/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,\n/// the nomenclature for the 2-step ownership handover may be unique to this codebase.\nabstract contract Ownable {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The caller is not authorized to call the function.\n    error Unauthorized();\n\n    /// @dev The `newOwner` cannot be the zero address.\n    error NewOwnerIsZeroAddress();\n\n    /// @dev The `pendingOwner` does not have a valid handover request.\n    error NoHandoverRequest();\n\n    /// @dev Cannot double-initialize.\n    error AlreadyInitialized();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.\n    /// This event is intentionally kept the same as OpenZeppelin\u0027s Ownable to be\n    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),\n    /// despite it not being as lightweight as a single argument event.\n    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);\n\n    /// @dev An ownership handover to `pendingOwner` has been requested.\n    event OwnershipHandoverRequested(address indexed pendingOwner);\n\n    /// @dev The ownership handover to `pendingOwner` has been canceled.\n    event OwnershipHandoverCanceled(address indexed pendingOwner);\n\n    /// @dev `keccak256(bytes(\"OwnershipTransferred(address,address)\"))`.\n    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =\n        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;\n\n    /// @dev `keccak256(bytes(\"OwnershipHandoverRequested(address)\"))`.\n    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =\n        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;\n\n    /// @dev `keccak256(bytes(\"OwnershipHandoverCanceled(address)\"))`.\n    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =\n        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The owner slot is given by:\n    /// `bytes32(~uint256(uint32(bytes4(keccak256(\"_OWNER_SLOT_NOT\")))))`.\n    /// It is intentionally chosen to be a high value\n    /// to avoid collision with lower slots.\n    /// The choice of manual storage layout is to enable compatibility\n    /// with both regular and upgradeable contracts.\n    bytes32 internal constant _OWNER_SLOT =\n        0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;\n\n    /// The ownership handover slot of `newOwner` is given by:\n    /// ```\n    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))\n    ///     let handoverSlot := keccak256(0x00, 0x20)\n    /// ```\n    /// It stores the expiry timestamp of the two-step ownership handover.\n    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     INTERNAL FUNCTIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Override to return true to make `_initializeOwner` prevent double-initialization.\n    function _guardInitializeOwner() internal pure virtual returns (bool guard) {}\n\n    /// @dev Initializes the owner directly without authorization guard.\n    /// This function must be called upon initialization,\n    /// regardless of whether the contract is upgradeable or not.\n    /// This is to enable generalization to both regular and upgradeable contracts,\n    /// and to save gas in case the initial owner is not the caller.\n    /// For performance reasons, this function will not check if there\n    /// is an existing owner.\n    function _initializeOwner(address newOwner) internal virtual {\n        if (_guardInitializeOwner()) {\n            /// @solidity memory-safe-assembly\n            assembly {\n                let ownerSlot := _OWNER_SLOT\n                if sload(ownerSlot) {\n                    mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.\n                    revert(0x1c, 0x04)\n                }\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Store the new value.\n                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)\n            }\n        } else {\n            /// @solidity memory-safe-assembly\n            assembly {\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Store the new value.\n                sstore(_OWNER_SLOT, newOwner)\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)\n            }\n        }\n    }\n\n    /// @dev Sets the owner directly without authorization guard.\n    function _setOwner(address newOwner) internal virtual {\n        if (_guardInitializeOwner()) {\n            /// @solidity memory-safe-assembly\n            assembly {\n                let ownerSlot := _OWNER_SLOT\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)\n                // Store the new value.\n                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))\n            }\n        } else {\n            /// @solidity memory-safe-assembly\n            assembly {\n                let ownerSlot := _OWNER_SLOT\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)\n                // Store the new value.\n                sstore(ownerSlot, newOwner)\n            }\n        }\n    }\n\n    /// @dev Throws if the sender is not the owner.\n    function _checkOwner() internal view virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // If the caller is not the stored owner, revert.\n            if iszero(eq(caller(), sload(_OWNER_SLOT))) {\n                mstore(0x00, 0x82b42900) // `Unauthorized()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n\n    /// @dev Returns how long a two-step ownership handover is valid for in seconds.\n    /// Override to return a different value if needed.\n    /// Made internal to conserve bytecode. Wrap it in a public function if needed.\n    function _ownershipHandoverValidFor() internal view virtual returns (uint64) {\n        return 48 * 3600;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  PUBLIC UPDATE FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Allows the owner to transfer the ownership to `newOwner`.\n    function transferOwnership(address newOwner) public payable virtual onlyOwner {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(shl(96, newOwner)) {\n                mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.\n                revert(0x1c, 0x04)\n            }\n        }\n        _setOwner(newOwner);\n    }\n\n    /// @dev Allows the owner to renounce their ownership.\n    function renounceOwnership() public payable virtual onlyOwner {\n        _setOwner(address(0));\n    }\n\n    /// @dev Request a two-step ownership handover to the caller.\n    /// The request will automatically expire in 48 hours (172800 seconds) by default.\n    function requestOwnershipHandover() public payable virtual {\n        unchecked {\n            uint256 expires = block.timestamp + _ownershipHandoverValidFor();\n            /// @solidity memory-safe-assembly\n            assembly {\n                // Compute and set the handover slot to `expires`.\n                mstore(0x0c, _HANDOVER_SLOT_SEED)\n                mstore(0x00, caller())\n                sstore(keccak256(0x0c, 0x20), expires)\n                // Emit the {OwnershipHandoverRequested} event.\n                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())\n            }\n        }\n    }\n\n    /// @dev Cancels the two-step ownership handover to the caller, if any.\n    function cancelOwnershipHandover() public payable virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute and set the handover slot to 0.\n            mstore(0x0c, _HANDOVER_SLOT_SEED)\n            mstore(0x00, caller())\n            sstore(keccak256(0x0c, 0x20), 0)\n            // Emit the {OwnershipHandoverCanceled} event.\n            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())\n        }\n    }\n\n    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.\n    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.\n    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute and set the handover slot to 0.\n            mstore(0x0c, _HANDOVER_SLOT_SEED)\n            mstore(0x00, pendingOwner)\n            let handoverSlot := keccak256(0x0c, 0x20)\n            // If the handover does not exist, or has expired.\n            if gt(timestamp(), sload(handoverSlot)) {\n                mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.\n                revert(0x1c, 0x04)\n            }\n            // Set the handover slot to 0.\n            sstore(handoverSlot, 0)\n        }\n        _setOwner(pendingOwner);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   PUBLIC READ FUNCTIONS                    */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the owner of the contract.\n    function owner() public view virtual returns (address result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := sload(_OWNER_SLOT)\n        }\n    }\n\n    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.\n    function ownershipHandoverExpiresAt(address pendingOwner)\n        public\n        view\n        virtual\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the handover slot.\n            mstore(0x0c, _HANDOVER_SLOT_SEED)\n            mstore(0x00, pendingOwner)\n            // Load the handover slot.\n            result := sload(keccak256(0x0c, 0x20))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         MODIFIERS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Marks a function as only callable by the owner.\n    modifier onlyOwner() virtual {\n        _checkOwner();\n        _;\n    }\n}\n"},"OwnableRoles.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {Ownable} from \"./Ownable.sol\";\n\n/// @notice Simple single owner and multiroles authorization mixin.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)\n/// @dev While the ownable portion follows [EIP-173](https://eips.ethereum.org/EIPS/eip-173)\n/// for compatibility, the nomenclature for the 2-step ownership handover and roles\n/// may be unique to this codebase.\nabstract contract OwnableRoles is Ownable {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The `user`\u0027s roles is updated to `roles`.\n    /// Each bit of `roles` represents whether the role is set.\n    event RolesUpdated(address indexed user, uint256 indexed roles);\n\n    /// @dev `keccak256(bytes(\"RolesUpdated(address,uint256)\"))`.\n    uint256 private constant _ROLES_UPDATED_EVENT_SIGNATURE =\n        0x715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The role slot of `user` is given by:\n    /// ```\n    ///     mstore(0x00, or(shl(96, user), _ROLE_SLOT_SEED))\n    ///     let roleSlot := keccak256(0x00, 0x20)\n    /// ```\n    /// This automatically ignores the upper bits of the `user` in case\n    /// they are not clean, as well as keep the `keccak256` under 32-bytes.\n    ///\n    /// Note: This is equivalent to `uint32(bytes4(keccak256(\"_OWNER_SLOT_NOT\")))`.\n    uint256 private constant _ROLE_SLOT_SEED = 0x8b78c6d8;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     INTERNAL FUNCTIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Overwrite the roles directly without authorization guard.\n    function _setRoles(address user, uint256 roles) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x0c, _ROLE_SLOT_SEED)\n            mstore(0x00, user)\n            // Store the new value.\n            sstore(keccak256(0x0c, 0x20), roles)\n            // Emit the {RolesUpdated} event.\n            log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), roles)\n        }\n    }\n\n    /// @dev Updates the roles directly without authorization guard.\n    /// If `on` is true, each set bit of `roles` will be turned on,\n    /// otherwise, each set bit of `roles` will be turned off.\n    function _updateRoles(address user, uint256 roles, bool on) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x0c, _ROLE_SLOT_SEED)\n            mstore(0x00, user)\n            let roleSlot := keccak256(0x0c, 0x20)\n            // Load the current value.\n            let current := sload(roleSlot)\n            // Compute the updated roles if `on` is true.\n            let updated := or(current, roles)\n            // Compute the updated roles if `on` is false.\n            // Use `and` to compute the intersection of `current` and `roles`,\n            // `xor` it with `current` to flip the bits in the intersection.\n            if iszero(on) { updated := xor(current, and(current, roles)) }\n            // Then, store the new value.\n            sstore(roleSlot, updated)\n            // Emit the {RolesUpdated} event.\n            log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), updated)\n        }\n    }\n\n    /// @dev Grants the roles directly without authorization guard.\n    /// Each bit of `roles` represents the role to turn on.\n    function _grantRoles(address user, uint256 roles) internal virtual {\n        _updateRoles(user, roles, true);\n    }\n\n    /// @dev Removes the roles directly without authorization guard.\n    /// Each bit of `roles` represents the role to turn off.\n    function _removeRoles(address user, uint256 roles) internal virtual {\n        _updateRoles(user, roles, false);\n    }\n\n    /// @dev Throws if the sender does not have any of the `roles`.\n    function _checkRoles(uint256 roles) internal view virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the role slot.\n            mstore(0x0c, _ROLE_SLOT_SEED)\n            mstore(0x00, caller())\n            // Load the stored value, and if the `and` intersection\n            // of the value and `roles` is zero, revert.\n            if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {\n                mstore(0x00, 0x82b42900) // `Unauthorized()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n\n    /// @dev Throws if the sender is not the owner,\n    /// and does not have any of the `roles`.\n    /// Checks for ownership first, then lazily checks for roles.\n    function _checkOwnerOrRoles(uint256 roles) internal view virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // If the caller is not the stored owner.\n            // Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`.\n            if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) {\n                // Compute the role slot.\n                mstore(0x0c, _ROLE_SLOT_SEED)\n                mstore(0x00, caller())\n                // Load the stored value, and if the `and` intersection\n                // of the value and `roles` is zero, revert.\n                if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {\n                    mstore(0x00, 0x82b42900) // `Unauthorized()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n        }\n    }\n\n    /// @dev Throws if the sender does not have any of the `roles`,\n    /// and is not the owner.\n    /// Checks for roles first, then lazily checks for ownership.\n    function _checkRolesOrOwner(uint256 roles) internal view virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the role slot.\n            mstore(0x0c, _ROLE_SLOT_SEED)\n            mstore(0x00, caller())\n            // Load the stored value, and if the `and` intersection\n            // of the value and `roles` is zero, revert.\n            if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {\n                // If the caller is not the stored owner.\n                // Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`.\n                if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) {\n                    mstore(0x00, 0x82b42900) // `Unauthorized()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n        }\n    }\n\n    /// @dev Convenience function to return a `roles` bitmap from an array of `ordinals`.\n    /// This is meant for frontends like Etherscan, and is therefore not fully optimized.\n    /// Not recommended to be called on-chain.\n    /// Made internal to conserve bytecode. Wrap it in a public function if needed.\n    function _rolesFromOrdinals(uint8[] memory ordinals) internal pure returns (uint256 roles) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for { let i := shl(5, mload(ordinals)) } i { i := sub(i, 0x20) } {\n                // We don\u0027t need to mask the values of `ordinals`, as Solidity\n                // cleans dirty upper bits when storing variables into memory.\n                roles := or(shl(mload(add(ordinals, i)), 1), roles)\n            }\n        }\n    }\n\n    /// @dev Convenience function to return an array of `ordinals` from the `roles` bitmap.\n    /// This is meant for frontends like Etherscan, and is therefore not fully optimized.\n    /// Not recommended to be called on-chain.\n    /// Made internal to conserve bytecode. Wrap it in a public function if needed.\n    function _ordinalsFromRoles(uint256 roles) internal pure returns (uint8[] memory ordinals) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Grab the pointer to the free memory.\n            ordinals := mload(0x40)\n            let ptr := add(ordinals, 0x20)\n            let o := 0\n            // The absence of lookup tables, De Bruijn, etc., here is intentional for\n            // smaller bytecode, as this function is not meant to be called on-chain.\n            for { let t := roles } 1 {} {\n                mstore(ptr, o)\n                // `shr` 5 is equivalent to multiplying by 0x20.\n                // Push back into the ordinals array if the bit is set.\n                ptr := add(ptr, shl(5, and(t, 1)))\n                o := add(o, 1)\n                t := shr(o, roles)\n                if iszero(t) { break }\n            }\n            // Store the length of `ordinals`.\n            mstore(ordinals, shr(5, sub(ptr, add(ordinals, 0x20))))\n            // Allocate the memory.\n            mstore(0x40, ptr)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  PUBLIC UPDATE FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Allows the owner to grant `user` `roles`.\n    /// If the `user` already has a role, then it will be an no-op for the role.\n    function grantRoles(address user, uint256 roles) public payable virtual onlyOwner {\n        _grantRoles(user, roles);\n    }\n\n    /// @dev Allows the owner to remove `user` `roles`.\n    /// If the `user` does not have a role, then it will be an no-op for the role.\n    function revokeRoles(address user, uint256 roles) public payable virtual onlyOwner {\n        _removeRoles(user, roles);\n    }\n\n    /// @dev Allow the caller to remove their own roles.\n    /// If the caller does not have a role, then it will be an no-op for the role.\n    function renounceRoles(uint256 roles) public payable virtual {\n        _removeRoles(msg.sender, roles);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   PUBLIC READ FUNCTIONS                    */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the roles of `user`.\n    function rolesOf(address user) public view virtual returns (uint256 roles) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the role slot.\n            mstore(0x0c, _ROLE_SLOT_SEED)\n            mstore(0x00, user)\n            // Load the stored value.\n            roles := sload(keccak256(0x0c, 0x20))\n        }\n    }\n\n    /// @dev Returns whether `user` has any of `roles`.\n    function hasAnyRole(address user, uint256 roles) public view virtual returns (bool) {\n        return rolesOf(user) \u0026 roles != 0;\n    }\n\n    /// @dev Returns whether `user` has all of `roles`.\n    function hasAllRoles(address user, uint256 roles) public view virtual returns (bool) {\n        return rolesOf(user) \u0026 roles == roles;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         MODIFIERS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Marks a function as only callable by an account with `roles`.\n    modifier onlyRoles(uint256 roles) virtual {\n        _checkRoles(roles);\n        _;\n    }\n\n    /// @dev Marks a function as only callable by the owner or by an account\n    /// with `roles`. Checks for ownership first, then lazily checks for roles.\n    modifier onlyOwnerOrRoles(uint256 roles) virtual {\n        _checkOwnerOrRoles(roles);\n        _;\n    }\n\n    /// @dev Marks a function as only callable by an account with `roles`\n    /// or the owner. Checks for roles first, then lazily checks for ownership.\n    modifier onlyRolesOrOwner(uint256 roles) virtual {\n        _checkRolesOrOwner(roles);\n        _;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       ROLE CONSTANTS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // IYKYK\n\n    uint256 internal constant _ROLE_0 = 1 \u003c\u003c 0;\n    uint256 internal constant _ROLE_1 = 1 \u003c\u003c 1;\n    uint256 internal constant _ROLE_2 = 1 \u003c\u003c 2;\n    uint256 internal constant _ROLE_3 = 1 \u003c\u003c 3;\n    uint256 internal constant _ROLE_4 = 1 \u003c\u003c 4;\n    uint256 internal constant _ROLE_5 = 1 \u003c\u003c 5;\n    uint256 internal constant _ROLE_6 = 1 \u003c\u003c 6;\n    uint256 internal constant _ROLE_7 = 1 \u003c\u003c 7;\n    uint256 internal constant _ROLE_8 = 1 \u003c\u003c 8;\n    uint256 internal constant _ROLE_9 = 1 \u003c\u003c 9;\n    uint256 internal constant _ROLE_10 = 1 \u003c\u003c 10;\n    uint256 internal constant _ROLE_11 = 1 \u003c\u003c 11;\n    uint256 internal constant _ROLE_12 = 1 \u003c\u003c 12;\n    uint256 internal constant _ROLE_13 = 1 \u003c\u003c 13;\n    uint256 internal constant _ROLE_14 = 1 \u003c\u003c 14;\n    uint256 internal constant _ROLE_15 = 1 \u003c\u003c 15;\n    uint256 internal constant _ROLE_16 = 1 \u003c\u003c 16;\n    uint256 internal constant _ROLE_17 = 1 \u003c\u003c 17;\n    uint256 internal constant _ROLE_18 = 1 \u003c\u003c 18;\n    uint256 internal constant _ROLE_19 = 1 \u003c\u003c 19;\n    uint256 internal constant _ROLE_20 = 1 \u003c\u003c 20;\n    uint256 internal constant _ROLE_21 = 1 \u003c\u003c 21;\n    uint256 internal constant _ROLE_22 = 1 \u003c\u003c 22;\n    uint256 internal constant _ROLE_23 = 1 \u003c\u003c 23;\n    uint256 internal constant _ROLE_24 = 1 \u003c\u003c 24;\n    uint256 internal constant _ROLE_25 = 1 \u003c\u003c 25;\n    uint256 internal constant _ROLE_26 = 1 \u003c\u003c 26;\n    uint256 internal constant _ROLE_27 = 1 \u003c\u003c 27;\n    uint256 internal constant _ROLE_28 = 1 \u003c\u003c 28;\n    uint256 internal constant _ROLE_29 = 1 \u003c\u003c 29;\n    uint256 internal constant _ROLE_30 = 1 \u003c\u003c 30;\n    uint256 internal constant _ROLE_31 = 1 \u003c\u003c 31;\n    uint256 internal constant _ROLE_32 = 1 \u003c\u003c 32;\n    uint256 internal constant _ROLE_33 = 1 \u003c\u003c 33;\n    uint256 internal constant _ROLE_34 = 1 \u003c\u003c 34;\n    uint256 internal constant _ROLE_35 = 1 \u003c\u003c 35;\n    uint256 internal constant _ROLE_36 = 1 \u003c\u003c 36;\n    uint256 internal constant _ROLE_37 = 1 \u003c\u003c 37;\n    uint256 internal constant _ROLE_38 = 1 \u003c\u003c 38;\n    uint256 internal constant _ROLE_39 = 1 \u003c\u003c 39;\n    uint256 internal constant _ROLE_40 = 1 \u003c\u003c 40;\n    uint256 internal constant _ROLE_41 = 1 \u003c\u003c 41;\n    uint256 internal constant _ROLE_42 = 1 \u003c\u003c 42;\n    uint256 internal constant _ROLE_43 = 1 \u003c\u003c 43;\n    uint256 internal constant _ROLE_44 = 1 \u003c\u003c 44;\n    uint256 internal constant _ROLE_45 = 1 \u003c\u003c 45;\n    uint256 internal constant _ROLE_46 = 1 \u003c\u003c 46;\n    uint256 internal constant _ROLE_47 = 1 \u003c\u003c 47;\n    uint256 internal constant _ROLE_48 = 1 \u003c\u003c 48;\n    uint256 internal constant _ROLE_49 = 1 \u003c\u003c 49;\n    uint256 internal constant _ROLE_50 = 1 \u003c\u003c 50;\n    uint256 internal constant _ROLE_51 = 1 \u003c\u003c 51;\n    uint256 internal constant _ROLE_52 = 1 \u003c\u003c 52;\n    uint256 internal constant _ROLE_53 = 1 \u003c\u003c 53;\n    uint256 internal constant _ROLE_54 = 1 \u003c\u003c 54;\n    uint256 internal constant _ROLE_55 = 1 \u003c\u003c 55;\n    uint256 internal constant _ROLE_56 = 1 \u003c\u003c 56;\n    uint256 internal constant _ROLE_57 = 1 \u003c\u003c 57;\n    uint256 internal constant _ROLE_58 = 1 \u003c\u003c 58;\n    uint256 internal constant _ROLE_59 = 1 \u003c\u003c 59;\n    uint256 internal constant _ROLE_60 = 1 \u003c\u003c 60;\n    uint256 internal constant _ROLE_61 = 1 \u003c\u003c 61;\n    uint256 internal constant _ROLE_62 = 1 \u003c\u003c 62;\n    uint256 internal constant _ROLE_63 = 1 \u003c\u003c 63;\n    uint256 internal constant _ROLE_64 = 1 \u003c\u003c 64;\n    uint256 internal constant _ROLE_65 = 1 \u003c\u003c 65;\n    uint256 internal constant _ROLE_66 = 1 \u003c\u003c 66;\n    uint256 internal constant _ROLE_67 = 1 \u003c\u003c 67;\n    uint256 internal constant _ROLE_68 = 1 \u003c\u003c 68;\n    uint256 internal constant _ROLE_69 = 1 \u003c\u003c 69;\n    uint256 internal constant _ROLE_70 = 1 \u003c\u003c 70;\n    uint256 internal constant _ROLE_71 = 1 \u003c\u003c 71;\n    uint256 internal constant _ROLE_72 = 1 \u003c\u003c 72;\n    uint256 internal constant _ROLE_73 = 1 \u003c\u003c 73;\n    uint256 internal constant _ROLE_74 = 1 \u003c\u003c 74;\n    uint256 internal constant _ROLE_75 = 1 \u003c\u003c 75;\n    uint256 internal constant _ROLE_76 = 1 \u003c\u003c 76;\n    uint256 internal constant _ROLE_77 = 1 \u003c\u003c 77;\n    uint256 internal constant _ROLE_78 = 1 \u003c\u003c 78;\n    uint256 internal constant _ROLE_79 = 1 \u003c\u003c 79;\n    uint256 internal constant _ROLE_80 = 1 \u003c\u003c 80;\n    uint256 internal constant _ROLE_81 = 1 \u003c\u003c 81;\n    uint256 internal constant _ROLE_82 = 1 \u003c\u003c 82;\n    uint256 internal constant _ROLE_83 = 1 \u003c\u003c 83;\n    uint256 internal constant _ROLE_84 = 1 \u003c\u003c 84;\n    uint256 internal constant _ROLE_85 = 1 \u003c\u003c 85;\n    uint256 internal constant _ROLE_86 = 1 \u003c\u003c 86;\n    uint256 internal constant _ROLE_87 = 1 \u003c\u003c 87;\n    uint256 internal constant _ROLE_88 = 1 \u003c\u003c 88;\n    uint256 internal constant _ROLE_89 = 1 \u003c\u003c 89;\n    uint256 internal constant _ROLE_90 = 1 \u003c\u003c 90;\n    uint256 internal constant _ROLE_91 = 1 \u003c\u003c 91;\n    uint256 internal constant _ROLE_92 = 1 \u003c\u003c 92;\n    uint256 internal constant _ROLE_93 = 1 \u003c\u003c 93;\n    uint256 internal constant _ROLE_94 = 1 \u003c\u003c 94;\n    uint256 internal constant _ROLE_95 = 1 \u003c\u003c 95;\n    uint256 internal constant _ROLE_96 = 1 \u003c\u003c 96;\n    uint256 internal constant _ROLE_97 = 1 \u003c\u003c 97;\n    uint256 internal constant _ROLE_98 = 1 \u003c\u003c 98;\n    uint256 internal constant _ROLE_99 = 1 \u003c\u003c 99;\n    uint256 internal constant _ROLE_100 = 1 \u003c\u003c 100;\n    uint256 internal constant _ROLE_101 = 1 \u003c\u003c 101;\n    uint256 internal constant _ROLE_102 = 1 \u003c\u003c 102;\n    uint256 internal constant _ROLE_103 = 1 \u003c\u003c 103;\n    uint256 internal constant _ROLE_104 = 1 \u003c\u003c 104;\n    uint256 internal constant _ROLE_105 = 1 \u003c\u003c 105;\n    uint256 internal constant _ROLE_106 = 1 \u003c\u003c 106;\n    uint256 internal constant _ROLE_107 = 1 \u003c\u003c 107;\n    uint256 internal constant _ROLE_108 = 1 \u003c\u003c 108;\n    uint256 internal constant _ROLE_109 = 1 \u003c\u003c 109;\n    uint256 internal constant _ROLE_110 = 1 \u003c\u003c 110;\n    uint256 internal constant _ROLE_111 = 1 \u003c\u003c 111;\n    uint256 internal constant _ROLE_112 = 1 \u003c\u003c 112;\n    uint256 internal constant _ROLE_113 = 1 \u003c\u003c 113;\n    uint256 internal constant _ROLE_114 = 1 \u003c\u003c 114;\n    uint256 internal constant _ROLE_115 = 1 \u003c\u003c 115;\n    uint256 internal constant _ROLE_116 = 1 \u003c\u003c 116;\n    uint256 internal constant _ROLE_117 = 1 \u003c\u003c 117;\n    uint256 internal constant _ROLE_118 = 1 \u003c\u003c 118;\n    uint256 internal constant _ROLE_119 = 1 \u003c\u003c 119;\n    uint256 internal constant _ROLE_120 = 1 \u003c\u003c 120;\n    uint256 internal constant _ROLE_121 = 1 \u003c\u003c 121;\n    uint256 internal constant _ROLE_122 = 1 \u003c\u003c 122;\n    uint256 internal constant _ROLE_123 = 1 \u003c\u003c 123;\n    uint256 internal constant _ROLE_124 = 1 \u003c\u003c 124;\n    uint256 internal constant _ROLE_125 = 1 \u003c\u003c 125;\n    uint256 internal constant _ROLE_126 = 1 \u003c\u003c 126;\n    uint256 internal constant _ROLE_127 = 1 \u003c\u003c 127;\n    uint256 internal constant _ROLE_128 = 1 \u003c\u003c 128;\n    uint256 internal constant _ROLE_129 = 1 \u003c\u003c 129;\n    uint256 internal constant _ROLE_130 = 1 \u003c\u003c 130;\n    uint256 internal constant _ROLE_131 = 1 \u003c\u003c 131;\n    uint256 internal constant _ROLE_132 = 1 \u003c\u003c 132;\n    uint256 internal constant _ROLE_133 = 1 \u003c\u003c 133;\n    uint256 internal constant _ROLE_134 = 1 \u003c\u003c 134;\n    uint256 internal constant _ROLE_135 = 1 \u003c\u003c 135;\n    uint256 internal constant _ROLE_136 = 1 \u003c\u003c 136;\n    uint256 internal constant _ROLE_137 = 1 \u003c\u003c 137;\n    uint256 internal constant _ROLE_138 = 1 \u003c\u003c 138;\n    uint256 internal constant _ROLE_139 = 1 \u003c\u003c 139;\n    uint256 internal constant _ROLE_140 = 1 \u003c\u003c 140;\n    uint256 internal constant _ROLE_141 = 1 \u003c\u003c 141;\n    uint256 internal constant _ROLE_142 = 1 \u003c\u003c 142;\n    uint256 internal constant _ROLE_143 = 1 \u003c\u003c 143;\n    uint256 internal constant _ROLE_144 = 1 \u003c\u003c 144;\n    uint256 internal constant _ROLE_145 = 1 \u003c\u003c 145;\n    uint256 internal constant _ROLE_146 = 1 \u003c\u003c 146;\n    uint256 internal constant _ROLE_147 = 1 \u003c\u003c 147;\n    uint256 internal constant _ROLE_148 = 1 \u003c\u003c 148;\n    uint256 internal constant _ROLE_149 = 1 \u003c\u003c 149;\n    uint256 internal constant _ROLE_150 = 1 \u003c\u003c 150;\n    uint256 internal constant _ROLE_151 = 1 \u003c\u003c 151;\n    uint256 internal constant _ROLE_152 = 1 \u003c\u003c 152;\n    uint256 internal constant _ROLE_153 = 1 \u003c\u003c 153;\n    uint256 internal constant _ROLE_154 = 1 \u003c\u003c 154;\n    uint256 internal constant _ROLE_155 = 1 \u003c\u003c 155;\n    uint256 internal constant _ROLE_156 = 1 \u003c\u003c 156;\n    uint256 internal constant _ROLE_157 = 1 \u003c\u003c 157;\n    uint256 internal constant _ROLE_158 = 1 \u003c\u003c 158;\n    uint256 internal constant _ROLE_159 = 1 \u003c\u003c 159;\n    uint256 internal constant _ROLE_160 = 1 \u003c\u003c 160;\n    uint256 internal constant _ROLE_161 = 1 \u003c\u003c 161;\n    uint256 internal constant _ROLE_162 = 1 \u003c\u003c 162;\n    uint256 internal constant _ROLE_163 = 1 \u003c\u003c 163;\n    uint256 internal constant _ROLE_164 = 1 \u003c\u003c 164;\n    uint256 internal constant _ROLE_165 = 1 \u003c\u003c 165;\n    uint256 internal constant _ROLE_166 = 1 \u003c\u003c 166;\n    uint256 internal constant _ROLE_167 = 1 \u003c\u003c 167;\n    uint256 internal constant _ROLE_168 = 1 \u003c\u003c 168;\n    uint256 internal constant _ROLE_169 = 1 \u003c\u003c 169;\n    uint256 internal constant _ROLE_170 = 1 \u003c\u003c 170;\n    uint256 internal constant _ROLE_171 = 1 \u003c\u003c 171;\n    uint256 internal constant _ROLE_172 = 1 \u003c\u003c 172;\n    uint256 internal constant _ROLE_173 = 1 \u003c\u003c 173;\n    uint256 internal constant _ROLE_174 = 1 \u003c\u003c 174;\n    uint256 internal constant _ROLE_175 = 1 \u003c\u003c 175;\n    uint256 internal constant _ROLE_176 = 1 \u003c\u003c 176;\n    uint256 internal constant _ROLE_177 = 1 \u003c\u003c 177;\n    uint256 internal constant _ROLE_178 = 1 \u003c\u003c 178;\n    uint256 internal constant _ROLE_179 = 1 \u003c\u003c 179;\n    uint256 internal constant _ROLE_180 = 1 \u003c\u003c 180;\n    uint256 internal constant _ROLE_181 = 1 \u003c\u003c 181;\n    uint256 internal constant _ROLE_182 = 1 \u003c\u003c 182;\n    uint256 internal constant _ROLE_183 = 1 \u003c\u003c 183;\n    uint256 internal constant _ROLE_184 = 1 \u003c\u003c 184;\n    uint256 internal constant _ROLE_185 = 1 \u003c\u003c 185;\n    uint256 internal constant _ROLE_186 = 1 \u003c\u003c 186;\n    uint256 internal constant _ROLE_187 = 1 \u003c\u003c 187;\n    uint256 internal constant _ROLE_188 = 1 \u003c\u003c 188;\n    uint256 internal constant _ROLE_189 = 1 \u003c\u003c 189;\n    uint256 internal constant _ROLE_190 = 1 \u003c\u003c 190;\n    uint256 internal constant _ROLE_191 = 1 \u003c\u003c 191;\n    uint256 internal constant _ROLE_192 = 1 \u003c\u003c 192;\n    uint256 internal constant _ROLE_193 = 1 \u003c\u003c 193;\n    uint256 internal constant _ROLE_194 = 1 \u003c\u003c 194;\n    uint256 internal constant _ROLE_195 = 1 \u003c\u003c 195;\n    uint256 internal constant _ROLE_196 = 1 \u003c\u003c 196;\n    uint256 internal constant _ROLE_197 = 1 \u003c\u003c 197;\n    uint256 internal constant _ROLE_198 = 1 \u003c\u003c 198;\n    uint256 internal constant _ROLE_199 = 1 \u003c\u003c 199;\n    uint256 internal constant _ROLE_200 = 1 \u003c\u003c 200;\n    uint256 internal constant _ROLE_201 = 1 \u003c\u003c 201;\n    uint256 internal constant _ROLE_202 = 1 \u003c\u003c 202;\n    uint256 internal constant _ROLE_203 = 1 \u003c\u003c 203;\n    uint256 internal constant _ROLE_204 = 1 \u003c\u003c 204;\n    uint256 internal constant _ROLE_205 = 1 \u003c\u003c 205;\n    uint256 internal constant _ROLE_206 = 1 \u003c\u003c 206;\n    uint256 internal constant _ROLE_207 = 1 \u003c\u003c 207;\n    uint256 internal constant _ROLE_208 = 1 \u003c\u003c 208;\n    uint256 internal constant _ROLE_209 = 1 \u003c\u003c 209;\n    uint256 internal constant _ROLE_210 = 1 \u003c\u003c 210;\n    uint256 internal constant _ROLE_211 = 1 \u003c\u003c 211;\n    uint256 internal constant _ROLE_212 = 1 \u003c\u003c 212;\n    uint256 internal constant _ROLE_213 = 1 \u003c\u003c 213;\n    uint256 internal constant _ROLE_214 = 1 \u003c\u003c 214;\n    uint256 internal constant _ROLE_215 = 1 \u003c\u003c 215;\n    uint256 internal constant _ROLE_216 = 1 \u003c\u003c 216;\n    uint256 internal constant _ROLE_217 = 1 \u003c\u003c 217;\n    uint256 internal constant _ROLE_218 = 1 \u003c\u003c 218;\n    uint256 internal constant _ROLE_219 = 1 \u003c\u003c 219;\n    uint256 internal constant _ROLE_220 = 1 \u003c\u003c 220;\n    uint256 internal constant _ROLE_221 = 1 \u003c\u003c 221;\n    uint256 internal constant _ROLE_222 = 1 \u003c\u003c 222;\n    uint256 internal constant _ROLE_223 = 1 \u003c\u003c 223;\n    uint256 internal constant _ROLE_224 = 1 \u003c\u003c 224;\n    uint256 internal constant _ROLE_225 = 1 \u003c\u003c 225;\n    uint256 internal constant _ROLE_226 = 1 \u003c\u003c 226;\n    uint256 internal constant _ROLE_227 = 1 \u003c\u003c 227;\n    uint256 internal constant _ROLE_228 = 1 \u003c\u003c 228;\n    uint256 internal constant _ROLE_229 = 1 \u003c\u003c 229;\n    uint256 internal constant _ROLE_230 = 1 \u003c\u003c 230;\n    uint256 internal constant _ROLE_231 = 1 \u003c\u003c 231;\n    uint256 internal constant _ROLE_232 = 1 \u003c\u003c 232;\n    uint256 internal constant _ROLE_233 = 1 \u003c\u003c 233;\n    uint256 internal constant _ROLE_234 = 1 \u003c\u003c 234;\n    uint256 internal constant _ROLE_235 = 1 \u003c\u003c 235;\n    uint256 internal constant _ROLE_236 = 1 \u003c\u003c 236;\n    uint256 internal constant _ROLE_237 = 1 \u003c\u003c 237;\n    uint256 internal constant _ROLE_238 = 1 \u003c\u003c 238;\n    uint256 internal constant _ROLE_239 = 1 \u003c\u003c 239;\n    uint256 internal constant _ROLE_240 = 1 \u003c\u003c 240;\n    uint256 internal constant _ROLE_241 = 1 \u003c\u003c 241;\n    uint256 internal constant _ROLE_242 = 1 \u003c\u003c 242;\n    uint256 internal constant _ROLE_243 = 1 \u003c\u003c 243;\n    uint256 internal constant _ROLE_244 = 1 \u003c\u003c 244;\n    uint256 internal constant _ROLE_245 = 1 \u003c\u003c 245;\n    uint256 internal constant _ROLE_246 = 1 \u003c\u003c 246;\n    uint256 internal constant _ROLE_247 = 1 \u003c\u003c 247;\n    uint256 internal constant _ROLE_248 = 1 \u003c\u003c 248;\n    uint256 internal constant _ROLE_249 = 1 \u003c\u003c 249;\n    uint256 internal constant _ROLE_250 = 1 \u003c\u003c 250;\n    uint256 internal constant _ROLE_251 = 1 \u003c\u003c 251;\n    uint256 internal constant _ROLE_252 = 1 \u003c\u003c 252;\n    uint256 internal constant _ROLE_253 = 1 \u003c\u003c 253;\n    uint256 internal constant _ROLE_254 = 1 \u003c\u003c 254;\n    uint256 internal constant _ROLE_255 = 1 \u003c\u003c 255;\n}\n"},"ReentrancyGuard.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.22;\n\n/// @notice Gas optimized reentrancy protection for smart contracts\n/// @author Cheezburger (https://cheezburger.lol)\nabstract contract ReentrancyGuard {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    error ReentrancyDetected();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    uint8 private locked = 1;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         MODIFIERS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    modifier nonReentrant() virtual {\n        if (locked == 2) {\n            revert ReentrancyDetected();\n        }\n        locked = 2;\n        _;\n        locked = 1;\n    }\n}\n"},"SafeTransferLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)\n///\n/// @dev Note:\n/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.\n/// - For ERC20s, this implementation won\u0027t check that a token has code,\n///   responsibility is delegated to the caller.\nlibrary SafeTransferLib {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The ETH transfer has failed.\n    error ETHTransferFailed();\n\n    /// @dev The ERC20 `transferFrom` has failed.\n    error TransferFromFailed();\n\n    /// @dev The ERC20 `transfer` has failed.\n    error TransferFailed();\n\n    /// @dev The ERC20 `approve` has failed.\n    error ApproveFailed();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.\n    uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;\n\n    /// @dev Suggested gas stipend for contract receiving ETH to perform a few\n    /// storage reads and writes, but low enough to prevent griefing.\n    uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       ETH OPERATIONS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.\n    //\n    // The regular variants:\n    // - Forwards all remaining gas to the target.\n    // - Reverts if the target reverts.\n    // - Reverts if the current contract has insufficient balance.\n    //\n    // The force variants:\n    // - Forwards with an optional gas stipend\n    //   (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).\n    // - If the target reverts, or if the gas stipend is exhausted,\n    //   creates a temporary contract to force send the ETH via `SELFDESTRUCT`.\n    //   Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.\n    // - Reverts if the current contract has insufficient balance.\n    //\n    // The try variants:\n    // - Forwards with a mandatory gas stipend.\n    // - Instead of reverting, returns whether the transfer succeeded.\n\n    /// @dev Sends `amount` (in wei) ETH to `to`.\n    function safeTransferETH(address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n\n    /// @dev Sends all the ETH in the current contract to `to`.\n    function safeTransferAllETH(address to) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Transfer all the ETH and check if it succeeded or not.\n            if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n\n    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.\n    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if lt(selfbalance(), amount) {\n                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n            if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, to) // Store the address in scratch space.\n                mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n            }\n        }\n    }\n\n    /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.\n    function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, to) // Store the address in scratch space.\n                mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n            }\n        }\n    }\n\n    /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.\n    function forceSafeTransferETH(address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if lt(selfbalance(), amount) {\n                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n            if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, to) // Store the address in scratch space.\n                mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n            }\n        }\n    }\n\n    /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.\n    function forceSafeTransferAllETH(address to) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // forgefmt: disable-next-item\n            if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, to) // Store the address in scratch space.\n                mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n            }\n        }\n    }\n\n    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.\n    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)\n        internal\n        returns (bool success)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)\n        }\n    }\n\n    /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.\n    function trySafeTransferAllETH(address to, uint256 gasStipend)\n        internal\n        returns (bool success)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      ERC20 OPERATIONS                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.\n    /// Reverts upon failure.\n    ///\n    /// The `from` account must have at least `amount` approved for\n    /// the current contract to manage.\n    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x60, amount) // Store the `amount` argument.\n            mstore(0x40, to) // Store the `to` argument.\n            mstore(0x2c, shl(96, from)) // Store the `from` argument.\n            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.\n            // Perform the transfer, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x60, 0) // Restore the zero slot to zero.\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Sends all of ERC20 `token` from `from` to `to`.\n    /// Reverts upon failure.\n    ///\n    /// The `from` account must have their entire balance approved for\n    /// the current contract to manage.\n    function safeTransferAllFrom(address token, address from, address to)\n        internal\n        returns (uint256 amount)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x40, to) // Store the `to` argument.\n            mstore(0x2c, shl(96, from)) // Store the `from` argument.\n            mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.\n            // Read the balance, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.\n            amount := mload(0x60) // The `amount` is already at 0x60. We\u0027ll need to return it.\n            // Perform the transfer, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x60, 0) // Restore the zero slot to zero.\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.\n    /// Reverts upon failure.\n    function safeTransfer(address token, address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x14, to) // Store the `to` argument.\n            mstore(0x34, amount) // Store the `amount` argument.\n            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.\n            // Perform the transfer, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n        }\n    }\n\n    /// @dev Sends all of ERC20 `token` from the current contract to `to`.\n    /// Reverts upon failure.\n    function safeTransferAll(address token, address to) internal returns (uint256 amount) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.\n            mstore(0x20, address()) // Store the address of the current contract.\n            // Read the balance, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n                    staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x14, to) // Store the `to` argument.\n            amount := mload(0x34) // The `amount` is already at 0x34. We\u0027ll need to return it.\n            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.\n            // Perform the transfer, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n        }\n    }\n\n    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.\n    /// Reverts upon failure.\n    function safeApprove(address token, address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x14, to) // Store the `to` argument.\n            mstore(0x34, amount) // Store the `amount` argument.\n            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.\n            // Perform the approval, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n        }\n    }\n\n    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.\n    /// If the initial attempt to approve fails, attempts to reset the approved amount to zero,\n    /// then retries the approval again (some tokens, e.g. USDT, requires this).\n    /// Reverts upon failure.\n    function safeApproveWithRetry(address token, address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x14, to) // Store the `to` argument.\n            mstore(0x34, amount) // Store the `amount` argument.\n            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.\n            // Perform the approval, retrying upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x34, 0) // Store 0 for the `amount`.\n                mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.\n                pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00)) // Reset the approval.\n                mstore(0x34, amount) // Store back the original `amount`.\n                // Retry the approval, reverting upon failure.\n                if iszero(\n                    and(\n                        or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                        call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                    )\n                ) {\n                    mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n        }\n    }\n\n    /// @dev Returns the amount of ERC20 `token` owned by `account`.\n    /// Returns zero if the `token` does not exist.\n    function balanceOf(address token, address account) internal view returns (uint256 amount) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x14, account) // Store the `account` argument.\n            mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.\n            amount :=\n                mul(\n                    mload(0x20),\n                    and( // The arguments of `and` are evaluated from right to left.\n                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n                        staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)\n                    )\n                )\n        }\n    }\n}\n"}}