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

# OFT Variants

> Cross-chain transfer OFTs: BurnMint, BurnSelfMint, LockUnlock, and Native variants.

Stablecoin OFT provides multiple OFT variants to support different token economics and deployment scenarios. Each variant implements a different cross-chain transfer model. All share the same extension stack (fee, rate limiting, pause).

## Decision Matrix

| Scenario                                                  | OFT               | Why                                                                   |
| --------------------------------------------------------- | ----------------- | --------------------------------------------------------------------- |
| Token with permissioned burn and mint                     | `OFTBurnMint`     | Burn on source, mint on destination. No locked collateral.            |
| Token with permissionless self-burn and permissioned mint | `OFTBurnSelfMint` | Transfers to OFT via allowance, then self-burns. Mint on destination. |
| Existing token with supply on one chain                   | `OFTLockUnlock`   | Lock on source, unlock on destination. No supply change.              |
| Native gas token (ETH, MATIC, etc.)                       | `OFTNative`       | Wraps `msg.value` for cross-chain transfer.                           |
| Target chain uses ERC20 for gas fees                      | **Alt variants**  | Same logic but built for `EndpointV2Alt`.                             |

## OFTBurnMint

Burns tokens on the source chain and mints them on the destination chain. Supports any token that exposes mint and burn functions with `(address, uint256)` parameters. The OFT must be granted the required roles (e.g., `MINTER_ROLE`, `BURNER_ROLE`) to call these functions.

**Key feature:** Configurable function selectors allow the OFT to call non-standard mint/burn function names.

### Constructor Parameters

| Parameter                   | Type      | Description                                                                |
| --------------------------- | --------- | -------------------------------------------------------------------------- |
| `_token`                    | `address` | Underlying ERC20 token address (must implement `IERC20Metadata`)           |
| `_burnerMinter`             | `address` | Contract with burn/mint capabilities (can differ from `_token`)            |
| `_endpoint`                 | `address` | LayerZero EndpointV2 address                                               |
| `_approvalRequired`         | `bool`    | Whether the OFT needs ERC20 approval to burn                               |
| `_burnSelector`             | `bytes4`  | Function selector for burn, e.g., `0x9dc29fac` for `burn(address,uint256)` |
| `_mintSelector`             | `bytes4`  | Function selector for mint, e.g., `0x40c10f19` for `mint(address,uint256)` |
| `_rateLimiterScaleDecimals` | `uint8`   | Decimals to scale rate limit amounts (usually `0`)                         |

### Common Selector Values

| Function Signature        | Selector     |
| ------------------------- | ------------ |
| `mint(address,uint256)`   | `0x40c10f19` |
| `burn(address,uint256)`   | `0x9dc29fac` |
| `issue(address,uint256)`  | `0x867904b4` |
| `redeem(address,uint256)` | `0x1e9a6950` |

### Initialization Parameters

| Parameter       | Type      | Description                                                      |
| --------------- | --------- | ---------------------------------------------------------------- |
| `_initialAdmin` | `address` | Address to be granted `DEFAULT_ADMIN_ROLE` and endpoint delegate |
| `_feeDeposit`   | `address` | Address that will receive any accrued fees                       |

```solidity theme={null}
function initialize(address _initialAdmin, address _feeDeposit) public initializer;
```

## OFTBurnSelfMint

