Security

Known limits

Every known limit of Tally, stated plainly: testnet only, unaudited, built on an untagged preview branch, a seven-day verification window, no users, and what the planned operator design cannot avoid.

This page lists what Tally does not do, does not have, or cannot yet guarantee. Each item links to the file it comes from.

Testnet only. No users, no integrations. Nothing has been audited. Do not use with real value.

Status

LimitWhat it meansSource
Testnet onlyEverything runs on Stellar testnet. Nothing is deployed on mainnet. Testnet XLM has no valueREADME; evidence README
UnauditedNothing in Tally has been audited. The OpenZeppelin confidential-token suite it builds on is an unaudited developer previewREADME
Built on a preview branchTally pins OpenZeppelin stellar-contracts v0.9.0 (df602b6). v0.9.0 is a branch, not a tagged release. OpenZeppelin's main and v0.9.0 have diverged, and which one mainnet will use is an open questionREADME; OPERATOR-DESIGN §9
No users or integrationsTally has no users, no integrations and no partner agreements. Nothing in the repository is used by anyone elseDEMONSTRATION-STATUS
No independent verification yetNobody outside the project has run the verifier on a published round and reported the outputDEMONSTRATION-STATUS, row 8
Demo recipients are not peopleThe published round was generated by a test harness. Its recipients are freshly created testnet accounts. A round with real, independent contributors holding their own keys has not been builtevidence README; DEMONSTRATION-STATUS, row 9
SDK is internal and unauditedThe client SDK under ct/sdk is Tally's own port of the reference demo's SDK to v0.9.0. It passes the 19 OpenZeppelin v0.9.0 primitive vectors it implements. It is not published as a package and not auditedDEMONSTRATION-STATUS, notes

What the guarantee does not cover

The trust statement is scoped on purpose. Two limits follow directly from its second sentence.

LimitWhat it meansSource
Only the declared lanesThe proof covers transfers from the lane accounts declared before the round, within its ledger window. It says nothing about the funder's other accounts or total spendTRUST-STATEMENT
Recipient independence is not verifiedA funder can pay accounts it controls and prove a valid total. The proof shows what amounts moved, not who controls the receiving accounts. A recipient-identity layer is future work and outside the current scopeTRUST-STATEMENT; README roadmap
Repeated aggregatesAggregates over overlapping sets of transfers could be subtracted from each other to narrow down amounts. Checks against this are not designed yetOPERATOR-DESIGN §7, T13

Verification window

LimitWhat it meansSource
About 7 days of eventsSoroban RPC keeps a rolling window of events, about 120,960 ledgers or roughly 7 days on testnet. The verifier lists a round's transfers from chain events on purpose, so after the window it has nothing to listSDK-SAFETY-INVARIANTS §I4
No durable archiveEvery published round stops being verifiable when its ledgers leave the window. tally verify detects this and exits with code 3. pnpm evidence:refresh publishes a fresh round, which keeps current evidence checkable but does not make an old round checkable. A durable path (event archive or ledger replay) is designed and not builtevidence README; DEMONSTRATION-STATUS, row 11
Earlier rounds cannot be reproducedround-001 and round-002 (August 2026) came from the retired deployment. Their ledgers have left the window and their pinned verification keys no longer match the current circuitsevidence README
Explorer view is from the retired deploymentThe decoded explorer view of a transfer was made against the August deployment and has not been regenerated against v0.9.0DEMONSTRATION-STATUS, row 2

The payout flow

LimitWhat it meansSource
One transfer per transaction in the demoFour confidential transfers from one sender fit in one transaction, and this was demonstrated on testnet through a measurement-only wrapper. The demo still sends one transfer per transaction. Moving the payout flow to batching is unscheduledMEASUREMENTS; DEMONSTRATION-STATUS, notes
No browser registration pageNon-custodial registration works headless and is tested against live testnet. There is no wallet connect pageDEMONSTRATION-STATUS, row 5; registration README
Demo lane keys in plaintextThe demo writes the funder's lane spending keys in plaintext to demo/last-round.json. The file is gitignored and holds testnet keys only. A real funder would hold them in a signer servicecli README
Override still present in the SDKSafety invariant I1 says the transfer path must not expose an override for the ephemeral scalar. The ported SDK's transfer witness builder still accepts an optional rE. It defaults to the derived valueSDK-SAFETY-INVARIANTS §I1; ct/sdk/src/witness/transfer.ts
Measured on one machineProof generation times were measured on an Apple M4 Pro. Other hardware will differMEASUREMENTS

The planned operator service

The operator service (split auditor-key custody, scoped audit requests, disclosure outputs, list management, tax export) is designed, not built.

LimitWhat it meansSource
None of it existsAuditor-key custody, scoped audits and list management are a design onlyDEMONSTRATION-STATUS, row 12; OPERATOR-DESIGN §6
The design's weakest pointOpenZeppelin's clawback proof and auditor-side disclosure proofs need the whole auditor key as a private witness. The design reassembles the key briefly inside an attested enclave (TEE) to produce those proofs, so for the duration of one proof the key exists in one place. A hardware-level attack on the enclave would expose itOPERATOR-DESIGN §2.3, T5
Colluding custodiansIf t custodians collude, they can decrypt every account bound to that auditor. Cryptography cannot detect this; deterrence is contractualOPERATOR-DESIGN §7, T1
Commercial custody is unverifiedWhether commercial MPC custody products support the curves these systems use is unverified and thought unlikelyOPERATOR-DESIGN §2.2
Mainnet depends on othersMainnet work follows SDF's approval of Confidential Tokens for mainnet. Its timing is outside the project's controlSCOPE-LEDGER
SPP lists cannot remove membersIn Nethermind's Stellar Private Payments the allowlist has no delete. A blocked subject who makes fresh note keys outside the admission flow is not caught by a blocklist-only poolOPERATOR-DESIGN §5

Demand evidence

The written evidence that anyone wants this operator is one explicit ask, at one SDF meeting. On 2026-08-06 the official meeting notes, written by SDF DevRel, say "Nobody is building that platform for you. Hint." and record SDF's privacy product manager's ask, in paraphrase, to "go be the operator". Other claimed asks on video could not be confirmed from captions. No statement by SDF, OpenZeppelin or Nethermind says they will not build this themselves (OPERATOR-DESIGN §0; DEMAND-QUOTES).