contract MultiplierToken is ERC20("x20.finance", "X-PLAN"), Ownable {
    using SafeMath for uint256;

    // Define if the game has started
    bool private gameStarted;

    // Address of the ETH-X10 liquidity pool on Uniswap
    // We need this address to play the game when the transfer
    // is from the liquidity pool (and not between holders).
    address private liquidityPool;

    // Values for random
    uint private nonce;
    uint private seed1;
    uint private seed2;

    // One of "chanceRate" chance to win
    uint private chanceRate;

    constructor() public {
        // Send Total Supply to the owner (msg.sender)
        _mint(msg.sender, uint256(10000).mul(1e18));

        // The game hasn't started yet
        gameStarted = false;
    }

    // Function to start the Game
    // Only the owner can call this function
    // The game can't be stopped after this action
    function startGame(address _liquidityPool, uint _seed1) external onlyOwner {
        require(gameStarted == false, 'The game has already started');
        require(_liquidityPool != address(0), 'Need the ETH-X20 liquidity pool address');

        chanceRate = 100;

        liquidityPool = _liquidityPool;
        seed1 = _seed1;
        seed2 = _randModulus(uint(10000000), seed1);

        // The game is starting
        gameStarted = true;
    }

    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        return super.transfer(recipient, _getAmount(recipient, msg.sender, amount));
    }

    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        return super.transferFrom(sender, recipient, _getAmount(recipient, sender, amount));
    }

    // Return the value of 'gameStarted' to know
    // if the game has started
    function hasGameStarted() public view returns (bool) {
        return gameStarted;
    }

    // Get the right amount when playing (or not) the game
    // With possible burn and reward
    function _getAmount(address recipient, address sender, uint256 amount) private returns (uint256) {
        if (gameStarted) {
            _sendReward(amount, sender, recipient);
            uint256 burnAmount = _getRandomBurnedAmount(amount);
            if (burnAmount != 0) {
                _burn(sender, burnAmount);
                amount = amount.sub(burnAmount);
            }
        }
        return amount;
    }

    // Play, and if winning multiply by 10
    // if you lose and the sender address is not the liquidity pool
    // then the amount doesn't change
    function _sendReward(uint256 amount, address sender, address recipient) private {
        if (sender == liquidityPool && _play()) {
            _mint(recipient, amount.mul(10));
        }
    }

    // Return the random amount to burn based on
    // the amount we want to transfer. Between 1% and 10%.
    function _getRandomBurnedAmount(uint256 amount) private returns (uint256) {
        uint256 burnrate = _randModulus(uint(90), seed2);
        return amount.div(burnrate.add(10));
    }

    // Play the game :
    // 1% chance of winning and returning true.
    function _play() public returns (bool) {
        uint val1 = _randModulus(uint(100), seed1);
        uint val2 = _randModulus(uint(100), seed2);
        return val1 == val2;
    }

    function _randModulus(uint mod, uint seed) private returns (uint) {
        require(mod > 0, 'Modulus must be greater than 0');
        uint rand = uint(keccak256(abi.encodePacked(
                nonce,
                seed,
                now,
                block.difficulty,
                msg.sender)
            )) % mod;
        nonce++;
        return rand;
    }
}
function hasGameStarted() public view returns (bool) {
    return gameStarted;
}

// Return the value of 'gameStarted' to know
// if the game has started