There is a logic discrepancy between the view function getCurrentPhase() and the core enforcement logic in _beforeSwap()
Likelihood:
The logical inconsistency occurs specifically at two transition points: when blocksSinceLaunch == phase1Duration and when blocksSinceLaunch == phase1Duration + phase2Duration.
Crucially, this error propagates beyond just the phase display. Since both getUserRemainingLimit and getUserCooldownEnd internally call getCurrentPhase(), these functions will also return incorrect data to the frontend or external callers during those specific blocks.
Impact:
During transition blocks, getCurrentPhase and dependent functions (getUserRemainingLimit, getUserCooldownEnd) incorrectly report relaxed restrictions. Users acting on this misleading data face unexpected reverts or higher fees, as the contract strictly enforces the previous phase's tighter limits.
Advance the blockchain to the exact block where block.number == launchStartBlock + phase1Duration.
Call getCurrentPhase(). It returns 2, indicating Phase 2 has started.
Observe that _beforeSwap still enforces Phase
Simply changing the comparison operator in the getCurrentPhase function's conditional statement from < to <= will suffice.
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.