abx.
Reference

Deployments

The canonical, shared ABX infrastructure — the clone factories (trust anchors) and the stateless singletons every project reuses, deployed as public goods.

The machine-readable source of truth is packages/sdk/src/deployments.ts (keyed by EIP-155 chainId). This page mirrors it for humans — if the two ever disagree, the manifest wins, and the drift is a bug. The toolkit resolves every address by override → env → manifest: a --factory/--renderer/… flag, then the matching ABX_* env var, then the manifest below.

Same address on every chain

Every contract below except the generator is deployed through the keyless CREATE2 proxy (, present on every EVM chain) with a canonical salt (contracts/script/AbxSalts.sol). Identical salt + identical initcode ⇒ the same address on every chain — so the whole infra set is one address list, and a new chain deploys to the same addresses (computable before the first transaction). The factory implementations are cross-chain-identical too: a factory does exactly one CREATE at nonce 1 from its own (identical) address.

Production (mainnet)

None yet. ABX is in a testnet-only alpha — the supported chain targets today are sepolia and base-sepolia (see SDK → Chains). Mainnet and L2 production entries are intentionally absent until the canonical set is deployed and funded on those chains (Distribution roadmap). When they are, these addresses are the same there too.

Canonical infrastructure (Sepolia · Base Sepolia — identical)

ContractEnv overrideAddress (all chains)
OneOfOneImageFactory (1/1 anchor)ABX_FACTORY
SeriesImageFactory (Series anchor)ABX_SERIES_FACTORY
SeriesCodeFactory (code anchor)ABX_SERIES_CODE_FACTORY
OneOfOneEditionFactory (1/1-edition anchor)ABX_ONE_OF_ONE_EDITION_FACTORY
EditionImageFactory (edition anchor)ABX_EDITION_FACTORY
EditionCodeFactory (code-edition anchor)ABX_EDITION_CODE_FACTORY
AbxMetadataRenderer (spec v11)ABX_RENDERER
AbxChunkStore (SSTORE2 reader)ABX_CHUNK_STORE
AbxSeedSource (mint-time pseudorandom seed)ABX_SEED_SOURCE
AbxFixedPriceMinter (shared 721 sale)ABX_FIXED_PRICE_MINTER
AbxFixedPriceMinter1155 (per-id edition sale)ABX_FIXED_PRICE_MINTER_1155
AbxMetadataLib (delegatecalled write path)
AbxParamsLib (delegatecalled write path)
AbxCodeLib (delegatecalled write path)
AbxEditionLib (delegatecalled write path)

Factory EIP-1167 implementations (also identical on every chain): OneOfOneImage · SeriesImage · SeriesCode · OneOfOneEdition · EditionImage · EditionCode .

One deployment, re-cut 2026-08-20

Every address on this page comes from one source tree, and nothing here descends from an earlier generation. That is deliberate: ABX is pre-launch, so rather than layering a migration on top of the previous set, the whole thing is re-cut whenever the contracts change — greenfield, so old anchors are simply forgotten.

The 2026-08-20 batch added opt-in burn and an owner-set, reduce-only royalty cap (up to 100%), on top of moving the Params/ConfigurableParams write shells into AbxParamsLib (the extraction that bought the two code tokens their EIP-170 headroom back). So it moved all six token factories and their implementations, plus AbxParamsLib and AbxEditionLib (which links it). What did not move — because their initcode is unchanged — is checkable rather than asserted: the renderer (spec v11), the generator, the chunk store, the seed source, both minters, and AbxMetadataLib / AbxCodeLib keep their addresses. A CREATE2 address is a function of the initcode, so what moved is something you can verify.

