Vanguard

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

Phase Reset Does Not Reset Users, Causing Unfair Penalties

Author Revealed upon completion

Description

When phases transition, users should get fresh swap limits to ensure fair trading conditions.

The _resetPerAddressTracking() function only resets address(0) instead of actual users. Phase 1 swapped amounts carry over to Phase 2, causing users to pay unfair penalties.

function _resetPerAddressTracking() internal {
addressSwappedAmount[address(0)] = 0; // @> Only resets address(0)!
addressLastSwapBlock[address(0)] = 0; // @> Real users never reset
}
function _beforeSwap(...) {
// Line 146-149: Called during phase transitions
if (newPhase != currentPhase) {
_resetPerAddressTracking(); // @> Only resets address(0)
currentPhase = newPhase;
lastPhaseUpdateBlock = block.number;
}
}

Risk

Likelihood:

  • Affects every user who swapped in Phase 1 when Phase 2 starts

  • Guaranteed to happen on every phase transition

Impact:

  • Users' Phase 1 amounts carry over to Phase 2 unfairly

  • If Phase 1 amount > Phase 2 limit, users pay penalties on EVERY Phase 2 swap

  • Worst case: User cannot trade in Phase 2 without constant penalties

  • Breaks core design where each phase should give fresh limits

Proof of Concept

Run: forge test --mt test_PhaseResetCausesUnfairPenalties -vv

Test shows user swaps 0.3 ETH in Phase 1, then in Phase 2 (limit 0.1 ETH), even tiny swaps trigger penalties because 0.3 ETH > 0.1 ETH.

Recommended Mitigation

Use epoch-based tracking:

+ uint256 public currentEpoch;
- mapping(address => uint256) public addressSwappedAmount;
+ mapping(address => mapping(uint256 => uint256)) public addressSwappedAmount;
function _resetPerAddressTracking() internal {
- addressSwappedAmount[address(0)] = 0;
+ currentEpoch++; // Invalidate all old data
}
function _beforeSwap(...) {
- if (addressSwappedAmount[sender] + swapAmount > maxSwapAmount) {
+ if (addressSwappedAmount[sender][currentEpoch] + swapAmount > maxSwapAmount) {
applyPenalty = true;
}
- addressSwappedAmount[sender] += swapAmount;
+ addressSwappedAmount[sender][currentEpoch] += swapAmount;
}

Support

FAQs

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

Give us feedback!