System transactions reference
The StableSystem precompile exposes Stable protocol data and events through a fixed EVM contract interface. In v1.8.0, any client can query the guaranteed blockspace registry, while only protocol-generated transactions can emit system logs.
Contract
The precompile uses the same address on Mainnet and Testnet:
0x0000000000000000000000000000000000009999
| Method | Selector | Access | Gas limit | Purpose |
|---|---|---|---|---|
blockspaceLanes() | 0x2c0ac3be | Anyone, read-only | 10,000 | Return the active Enterprise and transaction-type lane registry. |
notifySystemTxLogs() | 0xe8e983b7 | System transaction sender only | 50,000 | Process up to 100 queued system log entries. |
Use this Solidity interface for the v1.8.0 ABI:
// SAFE: This interface matches the Stable v1.8.0 StableSystem ABI.
struct EnterpriseLane {
uint64 id;
string name;
uint32 weight;
}
struct TxTypeLane {
uint64 id;
string name;
address[] toAddrs;
bytes4[] methods;
uint8[] txTypes;
uint64[] nonceKeys;
address[] senders;
uint32 weight;
bool noOverflow;
}
struct BlockspaceLanes {
uint32 maxBlockspaceGasWeight;
EnterpriseLane[] enterpriseLanes;
TxTypeLane[] txTypeLanes;
}
interface IStableSystem {
event UnbondingCompleted(
address indexed delegator,
address indexed validator,
uint64 indexed originBlockHeight,
uint256 amount
);
function notifySystemTxLogs() external;
function blockspaceLanes()
external
view
returns (BlockspaceLanes memory lanes);
}blockspaceLanes()
blockspaceLanes() returns the governance-controlled lane registry used during block proposal and validation. It is a normal eth_call, not a custom JSON-RPC method, and it does not require an Enterprise gateway.
Both lane arrays are sorted by id in ascending order. Lower IDs have higher match priority.
Return value
| Field | Type | Description |
|---|---|---|
maxBlockspaceGasWeight | uint32 | Percentage from 0 to 100 of the block gas limit reserved across all configured lanes. |
enterpriseLanes | EnterpriseLane[] | Enterprise lane definitions. Governance allows at most one Enterprise lane. |
txTypeLanes | TxTypeLane[] | Lanes whose match rules inspect transaction fields. |
Enterprise lane
Any CustomTx whose NonceKey has bit 63 set routes to the configured Enterprise lane, except MaxUint64. The lower 63 bits select an independent nonce channel, not a lane.
| Field | Type | Description |
|---|---|---|
id | uint64 | Drain-order priority and identifier. |
name | string | Human-readable lane name. |
weight | uint32 | Percentage from 0 to 100 of the reserved blockspace pool assigned to the lane. |
Transaction-type lanes
A transaction must match every populated matcher field. Entries within one field are alternatives, and an empty matcher is a wildcard.
| Field | Type | Description |
|---|---|---|
id | uint64 | Lane priority and identifier. Lower IDs match first. |
name | string | Human-readable lane name. |
toAddrs | address[] | Allowed destination addresses. Empty matches any destination. |
methods | bytes4[] | Allowed four-byte function selectors. Empty matches any selector. |
txTypes | uint8[] | Allowed transaction formats. Empty or an entry of 0 matches any format. |
nonceKeys | uint64[] | Allowed nonce keys. Empty or an entry of 0 matches any key. |
senders | address[] | Allowed sender addresses. Empty matches any sender. |
weight | uint32 | Percentage from 0 to 100 of the reserved blockspace pool assigned to the lane. |
noOverflow | bool | When true, unused capacity does not cascade to later lanes. |
txTypes uses these TxFormat values:
| Value | Transaction format | EVM type |
|---|---|---|
0 | Wildcard | Any |
1 | Legacy | 0x00 |
2 | Access list | 0x01 |
3 | Dynamic fee | 0x02 |
4 | Set code | 0x04 |
5 | Two-dimensional nonce | 0x3F |
Query the registry
Call the precompile with Foundry's cast command:
cast call \
0x0000000000000000000000000000000000009999 \
"blockspaceLanes()((uint32,(uint64,string,uint32)[],(uint64,string,address[],bytes4[],uint8[],uint64[],address[],uint32,bool)[]))" \
--rpc-url https://rpc.stable.xyzThe v1.8.0 Mainnet activation seeded a 20% reserved pool and one Enterprise lane with 50% of that pool. Governance can change this output.
(20, [(1, "enterprise", 50)], [])notifySystemTxLogs()
notifySystemTxLogs() reads queued protocol log entries from state and processes up to 100 per call. It takes no arguments and returns no value.
Only a system transaction with sender 0x0000000000000000000000000000000000000001 can call this method. Calls from users or contracts revert.
When an unbonding completes, the flow is:
- The staking module completes the operation and records its SDK event.
- The
x/stablemodule queues the event data and its original block height. - The next block proposer creates a system transaction that calls
notifySystemTxLogs(). - The precompile emits EVM logs for up to 100 queued entries.
- Clients read the logs with
eth_getLogs, a WebSocket subscription, or a block explorer.
Entries above the batch limit stay queued for a later block.
UnbondingCompleted event
| Parameter | Type | Indexed | Description |
|---|---|---|---|
delegator | address | Yes | Address whose delegated tokens finished unbonding. |
validator | address | Yes | Validator address derived from its validator-operator address. |
originBlockHeight | uint64 | Yes | Block height at which the SDK-layer unbonding originally completed. |
amount | uint256 | No | Amount that finished unbonding. |
The EVM log appears in the block containing the system transaction. Use originBlockHeight when you need the height of the original SDK event.
Security model
- The protocol creates system transactions during block proposal.
- EVM state-transition rules reserve sender
0x0000000000000000000000000000000000000001for system transactions. - User transactions cannot forge the sender or call
notifySystemTxLogs()successfully. blockspaceLanes()is intentionally public and cannot change state.
Where to go next
- Guaranteed blockspace: Understand how the returned weights and matchers control reserved capacity.
- Track unbonding completions: Subscribe to
UnbondingCompletedand query historical events. - System transactions: Understand how protocol events become EVM logs.

