L2MessageReceiver

Introduction

The L2MessageReceiver contract is a crucial component of the protocol's cross-chain reward distribution system. It resides on the Arbitrum network (L2) and is responsible for receiving cross-chain messages from Ethereum (L1) via LayerZero. These messages contain instructions for minting MOR tokens to users who have earned rewards based on their staked stETH in L1.

The contract ensures the secure and accurate minting of MOR tokens by validating incoming messages and calling the minting logic.

Key Responsibilities

  1. LayerZero endpoint integration: listens for and receives payloads sent from the L1Sender contract on Ethereum.

  2. Message decoding and validation: verifies the origin and decodes message payloads to extract reward details.

  3. Reward Distribution: mint the MOR token for the users.

Storage

rewardToken

The address of the MOR token contract on Arbitrum.

address public rewardToken;

config

The LayerZero config for cross-chain message receiving.

Config public config;

struct Config {
  address gateway;
  address sender;
  uint16 senderChainId;
}
Name
Description

gateway

The LayerZero EndpointV1 contract address.

sender

The L1MessageSender contract address.

senderChainId

The Ethereum chain id fron the LayerZero doc.

Write functions for the contract owner

L2MessageReceiver__init

Initializes the contract during deployment (used with proxies). Can only be called once.

function L2MessageReceiver__init() external initializer;

setParams

Sets or updates the MOR token address and LayerZero message config.

function setParams(
  address rewardToken_,
  Config calldata config_
) external onlyOwner;
Name
Description

rewardToken_

Address of the MOR token on Arbitrum.

config_

The LayerZero config for cross-chain message receiving.

Write functions for the LayerZero endpoint

lzReceive

Receives and verifies cross-chain messages from LayerZero. Only callable by the LayerZero endpoint. Delegates execution to nonblockingLzReceive.

function lzReceive(
    uint16 senderChainId_,
    bytes memory senderAndReceiverAddresses_,
    uint64 nonce_,
    bytes memory payload_
) external
Name
Description

senderChainId_

ID of the source chain (Ethereum L1).

senderAndReceiverAddresses_

Encoded source/destination addresses.

nonce_

Unique nonce to identify the message.

payload_

ABI-encoded payload: user address and MOR amount.

nonblockingLzReceive

Internal message handler that performs the actual minting logic. Ensures execution does not block LayerZero.

function nonblockingLzReceive(
    uint16 senderChainId_,
    bytes memory senderAndReceiverAddresses_,
    bytes memory payload_
) public
Name
Description

senderChainId_

ID of the source chain (Ethereum L1).

senderAndReceiverAddresses_

Encoded source/destination addresses.

payload_

ABI-encoded payload: user address and MOR amount.

Write functions

retryMessage

Allows retrying a failed cross-chain message. Can be used to recover from transient errors or gas issues.

function retryMessage(
    uint16 senderChainId_,
    bytes memory senderAndReceiverAddresses_,
    uint64 nonce_,
    bytes memory payload_
) external
Name
Description

senderChainId_

ID of the source chain.

senderAndReceiverAddresses_

Encoded source/destination addresses.

nonce_

Unique message identifier.

payload_

Original encoded user address and amount.

Last updated

Was this helpful?