make_post_sell/docs/MONERO_DOOM.rst
Russell Ballestrini 923bd873f2 Add comprehensive crypto payment state transition validation
* Implement complete state machine with 17 test scenarios
* Add priority-based processing order validation
* Include property-based testing for state transitions
* Add graph analysis for state machine integrity
* Validate all payment lifecycle paths
* Ensure robust error handling and logging
* Remove temporary debug files and consolidate test structure
2025-09-30 11:26:44 -04:00

80 lines
No EOL
4.1 KiB
ReStructuredText

========================================
MONERO DOOM: The Great Restocking Crisis
========================================
Background Scenario
==================
The Complex Multi-Duplicate Payment Scenario:
1. **Setup**: $1 digital item, single user/quote/invoice
2. **Payment 1**: $1 payment → STATUS_RECEIVED → STATUS_CONFIRMED (normal flow, invoice finalized)
3. **Payment 2**: $1 payment (accidental duplicate) → STATUS_DOUBLEPAY_REFUND → refund processing → STATUS_DOUBLEPAY_REFUND_COMPLETE
4. **At 18 confirmations**: Payment 2 is close to restocking threshold (needs 20 for XMR mid-tier)
5. **Payment 3**: BOOM! Another $1 payment arrives (third payment to same address)
Expected Flow:
- Payment 3 detected as second duplicate (Payment 1 already STATUS_CONFIRMED)
- Payment 3 → STATUS_DOUBLEPAY_REFUND → refund cycle → STATUS_DOUBLEPAY_REFUND_COMPLETE
- Payment 2 hits 20 confirmations → triggers first restocking fee sweep
- Payment 3 eventually hits 20 confirmations → triggers second restocking fee sweep
The Restocking Fee Crisis
========================
**THE REAL PROBLEM**: The `sweep_restocking_fee` function appears designed to sweep "whatever is left" to close out the quote. This suggests it's meant to be run ONCE per quote, not multiple times per duplicate payment.
Critical Questions:
1. **Multiple Restocking Sweeps**: If Payment 2 and Payment 3 both trigger restocking fee sweeps, what happens?
2. **Wallet State**: After first restocking sweep, is there anything left for the second sweep?
3. **Quote Closure**: Does each duplicate payment try to "close out" the same quote multiple times?
4. **Race Conditions**: What if both payments hit 20 confirmations simultaneously?
The Danger Zone:
- Restocking fee function may assume it's the final operation on a quote
- Multiple calls could lead to double-sweeping or wallet conflicts
- Each duplicate might try to sweep the entire remaining balance
- Quote may be "closed" multiple times with unpredictable results
This scenario exposes a fundamental design assumption: that restocking fees are quote-level operations, not payment-level operations.
Investigation Required:
- Does `sweep_restocking_fee` properly handle multiple calls per quote?
- Are restocking fees calculated per payment or per quote?
- What safety mechanisms prevent multiple restocking sweeps?
- Should restocking be quote-level (once) or payment-level (per duplicate)?
Conclusion: The Solution
=======================
**THE PROBLEM**: The original `sweep_restocking_fee` function used `sweep_all` for XMR, which swept the entire subaddress balance. In multi-duplicate scenarios, this caused fund theft between payments sharing the same subaddress.
**THE ROOT CAUSE**: Multiple duplicate payments to the same Monero subaddress + `sweep_all` operations = Payment 2's restocking sweep steals Payment 3's funds (and potentially the original payment's funds too).
**THE SOLUTION**: Implemented simple, safe logic for both XMR and DOGE:
.. code-block:: python
# Simple logic: send min(balance, expected_fee)
amount_to_send = min(current_balance, fee_amount)
**Key Insights**:
1. **Perfect Accounting**: The 9% restocking fee is exact because refund network fees are deducted from the refund itself, not the restocking fee.
2. **Simple Logic**:
- If balance < expected fee: Send balance (whatever is available)
- If balance >= expected fee: Send expected fee (exact amount)
3. **No Fund Theft**: Each payment only takes what it's owed, never more.
4. **No Dust Issues**: Any remaining amounts stay for future operations or dust collection by separate processes.
5. **Priority System**: Restocking fee sweeps are Priority 4 (dead last) and blocked by mid-tier confirmation requirements (XMR=20, DOGE=12) to ensure refunds complete before fee collection.
**RESULT**: The MONERO DOOM scenario now works correctly:
- Payment 2 sends exactly $0.09 restocking fee
- Payment 3 sends exactly $0.09 restocking fee
- No fund theft, no accounting errors, no wallet drainage
The crisis is resolved with elegant simplicity: `min(balance, expected_fee)` prevents all forms of fund theft while ensuring proper restocking fee collection.