Skip to main content

BondRegistry Fuzz Coverage

Vertical entrypoint: test/fuzzing/FuzzBondRegistryIntegrity.sol Invariants: test/fuzzing/properties/Properties_BOND.sol Descriptions: test/fuzzing/properties/PropertiesDescriptions.sol

Scope

End-to-end exercise of the BondRegistry lifecycle and issuance accounting: publishing successor versions, amending published bonds, issuing tranches, closing issuance, suspending/unsuspending, cancelling, terminally redeeming, issuer recovery, and both burn kinds (ISSUER_RECLAIM / FINAL_SETTLEMENT). The harness tracks every published version of the single BOND_ISIN series so multi-version flows (successor cutover, Replaced cascade) are reachable.

Registry-to-token consistency is the central cross-cutting property: token.totalSupply(tokenId) must equal mintedSupply − totalBurned for every tracked version at all times. Tranche consistency is checked independently by summing all tracked tranche issueCount values and comparing the result with mintedSupply.

Handlers

EntrypointCallerTargetPurpose
fuzz_publishBondharness admin (PUBLISHER)bondRegistry.publishBondPublish a successor version
fuzz_publishBondActiveVersionNotIssuableharness admin (PUBLISHER)bondRegistry.publishBondNegative path: successor publish from non-Issued active version must revert
fuzz_publishBondSuccessorAlreadyPublishedharness admin (PUBLISHER)bondRegistry.publishBondNegative path: second Published successor must revert
fuzz_updatePublishedBondharness admin (PUBLISHER)bondRegistry.updatePublishedBondAmend a Published version in place
fuzz_updatePublishedBondInvalidStatusharness admin (PUBLISHER)bondRegistry.updatePublishedBondNegative path: update on non-Published status must revert
fuzz_issueBondbond issuer (USER1)bondRegistry.issueBondMint a tranche and record it
fuzz_issueBondPublisherharness admin (PUBLISHER)bondRegistry.issueBondMint a tranche through the role-authorized publisher path
fuzz_issueBondUnauthorizednon-issuer brokerbondRegistry.issueBondNegative path: unauthorized issuance caller must revert
fuzz_issueBondClosedbond issuerbondRegistry.issueBondNegative path: issuance after closeIssuance must revert
fuzz_issueBondZeroAmountbond issuerbondRegistry.issueBondNegative path: zero issuance amount must revert
fuzz_issueBondMaxSupplyExceededbond issuerbondRegistry.issueBondNegative path: issuance above remaining supply must revert
fuzz_issueBondMaturityExpiredbond issuerbondRegistry.issueBondNegative path: issuance after maturity must revert
fuzz_issueBondSuccessorSuspendedPreviousbond issuerbondRegistry.issueBondNegative path: first issuance of a published successor while the previous active version is suspended must revert
fuzz_closeIssuanceharness admin (PUBLISHER)bondRegistry.closeIssuancePermanently block future issuance
fuzz_closeIssuanceIssuerbond issuerbondRegistry.closeIssuancePermanently block future issuance through the issuer-authorized path
fuzz_closeIssuanceInvalidStatusharness adminbondRegistry.closeIssuanceNegative path: invalid lifecycle status must revert
fuzz_closeIssuanceUnauthorizednon-issuer brokerbondRegistry.closeIssuanceNegative path: unauthorized close caller must revert
fuzz_closeIssuanceAlreadyClosedbond issuerbondRegistry.closeIssuanceNegative path: closing issuance twice must revert
fuzz_cancelBondharness admin (CANCEL)bondRegistry.cancelBondCancel the latest Published version when it has no tranches
fuzz_suspendBondharness admin (SUSPEND)bondRegistry.suspendBondTransition Issued to Suspended, pause token id
fuzz_unsuspendBondharness admin (UNSUSPEND)bondRegistry.unsuspendBondTransition Suspended back to Issued, unpause
fuzz_closeBondharness admin (CLOSE)bondRegistry.closeBondTerminally redeem a version once supply is zero and no pending Published successor blocks active-version closure
fuzz_rotateIssuerharness admin (ISSUER_RECOVERY)bondRegistry.rotateIssuerRotate the issuer for a recoverable version; prefers Replaced when reachable
fuzz_rotateIssuerInvalidStatusharness admin (ISSUER_RECOVERY)bondRegistry.rotateIssuerNegative path: issuer recovery from Cancelled / Redeemed must revert
fuzz_burnBondReclaimbond issuerbondRegistry.burnBond (ISSUER_RECLAIM)Burn unfrozen issuer-held tokens and reopen capacity
fuzz_burnBondSettlementenabled harness admin (BURNER)bondRegistry.burnBond (FINAL_SETTLEMENT)Burn tokens without returning capacity
fuzz_burnBondSettlementIssuerbond issuerbondRegistry.burnBond (FINAL_SETTLEMENT)Burn issuer-held tokens through the issuer-authorized settlement path
fuzz_burnBondSettlementHolderenabled harness admin (BURNER)bondRegistry.burnBond (FINAL_SETTLEMENT)Burn non-issuer holder/source tokens without returning capacity
fuzz_burnBondBatchReclaimbond issuerbondRegistry.burnBondBatch (ISSUER_RECLAIM)Batch burn unfrozen issuer-held tokens and reopen capacity
fuzz_burnBondReclaimFrozenIssuerbond issuerbondRegistry.burnBond (ISSUER_RECLAIM)Negative path: reclaim that includes frozen issuer inventory must revert
fuzz_burnBondBatchSettlementenabled harness admin (BURNER)bondRegistry.burnBondBatch (FINAL_SETTLEMENT)Batch burn tokens without returning capacity
fuzz_issueBondInvalidStatusbond issuerbondRegistry.issueBondNegative path: issuance against non-issuable status must revert
fuzz_cancelBondInvalidharness adminbondRegistry.cancelBondNegative path: cancel on non-Published or already-issued bond must revert
fuzz_suspendBondInvalidStatusharness adminbondRegistry.suspendBondNegative path: suspend on non-Issued status must revert
fuzz_unsuspendBondInvalidStatusharness adminbondRegistry.unsuspendBondNegative path: unsuspend on non-Suspended status must revert
fuzz_closeBondInvalidharness adminbondRegistry.closeBondNegative path: close on non-closeable status, non-zero supply, or active version with pending Published successor must revert
fuzz_burnBondReclaimUnauthorizednon-issuer brokerbondRegistry.burnBond (ISSUER_RECLAIM)Negative path: reclaim from non-issuer caller must revert
fuzz_burnBondSettlementUnauthorizednon-issuer non-BURNER brokerbondRegistry.burnBond (FINAL_SETTLEMENT)Negative path: settlement burn from caller without BURNER role must revert
fuzz_burnBondSettlementBurnerNotEnabledunregistered BURNER callerbondRegistry.burnBond (FINAL_SETTLEMENT)Negative path: settlement burn from BURNER caller not enabled in EntityRegistry must revert
fuzz_burnBondInvalidSourcebond issuerbondRegistry.burnBondNegative path: invalid source for the burn kind must revert
fuzz_burnBondInvalidStatusissuer or enabled BURNERbondRegistry.burnBondNegative path: invalid burn lifecycle status must revert
fuzz_burnBondBatchLengthMismatchbond issuerbondRegistry.burnBondBatchNegative path: mismatched batch arrays must revert
fuzz_burnBondBatchInvalidSourcebond issuerbondRegistry.burnBondBatchNegative path: invalid batch source must revert
fuzz_bondRegistryViewSurfaceharnessBondRegistry gettersExercise tranche, coupon, version, token, and interface getters
fuzz_publishIndependentZeroCouponBondharness admin (PUBLISHER)bondRegistry.publishBond + coupon gettersPublish an independent zero-coupon ISIN and cover zero-coupon getter paths
fuzz_appendScoringharness admin (SCORING)bondRegistry.appendScoringAppend a valid scoring record and verify scoring getters
fuzz_appendScoringInvalidharness admin (SCORING)bondRegistry.appendScoringNegative path: invalid scoring input must revert
fuzz_scoringInvalidQueriesharnessscoring gettersNegative path: invalid scoring reads must revert
fuzz_bondRegistryAdminSurfaceharness ownergrantRoles(address[],uint256)Cover valid array-role grants, including the issuer-recovery role
fuzz_bondRegistryGrantInvalidRoleharness ownergrantRoles(address,uint256)Negative path: out-of-range role bit must revert
fuzz_bondRegistrySetMultiTokenLockedharness ownerbondRegistry.setMultiTokenNegative path: locked token address must revert
fuzz_bondRegistryInitializeAgainharness ownerbondRegistry.initializeNegative path: repeated initializer must revert
fuzz_publishBondInvalidInputharness admin (PUBLISHER)bondRegistry.publishBondNegative path: invalid bond input validation must revert

