On-chain

EVM — Seaport attribution

Exclusivo EVM sales settle on canonical OpenSea Seaport, not on a contract of ours. Attribution is therefore a convention on the order struct — this page is the whole of it, including the parts that do not work.

The attribution markers

Every Seaport order Exclusivo builds — listings and collection offers alike — carries two markers. Both are set in buildExclusivoOrderAttribution() and neither touches order economics.

1. zone — the crawlable marker

The order's zone is set to the Exclusivo platform fee recipient:

zone
0xCD93552140bF932842Dbc767D0c6Cc75F2BA680C

Orders stay FULL_OPEN; the zone is never given execution authority, so it cannot block or alter a fill. It exists purely because Seaport echoes it in the OrderFulfilled log, which gives you a one-field test for "is this ours". The same value is published as marketplaceContracts.evmFeeRecipient in the manifest; treat the manifest as authoritative if the two ever differ.

2. salt — the order-struct brand

The order salt is built as a constant 8-byte brand prefix followed by 24 random bytes:

salt prefix (ASCII "EXC1:SEa")
0x455843313a534561  // + 24 random bytes

salt is not present in OrderFulfilled, so it is useless for log scanning. It brands the order struct itself, which means you can use it when you hold the order — order JSON from an API, fulfillment calldata, or the order-hash preimage.

The OrderFulfilled log

Sales are emitted by canonical Seaport at these addresses on every chain we trade on:

VersionAddress
Seaport 1.50x00000000000000ADc04C56Bf30aC9d3c0aAF14dC
Seaport 1.60x0000000000000068f116a894984e2db1123eb395
ABI
event OrderFulfilled(
    bytes32 orderHash,
    address indexed offerer,
    address indexed zone,
    address recipient,
    SpentItem[] offer,
    ReceivedItem[] consideration
);

// topic0
0x9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31

Because zone is indexed, you can filter server-side: topic0 = the hash above, topic2 = the zone address, left-padded to 32 bytes. That is a cheap, exact query on any log provider.

eth_getLogs
{
  "address": ["0x0000000000000068f116a894984e2db1123eb395", "0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC"],
  "topics": [
    "0x9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31",
    null,
    "0x000000000000000000000000cd93552140bf932842dbc767d0c6cc75f2ba680c"
  ]
}

Decode recipe

For a listing fill (the common case: someone buys a listed NFT), decode the matched log like this.

Pseudocode
for each log where topic0 == OrderFulfilled and emitter in {Seaport 1.5, 1.6}:
  if zone != 0xCD93552140bF932842Dbc767D0c6Cc75F2BA680C: skip   // not an Exclusivo order

  offer item (ERC721)  -> collection, tokenId
  offerer              -> seller
  recipient            -> buyer

  consideration items:
    item paid to the offerer   -> price          (seller proceeds / ask)
    item paid to the zone addr -> marketplaceFee (200 bps of price)
    any remaining item         -> royaltyAmount, royaltyRecipient

  itemType NATIVE -> currency is the chain-native asset
  itemType ERC20  -> currency is that token (WETH on accepted offers)

  orderHash -> orderId
  tx hash   -> tx
  block.timestamp -> timestamp

The consideration array is ordered as built, but do not rely on index positions — identify each item by its recipient. The seller leg is the item paid to offerer, the fee leg is the item paid to the zone address, and whatever is left is royalty.

Fees are on top, not deducted

price is the seller ask and is exactly what the seller receives. The buyer paid price + marketplaceFee + royaltyAmount. If you sum every consideration item and call the result the sale price, your floor and volume figures will run high against every other source.

Accepted collection offers

When a seller accepts a collection offer, the same event fires but the roles invert, because the offerer is now the buyer. Handling this wrong is the fastest way to publish a sale with the parties swapped.

FieldListing fillAccepted collection offer
Offer itemThe ERC-721WETH (the currency)
ConsiderationThe payment legsIncludes the ERC-721
offererSellerBuyer
recipientBuyerSeller
Seller identityoffererThe token's previous owner — read Transfer.from for that ERC-721 in the same receipt
CurrencyUsually nativeERC-20 (WETH)

