# 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.

```solidity
address public rewardToken;
```

### config

The LayerZero config for cross-chain message receiving.

```solidity
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.

```solidity
function L2MessageReceiver__init() external initializer;
```

### setParams

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

```solidity
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`.

```solidity
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.

```solidity
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.

```solidity
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. |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gitbook.mor.org/smart-contracts/documentation/distribution-protocol/v7-protocol/contracts/l2messagereceiver.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
