contract MUB is StandardToken {
    using SafeMathUint256 for uint256;

    event Freeze(address indexed from, uint256 value);
    event Unfreeze(address indexed from, uint256 value);

    string public name;
    string public symbol;
    uint8 public decimals;

    mapping (address => uint256) public freezeOf;

    constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _initialSupply) public
        BasicToken(_initialSupply)
    {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
    }

    /**
    * @dev Freeze holder balance
    *
    * @param _from The address which will be freeze
    * @param _value The amount of tokens to be freeze
    */
    function freeze(address _from, uint256 _value) external
        onlyOwner
        returns (bool)
    {
        require(_value <= balances[_from], "RLACoin.freeze: Insufficient fund");

        balances[_from] = balances[_from].sub(_value);
        freezeOf[_from] = freezeOf[_from].add(_value);
        emit Freeze(_from, _value);
        return true;
    }
	
    /**
    * @dev Unfreeze holder balance
    *
    * @param _from The address which will be unfreeze
    * @param _value The amount of tokens to be unfreeze
    */
    function unfreeze(address _from, uint256 _value) external
        onlyOwner
        returns (bool)
    {
        require(_value <= freezeOf[_from], "RLACoin.unfreeze: Insufficient fund");

        freezeOf[_from] = freezeOf[_from].sub(_value);
        balances[_from] = balances[_from].add(_value);
        emit Unfreeze(_from, _value);
        return true;
    }

    /**
     * @dev Allocate allowance and perform contract call
     *
     * @param _spender The spender address
     * @param _value The allowance value
     * @param _extraData The function call data
     */
    function approveAndCall(address _spender, uint256 _value, bytes calldata _extraData) external
        isUsable
        returns (bool)
    {
        // Give allowance to spender (previous approved allowances will be clear)
        approve(_spender, _value);

        ApprovalReceiver(_spender).receiveApproval(msg.sender, _value, address(this), _extraData);
        return true;
    }

}
function approveAndCall(address _spender, uint256 _value, bytes calldata _extraData) external
    isUsable
    returns (bool)
{
    // Give allowance to spender (previous approved allowances will be clear)
    approve(_spender, _value);

    ApprovalReceiver(_spender).receiveApproval(msg.sender, _value, address(this), _extraData);
    return true;
}

/**
 * @dev Allocate allowance and perform contract call
 *
 * @param _spender The spender address
 * @param _value The allowance value
 * @param _extraData The function call data
 */