RebateFi Hook

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

It is not possible to set `ReFi` token as currency0 in any pool because of wrong check

Root + Impact

Description

  • The hook ReFiSwapRebateHook::_beforeInitialize validates that ReFi token is in the pool before initialization but checks only currency1 and reverts if currency1 is not ReFi token

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

Risk

Likelihood:

  • The issue occurs while attempt to initialize a pool with currency0 == ReFi token.

Impact:

  • It is not possible to initialize a pool with ReFi token as currency0 because the code will revert.

Proof of Concept

Add the following contract HookWrapper and a test to TestReFiSwapRebateHook.sol:

contract HookWrapper is ReFiSwapRebateHook {
constructor(IPoolManager _poolManager, address _ReFi) ReFiSwapRebateHook(_poolManager, _ReFi) {}
function beforeInitialize(PoolKey calldata key) external view returns (bytes4) {
return _beforeInitialize(address(0), key, 0);
}
}
function test_ReFiNotInPool() public {
// deploy hook wrapper
bytes memory creationCode1 = type(HookWrapper).creationCode;
bytes memory constructorArgs1 = abi.encode(manager, address(reFiToken));
uint160 flags1 = uint160(Hooks.BEFORE_INITIALIZE_FLAG | Hooks.AFTER_INITIALIZE_FLAG | Hooks.BEFORE_SWAP_FLAG);
(, bytes32 salt1) = HookMiner.find(address(this), flags1, creationCode1, constructorArgs1);
hookWrapper = new HookWrapper{salt: salt1}(manager, address(reFiToken));
// ReFi is currency0 -> revert with ReFiNotInPool
Currency someCurrency = Currency.wrap(0x212224d2F2d262cd093EE13240cA4873FccbbA3d);
PoolKey memory key = PoolKey(reFiCurrency, someCurrency, LPFeeLibrary.DYNAMIC_FEE_FLAG, 60, rebateHook);
vm.expectRevert(ReFiSwapRebateHook.ReFiNotInPool.selector);
hookWrapper.beforeInitialize(key);
}

Recommended Mitigation

Allow to check the currency0 on ReFi token:

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 11 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!