Skip to main content
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

ScenarioOFTWhy
Token with permissioned burn and mintOFTBurnMintBurn on source, mint on destination. No locked collateral.
Token with permissionless self-burn and permissioned mintOFTBurnSelfMintTransfers to OFT via allowance, then self-burns. Mint on destination.
Existing token with supply on one chainOFTLockUnlockLock on source, unlock on destination. No supply change.
Native gas token (ETH, MATIC, etc.)OFTNativeWraps msg.value for cross-chain transfer.
Target chain uses ERC20 for gas feesAlt variantsSame 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

ParameterTypeDescription
_tokenaddressUnderlying ERC20 token address (must implement IERC20Metadata)
_burnerMinteraddressContract with burn/mint capabilities (can differ from _token)
_endpointaddressLayerZero EndpointV2 address
_approvalRequiredboolWhether the OFT needs ERC20 approval to burn
_burnSelectorbytes4Function selector for burn, e.g., 0x9dc29fac for burn(address,uint256)
_mintSelectorbytes4Function selector for mint, e.g., 0x40c10f19 for mint(address,uint256)
_rateLimiterScaleDecimalsuint8Decimals to scale rate limit amounts (usually 0)

Common Selector Values

Function SignatureSelector
mint(address,uint256)0x40c10f19
burn(address,uint256)0x9dc29fac
issue(address,uint256)0x867904b4
redeem(address,uint256)0x1e9a6950

Initialization Parameters

ParameterTypeDescription
_initialAdminaddressAddress to be granted DEFAULT_ADMIN_ROLE and endpoint delegate
_feeDepositaddressAddress that will receive any accrued fees
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

ParameterTypeDescription
_tokenaddressToken address that is also the burner/minter
_endpointaddressLayerZero EndpointV2 address
_burnSelectorbytes4Function selector for burn
_mintSelectorbytes4Function selector for mint
_rateLimiterScaleDecimalsuint8Decimals to scale rate limit amounts

Common Selector Values for OFTBurnSelfMint

Function SignatureSelector
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

ParameterTypeDescription
_tokenaddressUnderlying ERC20 token address (must implement IERC20Metadata)
_endpointaddressLayerZero EndpointV2 address
_rateLimiterScaleDecimalsuint8Decimals to scale rate limit amounts
approvalRequired is always true for lock/unlock since users must approve the OFT to transfer their tokens.
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.

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

ParameterTypeDescription
_localDecimalsuint8Decimals of the native token (18 for ETH)
_endpointaddressLayerZero EndpointV2 address
_rateLimiterScaleDecimalsuint8Decimals to scale rate limit amounts

Send Behavior

The overridden send() function validates that msg.value equals exactly _fee.nativeFee + _sendParam.amountLD:
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 VariantAlt Variant
OFTBurnMintOFTBurnMintAlt
OFTBurnSelfMintOFTBurnSelfMintAlt
OFTLockUnlockOFTLockUnlockAlt
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