A reliable discriminator: if the offer array contains an ERC-721 item it is a listing fill; if the consideration array contains the ERC-721 it is an accepted offer.

Caveats you must handle

Orders created before 2026-07-26 have zone 0x0

The zone convention was adopted on 2026-07-26. Every order signed before that date has zone = address(0) and is indistinguishable from any other Seaport order. The only heuristic available is a consideration item paying exactly 200 bps of the seller leg to our fee recipient, which is weak and will produce both false positives and false negatives. For historical EVM sales, use the public API.

ApeChain is not attributable at all

ApeChain purchases route through Reservoir rather than through a Seaport order we built. There is no zone, no salt, and no OrderFulfilled from us. ApeChain activity is served by the API only — if your pipeline is chain-complete only when every chain resolves on-chain, ApeChain will silently be missing.

The external-aggregator fee is not an Exclusivo sale

When a user buys a foreign OpenSea listing surfaced inside Exclusivo, we charge a 2% aggregator fee as a bare EOA transfer in a separate transaction. It emits no log. That underlying sale is an OpenSea sale, not an Exclusivo sale, and counting it as ours would double-count marketplace volume. The absence of a log here is by design, not an oversight.
  • OpenSea prepared fulfillment (required on Ink) still emits the same OrderFulfilled carrying our zone — attribution holds, no special case needed.
  • Both Seaport versions are live. Filter on 1.5 and 1.6 together; an indexer watching only one will lose sales without erroring.
  • A cancelled listing may still be fillable. We do not call cancelOrders for listings, so an order cancelled in our book remains valid on-chain until expiry. A fill of such an order still carries our zone and is still a real sale.

Launchpad (primary market)

The launchpad ERC-721 is Exclusivo's own bytecode, deployed fresh per collection, so primary-market activity is fully on-chain. Contracts from the v3.1 template revision (2026-07-26 onward) emit:

ExclusivoERC721 v3.1
// One event per mint, full economics.
// Buyer total = paid + platformFee.
event Minted(uint256 indexed phaseId, address indexed to, uint256 quantity,
             uint256 paid,          // phase.price * quantity (creator proceeds)
             uint256 platformFee);  // per-mint platform fee * quantity (treasury)

// Full phase payload — no archival view calls needed.
event PhaseAdded(uint256 indexed phaseId, Phase phase);
event PhaseUpdated(uint256 indexed phaseId, Phase phase);
// Phase = (uint8 kind, bytes32 merkleRoot, address gateToken, uint256 minBalance,
//          uint256 price, uint64 startTime, uint64 endTime,
//          uint32 maxPerWallet, uint32 maxSupply)
// kind: 0 = public, 1 = allowlist, 2 = ERC-721 gated, 3 = ERC-20 gated

// Reserved (airdrop) deliveries, distinguishable from paid mints.
event ReservedMinted(address indexed to, uint256 quantity);

// Royalty config — ERC-2981 itself is silent.
event RoyaltySet(address receiver, uint96 bps);

// ERC-4906 — refresh metadata on reveal / baseURI change.
event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);

Legacy signatures still in service

Already-deployed contracts are immutable, so older signatures remain live. An indexer must decode both forms or it will silently skip mints on older collections.

Deploy eraMintedPhaseAdded / PhaseUpdated
v2 (legacy)None — only the ERC-721 TransferNone — phase config is not observable
v3, before 2026-07-26Minted(uint256 indexed phaseId, address indexed to, uint256 quantity, uint256 paid) paid excludes the per-mint platform fee, so true buyer spend is not recoverable from logs(uint256 indexed phaseId, uint8 kind) — config requires a phases(id) view call
v3.1 (current)The 5-field form aboveFull Phase payload

v2 mint prices are unrecoverable

v2 contracts emit no custom events at all. There is no mint price, no phase, and no platform-fee split in their logs — only transfers. v2 is no longer deployed, but the deployed ones will never gain events. Price those mints from the API or not at all.