contract ERC20Whitelist is Ownable, ERC20 {   
    GlobalWhitelist public whitelist;
    bool public isWhitelisting = true;  // default to true

    /** EVENTS **/
    event ESTWhitelistingEnabled();
    event ESTWhitelistingDisabled();

    /*** FUNCTIONS ***/
    /**
    * @notice disables whitelist per individual EST
    * @dev parnent contract, ExporoTokenFactory, is owner
    */
    function toggleWhitelist() external onlyOwner {
        isWhitelisting = isWhitelisting ? false : true;
        
        if (isWhitelisting) {
            emit ESTWhitelistingEnabled();
        } else {
            emit ESTWhitelistingDisabled();
        }
    }

    /** OVERRIDE
    * @dev transfer token for a specified address
    * @param _to The address to transfer to.
    * @param _value The amount to be transferred.
    * @return bool
    */
    function transfer(address _to, uint256 _value) public returns (bool) {
        if (checkWhitelistEnabled()) {
            checkIfWhitelisted(msg.sender);
            checkIfWhitelisted(_to);
        }
        return super.transfer(_to, _value);
    }

    /** OVERRIDE
    * @dev Transfer tokens from one address to another
    * @param _from address The address which you want to send tokens from
    * @param _to address The address which you want to transfer to
    * @param _value uint256 the amount of tokens to be transferred
    * @return bool
    */
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
        if (checkWhitelistEnabled()) {
            checkIfWhitelisted(_from);
            checkIfWhitelisted(_to);
        }
        return super.transferFrom(_from, _to, _value);
    }

    /**
    * @dev check if whitelisting is in effect versus local and global bools
    * @return bool
    */
    function checkWhitelistEnabled() public view returns (bool) {
        // local whitelist
        if (isWhitelisting) {
            // global whitelist
            if (whitelist.isWhitelisting()) {
                return true;
            }
        }

        return false;
    }

    /*** INTERNAL/PRIVATE ***/
    /**
    * @dev check if the address has been whitelisted by the Whitelist contract
    * @param _account address of the account to check
    */
    function checkIfWhitelisted(address _account) internal view {
        require(whitelist.isWhitelisted(_account), "not whitelisted");
    }
}
function checkIfWhitelisted(address _account) internal view {
    require(whitelist.isWhitelisted(_account), "not whitelisted");
}

/**
 * @dev check if the address has been whitelisted by the Whitelist contract
 * @param _account address of the account to check
 */