Skip to main content

DEUSSToken Fuzz Coverage

Vertical entrypoint: test/fuzzing/FuzzDEUSSTokenIntegrity.sol Invariants:

  • Token-side: test/fuzzing/properties/Properties_TKN.sol
  • Supply/accounting: test/fuzzing/properties/Properties_SPLY.sol

Descriptions: test/fuzzing/properties/PropertiesDescriptions.sol

Scope

Direct exercise of the issued DEUSSToken bond token created during FuzzSetup. The vertical targets only the setup bondTokenId and uses the tracked users pool (USER1..3) as token holders, spenders, operators, and receivers so total-supply accounting remains bounded and enumerable.

Covered behavior:

  • approvals, including zero revocation and nonzero-to-nonzero allowance overwrite
  • BaseToken batch role-grant validation for invalid role bitmaps
  • normal transfers, both batchTransferFrom overloads, and transferFrom through allowance
  • operator grant/revoke and transferFrom through operator approval
  • freeze/unfreeze, batch freeze/unfreeze, forced transfer, and batch forced transfer, including forced release of frozen balance
  • owner-driven address protection checks
  • protected receiver rejection for ordinary third-party transfers
  • BondRegistry-only burn and burnBatch, including forced release of frozen balance
  • contract pause and BondRegistry-driven token-id suspension
  • supply, bondNominalValue, face-value, current-block checkpoint accounting, and future-block checkpoint rejection

Handlers

EntrypointCallerTargetPurpose
fuzz_approvecurrentActortoken.approveSet or reset allowance for the issued token
fuzz_approveOverwriteExistingcurrentActortoken.approveAssert nonzero-to-nonzero approval overwrites the allowance
fuzz_grantRolesBatchInvalidRolesharness ownertoken.grantRoles(address[],uint256)Assert batch role grants reject role bitmaps outside BaseToken.ALL_ROLES
fuzz_transfercurrentActortoken.transferMove free balance between tracked users
fuzz_transferFromAllowanceallowance spendertoken.transferFromMove balance and spend allowance
fuzz_setOperatorcurrentActortoken.setOperatorGrant or revoke operator approval
fuzz_setOperatorUnregisteredcurrentActortoken.setOperatorAssert unregistered operator enablement is rejected
fuzz_transferFromOperatorapproved operatortoken.transferFromMove balance without spending allowance
fuzz_batchTransferFromSingleReceivercurrentActortoken.batchTransferFrom(address,address,uint256[],uint256[])Cover the multi-token-id batch transfer overload for the issued token
fuzz_batchTransferFromMultipleReceiverscurrentActortoken.batchTransferFrom(address,address[],uint256,uint256[])Cover the multi-recipient batch transfer overload for the issued token
fuzz_freezePartialTokensharness role holdertoken.freezePartialTokensFreeze free balance on a tracked user
fuzz_batchFreezePartialTokensharness role holdertoken.batchFreezePartialTokensFreeze free balance through the batch entrypoint
fuzz_unfreezePartialTokensharness role holdertoken.unfreezePartialTokensRelease frozen balance on a tracked user
fuzz_batchUnfreezePartialTokensharness role holdertoken.batchUnfreezePartialTokensRelease frozen balance through the batch entrypoint
fuzz_forcedTransferharness role holdertoken.forcedTransferPrivileged transfer that can release frozen balance
fuzz_batchForcedTransferharness role holdertoken.batchForcedTransferPrivileged batch transfer that can release frozen balance
fuzz_forcedTransferToProtectedReceiverharness role holdertoken.forcedTransferAssert protected custody cannot be the receiver of a forced transfer
fuzz_batchForcedTransferToProtectedReceiverharness role holdertoken.batchForcedTransferAssert protected custody cannot be the receiver of a batch forced transfer
fuzz_burnBondRegistry pranktoken.burnBurn a tracked user's balance through the registry-only token entrypoint
fuzz_burnBatchBondRegistry pranktoken.burnBatchBurn a tracked user's balance through the batch registry-only token entrypoint
fuzz_protectAddressharness ownertoken.protectAddress / token.isAddressProtectedMark a non-token-flow fuzz wallet as protected custody
fuzz_protectedReceiverTransferselected tracked usertoken.transferAssert ordinary transfers into a protected receiver are rejected
fuzz_checkpointFutureRevertsharnesstoken.balanceOfAtAssert future-block checkpoint queries revert
fuzz_setContractPauseharness ownertoken.pause / token.unpauseToggle contract-level pause
fuzz_setBondSuspendedharness BondRegistry role holderbondRegistry.suspendBond / unsuspendBondToggle token-id pause through the registry
fuzz_contractPauseBlocksActioncurrentActortoken.approveAssert contract pause blocks token actions
fuzz_tokenIdPauseBlocksTransferselected tracked usertoken.transferAssert token-id pause blocks normal transfers