Two consequences worth stating plainly:

  • Projects deployed from any earlier anchor are not covered by this page. They keep working on their frozen implementations, but they are not canonical against this manifest, and abx will report their factory as an older version. Redeploy from the anchors above.
  • creator and creator_links replaced artist and artist_links as on-chain collection metadata field keys, and AuthOption.Artist became AuthOption.Creator. Renderer spec version moved to 7 for exactly this reason — a v6 renderer emits a different member key, so it is genuinely behind rather than cosmetically so.
  • Renderer spec version is now 8. v8 removed the abx_params block from the token document and narrowed each field's provenance note to the route the value took rather than a claim about where it ends up. A renderer that still emits abx_params describes params the contract no longer guarantees it can enumerate the same way, so v7 is genuinely behind too. Params remain readable on-chain from the token itself — see Params.
  • The on-chain metadata field store moved into AbxMetadataLib, a delegatecalled library all six token types link. That is what bought the two code types their EIP-170 headroom, and it is why every implementation address on this page moved even where the token's own behavior did not.

The factory address is the trust anchor: a contract is canonical when the chain's factory deployed it (verified via isAbxClone, not the spoofable AbxDeployed beacon — see Authenticity). The rest are stateless, ownerless singletons referenced by address.

Anchor generations — "canonically ABX v2"

The six factories above are one generation, identified by the core spec version its clones report as abxVersion() — currently v2. A generation is what a redeploy batch replaces, and the SDK records them in ANCHOR_GENERATIONS so a consumer can distinguish two answers that would otherwise both be a bare false:

  • deployed by an ABX factory that has since been replaced — canonically ABX, older;
  • deployed outside the toolkit entirely.

verifyProvenance() returns which, plus the core version, so the sayable answer is "canonically ABX v2" rather than a boolean. It is checkable without trusting this page: the version is on the clone itself, which is also why the answer survives its factory being retired.

Two rules this list lives by. It is provenance, never trust — a retired generation never widens verifyCanonical, because a superseded generation can predate a security remediation, and the gate must stay exactly as narrow as the current anchors. And one core version, one generation — every token-layer redeploy bumps AbxVersion.CORE_VERSION, enforced by a test rather than a convention.

Pre-launch generations are deliberately not enumerated: they were testnet-only and disposable, so a collection deployed by one reads as not-canonical until it is redeployed or re-registered. Git has their addresses; the manifest records what is live and, from the first batch that retires an anchor set, what it replaced.

Per-chain (the generator)

AbxGenerator (ABX_GENERATOR) — the animation_url field renderer for code projects — bakes chain-specific immutables (per-chain runtime-asset pointers and the dependency registry), so its address differs per chain:

ChainAbxGenerator
Sepolia (11155111)
Base Sepolia (84532)

Linked libraries and external pointers

