Repository navigation
[#546] Define offer expiration at exact ledger boundaries - #568
Open
woahwhattheheck wants to merge 1 commit into
Open
woahwhattheheck wants to merge 1 commit into
woahwhattheheck wants to merge 1 commit into
Conversation
Offers gain an expires_at ledger timestamp computed as created_at + duration (checked arithmetic). The boundary is exclusive - an offer is valid only while ledger.timestamp() < expires_at, matching the Auction::ends_at convention. Expired offers cannot be accepted (OfferExpired); re-offering after expiry replaces the stale offer; zero duration and arithmetic overflow fail with InvalidDuration. The OfferMade event exposes the effective expiry. Fixes Commitlabs-Org#546
Author
|
/claim #546 Original-author GrantFox OSS/FWC26 contribution and conditional compensation claim: I, @woahwhattheheck (GitHub account ID 293286387), submit this original contribution for GrantFox OSS Third Campaign issue #546 and affirmatively claim contributor credit and consideration for any eligible bounty compensation. Please confirm eligibility, acceptance criteria, award amount (if applicable), and payment instructions. The issue is labeled "Maybe Rewarded"; no award or payment is presumed. |
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.
Summary
Fixes #546 — offers previously had no expiration at all:
Offercarriedcreated_atonly, andaccept_offercould settle a stale offer at anyfuture ledger time. This PR adds an explicit, documented expiry policy.
Offergainsexpires_at: u64, computed at creation ascreated_at + durationusing checked arithmetic.make_offertakes a newduration: u64parameter (ledger seconds).is_offer_expired(now, expires_at), centralizes alloffer-expiry comparisons.
OfferMadeevent payload now exposes the effectiveexpires_at.contracts/commitment_marketplace/README.mdanddocs/commitment_marketplace.mddocument the policy and signature.Expiration policy (documented)
The boundary is exclusive — the same convention
Auction::ends_atalready uses in this contract: an offer is valid only while
ledger.timestamp() < expires_at. At the exact expiry instant the offer isalready expired.
duration == 0or an overflowingcreated_at + durationfails with
InvalidDuration(mirrorsstart_auction).make_offerfails with
OfferExists). Once expired, a freshmake_offerby the sameofferer replaces the stale offer in place — the update path.
accept_offerrejects offers at or pastexpires_atwith the new
OfferExpirederror (feat: implement comprehensive compliance verification for commitments #35, appended; existing discriminantsunchanged) before any token movement, and does not mutate the offer.
cancel_offeris allowed before, at, or after expiry —it is also the manual cleanup path for expired offers.
Acceptance criteria
(exclusive — expired at
now == expires_at, covered bytest_offer_expires_at_exclusive_boundary).(
accept_offerfails closed; rejected calls leave storage untouchedbecause Soroban rolls back state on contract errors).
(
OfferMadecarriesexpires_at;OffAccpt/OfferCancunchanged).(exclusive-boundary accept/replace, past-boundary accept, expired-offer
cancel, zero duration,
u64::MAXoverflow, expired re-offer).Validation
cargo test -p commitment-marketplace— focused coverage for the changedbehavior lives in
tests.rs"Offer Expiration Policy Tests":test_make_offer_zero_duration_fails,test_make_offer_duration_overflow_fails,test_offer_expires_at_exclusive_boundary,test_expired_offer_replaced_by_reoffer. All existingmake_offercallsites were updated to pass an explicit
86400duration.Tradeoffs and limitations
make_offergains a requireddurationparameter;external callers must pass it. No in-repo callers existed outside unit
tests and docs (all updated here).
Offerrecords written before thischange lack
expires_atand will not deserialize under the new layout;get::<_, Vec<Offer>>treats them as absent. Offers carry no escrowedfunds (payment settles only at
accept_offer), so a dropped stale offerstrands no assets — the offerer simply re-offers.
sweeper/background cleanup is added (keeps the change minimal).
get_offersreturns expired offers too; liveness is derived by callersfrom
expires_atversus ledger time.