function bitcoin_withdraw($uid, $amount, $curr_type, &$voucher_code, &$reqid)
{
    $voucher = isset($_POST['voucher']);
    if ($voucher) {
        syslog(LOG_NOTICE, "address=voucher");
        $query = "\n            INSERT INTO requests (req_type, uid, amount, curr_type)\n            VALUES ('WITHDR', '{$uid}', '{$amount}', '{$curr_type}');\n        ";
    } else {
        $addy = post('address');
        try {
            $validaddy = bitcoin_validate_address($addy);
        } catch (Exception $e) {
            if ($e->getMessage() != 'Unable to connect.') {
                throw $e;
            }
            throw new Problem(_("Sorry..."), _("We are currently experiencing trouble connecting to the Bitcoin network and so cannot verify that you entered a valid Bitcoin address.") . "</p><p>" . _("Your withdrawal request has been cancelled.") . "</p><p>" . _("Please try again in a few minutes."));
        }
        if (!$validaddy['isvalid']) {
            throw new Problem(_('Bitcoin says no'), _('That address you supplied was invalid.'));
        }
        syslog(LOG_NOTICE, "address={$addy}");
        $we_have = bitcoin_get_balance("*", 0);
        if (gmp_cmp($we_have, $amount) <= 0) {
            $message = sprintf(_("User %s is asking to withdraw %s BTC.  We only have %s BTC."), $uid, internal_to_numstr($amount, BTC_PRECISION), internal_to_numstr($we_have, BTC_PRECISION));
            email_tech(_("Exchange Wallet Balance is Too Low"), $message);
        }
        $query = "\n            INSERT INTO requests (req_type, uid, amount, curr_type)\n            VALUES ('WITHDR', '{$uid}', '{$amount}', '{$curr_type}');\n        ";
    }
    endlog();
    do_query($query);
    $reqid = mysql_insert_id();
    if ($voucher) {
        $voucher_code = store_new_bitcoin_voucher_code($reqid);
    } else {
        $query = "\n            INSERT INTO bitcoin_requests (reqid, addy)\n            VALUES ('{$reqid}', '{$addy}');\n        ";
        do_query($query);
    }
}
Example #2
0
function sync_to_bitcoin($uid)
{
    if (!is_string($uid)) {
        throw new Error('Coding error!', "sync_to_bitcoin() expects a string, not type '" . gettype($uid) . "'");
    }
    try {
        $balance = bitcoin_get_balance($uid, CONFIRMATIONS_FOR_DEPOSIT);
        if (is_float($balance)) {
            throw new Error(_("bitcoind version error"), _("bitcoind getbalance should return an integer not a float"));
        }
        if (gmp_cmp($balance, '0') > 0) {
            bitcoin_move($uid, '', $balance);
            $query = "\n            INSERT INTO requests (req_type, uid, amount, curr_type)\n            VALUES ('DEPOS', '{$uid}', '{$balance}', 'BTC');\n        ";
            do_query($query);
            $we_have = bitcoin_get_balance('*', 1);
            if (gmp_cmp($we_have, numstr_to_internal(WARN_HIGH_WALLET_THRESHOLD)) > 0) {
                email_tech(_("Exchange Wallet Balance is High"), sprintf(_("The exchange wallet has %s BTC available."), internal_to_numstr($we_have, BTC_PRECISION)));
            }
        }
    } catch (Exception $e) {
        if ($e->getMessage() != 'Unable to connect.') {
            throw $e;
        }
    }
}
Example #3
0
            <th><?php 
        echo _("Amount");
        ?>
</th>
            <th><?php 
        echo _("Confirmations Received");
        ?>
</th>
            <th><?php 
        echo _("More Confirmations Needed");
        ?>