USER1 is bound as the bond issuer during setup and is granted the issuer-authorized path for issueBond and burnBond(ISSUER_RECLAIM). All admin-gated calls are issued from address(this), which is granted ALL_BR_ROLES in _grantRoles and registered as an enabled DEUSS_PROTOCOL account in EntityRegistry. The harness keeps a local ledger of burned amounts per (version, kind) (burnedReclaimed, burnedSettled) so the cross-cutting supply invariant can be expressed as an equality despite _reservedByAsset and burn accounting being private to the registry.

Invariants

Global — group 00

Re-evaluated after every successful action in any vertical through onSuccessInvariantsGeneral.

IDCondition
BOND-01For every tracked bond version, token.totalSupply(tokenId) == mintedSupply − (burnedReclaimed + burnedSettled)
BOND-02For every tracked bond version, remainingIssuableSupply + mintedSupply == maxSupply + burnedReclaimed
BOND-03For every tracked bond version in an active status (Published / Issued / Suspended), token.isTokenPaused(tokenId) matches status == Suspended. Terminal statuses (Cancelled, Replaced, Redeemed) are excluded because the token id pause state is not constrained after the lifecycle ends. closeBond unpauses a Suspended bond's token id on close, except when the token contract is globally paused (unpauseTokenId is whenNotPaused-guarded), in which case the token id may remain paused in the terminal Redeemed state.
BOND-04For every tracked bond version, reverse tokenId mapping, stored token address, and computed tokenId are consistent
BOND-05For every tracked bond version, the sum of all tranche issueCount values equals mintedSupply

