> ## Documentation Index
> Fetch the complete documentation index at: https://docs.immutable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Operator Allowlist

The Operator Allowlist restricts which addresses can transfer your tokens, ensuring royalties are enforced by only allowing transfers through compliant marketplaces like [Immutable's Orderbook](/docs/products/orderbook/overview).

<Card title="Contracts Repository" icon="github" href="https://github.com/immutable/contracts/blob/main/contracts/allowlist/OperatorAllowlistEnforced.sol">
  View the Operator Allowlist source code
</Card>

## Why It's Required

The Operator Allowlist protects game studios from:

* **Vampire attacks**: Unauthorized marketplaces bypassing royalties
* **Protocol fee evasion**: Trading outside Immutable's ecosystem
* **Revenue loss**: Transactions that don't pay creator royalties

<Warning>
  **Mandatory Compliance**: All ERC-721 and ERC-1155 collections on Immutable Chain must implement the Operator Allowlist.
</Warning>

### Non-Compliance Consequences

* Forfeit any token grants received
* Passport users see warnings that your collection may be counterfeit
* Exclusion from ecosystem marketplaces (TokenTrove, GameStop NFT, etc.)

## How It Works

The allowlist is a registry of approved operator addresses:

| Address Type               | Example                               |
| -------------------------- | ------------------------------------- |
| **Contract Address**       | Seaport settlement contract           |
| **Bytecode Hash**          | Smart contract wallet implementations |
| **Implementation Address** | Proxy contract targets                |

### Enforcement Flows

**Approvals** (`approve`, `setApprovalForAll`):

| Scenario                       | Allowed |
| ------------------------------ | ------- |
| Target is an EOA (user wallet) | ✅       |
| Target has approved bytecode   | ✅       |
| Target has approved address    | ✅       |
| Unapproved smart contract      | ❌       |

**Transfers** (`transferFrom`, `safeTransferFrom`):

| Scenario                       | Allowed |
| ------------------------------ | ------- |
| Caller is an EOA               | ✅       |
| Caller is approved marketplace | ✅       |
| Unapproved contract            | ❌       |

## Implementation

### Using Preset Contracts

All [Immutable preset contracts](/docs/products/asset-contracts/overview) and contracts deployed via [Hub](https://hub.immutable.com) include Operator Allowlist protection by default.

### Custom Contracts

For custom contracts, inherit from `OperatorAllowlistEnforced.sol`:

```solidity theme={null}
import "@imtbl/contracts/contracts/allowlist/OperatorAllowlistEnforced.sol";

contract MyNFT is ERC721, OperatorAllowlistEnforced {
    constructor(address allowlist) {
        _setOperatorAllowlistRegistry(allowlist);
    }
    
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal override {
        // Check operator allowlist for transfers
        if (from != address(0) && to != address(0)) {
            require(
                _isAllowlisted(msg.sender),
                "Operator not allowlisted"
            );
        }
        super._beforeTokenTransfer(from, to, tokenId);
    }
}
```

## Operator Allowlist Addresses

Get the current address from the Immutable API:

| Network     | Chain ID       | API Endpoint                                                                 |
| ----------- | -------------- | ---------------------------------------------------------------------------- |
| **Testnet** | `eip155:13473` | `https://api.sandbox.immutable.com/v1/chains` → `operator_allowlist_address` |
| **Mainnet** | `eip155:13371` | `https://api.immutable.com/v1/chains` → `operator_allowlist_address`         |

```bash theme={null}
# Get testnet address
curl https://api.sandbox.immutable.com/v1/chains | jq '.result[] | select(.name == "imtbl-zkevm-testnet") | .operator_allowlist_address'

# Get mainnet address  
curl https://api.immutable.com/v1/chains | jq '.result[] | select(.name == "imtbl-zkevm-mainnet") | .operator_allowlist_address'
```

<Info>
  Immutable manages the allowlist with pre-approved addresses including Seaport and smart contract wallet deployments. Use this instead of deploying your own.
</Info>

## Request Allowlist Addition

To add your contract to the Operator Allowlist:

<Steps>
  <Step title="Verify Contract">
    Verify your contract on [Immutable Explorer](https://explorer.immutable.com/contract-verification). See the [verification guide](/docs/products/asset-contracts/erc721#deploy-via-code).
  </Step>

  <Step title="Link Contract">
    In [Hub](https://hub.immutable.com), go to **Contracts** and click **Link Contract**.
  </Step>

  <Step title="Request OAL Addition">
    On your contract's detail page, click **Add to OAL** and follow the instructions.
  </Step>

  <Step title="Wait for Approval">
    * **Testnet**: Typically seconds (automated)
    * **Mainnet**: Up to one week (manual review)
  </Step>
</Steps>

## Pre-Approved Operators

The following are already on the Operator Allowlist:

* [Immutable Orderbook](/docs/products/orderbook/overview)
* Immutable smart contract wallets
* Major ecosystem marketplaces

## Interface

The `IOperatorAllowlist` interface provides:

```solidity theme={null}
interface IOperatorAllowlist {
    /// @notice Check if an address is allowlisted
    /// @param target The address to check
    /// @return bool True if allowlisted
    function isAllowlisted(address target) external view returns (bool);
}
```

<CardGroup cols={2}>
  <Card title="Royalties" icon="coins" href="/docs/products/asset-contracts/royalties">
    Configure royalty payments
  </Card>

  <Card title="Deploy Contract" icon="rocket" href="/docs/products/asset-contracts/overview">
    Deploy a compliant contract
  </Card>
</CardGroup>