</th>
        </tr>
    <?php 
        for ($conf = $needed_conf; $conf >= 0; $conf--) {
            $new_balance = bitcoin_get_balance($uid, $conf);
            if ($balance != $new_balance) {
                $diff = gmp_sub($new_balance, $balance);
                echo "<tr><td>", internal_to_numstr($diff), "</td><td>{$conf}</td><td>", $needed_conf - $conf, "</td></tr>\n";
                $balance = $new_balance;
            }
        }
        echo "</table></div>";
    }
} catch (Exception $e) {
    if ($e->getMessage() != 'Unable to connect.') {
        throw $e;
    }
    echo "<div class='content_box'>\n";
    echo "<h3>" . _("Pending bitcoin deposits") . "</h3>\n";
    echo "<p>" . _("Normally this area would display any Bitcoin deposits you have made that are awaiting confirmations, but we are having trouble connecting to the Bitcoin network at the moment, so it doesn't.") . "</p>\n";
Example #4
0
function show_users()
{
    $omit_zero_balances = true;
    $omit_very_low_balances = true;
    echo "<div class='content_box'>\n";
    echo "<h3>" . _("Users") . "</h3>\n";
    $query = "\n    SELECT\n        u.uid, oidlogin, is_admin, timest, a.amount as fiat, b.amount as btc\n    FROM\n        users as u\n    JOIN\n        purses as a\n    ON\n        a.uid = u.uid AND a.type = '" . CURRENCY . "'\n    JOIN\n        purses as b\n    ON\n        b.uid = u.uid AND b.type = 'BTC'\n    ORDER BY\n        is_admin DESC, u.uid;\n    ";
    $result = do_query($query);
    $fiat_total = $c_fiat_total = $t_fiat_total = '0';
    $btc_total = $c_btc_total = $t_btc_total = '0';
    $first = true;
    $count_users = $count_funded_users = $count_low_balance_users = $count_shown_users = 0;
    // omit users who don't have more than just least-significant-digit amounts of anything
    $tiny_fiat = pow(10, 8 - FIAT_PRECISION) * 10;
    $tiny_btc = pow(10, 8 - BTC_PRECISION) * 10;
    while ($row = mysql_fetch_assoc($result)) {
        $uid = $row['uid'];
        $oidlogin = $row['oidlogin'];
        $is_admin = $row['is_admin'];
        $timest = $row['timest'];
        $fiat = $row['fiat'];
        $btc = $row['btc'];
        $committed = fetch_committed_balances($uid);
        $c_fiat = $committed[CURRENCY];
        $c_btc = $committed['BTC'];
        $t_fiat = gmp_add($fiat, $c_fiat);
        $t_btc = gmp_add($btc, $c_btc);
        if ($uid == '1') {
            $uid = "fees";
        } else {
            $count_users++;
        }
        if ($omit_zero_balances && $fiat == 0 && $c_fiat == 0 && $btc == 0 && $c_btc == 0) {
            continue;
        }
        if ($first) {
            $first = false;
            echo "<table class='display_data'>\n";
            show_users_header();
        }
        $fiat_total = gmp_add($fiat_total, $fiat);
        $c_fiat_total = gmp_add($c_fiat_total, $c_fiat);
        $t_fiat_total = gmp_add($t_fiat_total, $t_fiat);
        $btc_total = gmp_add($btc_total, $btc);
        $c_btc_total = gmp_add($c_btc_total, $c_btc);
        $t_btc_total = gmp_add($t_btc_total, $t_btc);
        if ($uid != 'fees') {
            $count_funded_users++;
            if ($fiat < $tiny_fiat && $c_fiat < $tiny_fiat && $btc < $tiny_btc && $c_btc < $tiny_btc) {
                $count_low_balance_users++;
                if ($omit_very_low_balances) {
                    continue;
                }
            }
            $count_shown_users++;
        }
        if ($uid == 'fees') {
            $url = "?page=commission";
        } else {
            $url = "?page=statement&user={$uid}";
        }
        if ($is_admin) {
            active_table_row('me', $url);
        } else {
            active_table_row('active', $url);
        }
        echo "<td>{$uid}</td>";
        //      echo "<td>$oidlogin</td>";
        echo "<td class='right'>", internal_to_numstr($fiat, FIAT_PRECISION), "</td>";
        echo "<td class='right'>", internal_to_numstr($c_fiat, FIAT_PRECISION), "</td>";
        echo "<td class='right'>", internal_to_numstr($t_fiat, FIAT_PRECISION), "</td>";
        echo "<td class='right'>", internal_to_numstr($btc, BTC_PRECISION), "</td>";
        echo "<td class='right'>", internal_to_numstr($c_btc, BTC_PRECISION), "</td>";
        echo "<td class='right'>", internal_to_numstr($t_btc, BTC_PRECISION), "</td>";
        //      echo "<td>$timest</td>";
        echo "</tr>\n";
        if (!($count_shown_users % RESHOW_COLUMN_HEADINGS_AFTER_ROWS)) {
            show_users_header();
        }
    }
    if (!$first) {
        echo "<tr><td></td><td class='right'>--------</td><td class='right'>--------</td><td class='right'>--------</td><td class='right'>--------</td><td class='right'>--------</td><td class='right'>--------</td></tr>\n";
        active_table_row('me', "?page=statement&user=all");
        echo "<td></td>";
        echo "<td class='right'>", internal_to_numstr($fiat_total, FIAT_PRECISION), "</td>";
        echo "<td class='right'>", internal_to_numstr($c_fiat_total, FIAT_PRECISION), "</td>";
        echo "<td class='right'>", internal_to_numstr($t_fiat_total, FIAT_PRECISION), "</td>";
        echo "<td class='right'>", internal_to_numstr($btc_total, BTC_PRECISION), "</td>";
        echo "<td class='right'>", internal_to_numstr($c_btc_total, BTC_PRECISION), "</td>";
        echo "<td class='right'>", internal_to_numstr($t_btc_total, BTC_PRECISION), "</td>";
        echo "</tr>\n";
        echo "</table>\n";
        echo "<p>" . _("Admins are shown in bold type, and at the top of the table.") . "</p>\n";
    }
    echo "<p>" . sprintf(_("There are %s users with funds, and %s in total."), $count_funded_users, $count_users) . "</p>\n";
    if ($omit_very_low_balances && $count_low_balance_users) {
        echo "<p>" . sprintf(_("%d user(s) have very low balances, and aren't shown above."), $count_low_balance_users) . "</p>\n";
    }
    $balance0 = bitcoin_get_balance('*', 0);
    $balance1 = bitcoin_get_balance('*', 1);
    $balance = bitcoin_get_balance('', 0);
    $unconfirmed = gmp_sub($balance0, $balance1);
    echo "<p>" . sprintf(_("The Bitcoin wallet has %s BTC"), internal_to_numstr($balance0, BTC_PRECISION));
    if (gmp_cmp($unconfirmed, 0) != 0) {
        printf(_(", %s BTC of which currently has 0 confirmations"), internal_to_numstr($unconfirmed, BTC_PRECISION));
    }
    echo ".<br/></p>\n";
    if ($balance0 == $balance) {
        $balance = $balance0;
    } else {
        $pending = gmp_sub($balance0, $balance);
        echo "<p>" . sprintf(_("The main wallet account has %s BTC; other accounts have %s BTC awaiting confirmations."), internal_to_numstr($balance, BTC_PRECISION), internal_to_numstr($pending, BTC_PRECISION)) . "</p>";
    }
    // take off the amount that's waiting to be withdrawn.  it's in the wallet, but not in user accounts
    $pending_withdrawal = btc_pending_withdrawal();
    $balance = gmp_sub($balance, $pending_withdrawal);
    if ($pending_withdrawal) {
        echo "<p>" . sprintf(_("There are pending BTC withdrawals worth %s BTC, which will reduce the wallet balance to %s BTC."), internal_to_numstr($pending_withdrawal, BTC_PRECISION), internal_to_numstr($balance, BTC_PRECISION)) . "</p>";
    }
    $diff = gmp_sub($t_btc_total, $balance);
    $cmp = gmp_cmp($diff, 0);
    if ($cmp == 0) {
        echo "<p>" . _("That's the exact right amount.") . "</p>\n";
    } else {
        if ($cmp > 0) {
            echo "<p>" . sprintf(_("That's %s BTC less than is on deposit."), internal_to_numstr($diff, BTC_PRECISION)) . "</p>\n";
        } else {
            echo "<p>" . sprintf(_("That's %s BTC more than is on deposit"), internal_to_numstr(gmp_mul("-1", $diff), BTC_PRECISION)) . "</p>\n";
        }
    }
    echo "</div>\n";
}
        $reqid = $row['reqid'];
        $uid = $row['uid'];
        $amount = $row['amount'];
        $addy = $row['addy'];
        $we_have = bitcoin_get_balance("*", CONFIRMATIONS_FOR_DEPOSIT);
        // add on anything we've recently sent from offline storage but which isn't fully confirmed yet
        $main_unconfirmed = gmp_sub(bitcoin_get_balance("", 1), bitcoin_get_balance("", CONFIRMATIONS_FOR_DEPOSIT));
        $we_have = gmp_add($we_have, $main_unconfirmed);
        addlog(LOG_CRONJOB, "Attempting to withdraw " . internal_to_numstr($amount) . " of " . internal_to_numstr($we_have) . " BTC for user {$uid} (reqid {$reqid})");
        if (gmp_cmp($we_have, $amount) >= 0) {
            update_req($reqid, "PROCES");
            // use 'sendtoaddress' rather than 'sendfrom' because it can 'go overdrawn'
            // so long as there are funds in other accounts (pending deposits) to cover it
            bitcoin_send_to_address($addy, $amount);
            update_req($reqid, "FINAL");
            $we_have = bitcoin_get_balance("*", 0);
            addlog(LOG_CRONJOB, "We have " . internal_to_numstr($we_have) . " BTC in total");
            if (gmp_cmp($we_have, numstr_to_internal(WARN_LOW_WALLET_THRESHOLD)) < 0) {
                email_tech(_("Exchange Wallet Balance is Low"), sprintf(_("The exchange wallet only has %s BTC available."), internal_to_numstr($we_have, BTC_PRECISION)));
            }
        } else {
            $message = sprintf(_("We only have %s BTC so can't withdraw %s BTC"), internal_to_numstr($we_have, BTC_PRECISION), internal_to_numstr($amount, BTC_PRECISION));
            addlog(LOG_CRONJOB, $message);
            // email_tech(_("Exchange Wallet Balance is Too Low"), $message);
        }
    }
} catch (Error $e) {
    report_exception($e, SEVERITY::ERROR);
    // Same as below, but flag + log this for review,
    echo "\nError: \"{$e->getTitle()}\"\n  {$e->getMessage()}\n";
} catch (Problem $e) {