BOND-01 through BOND-03 are evaluated via separate supply, capacity, and pause aggregates in the BeforeAfterBondRegistry snapshot module; BOND-04 uses the allTrackedBondReverseMappingsConsistent aggregate; BOND-05 uses the allTrackedBondTranchesConsistent aggregate.

publishBond — group 10

Checked in publishSuccessorPostconditions for fuzz_publishBond.

IDConditionChecked
BOND-10New version equals previous latest plus oneon success
BOND-11New version has status Publishedon success
BOND-12New version starts with mintedSupply = 0 and remainingIssuableSupply = maxSupplyon success
BOND-13Previous active version's status is not mutated by publishon success
BOND-14No unexpected revertson revert
BOND-15publishBond successor does not change activeVersionon success
BOND-16Successor bond fields, including isGuaranteed, match the supplied BondInputon success

updatePublishedBond — group 20

Checked in updatePublishedPostconditions for fuzz_updatePublishedBond.

IDConditionChecked
BOND-20tokenId and trancheCount are preserved across the amendmenton success
BOND-21remainingIssuableSupply is reset to the new maxSupplyon success
BOND-22Bond status stays Publishedon success
BOND-23No unexpected revertson revert
BOND-24Mutable bond fields are written from the amended input while immutable isGuaranteed is preservedon success

