Matador Docs
API Reference

Contract Interfaces

Technical reference for the Matador smart contract ecosystem.

This reference documents the core interfaces, data structures, and errors used by the on-chain components of Matador.

IPermissionInterpreter

The IPermissionInterpreter is the heart of the system. It executes the compiled bytecode to validate transactions.

contracts/src/interfaces/IPermissionInterpreter.sol
interface IPermissionInterpreter {
    function enforce(
        bytes memory context,
        address subject,
        ExecutionContext calldata exec
    ) external;

    function callBool(
        bytes memory context,
        bytes4 selector,
        bytes memory args,
        address subject,
        ExecutionContext calldata exec
    ) external view returns (bool);

    function callUint256(
        bytes memory context,
        bytes4 selector,
        bytes memory args,
        address subject,
        ExecutionContext calldata exec
    ) external view returns (uint256);

    function callBytes32(
        bytes memory context,
        bytes4 selector,
        bytes memory args,
        address subject,
        ExecutionContext calldata exec
    ) external view returns (bytes32);

    function callAddress(
        bytes memory context,
        bytes4 selector,
        bytes memory args,
        address subject,
        ExecutionContext calldata exec
    ) external view returns (address);
}

ExecutionContext

The ExecutionContext struct contains all runtime metadata available to the interpreter during a policy check.

PropertyTypeDescription
calleraddressThe address initiating the execution (usually the entry point or msg.sender).
targetaddressThe destination contract address.
valueuint256The native value (Wei) sent with the call.
databytesThe transaction calldata.
gasLimituint256The gas limit for the execution.
gasPriceuint256The gas price (or max fee per gas) of the transaction.
nonceuint256The nonce of the smart account.
blobBaseFeeuint256The base fee for blob gas (EIP-4844).
blobGasPriceuint256The blob gas price.

Methods

enforce

Executes the reserved fn main() -> bool lifecycle entry in a mutable context. Successful execution requires main() to return canonical true; persistence writes are flushed only on that successful path.

  • Reverts: If any condition in the policy fails.
  • Gas: Costs vary based on the policy complexity and state access.

Typed Read Callables

Executes a public read callable selected by its canonical function selector. These APIs are for query surfaces such as validate() or remainingDailySpend().

Read Callables

Public callable functions are read-only in the initial implementation. Use enforce for the write-capable main() lifecycle path.

bytes memory policy = account.permission(policyId);
IPermissionInterpreter.ExecutionContext memory exec = IPermissionInterpreter.ExecutionContext({
    caller: msg.sender,
    target: target,
    value: value,
    data: data,
    gasLimit: 0,
    gasPrice: 0,
    nonce: 0,
    blobBaseFee: 0,
    blobGasPrice: 0
});

bool ok = interpreter.callBool(
    policy,
    bytes4(keccak256("validate()")),
    "",
    accountOwner,
    exec
);

uint256 nav = interpreter.callUint256(
    policy,
    bytes4(keccak256("nav(address)")),
    abi.encode(vault),
    accountOwner,
    exec
);

Callable Bytecode Notes

Callable bytecode starts with the callable format header and a fixed-size function table before the instruction section. The reserved main() lifecycle entry has function id 0 and selector 0x00000000; public entries are sorted by canonical selector and carry return type, argument count, argument type tags, local count, stack bound, flags, and body offsets.

Every execution path runs preflight before dispatch. Preflight rejects malformed headers, unsupported versions, duplicate public selectors, non-public selectors, overlapping or gapped function bodies, invalid branch targets, invalid CALL_FN targets, unsupported type tags, local/stack limit violations, and read entries that can reach write-classified behavior.

IModuleRegistry

The registry maps 1-byte module IDs to their deployed contract addresses.

contracts/src/interfaces/IModuleRegistry.sol
interface IModuleRegistry {
    function getModule(uint8 moduleId) external view returns (address module);
}

Errors

Matador uses custom errors for gas efficiency and clarity.

Permission Errors

Errors thrown when a specific policy condition fails.

ErrorParametersDescription
UnknownOpcodeuint8 opcodeThe bytecode contained an undefined opcode.
InvalidCondition-A logical condition (AND/OR) was malformed.
RateLimitExceededcount, limit, resetA rate limit has been breached.
BalanceCheckFailedtoken, account, req, actToken or native balance requirements were not met.
CallerCheckFailedrequired, actualThe caller is not allowed.
PermissionExpiredexpiry, currentThe policy includes an expiry timestamp that has passed.

System Errors

Errors related to the interpreter's internal execution or account management.

ErrorParametersDescription
Unauthorized-Caller is not authorized to grant/revoke permissions.
StackOverflow-Policy complexity exceeded the interpreter's stack limit (1024).
StackUnderflow-An opcode attempted to pop from an empty stack.
PermissionNotFoundbytes32 idThe requested permission ID does not exist on the account.

On this page