Untitled Diff

Created Diff never expires
The two texts are identical
There is no difference to show between these two texts
0 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
92 lines
0 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
92 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2021 Dai Foundation
// Copyright (C) 2021 Dai Foundation
// This program is free software: you can redistribute it and/or modify
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// (at your option) any later version.
//
//
// This program is distributed in the hope that it will be useful,
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
// GNU Affero General Public License for more details.
//
//
// You should have received a copy of the GNU Affero General Public License
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// along with this program. If not, see <https://www.gnu.org/licenses/>.


pragma solidity ^0.6.11;
pragma solidity ^0.6.11;


import "../arbitrum/IInbox.sol";
import "../arbitrum/IInbox.sol";


import "./L1CrossDomainEnabled.sol";
import "./L1CrossDomainEnabled.sol";
import "../l2/L2GovernanceRelay.sol";
import "../l2/L2GovernanceRelay.sol";


// Relay a message from L1 to L2GovernanceRelay
// Relay a message from L1 to L2GovernanceRelay
// Sending L1->L2 message on arbitrum requires ETH balance. That's why this contract can receive ether.
// Sending L1->L2 message on arbitrum requires ETH balance. That's why this contract can receive ether.
// Excessive ether can be reclaimed by governance by calling reclaim function.
// Excessive ether can be reclaimed by governance by calling reclaim function.


contract L1GovernanceRelay is L1CrossDomainEnabled {
contract L1GovernanceRelay is L1CrossDomainEnabled {
// --- Auth ---
// --- Auth ---
mapping(address => uint256) public wards;
mapping(address => uint256) public wards;


function rely(address usr) external auth {
function rely(address usr) external auth {
wards[usr] = 1;
wards[usr] = 1;
emit Rely(usr);
emit Rely(usr);
}
}


function deny(address usr) external auth {
function deny(address usr) external auth {
wards[usr] = 0;
wards[usr] = 0;
emit Deny(usr);
emit Deny(usr);
}
}


modifier auth() {
modifier auth() {
require(wards[msg.sender] == 1, "L1GovernanceRelay/not-authorized");
require(wards[msg.sender] == 1, "L1GovernanceRelay/not-authorized");
_;
_;
}
}


address public immutable l2GovernanceRelay;
address public immutable l2GovernanceRelay;


event Rely(address indexed usr);
event Rely(address indexed usr);
event Deny(address indexed usr);
event Deny(address indexed usr);


constructor(address _inbox, address _l2GovernanceRelay) public L1CrossDomainEnabled(_inbox) {
constructor(address _inbox, address _l2GovernanceRelay) public L1CrossDomainEnabled(_inbox) {
wards[msg.sender] = 1;
wards[msg.sender] = 1;
emit Rely(msg.sender);
emit Rely(msg.sender);


l2GovernanceRelay = _l2GovernanceRelay;
l2GovernanceRelay = _l2GovernanceRelay;
}
}


// Allow contract to receive ether
// Allow contract to receive ether
receive() external payable {}
receive() external payable {}


// Allow governance to reclaim stored ether
// Allow governance to reclaim stored ether
function reclaim(address receiver, uint256 amount) external auth {
function reclaim(address receiver, uint256 amount) external auth {
(bool sent, ) = receiver.call{value: amount}("");
(bool sent, ) = receiver.call{value: amount}("");
require(sent, "L1GovernanceRelay/failed-to-send-ether");
require(sent, "L1GovernanceRelay/failed-to-send-ether");
}
}


// Forward a call to be repeated on L2
// Forward a call to be repeated on L2
function relay(
function relay(
address target,
address target,
bytes calldata targetData,
bytes calldata targetData,
uint256 l1CallValue,
uint256 l1CallValue,
uint256 maxGas,
uint256 maxGas,
uint256 gasPriceBid,
uint256 gasPriceBid,
uint256 maxSubmissionCost
uint256 maxSubmissionCost
) external payable auth {
) external payable auth {
bytes memory data = abi.encodeWithSelector(
bytes memory data = abi.encodeWithSelector(
L2GovernanceRelay.relay.selector,
L2GovernanceRelay.relay.selector,
target,
target,
targetData
targetData
);
);


sendTxToL2NoAliasing(
sendTxToL2NoAliasing(
l2GovernanceRelay,
l2GovernanceRelay,
l2GovernanceRelay, // send any excess ether to the L2 counterpart
l2GovernanceRelay, // send any excess ether to the L2 counterpart
l1CallValue,
l1CallValue,
maxSubmissionCost,
maxSubmissionCost,
maxGas,
maxGas,
gasPriceBid,
gasPriceBid,
data
data
);
);
}
}
}
}