Basic Syntax

Fundamental building blocks of FailSafe expressions - the core functions to master first

Learning Objective

Understand the three primary detection functions and basic comparison operators

Function Invocation Detection

watchRule:

{
  "expressions": [
    "system.invoked(tx1.WETH.F.transfer)"
  ]
}
Concept: Function invocation detection

Detects when the transfer function is called on WETH contract

Event Emission Detection

watchRule:

{
  "expressions": [
    "system.emitted(tx1.UniswapV2Pair.E.Swap)"
  ]
}
Concept: Event emission detection

Detects when Swap event is emitted from Uniswap V2 pair contract

Function Invocation with Address Filtering

watchRule:

{
  "expressions": [
    "system.invoked(tx1.USDC.F.*)"
  ]
}

options:

{
  "ruleScope": {
    "contractName": "USDC",
    "groupId": "trusted_addresses",
    "member": false
  }
}
Concept: Function invocation with address filtering

Detects USDC function calls with address list filtering applied via ruleScope - rule fires when USDC functions are called by addresses NOT in the trusted_addresses list

Numeric Comparison

watchRule:

{
  "expressions": [
    "system.uintCompare(tx1.USDC.F.transfer.value, >, 1000000000000000000000000000)"
  ]
}
Concept: Numeric comparison

Compares transfer amount to exact value

Numeric Comparison with Literal Placeholder

watchRule:

{
  "expressions": [
    "system.uintCompare(tx1.DAI.F.transfer.value, >, ${maxTransferAmount})"
  ]
}

options:

{
  "literalDefs": {
    "maxTransferAmount": 1e+27
  }
}
Concept: Numeric comparison with literal placeholder

Compares DAI transfer amount to configurable threshold using placeholder

Risk Score Comparison

watchRule:

{
  "expressions": [
    "system.uintCompare(tx1.LendingPool.riskscore, >, 75)"
  ]
}
Concept: Risk score comparison

Triggers on transactions involving very high-risk addresses (FailSafe Radar assessment)

Risk Score Comparison with Literal Placeholder

watchRule:

{
  "expressions": [
    "system.uintCompare(tx1.CompoundCToken.riskscore, >, ${riskThreshold})"
  ]
}

options:

{
  "literalDefs": {
    "riskThreshold": 50
  }
}
Concept: Risk score comparison with literal placeholder

Triggers on Compound transactions exceeding configurable risk threshold

Address Comparison

watchRule:

{
  "expressions": [
    "system.addressCompare(tx1.USDC.F.transfer.to, ==, 0x67bcc2443971070599265b34cf63dF57eAbA5940)"
  ]
}
Concept: Address comparison

Compares transfer recipient to specific address

Address Comparison with Literal Placeholder

watchRule:

{
  "expressions": [
    "system.addressCompare(tx1.AavePool.F.deposit.asset, ==, ${trustedAsset})"
  ]
}

options:

{
  "literalDefs": {
    "trustedAsset": "0x67bcc2443971070599265b34cf63dF57eAbA5940"
  }
}
Concept: Address comparison with literal placeholder

Compares Aave deposit asset to configurable trusted asset address

String/Bytes Comparison

watchRule:

{
  "expressions": [
    "system.stringCompare(tx1.Router.F.smartSwapByOrderId.batches[0][1].extraData[0], ==, 0x01)"
  ]
}
Concept: String/bytes comparison

Compares batch extra data to specific bytes value

String/Bytes Comparison with Literal Placeholder

watchRule:

{
  "expressions": [
    "system.stringCompare(tx1.MultisigWallet.F.executeTransaction.data, ==, ${expectedCalldata})"
  ]
}

options:

{
  "literalDefs": {
    "expectedCalldata": "0x01"
  }
}
Concept: String/bytes comparison with literal placeholder

Compares multisig transaction calldata to configurable expected value

Multiple Expressions (Comma-Separated AND)

watchRule:

{
  "expressions": [
    "system.emitted(tx1.WETH.E.Transfer)",
    "system.uintCompare(tx1.WETH.F.transfer.value, >, ${largeAmount})"
  ]
}

options:

{
  "literalDefs": {
    "largeAmount": 100000000000000000000
  }
}
Concept: Multiple expressions as AND conditions

Comma-separated expressions are equivalent to `(expression1) && (expression2)` - triggers when WETH transfer is invoked AND the amount exceeds threshold