# Contracts
URL: https://docs.arcns.io/contracts/

> The ArcNS contract set on Arc testnet, where the deployed addresses will be published, and the pinned peer registry that .arc and .circle lookups also consult.

<LlmActions />

## Addresses: testnet deployment pending

The Arc testnet (chain id `5042002`) deployment of the ArcNS contracts has not happened yet. When it does, this page is generated from `contracts/deployments/5042002.json` in the repository and CI compares the hash of the published table against that file on every build, so an address on this page is never typed by hand.

<Callout title="Warning" type="warn">
  Until then, do not trust any address claiming to be an ArcNS contract. The only source of truth will be that file on the `main` branch of [fortiblox/fortiblox-arcns](https://forgejo.selfhsted.com/fortiblox/fortiblox-arcns). The SDK ships no default addresses either: without a deployment it throws `not-configured` rather than guess.
</Callout>

## The contract set

All contracts are immutable (no proxies). Upgrades happen by deploying a replacement and re-pointing through the timelock. TLDs are data: adding one is a script run, not a redeploy.

| Contract                      | Instances | Origin                                | Role                                                                                                                                                                   |
| ----------------------------- | --------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HandleRegistry`              | 1         | new (ERC-721)                         | Source of truth for `@handle` ownership, recovery, lock and sub-handles. `tokenId = keccak256(name)`.                                                                  |
| `HandleController`            | 1         | new                                   | Commit-reveal registration for `@handle`, fee split, reserved genesis, vouchers. Swappable.                                                                            |
| `ENSRegistry` + `Root`        | 1         | verbatim ENS                          | node to (owner, resolver, ttl) for `.arc` / `.circle`; root owned by governance.                                                                                       |
| `TldDirectory`                | 1         | new                                   | The on-chain TLD table: registrar, controller, status (`Active`, `RegistrationsPaused`, `Sunset`, `Retired`), sunset and migration data. Written only by the timelock. |
| `BaseRegistrarImplementation` | 1 per TLD | verbatim ENS                          | ERC-721 per TLD, `tokenId = labelhash`; permanence expressed as a maximal duration.                                                                                    |
| `TldRegistrarController`      | 1 per TLD | fork of ENS `ETHRegistrarController`  | Registration path per TLD: commit-reveal, price oracle, reserved genesis, integrator hooks; renewals removed.                                                          |
| `ArcNSPriceOracle`            | 1         | new                                   | Per-namespace stacked price curve (ENS `IPriceOracle`).                                                                                                                |
| `ArcNSResolver`               | 1         | ENS profile mixins + verified records | One record store for every namespace: `addr(node, coinType)`, text, contenthash, name, plus `verified(node, coinType)`.                                                |
| `ReverseRegistrar`            | 1         | verbatim ENS                          | The single primary-name store: one primary per address across all namespaces.                                                                                          |
| `UniversalResolver`           | 1         | verbatim ENS                          | One-call ENSIP-10 resolution and reverse for SDK and wallets.                                                                                                          |
| `ArcNSMarket`                 | 1         | new                                   | Listings, escrowed offers, English auctions with anti-snipe, for any allow-listed collection. Pull-payment escrow.                                                     |
| `AttestationRegistry`         | 1         | new                                   | DNS / social attestations, EIP-712 signed by an attestor, submitted by anyone.                                                                                         |
| `TimelockController`          | 1         | verbatim OpenZeppelin                 | Owner of every contract; proposer / executor is the admin Safe.                                                                                                        |

Registry cores are never pausable: resolution, record writes and transfers always work. Only new registrations and new market actions can be paused, and only the timelocked admin can unpause.

Checked-in ABIs for the new contracts (`HandleRegistry`, `HandleController`, `ArcNSResolver`) live in `contracts/abi/` in the repository; they are provisional until the first tagged release and the SDK guards against drift in its test suite. The verbatim ENS contracts use the published ENS ABIs unchanged.

## The pinned peer registry

`.arc` and `.circle` names exist in more than one registry on Arc testnet. Another project sells them from its own ENS-shaped contracts, and every ArcNS `.arc` / `.circle` lookup, in the SDK and in the API, **consults every pinned registry for that TLD** and labels each answer with the registry it came from. Two registries that disagree are a `conflict` (HTTP `409`), never a silent pick.

| Product label                                                     | Contract            | Address (Arc testnet)                        |
| ----------------------------------------------------------------- | ------------------- | -------------------------------------------- |
| `khenzarr-arcns` (SDK `product`), `khenzarr/arcns` (API `source`) | registry            | `0xc20B3F8C7A7B4FcbFfe35c6C63331a1D9D12fD1A` |
|                                                                   | resolver            | `0x4c3a2D4245346732CE498937fEAD6343e77Eb097` |
|                                                                   | `.arc` registrar    | `0xD600B8D80e921ec48845fC1769c292601e5e90C4` |
|                                                                   | `.circle` registrar | `0xE1fdE46df4bAC6F433C52a337F4818822735Bf8a` |

These addresses are pinned in the SDK (`KHENZARR_ARCNS_TESTNET`) and in the API (`PINNED_COMPETITOR_REGISTRIES`, overridable with `COMPETITOR_REGISTRIES`). They are the peer project's contracts, not ArcNS contracts: records read from them are always `unverified`, carry only the coin-type-60 record, and have no `epoch`. A registry address that is not pinned is refused by the SDK unless the integrator opts in with `allowUnpinnedRegistries: true`.

## Verification

Every deployed contract will be source-verified on the Arc block explorer ([testnet.arcscan.app](https://testnet.arcscan.app)); the deployment file records the verification URL next to each address.

## Questions

Questions: [support@arcns.io](mailto:support@arcns.io).
