Syntax for Defining a Policy

Policies are submitted to the Rules Engine SDK in the form of a JSON string, with the following available tags:

  • Policy: a string representing the name of the policy
  • ForeignCalls (optional): an array of Foreign Call JSON objects (defined below)
  • Trackers (optional): an array of Tracker JSON objects (defined below)
  • RulesJSON: an array of Rule JSON objects (defined below)

If you are not yet familiar with the concepts of Foreign Calls, Trackers, and Rules, check out our Concepts docs.

Here is a starting example:

{
  "Policy": "Alice's Policy",
  "ForeignCalls": [
    {
      "name": "GetAccessLevel",
      "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
      "signature": "accessLevel(address)",
      "returnType": "uint256",
      "parameterTypes": "address",
      "encodedIndices": "0"
    }
  ],
  "Trackers": [
    {
      "name": "largeTransactionCount",
      "type": "uint256",
      "defaultValue": 0
    }
  ],
  "RulesJSON": [
    {
      "condition": "(receiverBalance + amount > 100) AND (FC:GetAccessLevel < 1)",
      "positiveEffects": [
        "revert(\"Recipient Access Level too low to increase balance above 100\")"
      ],
      "negativeEffects": [],
      "functionSignature": "transfer(address recipient, uint256 amount)",
      "encodedValues": "address recipient, uint256 amount, uint256 receiverBalance"
    },
    {
      "condition": "amount > 10000",
      "positiveEffects": ["emit Whale alert", "TRU:largeTransactionCount += 1"],
      "negativeEffects": [],
      "functionSignature": "transfer(address recipient, uint256 amount)",
      "encodedValues": "address recipient, uint256 amount, uint256 receiverBalance"
    }
  ]
}

Foreign Calls

The ForeignCalls tag 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 tags:

  • name: The name of the foreign call (this is how it will be referred to in Rule condition and effect expressions)
  • address: The address of the foreign contract being called
  • signature: The function signature of the function that will be called on the foreign contract
  • returnType: The return type of the function (currently supported types include: uint256, address, bytes and string)
  • parameterTypes: A comma delimited list of the types of each of the parameters to the function (currently supported types include: uint256, address, bytes and string)
  • encodedIndices: Currently, arbitrary data cannot be passed into the foreign call parameters. Only the data incoming from the Calling Contract can be used (the encodedValues in the Rule). This encodedIndices is a mapping of the encodedValues that will be utilized in the parameters to the foreign call. For foreign calls with more than one parameter the encodedIndicies is represented as a comma separated list of indices, for example 0, 1, 2.
    • For example, imagine the Rule’s encodedValues are address to, uint256 value. You want to pass the address as the foreign call parameter, so you would set "encodedIndices": "0"

Trackers

The Trackers tag 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 tags:

  • name: The name of the tracker (this is how it will be referred to in Rule condition and effect expressions)
  • type: The type of the tracker (currently supported types include: uint256, address, bytes and string)
  • defaultValue: The initial value of the tracker

Rules

Now’s the fun part! The RulesJSON tag contains an array of Rules JSON objects. These represent all of the Rules that are configured for the policy. Each object consists of the following tags:

  • condition: a string representing a condition expression for the rule which must evaluate to a boolean (true or false) result. Specifics defined below
  • positiveEffects: an array of effect expressions to be executed if the condition evaluates to TRUE. Specifics defined below.
  • negativeEffects: an array of effect expressions to be executed if the condition evaluates to FALSE. Specifics defined below.
  • functionSignature: a string representation of the function signature this rule will be attached to, for example transfer(address recipient, uint256 amount)
  • encodedValues: a list of values that will be encoded along with the call to the rules engine from the calling contract, for example address recipient, uint256 amount, uint256 receiverBalance

Condition

Condition expressions must evaluate to a boolean result. A condition expression consists of values combined using operators, for example (receiverBalance + amount < 100) AND (FC:GetAccessLevel > 1).

Values available to use in condition 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 example TR:largeTransactionCount
    • 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 example FC:GetAccessLevel

Operators available to use in condition expressions:

  • +: Add two values. Static values or references (must be uint values)
  • -: Subtract two values. Static values or references (must be uint values)
  • *: Multiply two values. Static values or references (must be uint values)
  • /: divide two values. Static values or references (must be uint values)
  • <: perform a less than comparison of two values. Static values or references (must be uint values)
  • >: perform a greater than comparison of two values. Static values or references (must be uint values)
  • <=: perform a less than or equal to comparison of two values. Static values or references (must be uint values)
  • >=: perform a greater than or equal to comparison of two values. Static values or references (must be uint values)
  • ==: perform an equal to comparison of two values. Static values or references (all types supported)
  • AND: perform an AND operation on two expressions.
  • OR: perform an OR operation on two expressions.
  • ( and ) : parenthesis allow for multiple “combined expressions” (described in detail in the NOTE below)

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 tag are triggered if the rule Condition evaluates to TRUE. Effects under the negativeEffects tag are triggered if the rule Condition evaluates to FALSE. Effects can be one of four types: revert, event, tracker update, 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.

Event Effects

A event effect will emit an event when triggered. The syntax is: emit <Event message>, for example emit Whale alert!.

Tracker Update Effects

A tracker update effect will update a tracker’s value when triggered. The syntax is TRU:<trackerName> <updateOperator> <expression>, for example TRU:largeTransactionCount += 1.

The name of the tracker is the name defined in the Trackers tag.

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 be uint256 types)
  • -=: subtract the value following the operator from the current value of the tracker (both tracker and value must be uint256 types)
  • *=: multiply the value following the operator by the current value of the tracker (both tracker and value must be uint256 types)
  • /=: divide the tracker by the value following the operator (both tracker and value must be uint256 types)
  • =: assign the value of the tracker to the value after the operator (all types supported, uint256, address, bytes, string)

For the expression, this follows the same syntax as Condition expressions. Except, you will not use any relational or boolean operators (<, >, ==, AND, OR) since trackers cannot be booleans.

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.