# Phase boundary overlap and unit mismatch

Inclusive comparisons on both sides of one boundary, or deadlines anchored to the wrong block or unit

_Area: Smart contract access control and control flow. Seen in 2 disclosed reports; latest 2024-01-08. Updated 2026-10-23._

## How it works
Two code paths gate on the same boundary value (a timestamp, a block height, a cached update time) but disagree about which side they own. When both comparisons are inclusive (`<=` on one path, `>=` on the other), the boundary instant is valid for both phases at once, so state can change after the closing phase has already run. A related break: a deadline is anchored to the transaction's own block or a raw number in the wrong unit, so the clock starts at the wrong moment and the honest window shrinks or the guard misfires.

## Where it shows up
- Paired functions using `<=` and `>=` against the same end/deadline variable [E1](https://bugbountylibrary.com/r/c4%3A2023-10-nextgen%3AM-10.md)
- `participateToAuction()` accepts bids at `block.timestamp <= auctionEndTime` while `claimAuction()` settles at `>= auctionEndTime`, and `auctionClaim` is not checked on the bid path [E1](https://bugbountylibrary.com/r/c4%3A2023-10-nextgen%3AM-10.md)
- Session or deadline computed from the submitter's `block.number` rather than the target block's own time; here the unit is block height, not timestamp [E2](https://bugbountylibrary.com/r/sherlock%3A2023-11-covalent%3AM-8.md)
- Accumulators that re-sum from zero each call, guarded by a cached timestamp that can be in the future [E3](https://bugbountylibrary.com/r/cantina%3Aopal_feb2024%3A3.2.14.md)

## How to review
The invariant: for every boundary value, exactly one phase is valid at that instant, and the closing phase leaves state that the opening phase rejects. Check that open and close use complementary comparisons (strict on one side), and that close sets a terminal flag the open path tests. For deadlines, confirm the anchor is the target's own timestamp/height, not the caller's block, and that the unit matches. For accumulators, confirm the guard cannot skip summation while sibling mappings retain values.

## Variants seen
- Bid accepted at exact end timestamp after settlement, funds trapped [E1](https://bugbountylibrary.com/r/c4%3A2023-10-nextgen%3AM-10.md)
- Future-height submission pre-starts session, halving honest window [E2](https://bugbountylibrary.com/r/sherlock%3A2023-11-covalent%3AM-8.md)
- Future `lastUpdate` skips vote summation, total reads 0 while sibling mappings keep values [E3](https://bugbountylibrary.com/r/cantina%3Aopal_feb2024%3A3.2.14.md)

## Impact and severity
Trapped user funds with no refund path [E1](https://bugbountylibrary.com/r/c4%3A2023-10-nextgen%3AM-10.md), shortened honest participation windows [E2](https://bugbountylibrary.com/r/sherlock%3A2023-11-covalent%3AM-8.md), and wrong accounting in vote totals [E3](https://bugbountylibrary.com/r/cantina%3Aopal_feb2024%3A3.2.14.md). Severity rises when no cancel/refund path exists after the boundary [E1](https://bugbountylibrary.com/r/c4%3A2023-10-nextgen%3AM-10.md) and when the wrong value feeds downstream totals or governance weights [E3](https://bugbountylibrary.com/r/cantina%3Aopal_feb2024%3A3.2.14.md).

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2023-10-nextgen%3AM-10.md
- E2: https://bugbountylibrary.com/r/sherlock%3A2023-11-covalent%3AM-8.md
- E3: https://bugbountylibrary.com/r/cantina%3Aopal_feb2024%3A3.2.14.md
