Component
Pool Interaction, Hooks
Describe the suggested feature and problem it solves
Any router or aggregator that integrates v4 has to answer a question the protocol deliberately leaves open: which hooks is this integrator willing to route user funds through?
Two properties make that decision harder than a simple allowlist:
- Delta-returning hooks change the accounting. A hook carrying
BEFORE_SWAP_RETURNS_DELTA_FLAG or AFTER_SWAP_RETURNS_DELTA_FLAG can alter the amounts the swap settles. That is a feature, and it is also a materially different trust decision from routing through a hook that only observes.
- Code reviewed at admission is not necessarily code executed at swap time. A hook behind a proxy, or one redeployed at the same address, can be reviewed as benign and later behave differently. An address-keyed allowlist alone does not survive that.
Today each integrator solves this privately, or does not solve it at all. There is no small, shared reference pattern for the routing side of hook safety, and the cost of getting it wrong lands on end users rather than on the integrator.
We built one while integrating v4 into our own aggregator, and it seems more useful shared than kept: hook-safety-gate — a standalone, default-closed admission gate. MIT, zero external dependencies, 38 tests at 768 fuzz runs.
Describe the desired implementation
The gate is three layers plus a timelocked path, and integrates in one line:
if (!IHookSafetyGate(GATE).isRoutableHook(address(key.hooks))) revert UnsafeHook();
Layer 1 — delta-permission screen. The permission bits live in the hook's own address, so the screen is pure arithmetic on a bitmask: constant time, no external call, and nothing the hook can misreport.
Layer 2 — default-closed allowlist. Nothing routes unless it was explicitly admitted.
Layer 3 — codehash pinning. EXTCODEHASH is recorded at admission and re-checked at routing time, so a hook whose code changes after review stops being routable rather than silently continuing.
Delta hooks take a two-step timelocked path. proposeDeltaHook opens a public review window and records the codehash; confirmDeltaHook only succeeds after the delay and only if the code has not changed in between, which closes the bait-and-switch between proposal and confirmation. Non-delta hooks are admitted directly.
Additional context
The honest limitation, stated first: this is a permissioned gate. Admission is an owner decision, which makes it a tool for an integrator to express its own risk policy — not a protocol-level or trustless mechanism, and not something that belongs anywhere near core. We think that is the correct scope for the problem: the router is the party choosing to route, so the router is the party that should carry the policy. But it does mean the design is only as good as the admitting party, and we would rather say so than have it read as more than it is.
Three ways this could be useful, and we are genuinely fine with any of them, including the last:
- As a periphery reference or example for integrators, in whatever form you would want it — we would happily rewrite it to your conventions and open a PR.
- As documentation only — the pattern written up in the hooks docs, with no code adopted at all.
- Not at all, if you think delta-permission screening does not belong on the routing side. That answer is useful to us too, and we would like to hear the reasoning.
What would be most valuable either way: whether you consider the address-bitmask screen a sound thing for integrators to rely on long term, or whether hook permissions are expected to evolve in a way that would make it brittle.
Component
Pool Interaction, Hooks
Describe the suggested feature and problem it solves
Any router or aggregator that integrates v4 has to answer a question the protocol deliberately leaves open: which hooks is this integrator willing to route user funds through?
Two properties make that decision harder than a simple allowlist:
BEFORE_SWAP_RETURNS_DELTA_FLAGorAFTER_SWAP_RETURNS_DELTA_FLAGcan alter the amounts the swap settles. That is a feature, and it is also a materially different trust decision from routing through a hook that only observes.Today each integrator solves this privately, or does not solve it at all. There is no small, shared reference pattern for the routing side of hook safety, and the cost of getting it wrong lands on end users rather than on the integrator.
We built one while integrating v4 into our own aggregator, and it seems more useful shared than kept: hook-safety-gate — a standalone, default-closed admission gate. MIT, zero external dependencies, 38 tests at 768 fuzz runs.
Describe the desired implementation
The gate is three layers plus a timelocked path, and integrates in one line:
Layer 1 — delta-permission screen. The permission bits live in the hook's own address, so the screen is pure arithmetic on a bitmask: constant time, no external call, and nothing the hook can misreport.
Layer 2 — default-closed allowlist. Nothing routes unless it was explicitly admitted.
Layer 3 — codehash pinning.
EXTCODEHASHis recorded at admission and re-checked at routing time, so a hook whose code changes after review stops being routable rather than silently continuing.Delta hooks take a two-step timelocked path.
proposeDeltaHookopens a public review window and records the codehash;confirmDeltaHookonly succeeds after the delay and only if the code has not changed in between, which closes the bait-and-switch between proposal and confirmation. Non-delta hooks are admitted directly.Additional context
The honest limitation, stated first: this is a permissioned gate. Admission is an owner decision, which makes it a tool for an integrator to express its own risk policy — not a protocol-level or trustless mechanism, and not something that belongs anywhere near core. We think that is the correct scope for the problem: the router is the party choosing to route, so the router is the party that should carry the policy. But it does mean the design is only as good as the admitting party, and we would rather say so than have it read as more than it is.
Three ways this could be useful, and we are genuinely fine with any of them, including the last:
What would be most valuable either way: whether you consider the address-bitmask screen a sound thing for integrators to rely on long term, or whether hook permissions are expected to evolve in a way that would make it brittle.