File Structure: In examples that use
lists or macros, notice they are defined outside of rules (at the file level) before the rules that use them. This allows them to be reused by multiple rules in the same file. See Lists & Macros for details.High-Value Transfers
Large ETH Transfer
Detect transfers of significant amounts of native tokens (ETH, RBTC, etc.).value field.
Why these fields:
tx.value > 100 ether- Direct comparison of transaction value in native token unitstx.to != null- Excludes contract deployments (which havenullrecipient)
Very Large ETH Transfer
Detect extremely large transfers that may indicate significant events.tx.value > 1000 ether- Very high threshold to catch only exceptional transferstx.to != null- Ensures it’s a transfer, not a contract deployment
Token Operations
Token Burn Detection
Detect when tokens are sent to the zero address (burn address).0x0000...0000), which is the standard way to burn tokens on EVM chains.
Why these fields:
tx.logs.any(event_name == "Transfer" and to == "...")- Checks if any Transfer event in the transaction goes to the zero address- Uses the padded zero address format (66 characters with 0x prefix) as required by EVM
- The
event_name == "Transfer"filter ensures we only check Transfer events, and the automatic parsing provides thetofield
Unlimited Token Approval
Detect when a user approves the maximum possible amount (type(uint256).max) to a spender.2^256 - 1), which effectively gives unlimited spending access to the spender.
Why these fields:
tx.logs.any(event_name == "Approval" and amount == "...")- Checks if any Approval event in the transaction uses the max uint256 value- The hex value
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffis the max uint256 value - The
event_name == "Approval"filter ensures we only check Approval events, and the automatic parsing provides theamountfield
Function and Event Category Detection
Any Transfer Function Call
Detect when any transfer-related function is called (transfer, transferFrom, safeTransferFrom, etc.).transfer, transferFrom, safeTransferFrom, etc. This is broader than detecting a specific function.
Why these fields:
tx.function_category == "Transfer"- Detects any transfer-related function call- Uses category instead of specific function name for broader coverage
Any Swap Function Call
Detect when any swap-related function is called (all Uniswap variants).tx.function_category == "Swap"- Detects any swap-related function call- Automatically includes all swap variants (swapExactETHForTokens, exactInputSingle, etc.)
Any Transfer Event (Category)
Detect when any Transfer category event is emitted.Transfer events, but will automatically include new transfer-related events as they’re added to the database.
Why these fields:
tx.logs.any(event_category == "Transfer")- Detects any Transfer category event- Uses category for broader detection that automatically includes new event variants
Any Approval Event (Category)
Detect when any Approval category event is emitted (includes both Approval and ApprovalForAll).Approval and ApprovalForAll events.
Why these fields:
tx.logs.any(event_category == "Approval")- Detects any Approval category event- Automatically includes both
ApprovalandApprovalForAllwithout needing separate conditions
Any Swap Event (Category)
Detect when any Swap category event is emitted (Uniswap V2/V3 swaps).tx.logs.any(event_category == "Swap")- Detects any Swap category event- Automatically includes both Uniswap V2 and V3 swap events without needing separate conditions
Note on Function vs Event Categories: Function categories (
tx.function_category) and event categories (tx.logs.any(event_category == ...)) are designed to be consistent where possible. However, not all function categories have corresponding event categories because:- Functions represent what was called (e.g.,
swapExactETHForTokens,deposit,mint) - Events represent what was emitted (e.g.,
Swap,Transfer,Approval)
Liquidity, Lending, FlashLoan, Multicall, Mint, Burn, and Claim don’t have direct event equivalents because these operations often emit standard events like Transfer or protocol-specific events that vary by implementation.Current Event Categories: Transfer, Approval, Swap
Current Function Categories: Transfer, Approval, Swap, Liquidity, Lending, FlashLoan, Multicall, Mint, Burn, ClaimWatchlist-Based Detection
Known Attacker Activity
Monitor transactions from addresses on your threat intelligence watchlist.tx.from in (known_attackers)- Checks if the transaction sender is in your watchlist- Uses a
listcomponent to maintain your threat intelligence addresses
Sanctioned Address Interaction
Detect transactions involving OFAC-sanctioned or other compliance-monitored addresses.tx.from in (sanctioned_addresses)- Checks if sender is sanctionedtx.to in (sanctioned_addresses)- Checks if recipient is sanctioned- Uses
orto catch both directions of interaction
Operational Monitoring
Zero Value Transaction with High Gas
Detect contract interactions (zero value) that consume significant gas, which may indicate complex operations or potential attacks.tx.value == 0- Ensures it’s a contract interaction, not a transfertx.gas_used > 1000000- High gas threshold indicates complex operations- Requires receipt data (so
analysis.transaction.fetch_receiptmust be enabled)
High Gas Price Transaction
Detect transactions with abnormally high gas prices, which may indicate time-sensitive operations or MEV activity.tx.gas_price > 500 gwei- Direct comparison of gas price (converted from wei to gwei for readability)- Gas price is available in the transaction data
Contract Deployment Monitoring
Large Contract Deployment
Monitor new contract deployments that consume significant gas, indicating complex contracts.null recipient) that consume more than 2 million gas, indicating large or complex contracts.
Why these fields:
tx.to == null- Identifies contract deployments (no recipient address)tx.gas_used > 2000000- High gas threshold for large contractstx.status == 1- Only successful deployments (failed deployments are less interesting)