Skip to content

Commit

Permalink
feat: Endpoint Deployment changes (#93)
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Goulding <[email protected]>
  • Loading branch information
ryandgoulding authored Dec 10, 2023
1 parent 12bf62c commit 086b820
Show file tree
Hide file tree
Showing 10 changed files with 273 additions and 33 deletions.
8 changes: 3 additions & 5 deletions packages/ua-utils-evm-hardhat-test/contracts/DefaultOApp.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;

contract DefaultOApp {
mapping(uint256 => bytes32) public peers;
import { OmniCounter as OmniCounterImpl } from "@layerzerolabs/lz-evm-oapp-v2/contracts/examples/OmniCounter.sol";

function setPeer(uint256 eid, bytes32 peer) external {
peers[eid] = peer;
}
contract DefaultOApp is OmniCounterImpl {
constructor(address _endpoint) OmniCounterImpl(_endpoint) {}
}
103 changes: 103 additions & 0 deletions packages/ua-utils-evm-hardhat-test/deploy/001_bootstrap.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { type DeployFunction } from 'hardhat-deploy/types'
import assert from 'assert'
import { formatEid } from '@layerzerolabs/utils'
import { wrapEIP1193Provider } from '@layerzerolabs/utils-evm-hardhat'
import env from 'hardhat'
import { Contract } from 'ethers'
import { TransactionReceipt, TransactionResponse } from '@ethersproject/providers'

const DEFAULT_NATIVE_DECIMALS_RATE = '18' //ethers.utils.parseUnits('1', 18).toString()

/**
* This deploy function will deploy and configure LayerZero endpoint
Expand Down Expand Up @@ -31,11 +37,108 @@ const deploy: DeployFunction = async ({ getUnnamedAccounts, deployments, network
args: [endpointV2Deployment.address],
})

await Promise.all(
['DefaultProxyAdmin', 'PriceFeed_Proxy', 'PriceFeed', 'PriceFeed_Implementation'].map((contractName) =>
deployments.delete(contractName)
)
)
const priceFeed = await deployments.deploy('PriceFeed', {
from: deployer,
proxy: {
owner: deployer,
proxyContract: 'OptimizedTransparentProxy',
execute: {
init: {
methodName: 'initialize',
args: [deployer],
},
},
},
})

await deployments.delete('ExecutorFeeLib')
const executorFeeLib = await deployments.deploy('ExecutorFeeLib', {
from: deployer,
args: [DEFAULT_NATIVE_DECIMALS_RATE],
})

await Promise.all(
['Executor_Proxy', 'Executor_Implementation', 'Executor', 'ExecutorProxyAdmin'].map((contractName) =>
deployments.delete(contractName)
)
)
const executor = await deployments.deploy('Executor', {
from: deployer,
log: true,
skipIfAlreadyDeployed: true,
proxy: {
owner: deployer,
proxyContract: 'OptimizedTransparentProxy',
viaAdminContract: { name: 'ExecutorProxyAdmin', artifact: 'ProxyAdmin' },
execute: {
init: {
methodName: 'initialize',
args: [
endpointV2Deployment.address, // _endpoint
receiveUln302.address, // _receiveUln301
[sendUln302.address], // _messageLibs
priceFeed.address, // _priceFeed
deployer, // _roleAdmin
[deployer], // _admins
],
},
onUpgrade: {
methodName: 'onUpgrade',
args: [receiveUln302.address],
},
},
},
})

const signer = wrapEIP1193Provider(env.network.provider).getSigner()
const executorContract = new Contract(executor.address, executor.abi).connect(signer)
const setExecFeeLibResp: TransactionResponse = await executorContract.setWorkerFeeLib?.(executorFeeLib.address, {
from: await signer.getAddress(),
})
const setExecFeeLibReceipt: TransactionReceipt = await setExecFeeLibResp.wait()
assert(setExecFeeLibReceipt?.status === 1)

await deployments.delete('DVN')
const dvn = await deployments.deploy('DVN', {
from: deployer,
args: [
network.config.eid, // vid
[sendUln302.address], // messageLibs
priceFeed.address, // priceFeed
[deployer], // signers
1, // quorum
[deployer], // admins
],
})

await deployments.delete('DVNFeeLib')
const dvnFeeLib = await deployments.deploy('DVNFeeLib', {
from: deployer,
args: [DEFAULT_NATIVE_DECIMALS_RATE],
})

const dvnContract = new Contract(dvn.address, dvn.abi).connect(signer)
const setDvnFeeLibResp: TransactionResponse = await dvnContract.setWorkerFeeLib?.(dvnFeeLib.address, {
from: await signer.getAddress(),
})
const setDvnFeeLibReceipt: TransactionReceipt = await setDvnFeeLibResp.wait()
assert(setDvnFeeLibReceipt?.status === 1)

console.table({
Network: `${network.name} (endpoint ${formatEid(network.config.eid)})`,
EndpointV2: endpointV2Deployment.address,
SendUln302: sendUln302.address,
ReceiveUln302: receiveUln302.address,
PriceFeed: priceFeed.address,
Executor: executor.address,
ExecutorFeeLib: executorFeeLib.address,
DVN: dvn.address,
DVNFeeLib: dvnFeeLib.address,
})
}

Expand Down
2 changes: 2 additions & 0 deletions packages/ua-utils-evm-hardhat-test/deploy/002_oapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ const deploy: DeployFunction = async ({ getUnnamedAccounts, deployments, network
assert(deployer, 'Missing deployer')

await deployments.delete('DefaultOApp')
const endpointV2 = await deployments.get('EndpointV2')
const defaultOAppDeployment = await deployments.deploy('DefaultOApp', {
from: deployer,
args: [endpointV2.address],
})

console.table({
Expand Down
3 changes: 3 additions & 0 deletions packages/ua-utils-evm-hardhat-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
"@gnosis.pm/safe-service-client": "1.1.1",
"@layerzerolabs/io-utils": "~0.0.1",
"@layerzerolabs/lz-definitions": "~1.5.70",
"@layerzerolabs/lz-evm-oapp-v2": "~1.5.70",
"@layerzerolabs/lz-evm-protocol-v2": "~1.5.70",
"@layerzerolabs/lz-evm-sdk-v1": "~1.5.70",
"@layerzerolabs/lz-evm-sdk-v2": "~1.5.70",
"@layerzerolabs/lz-utility-v2": "~1.5.70",
"@layerzerolabs/protocol-utils": "~0.0.1",
"@layerzerolabs/protocol-utils-evm": "~0.0.1",
"@layerzerolabs/toolbox-hardhat": "~0.0.1",
Expand Down
59 changes: 45 additions & 14 deletions packages/ua-utils-evm-hardhat-test/test/__utils__/endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,40 @@ import { formatOmniPoint } from '@layerzerolabs/utils'
export const ethEndpoint = { eid: EndpointId.ETHEREUM_MAINNET, contractName: 'EndpointV2' }
export const ethReceiveUln = { eid: EndpointId.ETHEREUM_MAINNET, contractName: 'ReceiveUln302' }
export const ethSendUln = { eid: EndpointId.ETHEREUM_MAINNET, contractName: 'SendUln302' }
export const ethExecutor = { eid: EndpointId.ETHEREUM_MAINNET, contractName: 'Executor' }
export const ethDvn = { eid: EndpointId.ETHEREUM_MAINNET, contractName: 'DVN' }
export const avaxEndpoint = { eid: EndpointId.AVALANCHE_MAINNET, contractName: 'EndpointV2' }
export const avaxReceiveUln = { eid: EndpointId.AVALANCHE_MAINNET, contractName: 'ReceiveUln302' }
export const avaxSendUln = { eid: EndpointId.AVALANCHE_MAINNET, contractName: 'SendUln302' }
export const avaxExecutor = { eid: EndpointId.AVALANCHE_MAINNET, contractName: 'Executor' }
export const avaxDvn = { eid: EndpointId.AVALANCHE_MAINNET, contractName: 'DVN' }

export const defaultExecutorConfig: Uln302ExecutorConfig = {
maxMessageSize: 10000,
executor: '0x0000000000000000000000000000000000000001',
export const MAX_MESSAGE_SIZE = 10000 // match on-chain value

/**
* Helper function to generate the default Uln302ExecutorConfig for a given chain.
*
* @param executorAddress The local Executor address.
*/
export const getDefaultExecutorConfig = (executorAddress: string): Uln302ExecutorConfig => {
return {
maxMessageSize: MAX_MESSAGE_SIZE,
executor: executorAddress,
}
}

export const defaultUlnConfig: Uln302UlnConfig = {
confirmations: BigInt(1),
requiredDVNs: ['0x0000000000000000000000000000000000000002', '0x0000000000000000000000000000000000000003'],
optionalDVNs: [],
optionalDVNThreshold: 0,
/**
* Helper function to generate the default Uln302UlnConfig for a given chain.
*
* @param dvnAddress The local DVN address.
*/
export const getDefaultUlnConfig = (dvnAddress: string): Uln302UlnConfig => {
return {
confirmations: BigInt(1),
requiredDVNs: [dvnAddress],
optionalDVNs: [],
optionalDVNThreshold: 0,
}
}

/**
Expand Down Expand Up @@ -68,22 +88,33 @@ export const setupDefaultEndpoint = async (): Promise<void> => {
const avaxSendUlnPoint = omniContractToPoint(await contractFactory(avaxSendUln))
const ethReceiveUlnPoint = omniContractToPoint(await contractFactory(ethReceiveUln))
const avaxReceiveUlnPoint = omniContractToPoint(await contractFactory(avaxReceiveUln))
const ethExecutorPoint = omniContractToPoint(await contractFactory(ethExecutor))
const avaxExecutorPoint = omniContractToPoint(await contractFactory(avaxExecutor))
const ethDvnPoint = omniContractToPoint(await contractFactory(ethDvn))
const avaxDvnPoint = omniContractToPoint(await contractFactory(avaxDvn))

const ethUlnConfig: Uln302UlnConfig = getDefaultUlnConfig(ethDvnPoint.address)
const avaxUlnConfig: Uln302UlnConfig = getDefaultUlnConfig(avaxDvnPoint.address)

// This is the graph for SendUln302
const sendUlnConfig: OmniGraphHardhat<Uln302NodeConfig, unknown> = {
contracts: [
{
contract: ethSendUln,
config: {
defaultUlnConfigs: [[EndpointId.AVALANCHE_MAINNET, defaultUlnConfig]],
defaultExecutorConfigs: [[EndpointId.AVALANCHE_MAINNET, defaultExecutorConfig]],
defaultUlnConfigs: [[EndpointId.AVALANCHE_MAINNET, ethUlnConfig]],
defaultExecutorConfigs: [
[EndpointId.AVALANCHE_MAINNET, getDefaultExecutorConfig(ethExecutorPoint.address)],
],
},
},
{
contract: avaxSendUln,
config: {
defaultUlnConfigs: [[EndpointId.ETHEREUM_MAINNET, defaultUlnConfig]],
defaultExecutorConfigs: [[EndpointId.ETHEREUM_MAINNET, defaultExecutorConfig]],
defaultUlnConfigs: [[EndpointId.ETHEREUM_MAINNET, avaxUlnConfig]],
defaultExecutorConfigs: [
[EndpointId.ETHEREUM_MAINNET, getDefaultExecutorConfig(avaxExecutorPoint.address)],
],
},
},
],
Expand All @@ -96,14 +127,14 @@ export const setupDefaultEndpoint = async (): Promise<void> => {
{
contract: ethReceiveUln,
config: {
defaultUlnConfigs: [[EndpointId.AVALANCHE_MAINNET, defaultUlnConfig]],
defaultUlnConfigs: [[EndpointId.AVALANCHE_MAINNET, ethUlnConfig]],
defaultExecutorConfigs: [],
},
},
{
contract: avaxReceiveUln,
config: {
defaultUlnConfigs: [[EndpointId.ETHEREUM_MAINNET, defaultUlnConfig]],
defaultUlnConfigs: [[EndpointId.ETHEREUM_MAINNET, avaxUlnConfig]],
defaultExecutorConfigs: [],
},
},
Expand Down
11 changes: 8 additions & 3 deletions packages/ua-utils-evm-hardhat-test/test/endpoint/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import { createConnectedContractFactory } from '@layerzerolabs/utils-evm-hardhat
import type { OmniPoint } from '@layerzerolabs/utils'
import { omniContractToPoint } from '@layerzerolabs/utils-evm'
import { EndpointId } from '@layerzerolabs/lz-definitions'
import { defaultUlnConfig, setupDefaultEndpoint } from '../__utils__/endpoint'
import { getDefaultUlnConfig, setupDefaultEndpoint } from '../__utils__/endpoint'
import { Endpoint, Uln302 } from '@layerzerolabs/protocol-utils-evm'

describe('endpoint/config', () => {
const ethEndpoint = { eid: EndpointId.ETHEREUM_MAINNET, contractName: 'EndpointV2' }
const ethReceiveUln = { eid: EndpointId.ETHEREUM_MAINNET, contractName: 'ReceiveUln302' }
const ethSendUln = { eid: EndpointId.ETHEREUM_MAINNET, contractName: 'SendUln302' }
const ethDvn = { eid: EndpointId.ETHEREUM_MAINNET, contractName: 'DVN' }
const avaxEndpoint = { eid: EndpointId.AVALANCHE_MAINNET, contractName: 'EndpointV2' }
const avaxReceiveUln = { eid: EndpointId.AVALANCHE_MAINNET, contractName: 'ReceiveUln302' }
const avaxSendUln = { eid: EndpointId.AVALANCHE_MAINNET, contractName: 'SendUln302' }
const avaxDvn = { eid: EndpointId.AVALANCHE_MAINNET, contractName: 'DVN' }

beforeEach(async () => {
await setupDefaultEndpoint()
Expand Down Expand Up @@ -68,8 +70,11 @@ describe('endpoint/config', () => {
const ethConfig = await ethSendUlnSdk.getUlnConfig(avaxSendUlnPoint.eid, avaxSendUlnPoint.address)
const avaxConfig = await avaxSendUlnSdk.getUlnConfig(ethSendUlnPoint.eid, ethSendUlnPoint.address)

expect(ethConfig).toEqual(defaultUlnConfig)
expect(avaxConfig).toEqual(defaultUlnConfig)
const ethDvnPoint = omniContractToPoint(await connectedContractFactory(ethDvn))
const avaxDvnPoint = omniContractToPoint(await connectedContractFactory(avaxDvn))

expect(ethConfig).toEqual(getDefaultUlnConfig(ethDvnPoint.address))
expect(avaxConfig).toEqual(getDefaultUlnConfig(avaxDvnPoint.address))
})
})
})
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { defaultExecutorConfig, defaultUlnConfig, setupDefaultEndpoint } from '../__utils__/endpoint'
import { getDefaultExecutorConfig, getDefaultUlnConfig, setupDefaultEndpoint } from '../__utils__/endpoint'
import { createContractFactory, getEidForNetworkName } from '@layerzerolabs/utils-evm-hardhat'
import hre from 'hardhat'
import { TASK_LZ_GET_DEFAULT_CONFIG } from '@layerzerolabs/ua-utils-evm-hardhat'
import { omniContractToPoint } from '@layerzerolabs/utils-evm'

describe('task: getDefaultConfig', () => {
beforeEach(async () => {
Expand All @@ -20,12 +21,16 @@ describe('task: getDefaultConfig', () => {

const sendUln302 = await contractFactory({ contractName: 'SendUln302', eid: localEid })
const receiveUln302 = await contractFactory({ contractName: 'ReceiveUln302', eid: localEid })
const executor = await contractFactory({ contractName: 'Executor', eid: localEid })
const executorPoint = await omniContractToPoint(executor)
const dvn = await contractFactory({ contractName: 'DVN', eid: localEid })
const dvnPoint = await omniContractToPoint(dvn)

expect(defaultConfig.defaultSendLibrary).toEqual(sendUln302.contract.address)
expect(defaultConfig.defaultReceiveLibrary).toEqual(receiveUln302.contract.address)
expect(defaultConfig.sendExecutorConfig).toEqual(defaultExecutorConfig)
expect(defaultConfig.sendUlnConfig).toEqual(defaultUlnConfig)
expect(defaultConfig.receiveUlnConfig).toEqual(defaultUlnConfig)
expect(defaultConfig.sendExecutorConfig).toEqual(getDefaultExecutorConfig(executorPoint.address))
expect(defaultConfig.sendUlnConfig).toEqual(getDefaultUlnConfig(dvnPoint.address))
expect(defaultConfig.receiveUlnConfig).toEqual(getDefaultUlnConfig(dvnPoint.address))
}
}
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { defaultExecutorConfig, defaultUlnConfig, setupDefaultEndpoint } from '../__utils__/endpoint'
import { getDefaultExecutorConfig, getDefaultUlnConfig, setupDefaultEndpoint } from '../__utils__/endpoint'
import { createContractFactory, getEidForNetworkName } from '@layerzerolabs/utils-evm-hardhat'
import hre from 'hardhat'
import { AddressZero } from '@ethersproject/constants'
import { TASK_LZ_GET_OAPP_CONFIG } from '@layerzerolabs/ua-utils-evm-hardhat'
import { omniContractToPoint } from '@layerzerolabs/utils-evm'

describe('task: getOAppConfig', () => {
beforeEach(async () => {
Expand All @@ -25,12 +26,16 @@ describe('task: getOAppConfig', () => {
const defaultConfig = getDefaultConfigTask[localNetwork][remoteNetwork]
const sendUln302 = await contractFactory({ contractName: 'SendUln302', eid: localEid })
const receiveUln302 = await contractFactory({ contractName: 'ReceiveUln302', eid: localEid })
const executor = await contractFactory({ contractName: 'Executor', eid: localEid })
const executorPoint = omniContractToPoint(executor)
const dvn = await contractFactory({ contractName: 'DVN', eid: localEid })
const dvnPoint = omniContractToPoint(dvn)

expect(defaultConfig.defaultSendLibrary).toEqual(sendUln302.contract.address)
expect(defaultConfig.defaultReceiveLibrary).toEqual(receiveUln302.contract.address)
expect(defaultConfig.sendExecutorConfig).toEqual(defaultExecutorConfig)
expect(defaultConfig.sendUlnConfig).toEqual(defaultUlnConfig)
expect(defaultConfig.receiveUlnConfig).toEqual(defaultUlnConfig)
expect(defaultConfig.sendExecutorConfig).toEqual(getDefaultExecutorConfig(executorPoint.address))
expect(defaultConfig.sendUlnConfig).toEqual(getDefaultUlnConfig(dvnPoint.address))
expect(defaultConfig.receiveUlnConfig).toEqual(getDefaultUlnConfig(dvnPoint.address))
}
}
})
Expand Down
1 change: 0 additions & 1 deletion packages/ua-utils-evm/src/oapp/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export class OApp implements IOApp {

async setPeer(eid: EndpointId, address: Bytes32 | Address | null | undefined): Promise<OmniTransaction> {
const data = this.contract.contract.interface.encodeFunctionData('setPeer', [eid, makeBytes32(address)])

return this.createTransaction(data)
}

Expand Down
Loading

0 comments on commit 086b820

Please sign in to comment.