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.
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.
| Property | Type | Description |
|---|---|---|
caller | address | The address initiating the execution (usually the entry point or msg.sender). |
target | address | The destination contract address. |
value | uint256 | The native value (Wei) sent with the call. |
data | bytes | The transaction calldata. |
gasLimit | uint256 | The gas limit for the execution. |
gasPrice | uint256 | The gas price (or max fee per gas) of the transaction. |
nonce | uint256 | The nonce of the smart account. |
blobBaseFee | uint256 | The base fee for blob gas (EIP-4844). |
blobGasPrice | uint256 | The 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.
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.
| Error | Parameters | Description |
|---|---|---|
UnknownOpcode | uint8 opcode | The bytecode contained an undefined opcode. |
InvalidCondition | - | A logical condition (AND/OR) was malformed. |
RateLimitExceeded | count, limit, reset | A rate limit has been breached. |
BalanceCheckFailed | token, account, req, act | Token or native balance requirements were not met. |
CallerCheckFailed | required, actual | The caller is not allowed. |
PermissionExpired | expiry, current | The policy includes an expiry timestamp that has passed. |
System Errors
Errors related to the interpreter's internal execution or account management.
| Error | Parameters | Description |
|---|---|---|
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. |
PermissionNotFound | bytes32 id | The requested permission ID does not exist on the account. |