DSL Syntax
The complete grammar and syntax reference for the Matador DSL.
The Matador DSL (Domain-Specific Language) is a human-readable language designed for defining secure, gas-optimized permission policies. It compiles down to compact bytecode executable by the on-chain interpreter.
File Structure
A standard .matador policy file consists of four main sections.
Imports
Import external ABI definitions to enable type-safe checking of contract calls and calldata.
import "abis/UniswapV3.json" as Uniswap;Declaration
Define the policy name and semantic version. This helps with off-chain indexing and management.
permission SwapPolicy -> 1.0.0 {Metadata & Parameters
Define off-chain metadata (author, description) and runtime parameters that the policy expects.
metadata: {
author: "Steer Finance",
description: "Limits swap amount"
}
parameters: {
token: address,
maxAmount: uint256
}Condition Block
The core logic. The when block contains the rules that must evaluate to true for the transaction to succeed.
when: {
Uniswap.swap(amount: context.amount),
context.amount <= parameters.maxAmount
}
} // End permissionContext Properties
The context object provides access to the runtime execution environment. These properties map directly to Solidity global variables or transaction fields.
| Property | Type | Description |
|---|---|---|
context.caller | address | The address initiating the execution (e.g., msg.sender equivalent). |
context.target | address | The contract being called. |
context.account | address | The smart account being controlled. |
context.value | uint256 | The ETH value (in wei) sent with the call. |
context.data | bytes | The raw calldata. |
context.blockNumber | uint256 | Current block number (block.number). |
context.timestamp | uint256 | Current block timestamp (block.timestamp). |
context.chainId | uint256 | Current chain ID (block.chainid). |
Advanced Context
Extended properties like gasPrice, baseFee, blobBaseFee, and prevRandao are also available for advanced use cases.
Operators
Matador supports standard comparison operators.
| Operator | Description | Logic |
|---|---|---|
== | Equal | Strict equality check. |
!= | Not Equal | Inequality check. |
> | Greater Than | a > b |
< | Less Than | a < b |
>= | Greater Than or Equal | a >= b |
<= | Less Than or Equal | a <= b |
Control Flow
Logical grouping allows you to combine multiple conditions.
all (AND)
Requires all nested conditions to be true. Equivalent to logical &&.
all {
context.value > 0,
context.target == parameters.allowedTarget
}any (OR)
Requires at least one nested condition to be true. Equivalent to logical ||. Short-circuits on the first success.
any {
context.caller == parameters.owner,
context.caller == parameters.guardian
}Contract Calls
You can check calldata against specific function signatures defined in your imported ABIs.
// Checks if the transaction is a call to 'transfer' on the 'Token' contract
// AND if the 'recipient' argument equals the 'allowedRecipient' parameter
Token.transfer(recipient: parameters.allowedRecipient)Deep Nested Access
You can access nested struct fields in calldata (e.g. params.exactInput.recipient), provided the ABI definition supports it.