Index Market listings
Goal:
- index Market listings for analytics or a custom UI
- compute listing-level metrics (minimum payout per ve, discount vs principal)
Strict mode invariant:
- The Furnace is the only counterparty for listing settlement.
- Listings are limit sells to the Furnace. There are no user-to-user lock transfers.
What you will use
MarketRouteraddress fromdeployments/<network>.jsonabis/<network>/MarketRouter.abi.jsonVeClaimNFTreads for principal/autoMax/lockEnd
Data flow
Steps
1) Decode the core Market events
Minimum set:
LockListed(limit sell to Furnace created)LockDelisted(listing removed)ListingSettled(Furnace settled the listing)
If you support Buy intents (limit buys / bonus target escrow into the Furnace):
BonusTargetEscrowCreatedBonusTargetEscrowAutoFurnaceExecutedBonusTargetEscrowCancelledBonusTargetEscrowExpired
Note:
- Bonus target escrow execution routes into the Furnace, not into buying user locks.
Sellback note:
- A seller can exit via Sell now (Market sell) to the Furnace.
- In that case you will see:
- MarketRouter
MarketSellToFurnace(always) - LockDelisted (reason = SOLD_TO_FURNACE) if the lock was previously listed
- Furnace
LockSoldToFurnace(the lock is burned).
- MarketRouter
2) Maintain listing state
Your listing index can be:
- “event sourced” (derive current state from the event stream)
- or “state verified” (occasionally confirm with onchain views)
For most products:
- event sourced is enough and cheaper
Also index listing expiry (expiresAtTime) from LockListed so UIs can hide/disable expired listings and indexers can auto-mark them inactive.
3) Compute the 3 most useful listing metrics
Given a tokenId:
- principal: from
VeClaimNFT.getLockInfo(tokenId).amount - veNow: compute from the ve math (below)
Compute veNow:
- if
autoMax == true:veNow = amount - else:
veNow = floor(amount * (lockEnd - now) / MAX_LOCK_DURATION)
Then:
- minimum payout per ve =
minClaimOut / veNow - discount vs principal =
(minClaimOut - principal) / principal - time remaining =
effectiveLockEnd - now- if autoMax is ON, treat time remaining as
MAX_LOCK_DURATION
- if autoMax is ON, treat time remaining as
4) Track settlements correctly
When a listing is settled by the Furnace:
ListingSettledis emitted- The lock is transferred to the Furnace and burned
- The seller receives CLAIM
For indexers:
- treat
ListingSettledas the canonical “listing closed” moment
What success looks like
- You can render a listings page from your DB.
- “Listed/frozen” state matches the official app.
- All settlements show as Furnace settlements (no user-to-user lock transfers).
Next reads
- Protocol Market details: Market (MarketRouter)
- ve math + autoMax rules: Locks (veCLAIM)