# unsupported-contract-owner

> A declared callable pinned Ownable instance finishes with a contract-address owner rejected by its guard.

Canonical: https://nightshade.dicksonwu.xyz/rules/unsupported-contract-owner.html
Release: Nightshade 0.1.1 (v0.1.1)

| Field | Value |
| --- | --- |
| Rule ID | `unsupported-contract-owner` |
| Severity | medium |
| Confidence | high |
| Maturity | experimental |
| Selection | Opt-in + policy |
| Policy intent | required |
| Default enabled | no |
| Category | Policy-dependent rules |
| Engine facts used | module-identities, state-writes, all-predicates, constants, completed-entries, callable-ownable-policy |
| Release | v0.1.1 |

## Selection and scope

Not selected by default. Select it with `--detectors` or the `detectors` list in nightshade.json, and declare the matching application intent in `policies`. Selecting it alone does not supply that intent.

```sh
./.nightshade/node_modules/.bin/nightshade ./contracts --detectors unsupported-contract-owner
./.nightshade/node_modules/.bin/nightshade detector show unsupported-contract-owner
```

The first command runs only this rule; `--detectors` takes a comma-separated list. The second prints the rule's metadata from your installed version.

Severity is review priority. It does not express exploitability or impact. Confidence is detector metadata, not a probability. All built-in rules are experimental.

Compiler scope: the engine supports the pinned profiles 0.28.0, 0.29.0, 0.30.0, 0.31.1, 0.33.0-rc.2, 0.34.0, 0.35.0-rc.1 and 0.35.0, with ZKIR2 by default. Support for this rule can be narrower; the rule documentation below states any narrower scope.

## Corpus checks

Synthetic corpus checks for this rule in the 0.1.1 proof run. A check counts only with compiler acceptance and complete analysis.

| Positive detected | Corrected quiet | Lookalike quiet | Other negative quiet | Incomplete |
| ---: | ---: | ---: | ---: | ---: |
| 1/1 | 1/1 | 1/1 | 0/0 | 0 |

No deviations were recorded for this rule.

These are behavior checks on synthetic fixtures, not a precision or recall estimate. See [evaluation](https://nightshade.dicksonwu.xyz/evaluation.md#synthetic-corpus).

## Rule documentation

From https://github.com/DicksonWu654/nightshade/blob/v0.1.1/docs/detectors/unsupported-contract-owner.md at v0.1.1.

Availability: **opt-in policy**; severity **medium**, confidence **high** for the
final selected tag and authenticated guard behavior. Concrete feasibility remains
unproved.

### Description, example and scenario

```compact
Ownable__unsafeTransferOwnership(right<Bytes<32>, ContractAddress>(next));
```

For an owner selected by `callableOwnable`, a complete modeled successful history
leaves the pinned Ownable owner's active arm as `ContractAddress`. Its
`assertOnlyOwner` implementation explicitly rejects that arm, including nonzero
contract addresses, while this owner value remains stored. The library's unsafe
API is intentional; the policy declares that this particular owner guard must
remain usable with the current implementation.

Evidence uses OpenZeppelin Compact 0.4.0-alpha.3 revision
`ec1331cd8195694c747d291e8fc8ab6d2914a976`, exact Ownable and Utils bytes, and the
qualified Compact 0.34.0/ZKIR2 profile. The rule reviews configured application
invariants; it does not claim an upstream defect or a newly confirmed
vulnerability.

### Configuration and recommendation

Select `unsupported-contract-owner` explicitly and declare:

```json
{ "callableOwnable": [{ "owner": "_owner" }] }
```

The selector must resolve to a root native
`Either<Bytes<32>, ContractAddress>` ledger. Use its exact symbol ID when multiple
instances make `_owner` ambiguous. Arrays must be dense and contain at most 64
owners; duplicate selectors for the same resolved owner are deduplicated.
Authentication failures remain rule-scoped incomplete rather than quietly
passing the declared obligation.

Keep the selected owner in the account-identifier arm and use the safe
ownership-transfer circuit. Intentional authority suspension, migration staging
for future C2C support and test exposures should remain outside this policy.
Declaring a policy without selecting this opt-in rule does not run the rule.

### Evidence and limitations

Ordered state writes establish the final surviving discriminator for each
selected instance and successful history. Whole-owner writes and aggregate
reconstructions are compiler-qualified, including constructor and direct
authenticated ledger assignments. Exact regional discriminator/payload facts
are handled separately; their controls are synthetic because the pinned
compiler rejects direct native Either field assignment. Payload-only mutations
preserve the discriminator. A later
left discriminator, safe replacement or canonical left/zero renunciation stays
quiet. Rejected histories cannot supply a finding.

Bounded successful-constant projection uses the same immutable snapshot and
history, including later atomic assertions. It cannot borrow constraints from a
different ledger revision, branch, wildcard region or module instance. Unknown
final tags, unknown overlapping regions, absent invocation locations,
incomplete entries, unsupported profiles and exhausted observations produce
rule-scoped incomplete diagnostics. Supported findings for independent
relations and histories remain available.

The real-source seed triple is an owned focused mutation of the pinned OZ
MockOwnable test wrapper. Its nonzero right owner is independent of the existing
default-address rule; corrected and unrelated-ledger controls remain quiet.

## Suppress a match

If a match is intentional, suppress it on the line before with the exact rule ID and a reason of at least eight characters:

```compact
// nightshade-disable-next-line unsupported-contract-owner -- Reason this match is intentional
```

Diagnostics cannot be suppressed, and an unmatched directive for a selected rule makes analysis incomplete. See [configuration](https://nightshade.dicksonwu.xyz/configuration.md#suppress-an-intentional-match) for fingerprint suppressions and baselines.

## References

- [Rule source document at v0.1.1](https://github.com/DicksonWu654/nightshade/blob/v0.1.1/docs/detectors/unsupported-contract-owner.md)
- [Catalog entry in rules.json](https://nightshade.dicksonwu.xyz/rules.json)
- [All rules](https://nightshade.dicksonwu.xyz/rules.md#policy-dependent-rules)
- [Limitations](https://nightshade.dicksonwu.xyz/limitations.md)
