ASPRegistry contract
The ASPRegistry stores the append-only history of ASP-attested roots. Spending circuits prove their note's label is in an ASP root, and PoolVault.transact requires that root to equal the current latestASPRoot(). The history is kept for auditing, but only the latest root is accepted for spends.
State
associationSets(uint256 _index) → AssociationSetData Indexed accessor over the append-only history. Each entry is { uint256 root; bytes ipfsCID }.latestASPRoot() → uint256 The most-recent root in the history. Reverts with ASPRegistry_EmptyAssociationSet if no root has been published yet.latestIPFSCID() → bytes IPFS CID published alongside the latest root.Note: there is no isRootKnown or currentRoot view on this contract. To check a specific root, compare against latestASPRoot() or walk associationSets(i) backwards.
Only the latest root spends
Unlike the PoolVault's sixteen-root buffer and the Keystore's twenty-minute liveness window, the ASP root is checked by strict equality with latestASPRoot(). Publishing a new root immediately invalidates every transact proof built against the previous one (PoolVault_InvalidASPRoot), so clients should fetch the root as late as possible before proving and be ready to rebuild. A frequently posting or adversarially timed postman can delay withdrawals; it cannot freeze funds, because ragequit does not check this root at all.
Main functions
updateASPRoot(uint256 _aspRoot, bytes _ipfsCID) Append a new ASP root and the IPFS CID of the snapshot it was derived from. POSTMAN_ROLE-gated.registerLabel(bytes _ciphertext) Permissionless. Emits a LabelRegistered event with the encrypted label, for ASP indexers to pick up. The Entrypoint calls it at deposit time only when the caller supplies a non-empty aspCiphertext. Callers may also invoke it directly.Roles
POSTMAN_ROLE Allowed to call updateASPRoot. Typically granted to the ASP service's signing accounts.Trust model
The contract trusts holders of POSTMAN_ROLE to only publish roots derived from legitimate ASP attestation. A malicious postman could approve labels that shouldn't be approved, because the contract has no way to verify policy.
The mitigation is operational: POSTMAN_ROLE is granted carefully. Recovery from a bad update isn't automatic and would require either tolerating the bad approvals or a coordinated upgrade.
Source: v2-monorepo/packages/contracts/src/contracts/ASPRegistry.sol