issueBond — group 30

Checked in issueBondPostconditions for fuzz_issueBond and fuzz_issueBondPublisher.

IDConditionChecked
BOND-30mintedSupply grows by the issued amounton success
BOND-31remainingIssuableSupply shrinks by the issued amounton success
BOND-32trancheCount grows by 1 and the latest tranche has issueCount == amounton success
BOND-33Issuer bond balance grows by the issued amounton success
BOND-34Token totalSupply(tokenId) grows by the issued amounton success
BOND-35Status transitions Published → Issued on first issuanceon success + first issuance
BOND-36First issuance of a successor transitions previous active version to Replacedon success + first issuance of a successor
BOND-37No unexpected revertson revert
BOND-39First issuance of a successor updates activeVersion to the issued successor versionon success + first issuance of a successor
BOND-102The issued version is in Issued status after every successful issueBond, including repeat issuanceson success

closeIssuance — group 40

Checked in closeIssuancePostconditions for fuzz_closeIssuance and fuzz_closeIssuanceIssuer.

IDConditionChecked
BOND-40issuanceClosed flag flips to trueon success
BOND-41Bond status is not mutatedon success
BOND-42No unexpected revertson revert

cancelBond — group 50

Checked in cancelBondPostconditions for fuzz_cancelBond.

IDConditionChecked
BOND-50Status transitions Published → Cancelledon success
BOND-51No unexpected revertson revert
BOND-53cancelBond preserves monotonic latestVersion and only clears activeVersion when cancelling the active unissued drafton success

suspendBond / unsuspendBond — group 60

Checked in suspendBondPostconditions / unsuspendBondPostconditions for fuzz_suspendBond and fuzz_unsuspendBond.

IDConditionChecked
BOND-60suspendBond transitions status Issued → Suspendedon success of fuzz_suspendBond
BOND-61suspendBond pauses the bond token idon success of fuzz_suspendBond
BOND-62unsuspendBond transitions status Suspended → Issuedon success of fuzz_unsuspendBond
BOND-63unsuspendBond unpauses the bond token idon success of fuzz_unsuspendBond
BOND-64No unexpected reverts for either handleron revert

closeBond — group 70

Checked in closeBondPostconditions for fuzz_closeBond.

IDConditionChecked
BOND-70Token totalSupply(tokenId) is zero at the moment closeBond succeeds (verified against the pre-state snapshot)on success
BOND-71Status transitions Issued or SuspendedRedeemedon success
BOND-72No unexpected revertson revert

burnBond — group 80

Checked in burnReclaimPostconditions / burnSettlementPostconditions and the batch equivalents for all burn success handlers.

IDConditionChecked
BOND-80Burn source balance for the burned version's tokenId shrinks by the burned amounton success
BOND-81Token totalSupply(tokenId) shrinks by the burned amounton success
BOND-82mintedSupply is not changed by a burnon success
BOND-83ISSUER_RECLAIM burn grows remainingIssuableSupply by the burned amounton success of reclaim single/batch burns
BOND-84FINAL_SETTLEMENT burn leaves remainingIssuableSupply unchangedon success of settlement single/batch burns
BOND-85No unexpected reverts for burnBond or burnBondBatchon revert

rotateIssuer — group 105

Checked in rotateIssuerPostconditions for fuzz_rotateIssuer.

