Matador Docs
Guides

Policy Authoring Workflow

A step-by-step guide to the lifecycle of a Matador policy.

Authoring Matador policies is a structured process that transforms high-level security requirements into immutable on-chain enforcement. This guide walks you through the complete development lifecycle.

Requirements Gathering

Before writing code, define the strict security bounds of the policy.

  • Who is the actor? (e.g., an automated bot, a junior admin)
  • Where can they interact? (e.g., Uniswap Router, specific ERC20 tokens)
  • What functions can they call? (e.g., exactInputSingle, transfer)
  • How much can they spend? (e.g., max 1 ETH per day)

Environment Setup

Ensure you have the Matador CLI installed and your project directory structured. It is recommended to keep your ABIs in a dedicated folder.

# Install the CLI
npm install -D matador-policy-cli

# Create structure
mkdir policies abis

Writing the Policy

Create a new .matador file. Start by importing necessary ABIs and defining the parameters.

policies/swap-guard.matador
import "abis/UniswapRouter.json" as Uniswap;

permission SwapGuard -> 1.0.0 {
    parameters: {
        router: address
    }
    when: {
        all {
            context.target == parameters.router,
            context.selector == Uniswap.exactInputSingle.selector
        }
    }
}

Compilation & Validation

Use the CLI to compile your policy. The compiler performs static analysis to catch type mismatches and syntax errors before deployment.

npx matador-policy-cli compile policies/swap-guard.matador -d ./out

Compiler Feedback

The compiler will report precise errors (e.g., Type mismatch: expected address, got uint256) to help you debug your logic.

Testing (Foundry)

Before deploying to a live account, test your policy bytecode using Foundry. Create mock execution contexts to simulate both valid and invalid transactions.

function testPolicy() public {
    // Load compiled bytecode
    bytes memory bytecode = vm.readFile("./out/swap-guard.json");
    
    // 1. Test Valid Transaction (Should Pass)
    interpreter.enforce(bytecode, subject, validExec);
    
    // 2. Test Invalid Transaction (Should Revert)
    vm.expectRevert();
    interpreter.enforce(bytecode, subject, invalidExec);
}

Provisioning

Once tested, provision the policy to your smart account on-chain. This usually involves calling a grantPermission function on your account contract.

// On-chain transaction
smartAccount.grantPermission(permissionId, compiledBytecode);

Continuous Integration

For production environments, it is recommended to automate this workflow.

  1. Lint: Run matador-policy-cli format --check in CI to ensure code style.
  2. Compile: Run the compiler to verify all policies are valid.
  3. Test: Run forge test to execute your policy test suite against the latest bytecode.

On this page