mirror of
https://github.com/vacp2p/linea-monorepo.git
synced 2026-01-09 04:08:01 -05:00
chore(L1ETHBridge): L1ETHBridge inherits from MessageServiceBase and makes sure addresses are not 0 in setter functions
This commit is contained in:
@@ -10,13 +10,13 @@ import { L1ETHBridge } from "../../../../src/yield/bridge/L1ETHBridge.sol";
|
||||
contract DeployL1ETHBridge is BaseScript {
|
||||
function run() public returns (address, L1ETHBridge) {
|
||||
DeploymentConfig deploymentConfig = new DeploymentConfig(broadcaster);
|
||||
(address deployer, address rollup, address yieldManager, address l2ETHBridge) = deploymentConfig
|
||||
(address deployer, address messageService, address remoteSender, address yieldManager) = deploymentConfig
|
||||
.activeNetworkConfig();
|
||||
|
||||
vm.startBroadcast(deployer);
|
||||
|
||||
L1ETHBridge impl = new L1ETHBridge();
|
||||
bytes memory initializeData = abi.encodeCall(L1ETHBridge.initialize, (deployer, rollup, yieldManager, l2ETHBridge));
|
||||
bytes memory initializeData = abi.encodeCall(L1ETHBridge.initialize, (deployer, messageService, remoteSender, yieldManager));
|
||||
|
||||
address proxy = address(new ERC1967Proxy(address(impl), initializeData));
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@ contract DeploymentConfig is Script {
|
||||
|
||||
struct NetworkConfig {
|
||||
address deployer;
|
||||
address rollup;
|
||||
address messageService;
|
||||
address remoteSender;
|
||||
address yieldManager;
|
||||
address l2ETHBridge;
|
||||
}
|
||||
|
||||
NetworkConfig public activeNetworkConfig;
|
||||
@@ -32,14 +32,14 @@ contract DeploymentConfig is Script {
|
||||
|
||||
function getOrCreateAnvilEthConfig(address _deployer) public returns (NetworkConfig memory) {
|
||||
ETHYieldManagerMock yieldManager = new ETHYieldManagerMock();
|
||||
RollupMock rollup = new RollupMock();
|
||||
RollupMock rollupMock = new RollupMock();
|
||||
|
||||
return
|
||||
NetworkConfig({
|
||||
deployer: _deployer,
|
||||
rollup: address(rollup),
|
||||
yieldManager: address(yieldManager),
|
||||
l2ETHBridge: makeAddr("l2ETHBridge")
|
||||
messageService: address(rollupMock),
|
||||
remoteSender: makeAddr("remoteSender"),
|
||||
yieldManager: address(yieldManager)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0
|
||||
pragma solidity 0.8.26;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
@@ -7,38 +7,15 @@ import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/O
|
||||
|
||||
import { IRollup } from "./interfaces/IRollup.sol";
|
||||
import { IL2ETHBridge } from "./interfaces/IL2ETHBridge.sol";
|
||||
import { MessageServiceBase } from "../../messaging/MessageServiceBase.sol";
|
||||
import { IMessageService } from "../../messaging/interfaces/IMessageService.sol";
|
||||
|
||||
contract L1ETHBridge is Initializable, UUPSUpgradeable, OwnableUpgradeable {
|
||||
contract L1ETHBridge is Initializable, UUPSUpgradeable, OwnableUpgradeable, MessageServiceBase {
|
||||
error L1ETHBridge__ZeroValue();
|
||||
error L1ETHBridge__RollupAddressNotSet();
|
||||
error L1ETHBridge__YieldManagerNotSet();
|
||||
error L1ETHBridge__ZeroAddressNotAllowed();
|
||||
error L1ETHBridge__YieldManagerDepositFailed();
|
||||
error L1ETHBridge__L2ETHBridgeNotSet();
|
||||
|
||||
address public rollup;
|
||||
address public yieldManager;
|
||||
address public l2ETHBridge;
|
||||
|
||||
modifier rollupIsSet() {
|
||||
if (rollup == address(0)) {
|
||||
revert L1ETHBridge__RollupAddressNotSet();
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
modifier yieldManagerIsSet() {
|
||||
if (yieldManager == address(0)) {
|
||||
revert L1ETHBridge__YieldManagerNotSet();
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
modifier l2ETHBridgeIsSet() {
|
||||
if (l2ETHBridge == address(0)) {
|
||||
revert L1ETHBridge__L2ETHBridgeNotSet();
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Disables initializers to prevent reinitialization.
|
||||
@@ -50,28 +27,44 @@ contract L1ETHBridge is Initializable, UUPSUpgradeable, OwnableUpgradeable {
|
||||
/**
|
||||
* @notice Initializes the contract.
|
||||
* @param _initialOwner The initial owner of the contract.
|
||||
* @param _rollup The rollup address.
|
||||
* @param _messageService The message service address (previously rollup).
|
||||
* @param _yieldManager The yield manager address.
|
||||
* @param _l2ETHBridge The L2ETHBridge address.
|
||||
* @param _remoteSender The remote sender address (previously l2ETHBridge).
|
||||
*/
|
||||
function initialize(
|
||||
address _initialOwner,
|
||||
address _rollup,
|
||||
address _yieldManager,
|
||||
address _l2ETHBridge
|
||||
address _messageService,
|
||||
address _remoteSender,
|
||||
address _yieldManager
|
||||
) external initializer {
|
||||
_transferOwnership(_initialOwner);
|
||||
rollup = _rollup;
|
||||
__MessageServiceBase_init(_messageService);
|
||||
_setRemoteSender(_remoteSender);
|
||||
|
||||
if (_yieldManager == address(0)) {
|
||||
revert L1ETHBridge__ZeroAddressNotAllowed();
|
||||
}
|
||||
yieldManager = _yieldManager;
|
||||
l2ETHBridge = _l2ETHBridge;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Sets the rollup address.
|
||||
* @param _rollup The new rollup address.
|
||||
* @notice Sets the message service address.
|
||||
* @param _messageService The new message service address.
|
||||
*/
|
||||
function setRollup(address _rollup) external onlyOwner {
|
||||
rollup = _rollup;
|
||||
function setMessageService(address _messageService) external onlyOwner {
|
||||
if (_messageService == address(0)) {
|
||||
revert L1ETHBridge__ZeroAddressNotAllowed();
|
||||
}
|
||||
|
||||
messageService = IMessageService(_messageService);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Sets the remote sender address.
|
||||
* @param _remoteSender The new remote sender address.
|
||||
*/
|
||||
function setRemoteSender(address _remoteSender) external onlyOwner {
|
||||
_setRemoteSender(_remoteSender);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,15 +72,11 @@ contract L1ETHBridge is Initializable, UUPSUpgradeable, OwnableUpgradeable {
|
||||
* @param _yieldManager The new yield manager address.
|
||||
*/
|
||||
function setYieldManager(address _yieldManager) external onlyOwner {
|
||||
yieldManager = _yieldManager;
|
||||
}
|
||||
if (_yieldManager == address(0)) {
|
||||
revert L1ETHBridge__ZeroAddressNotAllowed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Sets the L2ETHBridge address.
|
||||
* @param _l2ETHBridge The new L2ETHBridge address.
|
||||
*/
|
||||
function setL2ETHBridge(address _l2ETHBridge) external onlyOwner {
|
||||
l2ETHBridge = _l2ETHBridge;
|
||||
yieldManager = _yieldManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,10 +84,7 @@ contract L1ETHBridge is Initializable, UUPSUpgradeable, OwnableUpgradeable {
|
||||
* @param _to The recipient address on the L2.
|
||||
* @param _calldata The calldata to be sent to the L2ETHBridge.
|
||||
*/
|
||||
function bridgeETH(
|
||||
address _to,
|
||||
bytes memory _calldata
|
||||
) external payable rollupIsSet yieldManagerIsSet l2ETHBridgeIsSet {
|
||||
function bridgeETH(address _to, bytes memory _calldata) external payable {
|
||||
if (msg.value == 0) {
|
||||
revert L1ETHBridge__ZeroValue();
|
||||
}
|
||||
@@ -109,7 +95,7 @@ contract L1ETHBridge is Initializable, UUPSUpgradeable, OwnableUpgradeable {
|
||||
}
|
||||
|
||||
bytes memory data = abi.encodeWithSelector(IL2ETHBridge.completeBridge.selector, _to, msg.value, _calldata);
|
||||
IRollup(rollup).sendMessage(l2ETHBridge, 0, data);
|
||||
messageService.sendMessage(remoteSender, 0, data);
|
||||
}
|
||||
|
||||
function _authorizeUpgrade(address) internal view override {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
@@ -8,7 +8,13 @@ import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/
|
||||
import { MessageServiceBase } from "../../messaging/MessageServiceBase.sol";
|
||||
import { IMessageService } from "../../messaging/interfaces/IMessageService.sol";
|
||||
|
||||
contract L2ETHBridge is Initializable, UUPSUpgradeable, OwnableUpgradeable, ReentrancyGuardUpgradeable, MessageServiceBase {
|
||||
contract L2ETHBridge is
|
||||
Initializable,
|
||||
UUPSUpgradeable,
|
||||
OwnableUpgradeable,
|
||||
ReentrancyGuardUpgradeable,
|
||||
MessageServiceBase
|
||||
{
|
||||
error L2ETHBridge__ETHTransferFailed();
|
||||
|
||||
/**
|
||||
@@ -57,7 +63,7 @@ contract L2ETHBridge is Initializable, UUPSUpgradeable, OwnableUpgradeable, Reen
|
||||
address _to,
|
||||
uint256 _value,
|
||||
bytes memory _calldata
|
||||
) external nonReentrant onlyMessagingService() onlyAuthorizedRemoteSender {
|
||||
) external nonReentrant onlyMessagingService onlyAuthorizedRemoteSender {
|
||||
(bool success, ) = _to.call{ value: _value }(_calldata);
|
||||
if (!success) {
|
||||
revert L2ETHBridge__ETHTransferFailed();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
interface IL2ETHBridge {
|
||||
function completeBridge(address _to, uint256 _value, bytes calldata _calldata) external;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
interface IRollup {
|
||||
function sendMessage(address _to, uint256 _fee, bytes calldata _calldata) external payable;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
import { Test } from "forge-std/Test.sol";
|
||||
import { L1ETHBridge } from "../../../../src/yield/bridge/L1ETHBridge.sol";
|
||||
@@ -11,44 +11,59 @@ import { ETHYieldManagerMock } from "./mocks/ETHYieldManagerMock.sol";
|
||||
|
||||
contract L1ETHBridgeTest is Test {
|
||||
L1ETHBridge bridge;
|
||||
RollupMock rollup;
|
||||
RollupMock messageService;
|
||||
ETHYieldManagerMock yieldManager;
|
||||
|
||||
address deployer;
|
||||
address l2ETHBridge;
|
||||
address remoteSender;
|
||||
address user1 = makeAddr("user1");
|
||||
address user2 = makeAddr("user2");
|
||||
|
||||
function setUp() public {
|
||||
DeployL1ETHBridge script = new DeployL1ETHBridge();
|
||||
(deployer, bridge) = script.run();
|
||||
rollup = RollupMock(bridge.rollup());
|
||||
messageService = RollupMock(address(bridge.messageService()));
|
||||
yieldManager = ETHYieldManagerMock(payable(bridge.yieldManager()));
|
||||
l2ETHBridge = bridge.l2ETHBridge();
|
||||
remoteSender = bridge.remoteSender();
|
||||
}
|
||||
|
||||
function test_RevertsIfYieldManagerIsNotSet() public {
|
||||
function test_setYieldManagerRevertsIfZeroAddress() public {
|
||||
vm.prank(deployer);
|
||||
vm.expectRevert("L1ETHBridge__ZeroAddressNotAllowed()");
|
||||
bridge.setYieldManager(address(0));
|
||||
|
||||
vm.expectRevert("L1ETHBridge__YieldManagerNotSet()");
|
||||
bridge.bridgeETH(address(0), "");
|
||||
}
|
||||
|
||||
function test_RevertsIfRollupIsNotSet() public {
|
||||
function test_setYieldManagerSetsYieldManager() public {
|
||||
vm.prank(deployer);
|
||||
bridge.setRollup(address(0));
|
||||
|
||||
vm.expectRevert("L1ETHBridge__RollupAddressNotSet()");
|
||||
bridge.bridgeETH(address(0), "");
|
||||
address newYieldManager = makeAddr("new-yieldManager");
|
||||
bridge.setYieldManager(newYieldManager);
|
||||
assertEq(bridge.yieldManager(), newYieldManager);
|
||||
}
|
||||
|
||||
function test_RevertsIfL2ETHBridgeIsNotSet() public {
|
||||
function test_setRemoteSenderRevertsIfZeroAddress() public {
|
||||
vm.prank(deployer);
|
||||
bridge.setL2ETHBridge(address(0));
|
||||
vm.expectRevert("ZeroAddressNotAllowed()");
|
||||
bridge.setRemoteSender(address(0));
|
||||
}
|
||||
|
||||
vm.expectRevert("L1ETHBridge__L2ETHBridgeNotSet()");
|
||||
bridge.bridgeETH(address(0), "");
|
||||
function test_setMessageServiceRevertsIfZeroAddress() public {
|
||||
vm.prank(deployer);
|
||||
vm.expectRevert("L1ETHBridge__ZeroAddressNotAllowed()");
|
||||
bridge.setMessageService(address(0));
|
||||
}
|
||||
|
||||
function test_setMessageServiceSetsMessageService() public {
|
||||
vm.prank(deployer);
|
||||
address newMessageService = makeAddr("new-messageService");
|
||||
bridge.setMessageService(newMessageService);
|
||||
assertEq(address(bridge.messageService()), newMessageService);
|
||||
}
|
||||
|
||||
function test_setRemoteSenderSetsRemoteSender() public {
|
||||
vm.prank(deployer);
|
||||
address newRemoteSender = makeAddr("new-remoteSender");
|
||||
bridge.setRemoteSender(newRemoteSender);
|
||||
assertEq(bridge.remoteSender(), newRemoteSender);
|
||||
}
|
||||
|
||||
function test_RevertsIfValueIsZero() public {
|
||||
@@ -73,7 +88,7 @@ contract L1ETHBridgeTest is Test {
|
||||
vm.prank(user1);
|
||||
bridge.bridgeETH{ value: 100 }(user2, "test-message");
|
||||
|
||||
assertEq(rollup.messagesLength(), 1);
|
||||
assertEq(messageService.messagesLength(), 1);
|
||||
|
||||
bytes memory expectedData = abi.encodeWithSelector(
|
||||
IL2ETHBridge.completeBridge.selector,
|
||||
@@ -82,8 +97,8 @@ contract L1ETHBridgeTest is Test {
|
||||
"test-message"
|
||||
);
|
||||
|
||||
RollupMock.Message memory message = rollup.lastMessage();
|
||||
assertEq(message.to, l2ETHBridge);
|
||||
RollupMock.Message memory message = messageService.lastMessage();
|
||||
assertEq(message.to, remoteSender);
|
||||
assertEq(message.fee, 0);
|
||||
assertEq(message.value, 0);
|
||||
assertEq(message.data, expectedData);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
import { Test, console } from "forge-std/Test.sol";
|
||||
import { L2ETHBridge } from "../../../../src/yield/bridge/L2ETHBridge.sol";
|
||||
@@ -57,4 +57,3 @@ contract L2ETHBridgeTest is Test {
|
||||
assertEq(address(recipientMock).balance, 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.23;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
library TestUtils {
|
||||
// Helper function to convert address to ascii string
|
||||
@@ -43,4 +43,5 @@ library TestUtils {
|
||||
}
|
||||
return string(hexString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.23;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
import { Test } from "forge-std/Test.sol";
|
||||
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
contract ETHYieldManagerMock {
|
||||
struct Deposit {
|
||||
@@ -22,4 +22,3 @@ contract ETHYieldManagerMock {
|
||||
return deposits[deposits.length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
contract L2MessageServiceMock {
|
||||
address public originalSender;
|
||||
@@ -12,4 +12,3 @@ contract L2MessageServiceMock {
|
||||
return originalSender;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
contract RecipientMock {
|
||||
uint256 public lastCallParam;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
import { IRollup } from "../../../../../src/yield/bridge/interfaces/IRollup.sol";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user