# Contract test coverage - 2026-09-11 `npx hardhat coverage` (solidity-coverage via the Hardhat toolbox) over the 259-test suite, contracts at the supplement tag's bytes plus the 2026-09-11 comment change in `Disorderly721.setStartingIndex`. The run needs `NODE_OPTIONS=--max-old-space-size=8192` on this machine (instrumented compilation exhausts the default heap); CI runs it with 6 GB and keeps the HTML report as a build artifact for 30 days (`.github/workflows/test.yml`). ## Production contracts | file | statements | branches | functions | lines | uncovered lines | |---|---|---|---|---|---| | Disorderly721.sol | 97.87% | 90.44% | 95.83% | 99.14% | 264 | | DisorderlyAgentCollection.sol | 100% | 86.67% | 91.67% | 96.77% | 187 | | PayoutDistributor.sol | 100% | 87.50% | 100% | 100% | none | | ProposalRegistry.sol | 100% | 97.92% | 100% | 100% | none | | RoyaltyRouter.sol | 98.65% | 77.03% | 100% | 100% | none | | all five | 98.89% | 87.79% | 97.30% | 99.39% | | The test mocks under `contracts/test/` are instrumented too and pull the whole-repository figure down to 93.69% statements; they are fixtures, not deliverables, and are excluded from Slither for the same reason. ## What the uncovered items are Lines: - `Disorderly721.sol:264`, the `totalMinted()` view (sum of the two counters). Read by the site, not asserted by a test. - `DisorderlyAgentCollection.sol:187`, the body of `setContractURI` on the optional wrapper. Branch sides never taken, by contract (a "T" is the revert or true side of a guard that no test triggers): - **RoyaltyRouter**: the constructor's five zero-address guards and the zero-target guard (lines 162-164), the `toReserve == 0` side of the release legs (222), the `fillWei > amount` rounding guard in the straddling fill (285), the re-entrancy revert side of the four `nonReentrant` entry points (304, 310, 316, 326), and the `usdRemaining` view (336). The rounding guard is the one worth a note: the fuzzing campaign executed the line 200,000 calls deep without producing a fill larger than the payment either, which is consistent with the arithmetic (`needUsd * 1e18 / price` cannot exceed `amount` when `amountUsd > needUsd`), so the guard is belt and braces. - **PayoutDistributor**: constructor zero-address guards (100), the re-entrancy revert side of `sweep` and `skim` (183, 206), the empty-cycle sides of `sweep` and `outstanding` (185, 211). - **Disorderly721**: the re-entrancy revert sides of the mint and withdraw entry points (179, 204, 457), the `Finalized` and `MintNotOpen` guards of the operator allowlist path (205, 206), `WalletLimitReached` on the allowlist path (208), the zero-quantity and cap guards of the public path (224, 225), `SoldOut` inside `_mintOperators` (230), the zero-root side of `_verify` (251), the `RootsCollide` side of `setOperatorRoot` (304), double `finalize` (312), and the `RevealExpired` side of `setStartingIndex` (404). - **DisorderlyAgentCollection**: two `require` strings in the constructor (103, 104), one guard in `canStamp` (152), and the owner guard of `setContractURI` (186). - **ProposalRegistry**: one side of the amendment guard (301). None of these is a money path without a test on its other side; they are revert sides of guards whose positive path is tested, or views. The `nonReentrant` revert sides are exercised by the attacker fixtures on the paths that matter (claim, release, withdraw) and show as uncovered only on the entry points that have no re-entrant caller in the suite. ## Not measured here Property fuzzing (`contracts/fuzz/`) and symbolic checks (`contracts/halmos/`) run outside Hardhat and are not part of this figure; their coverage is recorded in their own READMEs from the Echidna corpus and the Halmos path counts.