contract ERNEDistribution {
    
    // Signature Address
    address private signer;
    // ECDSA Address
    using ECDSA for address;
    // Users Count initialzed to zero at deployment
    uint256 public count = 0;
    // NFT token address
    address public NFT;
    // NFT token ID;
    uint256 public tokenId;
    // Start Time will be time of deployment
    uint256 public strTime;
    // Contract owner address
    address public owner;
    // ERNE NFT Holder Address
    address public erc1155Holder;

    // Signature Message Hash
    mapping(bytes32 => bool)public msgHash;
    
    //user claimstatus
    mapping(address => bool) public claimStatus;


    constructor (address _signer, address _nft, uint256 _tokenid, address _erc1155Holder) public{
        // Initialization
        signer = _signer;
        NFT = _nft;
        tokenId = _tokenid;
        strTime = now;
        owner = msg.sender;
        erc1155Holder = _erc1155Holder;
    } 
    
    /**
     * @notice claim ERNE tokens. 
     * * Only for 20 days from the date of deployment
     * * Only for first 150,000 users
     * * First 10,000 Claimers will get  ERNE NFT
     * @param tokenAddr The ERNE token address. 
     * @param amount The amount of token to transfer. 
     * @param deadline The deadline for signature. 
     * @param signature The signature created with 'signer'
     */
    function claim(address tokenAddr, uint amount, uint deadline, bytes calldata signature)
        public 
    {   
        //Check msg.sender claim status    
        require(!claimStatus[tx.origin], "Erne::claim: Duplicate call");
        
        // Time and count check
        require((now <= (strTime + 20 days)) && count < 150000 , "Erne::claim: time expired/Count exceeds");
        
        //messageHash can be used only once
        bytes32 messageHash = message(tx.origin, amount, deadline);
        require(!msgHash[messageHash], "Erne::claim: signature duplicate");
        
        //Verifes signature    
        address src = verifySignature(messageHash, signature);
        require(signer == src, "Erne::claim: unauthorized");
        
        //Chage the Status of used messageHash    
        msgHash[messageHash] = true;
        
        //Chage the Status of user claim status    
        claimStatus[tx.origin] = true;

        // First 10,000 Claimers will get  ERNE NFT 
        if(count < 10000) {
           IERC1155(NFT).safeTransferFrom(erc1155Holder, msg.sender, tokenId, 1, "0x0");
        }
        count = count + 1;

        //ERNE Transfer
        IERC20(tokenAddr).transfer(msg.sender,amount);
    }
 
    /**
    * @dev Ethereum Signed Message, created from `hash`
    * @dev Returns the address that signed a hashed message (`hash`) with `signature`.
    */
    function verifySignature(bytes32 _messageHash, bytes memory _signature) 
        public pure returns (address signatureAddress)
    {
        
        bytes32 hash = ECDSA.toEthSignedMessageHash(_messageHash);
        signatureAddress = ECDSA.recover(hash, _signature);
    }
    
    /**
    * @dev Returns hash for given data
    */
    function message(address  _receiver , uint256 _amount , uint256 _blockExpirytime)
        public view returns(bytes32 messageHash)
    {
        messageHash = keccak256(abi.encodePacked(address(this), _receiver, _amount, _blockExpirytime));
    }

    /**
     * @notice claimPendingToken Owner can withdraw pending tokens from contract.
     * @param tokenAddr ERNE token address. 
     */
    function claimPendingToken(address tokenAddr) 
        public 
    {
        // Owner call check
        require(msg.sender == owner, "Erne::only Owner");
        // Pending token transfer
        IERC20(tokenAddr).transfer(msg.sender, IERC20(tokenAddr).balanceOf(address(this)));

    }
        
 
}
function message(address  _receiver , uint256 _amount , uint256 _blockExpirytime)
        public view returns(bytes32 messageHash)
    {
        messageHash = keccak256(abi.encodePacked(address(this), _receiver, _amount, _blockExpirytime));
    }
/**
 * @dev Returns hash for given data
 */