function withdrawAdmin(address token, uint256 amount, address user, uint nonce, uint8 v, bytes32 r, bytes32 s)
        public onlyAdmin {

        require(amount > 0);

        bytes32 hash = keccak256(abi.encodePacked(this, token, amount, user, nonce));
        require(!withdrawn[hash]);
        withdrawn[hash] = true;

        address signer = ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)), v, r, s);
        require(user == signer);

        require(reduceBalance(user, token, amount));
        if (token == address(0)) {
            require(user.send(toTokenAmount(address(0), amount)));
        } else {
            require(Token(token).transfer(user, toTokenAmount(token, amount)));
        }
        emit Withdraw(token, user, amount, balances[token][user]);
    }