IDConditionChecked
BOND-105issuer is updated to the requested enabled replacement issueron success
BOND-106.statusLifecycle status is preservedon success
BOND-106.issuanceClosedIssuance-closed flag is preservedon success
BOND-106.isGuaranteedGuarantee flag is preservedon success
BOND-106.tokenIdPausedToken pause state is preservedon success
BOND-106.trancheCountTranche count is preservedon success
BOND-106.tokenIdToken id is preservedon success
BOND-106.tokenAddressToken address is preservedon success
BOND-106.mintedSupplyMinted supply is preservedon success
BOND-106.remainingIssuableSupplyRemaining issuable supply is preservedon success
BOND-106.maxSupplyMax supply is preservedon success
BOND-106.totalSupplyToken total supply is preservedon success
BOND-106.currencyCurrency is preservedon success
BOND-106.bondNominalValueNominal value is preservedon success
BOND-106.couponRateTypeCoupon rate type is preservedon success
BOND-106.couponFrequencyCoupon frequency is preservedon success
BOND-106.issuanceCountryIssuance country is preservedon success
BOND-106.maturityDateMaturity date is preservedon success
BOND-106.couponRatesHashCoupon rates are preservedon success
BOND-106.latestVersionLatest version is preservedon success
BOND-106.activeVersionActive version is preservedon success
BOND-107Old and new issuer token balances are unchangedon success
BOND-108No unexpected revertson revert

Getter / auxiliary positive surfaces

These handlers exercise valid read/admin/scoring surfaces and keep the same positive-path convention as the lifecycle handlers: preconditions should select valid inputs, and any protocol revert is unexpected unless a later trace proves a specific selector is legitimate. The view surface also covers current-coupon branches for active, zero-coupon, unissued, missing-issue-date, and matured bond structs.

IDConditionChecked
BOND-110appendScoring stores the expected scoring record and exposes it through getScoringAt / getLatestScoringon success of fuzz_appendScoring
BOND-111appendScoring does not unexpectedly reverton revert
BOND-114Valid BondRegistry admin helpers do not unexpectedly reverton revert
BOND-117Independent zero-coupon bond publication does not unexpectedly reverton revert
BOND-118BondRegistry getter surface does not unexpectedly revert for valid tracked series/version/token/tranche/coupon inputson getter revert

Negative paths — invalid statuses and unauthorized callers

Each invariant in this group checks that the call must revert and that the revert reason is one of a small allowlist for that operation. Anything else is a bug.

