contract ANON is Context, IERC20, Ownable {
      using SafeMath for uint256;
      using Address for address;
    
      mapping (address => uint256) private _rOwned;
      mapping (address => uint256) private _tOwned;
      mapping (address => mapping (address => uint256)) private _allowances;
    
      mapping (address => bool) private _isExcludedFromFee;
    
      mapping (address => bool) private _isExcluded;
      address[] private _excluded;
      mapping (address => bool) private _isBlackListedBot;
      address[] private _blackListedBots;
    
      uint256 private constant MAX = ~uint256(0);
      uint256 private _tTotal = 500000000000 * 10**9;
      uint256 private _rTotal = (MAX - (MAX % _tTotal));
      uint256 private _tFeeTotal;
    
      string private _name = 'Anonymous';
      string private _symbol = 'ANON';
      uint8 private _decimals = 9;
    
      uint256 private _taxFee = 2;
      uint256 private _teamFee = 10;
      uint256 private _previousTaxFee = _taxFee;
      uint256 private _previousTeamFee = _teamFee;
    
      address payable public _devWalletAddress1;
      address payable public _devWalletAddress2;
      address payable public _marketingWalletAddress;
      address payable public _dipWalletAddress;
    
      IUniswapV2Router02 public immutable uniswapV2Router;
      address public immutable uniswapV2Pair;
    
      bool inSwap = false;
      bool public swapEnabled = true;
    
      uint256 private _maxTxAmount = 5000000000 * 10**9;
      uint256 private _numOfTokensToExchangeForTeam = 10000 * 10**9;
    
      event MinTokensBeforeSwapUpdated(uint256 minTokensBeforeSwap);
      event SwapEnabledUpdated(bool enabled);
    
      modifier lockTheSwap {
          inSwap = true;
          _;
          inSwap = false;
      }
    
      constructor (address payable devWalletAddress1, address payable devWalletAddress2, address payable marketingWalletAddress, address payable dipWalletAddress) public {
          _devWalletAddress1 = devWalletAddress1;
          _devWalletAddress2 = devWalletAddress2;
          _marketingWalletAddress = marketingWalletAddress;
          _dipWalletAddress = dipWalletAddress;
          _rOwned[_msgSender()] = _rTotal;
    
          IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
          // Create a uniswap pair for this new token
          uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
              .createPair(address(this), _uniswapV2Router.WETH());
    
          // set the rest of the contract variables
          uniswapV2Router = _uniswapV2Router;
    
          // Exclude owner and this contract from fee
          _isExcludedFromFee[owner()] = true;
          _isExcludedFromFee[address(this)] = true;
    
          emit Transfer(address(0), _msgSender(), _tTotal);
      }
    
      function name() public view returns (string memory) {
          return _name;
      }
    
      function symbol() public view returns (string memory) {
          return _symbol;
      }
    
      function decimals() public view returns (uint8) {
          return _decimals;
      }
    
      function totalSupply() public view override returns (uint256) {
          return _tTotal;
      }
    
      function balanceOf(address account) public view override returns (uint256) {
          if (_isExcluded[account]) return _tOwned[account];
          return tokenFromReflection(_rOwned[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 increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
          _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
          return true;
      }
    
      function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
          _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
          return true;
      }
    
      function isExcluded(address account) public view returns (bool) {
          return _isExcluded[account];
      }
    
      function setExcludeFromFee(address account, bool excluded) external onlyOwner() {
          _isExcludedFromFee[account] = excluded;
      }
    
      function totalFees() public view returns (uint256) {
          return _tFeeTotal;
      }
    
      function deliver(uint256 tAmount) public {
          address sender = _msgSender();
          require(!_isExcluded[sender], "Excluded addresses cannot call this function");
          (uint256 rAmount,,,,,) = _getValues(tAmount);
          _rOwned[sender] = _rOwned[sender].sub(rAmount);
          _rTotal = _rTotal.sub(rAmount);
          _tFeeTotal = _tFeeTotal.add(tAmount);
      }
    
      function reflectionFromToken(uint256 tAmount, bool deductTransferFee) public view returns(uint256) {
          require(tAmount <= _tTotal, "Amount must be less than supply");
          if (!deductTransferFee) {
              (uint256 rAmount,,,,,) = _getValues(tAmount);
              return rAmount;
          } else {
              (,uint256 rTransferAmount,,,,) = _getValues(tAmount);
              return rTransferAmount;
          }
      }
    
      function tokenFromReflection(uint256 rAmount) public view returns(uint256) {
          require(rAmount <= _rTotal, "Amount must be less than total reflections");
          uint256 currentRate =  _getRate();
          return rAmount.div(currentRate);
      }
    
      function addBotToBlacklist (address account) external onlyOwner() {
         require(account != 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, 'We cannot blacklist UniSwap router');
         require (!_isBlackListedBot[account], 'Account is already blacklisted');
         _isBlackListedBot[account] = true;
         _blackListedBots.push(account);
      }
    
      function removeBotFromBlacklist(address account) external onlyOwner() {
        require (_isBlackListedBot[account], 'Account is not blacklisted');
        for (uint256 i = 0; i < _blackListedBots.length; i++) {
               if (_blackListedBots[i] == account) {
                   _blackListedBots[i] = _blackListedBots[_blackListedBots.length - 1];
                   _isBlackListedBot[account] = false;
                   _blackListedBots.pop();
                   break;
               }
         }
     }
    
      function excludeAccount(address account) external onlyOwner() {
          require(account != 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, 'We can not exclude Uniswap router.');
          require(!_isExcluded[account], "Account is already excluded");
          if(_rOwned[account] > 0) {
              _tOwned[account] = tokenFromReflection(_rOwned[account]);
          }
          _isExcluded[account] = true;
          _excluded.push(account);
      }
    
      function includeAccount(address account) external onlyOwner() {
          require(_isExcluded[account], "Account is already excluded");
          for (uint256 i = 0; i < _excluded.length; i++) {
              if (_excluded[i] == account) {
                  _excluded[i] = _excluded[_excluded.length - 1];
                  _tOwned[account] = 0;
                  _isExcluded[account] = false;
                  _excluded.pop();
                  break;
              }
          }
      }
    
      function removeAllFee() private {
          if(_taxFee == 0 && _teamFee == 0) return;
    
          _previousTaxFee = _taxFee;
          _previousTeamFee = _teamFee;
    
          _taxFee = 0;
          _teamFee = 0;
      }
    
      function restoreAllFee() private {
          _taxFee = _previousTaxFee;
          _teamFee = _previousTeamFee;
      }
    
      function isExcludedFromFee(address account) public view returns(bool) {
          return _isExcludedFromFee[account];
      }
    
      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 sender, address recipient, uint256 amount) private {
          require(sender != address(0), "ERC20: transfer from the zero address");
          require(recipient != address(0), "ERC20: transfer to the zero address");
          require(amount > 0, "Transfer amount must be greater than zero");
          require(!_isBlackListedBot[recipient], "You are blacklisted");
          require(!_isBlackListedBot[msg.sender], "You are blacklisted");
          require(!_isBlackListedBot[tx.origin], "You are blacklisted");
          if(sender != owner() && recipient != owner())
              require(amount <= _maxTxAmount, "Transfer amount exceeds the maxTxAmount.");
    
          // is the token balance of this contract address over the min number of
          // tokens that we need to initiate a swap?
          // also, don't get caught in a circular team event.
          // also, don't swap if sender is uniswap pair.
          uint256 contractTokenBalance = balanceOf(address(this));
    
          if(contractTokenBalance >= _maxTxAmount)
          {
              contractTokenBalance = _maxTxAmount;
          }
    
          bool overMinTokenBalance = contractTokenBalance >= _numOfTokensToExchangeForTeam;
          if (!inSwap && swapEnabled && overMinTokenBalance && sender != uniswapV2Pair) {
              // Swap tokens for ETH and send to resepctive wallets
              swapTokensForEth(contractTokenBalance);
    
              uint256 contractETHBalance = address(this).balance;
              if(contractETHBalance > 0) {
                  sendETHToTeam(address(this).balance);
              }
          }
    
          //indicates if fee should be deducted from transfer
          bool takeFee = true;
    
          //if any account belongs to _isExcludedFromFee account then remove the fee
          if(_isExcludedFromFee[sender] || _isExcludedFromFee[recipient]){
              takeFee = false;
          }
    
          //transfer amount, it will take tax and team fee
          _tokenTransfer(sender,recipient,amount,takeFee);
      }
    
      function swapTokensForEth(uint256 tokenAmount) private lockTheSwap{
          // generate the uniswap pair path of token -> weth
          address[] memory path = new address[](2);
          path[0] = address(this);
          path[1] = uniswapV2Router.WETH();
    
          _approve(address(this), address(uniswapV2Router), tokenAmount);
    
          // make the swap
          uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
              tokenAmount,
              0, // accept any amount of ETH
              path,
              address(this),
              block.timestamp
          );
      }
    
      function sendETHToTeam(uint256 amount) private {
          _devWalletAddress1.transfer(amount.div(10).mul(4));
          _devWalletAddress2.transfer(amount.div(10).mul(3));
          _marketingWalletAddress.transfer(amount.div(10).mul(2));
          _dipWalletAddress.transfer(amount.div(10));
      }
    
      function manualSwap() external onlyOwner() {
          uint256 contractBalance = balanceOf(address(this));
          swapTokensForEth(contractBalance);
      }
    
      function manualSend() external onlyOwner() {
          uint256 contractETHBalance = address(this).balance;
          sendETHToTeam(contractETHBalance);
      }
    
      function setSwapEnabled(bool enabled) external onlyOwner(){
          swapEnabled = enabled;
      }
    
      function _tokenTransfer(address sender, address recipient, uint256 amount, bool takeFee) private {
          if(!takeFee)
              removeAllFee();
    
          if (_isExcluded[sender] && !_isExcluded[recipient]) {
              _transferFromExcluded(sender, recipient, amount);
          } else if (!_isExcluded[sender] && _isExcluded[recipient]) {
              _transferToExcluded(sender, recipient, amount);
          } else if (!_isExcluded[sender] && !_isExcluded[recipient]) {
              _transferStandard(sender, recipient, amount);
          } else if (_isExcluded[sender] && _isExcluded[recipient]) {
              _transferBothExcluded(sender, recipient, amount);
          } else {
              _transferStandard(sender, recipient, amount);
          }
    
          if(!takeFee)
              restoreAllFee();
      }
    
      function _transferStandard(address sender, address recipient, uint256 tAmount) private {
          (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tTeam) = _getValues(tAmount);
          _rOwned[sender] = _rOwned[sender].sub(rAmount);
          _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
          _takeTeam(tTeam);
          _reflectFee(rFee, tFee);
          emit Transfer(sender, recipient, tTransferAmount);
      }
    
      function _transferToExcluded(address sender, address recipient, uint256 tAmount) private {
          (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tTeam) = _getValues(tAmount);
          _rOwned[sender] = _rOwned[sender].sub(rAmount);
          _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
          _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
          _takeTeam(tTeam);
          _reflectFee(rFee, tFee);
          emit Transfer(sender, recipient, tTransferAmount);
      }
    
      function _transferFromExcluded(address sender, address recipient, uint256 tAmount) private {
          (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tTeam) = _getValues(tAmount);
          _tOwned[sender] = _tOwned[sender].sub(tAmount);
          _rOwned[sender] = _rOwned[sender].sub(rAmount);
          _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
          _takeTeam(tTeam);
          _reflectFee(rFee, tFee);
          emit Transfer(sender, recipient, tTransferAmount);
      }
    
      function _transferBothExcluded(address sender, address recipient, uint256 tAmount) private {
          (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tTeam) = _getValues(tAmount);
          _tOwned[sender] = _tOwned[sender].sub(tAmount);
          _rOwned[sender] = _rOwned[sender].sub(rAmount);
          _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
          _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
          _takeTeam(tTeam);
          _reflectFee(rFee, tFee);
          emit Transfer(sender, recipient, tTransferAmount);
      }
    
      function _takeTeam(uint256 tTeam) private {
          uint256 currentRate =  _getRate();
          uint256 rTeam = tTeam.mul(currentRate);
          _rOwned[address(this)] = _rOwned[address(this)].add(rTeam);
          if(_isExcluded[address(this)])
              _tOwned[address(this)] = _tOwned[address(this)].add(tTeam);
      }
    
      function _reflectFee(uint256 rFee, uint256 tFee) private {
          _rTotal = _rTotal.sub(rFee);
          _tFeeTotal = _tFeeTotal.add(tFee);
      }
    
       //to recieve ETH from uniswapV2Router when swaping
      receive() external payable {}
    
      function _getValues(uint256 tAmount) private view returns (uint256, uint256, uint256, uint256, uint256, uint256) {
      (uint256 tTransferAmount, uint256 tFee, uint256 tTeam) = _getTValues(tAmount, _taxFee, _teamFee);
      uint256 currentRate = _getRate();
      (uint256 rAmount, uint256 rTransferAmount, uint256 rFee) = _getRValues(tAmount, tFee, tTeam, currentRate);
      return (rAmount, rTransferAmount, rFee, tTransferAmount, tFee, tTeam);
    }
    
      function _getTValues(uint256 tAmount, uint256 taxFee, uint256 teamFee) private pure returns (uint256, uint256, uint256) {
          uint256 tFee = tAmount.mul(taxFee).div(100);
          uint256 tTeam = tAmount.mul(teamFee).div(100);
          uint256 tTransferAmount = tAmount.sub(tFee).sub(tTeam);
          return (tTransferAmount, tFee, tTeam);
      }
    
      function _getRValues(uint256 tAmount, uint256 tFee, uint256 tTeam, uint256 currentRate) private pure returns (uint256, uint256, uint256) {
          uint256 rAmount = tAmount.mul(currentRate);
          uint256 rFee = tFee.mul(currentRate);
          uint256 rTeam = tTeam.mul(currentRate);
          uint256 rTransferAmount = rAmount.sub(rFee).sub(rTeam);
          return (rAmount, rTransferAmount, rFee);
      }
    
      function _getRate() private view returns(uint256) {
          (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
          return rSupply.div(tSupply);
      }
    
      function _getCurrentSupply() private view returns(uint256, uint256) {
          uint256 rSupply = _rTotal;
          uint256 tSupply = _tTotal;
          for (uint256 i = 0; i < _excluded.length; i++) {
              if (_rOwned[_excluded[i]] > rSupply || _tOwned[_excluded[i]] > tSupply) return (_rTotal, _tTotal);
              rSupply = rSupply.sub(_rOwned[_excluded[i]]);
              tSupply = tSupply.sub(_tOwned[_excluded[i]]);
          }
          if (rSupply < _rTotal.div(_tTotal)) return (_rTotal, _tTotal);
          return (rSupply, tSupply);
      }
    
      function _getTaxFee() public view returns(uint256) {
          return _taxFee;
      }
    
      function _getMaxTxAmount() public view returns(uint256) {
          return _maxTxAmount;
      }
    
      function _getETHBalance() public view returns(uint256 balance) {
          return address(this).balance;
      }
    
      function _setTaxFee(uint256 taxFee) external onlyOwner() {
          require(taxFee >= 1 && taxFee <= 25, 'taxFee should be in 1 - 25');
          _taxFee = taxFee;
      }
    
      function _setTeamFee(uint256 teamFee) external onlyOwner() {
          require(teamFee >= 1 && teamFee <= 25, 'teamFee should be in 1 - 25');
          _teamFee = teamFee;
      }
    
      function _setDevWallet1(address payable devWalletAddress1) external onlyOwner() {
          _devWalletAddress1 = devWalletAddress1;
      }
    
      function _setDevWallet2(address payable devWalletAddress2) external onlyOwner() {
          _devWalletAddress2 = devWalletAddress2;
      }
      function _setMarketingWallet(address payable marketingWalletAddress) external onlyOwner() {
          _marketingWalletAddress = marketingWalletAddress;
      }
    
    
      function _setMaxTxAmount(uint256 maxTxAmount) external onlyOwner() {
          _maxTxAmount = maxTxAmount;
      }
    }
//to recieve ETH from uniswapV2Router when swaping