/// <summary> Collect fees. </summary> /// /// <remarks> Paul, 18/02/2015. </remarks> /// /// <param name="bitcoinFeeAddress"> The bitcoin fee address. </param> /// <param name="bitsharesFeeAccount"> The bitshares fee account. </param> public override bool CollectFees(string bitcoinFeeAddress, string bitsharesFeeAccount) { List <TransactionsRow> transSince = m_daemon.GetCompletedTransactionsInMarketSince(m_market.symbol_pair, m_market.transaction_processed_uid); if (transSince.Count > kMaxTransactionsBeforeCollectFees) { decimal buyFees = transSince.Where(t => t.order_type == MetaOrderType.buy).Sum(t => t.fee); decimal sellFees = transSince.Where(t => t.order_type == MetaOrderType.sell).Sum(t => t.fee); // make sure these are in range buyFees = m_asset.Truncate(buyFees); sellFees = Numeric.TruncateDecimal(sellFees, 8); decimal btcWorthOfBitassets; if (m_flipped) { btcWorthOfBitassets = buyFees / m_market.bid; } else { btcWorthOfBitassets = buyFees * m_market.bid; } if (btcWorthOfBitassets > kMinBtcFee && sellFees > kMinBtcFee) { // update this here to prevent failures from continually sending fees m_daemon.UpdateTransactionProcessedForMarket(m_market.symbol_pair, transSince.Last().uid); string bitsharesTrxId = null, bitcoinTxId = null; string exception = null; try { BitsharesTransactionResponse bitsharesTrx = SendBitAssets(buyFees, m_asset, bitsharesFeeAccount, "Fee payment"); bitsharesTrxId = bitsharesTrx.record_id; // WTUPID BTC DUST SIZE PREVENTS SMALL TRANSACGTIOJNs bitcoinTxId = m_bitcoin.SendToAddress(bitcoinFeeAddress, sellFees, "Fee payment"); } catch (Exception e) { exception = e.ToString(); } m_daemon.m_Database.InsertFeeTransaction(m_market.symbol_pair, bitsharesTrxId, bitcoinTxId, buyFees, sellFees, transSince.Last().uid, exception, transSince.First().received_txid, transSince.Last().received_txid); return(true); } } return(false); }
/// <summary> Handles the command. </summary> /// /// <remarks> Paul, 26/02/2015. </remarks> /// /// <param name="l"> The BitsharesLedgerEntry to process. </param> /// <param name="handler"> The handler. </param> /// <param name="market"> The market. </param> /// /// <returns> true if it succeeds, false if it fails. </returns> public bool HandleCommand(BitsharesLedgerEntry l, MarketBase handler, MarketRow market, string trxid) { if (m_adminUsernames.Contains(l.from_account)) { try { string[] parts = l.memo.Split(' '); if (l.memo.StartsWith(kSetPricesMemoStart)) { HandlePriceSetting(parts, l, handler, market); return(true); } else if (l.memo.StartsWith(kWithdrawMemo)) { // process withdrawal if (parts[0] == kWithdrawMemo) { // make sure we didn't already process this transaction! if (!m_dataAccess.IsWithdrawalProcessed(trxid)) { decimal amount = decimal.Parse(parts[1]); CurrenciesRow type = CurrencyHelpers.FromSymbol(parts[2], m_allCurrencies); string to; string txid; if (!CurrencyHelpers.IsBitsharesAsset(type)) { to = m_dataAccess.GetStats().bitcoin_withdraw_address; Debug.Assert(to != null); txid = m_bitcoin.SendToAddress(to, amount); } else { to = l.from_account; BitsharesTransactionResponse response = m_bitshares.WalletTransfer(amount, CurrencyHelpers.ToBitsharesSymbol(type), m_bitsharesAccount, to); txid = response.record_id; } // log in DB m_dataAccess.InsertWithdrawal(trxid, txid, type.ToString(), amount, to, DateTime.UtcNow); } return(true); } } } catch (Exception e) { LogGeneralException(e.ToString()); } } return(false); }
/// <summary> Refund bitshares deposit. </summary> /// /// <remarks> Paul, 05/02/2015. </remarks> /// /// <param name="fromAccount"> from account. </param> /// <param name="larimers"> The larimers. </param> /// <param name="depositId"> Identifier for the deposit. </param> /// <param name="memo"> The memo. </param> /// <param name="asset"> The asset. </param> protected void RefundBitsharesDeposit(string fromAccount, ulong larimers, string depositId, string memo, BitsharesAsset asset, string depositAddress, MetaOrderType orderType) { decimal amount = asset.GetAmountFromLarimers(larimers); // make sure failures after this point don't result in multiple refunds m_daemon.MarkTransactionAsRefundedStart(depositId, depositAddress, m_market.symbol_pair, orderType); BitsharesTransactionResponse response = SendBitAssets(amount, asset, fromAccount, memo, false); //BitsharesTransactionResponse response = m_bitshares.WalletTransfer(amount, asset.symbol, m_bitsharesAccount, fromAccount, memo); m_daemon.MarkTransactionAsRefundedEnd(depositId, response.record_id, MetaOrderStatus.refunded, amount, memo); }
/// <summary> Sends a bit assets to depositor. </summary> /// /// <remarks> Paul, 05/02/2015. </remarks> /// /// <exception cref="RefundBitcoinException"> Thrown when a Refund Bitcoin error condition /// occurs. </exception> /// /// <param name="t"> The TransactionSinceBlock to process. </param> /// <param name="asset"> The asset. </param> /// /// <returns> A BitsharesTransactionResponse. </returns> protected BitsharesTransactionResponse SendBitAssetsToDepositor(TransactionSinceBlock t, BitsharesAsset asset, SenderToDepositRow s2d, MetaOrderType orderType) { // make sure failures after this point do not result in repeated sending m_daemon.MarkDespositAsCreditedStart(t.TxId, s2d.deposit_address, m_market.symbol_pair, orderType, MetaOrderStatus.processing, TransactionPolicy.REPLACE); if (t.Amount > m_market.ask_max) { throw new RefundBitcoinException("Over " + Numeric.SerialisedDecimal(m_market.ask_max) + " " + asset.symbol + "!"); } string bitsharesAccount = s2d.receiving_address; decimal bitAssetAmountNoFee; if (m_flipped) { // they're sending us BTC, not bitAssets because the market is flipped, this is // equivelent to the opposite order type, so we have to use bid here bitAssetAmountNoFee = t.Amount * m_market.bid; } else { bitAssetAmountNoFee = t.Amount / m_market.ask; } // when buying, the fee is charged in bitAssets, // the amount recorded in the transaction is the amount of bitAssets purchased sans fee bitAssetAmountNoFee = asset.Truncate(bitAssetAmountNoFee); decimal fee = (m_market.ask_fee_percent / 100) * bitAssetAmountNoFee; decimal amountAsset = bitAssetAmountNoFee - fee; amountAsset = asset.Truncate(amountAsset); BitsharesTransactionResponse bitsharesTrx = SendBitAssets(amountAsset, asset, bitsharesAccount, "mX: " + orderType + " " + asset.symbol); m_daemon.MarkDespositAsCreditedEnd(t.TxId, bitsharesTrx.record_id, MetaOrderStatus.completed, bitAssetAmountNoFee, m_market.ask, fee); return(bitsharesTrx); }