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
ObjectField | 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
ObjectField | 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
StructureField | 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 5 days ago