— Deployment · Base Sepolia · chain 84532

Eight contracts,
one address book

This is what the specification compiled to, and where it lives.

The deployment is the fourth on this testnet and the first under the Ztakora name. Its root is a contract with an epoch clock and a load line; seven more hold the parameters, the bonded stake, the evidence, the books, the reserve, the unpaid part of a loss and the gate that changes any of them. Nothing on this page is typed by hand: the tables are generated from state/base-sepolia-v4.json and from the chain.

An OP Stack testnet, a faucet-funded treasury, and keys that exist only in environment variables. This is a rehearsal of a protocol, not a mainnet service, and §12 of the specification is the honest statement of what has not been audited.

A stack of eight bars beside a load-line markrootseven more, each in the other's storage
The root is the only contract a caller touches directly. The other seven are reachable from it, and the deployment order is a dependency order: a component is created before anything that stores its address.

— Components

What is deployed, and what each one is for

Runtime code length is what the chain reports at eth_getCode for that address — not what a build log claims. Where the explorer reports a different creation transaction from the one the deployer recorded, the explorer is the one a third party can check, so that is the one linked here.

The eight components of the live deployment, in dependency order. Runtime code length is what the chain itself reports at eth_getCode.
ComponentAddressWhat it is responsible forCode, bytes
Ztakora0x95d4…cf15The root: the epoch clock, the load line, and the only place a mint is refused.20215
ParameterSet0xe65e…7868Epoch to parameter set, hashed, and changeable only through the controller.5953
BondRegistry0x8fd7…32c8Verifier stake, approvals and slashing — the bond a quorum is measured in.6139
AttestationRegistry0x8508…f037Blind commit, reveal, quorum, settlement: the evidence an epoch is built from.9109
LiabilityRegistry0x332c…0d87Books, series, issuer cover, and the mint and burn that stay inside the line.11552
Backstop0xc3f6…3b2dThe reserve: its cap, its fee, and the rules under which it releases.3119
ShortfallLedger0x1b4e…b225The part of a loss that could not be paid, named and remembered.3345
GovernanceGate0x9da5…79b9Endorsements, observation period, signal and band for every parameter change.6642

The parameter set that is live

Chain
Base Sepolia · 84532
Creation transaction
0xede5…f512
Deployed at block
50982076
Parameter hash
0x2159b9646ac5ec57e0fbd8d05ad25096e8c38988bdb77f7023d3daa0a0461b16
Epoch
720 blocks · commit 240 · reveal 240 · settle 240
Quorum of bonded stake
666667 ppm
Required verifier bond
37393598585152 wad
Book collateral
45000000000000 wad
Read RPC
https://sepolia.base.org
Address book in the repository
state/base-sepolia-v4.json
These figures read from the chain
2026-10-28, block 51121485

Reading the line from these addresses

The two numbers a participant cares about are per-issuer and both are plain views:

# The ceiling for one issuer — ceilingFor(address), selector 0xe71ff5e7.
# An address argument is one 32-byte word: 24 zero bytes, then the 20-byte address.
ZTAKORA=0x95d445fad4d54e8e5f0375a75779bf79cdf4cf15
ISSUER=000000000000000000000000e143eebb5e9a36a01c2f33da96a900ee326b6b10
curl -s https://sepolia.base.org -H 'content-type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_call\",
       \"params\":[{\"to\":\"$ZTAKORA\",\"data\":\"0xe71ff5e7${ISSUER}\"},\"latest\"]}"

# What that issuer has outstanding — LiabilityRegistry.outstandingOf(address), 0x77a1875a
curl -s https://sepolia.base.org -H 'content-type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_call\",
       \"params\":[{\"to\":\"0x332c63580e8daf039b7e01b5ff165ece71d80d87\",\"data\":\"0x77a1875a${ISSUER}\"},\"latest\"]}"

# The line and the number below it are the whole protocol. Minting above the line is
# refused before the transaction exists, and the revert names the ceiling it refused
# against: AboveLoadLine(...). A book with no attested collateral gives
# NoAttestedCollateral(...) — the same protection seen from the other side.

Both calls are read-only, cost nothing, and answer in one 32-byte hex word. Selectors are the first four bytes of the Keccak-256 hash of the signature, which is why ./data/abi/ is published: any tool can derive them instead of trusting the ones printed here.

— Roles

The addresses that sign, and the rule about their keys

