Vanguard

First Flight #56
Beginner FriendlyDeFiFoundry
0 EXP
Submission Details
Impact: low
Likelihood: low

View Function Miscalculates Phase 0

Author Revealed upon completion

Root + Impact

Description

The getUserRemainingLimit view function uses an incomplete conditional check that defaults to Phase 2 parameters when getCurrentPhase() returns 0 (pre-launch phase). Phase 0 occurs when launchStartBlock is 0 or before any blocks have passed since initialization. Users querying their swap limits during Phase 0 will incorrectly see the Phase 2 limit (20% of initialLiquidity), creating false expectations. Once the launch actually starts and enters Phase 1, the effective limit abruptly drops to the much smaller Phase 1 cap (1% of initialLiquidity).

// TokenLaunchHook.sol:210-220 (getUserRemainingLimit)
function getUserRemainingLimit(PoolKey calldata key, address user) external view returns (uint256) {
// ...
uint256 currentPhase = getCurrentPhase();
uint256 phaseLimit;
if (currentPhase == 1) {
phaseLimit = phase1Limit;
} else {
// BUG: Phase 0 falls through to Phase 2 logic (20% instead of 0)
phaseLimit = phase2Limit;
}
// ...
}
// TokenLaunchHook.sol:194
function getCurrentPhase() public view returns (uint256) {
if (launchStartBlock == 0) return 0; // Phase 0: Not started
// ...
}

Risk

Likelihood:

Low - Only affects pre-launch queries. Most users interact after launch begins.

Impact:

Low - UX confusion. Users see "20% limit" before launch, then hit "1% limit" after launch starts. No fund loss, but potential trust issues.

Proof of Concept

Below is just a comment about this minor bug

// There is no PoC, just UI/UX error the user feel weird

Recommended Mitigation

Explicitly handle Phase 0 by returning 0 or a specific indicator that the launch hasn't started yet.

uint256 phaseLimit;
if (currentPhase == 0) {
return 0; // Pre-launch: no swaps allowed yet
} else if (currentPhase == 1) {
phaseLimit = phase1Limit;
} else if (currentPhase == 2) {
phaseLimit = phase2Limit;
} else {
return type(uint256).max; // Phase 3: unlimited
}

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!