All six token types delegatecall part of themselves into separately deployed libraries — every one of them the on-chain metadata field store, and the code and edition types their write paths on top of that. Linking one costs nothing in determinism: the libraries are CREATE2-deployed through the same keyless proxy at their own canonical salts, and linking is a substitution of an address into already-compiled bytecode, so the linked factory's initcode — and therefore its address — is fixed as soon as the libraries' are. (A deployer's nonce is an input to plain CREATE, never to a CREATE2 address. The recorded library addresses have always been chain-identical, and one of them landed at the same address on both chains from deployer nonces 215 apart.) The salts:

LibrarySalt string (AbxSalts.sol)keccak256(salt)
AbxMetadataLibabx.lib.metadata.v10xd7580b1da51d3bf89d2b793e13ac1555022c9b180961c117e86b9ab1a84680b9
AbxParamsLibabx.lib.params.v10xbf0c74210ab6a4720d238a4ce2636e2c2ce21a378a8f7688db175e0fd05697d5
AbxCodeLibabx.lib.code.v10x04c93005461fa51fa65cb9fbcf3d4ef591b3f9d1e7f01c6ddac70116149002bd
AbxEditionLibabx.lib.edition.v10x84bb4cc42185d7007eb139933b5ef32e59c09e94267ed5e0a4a6b3ad71c14d4a

AbxEditionLib delegatecalls AbxParamsLib, so it is itself linked before it is deployed — the one library whose initcode depends on another library's address.

The four libraries are listed in the main table above, deployed explicitly by DeployLibraries.s.sol at the salts named here — not by forge's automatic linking, which routes through the same proxy but at its own salt of zero. Which library each token links:

Token typeLinks
SeriesCodeAbxMetadataLib, AbxParamsLib, AbxCodeLib
EditionCodeAbxMetadataLib, AbxParamsLib, AbxCodeLib, AbxEditionLib
OneOfOneEdition, EditionImageAbxMetadataLib, AbxEditionLib
OneOfOneImage, SeriesImageAbxMetadataLib

AbxMetadataLib is the one every type links: the on-chain metadata field store — the setField / lockField write paths and the reads over them — lives there rather than in each token. Externalizing it is what put the two code types back under EIP-170 with room to spare, and it means the two ERC-721 image types, which linked nothing before, link one library now.

Do not pass --libraries when deploying. Compile-time linking writes the address map into settings.libraries, which is part of the metadata JSON whose hash is appended to the bytecode — so it changes the initcode, and therefore the CREATE2 address, of the very contracts it is meant to pin. Measured: adding it moves all five library-linked addresses. The deploy scripts substitute the placeholder in the compiled artifact instead (script/AbxLink.sol), which is also the only method the SDK can use — it ships bytecode, it does not compile — and that is what keeps the two lanes on one address.

  • Art Blocks DependencyRegistryV0 (ABX_DEPENDENCY_REGISTRY) — the name@version resolution root ABX reads but never deploys: Sepolia ; Base Sepolia has none (collections point at their own, or the resolver's built-in CDN map).

Verifying an address

Every contract on this page is source-verified on both chains — open any address in the explorer (Etherscan for Sepolia, Basescan for Base Sepolia) and you can read the exact Solidity it runs, rather than taking our word for it. The trust anchors are meant to be audited, so a canonical address that shows up unverified is a bug worth reporting.

Any address here is also checkable on-chain — the renderer, for example, reports its spec:

cast call <renderer> "specVersion()(uint256)" --rpc-url <rpc>   # → 11

Adding or updating a chain

Standing up a new chain runs the same script/Deploy*.s.sol with the same salts → the same addresses as above (the canonical set), so you can publish them before the first transaction. Deploying a fresh singleton (or a new contract revision) is an owner op that ends in a manifest edit. See the contract-change checklist, the authoritative workflow (redeploy → verify → update deployments.ts and this page).

The write-path libraries go first

CREATE2 for libraries is the standard process, not an accident of the toolchain. Deploy them explicitly, before anything that links them:

# print the three canonical library addresses — sends nothing
forge script script/DeployLibraries.s.sol --sig 'predict()'

# then deploy them (idempotent: a library that already has code is reported and skipped)
forge script script/DeployLibraries.s.sol --rpc-url <rpc> --broadcast

The addresses predict() prints are the ones the SDK predicts (predictParamsLib(), predictCodeLib(), predictEditionLib() in create2.ts), so a chain bootstrapped with forge and a chain bootstrapped by the toolkit agree. The SDK's own lazy bootstrap (deploySeriesCodeFactory / deployEditionCodeFactory, used for sandboxes and private chains) does the same thing in the same order — CREATE2 at the same salts, skipping any library already on-chain — so a partially set-up chain is finished, never duplicated.

A library's address is a function of its creation bytecode, so build settings move it. Two ways to get this silently wrong:

  • Compile-time linking. Passing --libraries src/…:Lib:0x… to forge build/forge script writes that map into settings.libraries in every artifact's metadata, and the metadata hash is appended to the creation bytecode — so the library's own address moves, and so does the linked factory's. Linking after compilation (substituting into solc's __$…$__ placeholder, which is what forge's automatic linking, the deploy scripts (script/AbxLink.sol), and the SDK all do) cannot have that effect.
  • Optimizer profile. The code tokens compile at optimizer_runs = 200 while everything else runs at 1,000,000, and a library inherits the profile of the unit that pulls it in. The canonical library bytecode is the default-profile artifact — the one vm.getCode returns and pnpm sync-abis ships to the SDK.

Both failures are invisible until two chains disagree, so check rather than assume: each script's --sig 'predict()' and the SDK's matching predict*() must print the same address — all five of them (three libraries, two code factories). If they differ, the build settings differ, or generated.ts is stale (pnpm sync-abis).

On this page