Assetera Docs
Smart contracts

Events

The AsseteraExchange event catalog: what each event means, its indexed fields, and the meta-transaction actor model.

AsseteraExchange emits one primary lifecycle event per order or offer per call, so a correct read model can be built purely from events; the view functions are only for point-in-time reconciliation. The tables below are the reference catalog. The machine-readable schema (canonical signatures, topic0 hashes, and custom-error selectors) is published with each deployment alongside the ABI and addresses.

The actor model: read identity from the event

Because the contract uses ERC-2771 meta-transactions, a relayed call's outer msg.sender / tx.origin is the trusted Forwarder, not the user. The contract resolves the real actor with _msgSender() before emitting, so the address inside each event (maker, taker, account, by, operator, proposedBy) is already correct.

Never key user identity off the transaction's from field when the forwarder is in play. Always use the address embedded in the event. isTrustedForwarder(address) / trustedForwarder() let an indexer detect and flag relayed transactions.

Order events

EventEmitted byIndexed fieldsNotes
OrderPlacedplaceOrder, placeOrderWithPermitid, makerNew order; carries sell/buy legs and expireTs.
OrderFilledfillOrder (full fill)id, maker, takerRemaining quantity reached 0; carries filled amounts, both fee amounts, feeCollector.
OrderPartiallyFilledfillOrder (partial fill)id, maker, takerOrder stays open; 5th field is the new remainingQuantity, not the buy amount.
OrderSettledsettlebuyId, sellId, operatorTwo complementary orders settled together; both fee legs and collectors.
OrderCancelledcancelOrder, cancelOrderSelfid, makerNo data fields; disambiguate the two paths via a matching KycConsumed.
OrderRefundedrefundid, maker, operatorOperator returns remaining escrow; carries a reason string.
OrderForceCancelledcancelOrderForUserid, maker, adminAdmin exit; recipient (non-indexed) may differ from maker.
OrderExpiredsweepExpiredid, makerOne per swept id in a batch; carries remainingQuantity returned.

Offer events

EventEmitted byIndexed fieldsNotes
OfferMademakeOfferid, maker, takerTargeted offer opened; carries both token legs, expireTs, and fee terms.
OfferReplacedreplaceOfferid, byCounter-proposal; by becomes the new proposedBy. Fee terms unchanged.
OfferAcceptedacceptOfferid, byAccepting party; carries the agreed terms.
OfferSettledsettleOfferid, operatorReceived amounts are net of fee; carries fee amount and collector.
OfferCancelledcancelOfferid, byTerms at cancellation; only the current proposer's side was escrowed.
OfferForceCancelledcancelOfferForUserid, maker, adminAdmin exit; both recipient fields present even if only one leg moved.
OfferExpiredsweepExpiredOffersid, proposedByOne per swept id; carries amountReturned.

Compliance and admin events

EventEmitted byIndexed fieldsNotes
KycConsumedany KYC-gated actionaccount, action, orderIdAttestation-consumed audit trail; emitted only when compliance is required for that action. orderId is 0 for Place / MakeOffer.
ComplianceRequiredSetsetComplianceRequiredactionPer-action KYC gating toggle.
CollectorAllowedsetAllowedCollectorcollectorFee-collector allowlist change.
BlacklistUpdatedsetBlacklistedhashedAccounthashedAccount is keccak256(account), pseudonymized, not reversible.

Roadmap: the on-chain blacklist (setBlacklisted / BlacklistUpdated) is slated for removal in the production baseline: a frozen user is one the backend simply declines to sign for, so the on-chain mapping is redundant for a MiFID venue. KycConsumed is emitted only when complianceRequired is true for that action; its absence means gating was disabled for the action, not that verification was skipped.

Inherited OpenZeppelin events also appear: Upgraded (UUPS), Paused / Unpaused, and RoleGranted / RoleRevoked. The role constant values needed to decode the last two are published with the deployment artifacts.

Indexing notes

  • Orders and offers are 1-indexed; totalOrders() / totalOffers() give the high-water mark.
  • Use (chain_id, tx_hash, log_index) as the idempotency key; sweep events can appear many times per transaction.
  • OrderRefunded, OrderForceCancelled, and the sweep* events are the only ways escrow leaves the contract without a matching fill or settlement; include them in any balance-reconciliation job.

Two events (OfferMade, OfferSettled) have fee-enriched signatures whose topic0 differs from an older pre-fee ABI. Always subscribe to the current topic0 values from the ABI published with the deployment, and branch decoding on topics[0] when backfilling across an upgrade.

On this page