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

# State Transfer

> Overview of L1-L2 state transfer options on Polygon Chain, including state sync, FxPortal, and the token bridge.

Polygon Chain provides several contracts for passing data between Ethereum (L1) and Polygon (L2). They serve different purposes and operate at different levels of abstraction. The right choice depends on what you are transferring and in which direction.

## Ethereum to Polygon (L1 to L2)

Data flows from Ethereum to Polygon via the **state sync** mechanism. A contract on Ethereum calls `syncState` on the `StateSender` contract, which emits a `StateSynced` event. Heimdall validators relay this event to Bor, which calls `onStateReceive` on the target contract on Polygon within a single sprint (approximately 16 blocks, or a few minutes).

This mechanism is used internally by both the PoS token bridge and FxPortal. You can also use it directly for arbitrary data, subject to the registration requirement described below.

For a step-by-step implementation, see [Ethereum to PoS](/pos/how-to/bridging/ethereum-polygon/ethereum-to-matic/).

### Registration requirement

Sender/receiver pairs must be registered with `StateSender` before state sync will relay events between them. This registration authorizes the pair: Heimdall only processes `StateSynced` events from registered sender contracts targeting registered receiver contracts.

Registration is managed by the Polygon team. Contact the team on [Discord](https://discord.com/invite/0xPolygonCommunity) or via the [mapping request form](https://docs.google.com/forms/d/e/1FAIpQLSeq8HTef2dYpRx35_WWYhyr4C146K9dfhyYJQcoD1RuTTVABg/viewform) to register a new pair.

<Tip>
  If you need arbitrary message passing without registering a custom pair, FxPortal provides a pre-registered sender/receiver abstraction. See the [FxPortal contracts](#fxportal) below.
</Tip>

### Security in receiver contracts

The `onStateReceive` function on Polygon is called by the `StateReceiver` system contract at address `0x0000000000000000000000000000000000001001`. Always verify `msg.sender` against this address in your receiver implementation. Without this check, any address on Polygon can call `onStateReceive` directly and inject arbitrary data.

See the [state sync architecture docs](/pos/architecture/bor/state-sync/) for a full description of how state sync works.

## Polygon to Ethereum (L2 to L1)

Data flows from Polygon back to Ethereum via the **checkpoint and exit** mechanism. There is no continuous message relay in this direction. Instead:

1. A transaction on Polygon emits an event containing the data to transfer.
2. The transaction is included in a Polygon checkpoint, which is committed to Ethereum roughly every 30 minutes.
3. After the checkpoint is finalized on Ethereum, anyone can submit an exit proof to `RootChainManager` on Ethereum to trigger the corresponding state change on the root contract.

This is how the PoS bridge handles withdrawals: tokens are burned on Polygon, and after checkpoint, the lock is released on Ethereum. The same pattern works for arbitrary data.

For a step-by-step implementation, see [PoS to Ethereum](/pos/how-to/bridging/ethereum-polygon/matic-to-ethereum/).

## Choosing the right approach

| Need                                                                       | Recommended approach                                                                                                       |
| -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| Bridge a standard ERC-20, ERC-721, or ERC-1155 token                       | [Submit a mapping request](/pos/how-to/bridging/ethereum-polygon/submit-mapping-request/) and use the PoS bridge contracts |
| Send arbitrary data from Ethereum to Polygon without custom registration   | Use FxPortal (`FxRoot` / `FxChild`)                                                                                        |
| Send arbitrary data from Ethereum to Polygon with a custom registered pair | Raw state sync via `StateSender`                                                                                           |
| Send data from Polygon back to Ethereum                                    | Checkpoint and exit via `RootChainManager`                                                                                 |

If you are building fee collection or settlement infrastructure that bridges tokens from Polygon back to Ethereum from a smart contract, use the PoS bridge withdrawal path: call `withdraw` on the child ERC-20 contract on Polygon to burn tokens, then after checkpoint, call `exit` on `RootChainManager` on Ethereum to release the funds to your target address.

## Contract reference

The following contracts are used for L1-L2 messaging on mainnet. Source addresses are from the [canonical network config](https://github.com/0xPolygon/static/blob/master/network/mainnet/v1/index.json).

### State sync

These are the low-level contracts that underpin all L1-to-L2 messaging on Polygon Chain.

| Contract        | Network  | Address                                      | Purpose                                                                                                           |
| --------------- | -------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `StateSender`   | Ethereum | `0x28e4F3a7f651294B9564800b2D01f35189A5bFbE` | Entry point for L1→L2 messages. Registered sender contracts call `syncState` here.                                |
| `StateReceiver` | Polygon  | `0x0000000000000000000000000000000000001001` | Genesis contract that delivers state sync messages on Polygon by calling `onStateReceive` on the target contract. |

### FxPortal

FxPortal is Polygon's pre-registered messaging layer built on top of state sync. `FxRoot` is already registered as a sender in `StateSender`, and `FxChild` is its registered receiver on Polygon. You can inherit from `FxBaseRootTunnel` and `FxBaseChildTunnel` to build bidirectional messaging without needing custom registration.

| Contract              | Network  | Address                                      | Purpose                                                                                                      |
| --------------------- | -------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `FxRoot`              | Ethereum | `0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2` | Ethereum-side entry point for FxPortal. Calls `syncState` on `StateSender`.                                  |
| `FxChild`             | Polygon  | `0x8397259c983751DAf40400790063935a11afa28a` | Polygon-side receiver for FxPortal. Called by `StateReceiver` and routes messages to child tunnel contracts. |
| `FxERC20RootTunnel`   | Ethereum | `0x0cc2caed31490b546c741bd93dbba8ab387f7f2c` | FxPortal tunnel for bridging ERC-20 tokens via FxRoot.                                                       |
| `FxERC721RootTunnel`  | Ethereum | `0xca1f5ec720eCdA31bE3d80BD3ef4686cBb07eb4D` | FxPortal tunnel for bridging ERC-721 tokens via FxRoot.                                                      |
| `FxERC20ChildTunnel`  | Polygon  | `0xd531Cf2142D9b9Dc8b077dF3c4E93B46E7Cf879a` | Polygon-side counterpart to `FxERC20RootTunnel`.                                                             |
| `FxERC721ChildTunnel` | Polygon  | `0x2b4732e448b3023131a7b25046b3A5EF50CfCf71` | Polygon-side counterpart to `FxERC721RootTunnel`.                                                            |

### PoS token bridge

These contracts handle token deposits and withdrawals through the official PoS bridge. Use these when bridging mapped ERC-20, ERC-721, or ERC-1155 tokens rather than arbitrary data.

| Contract                 | Network  | Address                                      | Purpose                                                                                                                                     |
| ------------------------ | -------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `RootChainManagerProxy`  | Ethereum | `0xA0c68C638235ee32657e8f720a23ceC1bFc77C77` | Main entry point for PoS token bridge on Ethereum. Call `depositFor` to deposit tokens and `exit` to finalize withdrawals after checkpoint. |
| `ChildChainManagerProxy` | Polygon  | `0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa` | Polygon-side manager. Mints tokens on deposit and processes burns on withdrawal.                                                            |
| `ERC20PredicateProxy`    | Ethereum | `0x40ec5B33f54e0E8A33A975908C5BA1c14e5BbbDf` | Locks ERC-20 tokens on Ethereum on deposit; releases them on exit.                                                                          |
| `ERC721PredicateProxy`   | Ethereum | `0xE6F45376f64e1F568BD1404C155e5fFD2F80F7AD` | Locks ERC-721 tokens on Ethereum on deposit; releases them on exit.                                                                         |
| `ERC1155PredicateProxy`  | Ethereum | `0x0B9020d4E32990D67559b1317c7BF0C15D6EB88f` | Locks ERC-1155 tokens on Ethereum on deposit; releases them on exit.                                                                        |
