📋 Description
BidStorage::cancel_bid in quicklendx-contracts/src/bid.rs transitions a bid Placed -> Cancelled, while accept_bid_and_fund in escrow.rs transitions a winning bid Placed -> Accepted and funds the invoice. The repo already added a concurrent-acceptance race regression for two acceptances, but there is no test for the cancel-versus-accept interleaving: what happens when an investor cancels the exact bid an operator is accepting in the same logical window.
Why this matters: a bid that is both cancelled and accepted would corrupt invoice/escrow/investment state — funding a cancelled bid or cancelling an already-funding bid. The status-machine guard must reject the second transition deterministically. This interleaving is a distinct race from double-acceptance and deserves its own regression.
🎯 Requirements & Context
Functional requirements
Context & constraints
- Soroban tests are single-threaded; model the race as ordered sequential invocations that simulate the interleaving, consistent with
test_accept_bid_race.rs.
- Test-only; document any genuine guard gap rather than patching silently.
- Soroban SDK
25.1.1.
🛠️ Suggested Execution
1. Fork & branch
git checkout -b test/bid-cancel-accept-race
2. Implement changes
- Build the two ordered interleavings and the cross-module consistency assertions.
- Doc-comment the threat model for each ordering.
3. Test & commit
cargo test -p quicklendx-contracts test_bid_cancel_accept_race -- --nocapture
- Edge cases: cancel by non-owner rejected first; accept of an already-expired bid; cancel after the bid expired but before cleanup.
Example commit message
test(bidding): add cancel-vs-accept interleaving race regression
Verifies the bid status machine rejects the second transition and that
invoice/escrow/investment state stays consistent under both orderings.
✅ Acceptance Criteria & Guidelines
| Requirement |
Target |
| Both interleavings covered with correct rejection |
Required |
| Cross-module consistency asserted |
Required |
| Cancelled bid never fundable |
Required |
| Coverage of cancel/accept branches |
≥ 95% |
| Docs + doc comments |
Required |
cargo test + cargo clippy clean |
Required |
| Timeframe |
96 hours from assignment |
💬 Community & Support
Questions, design discussion, and help getting your environment running — join the QuickLendX contributor community on Discord: https://discord.gg/VpngvTjWa
Please drop a note in the channel when you pick this up so we can avoid duplicate work and unblock you fast. Clear communication during the PR keeps the review fast and friction-free. 🚀
📋 Description
BidStorage::cancel_bidinquicklendx-contracts/src/bid.rstransitions a bidPlaced -> Cancelled, whileaccept_bid_and_fundinescrow.rstransitions a winning bidPlaced -> Acceptedand funds the invoice. The repo already added a concurrent-acceptance race regression for two acceptances, but there is no test for the cancel-versus-accept interleaving: what happens when an investor cancels the exact bid an operator is accepting in the same logical window.🎯 Requirements & Context
Functional requirements
quicklendx-contracts/src/test_bid_cancel_accept_race.rsmodeling: (a) cancel succeeds then accept of the same bid must fail; (b) accept succeeds then cancel of the same (now Accepted) bid must fail.QuickLendXError(InvalidStatus/OperationNotAllowed) and leaves no partial state.test_cross_module_consistency.rs).get_best_bidor funded.Context & constraints
test_accept_bid_race.rs.25.1.1.🛠️ Suggested Execution
1. Fork & branch
2. Implement changes
3. Test & commit
cargo test -p quicklendx-contracts test_bid_cancel_accept_race -- --nocaptureExample commit message
✅ Acceptance Criteria & Guidelines
cargo test+cargo clippyclean💬 Community & Support
Questions, design discussion, and help getting your environment running — join the QuickLendX contributor community on Discord: https://discord.gg/VpngvTjWa
Please drop a note in the channel when you pick this up so we can avoid duplicate work and unblock you fast. Clear communication during the PR keeps the review fast and friction-free. 🚀