IDConditionChecked
BOND-38issueBond against a version whose status is not Published or Issued reverts with BondRegistry__InvalidBondStatusalways (per fuzz_issueBondInvalidStatus)
BOND-52cancelBond against a version that is not Published, or that already has tranches, reverts with BondRegistry__InvalidBondStatus or BondRegistry__BondAlreadyIssuedalways (per fuzz_cancelBondInvalid)
BOND-65suspendBond against a version whose status is not Issued reverts with BondRegistry__InvalidBondStatusalways (per fuzz_suspendBondInvalidStatus)
BOND-66unsuspendBond against a version whose status is not Suspended reverts with BondRegistry__InvalidBondStatusalways (per fuzz_unsuspendBondInvalidStatus)
BOND-73closeBond against a version that is not in Issued/Suspended, whose token total supply is non-zero, or whose active version has a pending Published successor, reverts with the expected close guard erroralways (per fuzz_closeBondInvalid)
BOND-86burnBond from a caller that is neither the bond issuer nor an enabled BURNER reverts with BondRegistry__UnauthorizedBurnCalleralways (per fuzz_burnBondReclaimUnauthorized, fuzz_burnBondSettlementUnauthorized, and fuzz_burnBondSettlementBurnerNotEnabled)
BOND-87issueBond from a caller that is neither publisher nor issuer reverts with BondRegistry__UnauthorizedIssueralways (per fuzz_issueBondUnauthorized)
BOND-88issueBond after closeIssuance reverts with BondRegistry__IssuanceClosedalways (per fuzz_issueBondClosed)
BOND-89issueBond with amount zero reverts with BondRegistry__IssuanceAmountIsZeroalways (per fuzz_issueBondZeroAmount)
BOND-90issueBond above remaining issuable supply reverts with BondRegistry__MaxSupplyExceededalways (per fuzz_issueBondMaxSupplyExceeded)
BOND-91issueBond after maturity reverts with BondRegistry__MaturityDateExpiredalways (per fuzz_issueBondMaturityExpired)
BOND-92closeIssuance from an invalid lifecycle status reverts with BondRegistry__InvalidBondStatusalways (per fuzz_closeIssuanceInvalidStatus)
BOND-93closeIssuance from a caller that is neither publisher nor issuer reverts with BondRegistry__UnauthorizedIssuanceCloseralways (per fuzz_closeIssuanceUnauthorized)
BOND-94closeIssuance on an already closed version reverts with BondRegistry__IssuanceClosedalways (per fuzz_closeIssuanceAlreadyClosed)
BOND-95burnBond with a source disallowed for the burn kind reverts with BondRegistry__InvalidBurnSourcealways (per fuzz_burnBondInvalidSource)
BOND-96burnBond from an invalid lifecycle status reverts with BondRegistry__InvalidBondStatusalways (per fuzz_burnBondInvalidStatus)
BOND-97burnBondBatch with mismatched froms / amounts lengths reverts with LengthMismatchalways (per fuzz_burnBondBatchLengthMismatch)
BOND-98burnBondBatch validates each source and reverts with BondRegistry__InvalidBurnSourcealways (per fuzz_burnBondBatchInvalidSource)
BOND-99publishBond while the active version is not Issued reverts with BondRegistry__ActiveVersionNotIssuablealways (per fuzz_publishBondActiveVersionNotIssuable)
BOND-100publishBond while a successor version is already Published reverts with BondRegistry__SuccessorAlreadyPublishedalways (per fuzz_publishBondSuccessorAlreadyPublished)
BOND-101updatePublishedBond against a version whose status is not Published reverts with BondRegistry__InvalidBondStatusalways (per fuzz_updatePublishedBondInvalidStatus)
BOND-103issueBond for a published successor while the current active version is Suspended reverts with BondRegistry__InvalidBondStatusalways (per fuzz_issueBondSuccessorSuspendedPrevious)
BOND-104ISSUER_RECLAIM above the issuer's unfrozen/free balance reverts with BondRegistry__FrozenIssuerReclaimDeniedalways (per fuzz_burnBondReclaimFrozenIssuer)
BOND-109rotateIssuer against a version whose status is Cancelled or Redeemed reverts with BondRegistry__InvalidBondStatusalways (per fuzz_rotateIssuerInvalidStatus)
BOND-112Invalid appendScoring inputs revert with the expected scoring validation selectoralways (per fuzz_appendScoringInvalid)
BOND-113Invalid scoring reads revert with ScoringNotFound / InvalidScoringIdalways (per fuzz_scoringInvalidQueries)
BOND-115Protected admin calls revert with InvalidRoles, MultiTokenLocked, or InvalidInitialization as appropriatealways (per admin negative handlers)
BOND-116Invalid publishBond inputs revert with the expected bond input validation selectoralways (per fuzz_publishBondInvalidInput)

Cross-cutting invariants (pre-existing)

Also enforced after every successful BondRegistry action through onSuccessInvariantsGeneral:

  • SPLY-01, SPLY-02 — total supply of the fuzzed bond token id stays consistent with tracked balances.
  • ESCR-01, ESCR-02, ESCR-60 — escrow invariants hold across burns that drop registry supply.
  • OFER-01 — offer balance bounds stay respected even as the token id is suspended.
  • PAUS-01 — active bond status and active version token pause state remain aligned; BOND-03 is the per-version generalisation.

Preconditions

Summary of the clamping and state-selection logic applied before each handler issues a protocol call. Full implementation in helper/preconditions/PreconditionsBondRegistry.sol.

