contract ENTA is StandardToken,Owned {

    string public name = "ENTA";
    string public symbol = "ENTA";
    uint256 public decimals = 8;
    uint256 public INITIAL_SUPPLY = 2000000000 * (10 ** decimals); // Two billion
    uint256 public publicSell = 1530374400;//2018-07-01

    bool public allowTransfers = true; // if true then allow coin transfers
    mapping (address => bool) public frozenAccount;

    event FrozenFunds(address indexed target, bool frozen);
    event MinedBalancesUnlocked(address indexed target, uint256 amount);

    struct MinedBalance {
        uint256 total;
        uint256 left;
    }

    mapping(address => MinedBalance) minedBalances;

    constructor() public {
        totalSupply = INITIAL_SUPPLY;
        balances[msg.sender] = INITIAL_SUPPLY;
    }

    function transferMined(address to, uint256 tokens) public onlyOwner returns (bool success) {
        balances[msg.sender] = balances[msg.sender].safeSub(tokens);
        minedBalances[to].total = minedBalances[to].total.safeAdd(tokens);
        minedBalances[to].left = minedBalances[to].left.safeAdd(tokens);
        emit Transfer(msg.sender, to, tokens);
        return true;
    }

    // ------------------------------------------------------------------------
    // Transfer the balance from token owner's account to to account
    // - Owner's account must have sufficient balance to transfer
    // - 0 value transfers are allowed
    // - @dev override
    // ------------------------------------------------------------------------
    function transfer(address to, uint256 tokens) public returns (bool success) {
        if (!isOwner()) {
            require (allowTransfers);
            require(!frozenAccount[msg.sender]);                                        // Check if sender is frozen
            require(!frozenAccount[to]);                                               // Check if recipient is frozen
        }
        
        if (now >= publicSell) {
            uint256 month = (now-publicSell)/(30 days);
            if(month>=7){
                unlockMinedBalances(100);
            } else if(month>=6){
                unlockMinedBalances(90);
            } else if(month>=3){
                unlockMinedBalances(80);
            } else if(month>=2){
                unlockMinedBalances(60);
            } else if(month>=1){
                unlockMinedBalances(40);
            } else if(month>=0){
                unlockMinedBalances(20);
            }
        }
        return super.transfer(to,tokens);
    }

    function unlockMinedBalances(uint256 unlockPercent) internal {
        uint256 lockedMinedTokens = minedBalances[msg.sender].total*(100-unlockPercent)/100;
        if(minedBalances[msg.sender].left > lockedMinedTokens){
            uint256 unlock = minedBalances[msg.sender].left.safeSub(lockedMinedTokens);
            minedBalances[msg.sender].left = lockedMinedTokens;
            balances[msg.sender] = balances[msg.sender].safeAdd(unlock);
            emit MinedBalancesUnlocked(msg.sender,unlock);
        }
    }

    function setAllowTransfers(bool _allowTransfers) onlyOwner public {
        allowTransfers = _allowTransfers;
    }

    function destroyToken(address target, uint256 amount) onlyOwner public {
        balances[target] = balances[target].safeSub(amount);
        totalSupply = totalSupply.safeSub(amount);
        emit Transfer(target, this, amount);
        emit Transfer(this, 0, amount);
    }

    /// @notice `freeze? Prevent | Allow` `target` from sending & receiving tokens
    /// @param target Address to be frozen
    /// @param freeze either to freeze it or not
    function freezeAccount(address target, bool freeze) onlyOwner public {
        frozenAccount[target] = freeze;
        emit FrozenFunds(target, freeze);
    }

    // @dev override
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
        if (!isOwner()) {
            require (allowTransfers);
            require(!frozenAccount[_from]);                                          // Check if sender is frozen
            require(!frozenAccount[_to]);                                            // Check if recipient is frozen
        }
        return super.transferFrom(_from, _to, _value);
    }
    
    // ------------------------------------------------------------------------
    // Get the token balance for account tokenOwner
    // ------------------------------------------------------------------------
    function balanceOf(address tokenOwner) public view returns (uint256 balance) {
        return balances[tokenOwner].safeAdd(minedBalances[tokenOwner].left);
    }
}
/**
 * @title ENTA is Standard ERC20 token
 */
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
    if (!isOwner()) {
        require (allowTransfers);
        require(!frozenAccount[_from]);                                          // Check if sender is frozen
        require(!frozenAccount[_to]);                                            // Check if recipient is frozen
    }
    return super.transferFrom(_from, _to, _value);
}

// @dev override