Skip to content

feat: owner-managed global default hooks on V2 MultiHookRouter#34

Closed
JhiNResH wants to merge 3 commits into
erc-8183:mainfrom
JhiNResH:feat/global-hook-defaults-v2
Closed

feat: owner-managed global default hooks on V2 MultiHookRouter#34
JhiNResH wants to merge 3 commits into
erc-8183:mainfrom
JhiNResH:feat/global-hook-defaults-v2

Conversation

@JhiNResH
Copy link
Copy Markdown

Rewritten on V2 per @ariessa's comment. Closes #28.

Summary

Extends the V2 per-selector, per-hook-data router with owner-managed global default hook lists that apply when a job has no per-job configuration for a given selector.

Resolution per (jobId, selector):

  • per-job list non-empty → use per-job (unchanged V2 behavior)
  • per-job list empty → fall back to global defaults
  • both empty → no-op

All V2 guarantees carry through for resolved lists regardless of source:

  • per-hook data dispatch via abi.encode(bytes[])
  • de-whitelist resilience (skipped, event emitted)
  • selector-completeness validation against IERC8183HookMetadata

Validation at FUND runs unconditionally — even when FUND has no resolved hooks — so a dependent hook declared on one selector without its counterpart globally is caught before value transfers begin.

Admin surface (onlyOwner)

  • configureGlobalHooks(selector, hooks) — replace per-selector list
  • batchConfigureGlobalHooks(selectors[], hooksPerSelector[][])
  • addGlobalHook(selector, hook)
  • removeGlobalHook(selector, hook)
  • reorderGlobalHooks(selector, hooks)

Views: getGlobalHooks, globalHookCount, resolveHooks.

Events

GlobalHooksConfigured, GlobalHookAdded, GlobalHookRemoved, GlobalHooksReordered.

Tests

23 new tests in test/MultiHookRouterGlobal.t.sol:

  • Admin CRUD + per-selector independence
  • Revert paths: duplicate, non-owner, invalid selector, not whitelisted, max cap, length mismatch
  • Resolution: global-only, per-job override, neither
  • Runtime dispatch: global invoked, per-job precedence, no-op, de-whitelist skip
  • Cross-selector dependency validation on resolved lists
Ran 23 tests for test/MultiHookRouterGlobal.t.sol:MultiHookRouterGlobalTest
Suite result: ok. 23 passed; 0 failed; 0 skipped

Test plan

  • forge build green
  • forge test --match-contract MultiHookRouterGlobalTest — 23/23 passing
  • Maintainer review

Extends the V2 per-selector, per-hook-data router with owner-managed
global default hook lists. Resolution per (jobId, selector):
- per-job list non-empty → use per-job (unchanged V2 behavior)
- per-job list empty     → fall back to global defaults
- both empty             → no-op

All V2 guarantees apply to resolved lists from either source:
- per-hook data dispatch via abi.encode(bytes[])
- de-whitelist resilience (skipped, event emitted)
- selector completeness validation against IERC8183HookMetadata

Validation at FUND runs unconditionally so a dependent hook declared
on one selector without its counterpart globally is caught before
value transfers begin.

Admin surface (onlyOwner): configureGlobalHooks,
batchConfigureGlobalHooks, addGlobalHook, removeGlobalHook,
reorderGlobalHooks. Views: getGlobalHooks, globalHookCount,
resolveHooks.

23 new tests cover admin CRUD, per-selector independence, revert
paths, resolution precedence, runtime dispatch, de-whitelist skip,
and cross-selector dependency validation.
…faults-v2

# Conflicts:
#	contracts/hooks/MultiHookRouter.sol
Copy link
Copy Markdown
Collaborator

@ariessa ariessa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @JhiNResH,

Please pull current changes from main branch into this PR and resolve conflicts in this branch.

…faults-v2

# Conflicts:
#	contracts/hooks/MultiHookRouter.sol
@JhiNResH
Copy link
Copy Markdown
Author

JhiNResH commented May 4, 2026

Updated PR #34 in commit 244b2e1.\n\nPulled latest upstream main into the branch and resolved the MultiHookRouter conflict. The branch is now mergeable again, and the diff is back to the router + global-default tests only.\n\nVerification: forge test passes, 23 tests passed / 0 failed.

@ariessa
Copy link
Copy Markdown
Collaborator

ariessa commented May 5, 2026

Hi @JhiNResH,

Thanks for addressing the requested changes. Appreciate the work.

After thorough review, this PR will be closed rather than merged. The global-defaults model conflicts with the router's core invariant (client-elected hooks, locked at Funded), and the implementation has security regressions on top of that:

  • Globals bypass the Funded-state lock — owner can mutate hooks on in-flight jobs.
  • removeGlobalHook reintroduces swap-and-pop; fix(MultiHookRouter): preserve hook order in removeHook #41 just fixed this on the per-job path.
  • Owner mutation of globals can DoS in-flight jobs via HookDataLengthMismatch.
  • _validateSelectorCompleteness runs only at FUND; globals can drift after.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants