Description
In Soroban, entries in persistent() storage expire after their TTL (time-to-live) elapses. Once archived, the entry is pruned from the ledger and reads return None — identical to the entry never having existed.
contracts/marketplace/src/lib.rs stores Listing structs in persistent storage:
env.storage()
.persistent()
.set(&DataKey::Listing(invoice_id), &listing);
However, no call to extend_ttl is made anywhere in the contract — not in list_invoice, fund_invoice, or cancel_listing. This means every listing will eventually expire and be archived by the ledger.
When that happens, get_listing returns KoraError::ListingNotFound for a listing that was created and never explicitly removed. Investors lose visibility into their positions, and the funded_amount history is irrecoverably gone.
Contrast this with the treasury contract, which correctly calls extend_ttl on persistent entries after updates.
Fix
Extend the TTL of a listing entry on every write (create, fund, cancel):
const LISTING_TTL_THRESHOLD: u32 = 535_680; // ~31 days
const LISTING_TTL_BUMP: u32 = 535_680;
// After each .set():
env.storage().persistent().extend_ttl(
&DataKey::Listing(invoice_id),
LISTING_TTL_THRESHOLD,
LISTING_TTL_BUMP,
);
Also extend TTL in get_listing to reset the clock on read-only access for long-lived listings.
Acceptance Criteria
Complexity: Low (75 points)
Description
In Soroban, entries in
persistent()storage expire after their TTL (time-to-live) elapses. Once archived, the entry is pruned from the ledger and reads returnNone— identical to the entry never having existed.contracts/marketplace/src/lib.rsstoresListingstructs in persistent storage:However, no call to
extend_ttlis made anywhere in the contract — not inlist_invoice,fund_invoice, orcancel_listing. This means every listing will eventually expire and be archived by the ledger.When that happens,
get_listingreturnsKoraError::ListingNotFoundfor a listing that was created and never explicitly removed. Investors lose visibility into their positions, and thefunded_amounthistory is irrecoverably gone.Contrast this with the
treasurycontract, which correctly callsextend_ttlon persistent entries after updates.Fix
Extend the TTL of a listing entry on every write (create, fund, cancel):
Also extend TTL in
get_listingto reset the clock on read-only access for long-lived listings.Acceptance Criteria
list_invoice,fund_invoice, andcancel_listingall callextend_ttlafter writing.Complexity: Low (75 points)