Vanguard

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

Inaccurate phase calculation inside getCurrentPhase()

Author Revealed upon completion

Inaccurate phase calculation inside getCurrentPhase()

Description

During calculation to determine the user phase inside getCurrentPhase() on TokenLaunchHook.sol contract, inaccuracy calculation during phase transition.

function getCurrentPhase() public view returns (uint256) {
if (launchStartBlock == 0) return 0;
uint256 blocksSinceLaunch = block.number - launchStartBlock;
if (blocksSinceLaunch < phase1Duration) { // <@ less 1 block here
return 1;
} else if (blocksSinceLaunch < phase1Duration + phase2Duration) { // <@ less 1 block here
return 2;
} else {
return 3;
}
}

Risk

Minimal risk as it is only used for getter function
Inaccuracy information from getter function

Likelihood:

  • It will always occurs whenever protocol is using current code

Impact:

  • Inaccuracy information from getter function

Proof of Concept

Add bellow function into existing test suite TokenLaunchHook.t.sol
Run test suite with forge test --match-test test_PhaseCalculation -vvv

function test_PhaseCalculation1() public {
assertEq(antiBotHook.getCurrentPhase(), 1, "Should start in phase 1");
vm.roll(block.number + phase1Duration);
console.log("Current phase should be 1, but instead getPhase ", antiBotHook.getCurrentPhase());
assertEq(antiBotHook.getCurrentPhase(), 1, "Should still in phase 1");
}
function test_PhaseCalculation2() public {
assertEq(antiBotHook.getCurrentPhase(), 1, "Should start in phase 1");
vm.roll(block.number + phase1Duration + phase2Duration);
console.log("Current phase should be still 2, but instead getPhase ", antiBotHook.getCurrentPhase());
assertEq(antiBotHook.getCurrentPhase(), 2, "Should be in phase 2");
}

Log output :

Suite result: FAILED. 0 passed; 2 failed; 0 skipped; finished in 13.78ms (424.21µs CPU time)
Ran 1 test suite in 367.03ms (13.78ms CPU time): 0 tests passed, 2 failed, 0 skipped (2 total tests)
Failing tests:
Encountered 2 failing tests in test/TokenLaunchHookUnit.t.sol:TestTokenLaunchHook
[FAIL: Should still in phase 1: 2 != 1] test_PhaseCalculation1() (gas: 20719)
[FAIL: Should be in phase 2: 3 != 2] test_PhaseCalculation2() (gas: 22874)

Recommended Mitigation

Add = sign on the root cause of the code

function getCurrentPhase() public view returns (uint256) {
if (launchStartBlock == 0) return 0;
uint256 blocksSinceLaunch = block.number - launchStartBlock;
- if (blocksSinceLaunch < phase1Duration) {
+ if (blocksSinceLaunch <= phase1Duration) {
return 1;
- } else if (blocksSinceLaunch < phase1Duration + phase2Duration) {
+ } else if (blocksSinceLaunch <= phase1Duration + phase2Duration) {
return 2;
} else {
return 3;
}
}

Support

FAQs

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

Give us feedback!