creation_sourcecode: // SPDX-License-Identifier: MIT
  
  pragma solidity 0.8.19;
  
  /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
  /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
  /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
  /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
  abstract contract ERC20 {
      /*//////////////////////////////////////////////////////////////
                                   EVENTS
      //////////////////////////////////////////////////////////////*/
  
      event Transfer(address indexed from, address indexed to, uint256 amount);
  
      event Approval(
          address indexed owner,
          address indexed spender,
          uint256 amount
      );
  
      /*//////////////////////////////////////////////////////////////
                              METADATA STORAGE
      //////////////////////////////////////////////////////////////*/
  
      string public name;
  
      string public symbol;
  
      uint8 public immutable decimals;
  
      /*//////////////////////////////////////////////////////////////
                                ERC20 STORAGE
      //////////////////////////////////////////////////////////////*/
  
      uint256 public totalSupply;
  
      mapping(address => uint256) public balanceOf;
  
      mapping(address => mapping(address => uint256)) public allowance;
  
      /*//////////////////////////////////////////////////////////////
                              EIP-2612 STORAGE
      //////////////////////////////////////////////////////////////*/
  
      uint256 internal immutable INITIAL_CHAIN_ID;
  
      bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
  
      mapping(address => uint256) public nonces;
  
      /*//////////////////////////////////////////////////////////////
                                 CONSTRUCTOR
      //////////////////////////////////////////////////////////////*/
  
      constructor(string memory _name, string memory _symbol, uint8 _decimals) {
          name = _name;
          symbol = _symbol;
          decimals = _decimals;
  
          INITIAL_CHAIN_ID = block.chainid;
          INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
      }
  
      /*//////////////////////////////////////////////////////////////
                                 ERC20 LOGIC
      //////////////////////////////////////////////////////////////*/
  
      function approve(
          address spender,
          uint256 amount
      ) public virtual returns (bool) {
          allowance[msg.sender][spender] = amount;
  
          emit Approval(msg.sender, spender, amount);
  
          return true;
      }
  
      function transfer(
          address to,
          uint256 amount
      ) public virtual returns (bool) {
          balanceOf[msg.sender] -= amount;
  
          // Cannot overflow because the sum of all user
          // balances can't exceed the max uint256 value.
          unchecked {
              balanceOf[to] += amount;
          }
  
          emit Transfer(msg.sender, to, amount);
  
          return true;
      }
  
      function transferFrom(
          address from,
          address to,
          uint256 amount
      ) public virtual returns (bool) {
          uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
  
          if (allowed != type(uint256).max)
              allowance[from][msg.sender] = allowed - amount;
  
          balanceOf[from] -= amount;
  
          // Cannot overflow because the sum of all user
          // balances can't exceed the max uint256 value.
          unchecked {
              balanceOf[to] += amount;
          }
  
          emit Transfer(from, to, amount);
  
          return true;
      }
  
      /*//////////////////////////////////////////////////////////////
                               EIP-2612 LOGIC
      //////////////////////////////////////////////////////////////*/
  
      function permit(
          address owner,
          address spender,
          uint256 value,
          uint256 deadline,
          uint8 v,
          bytes32 r,
          bytes32 s
      ) public virtual {
          require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
  
          // Unchecked because the only math done is incrementing
          // the owner's nonce which cannot realistically overflow.
          unchecked {
              address recoveredAddress = ecrecover(
                  keccak256(
                      abi.encodePacked(
                          "\x19\x01",
                          DOMAIN_SEPARATOR(),
                          keccak256(
                              abi.encode(
                                  keccak256(
                                      "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                  ),
                                  owner,
                                  spender,
                                  value,
                                  nonces[owner]++,
                                  deadline
                              )
                          )
                      )
                  ),
                  v,
                  r,
                  s
              );
  
              require(
                  recoveredAddress != address(0) && recoveredAddress == owner,
                  "INVALID_SIGNER"
              );
  
              allowance[recoveredAddress][spender] = value;
          }
  
          emit Approval(owner, spender, value);
      }
  
      function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
          return
              block.chainid == INITIAL_CHAIN_ID
                  ? INITIAL_DOMAIN_SEPARATOR
                  : computeDomainSeparator();
      }
  
      function computeDomainSeparator() internal view virtual returns (bytes32) {
          return
              keccak256(
                  abi.encode(
                      keccak256(
                          "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
                      ),
                      keccak256(bytes(name)),
                      keccak256("1"),
                      block.chainid,
                      address(this)
                  )
              );
      }
  
      /*//////////////////////////////////////////////////////////////
                          INTERNAL MINT/BURN LOGIC
      //////////////////////////////////////////////////////////////*/
  
      function _mint(address to, uint256 amount) internal virtual {
          totalSupply += amount;
  
          // Cannot overflow because the sum of all user
          // balances can't exceed the max uint256 value.
          unchecked {
              balanceOf[to] += amount;
          }
  
          emit Transfer(address(0), to, amount);
      }
  
      function _burn(address from, uint256 amount) internal virtual {
          balanceOf[from] -= amount;
  
          // Cannot underflow because a user's balance
          // will never be larger than the total supply.
          unchecked {
              totalSupply -= amount;
          }
  
          emit Transfer(from, address(0), amount);
      }
  }
  
  // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
  
  // OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
  
  /**
   * @dev Provides information about the current execution context, including the
   * sender of the transaction and its data. While these are generally available
   * via msg.sender and msg.data, they should not be accessed in such a direct
   * manner, since when dealing with meta-transactions the account sending and
   * paying for execution may not be the actual sender (as far as an application
   * is concerned).
   *
   * This contract is only required for intermediate, library-like contracts.
   */
  abstract contract Context {
      function _msgSender() internal view virtual returns (address) {
          return msg.sender;
      }
  
      function _msgData() internal view virtual returns (bytes calldata) {
          return msg.data;
      }
  }
  
  /**
   * @dev Contract module which provides a basic access control mechanism, where
   * there is an account (an owner) that can be granted exclusive access to
   * specific functions.
   *
   * By default, the owner account will be the one that deploys the contract. This
   * can later be changed with {transferOwnership}.
   *
   * This module is used through inheritance. It will make available the modifier
   * `onlyOwner`, which can be applied to your functions to restrict their use to
   * the owner.
   */
  abstract contract Ownable is Context {
      address private _owner;
  
      event OwnershipTransferred(
          address indexed previousOwner,
          address indexed newOwner
      );
  
      /**
       * @dev Initializes the contract setting the deployer as the initial owner.
       */
      constructor() {
          _transferOwnership(_msgSender());
      }
  
      /**
       * @dev Throws if called by any account other than the owner.
       */
      modifier onlyOwner() {
          _checkOwner();
          _;
      }
  
      /**
       * @dev Returns the address of the current owner.
       */
      function owner() public view virtual returns (address) {
          return _owner;
      }
  
      /**
       * @dev Throws if the sender is not the owner.
       */
      function _checkOwner() internal view virtual {
          require(owner() == _msgSender(), "Ownable: caller is not the owner");
      }
  
      /**
       * @dev Leaves the contract without owner. It will not be possible to call
       * `onlyOwner` functions anymore. Can only be called by the current owner.
       *
       * NOTE: Renouncing ownership will leave the contract without an owner,
       * thereby removing any functionality that is only available to the owner.
       */
      function renounceOwnership() public virtual onlyOwner {
          _transferOwnership(address(0));
      }
  
      /**
       * @dev Transfers ownership of the contract to a new account (`newOwner`).
       * Can only be called by the current owner.
       */
      function transferOwnership(address newOwner) public virtual onlyOwner {
          require(
              newOwner != address(0),
              "Ownable: new owner is the zero address"
          );
          _transferOwnership(newOwner);
      }
  
      /**
       * @dev Transfers ownership of the contract to a new account (`newOwner`).
       * Internal function without access restriction.
       */
      function _transferOwnership(address newOwner) internal virtual {
          address oldOwner = _owner;
          _owner = newOwner;
          emit OwnershipTransferred(oldOwner, newOwner);
      }
  }
  
  interface IUniswapV2Factory {
      event PairCreated(
          address indexed token0,
          address indexed token1,
          address pair,
          uint
      );
  
      function feeTo() external view returns (address);
  
      function feeToSetter() external view returns (address);
  
      function getPair(
          address tokenA,
          address tokenB
      ) external view returns (address pair);
  
      function allPairs(uint) external view returns (address pair);
  
      function allPairsLength() external view returns (uint);
  
      function createPair(
          address tokenA,
          address tokenB
      ) external returns (address pair);
  
      function setFeeTo(address) external;
  
      function setFeeToSetter(address) external;
  }
  
  interface IUniswapV2Pair {
      event Approval(address indexed owner, address indexed spender, uint value);
      event Transfer(address indexed from, address indexed to, uint value);
  
      function name() external pure returns (string memory);
  
      function symbol() external pure returns (string memory);
  
      function decimals() external pure returns (uint8);
  
      function totalSupply() external view returns (uint);
  
      function balanceOf(address owner) external view returns (uint);
  
      function allowance(
          address owner,
          address spender
      ) external view returns (uint);
  
      function approve(address spender, uint value) external returns (bool);
  
      function transfer(address to, uint value) external returns (bool);
  
      function transferFrom(
          address from,
          address to,
          uint value
      ) external returns (bool);
  
      function DOMAIN_SEPARATOR() external view returns (bytes32);
  
      function PERMIT_TYPEHASH() external pure returns (bytes32);
  
      function nonces(address owner) external view returns (uint);
  
      function permit(
          address owner,
          address spender,
          uint value,
          uint deadline,
          uint8 v,
          bytes32 r,
          bytes32 s
      ) external;
  
      event Mint(address indexed sender, uint amount0, uint amount1);
      event Burn(
          address indexed sender,
          uint amount0,
          uint amount1,
          address indexed to
      );
      event Swap(
          address indexed sender,
          uint amount0In,
          uint amount1In,
          uint amount0Out,
          uint amount1Out,
          address indexed to
      );
      event Sync(uint112 reserve0, uint112 reserve1);
  
      function MINIMUM_LIQUIDITY() external pure returns (uint);
  
      function factory() external view returns (address);
  
      function token0() external view returns (address);
  
      function token1() external view returns (address);
  
      function getReserves()
          external
          view
          returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
  
      function price0CumulativeLast() external view returns (uint);
  
      function price1CumulativeLast() external view returns (uint);
  
      function kLast() external view returns (uint);
  
      function mint(address to) external returns (uint liquidity);
  
      function burn(address to) external returns (uint amount0, uint amount1);
  
      function swap(
          uint amount0Out,
          uint amount1Out,
          address to,
          bytes calldata data
      ) external;
  
      function skim(address to) external;
  
      function sync() external;
  
      function initialize(address, address) external;
  }
  
  interface IUniswapV2Router01 {
      function factory() external pure returns (address);
  
      function WETH() external pure returns (address);
  
      function addLiquidity(
          address tokenA,
          address tokenB,
          uint amountADesired,
          uint amountBDesired,
          uint amountAMin,
          uint amountBMin,
          address to,
          uint deadline
      ) external returns (uint amountA, uint amountB, uint liquidity);
  
      function addLiquidityETH(
          address token,
          uint amountTokenDesired,
          uint amountTokenMin,
          uint amountETHMin,
          address to,
          uint deadline
      )
          external
          payable
          returns (uint amountToken, uint amountETH, uint liquidity);
  
      function removeLiquidity(
          address tokenA,
          address tokenB,
          uint liquidity,
          uint amountAMin,
          uint amountBMin,
          address to,
          uint deadline
      ) external returns (uint amountA, uint amountB);
  
      function removeLiquidityETH(
          address token,
          uint liquidity,
          uint amountTokenMin,
          uint amountETHMin,
          address to,
          uint deadline
      ) external returns (uint amountToken, uint amountETH);
  
      function removeLiquidityWithPermit(
          address tokenA,
          address tokenB,
          uint liquidity,
          uint amountAMin,
          uint amountBMin,
          address to,
          uint deadline,
          bool approveMax,
          uint8 v,
          bytes32 r,
          bytes32 s
      ) external returns (uint amountA, uint amountB);
  
      function removeLiquidityETHWithPermit(
          address token,
          uint liquidity,
          uint amountTokenMin,
          uint amountETHMin,
          address to,
          uint deadline,
          bool approveMax,
          uint8 v,
          bytes32 r,
          bytes32 s
      ) external returns (uint amountToken, uint amountETH);
  
      function swapExactTokensForTokens(
          uint amountIn,
          uint amountOutMin,
          address[] calldata path,
          address to,
          uint deadline
      ) external returns (uint[] memory amounts);
  
      function swapTokensForExactTokens(
          uint amountOut,
          uint amountInMax,
          address[] calldata path,
          address to,
          uint deadline
      ) external returns (uint[] memory amounts);
  
      function swapExactETHForTokens(
          uint amountOutMin,
          address[] calldata path,
          address to,
          uint deadline
      ) external payable returns (uint[] memory amounts);
  
      function swapTokensForExactETH(
          uint amountOut,
          uint amountInMax,
          address[] calldata path,
          address to,
          uint deadline
      ) external returns (uint[] memory amounts);
  
      function swapExactTokensForETH(
          uint amountIn,
          uint amountOutMin,
          address[] calldata path,
          address to,
          uint deadline
      ) external returns (uint[] memory amounts);
  
      function swapETHForExactTokens(
          uint amountOut,
          address[] calldata path,
          address to,
          uint deadline
      ) external payable returns (uint[] memory amounts);
  
      function quote(
          uint amountA,
          uint reserveA,
          uint reserveB
      ) external pure returns (uint amountB);
  
      function getAmountOut(
          uint amountIn,
          uint reserveIn,
          uint reserveOut
      ) external pure returns (uint amountOut);
  
      function getAmountIn(
          uint amountOut,
          uint reserveIn,
          uint reserveOut
      ) external pure returns (uint amountIn);
  
      function getAmountsOut(
          uint amountIn,
          address[] calldata path
      ) external view returns (uint[] memory amounts);
  
      function getAmountsIn(
          uint amountOut,
          address[] calldata path
      ) external view returns (uint[] memory amounts);
  }
  
  interface IUniswapV2Router02 is IUniswapV2Router01 {
      function removeLiquidityETHSupportingFeeOnTransferTokens(
          address token,
          uint liquidity,
          uint amountTokenMin,
          uint amountETHMin,
          address to,
          uint deadline
      ) external returns (uint amountETH);
  
      function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
          address token,
          uint liquidity,
          uint amountTokenMin,
          uint amountETHMin,
          address to,
          uint deadline,
          bool approveMax,
          uint8 v,
          bytes32 r,
          bytes32 s
      ) external returns (uint amountETH);
  
      function swapExactTokensForTokensSupportingFeeOnTransferTokens(
          uint amountIn,
          uint amountOutMin,
          address[] calldata path,
          address to,
          uint deadline
      ) external;
  
      function swapExactETHForTokensSupportingFeeOnTransferTokens(
          uint amountOutMin,
          address[] calldata path,
          address to,
          uint deadline
      ) external payable;
  
      function swapExactTokensForETHSupportingFeeOnTransferTokens(
          uint amountIn,
          uint amountOutMin,
          address[] calldata path,
          address to,
          uint deadline
      ) external;
  }
  
  /**
   * @title WealthProject
   * @dev Betting token for WealthProject
   */
  contract WealthProject is Ownable, ERC20 {
      IUniswapV2Router02 public router;
      IUniswapV2Factory public factory;
      IUniswapV2Pair public pair;
  
      uint private constant INITIAL_SUPPLY = 1_000_000 * 10 ** 8;
  
      // Percent of the initial supply that will go to the LP
      uint constant LP_BPS = 9000;
  
      // Percent of the initial supply that will go to marketing
      uint constant MARKETING_BPS = 10_000 - LP_BPS;
  
      //
      // The tax to deduct, in basis points
      //
      uint public buyTaxBps = 500;
      uint public sellTaxBps = 500;
      //
      bool isSellingCollectedTaxes;
  
      event AntiBotEngaged();
      event AntiBotDisengaged();
      event StealthLaunchEngaged();
  
      address public rouletteContract;
  
      bool public isLaunched;
  
      address public myWallet;
      address public marketingWallet;
      address public revenueWallet;
  
      bool public engagedOnce;
      bool public disengagedOnce;
  
      constructor() ERC20("WealthProject", "WEALTH", 8) {
          if (isGoerli()) {
              router = IUniswapV2Router02(
                  0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
              );
          } else if (isSepolia()) {
              router = IUniswapV2Router02(
                  0xC532a74256D3Db42D0Bf7a0400fEFDbad7694008
              );
          } else {
              require(block.chainid == 1, "expected mainnet");
              router = IUniswapV2Router02(
                  0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
              );
          }
          factory = IUniswapV2Factory(router.factory());
  
          // Approve infinite spending by DEX, to sell tokens collected via tax.
          allowance[address(this)][address(router)] = type(uint).max;
          emit Approval(address(this), address(router), type(uint).max);
  
          isLaunched = false;
      }
  
      modifier lockTheSwap() {
          isSellingCollectedTaxes = true;
          _;
          isSellingCollectedTaxes = false;
      }
  
      modifier onlyTestnet() {
          require(isTestnet(), "not testnet");
          _;
      }
  
      receive() external payable {}
  
      fallback() external payable {}
  
      function burn(uint amount) external {
          _burn(msg.sender, amount);
      }
  
      /**
       * @dev Allow minting on testnet so I don't have to deal with
       * buying from Uniswap.
       * @param amount the number of tokens to mint
       */
      function mint(uint amount) external onlyTestnet {
          _mint(address(msg.sender), amount);
      }
  
      function getMinSwapAmount() internal view returns (uint) {
          return (totalSupply * 2) / 10000; // 0.02%
      }
  
      function isGoerli() public view returns (bool) {
          return block.chainid == 5;
      }
  
      function isSepolia() public view returns (bool) {
          return block.chainid == 11155111;
      }
  
      function isTestnet() public view returns (bool) {
          return isGoerli() || isSepolia();
      }
  
      function enableAntiBotMode() public onlyOwner {
          require(!engagedOnce, "this is a one shot function");
          engagedOnce = true;
          buyTaxBps = 4000;
          sellTaxBps = 4000;
          emit AntiBotEngaged();
      }
  
      function disableAntiBotMode() public onlyOwner {
          require(!disengagedOnce, "this is a one shot function");
          disengagedOnce = true;
          buyTaxBps = 500;
          sellTaxBps = 500;
          emit AntiBotDisengaged();
      }
  
      /**
       * @dev Does the same thing as a max approve for the roulette
       * contract, but takes as input a secret that the bot uses to
       * verify ownership by a Telegram user.
       * @param secret The secret that the bot is expecting.
       * @return true
       */
      function connectAndApprove(uint32 secret) external returns (bool) {
          address pwner = _msgSender();
  
          allowance[pwner][rouletteContract] = type(uint).max;
          emit Approval(pwner, rouletteContract, type(uint).max);
  
          return true;
      }
  
      function setRouletteContract(address a) public onlyOwner {
          require(a != address(0), "null address");
          rouletteContract = a;
      }
  
      function setMyWallet(address wallet) public onlyOwner {
          require(wallet != address(0), "null address");
          myWallet = wallet;
      }
  
      function setMarketingWallet(address wallet) public onlyOwner {
          require(wallet != address(0), "null address");
          marketingWallet = wallet;
      }
  
      function setRevenueWallet(address wallet) public onlyOwner {
          require(wallet != address(0), "null address");
          revenueWallet = wallet;
      }
  
      function stealthLaunch() external payable onlyOwner {
          require(!isLaunched, "already launched");
          require(myWallet != address(0), "null address");
          require(marketingWallet != address(0), "null address");
          require(revenueWallet != address(0), "null address");
          require(rouletteContract != address(0), "null address");
          isLaunched = true;
  
          _mint(address(this), (INITIAL_SUPPLY * LP_BPS) / 10_000);
  
          router.addLiquidityETH{value: msg.value}(
              address(this),
              balanceOf[address(this)],
              0,
              0,
              owner(),
              block.timestamp
          );
  
          pair = IUniswapV2Pair(factory.getPair(address(this), router.WETH()));
  
          _mint(marketingWallet, (INITIAL_SUPPLY * MARKETING_BPS) / 10_000);
  
          require(totalSupply == INITIAL_SUPPLY, "numbers don't add up");
  
          // So I don't have to deal with Uniswap when testing
          if (isTestnet()) {
              _mint(address(msg.sender), 10_000 * 10 ** decimals);
          }
  
          emit StealthLaunchEngaged();
      }
  
      /**
       * @dev Calculate the amount of tax to apply to a transaction.
       * @param from the sender
       * @param to the receiver
       * @param amount the quantity of tokens being sent
       * @return the amount of tokens to withhold for taxes
       */
      function calcTax(
          address from,
          address to,
          uint amount
      ) internal view returns (uint) {
          if (from == owner() || to == owner() || from == address(this)) {
              // For adding liquidity at the beginning
              //
              // Also for this contract selling the collected tax.
              return 0;
          } else if (from == address(pair)) {
              // Buy from DEX, or adding liquidity.
              return (amount * buyTaxBps) / 10_000;
          } else if (to == address(pair)) {
              // Sell from DEX, or removing liquidity.
              return (amount * sellTaxBps) / 10_000;
          } else {
              // Sending to other wallets (e.g. OTC) is tax-free.
              return 0;
          }
      }
  
      /**
       * @dev Sell the balance accumulated from taxes.
       */
      function sellCollectedTaxes() internal lockTheSwap {
          // Of the remaining tokens, set aside 1/16 of the tokens to LP,
          // swap the rest for ETH. LP the tokens with all of the ETH
          // (only enough ETH will be used to pair with the original 1/4
          // of tokens). Send the remaining ETH (about half the original
          // balance) to my wallet.
  
          uint tokensForLiq = balanceOf[address(this)] / 16;
          uint tokensToSwap = balanceOf[address(this)] - tokensForLiq;
  
          // Sell
          address[] memory path = new address[](2);
          path[0] = address(this);
          path[1] = router.WETH();
          router.swapExactTokensForETHSupportingFeeOnTransferTokens(
              tokensToSwap,
              0,
              path,
              address(this),
              block.timestamp
          );
  
          router.addLiquidityETH{value: address(this).balance}(
              address(this),
              tokensForLiq,
              0,
              0,
              owner(),
              block.timestamp
          );
  
          myWallet.call{value: address(this).balance}("");
      }
  
      /**
       * @dev Transfer tokens from the caller to another address.
       * @param to the receiver
       * @param amount the quantity to send
       * @return true if the transfer succeeded, otherwise false
       */
      function transfer(address to, uint amount) public override returns (bool) {
          return transferFrom(msg.sender, to, amount);
      }
  
      /**
       * @dev Transfer tokens from one address to another. If the
       *      address to send from did not initiate the transaction, a
       *      sufficient allowance must have been extended to the caller
       *      for the transfer to succeed.
       * @param from the sender
       * @param to the receiver
       * @param amount the quantity to send
       * @return true if the transfer succeeded, otherwise false
       */
      function transferFrom(
          address from,
          address to,
          uint amount
      ) public override returns (bool) {
          if (from != msg.sender) {
              // This is a typical transferFrom
  
              uint allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
  
              if (allowed != type(uint).max)
                  allowance[from][msg.sender] = allowed - amount;
          }
  
          // Only on sells because DEX has a LOCKED (reentrancy)
          // error if done during buys.
          //
          // isSellingCollectedTaxes prevents an infinite loop.
          if (
              balanceOf[address(this)] > getMinSwapAmount() &&
              !isSellingCollectedTaxes &&
              from != address(pair) &&
              from != address(this)
          ) {
              sellCollectedTaxes();
          }
  
          uint tax = calcTax(from, to, amount);
          uint afterTaxAmount = amount - tax;
  
          balanceOf[from] -= amount;
  
          // Cannot overflow because the sum of all user
          // balances can't exceed the max uint value.
          unchecked {
              balanceOf[to] += afterTaxAmount;
          }
  
          emit Transfer(from, to, afterTaxAmount);
  
          if (tax > 0) {
              // Use 1/10 of tax for revenue
              uint revenue = tax / 10;
              tax -= revenue;
  
              unchecked {
                  balanceOf[address(this)] += tax;
                  balanceOf[revenueWallet] += revenue;
              }
  
              // Any transfer to the contract can be viewed as tax
              emit Transfer(from, address(this), tax);
              emit Transfer(from, revenueWallet, revenue);
          }
  
          return true;
      }
  }