> For the complete documentation index, see [llms.txt](https://docs.lighter.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lighter.xyz/evm/interop/tokens/token-transfers.md).

# Token transfers

This section covers how to transfer assets between Ethereum L1, Lighter EVM, and Lighter Core. These transfers build on the cross-domain pathways introduced in [Message passing](/evm/interop/message-passing.md).

## Transfers to and from Core

The following conventions apply to transfers between [EVM and Core](/evm/interop/tokens/token-transfers/evm-and-core.md) and [L1 and Core](/evm/interop/tokens/token-transfers/l1-and-core.md).

### Supported assets

Every asset on Core is identified by a `uint32 assetIndex`.

Transfers to and from Core support the following asset types.

* **ETH.** ETH uses `assetIndex = 1` and is transferred as the native currency on L1 and Lighter EVM.
* **ERC-20 tokens.** The asset must be registered on Core and linked on the relevant non-Core domain. See [Token linking](/evm/interop/tokens/token-linking.md).

If a Core asset has representations on both L1 and Lighter EVM, the protocol assumes they use the same number of decimals.

The following assets are currently registered on Core.

| Asset | `assetIndex` | L1 / EVM decimals | [`tickSize`](#amounts) | L1 address                                   | EVM address                                  |
| ----- | ------------ | ----------------- | ---------------------- | -------------------------------------------- | -------------------------------------------- |
| ETH   | `1`          | `18`              | `10^10`                | Not applicable                               | Not applicable                               |
| LIT   | `2`          | `18`              | `10^10`                | `0x24734C47a5967b3ab43eC137909BcF72593E65E8` | Not linked                                   |
| USDC  | `3`          | `6`               | `1`                    | `0xb90a9f16ddf0AE8054d53AF5C8b559a19741991F` | `0xf2A5728d366c6d0f764Af612cD47F3608E2B4d5B` |

### Amounts

Core tracks balances in **base units**. During asset registration, the protocol records a `tickSize` for the Core asset, which specifies how many of the token's smallest units on L1 or Lighter EVM correspond to one Core **base unit**.

An asset's `tickSize` can be read from [`L1InteropManager.getAssetConfig(assetIndex)`](https://github.com/elliottech/lighter-contracts/blob/lighter-evm-devnet/contracts/interop/L1InteropManager.sol). If the asset is linked on EVM, EVM contracts can also read it from [`EvmInteropManager.getAssetConfig(assetIndex)`](https://github.com/elliottech/lighter-contracts/blob/lighter-evm-devnet/contracts/interop/EvmInteropManager.sol). The two calls return:

```solidity
enum CanonicalDomain { None, L1, Core, EVM }

// L1InteropManager.getAssetConfig(uint32 assetIndex)
struct CoreAssetL1Config {
    CanonicalDomain canonicalDomain;
    address l1Token;
    address coreTokenAdmin;
    uint56 extensionMultiplier;
    uint128 tickSize;
    address l1Gateway;
}

// EvmInteropManager.getAssetConfig(uint32 assetIndex)
struct CoreAssetEvmConfig {
    CanonicalDomain canonicalDomain;
    address evmToken;
    address evmGateway;
    uint128 tickSize;
}
```

Convert from the token's smallest units to Core base units with `baseAmount = amount / tickSize`, and back with `amount = baseAmount * tickSize`.

As an example, ETH has `tickSize = 10^10` wei, so transferring 1 ETH (`10^18` wei) corresponds to `10^8` Core base units.

### Routes

A route names the Core balance that a transfer uses: `Perps` for collateral in perpetuals markets, or `Spot` for the balance used in spot markets. Transfers involving Core specify a route. A transfer to Core credits the selected route, and a transfer from Core debits it.

New Core master accounts, including every account created through Lighter EVM, are [unified trading accounts](https://docs.lighter.xyz/trading/unified-trading-accounts). A unified account keeps its USDC in one shared margin balance, so both routes credit and debit the same USDC. The [account-info read](/evm/interop/reading-core-from-evm.md#account-info) reports this shared USDC collateral as `collateralBaseAmount`. It is not reserved exclusively for perpetuals and can also support spot operations, subject to margin requirements.

A USDC deposit through the `Spot` route can therefore leave the [spot-balance read](/evm/interop/reading-core-from-evm.md#spot-balance) at zero while `collateralBaseAmount` increases. The spot read alone does not capture all funds usable for spot operations, and the shared collateral is not necessarily all available to spend.

Other assets enabled as margin for a unified account also prioritize the margin balance. Incoming amounts that exceed the remaining per-account or global supply cap stay in the separate spot balance. Enabling margin for an asset reallocates its existing spot balance in the same way, subject to those caps. USDC has no supply cap, and switching an account to unified mode moves all existing spot USDC into the margin balance.

The `Perps` route accepts an asset other than USDC only if the asset is enabled as margin for the account. ETH is currently not enabled as margin, so send ETH on the `Spot` route: an ETH deposit on the `Perps` route is [refunded](/evm/interop/tokens/token-transfers/evm-and-core.md#send-to-core-refunds) in full.

Core's [account API](https://docs.lighter.xyz/api/account) reports an account's mode as `account_trading_mode`: `0` for classic, `1` for unified. A classic account keeps separate perps and spot balances.

The `RouteType` enum is ABI-encoded as `uint8`.

```solidity
enum RouteType {
    Perps, // 0
    Spot   // 1
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.lighter.xyz/evm/interop/tokens/token-transfers.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
