Policy Condition Language (PCL)
This page provides an overview of how to write conditions for Swivell's Policy Engine.
Language Features
Primitives
| Type | Description | Examples |
|---|---|---|
| string | Text values enclosed in single or double quotes | 'mainnet', 'BTC', "0x123..." |
| bool | True/false values | true, false |
| float | Numeric values with decimals | 100.0, 0.5, 1000.50 |
| list | Collections of values | ['mainnet', 'arbitrum'], [1, 2, 3] |
| object | Structured data with named fields | { symbol: "USD0" }, { address: "0x123...", risk_score: 0.3 } |
Comparisons
Equality and Inequality
==- Equal to:deposit.amount == 100.0!=- Not equal to:deposit.network != 'mainnet'
Numeric Comparisons
<- Less than:deposit.value_usd < 1000.0>- Greater than:deposit.amount > 50.0<=- Less than or equal:deposit.value_usd <= 5000.0>=- Greater than or equal:deposit.amount >= 10.0
Logical Operators
&&- Logical AND:deposit.amount > 0 && deposit.value_usd < 1000.0||- Logical OR:deposit.network == 'mainnet' || deposit.network == 'arbitrum'!- Logical NOT:!deposit.asset.is_possible_spam
Membership
in- Check if value exists in list:deposit.network in ['mainnet', 'arbitrum']
Objects
Field Access
.- Access object properties:deposit.asset.symbol
Lists
Access Elements
[index]- Get element at index:deposit.originators[0]
Functions
size()- Get list length:size(deposit.originators).all(item, condition)- Check if all items match:deposit.originators.all(o, o.risk_score < 0.5).exists(item, condition)- Check if any item matches:deposit.originators.exists(o, o.risk_score > 0.8)
Context
The policy conditions have these variables in scope
| Keyword | Type | Description | Available On |
|---|---|---|---|
deposit | Deposit | The deposit being processed | effect_freeze, effect_forward |
Deposit Object
Deposit Object| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the deposit |
network | string | Network where the deposit occurred (e.g mainnet, solana, base, arbitrum) |
asset | Asset | Details about the deposited asset |
amount | float | Amount of tokens deposited |
value_usd | float | USD value of the deposit (optional) |
originators | list[Originator] | The originators of the deposit |
Asset Object
Asset Object| Field | Type | Description |
|---|---|---|
address_checksum | string | The address/mint of the token in case-sensitive format |
address_lowercase | string | The address/mint of the token in lowercase format |
symbol | string | The symbol for the token (e.g., "BTC", "ETH") |
network | string | The network the token is on (e.g mainnet, solana, base, arbitrum) |
is_possible_spam | bool | Whether the token is flagged as possible spam |
name | string | The full name of the token (optional) |
pegged_to | string | Symbol this token's price is pegged to (optional) |
Originator Structure
Originator Structure| Field | Type | Description |
|---|---|---|
address_checksum | string | The address of the originator in case-sensitive format |
address_lowercase | string | The address of the originator in lowercase format |
risk_score | float | Score of the originator's fraud risk |
Examples Conditions
Amount Limits
// Allow deposits under $1,000 USD
deposit.value_usd < 1000.0
// Limit token amount
deposit.amount <= 100.0
Asset Restrictions
// Only allow specific tokens
deposit.asset.symbol in ['BTC', 'ETH', 'USDC']
// Block spam tokens
!deposit.asset.is_possible_spam
// Check specific token address (case-sensitive)
deposit.asset.address_checksum == '0xA0b86a33E6441d8178E82c5A3f4fa6Afdd59E33e'
// Check address (case-insensitive)
deposit.asset.address_lowercase == '0xa0b86a33e6441d8178e82c5a3f4fa6afdd59e33e'
Network Controls
// Only allow Ethereum mainnet
deposit.network == 'mainnet'
// Allow multiple networks
deposit.network in ['mainnet', 'arbitrum', 'base']
Combined Conditions
// Mainnet deposits under $10k OR L2 deposits under $5k
(deposit.network == 'mainnet' && deposit.value_usd < 10000.0) ||
(deposit.network in ['arbitrum', 'base'] && deposit.value_usd < 5000.0)
// Safe assets only
deposit.asset.symbol in ['ETH', 'USDC'] && !deposit.asset.is_possible_spam
Stablecoin Handling
// USD-pegged tokens with higher limits
deposit.asset.pegged_to == 'USD' && deposit.value_usd < 25000.0
// Specific stablecoins
!deposit.is_possible_spam && deposit.asset.symbol in ['USDC', 'USDT', 'DAI']
Originator Risk Validation
// Block high-risk originators
deposit.originators.all(o, o.risk_score < 0.5)
// Allow deposits if any originator has low risk
deposit.originators.exists(o, o.risk_score < 0.2)
// Check specific originator addresses (case-sensitive)
deposit.originators.exists(o, o.address_checksum in trusted_addresses)
// Check originator addresses (case-insensitive)
deposit.originators.exists(o, o.address_lowercase in trusted_addresses_lower)
Updated 7 days ago
