/**
  * Validates amount to ensure it follows the rules of monero
  * 
  * @param   string|float        amount
  * @return  bool    
  */
 public function valid_amount($amount)
 {
     if (!is_numeric($amount)) {
         return FALSE;
     }
     // XMR is limited to 12 decimals
     if (bc::count_decimals($amount) > 12) {
         return FALSE;
     }
     #// The maximum payment is depended on your system, 32-bit is 10 digits and 64-bit is 19 digits
     #$max_digits = strlen(PHP_INT_MAX);
     // PHP 64-bit does not support more than 9223372036854775807 (19-digits)
     if (bc::is($amount, '>=', '9223372.036854775807')) {
         return FALSE;
     }
     return TRUE;
 }
 /**
  * Check if user has sufficient balance
  * 
  * @param   object      user
  * @param   decimal     amount to check
  * @return  bool        true if enough balance (equal or more)
  */
 public function available_balance($user, $amount)
 {
     return (bool) bc::is($this->get_balance($user), '>=', $amount);
 }
示例#3
0
         $payment_ids = $pids->fetch_assoc();
         // Credit user his funds (if user has no balance for this asset, we create it, otherwise update)
         $db->query("INSERT INTO \n                                users_assets (`user_id`, `asset_id`, `balance`) \n                            VALUES \n                                (" . $payment_ids['user_id'] . "," . $asset->get_id() . "," . $row['amount'] . ")\n                            ON DUPLICATE KEY UPDATE \n                                `balance` = balance + " . $row['amount'] . ";");
     }
 }
 $db->query('COMMIT');
 // --------------------------------------------------------------------
 //
 //                      Process pending withdraws
 //
 // --------------------------------------------------------------------
 $result = $db->query('SELECT * FROM withdraws_pending WHERE status = 1 ORDER BY id ASC LIMIT 1000');
 $payments = array();
 while ($row = $result->fetch_array(MYSQL_ASSOC)) {
     // If there is not enough balance, we'll try again later ("break" instead of "continue" so that payment are processed as a queue, most fair)
     if (bc::is($row['amount'], '>', $wallet->get_unlocked_balance())) {
         break;
     }
     // In rare cases that bulk_transfer sends payment, but script does a rollback, the transfer will not be repeated by setting status to error first (requiring manual approval):
     $db->query("UPDATE withdraws_pending SET status = -1, error = 'PAYMENT IN PROCESS' WHERE id = " . $row['id']);
     $tx_id = $wallet->transfer($row['address'], $row['amount'], $row['payment_id'], $row['mixin'], $row['fee'], 0);
     $db->query('START TRANSACTION');
     if (!$tx_id) {
         $errors = $wallet->get_errors();
         $error_message = (isset($errors[0]) and isset($errors[0]['message'])) ? $errors[0]['message'] : 'Unknown error';
         $db->query("UPDATE withdraws_pending SET error = " . quote_escape($error_message) . " WHERE id = " . $row['id']);
     } else {
         $sql = insert_query('withdraws_complete', array('user_id' => $row['user_id'], 'address' => $row['address'], 'amount' => $row['amount'], 'fee' => $row['fee'], 'date_paid' => array('UTC_TIMESTAMP()'), 'asset_id' => $row['asset_id'], 'mixin' => $row['mixin'], 'txn' => $tx_id));
         $db->query($sql);
         $db->query("DELETE FROM withdraws_pending WHERE id = " . $row['id']);
     }
 /**
  * Validates withdraw (minimum withdraw)
  * 
  * @param   string|float        amount
  * @param   string|float        fee
  * @return  bool
  */
 public function valid_withdraw($amount, $fee)
 {
     global $config;
     $amount_after_fee = bc::op($amount, '-', $fee);
     // Check if amount after fee is negative
     if (bc::is($amount_after_fee, '=<', '0')) {
         return FALSE;
     }
     // Enforce minimum withdraw
     return (bool) (bccomp($amount, $config['asset'][$this->id]['min_withdraw']) !== -1);
 }