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
5 changes: 4 additions & 1 deletion src/contracts/adapters/layerZero/LayerZeroAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,18 @@ contract LayerZeroAdapter is BaseAdapter, ILayerZeroAdapter, ILayerZeroReceiver
* @param lzEndpoint address of the layer zero endpoint on the current chain where adapter is deployed
* @param providerGasLimit base gas limit used by the bridge adapter
* @param trustedRemotes array of objects with chain id and origin addresses which will be allowed to send messages to this adapter
* @param delegate address of the LayerZero delegate. Delegate can set configs
*/
constructor(
address crossChainController,
address lzEndpoint,
uint256 providerGasLimit,
TrustedRemotesConfig[] memory trustedRemotes
TrustedRemotesConfig[] memory trustedRemotes,
address delegate
) BaseAdapter(crossChainController, providerGasLimit, 'LayerZero adapter', trustedRemotes) {
require(lzEndpoint != address(0), Errors.INVALID_LZ_ENDPOINT);
LZ_ENDPOINT = ILayerZeroEndpointV2(lzEndpoint);
LZ_ENDPOINT.setDelegate(delegate);
}

/// @inheritdoc ILayerZeroReceiver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ struct Origin {
uint64 nonce;
}

struct SetConfigParam {
uint32 dstEid;
uint32 configType;
bytes config;
}

