V4HOOKSCUT SHEET DIRECTORY

Index / LpRewards

pattern · MIT · last updated 2026-08-27

LpRewards

Pull buy-side token rewards, then flush() donates pending balance to in-range LPs.

First-party teaching hook inspired by Spark LP Rewards. Spark routes an ETH-side buy cut; this version takes rewardBps of token output on exact-input buys (same afterSwapReturnDelta path as AutoBurn) into pending[poolId], then flush() unlocks and calls poolManager.donate + settle so feeGrowthGlobal rises for LPs. Deferred donate avoids NoLiquidityToReceiveFees when a large buy walks price out of range mid-callback. Contrast liquidity-penalty.yml (donate on JIT remove). Experimental. Forge tests in test/LpRewards.t.sol. 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

afterInitializeafterSwapafterSwapReturnDelta

Solidity

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

// SPDX-License-Identifier: MIT
// v4hooks first-party — excerpt. Full file: source.url
function _afterSwap(address, PoolKey calldata key, SwapParams calldata params, BalanceDelta delta, bytes calldata)
    internal
    override
    returns (bytes4, int128)
{
    if (!params.zeroForOne || params.amountSpecified >= 0) return (this.afterSwap.selector, 0);
    uint256 reward = (uint256(int256(delta.amount1())) * rewardBps) / 10_000;
    if (reward == 0) return (this.afterSwap.selector, 0);
    key.currency1.take(poolManager, address(this), reward, false);
    pending[key.toId()] += reward;
    return (this.afterSwap.selector, reward.toInt128());
}

function flush(PoolKey calldata key) external {
    poolManager.unlock(abi.encode(key));
}

Spec

Kindpattern
Statusexperimental
LicenseMIT
Sourcehttps://github.com/CryptoGnome/v4hooks
CategoriesLaunchpadsLP management
PropertiesVanilla swap
ChainsEthereum

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.