V4HOOKSCUT SHEET DIRECTORY

Index / ReHypothecationHook

pattern · MIT · last updated 2026-08-27

ReHypothecationHook

Park idle LP in yield sources, JIT a hook-owned position on beforeSwap, unwind afterSwap.

OpenZeppelin’s ReHypothecationHook (MIT) parks idle LP in external yield sources (ERC-4626 or lending) and JIT-injects a hook-owned full-range position on beforeSwap, then unwinds it on afterSwap and settles PoolManager deltas back to the vaults. Users mint and redeem the hook’s ERC20 via addReHypothecatedLiquidity; they do not add liquidity through PoolManager. beforeInitialize binds a single PoolKey. You implement getCurrencyYieldSource and the deposit or withdraw adapters. Experimental: yield-source risk, PoolManager reserve timing, and leveraged liquidity notes are in the file. Copy the full file. Listing is not an audit.

Permission bits

These bits must match the deployed address. Confirm on-chain before you route.

Initialize
ba
Liquidity
baba
Swap
ba
Donate
ba
Return delta
baaa

beforeInitializebeforeSwapafterSwap

Solidity

Excerpt from src/general/ReHypothecationHook.sol. Copy the full file to implement this. Not an audit.

// SPDX-License-Identifier: MIT
// OpenZeppelin Uniswap Hooks — excerpt. Full file: source.url
function getHookPermissions() public pure virtual override returns (Hooks.Permissions memory permissions) {
    return Hooks.Permissions({
        beforeInitialize: true,
        afterInitialize: false,
        beforeAddLiquidity: false,
        afterAddLiquidity: false,
        beforeRemoveLiquidity: false,
        afterRemoveLiquidity: false,
        beforeSwap: true,
        afterSwap: true,
        beforeDonate: false,
        afterDonate: false,
        beforeSwapReturnDelta: false,
        afterSwapReturnDelta: false,
        afterAddLiquidityReturnDelta: false,
        afterRemoveLiquidityReturnDelta: false
    });
}

function _beforeSwap(address, PoolKey calldata, SwapParams calldata, bytes calldata)
    internal
    virtual
    override
    returns (bytes4, BeforeSwapDelta, uint24)
{
    uint256 liquidityToUse = _getLiquidityToUse();
    if (liquidityToUse > 0) _modifyLiquidity(liquidityToUse.toInt256());
    return (this.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0);
}

function _afterSwap(address, PoolKey calldata key, SwapParams calldata, BalanceDelta, bytes calldata)
    internal
    virtual
    override
    returns (bytes4, int128)
{
    uint128 liquidity = _getHookPositionLiquidity();
    if (liquidity > 0) {
        _modifyLiquidity(-liquidity.toInt256());
        _resolveHookDelta(key.currency0);
        _resolveHookDelta(key.currency1);
    }
    return (this.afterSwap.selector, 0);
}

Spec

Kindpattern
Statusexperimental
LicenseMIT
Sourcehttps://github.com/OpenZeppelin/uniswap-hooks
CategoriesLendingLP management
PropertiesVanilla swap
ChainsEthereum
Websitehttps://v4hooks.com/learn/openzeppelin-hooks
Docshttps://github.com/OpenZeppelin/uniswap-hooks

FAQ

Can I paste this into production? The snippet is an excerpt. Use the full file at the source URL, match flags to the address, and treat this page as a map, not a guarantee.

How do I build this safely? Start with secure v4 hooks and the OpenZeppelin hooks guide.