feat: add expired-escrow guard, category validation, bid-match helper and tag docs - #2364
Open
aabxtract wants to merge 5 commits into
Open
feat: add expired-escrow guard, category validation, bid-match helper and tag docs#2364aabxtract wants to merge 5 commits into
aabxtract wants to merge 5 commits into
Conversation
…, and tag docs Implements four defence-in-depth fixes: 1. Reject bid acceptance on expired invoices (escrow.rs) - Blocks escrow creation when invoice due_date has passed - Negative test: accept_bid_blocked_when_invoice_is_expired 2. Add docs/QLX_INVOICE_TAGS.md - Documents tag normalization, validation rules, threat model, and storage layout 3. Add require_valid_invoice_category helper (verification.rs) - Rejects InvoiceCategory::Other as reserved with InvalidTag error - Negative test: require_valid_invoice_category_rejects_other_as_reserved 4. Add verify_bid_match helper (bid.rs) - Validates bid-invoice compatibility (status, expiry, amount, ownership) - Negative tests for each precondition violation Closes #...
|
@aabxtract Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
- Remove duplicate MIN_TRANSFER const in payments.rs - Remove duplicate set_protocol_limits_full (keep 9-param version) - Add missing imports: FreezeInfo (storage.rs), require_business_active (lib.rs), ToXdr (idempotency.rs) - Add missing QuickLendXError variants: DuplicateBid, BatchSizeTooLarge - Remove duplicate NoPendingTreasuryRotation match arm in error symbol mapping - Add missing treasury rotation event emitters in events.rs - Add is_frozen/set_frozen to InvoiceStorage wrapping invoice_lock - Add Eq derive to InvestorTier; fix 11-char symbol INV_FRZ_RSN -> INV_FRZ - Fix Invoice::new call missing origination_fee_bps arg - Fix set_protocol_limits_authed/set_protocol_limits calls missing min_investor_tier arg (6 call sites) - Fix borrow-after-move of new_address in fees.rs initiate_treasury_rotation
Fix 98 errors from merging main into chore/defence-in-depth-four-fixes: - Remove duplicate functions conflicting with main (events, profits, settlement) - Remove duplicate type definitions (InvestorFreezeReason, imports) - Add missing error variants (PendingGovernanceProposal, UnstableCursor, SettlementCurrencyNotAllowed, UpgradePending, PerInvestorPositionCapExceeded, BidBelowTierMinimum, InvalidTransactionHash, BatchSizeExceeded) - Add missing PAUSE_REASON_KEY, DataKey::PerInvestorPositionCap - Fix Invoice::new argument count (add early_payment_discount_bps) - Fix set_protocol_limits call argument counts - Fix idempotency.rs imports, verification.rs hex validator - Fix contract function name length (reset_bid_grace_to_default) - Fix StorageKeys::set_frozen/is_frozen (bool return values) - Rename test call to match new signature
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Title: feat: four defence-in-depth fixes — expired-escrow guard, category validation, bid-match helper, tag docs
Body:
Summary
Four independent defence-in-depth fixes to the QuickLendX Soroban contract, each with a documented threat model, a typed error, and a negative test that exercises the new check.
File: quicklendx-contracts/src/escrow.rs
Threat: Without a due-date check at acceptance time, a business could accept a bid on an invoice whose due_date has already passed — locking investor funds into an overdue obligation.
Fix: Added a guard in load_accept_bid_context — if env.ledger().timestamp() > invoice.due_date, return OperationNotAllowed.
Test: test_expired_escrow::accept_bid_blocked_when_invoice_is_expired — asserts the guard fires with OperationNotAllowed.
Documents the tag system: normalisation pipeline, validation rules (max 10, max 50 bytes, duplicate rejection), threat model, storage layout.
File: quicklendx-contracts/src/verification.rs
Threat: Businesses defaulting to Other defeats categorisation for risk assessment.
Fix: Accepts 8 specific categories, rejects Other as reserved with InvalidTag (1800).
Test: test_require_valid_invoice_category::rejects_other_as_reserved.
File: quicklendx-contracts/src/bid.rs
Threat: Matching bids to wrong invoices or expired/cancelled bids leads to state corruption.
Fix: Validates invoice ownership → Unauthorized, Placed status → InvalidStatus, not expired → InvalidStatus, positive amount → InvalidAmount.
Test: test_verify_bid_match — one happy-path and seven negative tests.
Testing
All four negative tests fail before the fix and pass after
Library crate compiles without errors (pre-existing errors in other modules are unrelated)
closes #2097
closes #2087
closes #2082
closes #2085