RebateFi Hook

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

_beforeInitialize Check Is Wrong (ReFi Can’t Be currency0)

Root + Impact

Description

Under normal behavior, the hook should allow initialization of any pool that contains the ReFi token in either currency0 or currency1.

However, the _beforeInitialize() function contains a duplicated condition that checks currency1 twice and never checks currency0. This causes the hook to reject all pools where ReFi is the first token in the pair.

This effectively forces ReFi to always be currency1, which is unintended and also guarantees that the buy/sell reversal bug (H-01) always triggers.

function _beforeInitialize(address, PoolKey calldata key, uint160) internal view override returns (bytes4) {
if (
Currency.unwrap(key.currency1) != ReFi &&
@> Currency.unwrap(key.currency1) != ReFi // BUG: duplicated check
) {
revert ReFiNotInPool();
}
return BaseHook.beforeInitialize.selector;
}

Risk

Likelihood:

  • This condition is triggered every time a pool is initialized.

  • Any pool where ReFi should be currency0 will always revert.

  • Developers cannot deploy pools with ReFi as token0 even if desired.

Impact:

  • Prevents valid pool deployments.

  • Forces a single hard-coded pool configuration.

  • Locks ReFi into currency1, amplifying the impact of the buy/sell reversal bug.

  • Potential DoS for integrations expecting flexible token ordering.

Proof of Concept

Below PoC demonstrates that initializing a pool where ReFi is currency0 always fails, even though the ReFi token is present.

PoolKey memory key;
// Attempt to create pair: ReFi (currency0) / USDC (currency1)
key.currency0 = Currency.wrap(ReFi);
key.currency1 = Currency.wrap(USDC);
// Call initialize
_beforeInitialize(address(0), key, 0);
// Expected: succeeds (ReFi is part of the pair)
// Actual: reverts with ReFiNotInPool()

This occurs because currency0 is never checked.

Recommended Mitigation

The check should validate both currencies, not just currency1 twice.

function _beforeInitialize(address, PoolKey calldata key, uint160) internal view override returns (bytes4) {
- if (Currency.unwrap(key.currency1) != ReFi &&
- Currency.unwrap(key.currency1) != ReFi) {
+ if (Currency.unwrap(key.currency0) != ReFi &&
+ Currency.unwrap(key.currency1) != ReFi) {
revert ReFiNotInPool();
}
return BaseHook.beforeInitialize.selector;
}
Updates

Lead Judging Commences

chaossr Lead Judge 8 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!