OpenZeppelin / OpenZeppelin/compact-contracts
N-07: Owner Commitments Are Not Truly Distinct Over Multiple Contracts
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 55
- Forks
- 29
- Avg merge
- 5d 7h
- Merged PRs (30d)
- 25
Description
N-08 Owner Commitments Are Not Truly Distinct Over Multiple Contracts
Severity: Note
Source: Midnight Foundation #02 — OpenZeppelin Compact Contracts Audit, Release 0.3.0-alpha.1 (2026-08-18)
Ownership in ZOwnablePK is represented by a public commitment, returned by owner() and derived by _computeOwnerCommitment as a persistentHash over the owner identifier, the _instanceSalt, a counter and a fixed domain tag. Of those four inputs only the salt varies between deployments, the tag being a constant, so the salt alone provides the per-instance namespace the module documents it as providing.
initialize rejects a zero owner identifier but persists the salt without validating it. Two deployments that share an owner identifier and are both initialized with the type default therefore publish identical commitments at the same counter value, and an observer can correlate administrative identity across those contracts by comparing a public getter. Authorization behavior is unchanged, since the commitment still requires a preimage to satisfy the owner check, so the consequence is the loss of the unlinkability the salt exists to provide.
Consider rejecting a salt equal to the type default in initialize, matching the check already applied to the owner identifier on the line above. Consider also folding a contract-unique value such as kernel.self() into the commitment, so that deployments remain namespaced even where a consumer supplies a poor salt.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in contracts/src/access/ZOwnablePK.compact, reading initialize, _computeOwnerCommitment, and owner() at the referenced lines. Verify how the default salt produces equal commitments across deployments, then inspect existing tests for initialization and ownership behavior. Done means deployments with inadequate or default salts cannot expose identical owner commitments without breaking authorization behavior.
Written by the indexing model from the issue text.
Assessment
- Domain
- blockchain, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100