Offer Struct
Created when a seller callscreateOffer. Fields evolve as the offer is filled or cancelled. Records persist after the offer is consumed for historical queries.
The wallet address that created the offer and deposited the collateral. This is the address that receives quote token payments when the offer is filled and that is authorized to cancel the offer.
The ERC-20 token contract address of the asset being sold. This is the token that the seller has deposited as collateral and that buyers (or claim token holders) ultimately receive.
The ERC-20 token contract address accepted as payment. Quote tokens are never held by the venue — they are transferred directly to the seller and fee recipient at fill time.
The address permitted to fill this offer. When set to
address(0), the offer is public and any address may fill it. When set to a specific address, the offer is private and only that address can execute a fill.The address that receives the protocol fee for fills against this offer. Snapshotted from the venue’s
feeRecipient at offer creation time so that later changes to the venue’s fee recipient do not affect existing offers.The amount of escrowed asset collateral that has not yet been filled or cancelled. This value starts at the actual amount received by the venue (which may differ from the requested amount for fee-on-transfer tokens) and decreases as fills occur. When it reaches
0, the offer becomes inactive.The quote-token cost per one whole unit of the asset (i.e., per
10^assetDecimals of the asset token). See the Price Computation section below for how fill costs are calculated.A Unix timestamp after which the offer can no longer be filled. The offer reverts any fill attempt where
block.timestamp >= expiry. Expiry must be in the future at creation time.A Unix timestamp controlling the settlement mode:
0— Spot offer. Assets transfer directly to the buyer at fill time.- Non-zero — Deferred (forward) offer. Assets remain in escrow until the unlock time; buyers receive ERC-20 claim tokens at fill time and redeem them for the underlying collateral after
block.timestamp >= unlockTime. Must satisfyunlockTime >= expiry.
The decimal precision of the asset token, cached at offer creation. Used in the price calculation formula to convert
pricePerUnit to the correct quote amount.The fee rate in basis points, snapshotted from the venue’s
feeBps at offer creation time. This means the fee rate is locked for the lifetime of the offer, even if the admin changes the venue-level fee later.The cumulative amount of asset that has been filled so far across all partial fills. Used in the cumulative price calculation to ensure consistent pricing regardless of fill sequence.
The cumulative quote tokens paid across all fills. Used with
assetFilled in the cumulative mulDiv formula to ensure mathematically precise split-fill pricing.true while the offer is open for fills. Set to false when either the offer is fully filled (assetRemaining == 0) or the seller cancels.Series Struct
ASeries record is created automatically the first time a deferred offer is filled for a novel (asset, unlockTime) pair. All deferred offers that share these two parameters contribute to the same series and share the same claim token contract.
The ERC-20 asset token address that defines this series.
The unlock timestamp shared by all offers in this series. Claim tokens for this series become redeemable once
block.timestamp >= unlockTime.The address of the ERC-20 claim token contract deployed for this series by the venue on first fill. Buyers who fill deferred offers in this series receive tokens at this address, and redemption burns tokens from this contract.
The total amount of asset collateral currently backing outstanding claim tokens for this series. This counter increases when fills mint claim tokens and decreases when holders redeem. The protocol enforces that
claimToken.totalSupply() == series.backing as an invariant.SeriesId Derivation
TheseriesId is computed deterministically from the two fields that define a series:
The series key uses
abi.encode (not abi.encodePacked) and is derived from only the asset address and unlock time — not the quote token. This means all deferred fills for the same asset with the same unlock time share a single fungible claim token, regardless of which quote token was used for payment.OfferId
Offer IDs are sequential unsigned integers (uint256), assigned from a nextOfferId counter that starts at 0 and increments by one for each new offer. This means:
- The first offer created on the venue has
offerId = 0, the second hasofferId = 1, and so on. - You can enumerate all offers by iterating from
0tonextOfferId - 1. - You can predict the next offer ID by reading the
nextOfferIdpublic variable.
Price Computation
ThepricePerUnit field represents the quote-token cost per one whole unit of the asset token (i.e., per 10^assetDecimals base units). When computing the quote cost for a fill, the contract uses a cumulative pricing approach with full-precision integer arithmetic:
The venue provides a view function
quoteCostFor(offerId, assetUnits) that computes the exact quote cost for a prospective fill without sending a transaction. Use this to preview costs before submitting fills.Fee Calculation
The protocol fee is computed on the quote cost and paid by the buyer on top of the seller’s proceeds:quoteCost + fee (plus any transfer fees if either token is fee-on-transfer). The fee is transferred directly to the offer’s snapshotted feeRecipient.