_beforeSwap() and getCurrentPhase() use different comparison operators (<= vs <), causing view functions to return different phase than actual execution.
Location: src/TokenLaunchHook.sol:139-145 vs src/TokenLaunchHook.sol:196-203
At exact boundary (blocksSinceLaunch == phase1Duration):
_beforeSwap → Phase 1
getCurrentPhase → Phase 2
Likelihood:
Occurs at every phase boundary block (2 times per launch: Phase1->Phase2, Phase2->Phase3)
Users querying state exactly at boundary will see incorrect phase
Frontend/UI displaying phase info will be wrong for one block
Impact:
Users see incorrect phase in frontend (Phase 2 when actually Phase 1)
getUserRemainingLimit() returns wrong values at boundaries
getUserCooldownEnd() uses wrong cooldown at boundaries
Confusing UX and potential for unexpected penalties
Users may time swaps incorrectly based on displayed phase
At the exact phase boundary block where blocksSinceLaunch == phase1Duration, the view function returns Phase 2 while execution uses Phase 1.
Standardize to use <= everywhere (or < everywhere):
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.