Syntax for Defining a Policy
Policies are submitted to the Rules Engine SDK in the form of a JSON string, with the following available properties:Policy
: a string representing the name of the policy (optional)Description
: a short description of the policy (optional)PolicyType
: eitheropen
orclosed
(any contract can subscribe to an open policy whereas closed policies must approve the calling contract) - requiredCallingFunctions
: an array of Calling Function JSON objects (defined below) - requiredForeignCalls
: an array of Foreign Call JSON objects (defined below) - requiredTrackers
: an array of Tracker JSON objects (defined below) - requiredMappedTrackers
: an array of Mapped Tracker JSON objects (defined below) - requiredRules
: an array of Rule JSON objects (defined below) - required
Validation Rules
- All referenced calling functions in rules must exist in the CallingFunctions array
- All referenced foreign calls must exist in the ForeignCalls array
- All referenced trackers must exist in the Trackers or MappedTrackers arrays
- All component names within each array must be unique
- Foreign Call naming is only required to be unique if a single calling function is using multiple foreign calls
Calling Functions
The functions that when called will invoke the Policy. You define these in theCallingFunctions
top level property with the following details:
name
: The name of the calling function (must be unique within policy, leading/trailing whitespace automatically trimmed)functionSignature
: The signature of the calling function, which includes argument types and names (must follow Solidity syntax, must exactly match the function signature in the target smart contract)encodedValues
: a list of values that will be encoded along with the call to the rules engine from the calling contract (must contain valid parameter type declarations using supported Solidity types only)
Supported Parameter Types
The following Solidity types are supported for encodedValues parameters:- Primitive Types:
uint256
,address
,bool
,bytes
,string
- Array Types:
uint256[]
,address[]
,bool[]
,bytes[]
,string[]
- Fixed-Size Types:
bytes
(standard Solidity byte values)
Parameter Name Usage and References
- Parameter names defined in
encodedValues
serve as local identifiers within the rule engine - Local Scope: Names are used for referencing within the current policy only
- Rule References: Parameters can be referenced directly by name in rule conditions (e.g., value > 500)
- Foreign Call References: Parameters can be passed to foreign calls using their local names
- Name Independence: Parameter names do not need to match the actual smart contract parameter names
- Consistent Usage: Once defined, parameter names must be used consistently throughout the policy
Integration Requirements
- Function Signature Matching: The functionSignature must exactly match the target contract’s function signature including parameter types and order
- ABI Compatibility: The calling function definition must be ABI-compatible with the target smart contract function
Function Resolution
The SDK supports flexible calling function resolution for rules and foreign calls:- References must use the name field
- Case-insensitive fallback matching is available if exact matches fail
Foreign Calls
TheForeignCalls
property contains an array of Foreign Call JSON objects. These represent all of the Foreign Calls that will be available within the policy. Each object consists of the following properties:
name
: The name of the foreign call (must be unique within policy, leading/trailing whitespace automatically trimmed)function
: Function signature with supported argument types (must follow Solidity function syntax with parentheses, supported parameter types only)address
: The address of the foreign contract being called (must be valid Ethereum address format, automatically converted to checksummed format)returnType
: The return type of the function (must be supported Solidity type)valuesToPass
: Values to pass as function arguments (comma-separated format expected, can reference calling function parameters by name, use literal values, or mix both)mappedTrackerKeyValues
: Key-value mappings for tracker integration (comma-separated format expected when used, can reference calling function parameters for dynamic key resolution)callingFunction
: Reference to the associated calling function (must reference existing calling function, supports flexible resolution)
Parameter Passing and Key Value Usage
Values to Pass Examples
- Parameter Reference: “to, value” - passes the to and value parameters from the calling function
- Mixed Parameters and Literals: “to, 1000, value” - passes to parameter, literal value 1000, and value parameter
- Literal Values Only: “‘admin’, 100, true” - passes string ‘admin’, number 100, and boolean true
- Single Parameter: “to” - passes only the to parameter
- Function Signature Matching: Parameter count and types must match the foreign call function signature
Mapped Tracker Key Values Examples
- Dynamic Key from Parameter: “to” - uses the to parameter value as the mapped tracker key
- Multiple Parameters: “to, from” - when multiple mapped tracker operations are needed using different parameter values
- Empty/Unused: "" - when the foreign call doesn’t interact with mapped trackers
Parameter Resolution Rules
- Parameter Names: Must match exactly with names defined in the calling function’s encodedValues
- Type Compatibility: Passed values must be compatible with the foreign call function’s expected parameter types
- Order Sensitivity: Parameters must be provided in the same order as the foreign call function signature
- Reference Validation: All parameter names must exist in the associated calling function
Function Reference Resolution
- Case-insensitive fallback matching is available if exact matches fail
- When a reference like
"Transfer(address,uint256)"
doesn’t exactly match the stored function name"transfer(address,uint256)"
, the system converts both to lowercase for comparison as a fallback option
Trackers
TheTrackers
property contains an array of Tracker JSON objects. These represent all of the Trackers that will be available within the policy. Each object consists of the following properties:
name
: The name of the tracker (must be unique within policy, leading/trailing whitespace automatically trimmed)type
: The type of the tracker (must be exact match to supported types)initialValue
: The initial value of the tracker (for string types - leading/trailing whitespace automatically trimmed; for array types - each string element is trimmed)
Supported Tracker Types
- uint256 - Unsigned 256-bit integer
- address - Ethereum address
- bool - Boolean value (“true” / “false”)
- bytes - Bytes value (must use prefix “0x” e.g. “0x1234”)
- string - String value
- Array variants of the above types (uint256[], address[], bool[], bytes[], string[])
Type-Value Validation
- For single value types: initialValue must be a string
- For array types: initialValue must be an array of strings
- Values must be compatible with the specified type
Mapped Trackers
TheMappedTrackers
property contains an array of Mapped Tracker JSON objects. These represent all of the Mapped Trackers that will be available within the policy. Each object consists of the following properties:
name
: The name of the tracker (must be unique within policy, leading/trailing whitespace automatically trimmed)keyType
: The key type of the tracker (must be exact match to supported key types)valueType
: The value type of the tracker (must be exact match to supported types)initialKeys
: The initial keys of the tracker (array of strings, no automatic trimming on individual keys, must be unique values)initialValues
: The initial values of the tracker (for string value types - leading/trailing whitespace automatically trimmed; for array value types - each string element within arrays is trimmed)
Supported Key Types
- uint256 - Unsigned 256-bit integer
- address - Ethereum address
- string - String value
- bool - Boolean value (“true” / “false”)
- bytes - Bytes value (must use prefix “0x” e.g. “0x1234”)
Supported Value Types
- Same as regular tracker types (including array variants)
Mapped Tracker Validation Rules
name
must be unique within the policy’s MappedTrackers arraykeyType
must be a supported tracker key typevalueType
must be a supported tracker typeinitialKeys
andinitialValues
arrays must have the same lengthinitialKeys
must contain unique values (no duplicates)- Each value in
initialValues
must match the specified valueType - Each key in
initialKeys
must match the specified keyType
Type-Value Validation for Mapped Trackers
- For single value types: each entry in initialValues must be a string
- For array value types: each entry in initialValues must be an array of strings
- All keys must be valid for the specified keyType
- All values must be valid for the specified valueType
Rules
Now’s the fun part! TheRules
property contains an array of rule definition objects. These represent all of the rules that are configured for the policy. Each object consists of the following properties:
Name
: The name of the rule (optional, defaults to empty string if not provided, no special character restrictions, leading/trailing whitespace automatically trimmed)Description
: A description of the rule (optional, defaults to empty string if not provided, no special character restrictions, leading/trailing whitespace automatically trimmed)condition
: a string representing a conditional expression for the rule which must evaluate to a boolean (true or false) result. Must contain valid logical operators only (AND, OR, NOT), proper parentheses grouping required, no automatic trimmingpositiveEffects
: an array of effect expressions to be executed if the condition evaluates to TRUE (array of strings, no character restrictions on individual effect strings)negativeEffects
: an array of effect expressions to be executed if the condition evaluates to FALSE (array of strings, no character restrictions on individual effect strings)callingFunction
: a string representation of the function signature this rule will be attached to, for exampletransfer(address recipient, uint256 amount)
(must reference existing calling function name, no special character restrictions)order
: Optional ordering value for rule execution sequence (numeric values only, must be unique across all rules if used, enables deterministic rule execution sequence)
Condition
Conditional expressions must evaluate to a boolean result. A conditional expression consists of values combined using operators, for example(receiverBalance + amount < 100) AND (FC:GetAccessLevel > 1)
.
Values available to use in conditional expressions:
- Static values of the following types:
uint256
,address
,bytes
(0x format),string
- Referenced values:
- values encoded by the calling function. Referenced by the name listed in the
encodedValues
section for the rule. - Trackers: trackers are referenced in the condition statement by
TR:
followed by the name of the tracker (as defined in the tracker JSON object in the policy), for exampleTR:largeTransactionCount
- MappedTrackers: mapped trackers are referenced in the condition statement by
TR:
followed by the name of the tracker (as defined in the tracker JSON object in the policy), followed by the key wrapped in parenthesis, for exampleTR:largeTransactionCount(sender)
- Result of a Foreign Call: foreign calls are referenced in the condition statement by
FC:
followed by the name of the foreign call (as defined in the foreign call JSON object in the policy), for exampleFC:GetAccessLevel
- values encoded by the calling function. Referenced by the name listed in the
Condition Syntax Requirements and Restrictions
Parentheses Requirements
- Balanced Parentheses: All opening
(
must have matching closing)
parentheses - Proper Nesting: Nested parentheses must be properly structured
- Automatic Spacing: Parentheses are automatically padded with spaces during parsing
- Group Validation: Each parenthetical group is validated independently for operator consistency
Reference Syntax
- Foreign Calls: Must use
FC:
prefix followed by the foreign call name (e.g.,FC:GetBalance
) - Trackers: Must use
TR:
prefix followed by the tracker name (e.g.,TR:UserCount
) - Mapped Trackers: Must use
TR:
prefix with parentheses for the key (e.g.,TR:UserBalances(userAddress)
) - Case Sensitive: All reference names are case-sensitive and must exactly match component names
- No Spaces: Reference names cannot contain spaces or special characters except parentheses for mapped trackers
Logical Operator Rules
- Single Operator Per Group: Each set of parentheses can only contain one instance of AND or OR (either all AND or all OR, not mixed)
- Case Sensitive: Operators must be in ALL CAPS (AND, OR, NOT)
- Spacing: Operators are automatically padded with spaces during validation
- No Multiple Operators: Cannot have multiple AND or OR operators at the same level without proper grouping
String Literals
- Must be enclosed in single quotes (
"
) for string comparisons - Example:
TR:UserRole == "admin"
Supported Operators
The SDK supports 18 different operators organized into four categories: Logical Operators:AND
: Logical AND operator for combining conditionsOR
: Logical OR operator for alternative conditionsNOT
: Logical NOT operator for negation (placement and usage restrictions apply)
==
(equals): Checks if two values are equal!=
(not equals): Checks if two values are not equal>
(greater than): Checks if left value is greater than right value<
(less than): Checks if left value is less than right value>=
(greater than or equal): Checks if left value is greater than or equal to right value<=
(less than or equal): Checks if left value is less than or equal to right value
+
(addition): Arithmetic addition operator-
(subtraction): Arithmetic subtraction operator*
(multiplication): Arithmetic multiplication operator/
(division): Arithmetic division operator
=
(assignment): Sets a value+=
(add and assign): Adds to existing value-=
(subtract and assign): Subtracts from existing value*=
(multiply and assign): Multiplies existing value/=
(divide and assign): Divides existing value
()
- Parentheses for operation precedence and logical grouping
Order of operations is not assumed, it must be explicit. Any combination of more than 2 boolean expressions must be grouped using parentheses. For example:
- Not Supported:
1 == 1 AND 2 == 2 OR 3 == 4
- Supported:
1 == 1 AND (2 == 2 OR 3 == 4)
Effects (positiveEffects
and negativeEffects
)
Effects under the positiveEffects
property are triggered if the rule Condition evaluates to TRUE. Effects under the negativeEffects
property are triggered if the rule condition evaluates to false
. Effects can be one of four types: revert, event, tracker update, or foreign call.
Revert Effects
A revert effect will revert the transaction when triggered. The syntax is:revert(“Revert message”)
, where the message is optional, so could also simply use revert
. The message length limit is 32 bytes.
Event Effects
A event effect will emit an event when triggered. The syntax is:emit <Event message>
, for example emit Whale alert!
. This uses a generic event and logs the message.
Tracker Update Effects
A tracker update effect will update a tracker’s value when triggered. The syntax isTRU:<trackerName> <updateOperator> <expression>
, for example TRU:largeTransactionCount += 1
.
The syntax for mapped tracker updates is TRU:<trackerName>(<key>) <updateOperator> <expression>
, for example TRU:largeTransactionCount(sender) += 1
.
The name of the tracker is the name defined in the Trackers.name
property.
One of the following update operators must be used:
+=
: add the value following the operator to the current value of the tracker (both tracker and value must beuint256
types)-=
: subtract the value following the operator from the current value of the tracker (both tracker and value must beuint256
types)*=
: multiply the value following the operator by the current value of the tracker (both tracker and value must beuint256
types)/=
: divide the tracker by the value following the operator (both tracker and value must beuint256
types)=
: assign the value of the tracker to the value after the operator (all types supported,uint256
,address
,bytes
,string
)
<
, >
, ==
, AND
, OR
) since trackers cannot be booleans.
Special considerations should be taken when utilizing a tracker within an Open policy. Since the
policy is open, any/all contracts may subscribe to the policy, therefore, update the trackers.
Foreign Call Effects
A foreign call effect will call a foreign contract when triggered. The syntax is the same as when using a foreign call to get a value for an expression, e.g.FC:UpdateVIPStatus
.