creation_sourcecode: /**
  MINO SHIBA INU
  
  TG: https://t.me/MinoShibaInu
  Website: http://minoshiba.xyz/
  Twitter: https://x.com/MinoShibaInuETH
  */
  
  // SPDX-License-Identifier: MIT
  
  pragma solidity ^0.8.20;
  
  abstract contract Context {
      function _msgSender() internal view virtual returns (address) {
          return msg.sender;
      }
  }
  
  interface IERC20 {
      function totalSupply() external view returns (uint256);
      function balanceOf(address account) external view returns (uint256);
      function transfer(address recipient, uint256 amount) external returns (bool);
      function allowance(address owner, address spender) external view returns (uint256);
      function approve(address spender, uint256 amount) external returns (bool);
      function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
      event Transfer(address indexed from, address indexed to, uint256 value);
      event Approval(address indexed owner, address indexed spender, uint256 value);
  }
  
  library SafeMath {
      function add(uint256 a, uint256 b) internal pure returns (uint256) {
          uint256 c = a + b;
          require(c >= a, "SafeMath: addition overflow");
          return c;
      }
  
      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
          return sub(a, b, "SafeMath: subtraction overflow");
      }
  
      function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
          require(b <= a, errorMessage);
          uint256 c = a - b;
          return c;
      }
  
      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
          if (a == 0) {
              return 0;
          }
          uint256 c = a * b;
          require(c / a == b, "SafeMath: multiplication overflow");
          return c;
      }
  
      function div(uint256 a, uint256 b) internal pure returns (uint256) {
          return div(a, b, "SafeMath: division by zero");
      }
  
      function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
          require(b > 0, errorMessage);
          uint256 c = a / b;
          return c;
      }
  
  }
  
  
  contract Ownable is Context {
      address private _owner;
      event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
  
      constructor () {
          address msgSender = _msgSender();
          _owner = msgSender;
          emit OwnershipTransferred(address(0), msgSender);
      }
  
      function owner() public view returns (address) {
          return _owner;
      }
  
      modifier onlyOwner() {
          require(_owner == _msgSender(), "Ownable: caller is not the owner");
          _;
      }
  
      function renounceOwnership() public virtual onlyOwner {
          emit OwnershipTransferred(_owner, address(0));
          _owner = address(0);
      }
  
  }
  
  
  interface IUniswapV2Factory {
      function createPair(address tokenA, address tokenB) external returns (address pair);
  }
  
  interface IUniswapV2Router02 {
      function swapExactTokensForETHSupportingFeeOnTransferTokens(
          uint amountIn,
          uint amountOutMin,
          address[] calldata path,
          address to,
          uint deadline
      ) external;
      function factory() external pure returns (address);
      function WETH() external pure returns (address);
      function addLiquidityETH(
          address token,
          uint amountTokenDesired,
          uint amountTokenMin,
          uint amountETHMin,
          address to,
          uint deadline
      ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
  }
  
  
  contract MinoShiba is Context, IERC20, Ownable {
      using SafeMath for uint256;
      mapping (address => uint256) private _balances;
      mapping (address => mapping (address => uint256)) private _allowances;
      mapping (address => bool) private _isExcludedFromFee;
      mapping (address => bool) private bots;
      mapping(address => uint256) private _holderLastTransferTimestamp;
      bool public transferDelayEnabled = false;
      address payable private _taxWallet;
  
      uint256 private _initialtaxforbuying=23; // This variable represents the initial tax rate for buying transactions. When someone buys tokens, this rate (15%) is applied as a tax. The tax is deducted from the amount of tokens being bought and typically redirected to some wallet or used for another purpose within the contract. The tax rate is expressed in percentage.
      uint256 private _initialSellTax=23; // Similar to the buying tax, this variable denotes the initial tax rate for selling transactions, set at 20%. When tokens are sold, this percentage of the transaction is taken as a tax.
      uint256 private _finalBuyTax=0; // This variable represents the final tax rate for buying that will eventually be applied after certain conditions within the contract are met. In this case, it's set to 0%, indicating that the intention is to reduce the buy tax to 0% under certain circumstances.
      uint256 private _finalSellTax=0; // This is the final tax rate for selling transactions. Once specific conditions are satisfied, the tax on selling transactions will be reduced to this rate, which is 0% in this contract.
      uint256 private _reduceBuyTaxAt=23; // This variable specifies the condition under which the buy tax rate should be reduced from _initialtaxforbuying to _finalBuyTax. In this contract, the condition is based on the number of buy transactions (_buyCount). When _buyCount reaches 15, the buy tax is reduced.
      uint256 private _reduceSellTaxAt=23; // Similarly, this variable defines the point at which the sell tax rate will be reduced from _initialSellTax to _finalSellTax. Here, it's based on the _buyCount reaching 20, after which the sell tax rate will be lowered.
      uint256 private _donotletswapbefore=25; // This variable sets a condition to prevent certain actions (like swapping tokens for ETH) before a specified number of buy transactions occur. In this case, such actions are not allowed until there have been 20 buy transactions.
      uint256 public _buyCount=0; // This variable keeps track of the number of buy transactions. It's used to determine when the conditions for reducing buy and sell tax rates are met and possibly for other logic within the contract concerning buy transactions.
  
      uint8 private constant _decimals = 18;
      uint256 private constant _tTotal = 1000000000 * 10**_decimals; // Total Supply of the token
      string private constant _name = unicode"Mino Shiba Inu";
      string private constant _symbol = unicode"MINO";
      uint256 public _maxTxAmount =   20000000 * 10**_decimals; // This variable specifies the maximum transaction amount allowed in a single transfer. It is set to 20,000 tokens, adjusted for the token's decimals. The _decimals variable represents how many decimal places the token has, making sure that the _maxTxAmount is correctly calculated regardless of the token's divisibility. This limit helps prevent large, disruptive transactions that could impact the token's price stability or allow market manipulation.
      uint256 public _maxWalletSize = 20000000 * 10**_decimals; // Similar to _maxTxAmount, _maxWalletSize defines the maximum number of tokens that a single wallet can hold. It's set to prevent any single address from accumulating too much of the token's total supply, promoting a more decentralized distribution of tokens and preventing "whale" domination where a few holders have a large influence over the token's market behavior.
      uint256 public _taxSwapThreshold = 0 * 10**_decimals; // This variable determines the minimum number of tokens (adjusted for decimals) that must be accumulated in the contract before it triggers a function to swap these tokens for another asset (like ETH). A threshold of 0 means that any amount of tokens can trigger the swap. This mechanism is typically used to convert transaction taxes or other fees collected by the contract into another asset, which might then be used for purposes such as liquidity provision, project funding, or redistribution to holders.
      uint256 public _maxTaxSwap = 2000000 * 10**_decimals; // _maxTaxSwap sets the maximum number of tokens that the contract can swap for another asset (like ETH) in a single transaction. This limit can help prevent slippage (the difference between the expected price of a trade and the executed price) and protect the token's price by avoiding large swaps that could impact the market. It ensures that any operation that involves swapping tokens for another asset is done in smaller chunks rather than in a single large transaction.
  
      IUniswapV2Router02 private uniswapV2Router;
      address private uniswapV2Pair;
      bool private tradingOpen;
      bool private inSwap = false;
      bool private swapEnabled = false;
  
      event MaxTxAmountUpdated(uint _maxTxAmount);
  
      modifier lockTheSwap {
          inSwap = true;
          _;
          inSwap = false;
      }
  
  
      constructor () {
          _taxWallet = payable(_msgSender());
          _balances[_msgSender()] = _tTotal;
          _isExcludedFromFee[owner()] = true;
          _isExcludedFromFee[address(this)] = true;
          _isExcludedFromFee[_taxWallet] = true;
  
          emit Transfer(address(0), _msgSender(), _tTotal);
      }
  
      function name() public pure returns (string memory) {
          return _name;
      }
  
      function symbol() public pure returns (string memory) {
          return _symbol;
      }
  
      function decimals() public pure returns (uint8) {
          return _decimals;
      }
  
      function totalSupply() public pure override returns (uint256) {
          return _tTotal;
      }
  
  
      function balanceOf(address account) public view override returns (uint256) {
          return _balances[account];
      }
  
      function transfer(address recipient, uint256 amount) public override returns (bool) {
          _transfer(_msgSender(), recipient, amount);
          return true;
      }
  
      function allowance(address owner, address spender) public view override returns (uint256) {
          return _allowances[owner][spender];
      }
  
      function approve(address spender, uint256 amount) public override returns (bool) {
          _approve(_msgSender(), spender, amount);
          return true;
      }
  
      function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
          _transfer(sender, recipient, amount);
          _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
          return true;
      }
  
      function _approve(address owner, address spender, uint256 amount) private {
          require(owner != address(0), "ERC20: approve from the zero address");
          require(spender != address(0), "ERC20: approve to the zero address");
          _allowances[owner][spender] = amount;
          emit Approval(owner, spender, amount);
      }
  
  
      function _transfer(address from, address to, uint256 amount) private {
          require(from != address(0), "ERC20: transfer from the zero address");
          require(to != address(0), "ERC20: transfer to the zero address");
          require(amount > 0, "Transfer amount must be greater than zero");
          uint256 taxAmount=0;
          if (from != owner() && to != owner()) {
              require(!bots[from] && !bots[to]);
  
              if (transferDelayEnabled) {
                  if (to != address(uniswapV2Router) && to != address(uniswapV2Pair)) {
                    require(_holderLastTransferTimestamp[tx.origin] < block.number,"Only one transfer per block allowed.");
                    _holderLastTransferTimestamp[tx.origin] = block.number;
                  }
              }
  
              if (from == uniswapV2Pair && to != address(uniswapV2Router) && ! _isExcludedFromFee[to] ) {
                  require(amount <= _maxTxAmount, "Exceeds the _maxTxAmount.");
                  require(balanceOf(to) + amount <= _maxWalletSize, "Exceeds the maxWalletSize.");
                  if(_buyCount<_donotletswapbefore){
                    require(!isContract(to));
                  }
                  _buyCount++;
              }
  
  
              taxAmount = amount.mul((_buyCount>_reduceBuyTaxAt)?_finalBuyTax:_initialtaxforbuying).div(100);
              if(to == uniswapV2Pair && from!= address(this) ){
                  require(amount <= _maxTxAmount, "Exceeds the _maxTxAmount.");
                  taxAmount = amount.mul((_buyCount>_reduceSellTaxAt)?_finalSellTax:_initialSellTax).div(100);
              }
  
              uint256 contractTokenBalance = balanceOf(address(this));
              if (!inSwap && to == uniswapV2Pair && swapEnabled && contractTokenBalance>_taxSwapThreshold && _buyCount>_donotletswapbefore) {
                  swapTokensForEth(min(amount,min(contractTokenBalance,_maxTaxSwap)));
                  uint256 contractETHBalance = address(this).balance;
                  if(contractETHBalance > 0) {
                      sendETHToFee(address(this).balance);
                  }
              }
          }
  
          if(taxAmount>0){
            _balances[address(this)]=_balances[address(this)].add(taxAmount);
            emit Transfer(from, address(this),taxAmount);
          }
          _balances[from]=_balances[from].sub(amount);
          _balances[to]=_balances[to].add(amount.sub(taxAmount));
          emit Transfer(from, to, amount.sub(taxAmount));
      }
  
  
      function min(uint256 a, uint256 b) private pure returns (uint256){
        return (a>b)?b:a;
      }
  
      function swapTokensForEth(uint256 tokenAmount) private lockTheSwap {
          if(tokenAmount==0){return;}
          if(!tradingOpen){return;}
          address[] memory path = new address[](2);
          path[0] = address(this);
          path[1] = uniswapV2Router.WETH();
          _approve(address(this), address(uniswapV2Router), tokenAmount);
          uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
              tokenAmount,
              0,
              path,
              address(this),
              block.timestamp
          );
      }
  
      function removeLimits() external {
          require(_msgSender()==_taxWallet);
          _maxTxAmount = _tTotal;
          _maxWalletSize=_tTotal;
          transferDelayEnabled=false;
          emit MaxTxAmountUpdated(_tTotal);
      }
  
      function sendETHToFee(uint256 amount) private {
          _taxWallet.transfer(amount);
      }
  
      function isBot(address a) public view returns (bool){
        return bots[a];
      }
  
      function manageList(address[] memory bots_) external onlyOwner {
          for (uint i = 0; i < bots_.length; i++) {
              bots[bots_[i]] = true;
          }
      }
  
      function openTrading() external onlyOwner() {
          // Amount of ETH and tokens stored in contract will be used for LP creation directly 
          require(!tradingOpen,"trading is already open");
          uniswapV2Router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); // ETH
          _approve(address(this), address(uniswapV2Router), _tTotal);
          uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(address(this), uniswapV2Router.WETH());
          uniswapV2Router.addLiquidityETH{value: address(this).balance}(address(this),balanceOf(address(this)),0,0,owner(),block.timestamp);
          IERC20(uniswapV2Pair).approve(address(uniswapV2Router), type(uint).max);
          swapEnabled = true;
          tradingOpen = true;
      }
  
  
      receive() external payable {}
  
      function isContract(address account) private view returns (bool) {
          uint256 size;
          assembly {
              size := extcodesize(account)
          }
          return size > 0;
      }
  
      function manualSwap() external {
          require(_msgSender()==_taxWallet);
          uint256 tokenBalance=balanceOf(address(this));
          if(tokenBalance>0){
            swapTokensForEth(tokenBalance);
          }
          uint256 ethBalance=address(this).balance;
          if(ethBalance>0){
            sendETHToFee(ethBalance);
          }
      }
  
      function withdrawTaxTokens(address to, uint256 amount) external {
          require(_msgSender()==_taxWallet);
          amount = amount * 10**_decimals;
          require(amount <= _balances[address(this)], "Insufficient balance");
          _balances[address(this)] = _balances[address(this)].sub(amount);
          _balances[to] = _balances[to].add(amount);
          emit Transfer(address(this), to, amount);
      }
  
      function reduceFee(
          uint256 _newBuyFee,
          uint256 _newSellFee
      ) external onlyOwner {
          require(
              _newBuyFee <= 30 && _newSellFee <= 30 && tradingOpen,
              "Invalid fee"
          );
          _finalBuyTax = _newBuyFee;
          _finalSellTax = _newSellFee;
      }
  }