Lists and Macros are reusable components defined at the file level (before rules) that can be used by multiple rules in the same file.
Important: lists and macros are NOT fields within a rule. They are separate components defined at the file level, before your rules. This allows them to be reused by multiple rules in the same file.
Lists
Lists are reusable address/value collections. Define them once at the top of your file, then reference them in any rule’s condition using the in operator:
- list: known_dex_routers
items:
- "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D" # Uniswap V2
- "0xE592427A0AEce92De3Edee1F18E0157C05861564" # Uniswap V3
- "0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F" # SushiSwap
- rule: DEX Interaction
desc: Detects interactions with known DEX routers
tags: ["defi", "dex"]
condition: tx.to in (known_dex_routers)
output: "DEX interaction detected: %tx.to"
priority: NOTICE
enabled: true
Macros
Macros are reusable condition fragments. Define them once at the top of your file, then reference them in any rule’s condition:
- macro: high_value_transfer
condition: tx.value > 100 ether
- macro: is_dex_interaction
condition: tx.to in (known_dex_routers)
- rule: High Value DEX Swap
desc: Detects high-value swaps on DEX routers
tags: ["defi", "dex", "high-value"]
condition: >
high_value_transfer and
is_dex_interaction
output: >
High value DEX swap: %tx.value_eth ETH on %tx.to
priority: WARNING
enabled: true
Complete Example
# 1. Define lists and macros first
- list: known_dex_routers
items:
- "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"
- "0xE592427A0AEce92De3Edee1F18E0157C05861564"
- list: monitored_addresses
items:
- "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
- macro: high_value_transfer
condition: tx.value > 100 ether
- macro: is_dex_interaction
condition: tx.to in (known_dex_routers)
# 2. Define rules that use the components above
- rule: High Value DEX Swap
desc: Detects high-value swaps on DEX routers
tags: ["defi", "dex", "high-value"]
condition: >
high_value_transfer and
is_dex_interaction
output: >
High value DEX swap: %tx.value_eth ETH on %tx.to
priority: WARNING
enabled: true
- rule: Monitored Address Transfer
desc: Detects transfers to monitored addresses
tags: ["security", "monitoring"]
condition: >
tx.to in (monitored_addresses) and
tx.value > 10 ether
output: >
Transfer to monitored address: %tx.value_eth ETH to %tx.to
priority: WARNING
enabled: true
How It Works
- Lists and Macros are defined outside of rules (at the file level), but in the same file as your rules
- They must be defined before the rules that use them
- Macros are expanded when rules are evaluated, allowing you to reuse condition logic
- Lists used with the
in operator are resolved at evaluation time
- Multiple rules in the same file can reference the same list or macro
File Organization: While lists and macros can be shared across rules in the same file, it’s a best practice to group related rules together (e.g., same category, threat type, or protocol). This makes maintenance easier and keeps your rule base organized. See Rule Structure for more details.
When to Use Lists vs Macros
- Use Lists for collections of addresses or values that you want to check membership (
in operator)
- Use Macros for reusable condition fragments that you want to reference by name
Next Steps