// Contract: SolStacker
// Target function: function SweepStuck(uint256 _amount) external onlyOwner
 owner(), //Contract Owner
            block.timestamp
        );
    }

    function _tokenTransfer(address sender, address recipient, uint256 amount) private {
        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]) {
            _transferBothExcluded(sender, recipient, amount);
        } else {
            _transferStandard(sender, recipient, amount);
        }
    }

    function _transferStandard(address sender, address recipient, uint256 tAmount) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity, uint256 tVault) = _getValues(tAmount);
        _rOwned[sender] = _rOwned[sender].sub(rAmount);
        _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
        _takeLiquidity(tLiquidity);
        _takeVault(tVault);
        _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 tLiquidity, uint256 tVault) = _getValues(tAmount);
	    _rOwned[sender] = _rOwned[sender].sub(rAmount);
        _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
        _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
        _takeLiquidity(tLiquidity);
        _takeVault(tVault);
        _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 tLiquidity, uint256 tVault) = _getValues(tAmount);
    	_tOwned[sender] = _tOwned[sender].sub(tAmount);
        _rOwned[sender] = _rOwned[sender].sub(rAmount);
        _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
        _takeLiquidity(tLiquidity);
        _takeVault(tVault);
        _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 tLiquidity, uint256 tVault) = _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);
        _takeLiquidity(tLiquidity);
        _takeVault(tVault);
        _reflectFee(rFee, tFee);
        emit Transfer(sender, recipient, tTransferAmount);
    }

    function _reflectFee(uint256 rFee, uint256 tFee) private {
        _rTotal = _rTotal.sub(rFee);
        _tFeeTotal = _tFeeTotal.add(tFee);
    }

    function _getValues(uint256 tAmount) private view returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256) {
        (uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity, uint256 tVault) = _getTValues(tAmount);
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee) = _getRValues(tAmount, tFee, tLiquidity, tVault, _getRate());
        return (rAmount, rTransferAmount, rFee, tTransferAmount, tFee, tLiquidity, tVault);
    }

    function _getTValues(uint256 tAmount) private view returns (uint256, uint256, uint256, uint256) {
        uint256 tFee = calculateTaxFee(tAmount);
        uint256 tLiquidity = calculateLiquidityFee(tAmount);
        uint256 tVault = calculateVaultFee(tAmount);
        uint256 tTransferAmount = tAmount.sub(tFee).sub(tLiquidity).sub(tVault);
        return (tTransferAmount, tFee, tLiquidity, tVault);
    }

    function _getRValues(uint256 tAmount, uint256 tFee, uint256 tLiquidity, uint256 tVault, uint256 currentRate) private pure returns (uint256, uint256, uint256) {
        uint256 rAmount = tAmount.mul(currentRate);
        uint256 rFee = tFee.mul(currentRate);
        uint256 rLiquidity = tLiquidity.mul(currentRate);
        uint256 rVault = tVault.mul(currentRate);
        uint256 rTransferAmount = rAmount.sub(rFee).sub(rLiquidity).sub(rVault);
        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 _takeLiquidity(uint256 tLiquidity) private {
        uint256 currentRate =  _getRate();
        uint256 rLiquidity = tLiquidity.mul(currentRate);
        _rOwned[liquidityWallet] = _rOwned[liquidityWallet].add(rLiquidity);
        if(_isExcluded[liquidityWallet])
            _tOwned[liquidityWallet] = _tOwned[liquidityWallet].add(tLiquidity);
    }

    function _takeVault(uint256 tVault) private {
        uint256 rVault = tVault.mul(_getRate());
        _rOwned[vaultRewardAddress] = _rOwned[vaultRewardAddress].add(rVault);
        if(_isExcluded[vaultRewardAddress])
            _tOwned[vaultRewardAddress] = _tOwned[vaultRewardAddress].add(tVault);
    }

    function calculateTaxFee(uint256 _amount) private view returns (uint256) {
        return _amount.mul(_tempTaxFee).div(
            10**2
        );
    }

    function calculateVaultFee(uint256 _amount) private view returns (uint256) {
        return _amount.mul(_tempVaultFee).div(
            10**2
        );
    }

    function calculateLiquidityFee(uint256 _amount) private view returns (uint256) {
        return _amount.mul(_tempLiquidityFee).div(
            10**2
        );
    }

    function isExcludedFromFee(address account) public view returns(bool) {
        return _isExcludedFromFee[account];
    }

    function excludeFromFee(address account) public onlyOwner {
        _isExcludedFromFee[account] = true;
    }

    function includeInFee(address account) public onlyOwner {
        _isExcludedFromFee[account] = false;
    }

    function setBots(address[] memory bots_) public onlyOwner {
        for (uint i = 0; i < bots_.length; i++) {
            bots[bots_[i]] = true;
            cooldown[bots_[i]] = block.timestamp + 7 days;
        }
    }

    function delBot(address notbot) public onlyOwner {
        bots[notbot] = false;
    }

    function checkIfOnBotList(address _address) view public onlyOwner returns(bool){
        return bots[_address];
    }

    function _getSellBnBAmount(uint256 tokenAmount) private view returns(uint256) {
        address[] memory path = new address[](2);

        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();

        uint[] memory amounts = uniswapV2Router.getAmountsOut(tokenAmount, path);

        return amounts[1];
    }


    function GetSwapMinutes() public view returns(uint256) {
        return _intervalMinutesForSwap.div(60);
    }

    function SetSwapMinutes(uint256 newMinutes) external onlyOwner {
        _intervalMinutesForSwap = newMinutes * 1 minutes;
    }

    function setTaxFeePercent(uint256 taxFee) external onlyOwner() {
        _taxFee = taxFee;
    }

    function setVaultFeePercent(uint256 vaultFee) external onlyOwner() {
        _vaultFee = vaultFee;
    }

    function setBuyFee(uint256 buyTaxFee, uint256 buyVaultFee, uint256 buyLiquidityFee) external onlyOwner {
        _buyTaxFee = buyTaxFee;
        _buyVaultFee = buyVaultFee;
        _buyLiquidityFee = buyLiquidityFee;
    }

    function setSellFee(uint256 sellTaxFee, uint256 sellVaultFee, uint256 sellLiquidityFee) external onlyOwner {
        _sellTaxFee = sellTaxFee;
        _sellVaultFee = sellVaultFee;
        _sellLiquidityFee = sellLiquidityFee;
    }

    function setLiquidityFeePercent(uint256 liquidityFee) external onlyOwner {
        _liquidityFee = liquidityFee;
    }

    function setBuyMaxTxAmount(uint256 bMaxTxAmount) external onlyOwner {
        _bMaxTxAmount = bMaxTxAmount;
    }

    function setSellMaxTxAmount(uint256 sMaxTxAmount) external onlyOwner {
        _sMaxTxAmount = sMaxTxAmount;
    }

    function setTriggerAmount(uint256 trigger) external onlyOwner {
        _trigger = trigger;
    }

    function setMarketingDivisor(uint256 divisor) external onlyOwner {
        marketingDivisor = divisor;
    }

    function setNumTokensSellToAddToBuyBack(uint256 _minimumTokensBeforeSwap) external onlyOwner {
        minimumTokensBeforeSwap = _minimumTokensBeforeSwap;
    }

    function setMarketingAddress(address _marketingAddress) external onlyOwner {
        marketingAddress = payable(_marketingAddress);
        _isExcludedFromFee[marketingAddress] = true;
    }

    function setVaultAddress(address _vaultAddress) external onlyOwner {
        vaultRewardAddress = payable(_vaultAddress);
        _isExcludedFromFee[vaultRewardAddress] = true;
    }

    function setSwapAndLiquifyEnabled(bool _enabled) public onlyOwner {
        swapAndLiquifyEnabled = _enabled;
        emit SwapAndLiquifyEnabledUpdated(_enabled);
    }

    function setAvaxAddress(address _newAvax) external onlyOwner{
        avaxAddress = payable(_newAvax);
    }

    function setABMode(bool _enabled) public onlyOwner {
        _abmode = _enabled;
        emit ABMode(_enabled);
    }

    function setCooldownMode(bool _enabled) public onlyOwner {
        _cooldownMode = _enabled;
        emit CooldownMode(_enabled);
    }

    function setReawardAndMarketingFee(uint256 _sellRewardsPercent,uint256 _sellMarketingPercent,uint256 _buyRewardsPercent,uint256 _buyMarketingPercent ) external onlyOwner {
        _sellRewardFee = _sellRewardsPercent;
        _sellMarketingFee = _sellMarketingPercent;
        _buyRewardFee = _buyRewardsPercent;
        _buyMarketingFee = _buyMarketingPercent;
    }


    function prepareForPreSale() external onlyOwner {
        setSwapAndLiquifyEnabled(false);
        setABMode(false);
        setCooldownMode(false);
        setTradingOpen(false);
        _taxFee = 0;
        _vaultFee = 0;
        _liquidityFee = 0;
        _bMaxTxAmount = 1000000000 * 10**9;
        _sMaxTxAmount = 1000000000 * 10**9;
    }

    function afterPreSale() external onlyOwner {
        setSwapAndLiquifyEnabled(true);
        setABMode(true);
        setCooldownMode(true);
        _taxFee = 0;
        _vaultFee = 0;
        _liquidityFee = 9;
        _bMaxTxAmount = 6000000 * 10**9;
        _sMaxTxAmount = 3000000 * 10**9;
        setTradingOpen(true);
    }

    function setTradingOpen(bool _status) public onlyOwner {
        tradingOpen = _status;
    }

    function transferToAddressETH(address payable recipient, uint256 amount) private {
        recipient.transfer(amount);
    }

    function changeRouterVersion(address _router) public onlyOwner returns(address _pair) {
        IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(_router);

        _pair = IUniswapV2Factory(_uniswapV2Router.factory()).getPair(address(this), _uniswapV2Router.WETH());
        if(_pair == address(0)){
            // Pair doesn't exist
            _pair = IUniswapV2Factory(_uniswapV2Router.factory())
            .createPair(address(this), _uniswapV2Router.WETH());
        }
        uniswapV2Pair = _pair;

        // Set the router of the contract variables
        uniswapV2Router = _uniswapV2Router;
    }

     // To receive ETH from uniswapV2Router when swapping
    receive() external payable {}

    // for stuck tokens of other types
    function transferForeignToken(address _token, address _to) public onlyOwner returns(bool _sent){
        require(_token != address(this), "Can't let you take all native token");
        uint256 _contractBalance = IERC20(_token).balanceOf(address(this));
        _sent = IERC20(_token).transfer(_to, _contractBalance);
    }

    //Create additional liquidity using BNB tokens in contract
    function manualSwapAndLiquifyBNB(uint256 bnbLiquifyAmount) external lockTheSwap onlyOwner {
        SwapAndLiquifyBNBtoAvax(bnbLiquifyAmount);
    }

    //Create additional liquidity using  tokens in contract
    function manualSwapAndLiquifyTokens(uint256 tokenLiquifyAmount) external lockTheSwap onlyOwner{
        addLiquidityToToken(tokenLiquifyAmount);
    }

    function SwapAndLiquifyBNBtoAvax(uint256 bnbLiquifyAmount) private lockTheSwap {

        // swap ETH for Tokens
        swapETHForTokensToAvax(bnbLiquifyAmount); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered

        // how much Tokens did we just swap into?
        uint256 newTokenBalance = IERC20(avaxAddress).balanceOf(address(this));

        uint256 marketingFunds = newTokenBalance.div(2);
        uint256 stakingFunds = newTokenBalance.sub(marketingFunds);

        require(IERC20(avaxAddress).transfer(marketingAddress,marketingFunds));
        IERC20(avaxAddress).approve(vaultRewardAddress,stakingFunds);
        require(IERC20(avaxAddress).transfer(vaultRewardAddress,stakingFunds));

        emit SwapAndLiquifyBNB(bnbLiquifyAmount, newTokenBalance, bnbLiquifyAmount);
    }


    function addLiquidityToToken(uint256 tokenLiquifyAmount) private lockTheSwap{
        // split the contract balance into halves
        uint256 half = tokenLiquifyAmount.div(2); //staking tokens to be swaped
        uint256 otherHalf = tokenLiquifyAmount.sub(half); //staking tokens not swapped

        // capture the contract's current ETH balance.
        // this is so that we can capture exactly the amount of ETH that the
        // swap creates, and not make the liquidity event include any ETH that
        // has been manually sent to the contract
        uint256 initialBalance = address(this).balance;

        // swap tokens for ETH
        swapTokensForEth(half); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered

        // how much ETH did we just swap into?
        uint256 newBalance = address(this).balance.sub(initialBalance);

        // add liquidity to uniswap
        addLiquidity(otherHalf, newBalance);

        emit SwapAndLiquifyTokens(half, newBalance, otherHalf);
    }