Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
16 kB
1
Indexable
Never
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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) {
        require(b <= a, "SafeMath: subtraction overflow");
        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) {
        require(b > 0, "SafeMath: division by zero");
        uint256 c = a / b;
        return c;
    }
}

contract LQGToken is IERC20 {
    using SafeMath for uint256;

    string public name = "LQG Token";
    string public symbol = "LQG";
    uint8 public decimals = 18;
    uint256 private constant MAX = ~uint256(0);
    uint256 private constant _totalSupply = 1_000_000_000 * 10**uint256(decimals); // 1 billion tokens
    uint256 private _tTotal = (MAX - (MAX % _totalSupply));

    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;

    mapping(address => bool) private _isExcludedFromFee;
    mapping(address => bool) private _isExcludedFromMaxTx;
    address[] private _excludedFromFee;
    address[] private _excludedFromMaxTx;

    uint256 public _burnFee = 1;
    uint256 public _liquidityFee = 1;
    uint256 public _reflectionFee = 2;
    uint256 public _communityFee = 1;
    uint256 public _creatorFee = 0.5;

    address public _communityDecisionPool;
    address public _creatorWallet;

    uint256 private _tFeeTotal;
    uint256 private _tBurnTotal;
    uint256 private _tLiquidityTotal;

    uint256 public _maxTxAmount = _totalSupply / 100; // 1% of the total supply
    uint256 public _cooldownPeriod = 1 hours;

    mapping(address => uint256) private _lastSellTime;
    mapping(address => uint256) private _lastBuyTime;

    bool private _inSwapAndLiquify;
    bool public _swapAndLiquifyEnabled = true;

    IUniswapV2Router02 public immutable uniswapV2Router;
    address public immutable uniswapV2Pair;

    event SwapAndLiquify(uint256 tokensSwapped, uint256 ethReceived, uint256 tokensIntoLiquidity);
    event Burn(address indexed from, uint256 tokensBurned);
    event CommunityFee(address indexed from, uint256 tokensContributed);

    modifier lockTheSwap {
        _inSwapAndLiquify = true;
        _;
        _inSwapAndLiquify = false;
    }

    constructor(address routerAddress, address communityDecisionPool, address creatorWallet) {
        _balances[msg.sender] = _totalSupply;

        IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(routerAddress);
        uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
            .createPair(address(this), _uniswapV2Router.WETH());

        uniswapV2Router = _uniswapV2Router;
        _isExcludedFromFee[address(this)] = true;
        _isExcludedFromFee[owner()] = true;

        _communityDecisionPool = communityDecisionPool;
        _creatorWallet = creatorWallet;

        emit Transfer(address(0), msg.sender, _totalSupply);
    }

    function totalSupply() external view override returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    function transfer(address recipient, uint256 amount) external override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender) external view override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) external override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        _approve(sender, _msgSender(), currentAllowance.sub(amount));

        return true;
    }

    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(amount <= _maxTxAmount, "Transfer amount exceeds the maximum limit");

        if (sender != owner() && recipient != owner()) {
            if (_isExcludedFromMaxTx[sender] == false && _isExcludedFromMaxTx[recipient] == false) {
                require(_lastSellTime[sender].add(_cooldownPeriod) <= block.timestamp, "Please wait for the cooldown period to end");
            }

            if (!_isExcludedFromFee[sender] && !_isExcludedFromFee[recipient]) {
                (uint256 tTransferAmount, uint256 tBurnFee, uint256 tLiquidityFee, uint256 tReflectionFee, uint256 tCommunityFee, uint256 tCreatorFee) =
                    _calculateFees(amount);

                _balances[address(this)] = _balances[address(this)].add(tLiquidityFee);
                _tLiquidityTotal = _tLiquidityTotal.add(tLiquidityFee);

                _balances[address(0)] = _balances[address(0)].add(tBurnFee);
                _tBurnTotal = _tBurnTotal.add(tBurnFee);

                _balances[_communityDecisionPool] = _balances[_communityDecisionPool].add(tCommunityFee);
                emit CommunityFee(sender, tCommunityFee);

                _balances[_creatorWallet] = _balances[_creatorWallet].add(tCreatorFee);

                amount = tTransferAmount;
                _tFeeTotal = _tFeeTotal.add(tReflectionFee);
            }
        }

        _updateLastSellTime(sender);
        _updateLastBuyTime(recipient);

        _balances[sender] = _balances[sender].sub(amount);
        _balances[recipient] = _balances[recipient].add(amount);

        emit Transfer(sender, recipient, amount);
    }

    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 _calculateFees(uint256 amount)
        private
        view
        returns (
            uint256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        uint256 tBurnFee = amount.mul(_burnFee).div(100);
        uint256 tLiquidityFee = amount.mul(_liquidityFee).div(100);
        uint256 tReflectionFee = amount.mul(_reflectionFee).div(100);
        uint256 tCommunityFee = amount.mul(_communityFee).div(100);
        uint256 tCreatorFee = amount.mul(_creatorFee).div(100);
        uint256 tTransferAmount = amount.sub(tBurnFee).sub(tLiquidityFee).sub(tReflectionFee).sub(tCommunityFee).sub(tCreatorFee);

        return (tTransferAmount, tBurnFee, tLiquidityFee, tReflectionFee, tCommunityFee, tCreatorFee);
    }

    function _updateLastSellTime(address seller) private {
        if (_lastSellTime[seller] == 0) {
            _lastSellTime[seller] = block.timestamp;
        } else {
            _lastSellTime[seller] = block.timestamp;
        }
    }

    function _updateLastBuyTime(address buyer) private {
        _lastBuyTime[buyer] = block.timestamp;
    }

    function setMaxTxAmount(uint256 maxTxAmount) external onlyOwner {
        _maxTxAmount = maxTxAmount;
    }

    function setCooldownPeriod(uint256 cooldownPeriod) external onlyOwner {
        _cooldownPeriod = cooldownPeriod;
    }

    function setExcludedFromFee(address account, bool excluded) external onlyOwner {
        _isExcludedFromFee[account] = excluded;
        if (excluded) {
            if (!_isExcludedFromFee[account]) {
                _excludedFromFee.push(account);
            }
        } else {
            for (uint256 i = 0; i < _excludedFromFee.length; i++) {
                if (_excludedFromFee[i] == account) {
                    _excludedFromFee[i] = _excludedFromFee[_excludedFromFee.length - 1];
                    _excludedFromFee.pop();
                    break;
                }
            }
        }
    }

    function setExcludedFromMaxTx(address account, bool excluded) external onlyOwner {
        _isExcludedFromMaxTx[account] = excluded;
        if (excluded) {
            if (!_isExcludedFromMaxTx[account]) {
                _excludedFromMaxTx.push(account);
            }
        } else {
            for (uint256 i = 0; i < _excludedFromMaxTx.length; i++) {
                if (_excludedFromMaxTx[i] == account) {
                    _excludedFromMaxTx[i] = _excludedFromMaxTx[_excludedFromMaxTx.length - 1];
                    _excludedFromMaxTx.pop();
                    break;
                }
            }
        }
    }

    function setSwapAndLiquifyEnabled(bool enabled) external onlyOwner {
        _swapAndLiquifyEnabled = enabled;
    }

    function swapAndLiquify(uint256 contractTokenBalance) private lockTheSwap {
        uint256 half = contractTokenBalance.div(2);
        uint256 otherHalf = contractTokenBalance.sub(half);

        uint256 initialBalance = address(this).balance;

        _swapTokensForEth(half);

        uint256 newBalance = address(this).balance.sub(initialBalance);

        _addLiquidity(otherHalf, newBalance);

        emit SwapAndLiquify(half, newBalance, otherHalf);
    }

    function _swapTokensForEth(uint256 tokenAmount) private {
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();

        _approve(address(this), address(uniswapV2Router), tokenAmount);

        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of ETH
            path,
            address(this),
            block.timestamp
        );
    }

    function _addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            owner(),
            block.timestamp
        );
    }

    function burn(uint256 amount) external {
        require(amount > 0, "Amount must be greater than zero");
        require(amount <= balanceOf(msg.sender), "Insufficient balance");

        _balances[msg.sender] = _balances[msg.sender].sub(amount);
        _tTotal = _tTotal.sub(amount);
        _tBurnTotal = _tBurnTotal.add(amount);

        emit Burn(msg.sender, amount);
    }

    function contributeToCommunityPool(uint256 amount) external {
        require(amount > 0, "Amount must be greater than zero");
        require(amount <= balanceOf(msg.sender), "Insufficient balance");

        _balances[msg.sender] = _balances[msg.sender].sub(amount);
        _balances[_communityDecisionPool] = _balances[_communityDecisionPool].add(amount);

        emit CommunityFee(msg.sender, amount);
    }

    function getBurnTotal() external view returns (uint256) {
        return _tBurnTotal;
    }

    function getLiquidityTotal() external view returns (uint256) {
        return _tLiquidityTotal;
    }

    function getReflectionTotal() external view returns (uint256) {
        return _tFeeTotal;
    }

    function setCommunityDecisionPool(address communityDecisionPool) external onlyOwner {
        _communityDecisionPool = communityDecisionPool;
    }

    function setCreatorWallet(address creatorWallet) external onlyOwner {
        _creatorWallet = creatorWallet;
    }

    function setFees(
        uint256 burnFee,
        uint256 liquidityFee,
        uint256 reflectionFee,
        uint256 communityFee,
        uint256 creatorFee
    ) external onlyOwner {
        _burnFee = burnFee;
        _liquidityFee = liquidityFee;
        _reflectionFee = reflectionFee;
        _communityFee = communityFee;
        _creatorFee = creatorFee;
    }

    function setCommunityFee(uint256 communityFee) external onlyOwner {
        _communityFee = communityFee;
    }

    function setCreatorFee(uint256 creatorFee) external onlyOwner {
        _creatorFee = creatorFee;
    }

    function setMaxTxAmount(uint256 maxTxAmount) external onlyOwner {
        _maxTxAmount = maxTxAmount;
    }

    function setCooldownPeriod(uint256 cooldownPeriod) external onlyOwner {
        _cooldownPeriod = cooldownPeriod;
    }

    function setExcludedFromFee(address account, bool excluded) external onlyOwner {
        _isExcludedFromFee[account] = excluded;
    }

    function setExcludedFromMaxTx(address account, bool excluded) external onlyOwner {
        _isExcludedFromMaxTx[account] = excluded;
    }

    function setSwapAndLiquifyEnabled(bool enabled) external onlyOwner {
        _swapAndLiquifyEnabled = enabled;
    }

    function setSwapAndLiquifyThreshold(uint256 threshold) external onlyOwner {
        _swapAndLiquifyThreshold = threshold;
    }

    function setSwapAndLiquifyRouterAddress(address routerAddress) external onlyOwner {
        IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(routerAddress);
        uniswapV2Router = _uniswapV2Router;
        uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair(address(this), _uniswapV2Router.WETH());
    }

    function setFrontRunGuardDuration(uint256 guardDuration) external onlyOwner {
        _frontRunGuardDuration = guardDuration;
    }

    function setFrontRunGuardEnabled(bool enabled) external onlyOwner {
        _isFrontRunGuardEnabled = enabled;
    }

    function setFrontRunGuardWhitelist(address[] memory addresses, bool whitelisted) external onlyOwner {
        for (uint256 i = 0; i < addresses.length; i++) {
            _frontRunGuardWhitelist[addresses[i]] = whitelisted;
        }
    }

    function setFrontRunGuardThreshold(uint256 threshold) external onlyOwner {
        _frontRunGuardThreshold = threshold;
    }

    function setFrontRunGuardRecovery(address newRecovery) external onlyOwner {
        require(newRecovery != address(0), "Invalid address");
        _frontRunGuardRecovery = newRecovery;
    }
}