Policy Patterns
Common recipes and best practices for Matador policies.
This library contains copy-pasteable patterns for common use cases. Mix and match these snippets to build robust security policies for your smart accounts.
Financial Safety Rails
Spending Limit
Restrict the maximum amount of ETH or tokens that can be transferred in a single transaction.
import "abis/ERC20.json" as Token;
permission SpendLimit -> 1.0.0 {
parameters: {
token: address,
maxAmount: uint256
}
fn main() -> bool {
if (context.target != parameters.token) {
return false;
}
if (context.selector == Token.transfer) {
return Token.transfer.amount == parameters.maxAmount;
}
return false;
}
}One-Time Subscription Charge
Allow a specific service provider to charge a fixed fee once until the policy is reset or replaced.
permission Subscription -> 1.0.0 {
parameters: {
serviceProvider: address,
fee: uint256
}
@persist let chargeCount: uint256 = 0;
fn main() -> bool {
if (context.caller != parameters.serviceProvider) {
return false;
}
if (context.value != parameters.fee) {
return false;
}
if (state.chargeCount >= 1) {
return false;
}
state.chargeCount = state.chargeCount + 1;
return true;
}
}Security & Access Control
Whitelist
Restrict interactions to a known list of safe contracts (e.g., official Uniswap routers).
permission SafeInteractions -> 1.0.0 {
parameters: {
router: address,
vault: address
}
fn main() -> bool {
if (context.target == parameters.router) {
return true;
}
return context.target == parameters.vault;
}
}Circuit Breaker
Block all transactions if an emergency flag is set in the policy parameters.
permission EmergencyStop -> 1.0.0 {
parameters: {
paused: bool
}
fn main() -> bool {
return parameters.paused == false;
}
}DeFi Automation
Swap with Slippage Protection
Allow an automated bot to execute swaps, but enforce a minimum output amount supplied by the policy parameters.
import "abis/UniswapV3.json" as Uniswap;
permission SafeSwap -> 1.0.0 {
parameters: {
router: address,
minAmountOut: uint256
}
fn main() -> bool {
if (context.target != parameters.router) {
return false;
}
if (context.selector == Uniswap.exactInputSingle) {
return Uniswap.exactInputSingle.params.amountOutMinimum == parameters.minAmountOut;
}
return false;
}
}Math Precision
Matador's core arithmetic opcodes operate on uint256. For complex fixed-point math or price conversions, it is recommended to use a Custom Module or a helper contract rather than implementing complex math directly in DSL.
Flash Loan Prevention
Prevent the account from being used as a flash loan borrower by ensuring the transaction origin matches the sender.
permission NoFlashLoan -> 1.0.0 {
parameters: {
trustedCaller: address
}
fn main() -> bool {
return context.caller == parameters.trustedCaller;
}
}