V2 is now live at fwa.funV2 is now live at fwa.funV2 is now live at fwa.funV2 is now live at fwa.funV2 is now live at fwa.funV2 is now live at fwa.funV2 is now live at fwa.funV2 is now live at fwa.funV2 is now live at fwa.funV2 is now live at fwa.funV2 is now live at fwa.funV2 is now live at fwa.fun
MigrateDrops

Start here

  • How it works
  • Deployments

Main pool

  • Main pool overview
  • Positions & weighting
  • Pricing & allocation
  • Collections
  • NFT callbacks
  • Settlement
  • Sepolia deployment

Pool fees & rewards

  • Fees & protocol revenue
  • Crown reward

FWA token

  • $FWA overview
  • Earning & claiming
  • Buybacks & fee routing

FWAIR Launches

  • FWAIR overview
  • Backing a launch
  • Where funds go
  • Claims & recovery
  • Launch settings

Custom Pools

  • Custom pools overview
  • Standard pools
  • Buyback pools
  • Create & manage a pool
  • Pool settings & fees

Controls & safety

  • Exits & recovery
  • Roles & controls
  • Settings by product

Developers

  • Testing integrations
  • Deployment & integration

V1

  • V1 guide & settings
  • V1 contracts & testnet
DocumentationNFT callbacks

Start here

  • How it works
  • Deployments

Main pool

  • Main pool overview
  • Positions & weighting
  • Pricing & allocation
  • Collections
  • NFT callbacks
  • Settlement
  • Sepolia deployment

Pool fees & rewards

  • Fees & protocol revenue
  • Crown reward

FWA token

  • $FWA overview
  • Earning & claiming
  • Buybacks & fee routing

FWAIR Launches

  • FWAIR overview
  • Backing a launch
  • Where funds go
  • Claims & recovery
  • Launch settings

Custom Pools

  • Custom pools overview
  • Standard pools
  • Buyback pools
  • Create & manage a pool
  • Pool settings & fees

Controls & safety

  • Exits & recovery
  • Roles & controls
  • Settings by product

Developers

  • Testing integrations
  • Deployment & integration

V1

  • V1 guide & settings
  • V1 contracts & testnet

NFT callbacks

How NFTs with built-in purchase callbacks receive settlement outcomes, and what their collections can do with them.

Some NFT collections have a purchase callback built into their contract. When one of their main-pool positions settles, the pool notifies the NFT contract about the outcome. The collection can use that notification for its own onchain behavior, such as recording a purchase or updating collection-defined metadata.

The NFT's own contract decides what happens in response. FWA supplies the settlement information; it does not prescribe a reward, metadata change, or other effect. Holders do not need to register a separate callback when the collection already supports it.

When the NFT contract is notified

The callback fires when an allocated listing is resolved. It reports one of four outcomes:

  • The purchaser keeps the NFT.
  • The purchaser takes the standing bid in ETH.
  • The purchaser takes the standing bid as FWA.
  • The purchaser keeps the NFT and immediately relists it with fresh backing.

Depositor resolution and public finalization after the relevant choice windows also trigger the corresponding outcome. For a relist, the callback describes the old listing's settlement; the replacement is a new listing.

This happens within the settlement transaction, after the pool has recorded its state, transfers or swap, and settlement event. Requesting a draw, receiving randomness, or initially allocating an NFT does not trigger it. Neither do listing, ordinary withdrawal, a refunded acquisition, or an oracle-drift kick.

Which NFTs support it?

The collection contract must implement IFWAPurchaseCallback and advertise it through ERC-165. The pool's notifier checks supportsInterface(0x91f3d79d) on that collection when the listing settles. A compatible collection returns true. Ordinary ERC-721 support alone does not enable the feature.

This is a callback to the NFT collection itself. Implementing it on a purchaser wallet or an ordinary depositor contract does not subscribe that address. It is also separate from the ERC-721 receiving hook used by some NFT transfers.

A FWAIR collection can support the same feature. Its collection callback is independent of the launch contract's accounting notification. The launch is notified first; if the launch and collection are the same address, that address is called once.

