From 7465e7ef190a53f55828d0888deefc1f246ad9e2 Mon Sep 17 00:00:00 2001 From: 0xdapper <0xdapp@protonmail.com> Date: Tue, 11 Jul 2023 10:56:27 +0000 Subject: [PATCH 1/2] feat: add polygon zkEVM bridge executor --- contracts/bridges/ZkEVMBridgeExecutor.sol | 93 +++++++++++++++++++ .../polygon-zkevm/IBridgeMessageReceiver.sol | 14 +++ 2 files changed, 107 insertions(+) create mode 100644 contracts/bridges/ZkEVMBridgeExecutor.sol create mode 100644 contracts/dependencies/polygon-zkevm/IBridgeMessageReceiver.sol diff --git a/contracts/bridges/ZkEVMBridgeExecutor.sol b/contracts/bridges/ZkEVMBridgeExecutor.sol new file mode 100644 index 0000000..ce608e3 --- /dev/null +++ b/contracts/bridges/ZkEVMBridgeExecutor.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: AGPL-3.0 +pragma solidity ^0.8.10; + +import {L2BridgeExecutor} from './L2BridgeExecutor.sol'; +import {IBridgeMessageReceiver} from '../dependencies/polygon-zkevm/IBridgeMessageReceiver.sol'; + +/** + * @title ZkEVMBridgeExecutor + * @author Aave + * @notice Implementation of the ZkEVM Bridge Executor, able to receive cross-chain transactions from Ethereum + */ +contract ZkEVMBridgeExecutor is L2BridgeExecutor, IBridgeMessageReceiver { + error UnauthorizedBridgeCaller(); + error NotDirectlyCallable(); + error InvalidOriginNetwork(); + error InvalidMethodId(); + + address public immutable zkEVMBridge; + uint32 internal constant _MAINNET_NETWORK_ID = 0; + + /// @inheritdoc L2BridgeExecutor + modifier onlyEthereumGovernanceExecutor() override { + revert NotDirectlyCallable(); + _; + } + + modifier onlyBridge() { + if (msg.sender != zkEVMBridge) revert UnauthorizedBridgeCaller(); + _; + } + + /** + * @dev Constructor + * + * @param zkEVMBridge_ The address of the ZkEVMBridge. + * @param ethereumGovernanceExecutor The address of the EthereumGovernanceExecutor + * @param delay The delay before which an actions set can be executed + * @param gracePeriod The time period after a delay during which an actions set can be executed + * @param minimumDelay The minimum bound a delay can be set to + * @param maximumDelay The maximum bound a delay can be set to + * @param guardian The address of the guardian, which can cancel queued proposals (can be zero) + * @dev zkEVMBridge calls `onMessageReceived` with originSender, originNetwork and calldata. All of them are verified. + * But this also means we need queue function to not be callable, will always revert. + */ + constructor( + address zkEVMBridge_, + address ethereumGovernanceExecutor, + uint256 delay, + uint256 gracePeriod, + uint256 minimumDelay, + uint256 maximumDelay, + address guardian + ) + L2BridgeExecutor( + ethereumGovernanceExecutor, + delay, + gracePeriod, + minimumDelay, + maximumDelay, + guardian + ) + { + // Intentionally left blank + zkEVMBridge = zkEVMBridge_; + } + + function onMessageReceived( + address originAddress, + uint32 originNetwork, + bytes calldata data + ) external payable onlyBridge { + if (originAddress != _ethereumGovernanceExecutor) { + revert UnauthorizedEthereumExecutor(); + } + if (originNetwork != _MAINNET_NETWORK_ID) { + revert InvalidOriginNetwork(); + } + bytes4 methodId = bytes4(data[0:4]); + if (methodId != this.queue.selector) { + revert InvalidMethodId(); + } + + ( + address[] memory targets, + uint256[] memory values, + string[] memory signatures, + bytes[] memory calldatas, + bool[] memory withDelegatecalls + ) = abi.decode(data[4:], (address[], uint256[], string[], bytes[], bool[])); + + _queue(targets, values, signatures, calldatas, withDelegatecalls); + } +} diff --git a/contracts/dependencies/polygon-zkevm/IBridgeMessageReceiver.sol b/contracts/dependencies/polygon-zkevm/IBridgeMessageReceiver.sol new file mode 100644 index 0000000..e8b7273 --- /dev/null +++ b/contracts/dependencies/polygon-zkevm/IBridgeMessageReceiver.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: AGPL-3.0 + +pragma solidity ^0.8.10; + +/** + * @dev Define interface for PolygonZkEVM Bridge message receiver + */ +interface IBridgeMessageReceiver { + function onMessageReceived( + address originAddress, + uint32 originNetwork, + bytes memory data + ) external payable; +} From b4b656bc8234f0147da43b0630ef58eff70161d9 Mon Sep 17 00:00:00 2001 From: 0xdapper <0xdapp@protonmail.com> Date: Tue, 11 Jul 2023 12:15:08 +0000 Subject: [PATCH 2/2] refactor: zkEvmBridge address as constant --- contracts/bridges/ZkEVMBridgeExecutor.sol | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/contracts/bridges/ZkEVMBridgeExecutor.sol b/contracts/bridges/ZkEVMBridgeExecutor.sol index ce608e3..af573e4 100644 --- a/contracts/bridges/ZkEVMBridgeExecutor.sol +++ b/contracts/bridges/ZkEVMBridgeExecutor.sol @@ -15,7 +15,7 @@ contract ZkEVMBridgeExecutor is L2BridgeExecutor, IBridgeMessageReceiver { error InvalidOriginNetwork(); error InvalidMethodId(); - address public immutable zkEVMBridge; + address internal constant zkEVMBridge = 0x2a3DD3EB832aF982ec71669E178424b10Dca2EDe; uint32 internal constant _MAINNET_NETWORK_ID = 0; /// @inheritdoc L2BridgeExecutor @@ -32,7 +32,6 @@ contract ZkEVMBridgeExecutor is L2BridgeExecutor, IBridgeMessageReceiver { /** * @dev Constructor * - * @param zkEVMBridge_ The address of the ZkEVMBridge. * @param ethereumGovernanceExecutor The address of the EthereumGovernanceExecutor * @param delay The delay before which an actions set can be executed * @param gracePeriod The time period after a delay during which an actions set can be executed @@ -43,7 +42,6 @@ contract ZkEVMBridgeExecutor is L2BridgeExecutor, IBridgeMessageReceiver { * But this also means we need queue function to not be callable, will always revert. */ constructor( - address zkEVMBridge_, address ethereumGovernanceExecutor, uint256 delay, uint256 gracePeriod, @@ -61,7 +59,6 @@ contract ZkEVMBridgeExecutor is L2BridgeExecutor, IBridgeMessageReceiver { ) { // Intentionally left blank - zkEVMBridge = zkEVMBridge_; } function onMessageReceived(