creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/GoodTrouble.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n// OPENZEPPELIN IMPORTS\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n// UNISWAP INTERFACES\nimport {IUniswapRouter02, IUniswapFactory, IUniswapPair} from \"./interface/IUniswapV2.sol\";\n\n/**\n * @title Good Trouble\n * @author AssureDefi\n * @notice This is the token for Good Trouble on the ETH chain. It is an ERC20 token with a fixed supply.\n * Total Init Supply: 100,000,000 GTRB\n * Decimals: 18\n * Symbol: GTRB\n * Name: Good Trouble\n * This contract contains editable taxes for GTRB\n * Buy and Sell taxes will start at 40% and decrease by 5% every 5 minutes until it reaches 5%\n * Majority of taxes is converted to ETH, a small portion is kept to create liquidity, others are split between\n * marketing and dev.\n */\ncontract GoodTrouble is ERC20, Ownable {\n    //-------------------------------------------------------------------------\n    // Errors\n    //-------------------------------------------------------------------------\n    error GTRB__InvalidNewTax();\n    error GTRB__InvalidValue();\n    error GTRB__MaxTxExceeded();\n    error GTRB__MaxWalletExceeded();\n    error GTRB__InvalidListLength();\n    error GTRB__OnlyDevWallet();\n    error GTRB__OnlyMktWallet();\n    error GTRB__OnlyBBWallet();\n    error GTRB_NativeTransferFailed();\n    error GTRB__NoBalance();\n    error GTRB__AlreadySwapping();\n    //-------------------------------------------------------------------------\n    // STATE VARIABLES\n    //-------------------------------------------------------------------------\n    mapping(address => bool) public isExcludedFromTax;\n    mapping(address => bool) public isMaxWalletExcluded;\n    mapping(address => bool) public isMaxTxExcluded;\n    // We can add more pairs to tax them when necessary\n    mapping(address => bool) public isPair;\n\n    address public devWallet;\n    address public marketingWallet;\n    address public constant deadWallet =\n        0x000000000000000000000000000000000000dEaD;\n    IUniswapRouter02 public router;\n    IUniswapPair public pair;\n\n    uint public sellThreshold;\n    uint public startTaxTime;\n    uint public maxTx;\n    uint public maxWallet;\n\n    uint16 public mktShare = 375;\n    uint16 public devShare = 125;\n    uint16 private totalShares = 500;\n\n    uint8 public buyTax = 5;\n    uint8 public sellTax = 5;\n    uint8 private swapping = 1;\n\n    uint private constant _TAX_INTERVAL = 5 minutes;\n    uint private constant MAX_TAX_TIME = 40 minutes;\n    uint256 private constant _INIT_SUPPLY = 100_000_000 ether;\n    uint256 private constant PERCENTILE = 100;\n\n    //-------------------------------------------------------------------------\n    // EVENTS\n    //-------------------------------------------------------------------------\n    event UpdateSellTax(uint tax);\n    event UpdateBuyTax(uint tax);\n    event UpdateDevWallet(\n        address indexed prevWallet,\n        address indexed newWallet\n    );\n    event UpdateMarketingWallet(\n        address indexed prevWallet,\n        address indexed newWallet\n    );\n    event UpdateTaxExclusionStatus(address indexed account, bool status);\n    event UpdateMaxTxExclusionStatus(address indexed account, bool status);\n    event UpdateMaxWalletExclusionStatus(address indexed account, bool status);\n    event UpdateMaxTx(uint maxTx);\n    event UpdateMaxWallet(uint maxWallet);\n    event UpdateThreshold(uint threshold);\n    event SetNewPair(address indexed pair);\n    event UpdateShares(uint16 mktShare, uint16 devShare);\n    event UpdateUniswapRouter(address indexed router);\n\n    //-------------------------------------------------------------------------\n    // CONSTRUCTOR\n    //-------------------------------------------------------------------------\n    constructor(\n        address _devWallet,\n        address _marketingWallet,\n        address newOwner\n    ) ERC20(\"Good Trouble\", \"GTRB\") Ownable(newOwner) {\n        // Sell Threshold is 0.1% of the total supply\n        sellThreshold = _INIT_SUPPLY / (10 * PERCENTILE);\n        // Setup PancakeSwap Contracts\n        router = IUniswapRouter02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);\n        IUniswapFactory factory = IUniswapFactory(router.factory());\n        pair = IUniswapPair(factory.createPair(address(this), router.WETH()));\n        isPair[address(pair)] = true;\n        _approve(address(this), address(router), type(uint256).max);\n\n        isExcludedFromTax[address(this)] = true;\n        isExcludedFromTax[owner()] = true;\n        isMaxWalletExcluded[owner()] = true;\n        isMaxWalletExcluded[address(this)] = true;\n        isMaxWalletExcluded[address(router)] = true;\n        isMaxWalletExcluded[deadWallet] = true;\n        isMaxWalletExcluded[address(pair)] = true;\n        isMaxTxExcluded[owner()] = true;\n        isMaxTxExcluded[address(this)] = true;\n        isMaxTxExcluded[address(router)] = true;\n        isMaxTxExcluded[address(0)] = true;\n        devWallet = _devWallet;\n        marketingWallet = _marketingWallet;\n        maxTx = _INIT_SUPPLY / PERCENTILE; // 1% of total supply\n        maxWallet = _INIT_SUPPLY / PERCENTILE; // 1% of total supply\n\n        _mint(owner(), _INIT_SUPPLY);\n    }\n\n    //-------------------------------------------------------------------------\n    // EXTERNAL / PUBLIC FUNCTIONS\n    //-------------------------------------------------------------------------\n    // Allow contract to receive Native tokens\n    receive() external payable {}\n\n    fallback() external payable {}\n\n    //-------------------------------------------------------------------------\n    // Owner Functions\n    //-------------------------------------------------------------------------\n    /**\n     * @notice This function is called to edit the buy tax for GTRB\n     * @param _buyTax The new buy tax to set\n     * @dev the tax can only be a max of 40%\n     */\n    function setBuyTax(uint8 _buyTax) external onlyOwner {\n        if (_buyTax > 40) {\n            revert GTRB__InvalidNewTax();\n        }\n        buyTax = _buyTax;\n        emit UpdateBuyTax(_buyTax);\n    }\n\n    /**\n     * @notice This function is called to edit the buy tax for GTRB\n     * @param _sellTax The new buy tax to set\n     * @dev the tax can only be a max of 40%\n     */\n    function setSellTax(uint8 _sellTax) external onlyOwner {\n        if (_sellTax > 40) {\n            revert GTRB__InvalidNewTax();\n        }\n        sellTax = _sellTax;\n        emit UpdateBuyTax(_sellTax);\n    }\n\n    /**\n     * @notice Changes the tax exclusion status for an address\n     * @param _address The address to set the tax exclusion status for\n     * @param _status The exclusion status, TRUE for excluded, FALSE for not excluded\n     */\n    function setTaxExclusionStatus(\n        address _address,\n        bool _status\n    ) external onlyOwner {\n        isExcludedFromTax[_address] = _status;\n        emit UpdateTaxExclusionStatus(_address, _status);\n    }\n\n    /**\n     * @notice Changes the tax exclusion status for multiple addresses\n     * @param addresses The list of addresses to set the tax exclusion status for\n     * @param _status The exclusion status, TRUE for excluded, FALSE for not excluded for all addresses\n     */\n    function setMultipleTaxExclusionStatus(\n        address[] calldata addresses,\n        bool _status\n    ) external onlyOwner {\n        if (addresses.length == 0) {\n            revert GTRB__InvalidListLength();\n        }\n        for (uint256 i = 0; i < addresses.length; i++) {\n            isExcludedFromTax[addresses[i]] = _status;\n            emit UpdateTaxExclusionStatus(addresses[i], _status);\n        }\n    }\n\n    /**\n     * @notice changes the max tx exclusion status for an address\n     * @param _address The address to change the exclusion of max tx status of\n     * @param _status The new exclusion status for the address || TRUE for excluded, FALSE for not excluded\n     */\n    function setMaxTxExclusionStatus(\n        address _address,\n        bool _status\n    ) external onlyOwner {\n        isMaxTxExcluded[_address] = _status;\n        emit UpdateMaxTxExclusionStatus(_address, _status);\n    }\n\n    /**\n     * @notice changes the max wallet exclusion status for an address\n     * @param _address The address to change the exclusion of max wallet status of\n     * @param _status The new exclusion status for the address || TRUE for excluded, FALSE for not excluded\n     */\n    function setMaxWalletExclusionStatus(\n        address _address,\n        bool _status\n    ) external onlyOwner {\n        // Can't change the status of a pair since it'll always be excluded from max wallet\n        if (isPair[_address]) revert GTRB__InvalidValue();\n        isMaxWalletExcluded[_address] = _status;\n        emit UpdateMaxWalletExclusionStatus(_address, _status);\n    }\n\n    /**\n     * @notice sets the max transaction amount for GTRB\n     * @param _maxTx The new max transaction amount to set\n     * @dev the max transaction amount cannot be less than 0.2% of the total supply\n     */\n    function setMaxTx(uint _maxTx) external onlyOwner {\n        if (_maxTx < _INIT_SUPPLY / 500) revert GTRB__InvalidValue();\n        maxTx = _maxTx;\n        emit UpdateMaxTx(_maxTx);\n    }\n\n    /**\n     * @notice sets the max wallet amount for GTRB\n     * @param _maxWallet The new max wallet amount to set\n     * @dev the max wallet amount cannot be less than 1% of the total supply\n     */\n    function setMaxWallet(uint _maxWallet) external onlyOwner {\n        if (_maxWallet < _INIT_SUPPLY / 100) revert GTRB__InvalidValue();\n        maxWallet = _maxWallet;\n        emit UpdateMaxWallet(_maxWallet);\n    }\n\n    /**\n     * @notice Set a different wallet to receive the swapped out funds\n     * @param _devWallet The new wallet to receive buy funds\n     * @dev ONLY CURRENT BUY TAX WALLET AND OWNER CAN CHANGE THIS\n     */\n    function updateDevWallet(address _devWallet) external {\n        if (msg.sender != devWallet && msg.sender != owner())\n            revert GTRB__OnlyDevWallet();\n        if (_devWallet == address(0)) revert GTRB__InvalidValue();\n        emit UpdateDevWallet(devWallet, _devWallet);\n        devWallet = _devWallet;\n    }\n\n    /**\n     * @notice Set a different wallet to receive the swapped out funds for marketing\n     * @param _marketingwallet The new sell wallet to receive sell funds\n     * @dev ONLY CURRENT MARKETING WALLET AND OWNER CAN CHANGE THIS\n     */\n    function updateMarketingWallet(address _marketingwallet) external {\n        if (msg.sender != marketingWallet && msg.sender != owner())\n            revert GTRB__OnlyMktWallet();\n        if (_marketingwallet == address(0)) revert GTRB__InvalidValue();\n        emit UpdateMarketingWallet(marketingWallet, _marketingwallet);\n        marketingWallet = _marketingwallet;\n    }\n\n    /**\n     * @notice The sell threshold is the amount of GTRB that needs to be collected before a sell for Native happens\n     * @param _sellThreshold The new sell threshold to set\n     */\n    function updateSellThreshold(uint _sellThreshold) external onlyOwner {\n        // Sell threshold cannot be more than 0.1% of the total supply\n        // or less than 0.0001% of the total supply\n        if (\n            _sellThreshold > _INIT_SUPPLY / 1000 ||\n            _sellThreshold < _INIT_SUPPLY / 100000\n        ) revert GTRB__InvalidValue();\n        sellThreshold = _sellThreshold;\n        emit UpdateThreshold(_sellThreshold);\n    }\n\n    /**\n     * @notice regardless of the collected amount, the contract will swap, liquidate and transfer the funds to the respective wallets\n     */\n    function manualSwap() external onlyOwner {\n        if (swapping != 1) revert GTRB__AlreadySwapping();\n        uint balance = balanceOf(address(this));\n        _swapAndTransfer(balance);\n    }\n\n    /**\n     * @notice sets an address as a new pair to charge taxes on it\n     * @param _pair The pair to add to the list of pairs to tax\n     */\n    function addPair(address _pair) external onlyOwner {\n        if (_pair == address(0)) revert GTRB__InvalidValue();\n        isPair[_pair] = true;\n        isMaxWalletExcluded[_pair] = true;\n        emit SetNewPair(_pair);\n    }\n\n    /**\n     * @notice updates the shares for tax spread\n     * @param _mktShare Amount to be shared to the marketing wallet\n     * @param _devShare Amount to be shared to the dev wallet\n     */\n    function updateShares(\n        uint16 _mktShare,\n        uint16 _devShare\n    ) external onlyOwner {\n        totalShares = _mktShare + _devShare;\n        // Total Shares cannot be zero\n        if (totalShares == 0) revert GTRB__InvalidValue();\n        mktShare = _mktShare;\n        devShare = _devShare;\n        emit UpdateShares(_mktShare, _devShare);\n    }\n\n    function updateUniswapRouter(address _router) external onlyOwner {\n        if (router.WETH() != IUniswapRouter02(_router).WETH())\n            revert GTRB__InvalidValue();\n        router = IUniswapRouter02(_router);\n        emit UpdateUniswapRouter(_router);\n    }\n\n    function recoverNative(address _to, uint _amount) external onlyOwner {\n        (bool success, ) = payable(_to).call{value: _amount}(\"\");\n        if (!success) revert GTRB_NativeTransferFailed();\n    }\n\n    function recoverERC20(address _token, address _to) external onlyOwner {\n        uint amount = ERC20(_token).balanceOf(address(this));\n        ERC20(_token).transfer(_to, amount);\n    }\n\n    //-------------------------------------------------------------------------\n    // INTERNAL/PRIVATE FUNCTIONS\n    //-------------------------------------------------------------------------\n    /**\n     * @notice This function overrides the ERC20 `_transfer` function to apply taxes and swap and transfer.\n     * @param from Address that is sending tokens\n     * @param to Address that is receiving tokens\n     * @param amount Amount of tokens being transfered\n     * @dev Although this is an override, it still uses the original `_transfer` function from the ERC20 contract to finalize the updatess\n     * @dev On first adding liquidity, the contract will enable the high tax timer\n     */\n    function _update(address from, address to, uint amount) internal override {\n        bool isBuy = isPair[from];\n        bool isSell = isPair[to];\n        bool anyExcluded = isExcludedFromTax[from] || isExcludedFromTax[to];\n\n        // check max tx if sender or receiver are excluded or amount surpasses max tx revert\n        if (!isMaxTxExcluded[from] && !isMaxTxExcluded[to] && amount > maxTx)\n            revert GTRB__MaxTxExceeded();\n\n        uint currentBalance = balanceOf(address(this));\n        if (\n            !isBuy &&\n            currentBalance > sellThreshold &&\n            !anyExcluded &&\n            swapping == 1\n        ) {\n            _swapAndTransfer(currentBalance);\n        }\n\n        uint fee = 0;\n        if (!anyExcluded) {\n            uint8 tax = _getTimedTax(isBuy, isSell);\n            fee = (amount * tax) / PERCENTILE;\n            if (fee > 0) {\n                amount -= fee;\n                super._update(from, address(this), fee);\n            }\n        }\n        if (isSell && startTaxTime == 0) {\n            startTaxTime = block.timestamp;\n        }\n        // check max wallet\n        if (!isMaxWalletExcluded[to] && balanceOf(to) + amount > maxWallet)\n            revert GTRB__MaxWalletExceeded();\n\n        // Transfer rest\n        super._update(from, to, amount);\n    }\n\n    function _swapAndTransfer(uint balance) private {\n        swapping <<= 1;\n        if (balance == 0) revert GTRB__NoBalance();\n        // Sell half of liqAmount to ETH\n        address[] memory path = new address[](2);\n        path[0] = address(this);\n        path[1] = router.WETH();\n\n        uint minAmount = router.getAmountsOut(balance, path)[1];\n        minAmount = (minAmount * 7) / 10;\n        // Sell rest\n        router.swapExactTokensForETHSupportingFeeOnTransferTokens(\n            balance,\n            minAmount,\n            path,\n            address(this),\n            block.timestamp\n        );\n        // Distribute to rest\n        uint nativeBalance = address(this).balance;\n        if (totalShares == 0) return;\n        uint mktAmount = (nativeBalance * mktShare) / totalShares;\n        uint devAmount = nativeBalance - mktAmount;\n        // Transfer to wallets\n        if (mktAmount > 0) {\n            (bool success, ) = payable(marketingWallet).call{value: mktAmount}(\n                \"\"\n            );\n            if (!success) revert GTRB_NativeTransferFailed();\n        }\n        if (devAmount > 0) {\n            (bool success, ) = payable(devWallet).call{value: devAmount}(\"\");\n            if (!success) revert GTRB_NativeTransferFailed();\n        }\n\n        swapping >>= 1;\n    }\n\n    /**\n     * @notice This function is called to get the tax for the current block\n     * @param isBuy dictates if the tax is for a buy\n     * @param isSell dictates if the tax is for a sell\n     * @return the tax to be applied %\n     * @dev the tax will decrease by 5% every 5 minutes until it reaches 5%\n     */\n    function _getTimedTax(\n        bool isBuy,\n        bool isSell\n    ) private view returns (uint8) {\n        // if startTaxTime is not set or both isBuy and isSell are false, return 0\n        if ((!isBuy && !isSell) || startTaxTime == 0) return 0;\n\n        uint timePassed = block.timestamp - startTaxTime;\n        // If above max tax time, return the minimum tax\n        if (timePassed >= MAX_TAX_TIME) {\n            if (isBuy) return buyTax;\n            if (isSell) return sellTax;\n            return 0;\n        }\n        // it'll decrease by 5% every 5 minutes\n        return uint8(40 - (5 * (timePassed / _TAX_INTERVAL)));\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n    mapping(address account => uint256) private _balances;\n\n    mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `value`.\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `value`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `value`.\n     */\n    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, value);\n        _transfer(from, to, value);\n        return true;\n    }\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _transfer(address from, address to, uint256 value) internal {\n        if (from == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(from, to, value);\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n     * this function.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _update(address from, address to, uint256 value) internal virtual {\n        if (from == address(0)) {\n            // Overflow check required: The rest of the code assumes that totalSupply never overflows\n            _totalSupply += value;\n        } else {\n            uint256 fromBalance = _balances[from];\n            if (fromBalance < value) {\n                revert ERC20InsufficientBalance(from, fromBalance, value);\n            }\n            unchecked {\n                // Overflow not possible: value <= fromBalance <= totalSupply.\n                _balances[from] = fromBalance - value;\n            }\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n     * Relies on the `_update` mechanism\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _mint(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(address(0), account, value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n     * Relies on the `_update` mechanism.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead\n     */\n    function _burn(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        _update(account, address(0), value);\n    }\n\n    /**\n     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address owner, address spender, uint256 value) internal {\n        _approve(owner, spender, value, true);\n    }\n\n    /**\n     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n     *\n     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n     * `Approval` event during `transferFrom` operations.\n     *\n     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n     * true using the following override:\n     * ```\n     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n     *     super._approve(owner, spender, value, true);\n     * }\n     * ```\n     *\n     * Requirements are the same as {_approve}.\n     */\n    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n        if (owner == address(0)) {\n            revert ERC20InvalidApprover(address(0));\n        }\n        if (spender == address(0)) {\n            revert ERC20InvalidSpender(address(0));\n        }\n        _allowances[owner][spender] = value;\n        if (emitEvent) {\n            emit Approval(owner, spender, value);\n        }\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `value`.\n     *\n     * Does not update the allowance value in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Does not emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            if (currentAllowance < value) {\n                revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n            }\n            unchecked {\n                _approve(owner, spender, currentAllowance - value, false);\n            }\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "src/interface/IUniswapV2.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IUniswapRouter01 {\n    function factory() external pure returns (address);\n\n    function WETH() external pure returns (address);\n\n    function addLiquidity(\n        address tokenA,\n        address tokenB,\n        uint amountADesired,\n        uint amountBDesired,\n        uint amountAMin,\n        uint amountBMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountA, uint amountB, uint liquidity);\n\n    function addLiquidityETH(\n        address token,\n        uint amountTokenDesired,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline\n    )\n        external\n        payable\n        returns (uint amountToken, uint amountETH, uint liquidity);\n\n    function removeLiquidity(\n        address tokenA,\n        address tokenB,\n        uint liquidity,\n        uint amountAMin,\n        uint amountBMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountA, uint amountB);\n\n    function removeLiquidityETH(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountToken, uint amountETH);\n\n    function removeLiquidityWithPermit(\n        address tokenA,\n        address tokenB,\n        uint liquidity,\n        uint amountAMin,\n        uint amountBMin,\n        address to,\n        uint deadline,\n        bool approveMax,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external returns (uint amountA, uint amountB);\n\n    function removeLiquidityETHWithPermit(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline,\n        bool approveMax,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external returns (uint amountToken, uint amountETH);\n\n    function swapExactTokensForTokens(\n        uint amountIn,\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external returns (uint[] memory amounts);\n\n    function swapTokensForExactTokens(\n        uint amountOut,\n        uint amountInMax,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external returns (uint[] memory amounts);\n\n    function swapExactETHForTokens(\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external payable returns (uint[] memory amounts);\n\n    function swapTokensForExactETH(\n        uint amountOut,\n        uint amountInMax,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external returns (uint[] memory amounts);\n\n    function swapExactTokensForETH(\n        uint amountIn,\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external returns (uint[] memory amounts);\n\n    function swapETHForExactTokens(\n        uint amountOut,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external payable returns (uint[] memory amounts);\n\n    function quote(\n        uint amountA,\n        uint reserveA,\n        uint reserveB\n    ) external pure returns (uint amountB);\n\n    function getAmountOut(\n        uint amountIn,\n        uint reserveIn,\n        uint reserveOut\n    ) external pure returns (uint amountOut);\n\n    function getAmountIn(\n        uint amountOut,\n        uint reserveIn,\n        uint reserveOut\n    ) external pure returns (uint amountIn);\n\n    function getAmountsOut(\n        uint amountIn,\n        address[] calldata path\n    ) external view returns (uint[] memory amounts);\n\n    function getAmountsIn(\n        uint amountOut,\n        address[] calldata path\n    ) external view returns (uint[] memory amounts);\n}\n\ninterface IUniswapRouter02 is IUniswapRouter01 {\n    function removeLiquidityETHSupportingFeeOnTransferTokens(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountETH);\n\n    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline,\n        bool approveMax,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external returns (uint amountETH);\n\n    function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n        uint amountIn,\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external;\n\n    function swapExactETHForTokensSupportingFeeOnTransferTokens(\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external payable;\n\n    function swapExactTokensForETHSupportingFeeOnTransferTokens(\n        uint amountIn,\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external;\n}\n\ninterface IUniswapPair {\n    event Approval(address indexed owner, address indexed spender, uint value);\n    event Transfer(address indexed from, address indexed to, uint value);\n\n    function name() external pure returns (string memory);\n\n    function symbol() external pure returns (string memory);\n\n    function decimals() external pure returns (uint8);\n\n    function totalSupply() external view returns (uint);\n\n    function balanceOf(address owner) external view returns (uint);\n\n    function allowance(\n        address owner,\n        address spender\n    ) external view returns (uint);\n\n    function approve(address spender, uint value) external returns (bool);\n\n    function transfer(address to, uint value) external returns (bool);\n\n    function transferFrom(\n        address from,\n        address to,\n        uint value\n    ) external returns (bool);\n\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n    function PERMIT_TYPEHASH() external pure returns (bytes32);\n\n    function nonces(address owner) external view returns (uint);\n\n    function permit(\n        address owner,\n        address spender,\n        uint value,\n        uint deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    event Mint(address indexed sender, uint amount0, uint amount1);\n    event Burn(\n        address indexed sender,\n        uint amount0,\n        uint amount1,\n        address indexed to\n    );\n    event Swap(\n        address indexed sender,\n        uint amount0In,\n        uint amount1In,\n        uint amount0Out,\n        uint amount1Out,\n        address indexed to\n    );\n    event Sync(uint112 reserve0, uint112 reserve1);\n\n    function MINIMUM_LIQUIDITY() external pure returns (uint);\n\n    function factory() external view returns (address);\n\n    function token0() external view returns (address);\n\n    function token1() external view returns (address);\n\n    function getReserves()\n        external\n        view\n        returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n    function price0CumulativeLast() external view returns (uint);\n\n    function price1CumulativeLast() external view returns (uint);\n\n    function kLast() external view returns (uint);\n\n    function mint(address to) external returns (uint liquidity);\n\n    function burn(address to) external returns (uint amount0, uint amount1);\n\n    function swap(\n        uint amount0Out,\n        uint amount1Out,\n        address to,\n        bytes calldata data\n    ) external;\n\n    function skim(address to) external;\n\n    function sync() external;\n\n    function initialize(address, address) external;\n}\n\ninterface IUniswapFactory {\n    event PairCreated(\n        address indexed token0,\n        address indexed token1,\n        address pair,\n        uint\n    );\n\n    function feeTo() external view returns (address);\n\n    function feeToSetter() external view returns (address);\n\n    function getPair(\n        address tokenA,\n        address tokenB\n    ) external view returns (address pair);\n\n    function allPairs(uint) external view returns (address pair);\n\n    function allPairsLength() external view returns (uint);\n\n    function createPair(\n        address tokenA,\n        address tokenB\n    ) external returns (address pair);\n\n    function setFeeTo(address) external;\n\n    function setFeeToSetter(address) external;\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard ERC20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
        "forge-std/=lib/forge-std/src/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}