Add utilities for CrossChain messaging (#3183)
Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
This commit is contained in:
@ -0,0 +1,43 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.4;
|
||||
|
||||
import "../CrossChainEnabled.sol";
|
||||
import "./LibArbitrumL1.sol";
|
||||
|
||||
/**
|
||||
* @dev [Arbitrum](https://arbitrum.io/) specialization or the
|
||||
* {CrossChainEnabled} abstraction the L1 side (mainnet).
|
||||
*
|
||||
* This version should only be deployed on L1 to process cross-chain messages
|
||||
* originating from L2. For the other side, use {CrossChainEnabledArbitrumL2}.
|
||||
*
|
||||
* The bridge contract is provided and maintained by the arbitrum team. You can
|
||||
* find the address of this contract on the rinkeby testnet in
|
||||
* [Arbitrum's developer documentation](https://developer.offchainlabs.com/docs/useful_addresses).
|
||||
*
|
||||
* _Available since v4.6._
|
||||
*/
|
||||
abstract contract CrossChainEnabledArbitrumL1 is CrossChainEnabled {
|
||||
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
|
||||
address private immutable _bridge;
|
||||
|
||||
/// @custom:oz-upgrades-unsafe-allow constructor
|
||||
constructor(address bridge) {
|
||||
_bridge = bridge;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev see {CrossChainEnabled-_isCrossChain}
|
||||
*/
|
||||
function _isCrossChain() internal view virtual override returns (bool) {
|
||||
return LibArbitrumL1.isCrossChain(_bridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev see {CrossChainEnabled-_crossChainSender}
|
||||
*/
|
||||
function _crossChainSender() internal view virtual override onlyCrossChain returns (address) {
|
||||
return LibArbitrumL1.crossChainSender(_bridge);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.4;
|
||||
|
||||
import "../CrossChainEnabled.sol";
|
||||
import "./LibArbitrumL2.sol";
|
||||
|
||||
/**
|
||||
* @dev [Arbitrum](https://arbitrum.io/) specialization or the
|
||||
* {CrossChainEnabled} abstraction the L2 side (arbitrum).
|
||||
*
|
||||
* This version should only be deployed on L2 to process cross-chain messages
|
||||
* originating from L1. For the other side, use {CrossChainEnabledArbitrumL1}.
|
||||
*
|
||||
* Arbitrum L2 includes the `ArbSys` contract at a fixed address. Therefore,
|
||||
* this specialization of {CrossChainEnabled} does not include a constructor.
|
||||
*
|
||||
* _Available since v4.6._
|
||||
*/
|
||||
abstract contract CrossChainEnabledArbitrumL2 is CrossChainEnabled {
|
||||
/**
|
||||
* @dev see {CrossChainEnabled-_isCrossChain}
|
||||
*/
|
||||
function _isCrossChain() internal view virtual override returns (bool) {
|
||||
return LibArbitrumL2.isCrossChain(LibArbitrumL2.ARBSYS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev see {CrossChainEnabled-_crossChainSender}
|
||||
*/
|
||||
function _crossChainSender() internal view virtual override onlyCrossChain returns (address) {
|
||||
return LibArbitrumL2.crossChainSender(LibArbitrumL2.ARBSYS);
|
||||
}
|
||||
}
|
||||
42
contracts/crosschain/arbitrum/LibArbitrumL1.sol
Normal file
42
contracts/crosschain/arbitrum/LibArbitrumL1.sol
Normal file
@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.4;
|
||||
|
||||
import {IBridge as ArbitrumL1_Bridge} from "../../vendor/arbitrum/IBridge.sol";
|
||||
import {IInbox as ArbitrumL1_Inbox} from "../../vendor/arbitrum/IInbox.sol";
|
||||
import {IOutbox as ArbitrumL1_Outbox} from "../../vendor/arbitrum/IOutbox.sol";
|
||||
import "../errors.sol";
|
||||
|
||||
/**
|
||||
* @dev Primitives for cross-chain aware contracts for
|
||||
* [Arbitrum](https://arbitrum.io/).
|
||||
*
|
||||
* This version should only be used on L1 to process cross-chain messages
|
||||
* originating from L2. For the other side, use {LibArbitrumL2}.
|
||||
*/
|
||||
library LibArbitrumL1 {
|
||||
/**
|
||||
* @dev Returns whether the current function call is the result of a
|
||||
* cross-chain message relayed by the `bridge`.
|
||||
*/
|
||||
function isCrossChain(address bridge) internal view returns (bool) {
|
||||
return msg.sender == bridge;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the sender that triggered the current
|
||||
* cross-chain message through the `bridge`.
|
||||
*
|
||||
* NOTE: {isCrossChain} should be checked before trying to recover the
|
||||
* sender, as it will revert with `NotCrossChainCall` if the current
|
||||
* function call is not the result of a cross-chain message.
|
||||
*/
|
||||
function crossChainSender(address bridge) internal view returns (address) {
|
||||
if (!isCrossChain(bridge)) revert NotCrossChainCall();
|
||||
|
||||
address sender = ArbitrumL1_Outbox(ArbitrumL1_Bridge(bridge).activeOutbox()).l2ToL1Sender();
|
||||
require(sender != address(0), "LibArbitrumL1: system messages without sender");
|
||||
|
||||
return sender;
|
||||
}
|
||||
}
|
||||
42
contracts/crosschain/arbitrum/LibArbitrumL2.sol
Normal file
42
contracts/crosschain/arbitrum/LibArbitrumL2.sol
Normal file
@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.4;
|
||||
|
||||
import {IArbSys as ArbitrumL2_Bridge} from "../../vendor/arbitrum/IArbSys.sol";
|
||||
import "../errors.sol";
|
||||
|
||||
/**
|
||||
* @dev Primitives for cross-chain aware contracts for
|
||||
* [Arbitrum](https://arbitrum.io/).
|
||||
*
|
||||
* This version should only be used on L2 to process cross-chain messages
|
||||
* originating from L1. For the other side, use {LibArbitrumL1}.
|
||||
*/
|
||||
library LibArbitrumL2 {
|
||||
/**
|
||||
* @dev Returns whether the current function call is the result of a
|
||||
* cross-chain message relayed by `arbsys`.
|
||||
*/
|
||||
address public constant ARBSYS = 0x0000000000000000000000000000000000000064;
|
||||
|
||||
function isCrossChain(address arbsys) internal view returns (bool) {
|
||||
return ArbitrumL2_Bridge(arbsys).isTopLevelCall();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the sender that triggered the current
|
||||
* cross-chain message through `arbsys`.
|
||||
*
|
||||
* NOTE: {isCrossChain} should be checked before trying to recover the
|
||||
* sender, as it will revert with `NotCrossChainCall` if the current
|
||||
* function call is not the result of a cross-chain message.
|
||||
*/
|
||||
function crossChainSender(address arbsys) internal view returns (address) {
|
||||
if (!isCrossChain(arbsys)) revert NotCrossChainCall();
|
||||
|
||||
return
|
||||
ArbitrumL2_Bridge(arbsys).wasMyCallersAddressAliased()
|
||||
? ArbitrumL2_Bridge(arbsys).myCallersAddressWithoutAliasing()
|
||||
: msg.sender;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user