RebateFi Hook

First Flight #53
Beginner FriendlyDeFi
100 EXP
View results
Submission Details
Severity: high
Valid

Wrong check in _beforeInitialize

Description

  • In Uniswap v4, a hook’s beforeInitialize should validate that the target pool being initialized contains the designated ReFi token on either side of the pair (currency0 or currency1). If the token is present on at least one side, initialization should be allowed to proceed.

  • The current implementation checks the same side twice and never checks currency0. As a result, pool initialization reverts whenever ReFi is the token at currency0, causing a denial of service for valid pools.

// Root cause in the codebase with @> marks to highlight the relevant section
function _beforeInitialize(address, PoolKey calldata key, uint160) internal view override returns (bytes4) {
if (Currency.unwrap(key.currency1) != ReFi &&
@> Currency.unwrap(key.currency1) != ReFi) { // <-- duplicated check of currency1, currency0 never checked
revert ReFiNotInPool();
}
return BaseHook.beforeInitialize.selector;
}

Risk

Likelihood: High

  • Occurs whenever a new pool is initialized with ReFi set as currency0 (common, because token ordering depends on address sorting and deployer choice).

  • Triggers during standard deployment flows and test setups that happen to place ReFi on the currency0 side.

Impact: High

  • Prevents creation of valid pools (DoS) for the ReFi token when it is token0, blocking liquidity provisioning and swaps through those pools.

  • Forces operators to reorder tokens or redeploy, increasing operational risk and potential misconfiguration.

Proof of Concept

  • Under the current code, the hook only “passes” beforeInitialize when ReFi is currency1; it always reverts for ReFi as currency0.

function test_BeforeInitializeRevertsWhenReFiIsCurrency0() public {
// Arrange: set up currencies so that ReFi is currency0
Currency reFiCurrency = Currency.wrap(address(reFiToken));
Currency otherCurrency = Currency.wrap(address(token)); // any ERC20
// Act + Assert: init with ReFi as currency0 should revert due to wrong check
vm.expectRevert(ReFiSwapRebateHook.ReFiNotInPool.selector);
(PoolKey memory localKey, ) = initPool(
reFiCurrency, // <-- currency0 = ReFi
otherCurrency, // <-- currency1 = other with the address more than currency1
rebateHook,
LPFeeLibrary.DYNAMIC_FEE_FLAG,
SQRT_PRICE_1_1_s
);
// Note: the same code succeeds when ReFi is currency1
}

Recommended Mitigation

  • Replace the duplicated currency1 check with a currency0:

- if (Currency.unwrap(key.currency1) != ReFi &&
- Currency.unwrap(key.currency1) != ReFi) {
- revert ReFiNotInPool();
- }
+ if (
+ Currency.unwrap(key.currency0) != ReFi &&
+ Currency.unwrap(key.currency1) != ReFi
+ ) {
+ revert ReFiNotInPool();
+ }
Updates

Lead Judging Commences

chaossr Lead Judge 12 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Faulty pool check; only checks currency1 twice, omitting currency0.

Support

FAQs

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

Give us feedback!