3. Cross-Chain Integration with LayerZero V2
LayerZero messaging
One of the standout features of this TokenFactory system is its omnichain capability – the ability for the token sale to take place across multiple chains at once. This is enabled by LayerZero v2, a cross-chain messaging protocol. Each TokenFactory contract is connected to LayerZero on its respective chain to send and receive messages. Here’s how the cross-chain architecture works:
-
LayerZero Endpoints: LayerZero provides endpoint contracts on every supported chain that act as mailboxes for messages. In our system, each TokenFactory knows the address of the LayerZero Endpoint on its chain (this is configured on deployment). For example, on Ethereum mainnet the LayerZero endpoint address is
0x1a44076050125825900e736c501f859c50fe728c, and the same endpoint address is deployed on BSC, Avalanche, Arbitrum, and Base (LayerZero v2 uses identical endpoint addresses on many chains for convenience). This endpoint contract is what the TokenFactory uses to send messages to other chains and to receive them.
-
Peer Contract Mapping: Every TokenFactory also maintains a mapping of LayerZero Chain ID -> TokenFactory address on that chain. This mapping (populated via
setPeer) tells the contract where its counterpart is on each network. For example, the Ethereum TokenFactory’s mapping might map
{"BSC": 56 -> 0x..BSCFactory, "Avalanche": 43114 -> 0x..AVAXFactory, ...}. These mappings serve two purposes:
-
Routing Outgoing Messages: When the Ethereum factory needs to send a command to, say, BSC, it looks up the BSC factory address from this map and includes it in the message.
-
Validating Incoming Messages: When a LayerZero message is received, the endpoint delivers it to the TokenFactory’s
lzReceivefunction along with the source chain ID and sender address. The TokenFactory will check that the sender address matches the known peer address from its mapping. If not, it rejects the message. This prevents unauthorized contracts from sending fake messages.
-
-
Cross-Chain Buy (Message Flow): Suppose a token was created on Chain A (Ethereum), but a user on Chain B (BSC) wants to buy it:
-
The user on BSC calls
buy(token, amount)on the BSC TokenFactory and sends BNB (BSC’s native coin) as payment. The BSC TokenFactory sees that the token’s home chain is Ethereum (likely determined because it doesn’t have the primary state for that token).
-
The BSC TokenFactory does not mint tokens locally immediately. Instead, it packages the request into a LayerZero message. This message includes details like: target chain = Ethereum’s chain ID, the token identifier (perhaps the Ethereum token contract address or an internal token ID), the buyer’s address (on BSC), and the payment amount.
-
The BSC TokenFactory calls LayerZero Endpoint’s
sendfunction, providing the target chain ID, target address (Ethereum TokenFactory address from the peer map), and the message payload. It also pays LayerZero messaging fees (usually in BNB) for the cross-chain delivery.
-
The LayerZero Endpoint on BSC relays the message to the LayerZero Endpoint on Ethereum. The Ethereum endpoint then calls
lzReceiveon the Ethereum TokenFactory, delivering the payload.
-
The Ethereum TokenFactory processes the message: it reads that “User X on BSC sent Y BNB to buy token Z”. It then performs the bonding curve calculation on Ethereum (as it is the home chain with the authoritative supply and price data for that token). Say the user’s payment corresponds to N tokens to mint. The Ethereum TokenFactory will update the total supply (global supply) for token Z by +N.
-
Minting across chains: Now, instead of minting the N tokens on Ethereum (which wouldn’t directly help the BSC user), the Ethereum TokenFactory prepares a return message. There are two possible designs here:
-
Design 1: Ethereum TokenFactory mints N tokens on Ethereum into a escrow (or burns them immediately to remove from supply), and then sends a message to BSC instructing BSC’s TokenFactory to mint N tokens to the user. This effectively transfers the tokens’ presence to BSC.
-
Design 2: The Ethereum TokenFactory doesn’t mint on Ethereum at all; it simply uses the updated supply for price tracking. It sends a message to BSC with the instruction “mint N tokens for user X”. (In this design, the token contract on BSC would have its own mint capability for the BSC TokenFactory.)
In both cases, Ethereum’s factory will invoke the LayerZero endpoint to send the mint instruction back to BSC.
-
-
The message travels back to BSC’s LayerZero endpoint, which calls
lzReceiveon the BSC TokenFactory. The payload might contain: token Z, target user address, and N (the amount to mint).
-
The BSC TokenFactory receives this and mints N tokens of Z on BSC’s local ERC-20 token contract for Z to the user’s address. Finally, it emits a
BoughtCrosschainMemeToken(srcChain=Ethereum, buyer=UserX, token=Z, amount=N, cost=YBNB)event on BSC to log the completion of the cross-chain buy.
The net effect is the user on BSC now has the newly minted tokens in their wallet on BSC, as if they were issued locally, even though the pricing logic ran on Ethereum. The base currency (BNB) they paid remains on BSC – it is now part of the funds that will later be used for providing liquidity on BSC. Meanwhile, Ethereum’s TokenFactory updated the global supply, so it “knows” those N tokens have been issued (albeit on another chain). This ensures the next buyer (on any chain) will get the correct higher price due to the increased supply.
-
-
Cross-Chain Sell (Message Flow): A similar mechanism works for selling tokens across chains. Suppose a user on BSC now wants to sell those N tokens of Z:
-
The user calls
sell(token Z, N)on BSC TokenFactory. The contract will burn N tokens from the user’s balance on BSC (reducing the BSC token contract’s supply) and determine the expected payout in BNB for those N tokens (based on the current bonding curve state).
-
However, the bonding curve state (price, total supply) is maintained by Ethereum’s TokenFactory (home chain). So BSC’s factory sends a LayerZero message to Ethereum’s TokenFactory: “User X on BSC sold N tokens of Z”.
-
Ethereum’s TokenFactory receives this, and updates the global total supply down by N. It calculates the payout amount in base currency (in this case, what amount of ETH would N tokens refund if it were on Ethereum).
-
It then needs to get the appropriate amount of BNB back to the user on BSC. If the system tracks the distribution of funds, it knows that the user’s funds for these tokens are actually on BSC (since they were originally paid in BNB). In practice, the Ethereum factory can simply send a message back to BSC confirming the payout amount. The BSC factory, upon receiving this, will transfer the BNB payout to the user from its reserves (the funds collected from buyers).
-
The BSC factory emits a
SoldCrosschainMemeToken(srcChain=Ethereum, seller=UserX, token=Z, amount=N, payout=YBNB)event to log the cross-chain sale completion.
In effect, the tokens have been destroyed on BSC and the user received BNB. The global supply was synced on Ethereum. If, instead, a user on a different chain (say Avalanche) bought some of token Z, all factories would eventually sync the total supply so that price stays consistent.
-
-
Peer Security: The use of
setPeerto register the correct TokenFactory addresses is critical. This setup is done right after deployment (see Deployment section). For example, after all factories are deployed, the team will call something like:
// On Ethereum TokenFactory:
setPeer(56, 0x...BSCFactory);
setPeer(43114, 0x...AvaxFactory);
setPeer(8453, 0x...BaseFactory);
setPeer(42161, 0x...ArbFactory);
// ...and similarly on each chain’s TokenFactory for all others.
-
This ensures each factory knows the trusted addresses. LayerZero messages include the source chain ID and sender, so each factory verifies it against its
peersmapping.
-
LayerZero Fees: Note that cross-chain operations will incur LayerZero fees (for relaying and verification). The TokenFactory likely requires the user to pay these fees. For instance, the
buyCrossChainfunction on BSC might require the user to send a bit of extra BNB to cover the message to Ethereum and back. The contract could estimate or let the user provide a fee. This is an implementation detail; from the user’s perspective, it’s usually a seamless experience (the UI can bundle the fee).
-
Ominchain Fungible Token (OFT) Consideration: The pattern above is effectively implementing an Omnichain Fungible Token manually. LayerZero offers an OFT library, where a token contract can mint/burn and send tokens across chain. It’s possible the Meme Token contracts use the OFT v2 standard under the hood (which would automatically handle bridging tokens). In our design, we chose to handle it at the TokenFactory level to have more control over the bonding curve process. The result is the same: the token exists on all chains and can move between them. After the bonding curve phase, users could potentially bridge tokens between chains using the same LayerZero messaging if supported.
In summary, LayerZero integration allows cross-chain minting and burning so that no matter which chain a user is on, they interact with the TokenFactory and get the correct price and token delivery. All TokenFactory contracts together maintain a single logical “bonding curve state” for each token. This ensures, for example, that if 50% of a token’s supply was sold on Ethereum and 50% on BSC, both chains are aware the total supply = 100% and the price reflects that. Cross-chain messages keep the state in sync. The end result is an omnichain token launch: a user can buy on one chain and sell on another if they wish, and the system will account for it.
4. Bonding Curve Logic and PricingBonding and Pricing Logic