— 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.
— 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.
| Component | Address | What it is responsible for | Code, bytes |
|---|---|---|---|
Ztakora | 0x95d4…cf15 | The root: the epoch clock, the load line, and the only place a mint is refused. | 20215 |
ParameterSet | 0xe65e…7868 | Epoch to parameter set, hashed, and changeable only through the controller. | 5953 |
BondRegistry | 0x8fd7…32c8 | Verifier stake, approvals and slashing — the bond a quorum is measured in. | 6139 |
AttestationRegistry | 0x8508…f037 | Blind commit, reveal, quorum, settlement: the evidence an epoch is built from. | 9109 |
LiabilityRegistry | 0x332c…0d87 | Books, series, issuer cover, and the mint and burn that stay inside the line. | 11552 |
Backstop | 0xc3f6…3b2d | The reserve: its cap, its fee, and the rules under which it releases. | 3119 |
ShortfallLedger | 0x1b4e…b225 | The part of a loss that could not be paid, named and remembered. | 3345 |
GovernanceGate | 0x9da5…79b9 | Endorsements, observation period, signal and band for every parameter change. | 6642 |
The parameter set that is live
- Chain
- Base Sepolia · 84532
- Root contract
- 0x95d445fad4d54e8e5f0375a75779bf79cdf4cf15
- 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
- Deployer, also owner
- 0x27a2517176d611f1851c53757afd5ed3a1900db5
- 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.
| Variable | Address | What it does in an epoch |
|---|---|---|
ZTAKORA_KEY_ISSUER | 0xe143…6b10 | Publishes the book for its series and mints against the line. |
ZTAKORA_KEY_VERIFIER1 | 0x1300…5d2c | Commits and reveals an attestation; one third of the bonded stake. |
ZTAKORA_KEY_VERIFIER2 | 0x7ec3…c310 | Commits and reveals an attestation; one third of the bonded stake. |
ZTAKORA_KEY_VERIFIER3 | 0xe640…dde6 | Commits and reveals an attestation; one third of the bonded stake. |
ZTAKORA_KEY_WATCHER | 0xa42d…7681 | Reads the chain, keeps the journal, and reports a settlement that did not happen. |
ZTAKORA_KEY_OPS | 0xe46b…ef82 | The aggregator: assembles the pack, settles the epoch, takes the fee. |
ZTAKORA_KEY_BACKSTOP | 0x8f75…eefd | Holds 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.mdrecords 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 84532Why 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.orgThe 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.
- Ztakora
- ParameterSet
- BondRegistry
- AttestationRegistry
- LiabilityRegistry
- Backstop
- ShortfallLedger
- GovernanceGate
- deployment.json — every fact on this page
The root, in the calls that matter
| View | Answers |
|---|---|
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
| Call | Who |
|---|---|
advance() | Any address; it only moves the clock forward one phase |
declare(bytes32) | The aggregator, with a signed pack for the epoch |
commit / reveal | A bonded verifier — blind first, then the values |
mint / burn | The issuer of that book, and only inside its line |
depositCover | The issuer, against one series or unearmarked |
requestCoverWithdraw | The issuer; opens an ask, does not move money |
claimCoverWithdraw | The 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.
| Generation | Root address | Domain strings it signed | Created at block | On chain now |
|---|---|---|---|---|
| v1state/base-sepolia.json | 0x3687bdcbe46f7d387f22bc980b93140862ca0f60 | plimsoll/cycle/v1 · plimsoll/reveal/v1 | 50 932 746 | orphanedcode still at this address · 20 216 bytes |
| v2state/base-sepolia-v2.json | 0xde00f75545f9f26ad06fc4379fc5efec1f7dcc5a | plimsoll/cycle/v1 · plimsoll/reveal/v1 | 50 954 832 | orphanedcode still at this address · 20 216 bytes |
| v3state/base-sepolia-v3.json | 0x8e8825389ab3e5d7a3e151efd2e915fe87d3f84e | plimsoll/cycle/v1 · plimsoll/reveal/v1 | 50 958 156 | orphanedcode still at this address · 20 216 bytes |
| v4state/base-sepolia-v4.json | 0x95d445fad4d54e8e5f0375a75779bf79cdf4cf15 | ztakora/cycle/v1 · ztakora/reveal/v1 · ztakora/manifest/v1 | 50 982 076 | livecode, 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.