Six roles move this deployment: one issuer, three verifiers, one aggregator and one watcher. Their public addresses are below; their private keys are nowhere on this site, in this repository, or in a command line.

The addresses the role daemons sign for. A public address is not a secret; the key that signs at it is, and it is read only from the environment variable named against it — never a flag, never a file in the tree.
VariableAddressWhat it does in an epoch
ZTAKORA_KEY_ISSUER0xe143…6b10Publishes the book for its series and mints against the line.
ZTAKORA_KEY_VERIFIER10x1300…5d2cCommits and reveals an attestation; one third of the bonded stake.
ZTAKORA_KEY_VERIFIER20x7ec3…c310Commits and reveals an attestation; one third of the bonded stake.
ZTAKORA_KEY_VERIFIER30xe640…dde6Commits and reveals an attestation; one third of the bonded stake.
ZTAKORA_KEY_WATCHER0xa42d…7681Reads the chain, keeps the journal, and reports a settlement that did not happen.
ZTAKORA_KEY_OPS0xe46b…ef82The aggregator: assembles the pack, settles the epoch, takes the fee.
ZTAKORA_KEY_BACKSTOP0x8f75…eefdHolds the reserve position this deployment funds.

The key rule, stated where an operator will read it

A daemon's key is read from the environment variable named in the table above and from nothing else. It is never a flag — a flag lands in a shell history, a process list and a supervisor log — and never a file inside the project tree, because a tree gets committed, archived and copied. A role started without its variable refuses to start rather than falling back to the published devnet fixture keys; the one opt-in to that fallback is --allow-fixture-keys, and it is only accepted against the in-process rehearsal chain.

Three equal verifier bonds mean two thirds of the stake is 66.67% and two of three keys is 66.67% — the quorum is 666 667 ppm, so two of three signers is one part per million short and all three must attend. That is arithmetic, not a configuration choice, and it is why the supervisor counts available attester keys before it starts anything.

What is bonded, and who can move it

  • Owner and deployer are one address — the table's last row of the parameter block. On a testnet that is deliberate; the governance section specifies the handover, and docs/entity.md records that it has not happened.
  • Issuer cover is 0.00005 ETH in LiabilityRegistry — the entire treasury of the run, and six times the sum of every role key balance.
  • It leaves through a two-step gate. requestCoverWithdraw(bytes32) opens an ask, claimCoverWithdraw() takes it after 100 blocks. Both must be signed by the issuer, which is why the money is locked rather than gone.

— Verification

Check the deployment without trusting this page

Five commands, no key, no login, no library. They answer the three questions that matter about any address: is there code, how did it get there, and is it the code this repository compiles.

# 1. Does a contract live at the root address? ("0x" would answer: nothing here)
curl -s https://sepolia.base.org -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_getCode","params":["0x95d445fad4d54e8e5f0375a75779bf79cdf4cf15","latest"]}'

# 2. Who created it, in which transaction, and is its source published?
curl -s https://base-sepolia.blockscout.com/api/v2/addresses/0x95d445fad4d54e8e5f0375a75779bf79cdf4cf15 \
  | jq '{is_contract, creation_status, creator_address_hash, creation_transaction_hash, is_verified}'

# 3. The calls it has actually received
curl -s https://base-sepolia.blockscout.com/api/v2/addresses/0x95d445fad4d54e8e5f0375a75779bf79cdf4cf15/transactions \
  | jq '.items[:5][] | {hash, block_number, timestamp, status, method}'

# 4. Every component in the book against the code this repository compiles
node state/check-code.mjs state/base-sepolia-v4.json https://sepolia.base.org

# 5. Protocol state, the same way the operator CLI reads it
node node/src/cli.ts status --rpc https://sepolia.base.org --book state/base-sepolia-v4.json --chain-id 84532

Why the explorer page looks empty

Every address on this page answers is_verified: false. On Blockscout that means the Read Contract tab has no method list and the page shows a bare hex address, which reads like "nothing was deployed here". It is a publishing state, not an absence: the code is in the chain — command 1 above measures it — and no source has been submitted to the explorer.

Submitting the source makes the explorer readable and searchable, and it publishes the Solidity of a BUSL-1.1 licensed implementation to a public, permanent, indexed page. That is a company decision rather than a technical one, so it has not been made here. The input that makes it a five-minute job exists:

node build/compile.mjs --standard-json
# writes build/standard-json.json — 13 sources, solc 0.8.26, evm paris,
# optimizer enabled at 200 runs. Exactly the input a verifier API expects.

