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 policyPolicyType
: eitheropen
orclosed
(any contract can subscribe to an open policy whereas closed policies must approve the calling contract)ForeignCalls
(optional): an array of Foreign Call JSON objects (defined below)Trackers
(optional): an array of Tracker JSON objects (defined below)MappedTrackers
(optional): an array of Mapped Tracker JSON objects (defined below)Rules
: an array of Rule JSON objects (defined below)
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 (can also be the same as the functionSignature)functionSignature
: The signature of the calling function, which includes argument types and namesencodedValues
: a list of values that will be encoded along with the call to the rules engine from the calling contract
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 (this is how it will be referred to in Rule condition and effect expressions). This must include parentheses at the end, with at least one character in between the parentheses (the characters between the parentheses have no significance, this is a bit of a design bug we will remove soon).address
: The address of the foreign contract being calledfunction
: The function signature of the function that will be called on the foreign contractreturnType
: The return type of the function (currently supported types include:uint256
,address
,bytes
andstring
)valuesToPass
: Currently, arbitrary data cannot be passed into the foreign call parameters. Only the data incoming from the Calling Contract can be used (theencodedValues
in the Rule). ThisvaluesToPass
is a mapping of theencodedValues
that will be utilized in the parameters to the foreign call. For foreign calls with more than one parameter thevaluesToPass
is represented as a comma separated list of indices, for example0, 1, 2
- For example, imagine the Rule’s
encodedValues
areaddress to, uint256 value
. You want to pass the address as the foreign call parameter, so you would set"valuesToPass": "0"
- For example, imagine the Rule’s
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 (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
andstring
)initialValue
: The initial value of the tracker
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 (this is how it will be referred to in Rule condition and effect expressions)keyType
: The key type of the tracker (currently supported types include:uint256
,address
,bytes
andstring
)valueType
: The value type of the tracker (currently supported types include:uint256
,address
,bytes
andstring
)initialKeys
: The initial keys of the trackerinitialValues
: The initial values of the tracker
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.Description
: A description of the rule.condition
: a string representing a conditional expression for the rule which must evaluate to a boolean (true or false) result. Specifics defined belowpositiveEffects
: 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.callingFunction
: a string representation of the function signature this rule will be attached to, for exampletransfer(address recipient, uint256 amount)
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
In the current version, strings are not character-delimited when using the SDK. Therefore, do not
use special characters in strings like
AND
and OR
or you will have unexpected behavior. If you
use them in lowercase, there will be no problem.+
: 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
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
.