-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DEPLOY-178]: Adds Scroll L2EP Contracts (#11405)
* Adds scroll L2EP contracts and tests * fixes comments, adds fixed solidity compiler version, and adds scroll tech contracts as a dev dependency * renames SCROLL_CROSS_DOMAIN_MESSENGER to i_SCROLL_CROSS_DOMAIN_MESSENGER for solhint * removes unnecessary solhint disable rule * moves scroll mocks from tests folder to l2ep folder * resolve solhint errors for scroll * proposed restructure to reduce inheritance * removes extraneous comments from scroll contracts and refactors typeAndVersion * use named parameters in mappings for scroll contracts * removes extraneous empty comments from scroll contracts (again) * removes unnecessary comment from scroll cross domain governor * adds minor formatting updates to scroll mocks * adds onlyL1Owner modifier back to ScrollCrossDomainGovernor * adds style and formatting improvements * adds formatting updates * refactors scroll sequencer uptime feed to reduce gas and updates test suites --------- Co-authored-by: Rens Rooimans <[email protected]>
- Loading branch information
1 parent
dfc62cc
commit 82faf5d
Showing
15 changed files
with
1,961 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
6 changes: 6 additions & 0 deletions
6
contracts/src/v0.8/l2ep/dev/interfaces/ScrollSequencerUptimeFeedInterface.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.19; | ||
|
||
interface ScrollSequencerUptimeFeedInterface { | ||
function updateStatus(bool status, uint64 timestamp) external; | ||
} |
65 changes: 65 additions & 0 deletions
65
contracts/src/v0.8/l2ep/dev/scroll/ScrollCrossDomainForwarder.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.19; | ||
|
||
import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; | ||
import {ForwarderInterface} from "../interfaces/ForwarderInterface.sol"; | ||
|
||
import {CrossDomainForwarder} from "../CrossDomainForwarder.sol"; | ||
import {CrossDomainOwnable} from "../CrossDomainOwnable.sol"; | ||
|
||
import {IScrollMessenger} from "@scroll-tech/contracts/libraries/IScrollMessenger.sol"; | ||
import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; | ||
|
||
/// @title ScrollCrossDomainForwarder - L1 xDomain account representation | ||
/// @notice L2 Contract which receives messages from a specific L1 address and transparently forwards them to the destination. | ||
/// @dev Any other L2 contract which uses this contract's address as a privileged position, | ||
/// can be considered to be owned by the `l1Owner` | ||
contract ScrollCrossDomainForwarder is TypeAndVersionInterface, CrossDomainForwarder { | ||
// solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables | ||
string public constant override typeAndVersion = "ScrollCrossDomainForwarder 1.0.0"; | ||
|
||
address internal immutable i_scrollCrossDomainMessenger; | ||
|
||
/// @param crossDomainMessengerAddr the xDomain bridge messenger (Scroll bridge L2) contract address | ||
/// @param l1OwnerAddr the L1 owner address that will be allowed to call the forward fn | ||
constructor(IScrollMessenger crossDomainMessengerAddr, address l1OwnerAddr) CrossDomainOwnable(l1OwnerAddr) { | ||
// solhint-disable-next-line custom-errors | ||
require(address(crossDomainMessengerAddr) != address(0), "Invalid xDomain Messenger address"); | ||
i_scrollCrossDomainMessenger = address(crossDomainMessengerAddr); | ||
} | ||
|
||
/// @dev forwarded only if L2 Messenger calls with `xDomainMessageSender` being the L1 owner address | ||
/// @inheritdoc ForwarderInterface | ||
function forward(address target, bytes memory data) external override onlyL1Owner { | ||
Address.functionCall(target, data, "Forwarder call reverted"); | ||
} | ||
|
||
/// @notice This is always the address of the Scroll Cross Domain Messenger contract | ||
function crossDomainMessenger() external view returns (address) { | ||
return address(i_scrollCrossDomainMessenger); | ||
} | ||
|
||
/// @notice The call MUST come from the L1 owner (via cross-chain message.) Reverts otherwise. | ||
modifier onlyL1Owner() override { | ||
// solhint-disable-next-line custom-errors | ||
require(msg.sender == i_scrollCrossDomainMessenger, "Sender is not the L2 messenger"); | ||
// solhint-disable-next-line custom-errors | ||
require( | ||
IScrollMessenger(i_scrollCrossDomainMessenger).xDomainMessageSender() == l1Owner(), | ||
"xDomain sender is not the L1 owner" | ||
); | ||
_; | ||
} | ||
|
||
/// @notice The call MUST come from the proposed L1 owner (via cross-chain message.) Reverts otherwise. | ||
modifier onlyProposedL1Owner() override { | ||
// solhint-disable-next-line custom-errors | ||
require(msg.sender == i_scrollCrossDomainMessenger, "Sender is not the L2 messenger"); | ||
// solhint-disable-next-line custom-errors | ||
require( | ||
IScrollMessenger(i_scrollCrossDomainMessenger).xDomainMessageSender() == s_l1PendingOwner, | ||
"Must be proposed L1 owner" | ||
); | ||
_; | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
contracts/src/v0.8/l2ep/dev/scroll/ScrollCrossDomainGovernor.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.19; | ||
|
||
import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; | ||
import {DelegateForwarderInterface} from "../interfaces/DelegateForwarderInterface.sol"; | ||
// solhint-disable-next-line no-unused-import | ||
import {ForwarderInterface} from "../interfaces/ForwarderInterface.sol"; | ||
|
||
import {CrossDomainForwarder} from "../CrossDomainForwarder.sol"; | ||
import {CrossDomainOwnable} from "../CrossDomainOwnable.sol"; | ||
|
||
import {IScrollMessenger} from "@scroll-tech/contracts/libraries/IScrollMessenger.sol"; | ||
import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; | ||
|
||
/// @title ScrollCrossDomainGovernor - L1 xDomain account representation (with delegatecall support) for Scroll | ||
/// @notice L2 Contract which receives messages from a specific L1 address and transparently forwards them to the destination. | ||
/// @dev Any other L2 contract which uses this contract's address as a privileged position, | ||
/// can be considered to be simultaneously owned by the `l1Owner` and L2 `owner` | ||
contract ScrollCrossDomainGovernor is DelegateForwarderInterface, TypeAndVersionInterface, CrossDomainForwarder { | ||
// solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables | ||
string public constant override typeAndVersion = "ScrollCrossDomainGovernor 1.0.0"; | ||
|
||
address internal immutable i_scrollCrossDomainMessenger; | ||
|
||
/// @param crossDomainMessengerAddr the xDomain bridge messenger (Scroll bridge L2) contract address | ||
/// @param l1OwnerAddr the L1 owner address that will be allowed to call the forward fn | ||
constructor(IScrollMessenger crossDomainMessengerAddr, address l1OwnerAddr) CrossDomainOwnable(l1OwnerAddr) { | ||
// solhint-disable-next-line custom-errors | ||
require(address(crossDomainMessengerAddr) != address(0), "Invalid xDomain Messenger address"); | ||
i_scrollCrossDomainMessenger = address(crossDomainMessengerAddr); | ||
} | ||
|
||
/// @inheritdoc ForwarderInterface | ||
/// @dev forwarded only if L2 Messenger calls with `msg.sender` being the L1 owner address, or called by the L2 owner | ||
function forward(address target, bytes memory data) external override onlyLocalOrCrossDomainOwner { | ||
Address.functionCall(target, data, "Governor call reverted"); | ||
} | ||
|
||
/// @inheritdoc DelegateForwarderInterface | ||
/// @dev forwarded only if L2 Messenger calls with `msg.sender` being the L1 owner address, or called by the L2 owner | ||
function forwardDelegate(address target, bytes memory data) external override onlyLocalOrCrossDomainOwner { | ||
Address.functionDelegateCall(target, data, "Governor delegatecall reverted"); | ||
} | ||
|
||
/// @notice The address of the Scroll Cross Domain Messenger contract | ||
function crossDomainMessenger() external view returns (address) { | ||
return address(i_scrollCrossDomainMessenger); | ||
} | ||
|
||
/// @notice The call MUST come from the L1 owner (via cross-chain message.) Reverts otherwise. | ||
modifier onlyL1Owner() override { | ||
// solhint-disable-next-line custom-errors | ||
require(msg.sender == i_scrollCrossDomainMessenger, "Sender is not the L2 messenger"); | ||
// solhint-disable-next-line custom-errors | ||
require( | ||
IScrollMessenger(i_scrollCrossDomainMessenger).xDomainMessageSender() == l1Owner(), | ||
"xDomain sender is not the L1 owner" | ||
); | ||
_; | ||
} | ||
|
||
/// @notice The call MUST come from either the L1 owner (via cross-chain message) or the L2 owner. Reverts otherwise. | ||
modifier onlyLocalOrCrossDomainOwner() { | ||
// 1. The delegatecall MUST come from either the L1 owner (via cross-chain message) or the L2 owner | ||
// solhint-disable-next-line custom-errors | ||
require( | ||
msg.sender == i_scrollCrossDomainMessenger || msg.sender == owner(), | ||
"Sender is not the L2 messenger or owner" | ||
); | ||
// 2. The L2 Messenger's caller MUST be the L1 Owner | ||
if (msg.sender == i_scrollCrossDomainMessenger) { | ||
// solhint-disable-next-line custom-errors | ||
require( | ||
IScrollMessenger(i_scrollCrossDomainMessenger).xDomainMessageSender() == l1Owner(), | ||
"xDomain sender is not the L1 owner" | ||
); | ||
} | ||
_; | ||
} | ||
|
||
/// @notice The call MUST come from the proposed L1 owner (via cross-chain message.) Reverts otherwise. | ||
modifier onlyProposedL1Owner() override { | ||
// solhint-disable-next-line custom-errors | ||
require(msg.sender == i_scrollCrossDomainMessenger, "Sender is not the L2 messenger"); | ||
// solhint-disable-next-line custom-errors | ||
require( | ||
IScrollMessenger(i_scrollCrossDomainMessenger).xDomainMessageSender() == s_l1PendingOwner, | ||
"Must be proposed L1 owner" | ||
); | ||
_; | ||
} | ||
} |
Oops, something went wrong.