# zero-amount-complementary-send-review

> Review exact same-color complementary sends with two zero-inclusive amount envelopes.

Canonical: https://nightshade.dicksonwu.xyz/rules/zero-amount-complementary-send-review.html
Release: Nightshade 0.1.1 (v0.1.1)

| Field | Value |
| --- | --- |
| Rule ID | `zero-amount-complementary-send-review` |
| Severity | info |
| Confidence | varies |
| Maturity | experimental |
| Selection | Opt-in |
| Policy intent | not required |
| Default enabled | no |
| Category | Other active opt-ins / Token, coin and value transfers |
| Engine facts used | canonical-send-operands, complete-original-successful-histories, immutable-unsigned-subtraction |
| Release | v0.1.1 |

## Selection and scope

Not selected by default. Select it with `--detectors` or the `detectors` list in nightshade.json. Either one replaces profile selection, so list every rule you want.

```sh
./.nightshade/node_modules/.bin/nightshade ./contracts --detectors zero-amount-complementary-send-review
./.nightshade/node_modules/.bin/nightshade detector show zero-amount-complementary-send-review
```

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 |
| ---: | ---: | ---: | ---: | ---: |
| 4/4 | 2/2 | 3/4 | 7/8 | 1 |

Deviations recorded for this rule:

| Case | Kind | Expected to observed lines | Issue |
| --- | --- | --- | --- |
| manifest.json / complementarySendReview47/drafts/complementary47/boundaries/intentional-same-executable-as-positive.compact | lookalike | [9] to [9] | control hit |
| manifest.json / complementarySendReview47/drafts/complementary47/boundaries/persistent-map-lost-lineage-refusal.compact | negative | [] to [] | incomplete or unvalidated |

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/zero-amount-complementary-send-review.md at v0.1.1.

Availability: **opt-in**; severity **info**. Select it with
`--detectors zero-amount-complementary-send-review`.

The rule reports one complementary pair of canonical
`CompactStandardLibrary.sendUnshielded` calls on a complete original successful
invocation history. The calls use the same exact immutable token-color operand
and send unsigned scalar snapshots `P` and `T-P`. Aliases and value-preserving
casts retain the relationship. The exact total `T` must have a proven positive
modeled lower bound, and **both actual sent amount envelopes must have lower
bound zero** after all modeled mandatory checks, including late checks.

```compact
assert(disclose(total) > 0 as Uint<128>, "positive total");
const remainder = total - part;
sendUnshielded(disclose(color), disclose(part), disclose(recipient));
sendUnshielded(disclose(color), disclose(remainder), disclose(recipient));
```

Review whether the application's allocation policy should conditionally skip
exact zero endpoint sends. Intentional zero/full endpoint allocations may match.
A guard that makes either sent amount positive quiets this rule. A literal-zero
part with a positive total is quiet because its remainder is strictly positive.
Independent fee amounts, different color snapshots, mutually exclusive calls,
and Field subtraction do not establish the selected relationship.

Supported profiles are Compact **0.31.1/ZKIR2** and **0.34.0/ZKIR2 or ZKIR3**.
Admission counts possible canonical calls through helpers and callbacks, including
zero-iteration callbacks. Closures without an unsigned subtraction or two
possible canonical sends can establish structural absence
without requesting a numeric profile. Original histories remain separate; cached
and uncached transfers preserve the same operands and evaluation order. Exact
read/storage summaries remain available; fresh computed scalar occurrences are
interpreted rather than reused from cached results.

Preparation, execution, immutable-key traversal, numeric bounds, pair matching,
and emission share the existing **40,000 steps per entry, 256 paths per entry,
and 50,000 cumulative values per rule**. Unsupported applicable profiles,
checkpoints, lost arithmetic lineage, inconsistent or missing history carriers,
unfinished baseline analysis, and exhausted allowances produce rule-scoped
incomplete diagnostics. Experimental Counter-query histories do not supply this
rule's exact observation evidence.

## 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 zero-amount-complementary-send-review -- 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/zero-amount-complementary-send-review.md)
- [Catalog entry in rules.json](https://nightshade.dicksonwu.xyz/rules.json)
- [All rules](https://nightshade.dicksonwu.xyz/rules.md#token-coin-and-value-transfers)
- [Limitations](https://nightshade.dicksonwu.xyz/limitations.md)
