The attester set is immutable per deployment and the threshold gate is enforced entirely on-chain. Who operates the keys in that set is a separate question from what the contract enforces: on the current testnet deployments KeyStone operates all of them. See attester operation below.
How it works
- Off-chain compliance screening runs per party via LSEG World-Check (entity) and CipherOwl (wallet)
- On a passing result, an EIP-712
Attestationmessage is signed by M of the N configured attester keys - The signed bundle is submitted on-chain:
attest(attestation, signatures). The submitter is not trusted - the signatures authorize, so no single key (and no submitter) can forge a Pass - At the last deposit (or a later
execute()call), the KeystoneSettlement contract callsareAllPartiesCleared(settlementId, partyHashes)with the hashes bound at registration - If every bound hash has a passing attestation, the settlement executes; otherwise it stays registered until attestation lands
Functions
attest()
Submit an M-of-N signed compliance attestation for a party in a settlement.- Pass only. Only
Passattestations exist on-chain - a failed or flagged screening is never written to the registry; the gate simply never clears for that party. Any other status revertsInvalidComplianceStatus. - Deadline. A bundle submitted after
deadlinerevertsAttestationExpired, so a leaked old signature cannot be replayed indefinitely. - M-of-N signatures. Each signature must recover to a configured attester, signers must be in strictly ascending address order (rejects duplicates), and at least the threshold M must be present - otherwise
SignersNotSortedOrDuplicate,UnknownAttester, orThresholdNotMet. - Sequence. Re-attesting the same party increments a per-record
sequencecounter, so downstream systems can distinguish the first attestation from a re-screen.
isCleared()
Check if a specific party has a passing attestation.areAllPartiesCleared()
Check if every supplied party hash has a passing attestation for the settlement. This is the function the KeystoneSettlement contract calls as its execution gate, passing the party hashes bound at registration (the gate can never pass vacuously - registration rejects empty hash lists).Party hash computation
Party hashes are computed askeccak256(abi.encode(partyId_bytes32, walletAddress)). The same inputs MUST be used at registration (KeystoneSettlement partyHashes) and at attestation, or the gate never clears:
This allows separate attestations for entity-level and wallet-level screening while maintaining a consistent hashing scheme.
Status mapping
Off-chain, KeyStone tracks three screening outcomes per party:PASS, FLAGGED, and FAIL. On-chain, only one of them ever becomes a record:
Deposits are still accepted while the gate is closed - only execution is blocked. The
ComplianceStatus enum retains Flagged (2) and Fail (3) values for ABI compatibility, but attest rejects them.
Immutable M-of-N threshold
The attester set and the threshold are fixed at deployment and immutable: the contract has no function to add or remove an attester or to change the threshold. Changing the set means deploying a fresh registry, deploying KeystoneSettlement against it, and repointing the backend - a visible, coordinated, multi-step operation that cannot happen in a single transaction. There is no on-chain path to forge a Pass. The pause authority (PAUSER_ROLE, with DEFAULT_ADMIN_ROLE existing only to rotate it) is halt-only: it can freeze new attestations in an emergency but cannot forge, alter, or delete one.
Attester operation
The current testnet deployments run a 2-of-3 attester set, and KeyStone operates every key in it as an interim arrangement. What the contract guarantees and what the deployment currently delivers are therefore different things, and it is worth being precise about which is which:
The design goal is independent attester operators, at which point no single organization can clear the gate alone. Until then, the honest description of the gate is that it prevents any other party from clearing a settlement, and that KeyStone can decline to clear one. Neither the contract nor any key in the set can redirect a payout: an attestation permits a settlement to execute along the path fixed at registration and carries no recipient or amount.
Events
What KeyStone stores
KeyStone never stores raw KYC/AML data. The compliance flow stores:
The compliance provider (LSEG, CipherOwl) remains the source of truth for the actual screening data. KeyStone only records the outcome.