# Withdrawal timestamp and cooldown mishandling

User-writable or zero-default timestamps gating penalties, cooldowns, or withdrawal proofs

_Area: DeFi accounting and math bugs. Seen in 3 disclosed reports; latest 2024-04-05. Updated 2026-10-25._

## How it works
A timestamp is used as a gate: a penalty accrues only if a time delta exceeds a threshold, a cooldown blocks calls until a stored time passes, or a withdrawal proof is valid only if its timestamp is newer than a stored watermark. The bug is that the stored timestamp is writable by the party being gated, defaults to zero, or is snapshotted at a moment that collides with the event it must exclude. The gate then never fires, fires early, or rejects a legitimate event.

## Where it shows up
- A penalty accumulator computed as `block.number - max(lastRepay, coinAge.lastWithdrawRewards)` where `lastWithdrawRewards` is refreshed by the staker [E1](https://bugbountylibrary.com/r/sherlock%3A2023-02-union%3AH-3.md)
- Cooldown stored as `x += period` on a variable that defaults to 0, instead of `block.timestamp + period` [E3](https://bugbountylibrary.com/r/sherlock%3A2024-03-zivoe%3AM-4.md)
- `block.timestamp` snapshotted as a watermark with a strict `>` check on later proofs [E2](https://bugbountylibrary.com/r/cantina%3Aeigenlayer_mar2024%3A3.1.1.md)

## How to review
Identify every timestamp that gates value. For each, ask: who can write it, what is its default, and what event ordering does the comparison assume?
- Invariant: a user action must not be able to reset the clock that measures their own penalty or cooldown. The delta must be anchored to an event the user cannot trigger [E1](https://bugbountylibrary.com/r/sherlock%3A2023-02-union%3AH-3.md).
- Invariant: cooldown deadlines are absolute (`block.timestamp + period`), never relative increments on a possibly-zero base [E3](https://bugbountylibrary.com/r/sherlock%3A2024-03-zivoe%3AM-4.md).
- Invariant: a watermark compared with strict `>` must be set strictly before any event it must exclude; check same-block ordering, e.g. EIP-4895 beacon withdrawals executing after user transactions [E2](https://bugbountylibrary.com/r/cantina%3Aeigenlayer_mar2024%3A3.1.1.md).

## Variants seen
- Penalty dodged by refreshing a user-controlled timestamp each period, keeping the delta under threshold so the bad-debt penalty never accumulates [E1](https://bugbountylibrary.com/r/sherlock%3A2023-02-union%3AH-3.md)
- Watermark set to `block.timestamp` colliding with a same-block beacon withdrawal, making it unprovable [E2](https://bugbountylibrary.com/r/cantina%3Aeigenlayer_mar2024%3A3.1.1.md)
- Cooldown anchored to epoch 0 via `+=` on a zero default, bypassing the period [E3](https://bugbountylibrary.com/r/sherlock%3A2024-03-zivoe%3AM-4.md)

## Impact and severity
Rewards inflated and bad-debt penalties erased [E1](https://bugbountylibrary.com/r/sherlock%3A2023-02-union%3AH-3.md); user funds permanently lost [E2](https://bugbountylibrary.com/r/cantina%3Aeigenlayer_mar2024%3A3.1.1.md); cooldown bypass enabling premature yield forwarding [E3](https://bugbountylibrary.com/r/sherlock%3A2024-03-zivoe%3AM-4.md). Severity rises when the timestamp also feeds reward or penalty math, since the error compounds silently rather than reverting.

## Evidence
- E1: https://bugbountylibrary.com/r/sherlock%3A2023-02-union%3AH-3.md
- E2: https://bugbountylibrary.com/r/cantina%3Aeigenlayer_mar2024%3A3.1.1.md
- E3: https://bugbountylibrary.com/r/sherlock%3A2024-03-zivoe%3AM-4.md
