RebateFi Hook

First Flight #53
Beginner FriendlyDeFi
100 EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

[M-2] Potential integer overflow in fee calculation for large swap amounts

[M-2] Potential integer overflow in fee calculation for large swap amounts

Root + Impact

Description

The fee calculation in _beforeSwap() multiplies two uint values without overflow protection. While Solidity 0.8+ has built-in overflow checks that will cause reverts, the multiplication of swapAmount (uint256) by sellFee (uint24) can overflow for extremely large swap amounts.

When an overflow occurs, the transaction will revert instead of calculating the fee, preventing legitimate large swaps from executing.

function _beforeSwap(...) internal override returns (bytes4, BeforeSwapDelta, uint24) {
// ...
uint256 swapAmount = params.amountSpecified < 0
? uint256(-params.amountSpecified)
: uint256(params.amountSpecified);
// ...
} else {
fee = sellFee;
@> uint256 feeAmount = (swapAmount * sellFee) / 100000; // @audit can overflow
emit ReFiSold(sender, swapAmount, feeAmount);
}
// ...
}

Risk

Likelihood:

  • Large swaps approaching type(uint256).max / sellFee will trigger overflow

  • For sellFee = 3000, overflow occurs when swapAmount > type(uint256).max / 3000

  • This equals approximately 3.88 × 10^73 tokens, which is unlikely for normal tokens but possible for tokens with very high decimals or large total supplies

Impact:

  • Legitimate large swaps will revert due to overflow

  • Prevents whales or large traders from using the protocol

  • Could be exploited to grief large liquidity operations

  • Limits the protocol's ability to handle high-value transactions

  • Creates an artificial ceiling on swap sizes

Proof of Concept

function test_FeeCalculationOverflow() public {
// Calculate maximum safe swap amount
uint256 maxSafeSwap = type(uint256).max / 3000;
// Attempt swap just above the safe threshold
uint256 overflowSwap = maxSafeSwap + 1;
SwapParams memory params = SwapParams({
zeroForOne: false,
amountSpecified: -int256(overflowSwap),
sqrtPriceLimitX96: MAX_PRICE_LIMIT
});
// This will revert with arithmetic overflow
vm.expectRevert();
vm.prank(swapper);
swap(key, params, ZERO_BYTES);
// Demonstrate the overflow in isolation
vm.expectRevert(); // Arithmetic overflow
uint256 feeAmount = (overflowSwap * 3000) / 100000;
}

Recommended Mitigation

+import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
function _beforeSwap(...) internal override returns (bytes4, BeforeSwapDelta, uint24) {
// ...
} else {
fee = sellFee;
- uint256 feeAmount = (swapAmount * sellFee) / 100000;
+ uint256 feeAmount = Math.mulDiv(swapAmount, uint256(sellFee), 1000000);
emit ReFiSold(sender, swapAmount, feeAmount);
}
// ...
}
Updates

Lead Judging Commences

chaossr Lead Judge
12 days ago
chaossr Lead Judge 11 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!