P2P Trading 5.1.3
27 January 2025
This release has upgrade notes. Read them before updating — they describe behaviour changes that need your attention.
SECURITY CRITICALTRADE MANAGEMENTVALIDATION FRAMEWORKNOTIFICATION SYSTEMPERFORMANCE
P2P v5.1.3
Release Date: January 27, 2025
Tags: SECURITY CRITICAL, TRADE MANAGEMENT, VALIDATION FRAMEWORK, NOTIFICATION SYSTEM, PERFORMANCE
Upgrade Notes
Breaking changes
- Changed: starting a trade now requires an explicit action rather than happening automatically when an offer is accepted.
- Changed: a message must contain at least one character; an empty message is rejected.
- Changed: raising a dispute requires selecting one of the predefined reasons.
- Changed: creating a payment method requires a valid icon selection.
- Changed: trade statuses, offer statuses and dispute priorities are now uppercase. Dispute priorities are HIGH, MEDIUM and LOW, where they were previously numeric.
Migration notes
- No new database migrations are required, and existing trades remain compatible. Status values are converted to uppercase automatically.
- Add the P2P fee configuration to your settings.
- Configure the rate limit keys in Redis.
- Set up the notification email templates.
- Enable the background job scheduler, which expires timed-out trades and releases their locked funds.
- Apply the rate limiting and validation to any admin endpoints you have added yourself, and enable CSRF protection on state-changing operations.
Added
Trade state validation
- Added enforcement of the trade lifecycle, so an invalid status change — cancelling a completed trade, for example — is refused with a clear reason instead of being applied
- Added a check of the current status before any state change, blocking manipulation attempts
Rate limiting
- Added rate limits across all P2P operations, falling back to the caller's IP address for unauthenticated requests
- Offer creation: 5 per hour per user
- Trade initiation: 20 per hour per user
- Messages: 100 per hour per user
- Dispute creation: 3 per day per user
- Search: 60 per minute
Balance locking
- Added proper escrow: a seller's funds are locked when a trade is created, and unlocked automatically if the trade is cancelled or expires
- Added double-spending prevention and a balance check before a trade can start
Trading fees
- Added a maker/taker fee model with configurable rates, defaulting to 0.1% maker and 0.2% taker
- Added minimum and maximum fee limits
- Added volume-based discount tiers, up to 50%
- Added a separate escrow fee calculation, and a net amount for both parties
Transaction atomicity
- Added all-or-nothing handling for financial operations — starting a trade and locking the balance, releasing funds and deducting the fee, and updating an offer with its payment methods. Any error rolls the whole operation back.
Trade initiation
- Added a complete trade creation flow, with amount validation against the offer's limits, payment method verification, automatic adjustment of the remaining offer amount, an expiry time derived from the auto-cancel setting, and a timeline event
Notifications
- Added event-driven notifications for trade initiation, payment confirmation and fund release
- Added dispute notifications to all parties and to admins
- Added email notifications for critical events
- Added in-app notifications with action links, and configurable notification preferences
Trade timeout handling
- Added background jobs that expire pending trades after their timeout period and release the locked funds
- Added archiving of completed trades older than 90 days
- Added hourly reputation score updates
- Added expiry handling for inactive offer listings
Paginated trade history
- Added pagination to trade history, 20 items by default and 100 at most
- Added filters by status, type, currency and date range
- Added search by trade ID or counterparty, and sorting by date, amount or status
- Added summary statistics
Validation framework
- Added consistent validation of trade amounts against min/max limits, payment methods, locations against ISO country codes, price configuration, user requirements, and dispute reasons against the predefined options
Error handling
- Added a P2P error boundary, so a failure in one area no longer takes down the page
- Added error notifications that state what went wrong and offer a recovery action
- Added automatic retry for transient errors
Dispute evidence
- Added validation of uploaded evidence: images, PDFs and text only, 5MB per file, extension verification, and a maximum of 5 evidence items per dispute
Dispute priority
- Added automatic priority assignment, so the admin queue can be worked by priority
- HIGH: fraudulent activity, payment not received, amounts over $1000
- MEDIUM: amounts between $100 and $1000
- LOW: other disputes, amounts under $100
Authentication flow
- Added clear login prompts for unauthenticated users, login buttons in error notifications, preservation of the page they were on, and visual indicators on actions that require signing in
Reputation
- Added automated reputation calculation from completed trades and success rate, average rating from trade reviews, and dispute history
- Added milestone notifications at 10, 50 and 100 trades, and trusted trader status eligibility
P2P permissions
- Added a P2P permission system with view, edit and delete permissions per resource type, plus dispute resolution, settings management and super admin permissions
- Added ownership-based access with admin override, and wildcard permissions for flexible role management
Audit logging
- Added an audit trail categorised by risk (low, medium, high, critical), with automatic security alerts on high-risk events
- Added financial operation tracking with full metadata, and admin action attribution
- Added audit log export for compliance
- Added auditing of every balance lock and unlock, and risk assessment on trade initiation based on amount
- Added rate limits of 50-100 requests per hour on admin endpoints, permission-based access control, and tracking of unauthorized access attempts
Changed
Performance
- Changed the database indexes on frequently queried fields, so trade history and offer search return faster
- Changed offer and trade queries to fetch related records together, removing repeated lookups
Fixed
Security
- Fixed a cross-site scripting vulnerability in trade messages. All user-supplied text — messages, trade terms, offer descriptions and admin panel input — is now sanitized, and HTML is stripped.
- Fixed funds being released twice under a race condition. A release is now claimed before it runs, with a 30-second lock and an hour of result caching, and it falls back gracefully if Redis is unavailable.
- Fixed funds being released on a trade that had already been processed.
Critical fixes
- Fixed a missing trade creation step that prevented offers from being accepted at all
- Fixed funds being released without validating the trade status first
- Fixed a race condition when the same trade was operated on concurrently
- Fixed a mismatch in the offer approval status format
- Fixed locked funds not being released when a trade was cancelled
Major fixes
- Fixed admin panel messages not being sanitized
- Fixed the fee calculation applied when funds are released
- Fixed a way to bypass payment method validation
- Fixed disputes being created without a reason
Minor fixes
- Fixed trade timeline events appearing out of order
- Fixed the expiry date calculation
- Fixed notification delivery failures
- Fixed search result pagination
- Fixed the offer amount not updating after a trade