V4HOOKSCUT SHEET DIRECTORY

Index / Geomean oracle

pattern · UNLICENSED · last updated 2026-08-27

Geomean oracle

Write a geometric-mean observation before any action that can move price or liquidity.

The Uniswap GeomeanOracle example allows one oracle pool per pair (fee 0, max tick spacing). afterInitialize seeds the observation cardinality. beforeAddLiquidity forces full-range positions and writes a sample. beforeRemoveLiquidity always reverts so liquidity stays locked. beforeSwap updates the oracle then lets the swap proceed. Read observe() offchain or from another contract. UNLICENSED example — copy the full file including the Oracle library. 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

beforeInitializeafterInitializebeforeAddLiquiditybeforeRemoveLiquiditybeforeSwap

Solidity

Excerpt from contracts/hooks/examples/GeomeanOracle.sol. Copy the full file to implement this. Not an audit.

// SPDX-License-Identifier: UNLICENSED
function getHookPermissions() public pure override returns (Hooks.Permissions memory) {
    return Hooks.Permissions({
        beforeInitialize: true,
        afterInitialize: true,
        beforeAddLiquidity: true,
        beforeRemoveLiquidity: true,
        afterAddLiquidity: false,
        afterRemoveLiquidity: false,
        beforeSwap: true,
        afterSwap: false,
        beforeDonate: false,
        afterDonate: false,
        beforeSwapReturnDelta: false,
        afterSwapReturnDelta: false,
        afterAddLiquidityReturnDelta: false,
        afterRemoveLiquidityReturnDelta: false
    });
}

function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata, bytes calldata)
    external
    override
    onlyByManager
    returns (bytes4, BeforeSwapDelta, uint24)
{
    _updatePool(key);
    return (GeomeanOracle.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0);
}

function beforeRemoveLiquidity(address, PoolKey calldata, IPoolManager.ModifyLiquidityParams calldata, bytes calldata)
    external
    view
    override
    onlyByManager
    returns (bytes4)
{
    revert OraclePoolMustLockLiquidity();
}

Spec

Kindpattern
Statusexperimental
LicenseUNLICENSED
Sourcehttps://github.com/Uniswap/v4-periphery
CategoriesOracles
PropertiesVanilla swap
ChainsEthereum
Docshttps://docs.uniswap.org/contracts/v4/concepts/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.