Functional Specifications
- Block Confirmation Monitors: Scans and tracks confirmation heights before crediting deposit values to user accounts.
- Hot/Cold Wallet Storage: Segregates trade pools into highly-liquid
Hotpools (e.g. max 10 BTC) and off-chain vaultColdstorages. - Large-Value Withdrawal Reviews: Routes transactions exceeding set threshold filters (e.g. > 1 BTC) through dynamic manual audits.
- Hot Pool Sweepers: Monitors excessive pool capacities and automatically sweeps overflows down to cold vaults.
Production reference implementations demonstrating blockchain monitoring, automatic sweeps, block tracking, and manual reviews:
// ─── JAVA BLUEPRINT ──────────────────────────────────────────────────────────
import java.util.*;
import java.util.concurrent.*;
enum TransactionStatus {
PENDING_CONFIRMATION, CONFIRMED, REJECTED, PENDING_MANUAL_AUDIT, COMPLETED
}
class DepositTransaction {
private final String id;
private final String userId;
private final double amount;
private final String txHash;
private int confirmations;
private TransactionStatus status;
public DepositTransaction(String userId, double amount, String txHash) {
this.id = UUID.randomUUID().toString().substring(0, 8);
this.userId = userId;
this.amount = amount;
this.txHash = txHash;
this.confirmations = 0;
this.status = TransactionStatus.PENDING_CONFIRMATION;
}
public String getId() { return id; }
public String getUserId() { return userId; }
public double getAmount() { return amount; }
public String getTxHash() { return txHash; }
public int getConfirmations() { return confirmations; }
public TransactionStatus getStatus() { return status; }
public void incrementConfirmations(int targetConfirmations) {
if (this.status != TransactionStatus.PENDING_CONFIRMATION) return;
this.confirmations++;
if (this.confirmations >= targetConfirmations) {
this.status = TransactionStatus.CONFIRMED;
}
}
}
class WithdrawalRequest {
private final String id;
private final String userId;
private final double amount;
private final String targetAddress;
private TransactionStatus status;
public WithdrawalRequest(String userId, double amount, String targetAddress) {
this.id = "WTH_" + UUID.randomUUID().toString().substring(0, 8);
this.userId = userId;
this.amount = amount;
this.targetAddress = targetAddress;
this.status = amount > 1.0 ? TransactionStatus.PENDING_MANUAL_AUDIT : TransactionStatus.PENDING_CONFIRMATION;
}
public String getId() { return id; }
public String getUserId() { return userId; }
public double getAmount() { return amount; }
public String getTargetAddress() { return targetAddress; }
public TransactionStatus getStatus() { return status; }
public void setStatus(TransactionStatus status) { this.status = status; }
}
class ExchangeWalletSystem {
private double hotWalletBalance = 2.0; // Liquidity pool (e.g. BTC)
private double coldWalletBalance = 98.0; // offline custody
private static final double HOT_WALLETS_CAP = 10.0; // Max allowed hot liquidity
public double getHotWalletBalance() { return hotWalletBalance; }
public double getColdWalletBalance() { return coldWalletBalance; }
public synchronized void creditHotWallet(double amount) {
this.hotWalletBalance += amount;
// Sweep check: auto sweep to cold if it exceeds cap
if (this.hotWalletBalance > HOT_WALLETS_CAP) {
double excess = this.hotWalletBalance - 2.0; // Keep 2.0 BTC base liquidity
sweepToCold(excess);
}
}
public synchronized boolean debitHotWallet(double amount) {
if (this.hotWalletBalance < amount) return false;
this.hotWalletBalance -= amount;
return true;
}
private void sweepToCold(double amount) {
this.hotWalletBalance -= amount;
this.coldWalletBalance += amount;
System.out.println("SWEEP DAEMON: Swept " + amount + " BTC to Offline Cold custody vault.");
}
public synchronized void withdrawFromCold(double amount) {
if (this.coldWalletBalance < amount) {
throw new IllegalArgumentException("Cold vault liquidity overflow");
}
this.coldWalletBalance -= amount;
this.hotWalletBalance += amount;
}
}
class DepositMonitor {
private final List<DepositTransaction> activeDeposits = new CopyOnWriteArrayList<>();
private final Map<String, Double> userBalances = new ConcurrentHashMap<>();
private static final int TARGET_CONFIRMATIONS = 6;
private final ExchangeWalletSystem walletSystem;
public DepositMonitor(ExchangeWalletSystem walletSystem) {
this.walletSystem = walletSystem;
}
public void registerDeposit(String userId, double amount, String txHash) {
activeDeposits.add(new DepositTransaction(userId, amount, txHash));
}
public void onNewBlockMined() {
for (DepositTransaction tx : activeDeposits) {
if (tx.getStatus() == TransactionStatus.PENDING_CONFIRMATION) {
tx.incrementConfirmations(TARGET_CONFIRMATIONS);
if (tx.getStatus() == TransactionStatus.CONFIRMED) {
// Credit user balance atomically
userBalances.merge(tx.getUserId(), tx.getAmount(), Double::sum);
// Credit Hot Wallet liquidity
walletSystem.creditHotWallet(tx.getAmount());
}
}
}
}
public double getUserBalance(String userId) {
return userBalances.getOrDefault(userId, 0.0);
}
public Map<String, Double> getUserBalances() { return userBalances; }
public List<DepositTransaction> getActiveDeposits() { return activeDeposits; }
}
class WithdrawalService {
private final ExchangeWalletSystem walletSystem;
private final Map<String, Double> userBalances;
private final List<WithdrawalRequest> requests = new CopyOnWriteArrayList<>();
public WithdrawalService(ExchangeWalletSystem walletSystem, Map<String, Double> userBalances) {
this.walletSystem = walletSystem;
this.userBalances = userBalances;
}
public boolean requestWithdrawal(String userId, double amount, String targetAddress) {
double currentBal = userBalances.getOrDefault(userId, 0.0);
if (currentBal < amount) return false;
// Deduct balance instantly to lock fund availability
userBalances.put(userId, currentBal - amount);
WithdrawalRequest req = new WithdrawalRequest(userId, amount, targetAddress);
requests.add(req);
if (req.getStatus() == TransactionStatus.PENDING_CONFIRMATION) {
// Process automatically from hot wallet
if (walletSystem.debitHotWallet(amount)) {
req.setStatus(TransactionStatus.COMPLETED);
} else {
req.setStatus(TransactionStatus.PENDING_MANUAL_AUDIT); // Hot wallet dry-out fallback
}
}
return true;
}
public void approveManualWithdrawal(String requestId) {
for (WithdrawalRequest req : requests) {
if (req.getId().equals(requestId) && req.getStatus() == TransactionStatus.PENDING_MANUAL_AUDIT) {
if (walletSystem.debitHotWallet(req.getAmount())) {
req.setStatus(TransactionStatus.COMPLETED);
} else {
// Replenish hot wallet from cold storage
walletSystem.withdrawFromCold(req.getAmount());
walletSystem.debitHotWallet(req.getAmount());
req.setStatus(TransactionStatus.COMPLETED);
}
break;
}
}
}
public List<WithdrawalRequest> getRequests() { return requests; }
}
public class Main {
public static void main(String[] args) {
ExchangeWalletSystem walletSystem = new ExchangeWalletSystem();
DepositMonitor depositMonitor = new DepositMonitor(walletSystem);
WithdrawalService withdrawalService = new WithdrawalService(walletSystem, depositMonitor.getUserBalances());
System.out.println("=== INITIAL BALANCES ===");
System.out.println("Hot Wallet: " + walletSystem.getHotWalletBalance() + " BTC");
System.out.println("Cold Wallet: " + walletSystem.getColdWalletBalance() + " BTC");
System.out.println("\n=== DEPOSIT PROCESS ===");
depositMonitor.registerDeposit("alice", 9.0, "0xdeposit_hash");
for (int block = 1; block <= 6; block++) {
depositMonitor.onNewBlockMined();
System.out.println("Block " + block + " mined. Alice Balance: " + depositMonitor.getUserBalance("alice") + " BTC | Hot Wallet: " + walletSystem.getHotWalletBalance() + " BTC");
}
System.out.println("Cold Wallet Balance: " + walletSystem.getColdWalletBalance() + " BTC");
System.out.println("\n=== AUTOMATED WITHDRAWAL ===");
System.out.println("Alice requests 0.5 BTC withdrawal...");
withdrawalService.requestWithdrawal("alice", 0.5, "address_xyz");
System.out.println("Alice balance: " + depositMonitor.getUserBalance("alice") + " BTC | Hot Wallet: " + walletSystem.getHotWalletBalance() + " BTC");
System.out.println("\n=== LARGE WITHDRAWAL (AUDIT FLOW) ===");
System.out.println("Alice requests 2.5 BTC withdrawal...");
withdrawalService.requestWithdrawal("alice", 2.5, "address_abc");
for (WithdrawalRequest req : withdrawalService.getRequests()) {
System.out.println("Request: " + req.getId() + " | Amount: " + req.getAmount() + " | Status: " + req.getStatus());
if (req.getStatus() == TransactionStatus.PENDING_MANUAL_AUDIT) {
System.out.println("Approving " + req.getId() + " manually...");
withdrawalService.approveManualWithdrawal(req.getId());
System.out.println("Request Status after audit: " + req.getStatus());
}
}
System.out.println("\n=== FINAL STATE ===");
System.out.println("Alice Balance: " + depositMonitor.getUserBalance("alice") + " BTC");
System.out.println("Hot Wallet: " + walletSystem.getHotWalletBalance() + " BTC");
System.out.println("Cold Wallet: " + walletSystem.getColdWalletBalance() + " BTC");
}
}