Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/lzapp-migration/layerzero.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const config: OAppOmniGraphHardhat = {
// Optional Receive Configuration
// @dev Controls how the `from` chain receives messages from the `to` chain.
receiveConfig: {
executorConfig: '0x718B92b5CB0a5552039B593faF724D182A881eDA',
ulnConfig: {
// The number of block confirmations to expect from the `to` chain.
confirmations: BigInt(15),
Expand Down
1 change: 1 addition & 0 deletions examples/lzapp-migration/lzapp.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const config: OAppOmniGraphHardhat = {
},
},
receiveConfig: {
executorConfig: '0x718B92b5CB0a5552039B593faF724D182A881eDA',
ulnConfig: {
confirmations: BigInt(1),
requiredDVNs: ['0x53f488e93b4f1b60e8e83aa374dbe1780a1ee8a8'], // LayerZero Labs DVN for Arbitrum Sepolia
Expand Down
79 changes: 77 additions & 2 deletions examples/lzapp-migration/tasks/common/taskHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { HardhatRuntimeEnvironment } from 'hardhat/types'
import { OmniAddress, OmniPoint, OmniTransaction, flattenTransactions } from '@layerzerolabs/devtools'
import { createGetHreByEid } from '@layerzerolabs/devtools-evm-hardhat'
import { createModuleLogger } from '@layerzerolabs/io-devtools'
import { EndpointId } from '@layerzerolabs/lz-definitions'
import { EndpointId, endpointIdToVersion } from '@layerzerolabs/lz-definitions'
import { addressToBytes32 } from '@layerzerolabs/lz-v2-utilities'
import { Uln302ExecutorConfig, Uln302UlnConfig } from '@layerzerolabs/protocol-devtools'
import { LzAppOmniGraph, OAppEdgeConfig } from '@layerzerolabs/ua-devtools'
Expand Down Expand Up @@ -153,6 +153,34 @@ export async function getEpv1ReceiveUlnConfig(
}
}

/**
* Get the Receive Executor address for EPV1 (EVM-based) OApp
* @param hre {HardhatRuntimeEnvironment} Hardhat runtime environment
* @param eid {EndpointId} Remote Endpoint ID
* @param address {OmniAddress} Address of the OApp
* @returns Executor address or undefined
*/
export async function getEpv1ReceiveExecutorConfig(
hre: HardhatRuntimeEnvironment,
eid: EndpointId,
address: OmniAddress
): Promise<string | undefined> {
try {
const receiveUlnDeployment = await hre.deployments.get('ReceiveUln301')
const signer: Signer = hre.ethers.provider.getSigner()

const receiveUlnContract = new Contract(receiveUlnDeployment.address, receiveUlnDeployment.abi, signer)
const configBytes: string = await receiveUlnContract.getConfig(eid, address, CONFIG_TYPE_EXECUTOR)

const [executorAddress] = ethers.utils.defaultAbiCoder.decode(['address'], configBytes)
return executorAddress
} catch (error) {
const moduleLogger = createModuleLogger('LzApp')
moduleLogger.error(`Error fetching EPV1 receive executor config: ${(error as Error).message}`)
return undefined
}
}

/**
* Get the send library address for EPV1 (EVM-based) OApp
* @param hre {HardhatRuntimeEnvironment} Hardhat runtime environment
Expand Down Expand Up @@ -677,6 +705,33 @@ export async function setExecutorConfig(
}
}

/**
* Sets the Receive Executor Config on the LzApp contract and returns the transaction.
*/
export async function setReceiveExecutorConfig(
hre: HardhatRuntimeEnvironment,
lzApp: OmniPoint,
lzAppConfig: OAppEdgeConfig,
eid: EndpointId
): Promise<OmniTransaction | undefined> {
const lzAppDeployment = await hre.deployments.get(lzApp.contractName || lzApp.address)
const lzAppContract = new Contract(lzAppDeployment.address, lzAppDeployment.abi, hre.ethers.provider.getSigner())
const receiveUlnIndex = await getLibraryIndex(hre, lzAppConfig.receiveLibraryConfig?.receiveLibrary!)
const encodedAddress = ethers.utils.defaultAbiCoder.encode(['address'], [lzAppConfig.receiveConfig?.executorConfig])

const data = lzAppContract.interface.encodeFunctionData('setConfig', [
receiveUlnIndex,
eid,
CONFIG_TYPE_EXECUTOR,
encodedAddress,
])
return {
point: lzApp,
data,
description: `Set Receive Executor Config for Endpoint ID ${eid}`,
}
}

/**
* Sets the ULN Config on the LzApp contract and returns the transaction.
*/
Expand Down Expand Up @@ -848,7 +903,8 @@ export const configureLzAppGraph = async (
!typedConfig.receiveLibraryConfig?.receiveLibrary ||
!typedConfig.sendConfig?.executorConfig ||
!typedConfig.sendConfig?.ulnConfig ||
!typedConfig.receiveConfig?.ulnConfig
!typedConfig.receiveConfig?.ulnConfig ||
(endpointIdToVersion(to.eid) === 'v1' && !typedConfig.receiveConfig?.executorConfig)
) {
logger.error(`Missing configuration properties for connection from ${from.eid} to ${to.eid}`)
return []
Expand Down Expand Up @@ -928,6 +984,25 @@ export const configureLzAppGraph = async (
if (executorTx) transactions.push(executorTx)
}

if (endpointIdToVersion(to.eid) === 'v1') {
const currentReceiveExecutor = await getEpv1ReceiveExecutorConfig(
hreForEid,
to.eid,
LzApp.address
)
if (!currentReceiveExecutor) {
throw new Error(`Failed to retrieve receive executor config for ${LzApp.address}`)
}

if (
currentReceiveExecutor.toLowerCase() !==
typedConfig.receiveConfig!.executorConfig!.toLowerCase()
) {
const recvExecTx = await setReceiveExecutorConfig(hreForEid, from, typedConfig, to.eid)
if (recvExecTx) transactions.push(recvExecTx)
}
}

const getSendUlnConfig = await getEpv1SendUlnConfig(hreForEid, to.eid, LzApp.address)
const getReceiveUlnConfig = await getEpv1ReceiveUlnConfig(hreForEid, to.eid, LzApp.address)

Expand Down