> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://docs.prividium.com/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

System contracts are contract records whose metadata comes from a hardcoded registry inside Prividium™. The system
manages their address, ABI, name, and configuration automatically. Administrators cannot create, edit, or delete system
contracts through the API or Admin Dashboard.

Permissions (function and event access rules) work exactly like regular contracts. Administrators can assign, modify,
and remove permission rules on system contracts without restriction.

### How system contracts work

#### Registry

Prividium™ ships with a built-in registry of system contract definitions. Each entry specifies a contract address, ABI,
name, description, disclosure settings, and `templateId: null`. All registry contracts belong to the zone, with
`organizationId: null`. The registry includes:

| Contract                 | Address                                      |
| ------------------------ | -------------------------------------------- |
| L2BaseToken              | `0x000000000000000000000000000000000000800A` |
| L2AssetRouter            | `0x0000000000000000000000000000000000010003` |
| L2NativeTokenVault       | `0x0000000000000000000000000000000000010004` |
| InteropCenter            | `0x000000000000000000000000000000000001000d` |
| L2Bridgehub              | `0x0000000000000000000000000000000000010002` |
| L2InteropAttributeParser | `0x0000000000000000000000000000000000010015` |
| L2BaseTokenHolder        | `0x0000000000000000000000000000000000010011` |
| L2AssetTracker           | `0x000000000000000000000000000000000001000f` |
| SystemContext            | `0x000000000000000000000000000000000000800B` |
| L1Messenger              | `0x0000000000000000000000000000000000008008` |
| L1MessengerHook          | `0x0000000000000000000000000000000000007001` |

#### Strict sync at startup

On every startup, Prividium™ runs a strict sync before serving traffic:

1. Upserts all registry contracts into the database with `isSystemContract=true`.
2. Overwrites registry metadata (address, ABI, name, description, disclosure settings) and sets `organizationId` and
   `templateId` to `null`.
3. Preserves directly assigned function and event permissions.
4. Deletes any database rows marked `isSystemContract=true` whose address no longer appears in the registry.
5. Emits audit log entries for every create, update, or delete operation.

If sync fails for any reason, the server exits with code `1` and does not serve traffic. Check the application logs for
the specific error.

Before upgrading, review existing registrations at registry addresses. Sync clears their template links, so
template-derived permissions and argument restrictions no longer apply. Reconcile those rules before restarting;
preserving direct permission rows does not preserve template-derived rules.

#### Immutable metadata

The API rejects metadata mutations on system contracts with HTTP `400`:

* `POST /api/contracts` with a system contract address returns `400`.
* `PUT /api/contracts/:contractAddress` on a system contract returns `400`.
* `DELETE /api/contracts/:contractAddress` on a system contract returns `400`.
* Template linking attempts on system contracts return `400`.
* Creating or moving a contract into a system contract address returns `400`.

The backend registry is authoritative. Even if client-side validation is bypassed, the API enforces these rules.

### System contracts in the Admin Dashboard

System contracts appear in the regular contract listing with a **System** badge.

On the contract detail page:

* **Edit** and **Delete** buttons are hidden.
* Template linking is disabled.
* The **Function Permissions** and **Event Permissions** tabs remain fully functional.

The **Add Contract** form validates the address field against known system contract addresses and blocks submission if
the address matches.

### System contracts in API responses

All contract endpoints include the `isSystemContract` boolean field:

```jsonc
{
  "contractAddress": "0x0000000000000000000000000000000000010004",
  "name": "L2NativeTokenVault",
  "isSystemContract": true
  // ... other fields
}
```

Regular contracts return `isSystemContract: false`.

### Managing permissions on system contracts

Direct calls to system contracts follow the same deny-by-default model as regular contracts. Sync creates no permission
rules; functions without rules default to **Forbidden**. Configure permissions through the Admin Dashboard or API:

1. Open the contract detail page for the system contract.
2. Select the **Function Permissions** or **Event Permissions** tab.
3. Assign permission levels (All Users, Check Role, Restrict Argument) as needed.

Directly assigned function and event permission rules persist across restarts.

Bridge entry points call other system contracts internally: `InteropCenter.sendBundle`, `L2BaseToken.withdraw` and
`L2AssetRouter.withdraw` all make further calls to complete an L2→L1 withdrawal. When the
[policy listener](/configuring/contracts/permissions#8-enforcement-across-internal-calls) is configured, every internal
call is permission-checked, so allowing the entry method alone is not enough. Enable **Umbrella** on its permission so
the inner calls are covered. Without it the inner calls are denied and the withdrawal fails.

An umbrella permission authorizes the calls made by a permitted entry point. In multi-org mode, six shared bridge
dependencies limit this inherited access to code-listed methods. Other methods require their own permissions.
See [Umbrella Permissions in Multi-Org Mode](/configuring/chain/bridging#umbrella-permissions-in-multi-org-mode) for
the method policy and optional accounting reads.

To enable ETH and ERC-20 bridging, see [Enabling Bridging](/configuring/chain/bridging) for the entry-point permissions
and per-token setup.

### Audit logs

Sync operations generate audit log entries with an anonymous identity (`system-contracts-sync`). Each create, update,
and delete action during sync produces a separate audit record with `trigger: system-contracts-sync` metadata.
