# Policies

A Policy is a lightweight contract that can inspect a node call and revert if a rule is violated (e.g., pause, cap, whitelist). Policies are attached to specific function selectors on a node. Whenever that selector executes, the node calls `policy.onCheck(caller, msg.data)`. Any revert in the policy reverts the underlying node call.

Which Policy contracts may be attached is controlled by the `NodeRegistry` via a Merkle root. Node owners can only attach policies included in that root for the given selector.

### Managing Policies on a Node

1. **Authorization:** The protocol owner sets `NodeRegistry.policiesRoot`, a Merkle root over `(function selector, policy address)` pairs. A node owner must supply a valid Merkle multi-proof when attaching policies.
2. **Attach:** `Node.addPolicies(proof, proofFlags, sigs, policies)` (owner only) validates the proof against the registry root and appends each policy under its selector. `PolicyAdded` events are emitted and `sigPolicy` is flagged.
3. **Detach:** `Node.removePolicies(sigs, policies)` (owner only) removes the mapping and emits `PolicyRemoved`.
4. **Inspect:** `Node.getPolicies(selector)` returns the ordered list of policies for a selector; `Node.isSigPolicy(selector, policy)` returns a boolean.
5. **Provide user data:** If a policy expects auxiliary data (e.g., Merkle proofs for whitelist), users call `Node.submitPolicyData(selector, policy, abi.encode(payload))` once. The policy caches the payload for that user/node pair and uses it on subsequent checks.

#### Commonly Guarded Node Functions

The current set of policies can fire on:

* `deposit`, `mint`, `requestRedeem`, `redeem`, `withdraw`
* `transfer`, `approve`, `transferFrom`
* `startRebalance`, `execute`, `payManagementFees`, `subtractProtocolExecutionFee`, `updateTotalAssets`
* `fulfillRedeemFromReserve`, `finalizeRedemption`, `setOperator`
