# Squeezing drips from a sender can be front-run and prevented by the sender

Drips sender front-runs a receiver's squeeze by adding a new drips config, invalidating the supplied historyHash and blocking fund collection until cycle end.

- Payout: Contest reward
- Severity: medium
- Program: Drips Protocol
- Credited: berndartmueller
- Disclosed: 2023-03-10
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-01-drips-findings/issues/276
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-drips%3AM-01
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:race-window technique:source-review vuln:business-logic vuln:race-condition

**Target:** Drips.sol squeeze/history verification
**Root cause:** Squeeze requires the receiver to supply the full drips history whose hash must equal the sender's current dripsHistoryHash; any new sender config changes that hash and invalidates the receiver's precomputed history.
**Steps:**
1. Receiver builds DripsHistory[] covering all configs since last squeeze and calls squeezeDrips with the resulting historyHash.
2. Sender observes the pending squeeze tx and submits setDrips adding a new configuration, updating dripsHistoryHash.
3. Squeeze tx executes; `_verifyDripsHistory` at Drips.sol#L461 fails `require(historyHash == finalHistoryHash, "Invalid drips history")`.
4. Receiver cannot squeeze until the next cycle; repeat each cycle to indefinitely postpone.
**How found:** Code-reading of _squeezeDripsResult/_verifyDripsHistory: noticed the history hash is checked against the sender's mutable latest hash, so any sender state change invalidates a receiver's precomputed history.
**Exploitation:** Sender (the only privileged account able to grief) front-runs each squeeze with a config update; owed funds cannot be revoked but collection is delayed until cycle end (1 week to 1 month per config).
**Insight:** When a claim/withdraw path requires the caller to reconstruct and hash-match another party's mutable on-chain state, that party can invalidate the proof by touching state in the same block; check whether verification pins to a timestamp/snapshot rather than 'latest'.