For tokens with a permissionless self-burn function (e.g., OpenZeppelin's `ERC20Burnable.burn(uint256)`) and a permissioned mint function. On the send path, the OFT transfers tokens from the user to itself via ERC20 allowance, then calls the self-burn selector to destroy them. On the receive path, it mints via the mint selector like `OFTBurnMint`.

### Constructor Parameters

| Parameter                   | Type      | Description                                  |
| --------------------------- | --------- | -------------------------------------------- |
| `_token`                    | `address` | Token address that is also the burner/minter |
| `_endpoint`                 | `address` | LayerZero EndpointV2 address                 |
| `_burnSelector`             | `bytes4`  | Function selector for burn                   |
| `_mintSelector`             | `bytes4`  | Function selector for mint                   |
| `_rateLimiterScaleDecimals` | `uint8`   | Decimals to scale rate limit amounts         |

### Common Selector Values for OFTBurnSelfMint

| Function Signature       | Selector     |
| ------------------------ | ------------ |
| `mint(address,uint256)`  | `0x40c10f19` |
| `burn(uint256)`          | `0x42966c68` |
| `issue(address,uint256)` | `0x867904b4` |
| `redeem(uint256)`        | `0xdb006a75` |

## OFTLockUnlock

Locks tokens in the OFT contract on the source chain and unlocks (transfers) them from the OFT on the destination chain. No minting or burning occurs.

### Constructor Parameters

| Parameter                   | Type      | Description                                                      |
| --------------------------- | --------- | ---------------------------------------------------------------- |
| `_token`                    | `address` | Underlying ERC20 token address (must implement `IERC20Metadata`) |
| `_endpoint`                 | `address` | LayerZero EndpointV2 address                                     |
| `_rateLimiterScaleDecimals` | `uint8`   | Decimals to scale rate limit amounts                             |

`approvalRequired` is always `true` for lock/unlock since users must approve the OFT to transfer their tokens.

<Warning>
  **Only one lock/unlock OFT should exist per OFT mesh.** If multiple lock/unlock OFTs exist on different chains, locked supply becomes fragmented and the system cannot guarantee solvency.
</Warning>

## OFTNative

Wraps native tokens (ETH, MATIC, AVAX, etc.) for cross-chain transfer. Users send native tokens as `msg.value` along with the `send()` call.

### Constructor Parameters

| Parameter                   | Type      | Description                               |
| --------------------------- | --------- | ----------------------------------------- |
| `_localDecimals`            | `uint8`   | Decimals of the native token (18 for ETH) |
| `_endpoint`                 | `address` | LayerZero EndpointV2 address              |
| `_rateLimiterScaleDecimals` | `uint8`   | Decimals to scale rate limit amounts      |

### Send Behavior

The overridden `send()` function validates that `msg.value` equals exactly `_fee.nativeFee + _sendParam.amountLD`:

```solidity theme={null}
uint256 requiredMsgValue = _fee.nativeFee + _sendParam.amountLD;
if (msg.value != requiredMsgValue) {
    revert IncorrectMessageValue(msg.value, requiredMsgValue);
}
```

### Receive Behavior

Credits are sent as native token transfers using low-level `.call{value}()`. If the transfer fails (e.g., recipient is a contract without a `receive` function), the transaction reverts with `CreditFailed(to, amountLD, revertData)`.

### Properties

* `token()` returns `address(0)` since there is no ERC20 token
* `approvalRequired()` returns `false` since `msg.value` is used directly
* Dust removal is not applied to `amountLD` since native token amounts always equal `amountSentLD`

## Alt Variants

Some chains use an ERC20 token for gas fees instead of a native token. Because gas fees are paid in an ERC20, the sender must approve the endpoint to spend the fee token before sending a message. This changes the standard `send()` workflow: users need an additional ERC20 approval step for the fee token, and the endpoint pulls fees via `transferFrom` rather than accepting `msg.value`.

These chains use `EndpointV2Alt` instead of `EndpointV2` to handle this difference. The Alt OFT variants are identical to their standard counterparts except they target `EndpointV2Alt`:

| Standard Variant  | Alt Variant          |
| ----------------- | -------------------- |
| `OFTBurnMint`     | `OFTBurnMintAlt`     |
| `OFTBurnSelfMint` | `OFTBurnSelfMintAlt` |
| `OFTLockUnlock`   | `OFTLockUnlockAlt`   |

Alt variants inherit from the corresponding `ExtendedRBACAltUpgradeable` contracts. Constructor parameters and behavior are otherwise the same.

## Multi-Chain Topology

### Burn/Mint

```
        +--------------+     +--------------+
        |  Chain A     |<--->|  Chain B     |
        | OFTBurnMint  |     | OFTBurnMint  |
        +------+-------+     +------+-------+
               |                    |
               +---------+----------+
                         |
                 +--------------+
                 |  Chain C     |
                 | OFTBurnMint  |
                 +--------------+
```

All chains are equal peers. Each OFT burns on send and mints on receive. Total supply across all chains stays constant. Works the same way with `OFTBurnSelfMint`.

### Lock/Unlock

```
        +--------------+     +--------------+
        |  Chain B     |     |  Chain C     |
        | OFTBurnMint  |     | OFTBurnMint  |
        +------+-------+     +------+-------+
               |                     |
               +----------+----------+
                          |
                 +----------------+
                 |  Chain A       |
                 | OFTLockUnlock  |
                 +----------------+
```

One chain (the token's home chain) deploys `OFTLockUnlock`, which locks tokens on send and unlocks on receive. All other chains deploy `OFTBurnMint`, which burns on send and mints on receive. This keeps a single pool of locked collateral on Chain A backing all circulating supply on remote chains.

## Next Steps

* [Extensions](/v2/developers/evm/stablecoin-oft/extensions) for fee, rate limiting, and pause configuration
* [RBAC Reference](/v2/developers/evm/stablecoin-oft/rbac-reference) for roles on extended OFTs