fuzz_setBondSuspended deliberately routes through BondRegistry instead of calling pauseTokenId directly, so BondStatus.Suspended and token.isTokenPaused(bondTokenId) stay aligned.

Invariants

Approvals and operators

IDConditionChecked
TKN-10approve writes the expected allowanceon success
TKN-11Approval/operator actions do not mutate owner or spender balanceson success
TKN-12Nonzero-to-nonzero approval overwrites the allowanceon success
TKN-13Batch grantRoles rejects invalid BaseToken role bits with InvalidRoles and leaves roles unchangedexpected revert
TKN-30setOperator stores the requested operator approvalon success
TKN-31Enabling an unregistered operator reverts with Token__OperatorNotEnabledexpected revert

Transfers and freezes

IDConditionChecked
TKN-20Transfer-like actions decrease sender balance and increase receiver balance by amounton success
TKN-21Allowance transfer spends exactly amount of allowanceon success
TKN-22Operator transfer leaves allowance unchangedon success
TKN-40Freeze increases frozen balance without changing total balance or supplyon success
TKN-41Unfreeze decreases frozen balance without changing total balance or supplyon success
TKN-50Forced transfer moves balance and reduces frozen balance only when free balance is insufficienton success
TKN-51Burn decreases holder balance, releases frozen balance when needed, and decreases total supplyon success
TKN-52Forced transfer into protected custody reverts with Token__ProtectedReceiverTransferNotAllowed and leaves source, receiver, and supply unchangedexpected revert

Pause and suspension

IDConditionChecked
TKN-60Contract pause state matches the requested stateon success
TKN-61Bond status and token-id pause match the requested suspension stateon success
TKN-62Contract pause blocks the selected token action with PausableUpgradeable.EnforcedPauseexpected revert
TKN-63Token-id pause blocks normal transfer with Token__TokenIdIsPausedexpected revert

Cross-cutting token accounting

These run after successful token actions through onSuccessInvariantsGeneral or targeted token postconditions.

IDCondition
TKN-01Every tracked frozen balance is bounded by its token balance
TKN-70Current-block balanceOfAt, frozenBalanceOfAt, and availableBalanceOfAt match current account state for touched actors
TKN-71Future-block checkpoint queries revert with Token__BlockInFuture
TKN-80protectAddress marks the selected account as protected
TKN-81Ordinary third-party transfers into a protected receiver revert with Token__ProtectedReceiverTransferNotAllowed and preserve balances
SPLY-01Total supply equals the sum of tracked balances
SPLY-02Total supply never exceeds the initial issued supply
SPLY-03Bond nominal value remains BOND_NOMINAL_VALUE
SPLY-04totalSupply * bondNominalValue equals tracked balance face value
SPLY-05Current-block totalSupplyAt matches current totalSupply

Touched actor balances, frozen balances, checkpoints, total supply, and pause state are snapshotted through the shared marketplace snapshot module because those accounting invariants are also used by offer, deal, and escrow flows. DEUSSToken-specific pair state, namely allowance(owner, spender, bondTokenId) and isOperator(owner, spender), is snapshotted in BeforeAfterDEUSSToken.

