Royalty enforcement (ERC-721C / ERC-1155C)
ABX royalties are ERC-2981: an on-chain rate and receiver that every marketplace can read
(abx set-royalty changes them). Whether a marketplace honors that rate is its choice — ERC-2981 is
a signal, not an enforcement mechanism. ERC-721C (and its ERC-1155 twin, ERC-1155C, for an
edition) is the opt-in
enforcement layer for creators who want one: the token checks every transfer against a validator
contract, and sales that don't route through an authorized venue revert. Both standards enroll through
the same --721c flag, the same validator registry, and the same permanence rule — a creator never has
to know there are two.
The default is plain — 721 or 1155 — and that's the recommendation
An ABX token deploys plain (ERC-721, or ERC-1155 for an edition) unless you say otherwise. That is the more sovereign asset: no third-party contract sits on the transfer path, it trades on every marketplace and wallet-to-wallet, and there is nothing anyone — including you — can later switch off or misconfigure. A plain ABX token can never grow transfer restrictions: enrollment is decided at deploy and can't be retrofitted. That's a feature — a collector holding an unenrolled token knows it stays unrestricted forever.
ERC-721C/ERC-1155C is for creators who specifically want more control and royalty enforcement, and are willing to take the trade-offs knowingly. It is a transparent, deliberate opt-in — not a nudge.
The honest market picture
Be clear-eyed about what enforcement buys in 2026: royalty enforcement via ERC-721C effectively means OpenSea, plus venues built on Limit Break's Payment Processor. OpenSea's own help docs state that enabling enforcement limits sales to OpenSea and Payment-Processor venues. Magic Eden's EVM marketplace shut down in March 2026, and Blur never honored ERC-721C. So the real trade is: enforced royalties on OpenSea, in exchange for the token not trading on venues the validator doesn't authorize.
What enrolling does — and doesn't
Enrolling at deploy makes the token a creator token, permanently:
- Transfers are validated. Every real transfer calls the configured validator; a policy
violation reverts the transfer. On ERC-721C the call is a view,
validateTransfer(caller, from, to, tokenId). On ERC-1155C it's the amount-aware, non-view twin,validateTransfer(caller, from, to, id, amount)— checked once per(id, amount)pair, so a single batch transfer of several ids makes several validator calls. - Mints and burns are never validated. Minting — including either fixed-price minter and any delegated minter — cannot be blocked by validator policy, no matter how the validator is configured.
- Collectors can see it. An enrolled token advertises the creator-token interfaces via ERC-165
(
0xad0d7f6cand the legacy0xa07d229a— the same ids on both standards) and reports the ABX beacon extension (keccak256("abx.extension.creator-token"), version 1). An unenrolled token advertises neither — it is indistinguishable from a token deployed before creator-token support existed. - The owner manages the validator, never the enrollment. After deploy you can re-point the validator to a different contract, or suspend enforcement by setting it to zero — the token stays enrolled either way. There is no un-enroll: an enrolled token can always have enforcement turned back on by its owner, and a plain token can never gain it.
- If the collection is renounced, anyone may suspend — and nobody may re-arm.
setTransferValidatoris owner-only while there is an owner. Onceowner()is the zero address, any caller may passaddress(0)to suspend enforcement, and arming a validator stays owner-only, so an ownerless collection can only ever be moved toward transferability. This is the release valve for the worst reachable state: a validator that reverts every transfer on a collection with nobody left to re-point it, which would otherwise leave every collector's token permanently stuck. The trade is stated plainly — "renounced and still enforcing forever" is not a configuration this protocol offers. It does not cover an owner who hands the contract to a dead key:owner()is then non-zero, and on chain that is indistinguishable from a cold multisig. - A validator must be a real contract and must behave like one. Two shapes silently enforce
nothing while every read surface reports enforcement as on: an address with no code, and a
permissive fallback that answers any call successfully — a Safe (its fallback returns empty when
no handler is set), an uninitialised proxy, an EIP-7702-delegated EOA. Because
validateTransferreturns nothing, there is no decode to fail, so a has-code check alone would pass all three. The contract probes with a selector no validator implements and requires it to fail — every live validator reverts there — and refuses both shapes withInvalidTransferValidator(). The CLI runs the same probe before any gas is spent, so pasting your Safe address is refused with the real reason rather than "no code on this chain". It is a misconfiguration guard, not a security boundary: a contract can always be written to pass it and enforce nothing.
The recommended configuration
So that a creator who wants enforcement makes exactly one decision, the toolkit ships one recommended
validator per chain: OpenSea's StrictAuthorizedTransferSecurityRegistry
(0xA000027A9B2802E1ddf7000061001e5c005A0000 on both shipped testnets) — the validator OpenSea's
creator-fee-enforcement docs recommend, and the same registry for both standards. Under it,
owner-initiated (wallet-to-wallet) transfers go through, and transfers initiated by a non-authorized
operator revert. In practice: collectors can still send their tokens anywhere, but marketplace sales
settle only through venues the registry authorizes.
Enroll at deploy
All three deploy commands take --721c (bare --721c means recommended) — on an edition
(--copies), the same flag enrolls ERC-1155C instead:
abx deploy --image art.png --name "…" --symbol … --721c recommended
abx deploy-series --dir ./photos --name "…" --symbol … --721c recommended
abx deploy-code --script art.js --name "…" --symbol … --721c 0xYourValidator…
abx deploy --image art.png --copies open --name "…" --symbol … --721c recommended # ERC-1155CAn explicit address is checksum-validated and checked for code on the target chain before anything is
uploaded or signed. Enrolling prints one plain statement of what enforcement means; a deploy without
--721c is byte-for-byte the plain deploy (ERC-721, or ERC-1155 on an edition). --721c none is
refused: "enrolled but suspended" is not a deploy-time state — either enroll with a real validator, or
leave the flag off.
Manage after deploy
abx state <collection> # shows a "721C validator" row when enrolled
abx set-transfer-validator <collection> 0xNewValidator… # re-point enforcement
abx set-transfer-validator <collection> none # suspend (the token STAYS enrolled)
abx set-transfer-validator <collection> recommended # the chain's recommended validatorset-transfer-validator is owner-only — with one exception, above: on a collection whose owner() is
zero, anyone may send the none (suspend) form, and no one may arm a validator. It runs on any
signing lane and accepts --dry-run. It refuses a collection that didn't enroll at deploy — enrollment can never be
added to a live collection, on either standard. abx state shows the validator only for enrolled
collections — labeled 721C validator on a 721 and 1155C validator on an edition (the detection is
identical: both standards share the same ERC-165 id and getter); a suspended one reads suspended
until a validator is set again. A plain collection shows nothing new.