Skip to content

feat: Add BatchDistributeHook — Spraay multi-recipient batch distribution - #95

Open
plagtech wants to merge 1 commit into
Uniswap:mainfrom
plagtech:feat/batch-distribute-hook
Open

plagtech wants to merge 1 commit into
Uniswap:mainfrom
plagtech:feat/batch-distribute-hook

Conversation

@plagtech

Copy link
Copy Markdown

feat: Add BatchDistributeHook — Spraay multi-recipient batch distribution

What it does

BatchDistributeHook lets a pool's operators push ERC-20 or native tokens to up to 200 recipients in one transaction, routed through Spraay's on-chain batch contract. V4's own incentive paths (LP fees, donate()) are pull-based and only reach in-range LPs; this adds a push path to any address (contributors, market makers, airdrops, revenue shares) with no claim step for recipients.

How it works

  • Built on OpenZeppelin BaseHook, matching this template's stack (uniswap-hooks + hookmate).
  • Permissions: afterInitialize (registers pools created with the hook, so every distribution is attributed to a real PoolId) and afterDonate (emits PoolDonation so indexers see pull-side and push-side incentives together). Neither returns a delta; swaps and liquidity are unaffected. Hook address flags: 0x…1010.
  • Distributions don't touch PoolManager accounting. The hook is non-custodial: each call pulls exactly amount + Spraay fee from the operator, approves Spraay for exactly that, and calls sprayToken / sprayETH / sprayEqual in the same tx. Excess native currency is refunded.
  • Roles: Ownable2Step owner (operators, Spraay address, rescue) and operators (trigger + fund distributions).
  • Spraay fee: 30 bps on top, read on-chain via calculateTotalCost.

Gas (ERC-20, fresh recipients, execution gas incl. 21k base)

Recipients Hook (1 tx) Minimal loop contract N separate transfers Hook vs. N transfers
5 316,347 185,812 361,340 −12%
50 1,584,308 1,380,385 3,614,000 −56%
100 2,993,781 2,707,667 7,228,000 −59%
200 5,814,984 5,362,392 14,456,000 −60%

A bare loop contract is 8–15% cheaper; the hook adds non-custodial funding, roles, native support with refunds, and pool attribution. Reproduce: forge test --match-contract BatchDistributeHookGasTest -vv.

Tests

  • 38 unit tests: all three Spraay paths, 1/5/50/200 recipients, 201 revert, fee math, access control, two-step ownership, address-flag validation, and a real add-liquidity → donate → settle round trip through PoolManager.
  • Fork tests against the live V4 PoolManager + Spraay on Base and BNB Chain (BASE_RPC_URL / BSC_RPC_URL).
  • Deploy script mines the CREATE2 salt with HookMiner and prints the verify command.

Chain support

Base and BNB Chain (where Spraay and the V4 PoolManager are both live).

Links

…tion

Example hook: operators push-distribute ERC-20 or native tokens to up to 200
recipients per call through Spraay. afterInitialize registers pools,
afterDonate emits PoolDonation for indexing; no deltas, swaps unaffected.

Includes unit tests (incl. initialize/donate/settle round trip), Base + BNB
fork tests, gas comparison, and a HookMiner-based deploy script.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant