-
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.
Adds scroll L2EP contracts and tests
- Loading branch information
1 parent
9bd3ecb
commit ab23752
Showing
14 changed files
with
2,046 additions
and
2 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
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.0; | ||
|
||
interface ScrollSequencerUptimeFeedInterface { | ||
function updateStatus(bool status, uint64 timestamp) external; | ||
} |
87 changes: 87 additions & 0 deletions
87
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,87 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; | ||
// solhint-disable-next-line no-unused-import | ||
import {ForwarderInterface} from "../interfaces/ForwarderInterface.sol"; | ||
|
||
/* ./dev dependencies - to be moved from ./dev after audit */ | ||
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/prefix-immutable-variables-with-i | ||
IScrollMessenger private immutable SCROLL_CROSS_DOMAIN_MESSENGER; | ||
|
||
/** | ||
* @notice creates a new Scroll xDomain Forwarder contract | ||
* @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"); | ||
SCROLL_CROSS_DOMAIN_MESSENGER = crossDomainMessengerAddr; | ||
} | ||
|
||
/** | ||
* @notice versions: | ||
* | ||
* - ScrollCrossDomainForwarder 1.0.0: initial release | ||
* | ||
* @inheritdoc TypeAndVersionInterface | ||
*/ | ||
function typeAndVersion() external pure virtual override returns (string memory) { | ||
return "ScrollCrossDomainForwarder 1.0.0"; | ||
} | ||
|
||
/** | ||
* @dev forwarded only if L2 Messenger calls with `xDomainMessageSender` being the L1 owner address | ||
* @inheritdoc ForwarderInterface | ||
*/ | ||
function forward(address target, bytes memory data) external virtual override onlyL1Owner { | ||
Address.functionCall(target, data, "Forwarder call reverted"); | ||
} | ||
|
||
/** | ||
* @notice This is always the address of the Scroll Cross Domain Messenger contract | ||
*/ | ||
function crossDomainMessenger() public view returns (address) { | ||
return address(SCROLL_CROSS_DOMAIN_MESSENGER); | ||
} | ||
|
||
/** | ||
* @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 == crossDomainMessenger(), "Sender is not the L2 messenger"); | ||
// solhint-disable-next-line custom-errors | ||
require( | ||
IScrollMessenger(crossDomainMessenger()).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 { | ||
address messenger = crossDomainMessenger(); | ||
// solhint-disable-next-line custom-errors | ||
require(msg.sender == messenger, "Sender is not the L2 messenger"); | ||
// solhint-disable-next-line custom-errors | ||
require(IScrollMessenger(messenger).xDomainMessageSender() == s_l1PendingOwner, "Must be proposed L1 owner"); | ||
_; | ||
} | ||
} |
71 changes: 71 additions & 0 deletions
71
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,71 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {DelegateForwarderInterface} from "../interfaces/DelegateForwarderInterface.sol"; | ||
// solhint-disable-next-line no-unused-import | ||
import {ForwarderInterface} from "../interfaces/ForwarderInterface.sol"; | ||
|
||
import {ScrollCrossDomainForwarder} from "./ScrollCrossDomainForwarder.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, ScrollCrossDomainForwarder { | ||
/** | ||
* @notice creates a new Scroll xDomain Forwarder contract | ||
* @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 | ||
* @dev Empty constructor required due to inheriting from abstract contract CrossDomainForwarder | ||
*/ | ||
constructor( | ||
IScrollMessenger crossDomainMessengerAddr, | ||
address l1OwnerAddr | ||
) ScrollCrossDomainForwarder(crossDomainMessengerAddr, l1OwnerAddr) {} | ||
|
||
/** | ||
* @notice versions: | ||
* | ||
* - ScrollCrossDomainGovernor 1.0.0: initial release | ||
*/ | ||
function typeAndVersion() external pure virtual override returns (string memory) { | ||
return "ScrollCrossDomainGovernor 1.0.0"; | ||
} | ||
|
||
/** | ||
* @dev forwarded only if L2 Messenger calls with `msg.sender` being the L1 owner address, or called by the L2 owner | ||
* @inheritdoc ForwarderInterface | ||
*/ | ||
function forward(address target, bytes memory data) external override onlyLocalOrCrossDomainOwner { | ||
Address.functionCall(target, data, "Governor call reverted"); | ||
} | ||
|
||
/** | ||
* @dev forwarded only if L2 Messenger calls with `msg.sender` being the L1 owner address, or called by the L2 owner | ||
* @inheritdoc DelegateForwarderInterface | ||
*/ | ||
function forwardDelegate(address target, bytes memory data) external override onlyLocalOrCrossDomainOwner { | ||
Address.functionDelegateCall(target, data, "Governor delegatecall reverted"); | ||
} | ||
|
||
/** | ||
* @notice The call MUST come from either the L1 owner (via cross-chain message) or the L2 owner. Reverts otherwise. | ||
*/ | ||
modifier onlyLocalOrCrossDomainOwner() { | ||
address messenger = crossDomainMessenger(); | ||
// 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 == messenger || 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 == messenger) { | ||
// solhint-disable-next-line custom-errors | ||
require(IScrollMessenger(messenger).xDomainMessageSender() == l1Owner(), "xDomain sender is not the L1 owner"); | ||
} | ||
_; | ||
} | ||
} |
Oops, something went wrong.