contract BurnedBytesDaoToken is ERC20, ERC20Permit, ERC20Votes, Ownable {
    address bytesContract;

    mapping(address=>bool) private claimed;

    event Claim(address indexed claimant, uint256 amount);
    event BytesContractChanged(address bytesContract);

    uint256 constant treasurySupply = 150_000_000e18;

    /**
     * @dev Constructor.
     * @param treasuryAddress The address of the treasury.
     */
    constructor(
        address treasuryAddress
    )
        ERC20("Burned Bytes DAO", "BITS")
        ERC20Permit("Burned Bytes DAO")
    {
        _mint(treasuryAddress, treasurySupply);
    }

    function claim() public {
        require(address(bytesContract) != address(0), "Bytes contract not set");

        IByteContract iBytes = IByteContract(bytesContract);

        require(iBytes.bytesBurned(msg.sender) > 0, "You have not burned any bytes.");
        require(!claimed[msg.sender], "Tokens already claimed.");
        claimed[msg.sender] = true;

        uint256 amount = iBytes.bytesBurned(msg.sender) * 1000 * 10 ** 18;

        emit Claim(msg.sender, amount);

        _mint(msg.sender, amount);
    }

    /**
     * @dev Returns true if address already claimed.
     * @param account The address to check if claimed.
     */
    function hasClaimed(address account) public view returns (bool) {
        return claimed[account];
    }

    /**
     * @dev Sets the Bytes Contract address.
     * @param _bytesContract The bytesContract address to set.
     */
    function setBytesContractAddress(address _bytesContract) public onlyOwner {
        bytesContract = _bytesContract;
        emit BytesContractChanged(_bytesContract);
    }

    // The following functions are overrides required by Solidity.

    function _afterTokenTransfer(address from, address to, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._afterTokenTransfer(from, to, amount);
    }

    function _mint(address to, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._mint(to, amount);
    }

    function _burn(address account, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._burn(account, amount);
    }
}
/**
 * @dev An ERC20 token for BurnedBytesDao.
 *      Besides the addition of voting capabilities.
 *      Airdrop can be claimed via `claim` function.
 */
function hasClaimed(address account) public view returns (bool) {
    return claimed[account];
}

/**
 * @dev Returns true if address already claimed.
 * @param account The address to check if claimed.
 */