Skip to content

Commit

Permalink
merges CrossDomainOwnable with CrossDomainForwarder and changes Cross…
Browse files Browse the repository at this point in the history
…DomainGovernor to inherit CrossDomainForwarder
  • Loading branch information
chris-de-leon-cll committed Jan 25, 2024
1 parent f8c0b92 commit f27c815
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 161 deletions.
4 changes: 2 additions & 2 deletions contracts/src/v0.8/l2ep/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ The `/dev` folder contains subfolders for each chain that
has an L2EP solution implemented for it (e.g. `/scroll`, `/arbitrum`,
`/optimism`). It also contains a subfolder named `/interfaces`,
which stores shared interface types between all the supported
contracts. The top-level contracts (e.g. `CrossDomainOwnable.sol`)
contracts. The top-level contracts (e.g. `Validator.sol`)
serve as either abstract or parent contracts that are meant
to be reused for each indiviudal chain.
to be reused for each individual chain.

## The `/test` Folder

Expand Down
68 changes: 64 additions & 4 deletions contracts/src/v0.8/l2ep/dev/CrossDomainForwarder.sol
Original file line number Diff line number Diff line change
@@ -1,27 +1,87 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {CrossDomainOwnableInterface} from "./interfaces/CrossDomainOwnableInterface.sol";
import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol";
import {ForwarderInterface} from "./interfaces/ForwarderInterface.sol";

import {CrossDomainOwnable} from "./CrossDomainOwnable.sol";
import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol";

import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";

/// @title CrossDomainForwarder - 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 consider that position to be held by the `l1Owner`
abstract contract CrossDomainForwarder is ITypeAndVersion, ForwarderInterface, CrossDomainOwnable {
abstract contract CrossDomainForwarder is
ITypeAndVersion,
ForwarderInterface,
CrossDomainOwnableInterface,
ConfirmedOwner
{
address internal s_l1Owner;
address internal s_l1PendingOwner;

/// @param l1OwnerAddr the L1 owner address that will be allowed to call the forward fn
constructor(address l1OwnerAddr) CrossDomainOwnable(l1OwnerAddr) {}
constructor(address l1OwnerAddr) ConfirmedOwner(msg.sender) {
_setL1Owner(l1OwnerAddr);
}

/// @notice Reverts if called by anyone other than the L1 owner.
modifier onlyL1Owner() virtual {
// solhint-disable-next-line custom-errors
require(msg.sender == s_l1Owner, "Only callable by L1 owner");
_;
}

/// @notice Reverts if called by anyone other than the L1 owner.
modifier onlyProposedL1Owner() virtual {
// solhint-disable-next-line custom-errors
require(msg.sender == s_l1PendingOwner, "Only callable by proposed L1 owner");
_;
}

/// @notice The address of the Cross Domain Messenger contract
function crossDomainMessenger() external view virtual returns (address);

/// @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 {
function forward(address target, bytes memory data) external virtual override onlyL1Owner {
Address.functionCall(target, data, "Forwarder call reverted");
}

/// @notice transfer ownership of this account to a new L1 owner
/// @param to new L1 owner that will be allowed to call the forward fn
function transferL1Ownership(address to) public virtual override onlyL1Owner {
_transferL1Ownership(to);
}

/// @notice accept ownership of this account to a new L1 owner
function acceptL1Ownership() public virtual override onlyProposedL1Owner {
_setL1Owner(s_l1PendingOwner);
}

/// @notice Get the current owner
function l1Owner() public view override returns (address) {
return s_l1Owner;
}

/// @notice validate, transfer ownership, and emit relevant events
function _transferL1Ownership(address to) internal {
// solhint-disable-next-line custom-errors
require(to != msg.sender, "Cannot transfer to self");

s_l1PendingOwner = to;

emit L1OwnershipTransferRequested(s_l1Owner, to);
}

/// @notice set ownership, emit relevant events. Used in acceptOwnership()
function _setL1Owner(address to) internal {
address oldOwner = s_l1Owner;
s_l1Owner = to;
s_l1PendingOwner = address(0);

emit L1OwnershipTransferred(oldOwner, to);
}
}
16 changes: 4 additions & 12 deletions contracts/src/v0.8/l2ep/dev/CrossDomainGovernor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,20 @@
pragma solidity 0.8.19;

import {DelegateForwarderInterface} from "./interfaces/DelegateForwarderInterface.sol";
import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol";
// solhint-disable-next-line no-unused-import
import {ForwarderInterface} from "./interfaces/ForwarderInterface.sol";

import {CrossDomainOwnable} from "./CrossDomainOwnable.sol";
import {CrossDomainForwarder} from "./CrossDomainForwarder.sol";

import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";

/// @title CrossDomainGovernor - 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`
abstract contract CrossDomainGovernor is
DelegateForwarderInterface,
ForwarderInterface,
CrossDomainOwnable,
ITypeAndVersion
{
abstract contract CrossDomainGovernor is DelegateForwarderInterface, CrossDomainForwarder {
/// @param l1OwnerAddr the L1 owner address that will be allowed to call the forward fn
constructor(address l1OwnerAddr) CrossDomainOwnable(l1OwnerAddr) {}

/// @notice The address of the Cross Domain Messenger contract
function crossDomainMessenger() external view virtual returns (address);
constructor(address l1OwnerAddr) CrossDomainForwarder(l1OwnerAddr) {}

/// @notice The call MUST come from either the L1 owner (via cross-chain message) or the L2 owner. Reverts otherwise.
function _requireLocalOrCrossDomainOwner() internal view virtual;
Expand Down
66 changes: 0 additions & 66 deletions contracts/src/v0.8/l2ep/dev/CrossDomainOwnable.sol

This file was deleted.

77 changes: 0 additions & 77 deletions contracts/test/v0.8/dev/CrossDomainOwnable.test.ts

This file was deleted.

0 comments on commit f27c815

Please sign in to comment.