A rule is the core decision-making unit within a policy. Each rule defines a condition expression that is evaluated during a contract call—and one or more effects that are triggered based on whether that condition expression evaluates to true or false.

Rules are executed in the order they appear in the policy. This matters when one rule affects data (like a tracker) used by another.

Every rule consists of:

  • Condition expression: An expression that must evaluate to a boolean (true or false)
  • Effects when true: What happens if the condition expression evaluates to true
  • Effects when false: What happens if the condition expression evaluates to false
  • Calling function signature: Each rule is only applied when a specific calling function invokes the policy
  • Encoded values: The calling function must also pass along specific encoded data for the rule to execute

Condition Expressions

Condition expressions are defined by a sequence of values, operators, and optional parentheses. These expressions evaluate to true or false and control whether the “true” or “false” effects run.

Supported operators include:

TypeOperators
Arithmetic+, -, *, /
Comparators>, <, >=, <=, ==, !=
LogicalAND, OR, (, )

Values in an expression can come from:

  • Config data: static data set at configuration time
  • Encoded values: data sent from the calling contract
  • Trackers: on-chain values managed by the policy
  • Foreign calls: values returned by external smart contract calls

Expressions follow standard operator precedence rules and can use parentheses for grouping.

Effects

Each rule must define at least one effect that takes place if the condition expression evaluates to true or false. You can include multiple effects in either branch. These can be:

  • revert: revert the transaction.
  • emit event: emit an on-chain event
  • update tracker: update a tracker’s value
  • call external contract: call a foreign contract

If the revert effect is triggered, no other effects will happen for that transaction.

Calling Function Signature

Each rule is evaluated only when called by a specific calling function signature.

For example, let’s say we have a staking contract with stake(uint256 amount) and unstake(uint256 amount) functions. We want to create a policy that enforces that users cannot stake tokens after September 1st, and cannot unstake tokens until September 15th.

We would create two separate rules in the policy, and they would have different function signatures:

    "condition": "timestamp > 1751452000",
    "positiveEffects": [],
    "negativeEffects": [revert],
    "functionSignature": "stake(uint256 amount)", 
    "encodedValues": "uint256 timestamp"
    "condition": "timestamp < 1752640000",
    "positiveEffects": [],
    "negativeEffects": [revert],
    "functionSignature": "unstake(uint256 amount)", 
    "encodedValues": "uint256 timestamp"

Encoded Values

When a calling contract invokes the rules engine, it explicitly defines what data to send along with the call. This is the encodedValues field in the JSON definition. This can include values from the calling function signature, and/or other values, like in the example above.

Example Rule

      "condition": "amount > 10000",
      "positiveEffects": ["emit Whale alert"],
      "negativeEffects": [],
      "functionSignature": "transfer(address recipient, uint256 amount)",
      "encodedValues": "address recipient, uint256 amount"

For a full explanation of Rule definition syntax, see here.