interface ILayerZeroEndpointV2 {
function quote(
MessagingParams calldata _params,
Expand All @@ -37,4 +43,16 @@ interface ILayerZeroEndpointV2 {
MessagingParams calldata _params,
address _refundAddress
) external payable returns (MessagingReceipt memory);

function setConfig(
address _oapp,
address _lib,
SetConfigParam[] calldata _params
) external;

function setDelegate(address _delegate) external;

function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external;

function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external;
}
31 changes: 31 additions & 0 deletions src/contracts/layerZeroCCC/CrossChainController.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.8;


import {CrossChainController} from '../CrossChainController.sol';
import {ILayerZeroEndpointV2} from '../adapters/layerZero/interfaces/ILayerZeroEndpointV2.sol';

contract LayerZeroCrossChainController is CrossChainController {
function initialize(
address owner,
address guardian,
ConfirmationInput[] memory initialRequiredConfirmations,
ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToAllow,
ForwarderBridgeAdapterConfigInput[] memory forwarderBridgeAdaptersToEnable,
address[] memory sendersToApprove,
OptimalBandwidthByChain[] memory optimalBandwidthByChain,
address lzEndpoint,
address delegate
) external initializer {
_baseInitialize(
owner,
guardian,
initialRequiredConfirmations,
receiverBridgeAdaptersToAllow,
forwarderBridgeAdaptersToEnable,
sendersToApprove,
optimalBandwidthByChain
);
ILayerZeroEndpointV2(lzEndpoint).setDelegate(delegate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.8;

import {CrossChainControllerWithEmergencyMode} from '../CrossChainControllerWithEmergencyMode.sol';
import {ILayerZeroEndpointV2} from '../adapters/layerZero/interfaces/ILayerZeroEndpointV2.sol';

contract LayerZeroCrossChainControllerWithEmergencyMode is CrossChainControllerWithEmergencyMode {
constructor(address clEmergencyOracle)
CrossChainControllerWithEmergencyMode(clEmergencyOracle)
{
}

function initialize(
address owner,
address guardian,
address clEmergencyOracle,
ConfirmationInput[] memory initialRequiredConfirmations,
ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToAllow,
ForwarderBridgeAdapterConfigInput[] memory forwarderBridgeAdaptersToEnable,
address[] memory sendersToApprove,
OptimalBandwidthByChain[] memory optimalBandwidthByChain,
address lzEndpoint,
address delegate
) external initializer {
_updateCLEmergencyOracle(clEmergencyOracle);
_baseInitialize(
owner,
guardian,
initialRequiredConfirmations,
receiverBridgeAdaptersToAllow,
forwarderBridgeAdaptersToEnable,
sendersToApprove,
optimalBandwidthByChain
);

ILayerZeroEndpointV2(lzEndpoint).setDelegate(delegate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.8;

import {CrossChainController} from '../../CrossChainController.sol';
import {IReinitialize} from './IReinitialize.sol';
import {ILayerZeroEndpointV2} from '../../adapters/layerZero/interfaces/ILayerZeroEndpointV2.sol';
/**
* @title CrossChainControllerUpgradeLayerZero
* @author BGD Labs
* @notice CrossChainController Revision 4. Contract inheriting from CrossChainController with the addition of re initialization method
* @dev reinitializer is not used on parent CrossChainController, so this contract is needed to be able to initialize CCC with a new implementation
* @dev it initializes the new implementation with the addition of the required confirmations for all destination networks supported
*/
contract CrossChainControllerUpgradeLayerZero is CrossChainController, IReinitialize {
/// @inheritdoc IReinitialize
function initializeRevision(
address lzEndpoint,
address delegate
) external reinitializer(4) {
ILayerZeroEndpointV2(lzEndpoint).setDelegate(delegate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.8;

import {CrossChainControllerWithEmergencyMode} from '../../CrossChainControllerWithEmergencyMode.sol';
import {IReinitialize} from './IReinitialize.sol';
import {ILayerZeroEndpointV2} from '../../adapters/layerZero/interfaces/ILayerZeroEndpointV2.sol';

/**
* @title CrossChainControllerWithEmergencyModeUpgradeRev3
* @author BGD Labs
* @notice Contract inheriting from CrossChainControllerWithEmergencyMode with the addition of re initialization method
* @dev reinitializer is not used on parent CrossChainController, so this contract is needed to be able to initialize CCC with a new implementation
* @dev it initializes the new implementation with the addition of the required confirmations for all destination networks supported
*/
contract CrossChainControllerWithEmergencyModeUpgradeRev3 is
CrossChainControllerWithEmergencyMode,
IReinitialize
{
constructor(address clEmergencyOracle) CrossChainControllerWithEmergencyMode(clEmergencyOracle) {}

/// @inheritdoc IReinitialize
function initializeRevision(
address lzEndpoint,
address delegate
) external reinitializer(4) {
ILayerZeroEndpointV2(lzEndpoint).setDelegate(delegate);
}
}
21 changes: 21 additions & 0 deletions src/contracts/revisions/update_to_layer_zero/IReinitialize.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {ICrossChainForwarder} from '../../interfaces/ICrossChainForwarder.sol';

/**
* @title IReinitialize
* @author BGD Labs
* @notice interface containing re initialization method
*/
interface IReinitialize {
/**
* @notice method called to re initialize the proxy
* @param lzEndpoint address of the LayerZero endpoint
* @param delegate address of the LayerZero delegate
*/
function initializeRevision(
address lzEndpoint,
address delegate
) external;
}
66 changes: 42 additions & 24 deletions tests/adapters/LayerZeroAdapter.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
address lzEndpoint,
address originForwarder,
uint256 baseGasLimit,
uint256 originChainId
uint256 originChainId,
address delegate
) {
vm.assume(crossChainController != tx.origin); // zkVM doesn't support mocking tx.origin
vm.assume(baseGasLimit < 1 ether);
Expand All @@ -34,11 +35,17 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
memory originConfigs = new IBaseAdapter.TrustedRemotesConfig[](1);
originConfigs[0] = originConfig;

vm.mockCall(
lzEndpoint,
abi.encodeWithSelector(ILayerZeroEndpointV2.setDelegate.selector),
abi.encode()
);
layerZeroAdapter = new LayerZeroAdapter(
crossChainController,
lzEndpoint,
baseGasLimit,
originConfigs
originConfigs,
delegate
);
_;
}
Expand All @@ -49,7 +56,8 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
address crossChainController,
uint256 baseGasLimit,
address originForwarder,
uint256 originChainId
uint256 originChainId,
address delegate
) public {
vm.assume(crossChainController != address(0));
vm.assume(originForwarder != address(0));
Expand All @@ -64,18 +72,19 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
originConfigs[0] = originConfig;

vm.expectRevert(bytes(Errors.INVALID_LZ_ENDPOINT));
new LayerZeroAdapter(crossChainController, address(0), baseGasLimit, originConfigs);
new LayerZeroAdapter(crossChainController, address(0), baseGasLimit, originConfigs, delegate);
}

function testInit(
address crossChainController,
address lzEndpoint,
address originForwarder,
uint256 baseGasLimit,
uint256 originChainId
uint256 originChainId,
address delegate
)
public
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, originChainId)
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, originChainId, delegate)
{
assertEq(
keccak256(abi.encode(layerZeroAdapter.adapterName())),
Expand All @@ -90,10 +99,11 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
address lzEndpoint,
address originForwarder,
uint256 baseGasLimit,
uint256 originChainId
uint256 originChainId,
address delegate
)
public
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, originChainId)
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, originChainId, delegate)
{
assertEq(layerZeroAdapter.nativeToInfraChainId(30109), ChainIds.POLYGON);
}
Expand All @@ -103,10 +113,11 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
address lzEndpoint,
address originForwarder,
uint256 baseGasLimit,
uint256 originChainId
uint256 originChainId,
address delegate
)
public
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, originChainId)
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, originChainId, delegate)
{
assertEq(layerZeroAdapter.infraToNativeChainId(ChainIds.POLYGON), 30109);
}
Expand All @@ -115,10 +126,11 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
address crossChainController,
address lzEndpoint,
address originForwarder,
uint256 baseGasLimit
uint256 baseGasLimit,
address delegate
)
public
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM)
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM, delegate)
{
bytes memory payload = abi.encode('test message');

Expand Down Expand Up @@ -152,10 +164,11 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
address lzEndpoint,
address originForwarder,
uint256 baseGasLimit,
address caller
address caller,
address delegate
)
public
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM)
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM, delegate)
{
Origin memory origin = Origin({
srcEid: uint32(30101),
Expand All @@ -175,10 +188,11 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
address lzEndpoint,
address originForwarder,
uint256 baseGasLimit,
address srcAddress
address srcAddress,
address delegate
)
public
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM)
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM, delegate)
{
vm.assume(srcAddress != originForwarder);

Expand All @@ -201,10 +215,11 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
uint256 baseGasLimit,
uint256 dstGasLimit,
address receiver,
address caller
address caller,
address delegate
)
public
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM)
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM, delegate)
{
vm.assume(dstGasLimit < 1 ether);
vm.assume(receiver != address(0));
Expand All @@ -219,10 +234,11 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
address originForwarder,
uint256 baseGasLimit,
uint256 dstGasLimit,
address receiver
address receiver,
address delegate
)
public
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM)
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM, delegate)
{
vm.assume(dstGasLimit > 200000 && dstGasLimit < 1 ether);
vm.assume(receiver != address(0));
Expand Down Expand Up @@ -253,10 +269,11 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
address originForwarder,
uint256 baseGasLimit,
uint256 dstGasLimit,
address receiver
address receiver,
address delegate
)
public
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM)
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM, delegate)
{
vm.assume(receiver != address(0));
vm.assume(dstGasLimit > 200000 && dstGasLimit < 1 ether);
Expand All @@ -272,10 +289,11 @@ contract LayerZeroAdapterTest is BaseAdapterTest {
address lzEndpoint,
address originForwarder,
uint256 baseGasLimit,
uint256 dstGasLimit
uint256 dstGasLimit,
address delegate
)
public
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM)
setLZAdapter(crossChainController, lzEndpoint, originForwarder, baseGasLimit, ChainIds.ETHEREUM, delegate)
{
vm.assume(dstGasLimit > 200000 && dstGasLimit < 1 ether);

Expand Down
Loading