Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
74a63c94
Unverified
Commit
74a63c94
authored
Feb 18, 2023
by
mergify[bot]
Committed by
GitHub
Feb 18, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4882 from ethereum-optimism/crossdomainownable3
contracts-bedrock: CrossDomainOwnable3
parents
ed4d716a
35ae34fe
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
308 additions
and
0 deletions
+308
-0
.gas-snapshot
packages/contracts-bedrock/.gas-snapshot
+12
-0
CrossDomainOwnable3.sol
...es/contracts-bedrock/contracts/L2/CrossDomainOwnable3.sol
+71
-0
CrossDomainOwnable3.t.sol
...ontracts-bedrock/contracts/test/CrossDomainOwnable3.t.sol
+225
-0
No files found.
packages/contracts-bedrock/.gas-snapshot
View file @
74a63c94
...
@@ -24,6 +24,18 @@ CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8416)
...
@@ -24,6 +24,18 @@ CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8416)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 61738)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 61738)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16588)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16588)
CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 77766)
CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 77766)
CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10510)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28311)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 78170)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32000)
CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 95748)
CrossDomainOwnable3_Test:test_localOnlyOwner_notOwner_reverts() (gas: 13237)
CrossDomainOwnable3_Test:test_localOnlyOwner_succeeds() (gas: 35197)
CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52084)
CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48565)
CrossDomainOwnable3_Test:test_transferOwnership_noLocal_zeroAddress_reverts() (gas: 12039)
CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13414)
CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12058)
DeployerWhitelist_Test:test_owner_succeeds() (gas: 7538)
DeployerWhitelist_Test:test_owner_succeeds() (gas: 7538)
DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395)
DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395)
FeeVault_Test:test_constructor_succeeds() (gas: 10647)
FeeVault_Test:test_constructor_succeeds() (gas: 10647)
...
...
packages/contracts-bedrock/contracts/L2/CrossDomainOwnable3.sol
0 → 100644
View file @
74a63c94
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { Predeploys } from "../libraries/Predeploys.sol";
import { L2CrossDomainMessenger } from "./L2CrossDomainMessenger.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title CrossDomainOwnable3
* @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned
* by contracts on either L1 or L2. Note that this contract is meant to be used with systems
* that use the CrossDomainMessenger system. It will not work if the OptimismPortal is
* used directly.
*/
abstract contract CrossDomainOwnable3 is Ownable {
/**
* @notice If true, the contract uses the cross domain _checkOwner function override. If false
* it uses the standard Ownable _checkOwner function.
*/
bool public isLocal = true;
/**
* @notice Emits when ownership of the contract is transferred. Includes the
* isLocal field in addition to the standard `Ownable` OwnershipTransferred event.
*/
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner,
bool isLocal
);
/**
* @notice Allows for ownership to be transferred with specifying the locality.
* @param _owner The new owner of the contract.
* @param _isLocal Configures the locality of the ownership.
*/
function transferOwnership(address _owner, bool _isLocal) external onlyOwner {
require(_owner != address(0), "CrossDomainOwnable3: new owner is the zero address");
address oldOwner = owner();
_transferOwnership(_owner);
isLocal = _isLocal;
emit OwnershipTransferred(oldOwner, _owner, _isLocal);
}
/**
* @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased
* `xDomainMessageSender` is the owner of the contract. This value is set to the caller
* of the L1CrossDomainMessenger.
*/
function _checkOwner() internal view override {
if (isLocal) {
require(owner() == msg.sender, "CrossDomainOwnable3: caller is not the owner");
} else {
L2CrossDomainMessenger messenger = L2CrossDomainMessenger(
Predeploys.L2_CROSS_DOMAIN_MESSENGER
);
require(
msg.sender == address(messenger),
"CrossDomainOwnable3: caller is not the messenger"
);
require(
owner() == messenger.xDomainMessageSender(),
"CrossDomainOwnable3: caller is not the owner"
);
}
}
}
packages/contracts-bedrock/contracts/test/CrossDomainOwnable3.t.sol
0 → 100644
View file @
74a63c94
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";
import { CommonTest, Messenger_Initializer } from "./CommonTest.t.sol";
import { CrossDomainOwnable3 } from "../L2/CrossDomainOwnable3.sol";
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
import { Hashing } from "../libraries/Hashing.sol";
import { Encoding } from "../libraries/Encoding.sol";
contract XDomainSetter3 is CrossDomainOwnable3 {
uint256 public value;
function set(uint256 _value) external onlyOwner {
value = _value;
}
}
contract CrossDomainOwnable3_Test is Messenger_Initializer {
XDomainSetter3 setter;
/**
* @notice OpenZeppelin Ownable.sol transferOwnership event
*/
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @notice CrossDomainOwnable3.sol transferOwnership event
*/
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner,
bool isLocal
);
function setUp() public override {
super.setUp();
vm.prank(alice);
setter = new XDomainSetter3();
}
function test_constructor_succeeds() public {
assertEq(setter.owner(), alice);
assertEq(setter.isLocal(), true);
}
function test_localOnlyOwner_notOwner_reverts() public {
vm.prank(bob);
vm.expectRevert("CrossDomainOwnable3: caller is not the owner");
setter.set(1);
}
function test_transferOwnership_notOwner_reverts() public {
vm.prank(bob);
vm.expectRevert("CrossDomainOwnable3: caller is not the owner");
setter.transferOwnership({ _owner: bob, _isLocal: true });
}
function test_crossDomainOnlyOwner_notOwner_reverts() public {
vm.expectEmit(true, true, true, true);
// OpenZeppelin Ownable.sol transferOwnership event
emit OwnershipTransferred(alice, alice);
// CrossDomainOwnable3.sol transferOwnership event
emit OwnershipTransferred(alice, alice, false);
vm.prank(setter.owner());
setter.transferOwnership({ _owner: alice, _isLocal: false });
// set the xDomainMsgSender storage slot
bytes32 key = bytes32(uint256(204));
bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob);
vm.store(address(L2Messenger), key, value);
vm.prank(address(L2Messenger));
vm.expectRevert("CrossDomainOwnable3: caller is not the owner");
setter.set(1);
}
function test_crossDomainOnlyOwner_notOwner2_reverts() public {
vm.expectEmit(true, true, true, true);
// OpenZeppelin Ownable.sol transferOwnership event
emit OwnershipTransferred(alice, alice);
// CrossDomainOwnable3.sol transferOwnership event
emit OwnershipTransferred(alice, alice, false);
vm.prank(setter.owner());
setter.transferOwnership({ _owner: alice, _isLocal: false });
assertEq(setter.isLocal(), false);
uint240 nonce = 0;
address sender = bob;
address target = address(setter);
uint256 value = 0;
uint256 minGasLimit = 0;
bytes memory message = abi.encodeWithSelector(XDomainSetter3.set.selector, 1);
bytes32 hash = Hashing.hashCrossDomainMessage(
Encoding.encodeVersionedNonce(nonce, 1),
sender,
target,
value,
minGasLimit,
message
);
// It should be a failed message. The revert is caught,
// so we cannot expectRevert here.
vm.expectEmit(true, true, true, true, address(L2Messenger));
emit FailedRelayedMessage(hash);
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));
L2Messenger.relayMessage(
Encoding.encodeVersionedNonce(nonce, 1),
sender,
target,
value,
minGasLimit,
message
);
assertEq(setter.value(), 0);
}
function test_crossDomainOnlyOwner_notMessenger_reverts() public {
vm.expectEmit(true, true, true, true);
// OpenZeppelin Ownable.sol transferOwnership event
emit OwnershipTransferred(alice, alice);
// CrossDomainOwnable3.sol transferOwnership event
emit OwnershipTransferred(alice, alice, false);
vm.prank(setter.owner());
setter.transferOwnership({ _owner: alice, _isLocal: false });
vm.prank(bob);
vm.expectRevert("CrossDomainOwnable3: caller is not the messenger");
setter.set(1);
}
function test_transferOwnership_zeroAddress_reverts() public {
vm.prank(setter.owner());
vm.expectRevert("CrossDomainOwnable3: new owner is the zero address");
setter.transferOwnership({ _owner: address(0), _isLocal: true });
}
function test_transferOwnership_noLocal_zeroAddress_reverts() public {
vm.prank(setter.owner());
vm.expectRevert("Ownable: new owner is the zero address");
setter.transferOwnership(address(0));
}
function test_localOnlyOwner_succeeds() public {
assertEq(setter.isLocal(), true);
vm.prank(setter.owner());
setter.set(1);
assertEq(setter.value(), 1);
}
function test_localTransferOwnership_succeeds() public {
vm.expectEmit(true, true, true, true, address(setter));
emit OwnershipTransferred(alice, bob);
emit OwnershipTransferred(alice, bob, true);
vm.prank(setter.owner());
setter.transferOwnership({ _owner: bob, _isLocal: true });
assertEq(setter.isLocal(), true);
vm.prank(bob);
setter.set(2);
assertEq(setter.value(), 2);
}
/**
* @notice The existing transferOwnership(address) method
* still exists on the contract
*/
function test_transferOwnershipNoLocal_succeeds() public {
bool isLocal = setter.isLocal();
vm.expectEmit(true, true, true, true, address(setter));
emit OwnershipTransferred(alice, bob);
vm.prank(setter.owner());
setter.transferOwnership(bob);
// isLocal has not changed
assertEq(setter.isLocal(), isLocal);
vm.prank(bob);
setter.set(2);
assertEq(setter.value(), 2);
}
function test_crossDomainTransferOwnership_succeeds() public {
vm.expectEmit(true, true, true, true, address(setter));
emit OwnershipTransferred(alice, bob);
emit OwnershipTransferred(alice, bob, false);
vm.prank(setter.owner());
setter.transferOwnership({ _owner: bob, _isLocal: false });
assertEq(setter.isLocal(), false);
// Simulate the L2 execution where the call is coming from
// the L1CrossDomainMessenger
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));
L2Messenger.relayMessage(
Encoding.encodeVersionedNonce(1, 1),
bob,
address(setter),
0,
0,
abi.encodeWithSelector(XDomainSetter3.set.selector, 2)
);
assertEq(setter.value(), 2);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment