Transaction Hash:
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:
210 |
Cheezburger.Transfer( from=[Sender] 0x3e542154cc3b20f34f10cd816850c7569b0119b1, to=0x4cb4a52A94aFFee0A511E16aBe692e4427cD0419, amount=1000000000000000000000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x3e542154...69b0119b1 |
0.000111339360357712 Eth
Nonce: 262
|
0.000076916923908012 Eth
Nonce: 263
| 0.0000344224364497 | ||
0x95222290...5CC4BAfe5
Miner
| (beaverbuild) | 19.959209261870040647 Eth | 19.959216510346476567 Eth | 0.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"}}