Skip to main content
The FunctorPolicyHook is an ERC-7579 hook module that runs before and after every transaction on the smart account. It is the core of Functor’s onchain enforcement.

What it does

Three things in one module:
  1. Enforce policies - check every rule before the transaction executes
  2. Collect fees - transfer a flat fee directly to the Functor treasury
  3. Emit audit events - create an onchain record of every transaction and every blocked attempt

preCheck - before execution

Called by the smart account before every transaction. The hook:
  1. Identifies which keyId signed the transaction (from the validator context)
  2. Loads the policy set for that keyId
  3. Evaluates every policy - all must pass (AND semantics)
  4. Transfers the flat fee from the smart account to the treasury
  5. Caches pre-execution state (e.g., token balances before a swap)
If any policy fails, the transaction reverts immediately. No fee is charged.

postCheck - after execution

Called by the smart account after the transaction executes. The hook:
  1. Verifies execution outcome against cached pre-execution state (e.g., did the token balance change as expected?)
  2. Updates rolling spending counters per token per time window
  3. Increments rate limit counters
  4. Emits the FunctorTxExecuted event with full transaction details and policy results

Onchain state

The hook maintains per-account, per-keyId state:
account → keyId → {
  policy rules configuration
  spending per token per time window
  transaction count per time window
  last window reset timestamp
}
This state persists across sessions. A new session key linked to the same keyId inherits the existing counters - preventing limit bypasses through session rotation.

Time-windowed counters

Spending and rate limit counters reset lazily. On each transaction, the hook checks whether the current time has crossed a window boundary. If it has, the counter resets before evaluation. No background scheduler, no off-chain process.
Window: 24 hours
Last reset: April 5, 9:00 AM
Current time: April 6, 10:00 AM
→ Window crossed. Reset counter to 0. Evaluate fresh.

Post-execution verification

Because the hook runs after execution (postCheck), it can verify outcomes that pre-execution checks cannot:
  • Did a swap return at least the expected amount of tokens?
  • Did an unexpected token leave the account?
  • Did the account balance change by more than the transaction value?
If the outcome doesn’t match expectations, the hook can flag the transaction in the audit event. Future versions may support post-execution reverts for specific policy types.

Fee collection

The fee is a direct transfer in preCheck - from the smart account to the Functor treasury. The hook contract itself holds zero funds. There is no deposit, no balance, no pool.

Events

Two event types: FunctorTxExecuted - emitted on every successful transaction with account, keyId, target, value, policy results, fee, and timestamp. FunctorTxBlocked - emitted when a transaction is denied by policy, with account, keyId, target, value, denial reason, and timestamp. Both events are indexed onchain and queryable by the dashboard, the SDK, or any block explorer.