Reproducing the bytes

One pinned compiler for every number on this site: solc 0.8.26, EVM paris, optimizer on at 200 runs. A second compiler version in the pipeline is how a protocol acquires a "works on my machine" bug.

node build/compile.mjs            # writes build/artifacts/*.json
node build/compile.mjs --check    # fails if the artifacts are stale against contracts/src
node state/check-code.mjs state/base-sepolia-v4.json https://sepolia.base.org

The third command compares the code on chain with the code in this tree. It reports the difference it finds: dependency addresses inlined at deploy time, and the 32-byte metadata trailer at the end of runtime code. Everything before that trailer is byte-identical, which is the claim worth making. A verifier that ignored the linked dependencies would report every one of the eight as a mismatch.

— Interfaces

The ABIs, as machine-readable files

Eight JSON files, written from the same compiler artifacts as the addresses above, so a script pointed at this site needs nothing else. They are the interface of the deployment: what can be called, what it returns, and what it emits.

The root, in the calls that matter

ViewAnswers
currentEpoch()Which epoch the clock is in, from block height
params()The thirteen parameter-set words this deployment runs on
paramsHash()Their hash, so a parameter change is a different protocol
ceilingFor(address)One issuer's load line, in wad
aggregateCeiling()The sum the reserve cap is measured against
aggregateLiability()What is actually outstanding across every book
settlementBlocked()Whether a shortfall is stopping settlement, and how big it is
feeFor(uint256)What a mint of that size pays

Write calls, and who may send them

CallWho
advance()Any address; it only moves the clock forward one phase
declare(bytes32)The aggregator, with a signed pack for the epoch
commit / revealA bonded verifier — blind first, then the values
mint / burnThe issuer of that book, and only inside its line
depositCoverThe issuer, against one series or unearmarked
requestCoverWithdrawThe issuer; opens an ask, does not move money
claimCoverWithdrawThe issuer, after the delay has passed
setWatcher(address,bool)The owner; grants a read-only reporting role

Every one of these reverts with a named error rather than a silent false, and the errors are part of the ABI: AboveLoadLine, NoAttestedCollateral, ManifestMismatch, NotAuthorised, StaleEpoch. A refusal that costs no gas is also the cheapest fee probe available on a chain — the runbook uses it that way.

— Deployment history

A rename moves the addresses, and the old ones stay

A reader who looks up an address from before the rename finds code sitting at it, and a node built from this tree refusing to talk to it. Nothing is wrong with those deployments — they belong to a protocol that no longer exists in this repository. The table below is not this page's memory: it is written by build/deployment-data.mjs out of the address books in state/ and an eth_getCode call on each root, so every address, byte count and block height in it is the chain's answer.

Every root this protocol has had on Base Sepolia, oldest first. The address, the runtime code length and the creation block come from the chain and from the books in state/; the generation numbers are the order those books were written in.
GenerationRoot addressDomain strings it signedCreated at blockOn chain now
v1state/base-sepolia.json0x3687bdcbe46f7d387f22bc980b93140862ca0f60plimsoll/cycle/v1 · plimsoll/reveal/v150 932 746orphanedcode still at this address · 20 216 bytes
v2state/base-sepolia-v2.json0xde00f75545f9f26ad06fc4379fc5efec1f7dcc5aplimsoll/cycle/v1 · plimsoll/reveal/v150 954 832orphanedcode still at this address · 20 216 bytes
v3state/base-sepolia-v3.json0x8e8825389ab3e5d7a3e151efd2e915fe87d3f84eplimsoll/cycle/v1 · plimsoll/reveal/v150 958 156orphanedcode still at this address · 20 216 bytes
v4state/base-sepolia-v4.json0x95d445fad4d54e8e5f0375a75779bf79cdf4cf15ztakora/cycle/v1 · ztakora/reveal/v1 · ztakora/manifest/v150 982 076livecode, 20 215 bytes · epochs advance

The hash domains are not cosmetic. A commit is a hash over a domain string, the manifest and the values, so a node that says ztakora/reveal/v1 and a contract that expects plimsoll/reveal/v1 will never agree on a commitment — every reveal would fail the check. That is why a rename is a redeployment, and why the testnet has earlier addresses to explain. The parity test in test/parity.test.ts is what keeps the Solidity, the node and this page quoting the same domain strings.