Preconditions

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

HandlerClamp rules
approveContract must not be paused. Owner is currentActor; spender is selected from the tracked users pool. Amount is clamped to [0, initialIssuedSupply] and overwrites the existing allowance.
approveOverwriteExistingContract must not be paused. Selects a spender from the tracked users pool with existing nonzero allowance from currentActor; new amount is clamped to [1, initialIssuedSupply].
grantRolesBatchInvalidRolesSelects two adjacent tracked users, snapshots their token role bitmaps, and ORs BaseToken.ALL_ROLES with one invalid role bit selected from [3, 255].
transferContract and token ID must not be paused. currentActor must have free balance; receiver is a different tracked user; amount is clamped to [1, freeBalance].
transferFromAllowanceContract and token ID must not be paused. Selects an owner different from currentActor with nonzero allowance, no operator approval to currentActor, and free balance. Amount is clamped to the lower of allowance and free balance.
setOperatorContract must not be paused. Owner is currentActor; operator is a different enabled tracked user; requested boolean passes through.
setOperatorUnregisteredContract must not be paused. Operator is fixed to FUZZ_TOKEN_UNREGISTERED_OPERATOR and must not be enabled in EntityRegistry.
transferFromOperatorContract and token ID must not be paused. Selects an owner that approved currentActor as operator and has free balance.
batchTransferFromSingleReceiverSame as transfer, then wraps the issued bondTokenId and amount in singleton arrays for the multi-token-id overload.
batchTransferFromMultipleReceiversSame as transfer, then wraps the receiver and amount in singleton arrays for the multi-recipient overload.
freezePartialTokensContract must not be paused. Selects a tracked user with free balance; amount is clamped to [1, freeBalance]. Token-id suspension is allowed.
batchFreezePartialTokensSame as freezePartialTokens, then wraps the selected account and amount in singleton arrays for the batch entrypoint.
unfreezePartialTokensContract must not be paused. Selects a tracked user with frozen balance; amount is clamped to [1, frozenBalance]. Token-id suspension is allowed.
batchUnfreezePartialTokensSame as unfreezePartialTokens, then wraps the selected account and amount in singleton arrays for the batch entrypoint.
forcedTransferContract must not be paused. Selects a tracked user with balance; amount is clamped to [1, balance]. Token-id suspension is allowed.
batchForcedTransferSame as forcedTransfer, then wraps the source, receiver, and amount in singleton arrays for the batch entrypoint.
forcedTransferToProtectedReceiverSelects a tracked user with balance, ensures EscrowManager is protected custody and EntityRegistry-enabled, then attempts to force-transfer [1, balance] tokens into it.
batchForcedTransferToProtectedReceiverSame as forcedTransferToProtectedReceiver, then wraps the source, protected receiver, and amount in singleton arrays for the batch entrypoint.
burnEnsures the contract is unpaused. Selects an enabled, unprotected tracked user with balance; amount is clamped to a capped range so burn coverage does not starve later token actions. The token call is pranked as BondRegistry.
burnBatchSame as burn, then wraps the source and amount in singleton arrays for the batch entrypoint.
protectAddressSelects an unprotected address from FUZZ_WALLETS, which is disjoint from the main token-flow users pool.
protectedReceiverTransferEnsures FUZZ_WALLET_7 is enabled and protected, selects a tracked sender with free balance, clamps amount to [1, freeBalance], then attempts a normal transfer into the protected receiver.
checkpointFutureRevertsSelects a tracked user and queries balanceOfAt at block.number + 1.
setContractPauseRequested pause state must differ from current contract pause state.
setBondSuspendedSuspension requires BondStatus.Issued and is allowed while the contract is globally paused; unsuspension requires BondStatus.Suspended and the contract must not be paused.
contractPauseBlocksActionEnsures contract pause is active, snapshots allowance state, then attempts approve.
tokenIdPauseBlocksTransferEnsures token-id pause is active through BondRegistry.suspendBond, selects a user with free balance, then attempts transfer.

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