Skip to main content

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:
SlotControls
AUTHORIZE_PRE_ACTION_CONDITIONWho can create payments
CHARGE_PRE_ACTION_CONDITIONWho can charge partial amounts
CAPTURE_PRE_ACTION_CONDITIONWho can capture funds from escrow
VOID_PRE_ACTION_CONDITIONWho can refund during escrow
REFUND_PRE_ACTION_CONDITIONWho 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.

ICondition Interface

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

TypeExamplesDeploy Strategy
SingletonPayerCondition, ReceiverCondition, AlwaysTrueConditionDeployed once, reuse everywhere
Per-deploymentStaticAddressCondition, EscrowPeriod, FreezeDeploy per use case via factories
ComposableAnd/Or/NotCombine existing conditions via factories

Security Rules

Conditions MUST NOT revert. Return false to deny, never revert. The operator converts false into a ConditionNotMet error.
  • 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

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

Payer-Only Actions

config = {
    authorizePreActionCondition: PAYER_CONDITION,        // Only payer
    capturePreActionCondition: PAYER_CONDITION,          // Only payer
    // ...
};

Arbiter-Controlled

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 page.

Gas Optimization

Singleton Reuse

All operators reuse the same singleton conditions. Reference the existing addresses, don’t deploy new instances:
// Good: Reference the singleton address
const config1 = { authorizePreActionCondition: PAYER_CONDITION };
const config2 = { authorizePreActionCondition: PAYER_CONDITION }; // Same address

Stateless Conditions

Prefer stateless conditions when possible:
// 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

Hooks

Learn about the state recording system.

Combinators

Compose conditions with And/Or/Not logic.

Custom Conditions

Build your own condition contracts.

Examples

See complete configuration examples.