Description
When an invoice is listed on the marketplace via list_invoice, the contract makes a cross-contract call to InvoiceNftContract::set_listed to transition the NFT's status from Created → Listed.
However, when a listing is cancelled via cancel_listing (contracts/marketplace/src/lib.rs lines 217–239), the marketplace only marks its own Listing.is_active = false. It does not call the NFT contract to revert the status:
pub fn cancel_listing(env: Env, caller: Address, invoice_id: u64) -> Result<(), KoraError> {
// ...validation...
listing.is_active = false;
env.storage().persistent().set(&DataKey::Listing(invoice_id), &listing);
events::listing_cancelled(&env, invoice_id, &listing.seller);
Ok(())
// ← no call to nft_client.set_cancelled() or equivalent
}
After cancellation, the NFT remains in the Listed status permanently. The SME cannot re-list the invoice (because set_listed requires Created status) and cannot mint a replacement (the original NFT is stuck). The invoice is effectively dead.
Fix
Add a reverse-status transition. Either:
- Option A: Add a
set_cancelled or set_created function to InvoiceNftContract and call it from cancel_listing.
- Option B: Add a generic
revert_to_created(caller, invoice_id) on the NFT contract callable only by the authorized marketplace.
Acceptance Criteria
Complexity: Medium (150 points)
Description
When an invoice is listed on the marketplace via
list_invoice, the contract makes a cross-contract call toInvoiceNftContract::set_listedto transition the NFT's status fromCreated → Listed.However, when a listing is cancelled via
cancel_listing(contracts/marketplace/src/lib.rslines 217–239), the marketplace only marks its ownListing.is_active = false. It does not call the NFT contract to revert the status:After cancellation, the NFT remains in the
Listedstatus permanently. The SME cannot re-list the invoice (becauseset_listedrequiresCreatedstatus) and cannot mint a replacement (the original NFT is stuck). The invoice is effectively dead.Fix
Add a reverse-status transition. Either:
set_cancelledorset_createdfunction toInvoiceNftContractand call it fromcancel_listing.revert_to_created(caller, invoice_id)on the NFT contract callable only by the authorized marketplace.Acceptance Criteria
cancel_listing, the Invoice NFT status isCreated(notListed).Complexity: Medium (150 points)