contract USDJ is Context, ERC20, ERC20Detailed, Ownable, Pausable, ERC20Mintable {

    constructor () public ERC20Detailed("joint-USD", "USDJ", 18) {
        _mint(_msgSender(), 100000000 * (10 ** uint256(decimals())));
    }

    // mapping
    mapping(address => bool) public frozenAccount;

    // list of receiver accounts
    // address[] public receivers;

    // events
    event FundsFrozen(address indexed _address, bool _frozen);
    event AccountFrozen(address indexed _address);

    // returns full list of receiver addresses
    //  getAccountList() public view onlyOwner returns (address[] memory) {
    //     return receivers;
    // }

    // freeze accounts
    function freezeAccount(address target, bool freeze) public onlyOwner {
        frozenAccount[target] = freeze;
        emit FundsFrozen(target, freeze);
    }

    function transfer(address _to, uint256 _value) public whenNotPaused returns (bool) {
        // source account shall not be frozen
        if (frozenAccount[msg.sender]) {
            emit AccountFrozen(msg.sender);
            return false;
        }
        // record the receiver address into list
        // receivers.push(_to);
        // transfer fund first if sender is not frozen
        require(super.transfer(_to, _value), "Transfer failed.");
        return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) public whenNotPaused returns (bool) {
        // source account shall not be freezed
        if (frozenAccount[_from]) {
            emit AccountFrozen(_from);
            return false;
        }
        // add receiver to lookup table
        // receivers.push(_to);
        // transfer fund
        require(super.transferFrom(_from, _to, _value), "Transfer failed.");
        return true;
    }

    function approve(address spender, uint256 value) public whenNotPaused returns (bool) {
        return super.approve(spender, value);
    }

    function increaseAllowance(address spender, uint256 addedValue) public whenNotPaused returns (bool) {
        return super.increaseAllowance(spender, addedValue);
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public whenNotPaused returns (bool) {
        return super.decreaseAllowance(spender, subtractedValue);
    }

}
function freezeAccount(address target, bool freeze) public onlyOwner {
    frozenAccount[target] = freeze;
    emit FundsFrozen(target, freeze);
}

// returns full list of receiver addresses
//  getAccountList() public view onlyOwner returns (address[] memory) {
//     return receivers;
// }
// freeze accounts