HandlerClamp rules
publishBondRequires a free successor slot (latestVersion > 0 and < uint8.max), active version in Issued, and no existing Published successor. Cancelled successors remain in history, so the next successful publish advances to a fresh version/tokenId. New input reuses BOND_ISIN, the current issuer, and clamps maxSupply to [1, BOND_ISSUE_COUNT].
publishBondActiveVersionNotIssuableRequires an existing ISIN, a nonzero active version whose status is not Issued, and no Published successor; valid bond input is supplied so the active-status guard is isolated.
publishBondSuccessorAlreadyPublishedRequires active version in Issued and the latest tracked version in Published, then attempts to publish another successor.
updatePublishedBondPicks a tracked version in Published status via _pickKnownBondVersionByStatus. Picks a registered user as the amended issuer, clamps maxSupply the same way as publish, and preserves the tracked version's isGuaranteed value.
updatePublishedBondInvalidStatusPicks a tracked version whose status is not Published via _pickKnownBondVersionNotPublished.
issueBondPicks a tracked version that is Published or Issued, has issuanceClosed == false, non-zero remainingIssuableSupply, and unexpired maturity (via _pickKnownBondVersionIssuable). For first issuance of a successor, the current active predecessor must still be Issued; the suspended-predecessor case is covered by the dedicated negative handler. Amount clamped to [1, min(remainingIssuableSupply, BOND_ISSUE_COUNT)]. Prank uses the bond issuer.
issueBondPublisherUses the same positive issuance selector as issueBond, but calls from the harness admin so the PUBLISHER role path is exercised.
issueBondUnauthorizedReuses the positive issuance selector but picks a caller that is neither the issuer nor a holder of PUBLISHER.
issueBondClosedPicks a tracked Issued version where issuanceClosed == true and calls from the bond issuer.
issueBondZeroAmountPicks a positive issuable version and calls with amount 0.
issueBondMaxSupplyExceededPicks a positive issuable version and calls with remainingIssuableSupply + 1.
issueBondMaturityExpiredPicks a tracked Published / Issued version that is unclosed but has maturityDate <= block.timestamp.
closeIssuancePicks a tracked version with issuanceClosed == false in Issued / Suspended status (via _pickKnownBondVersionIssuanceUnclosed).
closeIssuanceIssuerUses the same positive close-issuance selector as closeIssuance, but calls from the bond issuer instead of the harness admin.
closeIssuanceInvalidStatusPicks a tracked version outside Issued / Suspended, including unissued Published versions.
closeIssuanceUnauthorizedReuses the positive close-issuance selector but picks a caller that is neither the issuer nor a holder of PUBLISHER.
closeIssuanceAlreadyClosedPicks a tracked Issued / Suspended version where issuanceClosed == true.
cancelBondPicks the latest tracked version only when it is Published with trancheCount == 0 (via _pickKnownBondVersionCancellable).
suspendBondPicks a tracked Issued version. May run while the token contract is globally paused.
unsuspendBondPicks a tracked Suspended version. Requires the token contract to be unpaused because unpauseTokenId remains blocked by global pause.
closeBondPicks a tracked version in Issued or Suspended with token.totalSupply(tokenId) == 0, excluding the active version when a later successor is pending (via _pickKnownBondVersionCloseable).
rotateIssuerPicks a tracked version in Published, Issued, Suspended, or Replaced; Replaced is preferred when present so superseded-version recovery is exercised densely. Replacement issuer is picked from enabled registered users and must differ from the stored issuer.
rotateIssuerInvalidStatusPicks a tracked version in Cancelled or Redeemed, then supplies an otherwise valid enabled replacement issuer so the status guard is isolated.
burnBondReclaimPicks a tracked Issued version whose issuer holds non-zero unfrozen/free bond balance (via _pickKnownBondVersionReclaimable). Amount clamped to [1, issuerFreeBalance]. Prank uses the issuer.
burnBondSettlementPicks a tracked version in Issued or Replaced whose issuer holds a non-zero bond balance (via _pickKnownBondVersionSettlementBurnable). Amount clamped the same way; prank uses the enabled harness admin (BURNER role).
burnBondSettlementIssuerUses the same positive settlement selector as burnBondSettlement, but calls from the issuer so the issuer-authorized FINAL_SETTLEMENT branch is exercised.
burnBondSettlementHolderPicks a tracked version in Issued or Replaced with a non-issuer source balance among tracked users, escrowManager, or the harness address, then burns from that source via the enabled harness admin (BURNER role).
burnBondBatchReclaimUses the same selector as reclaim, but splits the free-balance-clamped burn amount across one or two batch entries.
burnBondReclaimFrozenIssuerPicks a reclaimable Issued version, freezes part of the issuer's free balance as setup, then attempts to reclaim more than the issuer's remaining free balance.
burnBondBatchSettlementUses the same selector as settlement, but splits the clamped burn amount across one or two batch entries.
issueBondInvalidStatusPicks a tracked version whose status is not Published/Issued (via _pickKnownBondVersionNotIssuable). Calls issueBond with amount 1 from the bond issuer so only the status check can fire.
issueBondSuccessorSuspendedPreviousRequires the active version to be Suspended, then picks a tracked Published successor with open issuance, remaining supply, and unexpired maturity. Calls issueBond from the successor issuer and expects the predecessor-status cutover guard to revert.
cancelBondInvalidPicks a tracked version that is either not Published or has at least one tranche (via _pickKnownBondVersionNotCancellable).
suspendBondInvalidStatusPicks a tracked version whose status is not Issued (via _pickKnownBondVersionNotIssued).
unsuspendBondInvalidStatusPicks a tracked version whose status is not Suspended (via _pickKnownBondVersionNotSuspended).
closeBondInvalidPicks a tracked version where status is not in {Issued, Suspended}, where totalSupply(tokenId) > 0, or where the active version has a pending Published successor (via _pickKnownBondVersionNotCloseable).
burnBondReclaimUnauthorizedPicks a tracked Issued version with a non-zero issuer balance and a caller from tracked users that is neither the issuer nor a holder of the BURNER role. Amount is clamped to issuer balance because authorization fires before reclaim free-balance validation.
burnBondSettlementUnauthorizedPicks a tracked settlement-burnable version (Issued / Replaced with non-zero issuer balance) and the same kind of unauthorized caller.
burnBondSettlementBurnerNotEnabledPicks a tracked settlement-burnable version, grants BURNER to a fixed unregistered caller, and expects the EntityRegistry enabled-account gate to reject it.
burnBondInvalidSourcePicks a burn-compatible status for the selected kind and calls from the issuer with from != issuer, so the source check is isolated.
burnBondInvalidStatusPicks a status disallowed for the selected kind and uses an otherwise authorized caller/source.
burnBondBatchLengthMismatchPicks an existing version and supplies froms.length != amounts.length.
burnBondBatchInvalidSourcePicks an Issued version and includes a non-issuer source in an ISSUER_RECLAIM batch.
bondRegistryViewSurfacePicks a tracked version with at least one tranche and calls every BondRegistry getter variant against valid active/version/token ids, including current-coupon helper branches.
publishIndependentZeroCouponBondPublishes BOND_ZERO_COUPON_ISIN once with empty coupon arrays, then calls zero-coupon getter paths.
appendScoringPicks a user wallet, records its previous scoring count, and builds a valid append-only scoring record.
appendScoringInvalidSelects zero wallet, zero issue date, invalid expiration, zero distributor id, or probability over 10_000.
scoringInvalidQueriesUses an unscored fuzz wallet and a non-zero id to isolate scoring getter reverts.
bondRegistryAdminSurfaceGrants one valid role through the array overload, then revokes through the scalar and batch revoke surfaces.
bondRegistryGrantInvalidRoleCalls grantRoles(address,uint256) with an out-of-range role bit.
bondRegistrySetMultiTokenLockedCalls setMultiToken after the token address has already been locked by setup.
bondRegistryInitializeAgainCalls initialize after setup has already initialized the proxy.
publishBondInvalidInputSelects invalid issuer, currency, bondNominalValue, max supply, maturity, coupon length, coupon order, or duplicate coupon cases.

All clamp failures raise ClampFail(string), which the integrity layer accepts as a skip rather than a bug.