These callbacks are supported by the main pool. Standard and buyback custom pools do not dispatch them, even when the NFT contract advertises the interface.

What the NFT contract learns

The notification identifies the pool, settled listing, purchaser, and address that called the pool's settlement function. It also includes the listing's gross backing, the outcome, and the ETH amount represented by that outcome. All ETH amounts are in wei:

0 · PurchaserKeptNFT
The settlement amount is the net ETH returned to the old depositor when the NFT is awarded to the purchaser.
1 · PurchaserTookETH
The settlement amount is the ETH delivered to the purchaser for accepting the standing bid.
2 · PurchaserTookFWA
The settlement amount is the ETH spent under the separate FWA cashout rate, not the ETH cashout amount or the number of FWA tokens received.
3 · PurchaserRelistedNFT
The settlement amount is the net ETH returned to the old depositor. It does not include the new listing's fresh backing.

The token ID is available from the pool's canonical listing record; it is not repeated in the callback. The acquisition price and FWA token output are also omitted. An indexer can join the acquisition and settlement events for those details.

An NFT outcome describes who is entitled to the NFT. Some settlement paths can complete while NFT delivery remains pending recovery, so the callback does not always mean the NFT has already arrived in the recipient's wallet. See settlement for delivery and recovery rules.

What if the NFT callback fails?

A failed collection callback does not undo a successful settlement. The receiver gets up to 100,000 gas and no ETH. If it reverts or runs out of its allotted gas, its own changes roll back while the settlement can still complete. Any collection-specific effect may therefore be absent even though the purchase settled.

The notifier records each actual receiver call in PurchaseCallbackAttempted(fwa, target, listingId, success). A failed or unsupported ERC-165 probe skips the collection without an attempted-callback event. A successful call means the receiver returned without reverting; it does not prove a particular collection effect occurred.

The pool does not replay missed collection callbacks after successful settlement. Collections should keep essential state recoverable from canonical listings and settlement events, and provide their own reconciliation path if their feature needs one.

The pool's call to the notifier itself is a separate requirement. If that outer call fails, the entire settlement reverts and the position can be resolved again. The pool forwards 300,000 gas to the notifier, which requires at least 290,000 gas on entry; collection lookup and the ERC-165 probe each have a 30,000-gas cap. These are internal budgets, not a suggested limit for the complete settlement transaction.

Purchase notifier (Ethereum mainnet): 0x612dF3a344990F8E53499ec1bC79Be63cFa496D0

Collection implementation reference

The interface lives at src/interfaces/IFWAPurchaseCallback.sol in the contracts repository. Its function has no return value or success selector:

function onFWAPurchase(
    address fwa,
    uint256 listingId,
    address purchaser,
    address resolver,
    uint256 backing,
    uint256 settlementAmount,
    IFWAPurchaseCallback.Outcome outcome
) external;

At the receiver, msg.sender is the immutable purchase notifier. Authenticate both that exact trusted notifier and the expected fwa address. The notifier is permissionless, so checking its address alone is insufficient. Use the notifier address from trusted deployment configuration.

Read listings(listingId) from the trusted pool and verify that it is settled and names your contract as the collection before applying collection behavior. The purchaser is the recipient named in the acquisition request, who owns the allocation even when a different wallet or router paid. The resolver is the immediate caller of the pool's settlement function, which can be a campaign or forwarding contract rather than the wallet that submitted the outer transaction.

Keep the handler small and safe to reconcile more than once. Identify outcomes by pool and listing ID. Receiver return data is ignored, and guarded pool settlement functions cannot be called again from inside the callback. Ordinary collection listings do not receive the dedicated FWAIR accounting receipt.

Previous
Collections
Next
Settlement
ByTokenWorks™
Operated by Token Workshop, Inc.Terms of Service

Explore

  • Home
  • Activity
  • Leaderboard

Protocol

  • $FWA
  • Deposit
  • Manage
  • Migrate

Fwair

  • Drops
  • Beta

Resources

  • V2 explained
  • Documentation
  • Changelog
  • X