Solana Endpoint V1 OFT Overview
Requirements
The backward-compatible Solana OFT (OFT202) utilizes Endpoint V1 OFT V2's ability to support non-EVM chains. Endpoint V1 OFT V1, on the other hand, supports only EVM chains.
Refer to the comparison below to know whether your existing Endpoint V1 OFT is compatible.
- Endpoint V1 OFT V1 (Incompatible)
- Endpoint V1 OFT V2 (Compatible)
Endpoint V1 OFT V1s are not compatible with Solana OFT202.
A token that extends Endpoint V1 OFT V1 will look similar to the following:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@layerzerolabs/solidity-examples/contracts/token/oft/v1/interfaces/IOFT.sol";
import "@layerzerolabs/solidity-examples/contracts/token/oft/v1/OFTCore.sol";
// override decimal() function is needed
contract OFT is OFTCore, ERC20, IOFT {
constructor(
string memory _name,
string memory _symbol,
address _lzEndpoint
) ERC20(_name, _symbol) OFTCore(_lzEndpoint) {}
}
Note how the file imports from the /oft/v1/
directory and how the contract extends OFTCore
.
This means that the token is not compatible with the backward-compatible Solana OFT (OFT202).
Endpoint V1 OFT V1 can only work with EndpointV1, so you should not attempt to deploy an Endpoint V1 OFT V1 with the _lzEndpoint
being an EndpointV2 address.
Endpoint V1 OFT V2's are compatible with Solana OFT202.
A token that extends Endpoint V1 OFT V2 will look similar to the following:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@layerzerolabs/solidity-examples/contracts/token/oft/v2/BaseOFTV2.sol";
/// @title OFT V1.2 Contract
/// @notice This contract is version 1.2 of the OFT Standard, enabling cross-chain token transfers between EVM and non-EVM contracts.
/// @dev This contract is only compatible with Endpoint V1.
contract OFTV2 is BaseOFTV2, ERC20 {
uint internal immutable ld2sdRate;
constructor(
string memory _name,
string memory _symbol,
uint8 _sharedDecimals,
address _lzEndpoint
) ERC20(_name, _symbol) BaseOFTV2(_sharedDecimals, _lzEndpoint) {
uint8 decimals = decimals();
require(_sharedDecimals <= decimals, "OFT: sharedDecimals must be <= decimals");
ld2sdRate = 10**(decimals - _sharedDecimals);
}
...
Note how the file imports from the /oft/v2/
directory and how the contract extends BaseOFTV2
.
This means that the token is compatible with the backward-compatible Solana OFT (OFT202).
After confirming your Endpoint V1 OFT's compatibility, you can proceed with the following instructions.
Set up the example repo
Use the LayerZero CLI to set up an example repo:
LZ_ENABLE_MIGRATION_EXAMPLE=1 npx create-lz-oapp@latest
When prompted, select EndpointV1 Migration
.
Deployment
Refer to the created repo's README for detailed instructions.
How it works
The Solana OFT202 program is a variation of the standard Endpoint V2 Solana OFT Program that can be paired with Endpoint V1 OFT V2 deployments.
On the Endpoint V1 OFT V2 side, the send and receive libraries need to first be updated to use ULN301. This is done via the wiring step with the configurations declared via the LZ Config file (layerzero.config.ts
). This allows for protocol level backward compatibility.
On the application level, the Solana OFT202 program implements a codec that allows for it to work with Endpoint V1 OFT V2.
The accounts used by the Solana OFT202 program are the same (with slightly different structures) as the standard Endpoint V2 Solana OFT Program. You can read more on the accounts structure here
Note that on the Endpoint V1 OFT V2 side, there is no contract upgrade or change required.