# Unconditional guard and flow assumptions

Zero-value transfers, same-block deposit/withdraw guards, and if/else branches that skip a required floor

_Area: Smart contract access control and control flow. Seen in 3 disclosed reports; latest 2022-12-21. Updated 2026-10-24._

## How it works
A guard or flow assumes a condition that does not always hold, and the code never checks it. Three shapes appear in the evidence: (1) a transfer is issued unconditionally for a parameter that can legitimately be zero, and a token that reverts on zero-value transfers makes the whole call revert; (2) an integration deposits then withdraws in one transaction, but the underlying protocol forbids same-block deposit+withdraw for the same origin, so the flow reverts; (3) a guard uses if/else between two thresholds, and the high-count branch never enforces the other floor, so a value below the intended minimum passes. In each case the missing check (nonzero amount, allowed ordering, both floors) is what breaks.

## Where it shows up
- Unconditional `safeTransferFrom`/`transfer` of a parameter that can legitimately be zero (strike, amount, fee).
- Integrations that call deposit then withdraw (or join/mint then exit/redeem) within one tx or block.
- Guards written as if/else where one branch omits a check the other branch enforces.
- Thresholds derived from averages or counts that shrink as many small positions are seeded.
- Ordering of internal calls (deposits before pulls) that a counterparty protocol restricts.

## How to review
For every transfer, confirm the amount is validated nonzero before the call, or that zero-transfer-reverting tokens are excluded. For every external vault/protocol integration, check its source for same-block or same-origin deposit/withdraw guards and confirm the flow never triggers both. For every if/else guard, verify each branch enforces all required floors; the invariant is that no reachable state lets a value fall below the intended minimum. Trace pool state (counts, averages) that can be manipulated to weaken a threshold.

## Variants seen
- Zero-strike option unexercisable due to revert-on-zero-transfer, maker keeps premium [E1](https://bugbountylibrary.com/r/c4%3A2022-06-putty%3AH-04.md).
- Rebalance blocked by same-block deposit+withdraw restriction in TrueFi/Idle [E2](https://bugbountylibrary.com/r/sherlock%3A2023-01-derby%3AM-5.md).
- Dust check skipped once loansCount >= 10, allowing sub-dust debt [E3](https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-18.md).

## Impact and severity
Loss of premium and locked/unexercisable positions [E1](https://bugbountylibrary.com/r/c4%3A2022-06-putty%3AH-04.md); blocked rebalancing and stuck strategy [E2](https://bugbountylibrary.com/r/sherlock%3A2023-01-derby%3AM-5.md); debt below dust minimum degrading pool economics [E3](https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-18.md). Severity rises when the broken path is the only route (no fallback) or when an attacker can steer state to force it.

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2022-06-putty%3AH-04.md
- E2: https://bugbountylibrary.com/r/sherlock%3A2023-01-derby%3AM-5.md
- E3: https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-18.md
