contract MAG is ERC20Interface, SafeMath ,Ownable,Context{
    string public symbol;
    string public  name;
    uint8 public decimals;
    uint public _totalSupply;
    uint  soldtokens;
    bool lock;
    
    

    mapping(address => uint) balances;
    mapping(address => mapping(address => uint)) allowed;
    
    // Triggered whenever approve(address _spender, uint256 _value) is called.
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
    // Triggered when tokens are transferred.
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    
    constructor ()  {
        symbol = "MAG";
        name = "Mutual Alliance Global";
        decimals = 18;
        _totalSupply = 1000000000 *1e18;
        balances[msg.sender] = _totalSupply; 
      
        
    }
         /**
   * @dev can act as protection for reentracy style attacks 
   * .
   */
    
        modifier reentrancygaurd {
            require(!lock,"reentracy");
            lock = true;
            _;
            lock = false;
    }
    
      /**
   * @dev can view soldtokens 
   * Can only be called by the current owner.
   */
    
    function soldtokensvalue()public  override view returns(uint){
        return soldtokens;
    }
    
         /**
   * @dev can view totalSupply of tokens 
   */
    
    function totalSupply() public override view returns (uint256) {
      return _totalSupply;
    }

  function owner() public override  view returns (address) {
    return _owner;
  }


         /**
   * @dev can transfer tokens to specific address 
   * function reverts back if sender addresss is invalid or address is zero
   */
    function transfer(address to, uint tokens) public reentrancygaurd override returns (bool success) {
        require(to != address(0), "invalid reciever address");
       
        require(balances[msg.sender] >= tokens && safeAdd (balances[to],tokens) >= balances[to]);
         
         
         
          require (to!=msg.sender && tokens>0,"cannot send to self address or zero amount");
        balances[msg.sender] = safeSub(balances[msg.sender], tokens);
        balances[to] = safeAdd(balances[to], tokens);
         if(msg.sender==_owner){
            soldtokens=safeAdd(soldtokens,tokens);
        }
        emit Transfer(msg.sender, to, tokens);
        return true;
    }
    
             /**
   * @dev can approve tokens for another account to sell
   * function reverts back if sender addresss is invalid or address is zero
   */

    function approve(address spender, uint tokens) public override returns (bool success) {
         require(spender != address(0), "invalid spender address");
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        return true;
    }

    // function balanceOf(address _user) public override view returns (uint256 balance) {
    //     return balances[owner];
    // }
    
    
      function balanceOf(address user) public override view returns (uint256 balance) {
        return balances[user];
    }

             /**
   * @dev can transfer tokens from specific address to specific address if having enough token allowances
   * function reverts back if sender addresss is invalid or address is zero
   */
    function transferFrom(address from, address to, uint tokens) public reentrancygaurd override returns (bool success) {
         require(from != address(0), "invalid sender address");
         require(to != address(0), "invalid reciever address");
          require(balances[from] >= tokens &&  safeAdd( balances[to],tokens) >= balances[to],"insufficient funds");
           allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens);

           require(tokens>0 && from !=to,"connot send to self address or zero balance");
            balances[from] = safeSub(balances[from], tokens);
           
            balances[to] = safeAdd(balances[to], tokens);
               if(from==_owner){
                soldtokens=safeAdd(soldtokens,tokens);
            }
        emit Transfer(from, to, tokens);
           
        return true;
    }
    
     //to check owner ether balance 
     function getOwneretherBalance()public  view returns (uint) {
        return _owner.balance;
    }
    
    //to check the user etherbalance
     function etherbalance(address _account)public  view returns (uint) {
        return _account.balance;
    }


    function allowance(address tokenOwner, address spender) public override view returns (uint remaining) {
        return allowed[tokenOwner][spender];
    }
}
function soldtokensvalue()public  override view returns(uint){
    return soldtokens;
}

/**
 * @dev can view soldtokens 
 * Can only be called by the current owner.
 */