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

# Conditions Overview

> Pluggable condition system for flexible payment authorization and state tracking

## What conditions do

Conditions are swappable contracts that control who can perform actions on a PaymentOperator. Each operator has **5 condition slots**, one per action:

| Slot                             | Controls                          |
| -------------------------------- | --------------------------------- |
| `AUTHORIZE_PRE_ACTION_CONDITION` | Who can create payments           |
| `CHARGE_PRE_ACTION_CONDITION`    | Who can charge partial amounts    |
| `CAPTURE_PRE_ACTION_CONDITION`   | Who can capture funds from escrow |
| `VOID_PRE_ACTION_CONDITION`      | Who can refund during escrow      |
| `REFUND_PRE_ACTION_CONDITION`    | Who can refund after capture      |

These are the condition half of the operator's 10 slots. For the full slot layout alongside the post-action hooks, see [PaymentOperator: 10-slot configuration](/contracts/payment-operator#10-slot-configuration).

## ICondition Interface

```solidity theme={null}
interface ICondition {
    function check(
        AuthCaptureEscrow.PaymentInfo calldata paymentInfo,
        uint256 amount,
        address caller,
        bytes calldata data
    ) external view returns (bool allowed);
}
```

**Parameters:**

* `paymentInfo`, The payment information struct
* `amount`, The amount involved in the action (0 for authorization-only checks like refund request status updates)
* `caller`, The address attempting the action
* `data`, Arbitrary data forwarded from the caller (signatures, proofs, attestations)

**Return:** `true` if the caller can proceed, `false` otherwise.

## Default Behavior

**Condition slot = `address(0)`**: always returns `true` (allow). The action has no restrictions.

You only need to set conditions for slots you want to restrict. Leave the rest as `address(0)`.

## Singleton vs Per-Deployment

| Type               | Examples                                                                                                                                                     | Deploy Strategy                                           |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------- |
| **Singleton**      | [PayerCondition](/contracts/conditions/payer), [ReceiverCondition](/contracts/conditions/receiver), [AlwaysTrueCondition](/contracts/conditions/always-true) | Deployed once, reuse everywhere                           |
| **Per-deployment** | [StaticAddressCondition](/contracts/conditions/static-address), [EscrowPeriod](/contracts/conditions/escrow-period), [Freeze](/contracts/conditions/freeze)  | Deploy per use case via [factories](/contracts/factories) |
| **Composable**     | [And/Or/Not](/contracts/conditions/combinators)                                                                                                              | Combine existing conditions via factories                 |

## Security Rules

<Warning>
  **Conditions MUST NOT revert.** Return `false` to deny, never `revert`. The operator converts `false` into a `ConditionNotMet` error.
</Warning>

* Conditions should be `view` or `pure` to prevent reentrancy attacks
* Never make external state-changing calls inside a condition
* Cover edge cases in tests. Bugs in authorization logic can lock funds

## Configuration Patterns

Conditions compose to create flexible authorization policies. Here are common patterns:

### Open Authorization, Restricted Capture

```solidity theme={null}
config = {
    authorizePreActionCondition: ALWAYS_TRUE_CONDITION,  // Anyone can authorize
    authorizePostActionHook: escrowHook,          // Record time
    capturePreActionCondition: capturePreActionCondition,         // Restricted
    // ...
};
```

### Payer-Only Actions

```solidity theme={null}
config = {
    authorizePreActionCondition: PAYER_CONDITION,        // Only payer
    capturePreActionCondition: PAYER_CONDITION,          // Only payer
    // ...
};
```

### Arbiter-Controlled

```solidity theme={null}
config = {
    authorizePreActionCondition: ARBITER_CONDITION,      // Only arbiter
    chargePreActionCondition: ARBITER_CONDITION,         // Only arbiter
    capturePreActionCondition: ARBITER_CONDITION,        // Only arbiter
    voidPreActionCondition: ARBITER_CONDITION, // Only arbiter
    refundPreActionCondition: ARBITER_CONDITION,
    // ...
};
```

For complete configuration examples, see the [Examples](/contracts/examples) page.

## Gas Optimization

### Singleton Reuse

All operators reuse the same singleton conditions. Reference the existing addresses, don't deploy new instances:

```typescript theme={null}
// Good: Reference the singleton address
const config1 = { authorizePreActionCondition: PAYER_CONDITION };
const config2 = { authorizePreActionCondition: PAYER_CONDITION }; // Same address
```

### Stateless Conditions

Prefer stateless conditions when possible:

```solidity theme={null}
// Stateless: No storage reads (pure)
function check(PaymentInfo calldata payment, uint256, address caller, bytes calldata)
    external pure returns (bool)
{
    return caller == payment.receiver;  // Pure computation
}

// Stateful: Storage reads cost gas (view)
function check(PaymentInfo calldata payment, uint256, address caller, bytes calldata)
    external view returns (bool)
{
    return allowList[caller];  // SLOAD costs gas
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Hooks" icon="database" href="/contracts/hooks/overview">
    Learn about the state recording system.
  </Card>

  <Card title="Combinators" icon="puzzle-piece" href="/contracts/conditions/combinators">
    Compose conditions with And/Or/Not logic.
  </Card>

  <Card title="Custom Conditions" icon="wrench" href="/contracts/conditions/custom">
    Build your own condition contracts.
  </Card>

  <Card title="Examples" icon="code" href="/contracts/examples">
    See complete configuration examples.
  </Card>
</CardGroup>
