RebateFi Hook

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

Negation overflow on INT256_MIN in _beforeSwap

Description

  • _beforeSwap() should safely derive a non‑negative swapAmount from SwapParams.amountSpecified by taking its absolute value. This value is then used for fee selection and event emission without causing unexpected reverts.

  • The code computes swapAmount using unary negation for negative inputs. Negating type(int256).min (i.e., INT256_MIN = -2^255) overflows in Solidity 0.8+ and reverts with a panic error before the swap proceeds. A router or integrator that (intentionally or accidentally) passes amountSpecified == INT256_MIN will cause _beforeSwap to revert immediately.

// Root cause in the codebase with @> marks to highlight the relevant section
function _beforeSwap(
address sender,
PoolKey calldata key,
SwapParams calldata params,
bytes calldata
) internal override returns (bytes4, BeforeSwapDelta, uint24) {
@> uint256 swapAmount = params.amountSpecified < 0
@> ? uint256(-params.amountSpecified) // <-- negation overflows for INT256_MIN
@> : uint256(params.amountSpecified);
// ...
}

Risk

Likelihood: Low

  • Occurs whenever an integrator or test harness supplies amountSpecified == type(int256).min. This may surface in fuzzing, adversarial inputs, or poorly validated custom routers.

  • While standard Uniswap routers are unlikely to set this exact value, the hook should be robust against such inputs.

Impact: Low

  • Unexpected revert / DoS path: The hook reverts before Uniswap’s pool logic runs, causing swap failures and potentially blocking certain test or integration scenarios.

  • Reduced resilience: Fuzzing and adversarial testing will hit this edge case, undermining reliability until addressed.

Proof of Concept

  • Add this test to TestReFiSwapRebateHook to demonstrate the revert caused by negating INT256_MIN:

function test_Int256MinNegationOverflowReverts() public {
int256 minAmount = type(int256).min;
SwapParams memory params = SwapParams({
zeroForOne: true,
amountSpecified: minAmount, // <-- INT256_MIN
sqrtPriceLimitX96: TickMath.MIN_SQRT_PRICE + 1
});
PoolSwapTest.TestSettings memory testSettings =
PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false});
// Arithmetic overflow triggers a Panic(0x11) under Solidity 0.8's checked math.
vm.expectRevert();
// This will revert in hook's _beforeSwap before reaching pool math.
swapRouter.swap(key, params, testSettings, ZERO_BYTES);
}

Recommended Mitigation

  • Add guard against INT256_MIN

- uint256 swapAmount = params.amountSpecified < 0
- ? uint256(-params.amountSpecified)
- : uint256(params.amountSpecified);
+ // Option A: explicit guard (simplest)
+ require(params.amountSpecified != type(int256).min, "invalid amount");
+ uint256 swapAmount = params.amountSpecified < 0
+ ? uint256(-params.amountSpecified)
+ : uint256(params.amountSpecified);
Updates

Lead Judging Commences

chaossr Lead Judge
13 days ago
chaossr Lead Judge 12 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!