> ## Documentation Index
> Fetch the complete documentation index at: https://policykit.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Three-Tier Rule System

> Understanding the three tiers of policy rule evaluation

# Three-Tier Rule System

PolicyKit organizes rules into three tiers based on where and how they are evaluated. This tiered approach balances security, cost, and capability.

## Overview

```mermaid theme={null}
flowchart TD
  TX["Transaction"]
  TX --> T1

  subgraph T1["Tier 1: Stateless On-Chain"]
    direction LR
    T1a["ALLOW_TARGETS"] ~~~ T1b["DENY_TARGETS"] ~~~ T1c["MAX_VALUE"]
    T1d["ALLOW_SELECTORS"] ~~~ T1e["DENY_SELECTORS"]
  end

  T1 -- "Pass" --> T2

  subgraph T2["Tier 2: Stateful On-Chain"]
    direction LR
    T2a["SPEND_LIMIT"] ~~~ T2b["COOLDOWN"]
  end

  T2 -- "Pass" --> T3

  subgraph T3["Tier 3: Off-Chain · Lit Protocol"]
    direction LR
    T3a["MAX_SLIPPAGE_BPS"] ~~~ T3b["REQUIRE_SIMULATION"] ~~~ T3c["CUSTOM"]
  end

  T3 -- "Pass" --> OK["✅ Transaction Allowed"]

  T1 -- "Fail" --> NO["❌ Rejected"]
  T2 -- "Fail" --> NO
  T3 -- "Fail" --> NO
```

Rules are evaluated sequentially: Tier 1 first, then Tier 2, then Tier 3. If any rule fails at any tier, the transaction is rejected immediately.

## Tier 1: Stateless On-Chain Rules

Stateless rules are the simplest and cheapest. They only look at the current transaction parameters — no storage reads needed.

### ALLOW\_TARGETS

Whitelist specific contract addresses that the account can interact with.

```typescript theme={null}
policy.allowTargets([
  "0xUniswapV3Router",
  "0xAaveLendingPool",
  "0xCompoundCToken",
]);
```

Transactions to any address **not** in the list are rejected.

### DENY\_TARGETS

Blacklist specific contract addresses.

```typescript theme={null}
policy.denyTargets([
  "0xKnownScamContract",
  "0xSanctionedAddress",
]);
```

Transactions to any address in the list are rejected. All others are allowed.

<Note>
  If both `ALLOW_TARGETS` and `DENY_TARGETS` are set, `ALLOW_TARGETS` is evaluated first. A transaction must be in the allow list AND not in the deny list.
</Note>

### ALLOW\_SELECTORS

Whitelist specific function selectors (first 4 bytes of calldata).

```typescript theme={null}
policy.allowSelectors([
  "0x38ed1739", // swapExactTokensForTokens
  "0x7ff36ab5", // swapExactETHForTokens
]);
```

### DENY\_SELECTORS

Blacklist specific function selectors.

```typescript theme={null}
policy.denySelectors([
  "0x095ea7b3", // approve (prevent unlimited approvals)
]);
```

### MAX\_VALUE

Set a maximum ETH value per transaction.

```typescript theme={null}
policy.maxValue(parseEther("10")); // Max 10 ETH per tx
```

## Tier 2: Stateful On-Chain Rules

Stateful rules use on-chain storage to track state across transactions. They cost more gas but enable time-based and cumulative constraints.

### SPEND\_LIMIT

Limit how much of a specific token can be spent within a rolling time window.

```typescript theme={null}
policy.spendLimit(
  "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
  parseUnits("50000", 6), // 50,000 USDC
  86400 // per 24 hours
);
```

The on-chain contract tracks cumulative spending and resets the counter when the time window expires.

### COOLDOWN

Enforce a minimum time between transactions.

```typescript theme={null}
policy.cooldown(300); // 5 minutes between transactions
```

This is useful for preventing rapid-fire transactions from compromised agents or scripts.

## Tier 3: Off-Chain Rules (Lit Protocol)

Off-chain rules are evaluated by the Lit Protocol network. They can access external data, perform simulations, and run arbitrary logic that would be impractical on-chain.

### MAX\_SLIPPAGE\_BPS

Check that a swap transaction doesn't exceed a maximum slippage tolerance.

```typescript theme={null}
policy.maxSlippageBps(50); // 0.5% max slippage
```

The Lit Action decodes the transaction calldata, compares input/output amounts, and checks against current market prices.

### REQUIRE\_SIMULATION

Require that the transaction succeeds when simulated.

```typescript theme={null}
policy.requireSimulation(true);
```

The Lit Action simulates the transaction using an RPC endpoint and rejects it if the simulation reverts.

### CUSTOM

Define custom rule logic hosted on IPFS.

```typescript theme={null}
policy.customRule({
  name: "check-oracle-price",
  description: "Verify price is within oracle bounds",
  cid: "QmCustomRuleLogicCID...",
  params: {
    oracle: "0xChainlinkPriceFeed",
    maxDeviation: 500, // 5%
  },
});
```

Custom rules let you implement any evaluation logic. The code is fetched from IPFS and executed in the Lit Action's secure environment.

## Choosing the Right Tier

| Consideration  | Tier 1    | Tier 2    | Tier 3            |
| -------------- | --------- | --------- | ----------------- |
| Gas cost       | Lowest    | Medium    | None (off-chain)  |
| Trust model    | Trustless | Trustless | Decentralized TEE |
| Latency        | Instant   | Instant   | \~1-3 seconds     |
| External data  | No        | No        | Yes               |
| State tracking | No        | Yes       | Yes               |
| Custom logic   | No        | No        | Yes               |

**Guidelines:**

* Use **Tier 1** for simple access control (targets, selectors, value limits)
* Use **Tier 2** when you need time-based or cumulative constraints
* Use **Tier 3** when you need external data, simulation, or custom logic
