Vanguard

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

getCurrentPhase() Uses Different Comparison Operator Than _beforeSwap() - View Functions Report Wrong Phase at Boundaries

Author Revealed upon completion

Root + Impact

Description

Root + Impact

Description

The getCurrentPhase() view function and _beforeSwap() internal function use different comparison operators for phase boundary checks:

In _beforeSwap() (actual swap logic):

if (blocksSinceLaunch <= phase1Duration) { // @> Uses <=
newPhase = 1;
}

In getCurrentPhase() (view function):

if (blocksSinceLaunch < phase1Duration) { // @> Uses <
return 1;
}

At exactly blocksSinceLaunch == phase1Duration:

  • _beforeSwap(): phase1Duration <= phase1Duration → TRUE → Phase 1

  • getCurrentPhase(): phase1Duration < phase1Duration → FALSE → Phase 2

Risk

Impact: MEDIUM - Users and frontends querying getCurrentPhase() see Phase 2, but swaps execute with Phase 1 rules. getUserRemainingLimit() and getUserCooldownEnd() also return incorrect values at boundary blocks.

Likelihood: HIGH - This occurs deterministically at every phase transition boundary block.

Proof of Concept

function testPhaseBoundaryMismatch() public {
// Fast forward to exactly phase1Duration blocks
vm.roll(launchStartBlock + phase1Duration);
// Query view function
uint256 viewPhase = hook.getCurrentPhase();
// Returns: 2 (because 100 < 100 is FALSE)
// But _beforeSwap internally calculates:
// 100 <= 100 is TRUE, so newPhase = 1
// MISMATCH: View says Phase 2, Swap executes as Phase 1
// User sees Phase 2 limit (5%), tries to swap that amount
// Swap executes with Phase 1 limit (1%), gets penalized!
}

Recommended Mitigation

Align comparison operators - change view function to use <=:

function getCurrentPhase() public view returns (uint256) {
- if (blocksSinceLaunch < phase1Duration) {
+ if (blocksSinceLaunch <= phase1Duration) {
return 1;
}
}
  • Describe the normal behavior in one or more sentences

  • Explain the specific issue or problem in one or more sentences

// Root cause in the codebase with @> marks to highlight the relevant section

Risk

Likelihood:

  • Reason 1 // Describe WHEN this will occur (avoid using "if" statements)

  • Reason 2

Impact:

  • Impact 1

  • Impact 2

Proof of Concept

Recommended Mitigation

- remove this code
+ add this code

Support

FAQs

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

Give us feedback!