More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 862 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Process Message ... | 17328688 | 432 days ago | IN | 0 ETH | 0.00811935 | ||||
Process Message ... | 17133715 | 460 days ago | IN | 0 ETH | 0.00856571 | ||||
Process Message ... | 17133456 | 460 days ago | IN | 0 ETH | 0.0083235 | ||||
Process Message ... | 17133425 | 460 days ago | IN | 0 ETH | 0.00771828 | ||||
Process Message ... | 17130162 | 460 days ago | IN | 0 ETH | 0.00868952 | ||||
Process Message ... | 17129860 | 460 days ago | IN | 0 ETH | 0.0078927 | ||||
Process Message ... | 17129606 | 460 days ago | IN | 0 ETH | 0.0085613 | ||||
Process Message ... | 17129598 | 460 days ago | IN | 0 ETH | 0.00816467 | ||||
Process Message ... | 17129280 | 460 days ago | IN | 0 ETH | 0.00747681 | ||||
Process Message ... | 17129272 | 460 days ago | IN | 0 ETH | 0.00838766 | ||||
Process Message ... | 17128981 | 461 days ago | IN | 0 ETH | 0.00853192 | ||||
Process Message ... | 17128685 | 461 days ago | IN | 0 ETH | 0.00994511 | ||||
Process Message ... | 17128676 | 461 days ago | IN | 0 ETH | 0.0079594 | ||||
Process Message ... | 17083582 | 467 days ago | IN | 0 ETH | 0.01211276 | ||||
Set Max Submissi... | 16805050 | 506 days ago | IN | 0 ETH | 0.00178875 | ||||
Set Max Gas Cap | 16805049 | 506 days ago | IN | 0 ETH | 0.00175863 | ||||
Set Gas Price Ca... | 16805049 | 506 days ago | IN | 0 ETH | 0.00188344 | ||||
Process Message ... | 16775613 | 510 days ago | IN | 0 ETH | 0.00496932 | ||||
Process Message ... | 16771439 | 511 days ago | IN | 0 ETH | 0.00888148 | ||||
Process Message ... | 16766401 | 512 days ago | IN | 0 ETH | 0.01066352 | ||||
Process Message ... | 16677974 | 524 days ago | IN | 0 ETH | 0.00893091 | ||||
Process Message ... | 16677095 | 524 days ago | IN | 0 ETH | 0.00734081 | ||||
Process Message ... | 16677079 | 524 days ago | IN | 0 ETH | 0.00592017 | ||||
Propose New Owne... | 16672914 | 525 days ago | IN | 0 ETH | 0.00206203 | ||||
Process Message ... | 16645533 | 529 days ago | IN | 0 ETH | 0.00616337 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
18812582 | 224 days ago | 0.00322669 ETH | ||||
18812582 | 224 days ago | 0.00322669 ETH | ||||
18811987 | 224 days ago | 0.00355875 ETH | ||||
18811987 | 224 days ago | 0.00355875 ETH | ||||
18811419 | 225 days ago | 0.00267118 ETH | ||||
18811419 | 225 days ago | 0.00267118 ETH | ||||
18810802 | 225 days ago | 0.00267281 ETH | ||||
18810802 | 225 days ago | 0.00267281 ETH | ||||
18810206 | 225 days ago | 0.00464074 ETH | ||||
18810206 | 225 days ago | 0.00464074 ETH | ||||
18809611 | 225 days ago | 0.00272327 ETH | ||||
18809611 | 225 days ago | 0.00272327 ETH | ||||
18809013 | 225 days ago | 0.00286601 ETH | ||||
18809013 | 225 days ago | 0.00286601 ETH | ||||
18806045 | 225 days ago | 0.00367476 ETH | ||||
18806045 | 225 days ago | 0.00367476 ETH | ||||
18805449 | 225 days ago | 0.00363805 ETH | ||||
18805449 | 225 days ago | 0.00363805 ETH | ||||
18804857 | 225 days ago | 0.00254293 ETH | ||||
18804857 | 225 days ago | 0.00254293 ETH | ||||
18804270 | 226 days ago | 0.00269298 ETH | ||||
18804270 | 226 days ago | 0.00269298 ETH | ||||
18803677 | 226 days ago | 0.00252537 ETH | ||||
18803677 | 226 days ago | 0.00252537 ETH | ||||
18803081 | 226 days ago | 0.00298892 ETH |
Loading...
Loading
Contract Name:
ArbitrumHubConnector
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; import {LibArbitrumL1} from "@openzeppelin/contracts/crosschain/arbitrum/LibArbitrumL1.sol"; import {TypedMemView} from "../../../shared/libraries/TypedMemView.sol"; import {IRootManager} from "../../interfaces/IRootManager.sol"; import {IArbitrumInbox} from "../../interfaces/ambs/arbitrum/IArbitrumInbox.sol"; import {IArbitrumOutbox} from "../../interfaces/ambs/arbitrum/IArbitrumOutbox.sol"; import {IArbitrumRollup, Node} from "../../interfaces/ambs/arbitrum/IArbitrumRollup.sol"; import {HubConnector} from "../HubConnector.sol"; import {Connector} from "../Connector.sol"; struct L2Message { address l2Sender; address to; uint256 l2Block; uint256 l1Block; uint256 l2Timestamp; uint256 value; bytes callData; } contract ArbitrumHubConnector is HubConnector { // ============ Libraries ============ using TypedMemView for bytes; using TypedMemView for bytes29; // ============ Storage ============ IArbitrumOutbox public outbox; IArbitrumRollup public rollup; /** * @notice Sets cap on maxSubmissionCost used in `createRetryableTicket` * @dev The value used in `createRetryableTicket` is the lesser of the cap or * a value passed in via `_encodedData` in `_sendMessage`. * * This value represents amount of ETH allocated to pay for the base submission fee */ uint256 public maxSubmissionCostCap; /** * @notice Sets cap on maxGas used in `createRetryableTicket` * @dev The value used in `createRetryableTicket` is the lesser of the cap or * a value passed in via `_encodedData` in `_sendMessage`. * * This value represents gas limit for immediate L2 execution attempt */ uint256 public maxGasCap; /** * @notice Sets cap on gasPrice used in `createRetryableTicket` * @dev The value used in `createRetryableTicket` is the lesser of the cap or * a value passed in via `_encodedData` in `_sendMessage`. * * This value represents L2 gas price bid for immediate L2 execution attempt */ uint256 public gasPriceCap; /** * @notice Tracks which messages have been processed from bridge */ mapping(uint256 => bool) public processed; // ============ Events ============ // TODO: do we need any other information from the ticket to link to message? event RetryableTicketCreated(uint256 indexed ticketId); /** * @notice Emitted when admin updates the maxSubmissionCap * @param _previous The starting value * @param _updated The final value */ event MaxSubmissionCapUpdated(uint256 _previous, uint256 _updated); /** * @notice Emitted when admin updates the maxGasCap * @param _previous The starting value * @param _updated The final value */ event MaxGasCapUpdated(uint256 _previous, uint256 _updated); /** * @notice Emitted when admin updates the gasPriceCap * @param _previous The starting value * @param _updated The final value */ event GasPriceCapUpdated(uint256 _previous, uint256 _updated); // ============ Constructor ============ constructor( uint32 _domain, uint32 _mirrorDomain, address _amb, address _rootManager, address _mirrorConnector, address _outbox, uint256 _maxSubmissionCostCap, uint256 _maxGasCap, uint256 _gasPriceCap ) HubConnector(_domain, _mirrorDomain, _amb, _rootManager, _mirrorConnector) { outbox = IArbitrumOutbox(_outbox); rollup = IArbitrumRollup(outbox.rollup()); // Set initial caps for L1 -> L2 messages maxSubmissionCostCap = _maxSubmissionCostCap; maxGasCap = _maxGasCap; gasPriceCap = _gasPriceCap; } // ============ Admin fns ============ /** * @notice Used (by admin) to update the maxSubmissionCostCap * @param _updated The new value */ function setMaxSubmissionCostCap(uint256 _updated) public onlyOwner { emit MaxSubmissionCapUpdated(maxSubmissionCostCap, _updated); maxSubmissionCostCap = _updated; } /** * @notice Used (by admin) to update the maxGasCap * @param _updated The new value */ function setMaxGasCap(uint256 _updated) public onlyOwner { emit MaxGasCapUpdated(maxGasCap, _updated); maxGasCap = _updated; } /** * @notice Used (by admin) to update the gasPriceCap * @param _updated The new value */ function setGasPriceCap(uint256 _updated) public onlyOwner { emit GasPriceCapUpdated(maxSubmissionCostCap, _updated); gasPriceCap = _updated; } // ============ Private fns ============ function _verifySender(address _expected) internal view override returns (bool) { return _expected == LibArbitrumL1.crossChainSender(AMB); } /** * @notice Helper to return the lesser of two values * @param _a Some number * @param _b Some number */ function _lesserOf(uint256 _a, uint256 _b) internal pure returns (uint256) { return _a < _b ? _a : _b; } function _sendMessage(bytes memory _data, bytes memory _encodedData) internal override { // Should always be dispatching the aggregate root require(_data.length == 32, "!length"); // Get the calldata bytes memory _calldata = abi.encodeWithSelector(Connector.processMessage.selector, _data); // Should include specialized calldata require(_encodedData.length == (32 * 3), "!data length"); // Decode all of the gas-related parameters (uint256 maxSubmissionCost, uint256 maxGas, uint256 gasPrice) = abi.decode( _encodedData, (uint256, uint256, uint256) ); // dispatch to l2 uint256 ticketID = IArbitrumInbox(AMB).createRetryableTicket{value: msg.value}( mirrorConnector, // destAddr 0, // arbTxCallValue _lesserOf(maxSubmissionCost, maxSubmissionCostCap), // maxSubmissionCost: Amount of ETH allocated to pay for the base submission fee mirrorConnector, // submissionRefundAddress: Address to which all excess gas is credited on L2 mirrorConnector, // valueRefundAddress: Address to which CallValue will be credited to on L2 if the retryable ticket times out or is cancelled _lesserOf(maxGas, maxGasCap), // maxGas: Gas limit for immediate L2 execution attempt _lesserOf(gasPrice, gasPriceCap), // gasPriceBid: L2 Gas price bid for immediate L2 execution attempt _calldata // data ); emit RetryableTicketCreated(ticketID); } // DO NOT override _processMessage, should revert from `Connector` class. All messages must use the // `processMessageFromRoot` flow. function processMessageFromRoot( uint64 _nodeNum, bytes32 _sendRoot, bytes32 _blockHash, bytes32[] calldata _proof, uint256 _index, L2Message calldata _message ) external { // Ensure the send root corresponds to an arbitrum node that exists onchain _validateSendRoot(_nodeNum, _sendRoot, _blockHash); // Ensure the given l2 message is included in the send root _validateMessage(_sendRoot, _proof, _index, _message); // Message has been proven within the send root, process the message // data itself. The message data is defined in the spoke connector as: // // `abi.encodeWithSelector(Connector.processMessage.selector, _data);` // // so to get the root data, we need to decode the _calldata. we can do this // by dropping the 4-byte selector, then using the rest as the raw _data. require(_message.callData.length == 100, "!length"); // NOTE: TypedMemView only loads 32-byte chunks onto stack, which is fine in this case // the calldata is 100 bytes long, the last 32 bytes represent the root to be aggregated. bytes32 _data = _message.callData.ref(0).index(68, 32); // Update root manager IRootManager(ROOT_MANAGER).aggregate(MIRROR_DOMAIN, _data); // Emit event emit MessageProcessed(abi.encode(_data), msg.sender); } function _validateSendRoot( uint64 _nodeNum, bytes32 _sendRoot, bytes32 _blockHash ) internal view { // Get the confirm data to ensure the node has been put on L1 with // the given block hash and send root bytes32 confirmData = _confirmHash(_blockHash, _sendRoot); // Validate inputs by checking against the stored none confirm data Node memory node = rollup.getNode(_nodeNum); require(node.confirmData == confirmData, "!confirmData"); // Validate the node is staked / not in dispute // NOTE: a dispute can happen at any point within the timeout window, so the closest // we can get is to ensure the staker count > 0 and that there have been stakes on child // nodes as well, meaning the node is less likely to be staked incorrectly (and thus less // likely to be disputed) require(node.stakerCount > 0 && node.childStakerCount > 0, "!staked"); } // prove the message was included in the given send root function _validateMessage( bytes32 _sendRoot, bytes32[] calldata _proof, uint256 _index, L2Message calldata _msg ) internal { // Check that the l2sender is the mirror connector require(_msg.l2Sender == mirrorConnector, "!mirrorConnector"); // Generate the message sent through from L2 (included in sendRoot) bytes32 userTx = outbox.calculateItemHash( _msg.l2Sender, _msg.to, _msg.l2Block, _msg.l1Block, _msg.l2Timestamp, _msg.value, _msg.callData ); // Prove message is included in the send root _recordOutputAsSpent(_proof, _index, userTx, _sendRoot); } // taken from: https://github.com/OffchainLabs/nitro/blob/208d9d50f250e9b4948f867d3795548256583b17/contracts/src/rollup/RollupLib.sol#L128-L130 function _confirmHash(bytes32 _blockHash, bytes32 _sendRoot) internal pure returns (bytes32) { return keccak256(abi.encodePacked(_blockHash, _sendRoot)); } // modified from: https://github.com/OffchainLabs/nitro/blob/fbaa96d6d6246b427629be176499e1d5c5013d89/contracts/src/bridge/Outbox.sol#L219-L235 function _recordOutputAsSpent( bytes32[] memory _proof, uint256 _index, bytes32 _item, bytes32 _sendRoot ) internal { require(_proof.length < 256, "proof length"); require((_index >> _proof.length) == 0, "!minimal proof"); // NOTE: in the arbitrum contracts, they check that the message index is not yet spent // Because the spoke connector calls `processMessage`, which does nothing, it is important // to check out own internal mapping to ensure the message is not played twice. this forces // all messages from l2 to be processed using the `processMessageFromRoot` fn path. require(!processed[_index], "spent"); // Calculate the root bytes32 calcRoot = outbox.calculateMerkleRoot(_proof, _index, _item); // Assert the sendRoot is correct // NOTE: this send root will *not* yet be stored on the `Outbox` // contract (fraud period has not yet elapsed); require(calcRoot == _sendRoot, "!proof"); // Mark as spent processed[_index] = true; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (crosschain/arbitrum/LibArbitrumL1.sol) pragma solidity ^0.8.4; import {IBridge as ArbitrumL1_Bridge} from "../../vendor/arbitrum/IBridge.sol"; import {IOutbox as ArbitrumL1_Outbox} from "../../vendor/arbitrum/IOutbox.sol"; import "../errors.sol"; /** * @dev Primitives for cross-chain aware contracts for * https://arbitrum.io/[Arbitrum]. * * 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (crosschain/errors.sol) pragma solidity ^0.8.4; error NotCrossChainCall(); error InvalidCrossChainSender(address actual, address expected);
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // OpenZeppelin Contracts (last updated v4.8.0) (vendor/arbitrum/IBridge.sol) // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; interface IBridge { event MessageDelivered( uint256 indexed messageIndex, bytes32 indexed beforeInboxAcc, address inbox, uint8 kind, address sender, bytes32 messageDataHash, uint256 baseFeeL1, uint64 timestamp ); event BridgeCallTriggered(address indexed outbox, address indexed to, uint256 value, bytes data); event InboxToggle(address indexed inbox, bool enabled); event OutboxToggle(address indexed outbox, bool enabled); event SequencerInboxUpdated(address newSequencerInbox); function allowedDelayedInboxList(uint256) external returns (address); function allowedOutboxList(uint256) external returns (address); /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function delayedInboxAccs(uint256) external view returns (bytes32); /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function sequencerInboxAccs(uint256) external view returns (bytes32); // OpenZeppelin: changed return type from IOwnable function rollup() external view returns (address); function sequencerInbox() external view returns (address); function activeOutbox() external view returns (address); function allowedDelayedInboxes(address inbox) external view returns (bool); function allowedOutboxes(address outbox) external view returns (bool); function sequencerReportedSubMessageCount() external view returns (uint256); /** * @dev Enqueue a message in the delayed inbox accumulator. * These messages are later sequenced in the SequencerInbox, either * by the sequencer as part of a normal batch, or by force inclusion. */ function enqueueDelayedMessage( uint8 kind, address sender, bytes32 messageDataHash ) external payable returns (uint256); function executeCall( address to, uint256 value, bytes calldata data ) external returns (bool success, bytes memory returnData); function delayedMessageCount() external view returns (uint256); function sequencerMessageCount() external view returns (uint256); // ---------- onlySequencerInbox functions ---------- function enqueueSequencerMessage( bytes32 dataHash, uint256 afterDelayedMessagesRead, uint256 prevMessageCount, uint256 newMessageCount ) external returns ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc ); /** * @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type * This is done through a separate function entrypoint instead of allowing the sequencer inbox * to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either * every delayed inbox or every sequencer inbox call. */ function submitBatchSpendingReport(address batchPoster, bytes32 dataHash) external returns (uint256 msgNum); // ---------- onlyRollupOrOwner functions ---------- function setSequencerInbox(address _sequencerInbox) external; function setDelayedInbox(address inbox, bool enabled) external; function setOutbox(address inbox, bool enabled) external; // ---------- initializer ---------- // OpenZeppelin: changed rollup_ type from IOwnable function initialize(address rollup_) external; }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // OpenZeppelin Contracts (last updated v4.8.0) (vendor/arbitrum/IOutbox.sol) // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IBridge.sol"; interface IOutbox { event SendRootUpdated(bytes32 indexed blockHash, bytes32 indexed outputRoot); event OutBoxTransactionExecuted( address indexed to, address indexed l2Sender, uint256 indexed zero, uint256 transactionIndex ); function rollup() external view returns (address); // the rollup contract function bridge() external view returns (IBridge); // the bridge contract function spent(uint256) external view returns (bytes32); // packed spent bitmap function roots(bytes32) external view returns (bytes32); // maps root hashes => L2 block hash // solhint-disable-next-line func-name-mixedcase function OUTBOX_VERSION() external view returns (uint128); // the outbox version function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external; /// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account /// When the return value is zero, that means this is a system message /// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies function l2ToL1Sender() external view returns (address); /// @return l2Block return L2 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1Block() external view returns (uint256); /// @return l1Block return L1 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1EthBlock() external view returns (uint256); /// @return timestamp return L2 timestamp when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1Timestamp() external view returns (uint256); /// @return outputId returns the unique output identifier of the L2 to L1 tx or 0 if no L2 to L1 transaction is active function l2ToL1OutputId() external view returns (bytes32); /** * @notice Executes a messages in an Outbox entry. * @dev Reverts if dispute period hasn't expired, since the outbox entry * is only created once the rollup confirms the respective assertion. * @dev it is not possible to execute any L2-to-L1 transaction which contains data * to a contract address without any code (as enforced by the Bridge contract). * @param proof Merkle proof of message inclusion in send root * @param index Merkle path to message * @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1) * @param to destination address for L1 contract call * @param l2Block l2 block number at which sendTxToL1 call was made * @param l1Block l1 block number at which sendTxToL1 call was made * @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made * @param value wei in L1 message * @param data abi-encoded L1 message data */ function executeTransaction( bytes32[] calldata proof, uint256 index, address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external; /** * @dev function used to simulate the result of a particular function call from the outbox * it is useful for things such as gas estimates. This function includes all costs except for * proof validation (which can be considered offchain as a somewhat of a fixed cost - it's * not really a fixed cost, but can be treated as so with a fixed overhead for gas estimation). * We can't include the cost of proof validation since this is intended to be used to simulate txs * that are included in yet-to-be confirmed merkle roots. The simulation entrypoint could instead pretend * to confirm a pending merkle root, but that would be less practical for integrating with tooling. * It is only possible to trigger it when the msg sender is address zero, which should be impossible * unless under simulation in an eth_call or eth_estimateGas */ function executeTransactionSimulation( uint256 index, address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external; /** * @param index Merkle path to message * @return true if the message has been spent */ function isSpent(uint256 index) external view returns (bool); function calculateItemHash( address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external pure returns (bytes32); function calculateMerkleRoot( bytes32[] memory proof, uint256 path, bytes32 item ) external pure returns (bytes32); }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; import {ProposedOwnable} from "../../shared/ProposedOwnable.sol"; import {IConnector} from "../interfaces/IConnector.sol"; /** * @title Connector * @author Connext Labs, Inc. * @notice This contract has the messaging interface functions used by all connectors. * * @dev This contract stores information about mirror connectors, but can be used as a * base for contracts that do not have a mirror (i.e. the connector handling messaging on * mainnet). In this case, the `mirrorConnector` and `MIRROR_DOMAIN` * will be empty * * @dev If ownership is renounced, this contract will be unable to update its `mirrorConnector` * or `mirrorGas` */ abstract contract Connector is ProposedOwnable, IConnector { // ========== Custom Errors =========== error Connector__processMessage_notUsed(); // ============ Events ============ event NewConnector( uint32 indexed domain, uint32 indexed mirrorDomain, address amb, address rootManager, address mirrorConnector ); event MirrorConnectorUpdated(address previous, address current); // ============ Public Storage ============ /** * @notice The domain of this Messaging (i.e. Connector) contract. */ uint32 public immutable DOMAIN; /** * @notice Address of the AMB on this domain. */ address public immutable AMB; /** * @notice RootManager contract address. */ address public immutable ROOT_MANAGER; /** * @notice The domain of the corresponding messaging (i.e. Connector) contract. */ uint32 public immutable MIRROR_DOMAIN; /** * @notice Connector on L2 for L1 connectors, and vice versa. */ address public mirrorConnector; // ============ Modifiers ============ /** * @notice Errors if the msg.sender is not the registered AMB */ modifier onlyAMB() { require(msg.sender == AMB, "!AMB"); _; } /** * @notice Errors if the msg.sender is not the registered ROOT_MANAGER */ modifier onlyRootManager() { // NOTE: RootManager will be zero address for spoke connectors. // Only root manager can dispatch a message to spokes/L2s via the hub connector. require(msg.sender == ROOT_MANAGER, "!rootManager"); _; } // ============ Constructor ============ /** * @notice Creates a new HubConnector instance * @dev The connectors are deployed such that there is one on each side of an AMB (i.e. * for optimism, there is one connector on optimism and one connector on mainnet) * @param _domain The domain this connector lives on * @param _mirrorDomain The spoke domain * @param _amb The address of the amb on the domain this connector lives on * @param _rootManager The address of the RootManager on mainnet * @param _mirrorConnector The address of the spoke connector */ constructor( uint32 _domain, uint32 _mirrorDomain, address _amb, address _rootManager, address _mirrorConnector ) ProposedOwnable() { // set the owner _setOwner(msg.sender); // sanity checks on values require(_domain != 0, "empty domain"); require(_rootManager != address(0), "empty rootManager"); // see note at top of contract on why the mirror values are not sanity checked // set immutables DOMAIN = _domain; AMB = _amb; ROOT_MANAGER = _rootManager; MIRROR_DOMAIN = _mirrorDomain; // set mutables if defined if (_mirrorConnector != address(0)) { _setMirrorConnector(_mirrorConnector); } emit NewConnector(_domain, _mirrorDomain, _amb, _rootManager, _mirrorConnector); } // ============ Receivable ============ /** * @notice Connectors may need to receive native asset to handle fees when sending a * message */ receive() external payable {} // ============ Admin Functions ============ /** * @notice Sets the address of the l2Connector for this domain */ function setMirrorConnector(address _mirrorConnector) public onlyOwner { _setMirrorConnector(_mirrorConnector); } // ============ Public Functions ============ /** * @notice Processes a message received by an AMB * @dev This is called by AMBs to process messages originating from mirror connector */ function processMessage(bytes memory _data) external virtual onlyAMB { _processMessage(_data); emit MessageProcessed(_data, msg.sender); } /** * @notice Checks the cross domain sender for a given address */ function verifySender(address _expected) external returns (bool) { return _verifySender(_expected); } // ============ Virtual Functions ============ /** * @notice This function is used by the Connext contract on the l2 domain to send a message to the * l1 domain (i.e. called by Connext on optimism to send a message to mainnet with roots) * @param _data The contents of the message * @param _encodedData Data used to send the message; specific to connector */ function _sendMessage(bytes memory _data, bytes memory _encodedData) internal virtual; /** * @notice This function is used by the AMBs to handle incoming messages. Should store the latest * root generated on the l2 domain. */ function _processMessage( bytes memory /* _data */ ) internal virtual { // By default, reverts. This is to ensure the call path is not used unless this function is // overridden by the inheriting class revert Connector__processMessage_notUsed(); } /** * @notice Verify that the msg.sender is the correct AMB contract, and that the message's origin sender * is the expected address. * @dev Should be overridden by the implementing Connector contract. */ function _verifySender(address _expected) internal virtual returns (bool); // ============ Private Functions ============ function _setMirrorConnector(address _mirrorConnector) internal virtual { emit MirrorConnectorUpdated(mirrorConnector, _mirrorConnector); mirrorConnector = _mirrorConnector; } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; import {Connector} from "./Connector.sol"; /** * @title HubConnector * @author Connext Labs, Inc. * @notice This contract implements the messaging functions needed on the hub-side of a given AMB. * The HubConnector has a limited set of functionality compared to the SpokeConnector, namely that * it contains no logic to store or prove messages. * * @dev This contract should be deployed on the hub-side of an AMB (i.e. on L1), and contracts * which extend this should implement the virtual functions defined in the BaseConnector class */ abstract contract HubConnector is Connector { /** * @notice Creates a new HubConnector instance * @dev The connectors are deployed such that there is one on each side of an AMB (i.e. * for optimism, there is one connector on optimism and one connector on mainnet) * @param _domain The domain this connector lives on * @param _mirrorDomain The spoke domain * @param _amb The address of the amb on the domain this connector lives on * @param _rootManager The address of the RootManager on mainnet * @param _mirrorConnector The address of the spoke connector */ constructor( uint32 _domain, uint32 _mirrorDomain, address _amb, address _rootManager, address _mirrorConnector ) Connector(_domain, _mirrorDomain, _amb, _rootManager, _mirrorConnector) {} // ============ Public fns ============ /** * @notice Sends a message over the amb * @dev This is called by the root manager *only* on mainnet to propagate the aggregate root */ function sendMessage(bytes memory _data, bytes memory _encodedData) external payable onlyRootManager { _sendMessage(_data, _encodedData); emit MessageSent(_data, _encodedData, msg.sender); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; import {IProposedOwnable} from "../../shared/interfaces/IProposedOwnable.sol"; /** * @notice This interface is what the Connext contract will send and receive messages through. * The messaging layer should conform to this interface, and should be interchangeable (i.e. * could be Nomad or a generic AMB under the hood). * * @dev This uses the nomad format to ensure nomad can be added in as it comes back online. * * Flow from transfer from polygon to optimism: * 1. User calls `xcall` with destination specified * 2. This will swap in to the bridge assets * 3. The swapped assets will get burned * 4. The Connext contract will call `dispatch` on the messaging contract to add the transfer * to the root * 5. [At some time interval] Relayers call `send` to send the current root from polygon to * mainnet. This is done on all "spoke" domains. * 6. [At some time interval] Relayers call `propagate` [better name] on mainnet, this generates a new merkle * root from all of the AMBs * - This function must be able to read root data from all AMBs and aggregate them into a single merkle * tree root * - Will send the mixed root from all chains back through the respective AMBs to all other chains * 7. AMB will call `update` to update the latest root on the messaging contract on spoke domains * 8. [At any point] Relayers can call `proveAndProcess` to prove inclusion of dispatched message, and call * process on the `Connext` contract * 9. Takes minted bridge tokens and credits the LP * * AMB requirements: * - Access `msg.sender` both from mainnet -> spoke and vice versa * - Ability to read *our root* from the AMB * * AMBs: * - PoS bridge from polygon * - arbitrum bridge * - optimism bridge * - gnosis chain * - bsc (use multichain for messaging) */ interface IConnector is IProposedOwnable { // ============ Events ============ /** * @notice Emitted whenever a message is successfully sent over an AMB * @param data The contents of the message * @param encodedData Data used to send the message; specific to connector * @param caller Who called the function (sent the message) */ event MessageSent(bytes data, bytes encodedData, address caller); /** * @notice Emitted whenever a message is successfully received over an AMB * @param data The contents of the message * @param caller Who called the function */ event MessageProcessed(bytes data, address caller); // ============ Public fns ============ function processMessage(bytes memory _data) external; function verifySender(address _expected) external returns (bool); }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; interface IRootManager { /** * @notice This is called by relayers to generate + send the mixed root from mainnet via AMB to * spoke domains. * @dev This must read information for the root from the registered AMBs. */ function propagate( address[] calldata _connectors, uint256[] calldata _fees, bytes[] memory _encodedData ) external payable; /** * @notice Called by the connectors for various domains on the hub to aggregate their latest * inbound root. * @dev This must read information for the root from the registered AMBs */ function aggregate(uint32 _domain, bytes32 _outbound) external; }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; /** * @notice Interface for sending L1 -> L2 messagesto Arbitrum. * @dev Arbitrum uses an inbox to aggregate messages going from L1 -> L2, source: * https://github.com/OffchainLabs/nitro/blob/master/contracts/src/bridge/Inbox.sol * */ interface IArbitrumInbox { function createRetryableTicket( address destAddr, uint256 arbTxCallValue, uint256 maxSubmissionCost, address submissionRefundAddress, address valueRefundAddress, uint256 maxGas, uint256 gasPriceBid, bytes calldata data ) external payable returns (uint256); }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; /** * @notice Interface for sending L1 -> L2 messagesto Arbitrum. * @dev Arbitrum uses an inbox to aggregate messages going from L1 -> L2, source: * https://github.com/OffchainLabs/nitro/blob/master/contracts/src/bridge/Inbox.sol * */ interface IArbitrumOutbox { event SendRootUpdated(bytes32 indexed blockHash, bytes32 indexed outputRoot); event OutBoxTransactionExecuted( address indexed to, address indexed l2Sender, uint256 indexed zero, uint256 transactionIndex ); function rollup() external view returns (address); // the rollup contract // function bridge() external view returns (IBridge); // the bridge contract function spent(uint256) external view returns (bytes32); // packed spent bitmap function roots(bytes32) external view returns (bytes32); // maps root hashes => L2 block hash // solhint-disable-next-line func-name-mixedcase function OUTBOX_VERSION() external view returns (uint128); // the outbox version function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external; /// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account /// When the return value is zero, that means this is a system message /// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies function l2ToL1Sender() external view returns (address); /// @return l2Block return L2 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1Block() external view returns (uint256); /// @return l1Block return L1 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1EthBlock() external view returns (uint256); /// @return timestamp return L2 timestamp when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1Timestamp() external view returns (uint256); /// @return outputId returns the unique output identifier of the L2 to L1 tx or 0 if no L2 to L1 transaction is active function l2ToL1OutputId() external view returns (bytes32); /** * @notice Executes a messages in an Outbox entry. * @dev Reverts if dispute period hasn't expired, since the outbox entry * is only created once the rollup confirms the respective assertion. * @dev it is not possible to execute any L2-to-L1 transaction which contains data * to a contract address without any code (as enforced by the Bridge contract). * @param proof Merkle proof of message inclusion in send root * @param index Merkle path to message * @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1) * @param to destination address for L1 contract call * @param l2Block l2 block number at which sendTxToL1 call was made * @param l1Block l1 block number at which sendTxToL1 call was made * @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made * @param value wei in L1 message * @param data abi-encoded L1 message data */ function executeTransaction( bytes32[] calldata proof, uint256 index, address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external; /** * @dev function used to simulate the result of a particular function call from the outbox * it is useful for things such as gas estimates. This function includes all costs except for * proof validation (which can be considered offchain as a somewhat of a fixed cost - it's * not really a fixed cost, but can be treated as so with a fixed overhead for gas estimation). * We can't include the cost of proof validation since this is intended to be used to simulate txs * that are included in yet-to-be confirmed merkle roots. The simulation entrypoint could instead pretend * to confirm a pending merkle root, but that would be less pratical for integrating with tooling. * It is only possible to trigger it when the msg sender is address zero, which should be impossible * unless under simulation in an eth_call or eth_estimateGas */ function executeTransactionSimulation( uint256 index, address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external; /** * @param index Merkle path to message * @return true if the message has been spent */ function isSpent(uint256 index) external view returns (bool); function calculateItemHash( address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external pure returns (bytes32); function calculateMerkleRoot( bytes32[] memory proof, uint256 path, bytes32 item ) external pure returns (bytes32); }
pragma solidity 0.8.17; // modified from: https://github.com/OffchainLabs/nitro/blob/master/contracts/src/rollup/Node.sol struct Node { // Hash of the state of the chain as of this node bytes32 stateHash; // Hash of the data that can be challenged bytes32 challengeHash; // Hash of the data that will be committed if this node is confirmed bytes32 confirmData; // Index of the node previous to this one uint64 prevNum; // Deadline at which this node can be confirmed uint64 deadlineBlock; // Deadline at which a child of this node can be confirmed uint64 noChildConfirmedBeforeBlock; // Number of stakers staked on this node. This includes real stakers and zombies uint64 stakerCount; // Number of stakers staked on a child node. This includes real stakers and zombies uint64 childStakerCount; // This value starts at zero and is set to a value when the first child is created. After that it is constant until the node is destroyed or the owner destroys pending nodes uint64 firstChildBlock; // The number of the latest child of this node to be created uint64 latestChildNumber; // The block number when this node was created uint64 createdAtBlock; // A hash of all the data needed to determine this node's validity, to protect against reorgs bytes32 nodeHash; } // modified from: https://github.com/OffchainLabs/nitro/blob/master/contracts/src/rollup/IRollupCore.sol interface IArbitrumRollup { /** * @notice Get the Node for the given index. */ function getNode(uint64 nodeNum) external view returns (Node memory); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.17; import {IProposedOwnable} from "./interfaces/IProposedOwnable.sol"; /** * @title ProposedOwnable * @notice Contract module which provides a basic access control mechanism, * where there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed via a two step process: * 1. Call `proposeOwner` * 2. Wait out the delay period * 3. Call `acceptOwner` * * @dev This module is used through inheritance. It will make available the * modifier `onlyOwner`, which can be applied to your functions to restrict * their use to the owner. * * @dev The majority of this code was taken from the openzeppelin Ownable * contract * */ abstract contract ProposedOwnable is IProposedOwnable { // ========== Custom Errors =========== error ProposedOwnable__onlyOwner_notOwner(); error ProposedOwnable__onlyProposed_notProposedOwner(); error ProposedOwnable__ownershipDelayElapsed_delayNotElapsed(); error ProposedOwnable__proposeNewOwner_invalidProposal(); error ProposedOwnable__proposeNewOwner_noOwnershipChange(); error ProposedOwnable__renounceOwnership_noProposal(); error ProposedOwnable__renounceOwnership_invalidProposal(); // ============ Properties ============ address private _owner; address private _proposed; uint256 private _proposedOwnershipTimestamp; uint256 private constant _delay = 7 days; // ======== Getters ========= /** * @notice Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @notice Returns the address of the proposed owner. */ function proposed() public view virtual returns (address) { return _proposed; } /** * @notice Returns the address of the proposed owner. */ function proposedTimestamp() public view virtual returns (uint256) { return _proposedOwnershipTimestamp; } /** * @notice Returns the delay period before a new owner can be accepted. */ function delay() public view virtual returns (uint256) { return _delay; } /** * @notice Throws if called by any account other than the owner. */ modifier onlyOwner() { if (_owner != msg.sender) revert ProposedOwnable__onlyOwner_notOwner(); _; } /** * @notice Throws if called by any account other than the proposed owner. */ modifier onlyProposed() { if (_proposed != msg.sender) revert ProposedOwnable__onlyProposed_notProposedOwner(); _; } /** * @notice Throws if the ownership delay has not elapsed */ modifier ownershipDelayElapsed() { // Ensure delay has elapsed if ((block.timestamp - _proposedOwnershipTimestamp) <= _delay) revert ProposedOwnable__ownershipDelayElapsed_delayNotElapsed(); _; } /** * @notice Indicates if the ownership has been renounced() by * checking if current owner is address(0) */ function renounced() public view returns (bool) { return _owner == address(0); } // ======== External ========= /** * @notice Sets the timestamp for an owner to be proposed, and sets the * newly proposed owner as step 1 in a 2-step process */ function proposeNewOwner(address newlyProposed) public virtual onlyOwner { // Contract as source of truth if (_proposed == newlyProposed && _proposedOwnershipTimestamp != 0) revert ProposedOwnable__proposeNewOwner_invalidProposal(); // Sanity check: reasonable proposal if (_owner == newlyProposed) revert ProposedOwnable__proposeNewOwner_noOwnershipChange(); _setProposed(newlyProposed); } /** * @notice Renounces ownership of the contract after a delay */ function renounceOwnership() public virtual onlyOwner ownershipDelayElapsed { // Ensure there has been a proposal cycle started if (_proposedOwnershipTimestamp == 0) revert ProposedOwnable__renounceOwnership_noProposal(); // Require proposed is set to 0 if (_proposed != address(0)) revert ProposedOwnable__renounceOwnership_invalidProposal(); // Emit event, set new owner, reset timestamp _setOwner(address(0)); } /** * @notice Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function acceptProposedOwner() public virtual onlyProposed ownershipDelayElapsed { // NOTE: no need to check if _owner == _proposed, because the _proposed // is 0-d out and this check is implicitly enforced by modifier // NOTE: no need to check if _proposedOwnershipTimestamp > 0 because // the only time this would happen is if the _proposed was never // set (will fail from modifier) or if the owner == _proposed (checked // above) // Emit event, set new owner, reset timestamp _setOwner(_proposed); } // ======== Internal ========= function _setOwner(address newOwner) internal { emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; delete _proposedOwnershipTimestamp; delete _proposed; } function _setProposed(address newlyProposed) private { _proposedOwnershipTimestamp = block.timestamp; _proposed = newlyProposed; emit OwnershipProposed(newlyProposed); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /** * @title IProposedOwnable * @notice Defines a minimal interface for ownership with a two step proposal and acceptance * process */ interface IProposedOwnable { /** * @dev This emits when change in ownership of a contract is proposed. */ event OwnershipProposed(address indexed proposedOwner); /** * @dev This emits when ownership of a contract changes. */ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @notice Get the address of the owner * @return owner_ The address of the owner. */ function owner() external view returns (address owner_); /** * @notice Get the address of the proposed owner * @return proposed_ The address of the proposed. */ function proposed() external view returns (address proposed_); /** * @notice Set the address of the proposed owner of the contract * @param newlyProposed The proposed new owner of the contract */ function proposeNewOwner(address newlyProposed) external; /** * @notice Set the address of the proposed owner of the contract */ function acceptProposedOwner() external; }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; library TypedMemView { // Why does this exist? // the solidity `bytes memory` type has a few weaknesses. // 1. You can't index ranges effectively // 2. You can't slice without copying // 3. The underlying data may represent any type // 4. Solidity never deallocates memory, and memory costs grow // superlinearly // By using a memory view instead of a `bytes memory` we get the following // advantages: // 1. Slices are done on the stack, by manipulating the pointer // 2. We can index arbitrary ranges and quickly convert them to stack types // 3. We can insert type info into the pointer, and typecheck at runtime // This makes `TypedMemView` a useful tool for efficient zero-copy // algorithms. // Why bytes29? // We want to avoid confusion between views, digests, and other common // types so we chose a large and uncommonly used odd number of bytes // // Note that while bytes are left-aligned in a word, integers and addresses // are right-aligned. This means when working in assembly we have to // account for the 3 unused bytes on the righthand side // // First 5 bytes are a type flag. // - ff_ffff_fffe is reserved for unknown type. // - ff_ffff_ffff is reserved for invalid types/errors. // next 12 are memory address // next 12 are len // bottom 3 bytes are empty // Assumptions: // - non-modification of memory. // - No Solidity updates // - - wrt free mem point // - - wrt bytes representation in memory // - - wrt memory addressing in general // Usage: // - create type constants // - use `assertType` for runtime type assertions // - - unfortunately we can't do this at compile time yet :( // - recommended: implement modifiers that perform type checking // - - e.g. // - - `uint40 constant MY_TYPE = 3;` // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }` // - instantiate a typed view from a bytearray using `ref` // - use `index` to inspect the contents of the view // - use `slice` to create smaller views into the same memory // - - `slice` can increase the offset // - - `slice can decrease the length` // - - must specify the output type of `slice` // - - `slice` will return a null view if you try to overrun // - - make sure to explicitly check for this with `notNull` or `assertType` // - use `equal` for typed comparisons. // The null view bytes29 public constant NULL = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff; uint256 constant TWENTY_SEVEN_BYTES = 8 * 27; uint256 private constant _27_BYTES_IN_BITS = 8 * 27; // <--- also used this named constant where ever 216 is used. uint256 private constant LOW_27_BYTES_MASK = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff; // (1 << _27_BYTES_IN_BITS) - 1; // ========== Custom Errors =========== error TypedMemView__assertType_typeAssertionFailed(uint256 actual, uint256 expected); error TypedMemView__index_overrun(uint256 loc, uint256 len, uint256 index, uint256 slice); error TypedMemView__index_indexMoreThan32Bytes(); error TypedMemView__unsafeCopyTo_nullPointer(); error TypedMemView__unsafeCopyTo_invalidPointer(); error TypedMemView__unsafeCopyTo_identityOOG(); error TypedMemView__assertValid_validityAssertionFailed(); /** * @notice Changes the endianness of a uint256. * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel * @param _b The unsigned integer to reverse * @return v - The reversed value */ function reverseUint256(uint256 _b) internal pure returns (uint256 v) { v = _b; // swap bytes v = ((v >> 8) & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) | ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8); // swap 2-byte long pairs v = ((v >> 16) & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) | ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16); // swap 4-byte long pairs v = ((v >> 32) & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) | ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32); // swap 8-byte long pairs v = ((v >> 64) & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) | ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64); // swap 16-byte long pairs v = (v >> 128) | (v << 128); } /** * @notice Create a mask with the highest `_len` bits set. * @param _len The length * @return mask - The mask */ function leftMask(uint8 _len) private pure returns (uint256 mask) { // ugly. redo without assembly? assembly { // solhint-disable-previous-line no-inline-assembly mask := sar(sub(_len, 1), 0x8000000000000000000000000000000000000000000000000000000000000000) } } /** * @notice Return the null view. * @return bytes29 - The null view */ function nullView() internal pure returns (bytes29) { return NULL; } /** * @notice Check if the view is null. * @return bool - True if the view is null */ function isNull(bytes29 memView) internal pure returns (bool) { return memView == NULL; } /** * @notice Check if the view is not null. * @return bool - True if the view is not null */ function notNull(bytes29 memView) internal pure returns (bool) { return !isNull(memView); } /** * @notice Check if the view is of a invalid type and points to a valid location * in memory. * @dev We perform this check by examining solidity's unallocated memory * pointer and ensuring that the view's upper bound is less than that. * @param memView The view * @return ret - True if the view is invalid */ function isNotValid(bytes29 memView) internal pure returns (bool ret) { if (typeOf(memView) == 0xffffffffff) { return true; } uint256 _end = end(memView); assembly { // solhint-disable-previous-line no-inline-assembly ret := gt(_end, mload(0x40)) } } /** * @notice Require that a typed memory view be valid. * @dev Returns the view for easy chaining. * @param memView The view * @return bytes29 - The validated view */ function assertValid(bytes29 memView) internal pure returns (bytes29) { if (isNotValid(memView)) revert TypedMemView__assertValid_validityAssertionFailed(); return memView; } /** * @notice Return true if the memview is of the expected type. Otherwise false. * @param memView The view * @param _expected The expected type * @return bool - True if the memview is of the expected type */ function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) { return typeOf(memView) == _expected; } /** * @notice Require that a typed memory view has a specific type. * @dev Returns the view for easy chaining. * @param memView The view * @param _expected The expected type * @return bytes29 - The view with validated type */ function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) { if (!isType(memView, _expected)) { revert TypedMemView__assertType_typeAssertionFailed(uint256(typeOf(memView)), uint256(_expected)); } return memView; } /** * @notice Return an identical view with a different type. * @param memView The view * @param _newType The new type * @return newView - The new view with the specified type */ function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) { // then | in the new type assembly { // solhint-disable-previous-line no-inline-assembly // shift off the top 5 bytes newView := or(and(memView, LOW_27_BYTES_MASK), shl(_27_BYTES_IN_BITS, _newType)) } } /** * @notice Unsafe raw pointer construction. This should generally not be called * directly. Prefer `ref` wherever possible. * @dev Unsafe raw pointer construction. This should generally not be called * directly. Prefer `ref` wherever possible. * @param _type The type * @param _loc The memory address * @param _len The length * @return newView - The new view with the specified type, location and length */ function unsafeBuildUnchecked( uint256 _type, uint256 _loc, uint256 _len ) private pure returns (bytes29 newView) { uint256 _uint96Bits = 96; uint256 _emptyBits = 24; // Cast params to ensure input is of correct length uint96 len_ = uint96(_len); uint96 loc_ = uint96(_loc); require(len_ == _len && loc_ == _loc, "!truncated"); assembly { // solium-disable-previous-line security/no-inline-assembly newView := shl(_uint96Bits, _type) // insert type newView := shl(_uint96Bits, or(newView, loc_)) // insert loc newView := shl(_emptyBits, or(newView, len_)) // empty bottom 3 bytes } } /** * @notice Instantiate a new memory view. This should generally not be called * directly. Prefer `ref` wherever possible. * @dev Instantiate a new memory view. This should generally not be called * directly. Prefer `ref` wherever possible. * @param _type The type * @param _loc The memory address * @param _len The length * @return newView - The new view with the specified type, location and length */ function build( uint256 _type, uint256 _loc, uint256 _len ) internal pure returns (bytes29 newView) { uint256 _end = _loc + _len; assembly { // solhint-disable-previous-line no-inline-assembly if gt(_end, mload(0x40)) { _end := 0 } } if (_end == 0) { return NULL; } newView = unsafeBuildUnchecked(_type, _loc, _len); } /** * @notice Instantiate a memory view from a byte array. * @dev Note that due to Solidity memory representation, it is not possible to * implement a deref, as the `bytes` type stores its len in memory. * @param arr The byte array * @param newType The type * @return bytes29 - The memory view */ function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) { uint256 _len = arr.length; uint256 _loc; assembly { // solhint-disable-previous-line no-inline-assembly _loc := add(arr, 0x20) // our view is of the data, not the struct } return build(newType, _loc, _len); } /** * @notice Return the associated type information. * @param memView The memory view * @return _type - The type associated with the view */ function typeOf(bytes29 memView) internal pure returns (uint40 _type) { assembly { // solhint-disable-previous-line no-inline-assembly // 216 == 256 - 40 _type := shr(_27_BYTES_IN_BITS, memView) // shift out lower 24 bytes } } /** * @notice Return the memory address of the underlying bytes. * @param memView The view * @return _loc - The memory address */ function loc(bytes29 memView) internal pure returns (uint96 _loc) { uint256 _mask = LOW_12_MASK; // assembly can't use globals assembly { // solhint-disable-previous-line no-inline-assembly // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space) _loc := and(shr(120, memView), _mask) } } /** * @notice The number of memory words this memory view occupies, rounded up. * @param memView The view * @return uint256 - The number of memory words */ function words(bytes29 memView) internal pure returns (uint256) { return (uint256(len(memView)) + 31) / 32; } /** * @notice The in-memory footprint of a fresh copy of the view. * @param memView The view * @return uint256 - The in-memory footprint of a fresh copy of the view. */ function footprint(bytes29 memView) internal pure returns (uint256) { return words(memView) * 32; } /** * @notice The number of bytes of the view. * @param memView The view * @return _len - The length of the view */ function len(bytes29 memView) internal pure returns (uint96 _len) { uint256 _mask = LOW_12_MASK; // assembly can't use globals assembly { // solhint-disable-previous-line no-inline-assembly _len := and(shr(24, memView), _mask) } } /** * @notice Returns the endpoint of `memView`. * @param memView The view * @return uint256 - The endpoint of `memView` */ function end(bytes29 memView) internal pure returns (uint256) { unchecked { return loc(memView) + len(memView); } } /** * @notice Safe slicing without memory modification. * @param memView The view * @param _index The start index * @param _len The length * @param newType The new type * @return bytes29 - The new view */ function slice( bytes29 memView, uint256 _index, uint256 _len, uint40 newType ) internal pure returns (bytes29) { uint256 _loc = loc(memView); // Ensure it doesn't overrun the view if (_loc + _index + _len > end(memView)) { return NULL; } _loc = _loc + _index; return build(newType, _loc, _len); } /** * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes. * @param memView The view * @param _len The length * @param newType The new type * @return bytes29 - The new view */ function prefix( bytes29 memView, uint256 _len, uint40 newType ) internal pure returns (bytes29) { return slice(memView, 0, _len, newType); } /** * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte. * @param memView The view * @param _len The length * @param newType The new type * @return bytes29 - The new view */ function postfix( bytes29 memView, uint256 _len, uint40 newType ) internal pure returns (bytes29) { return slice(memView, uint256(len(memView)) - _len, _len, newType); } /** * @notice Load up to 32 bytes from the view onto the stack. * @dev Returns a bytes32 with only the `_bytes` highest bytes set. * This can be immediately cast to a smaller fixed-length byte array. * To automatically cast to an integer, use `indexUint`. * @param memView The view * @param _index The index * @param _bytes The bytes * @return result - The 32 byte result */ function index( bytes29 memView, uint256 _index, uint8 _bytes ) internal pure returns (bytes32 result) { if (_bytes == 0) { return bytes32(0); } if (_index + _bytes > len(memView)) { // "TypedMemView/index - Overran the view. Slice is at {loc} with length {len}. Attempted to index at offset {index} with length {slice}, revert TypedMemView__index_overrun(loc(memView), len(memView), _index, uint256(_bytes)); } if (_bytes > 32) revert TypedMemView__index_indexMoreThan32Bytes(); uint8 bitLength; unchecked { bitLength = _bytes * 8; } uint256 _loc = loc(memView); uint256 _mask = leftMask(bitLength); assembly { // solhint-disable-previous-line no-inline-assembly result := and(mload(add(_loc, _index)), _mask) } } /** * @notice Parse an unsigned integer from the view at `_index`. * @dev Requires that the view have >= `_bytes` bytes following that index. * @param memView The view * @param _index The index * @param _bytes The bytes * @return result - The unsigned integer */ function indexUint( bytes29 memView, uint256 _index, uint8 _bytes ) internal pure returns (uint256 result) { return uint256(index(memView, _index, _bytes)) >> ((32 - _bytes) * 8); } /** * @notice Parse an unsigned integer from LE bytes. * @param memView The view * @param _index The index * @param _bytes The bytes * @return result - The unsigned integer */ function indexLEUint( bytes29 memView, uint256 _index, uint8 _bytes ) internal pure returns (uint256 result) { return reverseUint256(uint256(index(memView, _index, _bytes))); } /** * @notice Parse an address from the view at `_index`. Requires that the view have >= 20 bytes * following that index. * @param memView The view * @param _index The index * @return address - The address */ function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) { return address(uint160(indexUint(memView, _index, 20))); } /** * @notice Return the keccak256 hash of the underlying memory * @param memView The view * @return digest - The keccak256 hash of the underlying memory */ function keccak(bytes29 memView) internal pure returns (bytes32 digest) { uint256 _loc = loc(memView); uint256 _len = len(memView); assembly { // solhint-disable-previous-line no-inline-assembly digest := keccak256(_loc, _len) } } /** * @notice Return true if the underlying memory is equal. Else false. * @param left The first view * @param right The second view * @return bool - True if the underlying memory is equal */ function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) { return (loc(left) == loc(right) && len(left) == len(right)) || keccak(left) == keccak(right); } /** * @notice Return false if the underlying memory is equal. Else true. * @param left The first view * @param right The second view * @return bool - False if the underlying memory is equal */ function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) { return !untypedEqual(left, right); } /** * @notice Compares type equality. * @dev Shortcuts if the pointers are identical, otherwise compares type and digest. * @param left The first view * @param right The second view * @return bool - True if the types are the same */ function equal(bytes29 left, bytes29 right) internal pure returns (bool) { return left == right || (typeOf(left) == typeOf(right) && keccak(left) == keccak(right)); } /** * @notice Compares type inequality. * @dev Shortcuts if the pointers are identical, otherwise compares type and digest. * @param left The first view * @param right The second view * @return bool - True if the types are not the same */ function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) { return !equal(left, right); } /** * @notice Copy the view to a location, return an unsafe memory reference * @dev Super Dangerous direct memory access. * * This reference can be overwritten if anything else modifies memory (!!!). * As such it MUST be consumed IMMEDIATELY. * This function is private to prevent unsafe usage by callers. * @param memView The view * @param _newLoc The new location * @return written - the unsafe memory reference */ function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) { if (isNull(memView)) revert TypedMemView__unsafeCopyTo_nullPointer(); if (isNotValid(memView)) revert TypedMemView__unsafeCopyTo_invalidPointer(); uint256 _len = len(memView); uint256 _oldLoc = loc(memView); uint256 ptr; bool res; assembly { // solhint-disable-previous-line no-inline-assembly ptr := mload(0x40) // revert if we're writing in occupied memory if gt(ptr, _newLoc) { revert(0x60, 0x20) // empty revert message } // use the identity precompile to copy // guaranteed not to fail, so pop the success res := staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len) } if (!res) revert TypedMemView__unsafeCopyTo_identityOOG(); written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len); } /** * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to * the new memory * @dev Shortcuts if the pointers are identical, otherwise compares type and digest. * @param memView The view * @return ret - The view pointing to the new memory */ function clone(bytes29 memView) internal view returns (bytes memory ret) { uint256 ptr; uint256 _len = len(memView); assembly { // solhint-disable-previous-line no-inline-assembly ptr := mload(0x40) // load unused memory pointer ret := ptr } unchecked { unsafeCopyTo(memView, ptr + 0x20); } assembly { // solhint-disable-previous-line no-inline-assembly mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer mstore(ptr, _len) // write len of new array (in bytes) } } /** * @notice Join the views in memory, return an unsafe reference to the memory. * @dev Super Dangerous direct memory access. * * This reference can be overwritten if anything else modifies memory (!!!). * As such it MUST be consumed IMMEDIATELY. * This function is private to prevent unsafe usage by callers. * @param memViews The views * @return unsafeView - The conjoined view pointing to the new memory */ function unsafeJoin(bytes29[] memory memViews, uint256 _location) private view returns (bytes29 unsafeView) { assembly { // solhint-disable-previous-line no-inline-assembly let ptr := mload(0x40) // revert if we're writing in occupied memory if gt(ptr, _location) { revert(0x60, 0x20) // empty revert message } } uint256 _offset = 0; uint256 _len = memViews.length; for (uint256 i = 0; i < _len; ) { bytes29 memView = memViews[i]; unchecked { unsafeCopyTo(memView, _location + _offset); _offset += len(memView); ++i; } } unsafeView = unsafeBuildUnchecked(0, _location, _offset); } /** * @notice Produce the keccak256 digest of the concatenated contents of multiple views. * @param memViews The views * @return bytes32 - The keccak256 digest */ function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) { uint256 ptr; assembly { // solhint-disable-previous-line no-inline-assembly ptr := mload(0x40) // load unused memory pointer } return keccak(unsafeJoin(memViews, ptr)); } /** * @notice copies all views, joins them into a new bytearray. * @param memViews The views * @return ret - The new byte array */ function join(bytes29[] memory memViews) internal view returns (bytes memory ret) { uint256 ptr; assembly { // solhint-disable-previous-line no-inline-assembly ptr := mload(0x40) // load unused memory pointer } bytes29 _newView; unchecked { _newView = unsafeJoin(memViews, ptr + 0x20); } uint256 _written = len(_newView); uint256 _footprint = footprint(_newView); assembly { // solhint-disable-previous-line no-inline-assembly // store the legnth mstore(ptr, _written) // new pointer is old + 0x20 + the footprint of the body mstore(0x40, add(add(ptr, _footprint), 0x20)) ret := ptr } } }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"uint32","name":"_mirrorDomain","type":"uint32"},{"internalType":"address","name":"_amb","type":"address"},{"internalType":"address","name":"_rootManager","type":"address"},{"internalType":"address","name":"_mirrorConnector","type":"address"},{"internalType":"address","name":"_outbox","type":"address"},{"internalType":"uint256","name":"_maxSubmissionCostCap","type":"uint256"},{"internalType":"uint256","name":"_maxGasCap","type":"uint256"},{"internalType":"uint256","name":"_gasPriceCap","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Connector__processMessage_notUsed","type":"error"},{"inputs":[],"name":"NotCrossChainCall","type":"error"},{"inputs":[],"name":"ProposedOwnable__onlyOwner_notOwner","type":"error"},{"inputs":[],"name":"ProposedOwnable__onlyProposed_notProposedOwner","type":"error"},{"inputs":[],"name":"ProposedOwnable__ownershipDelayElapsed_delayNotElapsed","type":"error"},{"inputs":[],"name":"ProposedOwnable__proposeNewOwner_invalidProposal","type":"error"},{"inputs":[],"name":"ProposedOwnable__proposeNewOwner_noOwnershipChange","type":"error"},{"inputs":[],"name":"ProposedOwnable__renounceOwnership_invalidProposal","type":"error"},{"inputs":[],"name":"ProposedOwnable__renounceOwnership_noProposal","type":"error"},{"inputs":[],"name":"TypedMemView__index_indexMoreThan32Bytes","type":"error"},{"inputs":[{"internalType":"uint256","name":"loc","type":"uint256"},{"internalType":"uint256","name":"len","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"slice","type":"uint256"}],"name":"TypedMemView__index_overrun","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_previous","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_updated","type":"uint256"}],"name":"GasPriceCapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_previous","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_updated","type":"uint256"}],"name":"MaxGasCapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_previous","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_updated","type":"uint256"}],"name":"MaxSubmissionCapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"MessageProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"encodedData","type":"bytes"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"MessageSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previous","type":"address"},{"indexed":false,"internalType":"address","name":"current","type":"address"}],"name":"MirrorConnectorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"mirrorDomain","type":"uint32"},{"indexed":false,"internalType":"address","name":"amb","type":"address"},{"indexed":false,"internalType":"address","name":"rootManager","type":"address"},{"indexed":false,"internalType":"address","name":"mirrorConnector","type":"address"}],"name":"NewConnector","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proposedOwner","type":"address"}],"name":"OwnershipProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"ticketId","type":"uint256"}],"name":"RetryableTicketCreated","type":"event"},{"inputs":[],"name":"AMB","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIRROR_DOMAIN","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROOT_MANAGER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptProposedOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasPriceCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxGasCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSubmissionCostCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mirrorConnector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"outbox","outputs":[{"internalType":"contract IArbitrumOutbox","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"processMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_nodeNum","type":"uint64"},{"internalType":"bytes32","name":"_sendRoot","type":"bytes32"},{"internalType":"bytes32","name":"_blockHash","type":"bytes32"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"uint256","name":"_index","type":"uint256"},{"components":[{"internalType":"address","name":"l2Sender","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"l2Block","type":"uint256"},{"internalType":"uint256","name":"l1Block","type":"uint256"},{"internalType":"uint256","name":"l2Timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct L2Message","name":"_message","type":"tuple"}],"name":"processMessageFromRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"processed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newlyProposed","type":"address"}],"name":"proposeNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proposed","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposedTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounced","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rollup","outputs":[{"internalType":"contract IArbitrumRollup","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"bytes","name":"_encodedData","type":"bytes"}],"name":"sendMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_updated","type":"uint256"}],"name":"setGasPriceCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_updated","type":"uint256"}],"name":"setMaxGasCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_updated","type":"uint256"}],"name":"setMaxSubmissionCostCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mirrorConnector","type":"address"}],"name":"setMirrorConnector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_expected","type":"address"}],"name":"verifySender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101006040523480156200001257600080fd5b50604051620021f1380380620021f1833981016040819052620000359162000335565b888888888884848484846200004a3362000235565b8463ffffffff16600003620000955760405162461bcd60e51b815260206004820152600c60248201526b32b6b83a3c903237b6b0b4b760a11b60448201526064015b60405180910390fd5b6001600160a01b038216620000e15760405162461bcd60e51b815260206004820152601160248201527032b6b83a3c903937b7ba26b0b730b3b2b960791b60448201526064016200008c565b63ffffffff8086166080526001600160a01b0380851660a05283811660c05290851660e052811615620001195762000119816200029a565b604080516001600160a01b0385811682528481166020830152831681830152905163ffffffff86811692908816917f4f9c27c2fe3f84576ea469d367d044da53c45e951617e8389f2b5ed8db9d25f09181900360600190a35050600480546001600160a01b0319166001600160a01b038e1690811782556040805163cb23bcb560e01b81529051919a5063cb23bcb599508083019850602097509095508590030192508391508790505afa158015620001d6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fc9190620003d5565b600580546001600160a01b0319166001600160a01b039290921691909117905560069290925560075560085550620003fa945050505050565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316178155600255600180549091169055565b600354604080516001600160a01b03928316815291831660208301527fc77bec288fc88f168427f2f7da682eadb26cac89d8d591af6e443da98dff2bbc910160405180910390a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b805163ffffffff811681146200031857600080fd5b919050565b80516001600160a01b03811681146200031857600080fd5b60008060008060008060008060006101208a8c0312156200035557600080fd5b620003608a62000303565b98506200037060208b0162000303565b97506200038060408b016200031d565b96506200039060608b016200031d565b9550620003a060808b016200031d565b9450620003b060a08b016200031d565b935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b600060208284031215620003e857600080fd5b620003f3826200031d565b9392505050565b60805160a05160c05160e051611d936200045e60003960008181610227015261095901526000818161032e015281816105da015261098a0152600081816104eb0152818161068f01528181610cc9015261130b015260006102da0152611d936000f3fe6080604052600436106101a05760003560e01c80639ab0563b116100ec578063ce11e6ab1161008a578063d69f9d6111610064578063d69f9d61146104d9578063db1b76591461050d578063e2ce3c641461052d578063fbd4006b1461054357600080fd5b8063ce11e6ab1461047c578063d1851c921461049c578063d232c220146104ba57600080fd5b8063b64d327e116100c6578063b64d327e14610411578063c5b350df14610427578063cb23bcb51461043c578063cc3942831461045c57600080fd5b80639ab0563b146103b15780639d4373a4146103d1578063b1f8100d146103f157600080fd5b80634ff746f6116101595780635f61e3ec116101335780635f61e3ec1461031c5780636a42b8f814610368578063715018a61461037e5780638da5cb5b1461039357600080fd5b80634ff746f6146102a857806352a9674b146102c85780635bd11efc146102fc57600080fd5b806305a79e06146101ac5780630fca49cd146101f157806314168416146102155780633327998d1461025e5780633cf52ffb1461028057806348e6fa231461029557600080fd5b366101a757005b600080fd5b3480156101b857600080fd5b506101dc6101c736600461170b565b60096020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b3480156101fd57600080fd5b5061020760065481565b6040519081526020016101e8565b34801561022157600080fd5b506102497f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101e8565b34801561026a57600080fd5b5061027e61027936600461170b565b610563565b005b34801561028c57600080fd5b50600254610207565b61027e6102a33660046117f1565b6105cf565b3480156102b457600080fd5b5061027e6102c3366004611855565b610684565b3480156102d457600080fd5b506102497f000000000000000000000000000000000000000000000000000000000000000081565b34801561030857600080fd5b5061027e6103173660046118a7565b61072a565b34801561032857600080fd5b506103507f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101e8565b34801561037457600080fd5b5062093a80610207565b34801561038a57600080fd5b5061027e610761565b34801561039f57600080fd5b506000546001600160a01b0316610350565b3480156103bd57600080fd5b5061027e6103cc36600461170b565b610815565b3480156103dd57600080fd5b5061027e6103ec3660046118f2565b610881565b3480156103fd57600080fd5b5061027e61040c3660046118a7565b610a50565b34801561041d57600080fd5b5061020760075481565b34801561043357600080fd5b5061027e610aee565b34801561044857600080fd5b50600554610350906001600160a01b031681565b34801561046857600080fd5b50600354610350906001600160a01b031681565b34801561048857600080fd5b50600454610350906001600160a01b031681565b3480156104a857600080fd5b506001546001600160a01b0316610350565b3480156104c657600080fd5b506000546001600160a01b0316156101dc565b3480156104e557600080fd5b506103507f000000000000000000000000000000000000000000000000000000000000000081565b34801561051957600080fd5b506101dc6105283660046118a7565b610b5e565b34801561053957600080fd5b5061020760085481565b34801561054f57600080fd5b5061027e61055e36600461170b565b610b6f565b6000546001600160a01b0316331461058e576040516311a8a1bb60e31b815260040160405180910390fd5b60065460408051918252602082018390527f8826388bbfa56ae5df40ee5607d9d354fa66549d854624242c77b5af2a5e4c3b910160405180910390a1600655565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461063b5760405162461bcd60e51b815260206004820152600c60248201526b10b937b7ba26b0b730b3b2b960a11b60448201526064015b60405180910390fd5b6106458282610bdb565b7fdcaa37a042a0087de79018c629bbd29cee82ca80bd9be394e1696bf9e935507782823360405161067893929190611a02565b60405180910390a15050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106e55760405162461bcd60e51b81526004016106329060208082526004908201526310a0a6a160e11b604082015260600190565b6106ee81610de4565b7fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced813360405161071f929190611a40565b60405180910390a150565b6000546001600160a01b03163314610755576040516311a8a1bb60e31b815260040160405180910390fd5b61075e81610dfd565b50565b6000546001600160a01b0316331461078c576040516311a8a1bb60e31b815260040160405180910390fd5b62093a806002544261079e9190611a80565b116107bc576040516324e0285f60e21b815260040160405180910390fd5b6002546000036107df57604051630e4b303f60e21b815260040160405180910390fd5b6001546001600160a01b031615610809576040516323295ef960e01b815260040160405180910390fd5b6108136000610e66565b565b6000546001600160a01b03163314610840576040516311a8a1bb60e31b815260040160405180910390fd5b60075460408051918252602082018390527f57bffb29c4c6b672a2e334fa00ea826dba286d6cb34d61bebc6c667abb579c62910160405180910390a1600755565b61088c878787610ecb565b6108998685858585611020565b6108a660c0820182611a93565b90506064146108e15760405162461bcd60e51b8152602060048201526007602482015266042d8cadccee8d60cb1b6044820152606401610632565b600061094560446020610938846108fb60c0880188611a93565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506111839050565b62ffffff191691906111a7565b60405163473ec9fd60e11b815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690638e7d93fa90604401600060405180830381600087803b1580156109d657600080fd5b505af11580156109ea573d6000803e3d6000fd5b505050507fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced81604051602001610a2291815260200190565b60408051601f1981840301815290829052610a3e913390611a40565b60405180910390a15050505050505050565b6000546001600160a01b03163314610a7b576040516311a8a1bb60e31b815260040160405180910390fd5b6001546001600160a01b038281169116148015610a99575060025415155b15610ab7576040516311bc066560e11b815260040160405180910390fd5b6000546001600160a01b03808316911603610ae557604051634a2fb73f60e11b815260040160405180910390fd5b61075e816112b6565b6001546001600160a01b03163314610b19576040516311a7f27160e11b815260040160405180910390fd5b62093a8060025442610b2b9190611a80565b11610b49576040516324e0285f60e21b815260040160405180910390fd5b600154610813906001600160a01b0316610e66565b6000610b6982611304565b92915050565b6000546001600160a01b03163314610b9a576040516311a8a1bb60e31b815260040160405180910390fd5b60065460408051918252602082018390527f7f46895145f361561c5e9bbaf45b71269a4399dc3064511f123ebf4c6f04e357910160405180910390a1600855565b8151602014610c165760405162461bcd60e51b8152602060048201526007602482015266042d8cadccee8d60cb1b6044820152606401610632565b6000634ff746f660e01b83604051602401610c319190611ae1565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091528251909150606014610ca65760405162461bcd60e51b815260206004820152600c60248201526b042c8c2e8c240d8cadccee8d60a31b6044820152606401610632565b600080600084806020019051810190610cbf9190611af4565b92509250925060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663679b6ded34600360009054906101000a90046001600160a01b03166000610d1b8960065461134a565b6003546007546001600160a01b03909116908190610d3a908c9061134a565b610d468b60085461134a565b8e6040518a63ffffffff1660e01b8152600401610d6a989796959493929190611b22565b60206040518083038185885af1158015610d88573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610dad9190611b7d565b60405190915081907fde92b5b7839f4a2c640f5e3bbb66d415458dadc57a487b0c7fa562ed7c9c896f90600090a250505050505050565b6040516316c2fdb560e21b815260040160405180910390fd5b600354604080516001600160a01b03928316815291831660208301527fc77bec288fc88f168427f2f7da682eadb26cac89d8d591af6e443da98dff2bbc910160405180910390a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316178155600255600180549091169055565b604080516020808201849052818301859052825180830384018152606090920190925280519101206000906005546040516324b204d360e21b815267ffffffffffffffff871660048201529192506000916001600160a01b03909116906392c8134c9060240161018060405180830381865afa158015610f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f739190611ba6565b905081816040015114610fb75760405162461bcd60e51b815260206004820152600c60248201526b21636f6e6669726d4461746160a01b6044820152606401610632565b60008160c0015167ffffffffffffffff16118015610fe3575060008160e0015167ffffffffffffffff16115b6110195760405162461bcd60e51b8152602060048201526007602482015266085cdd185ad95960ca1b6044820152606401610632565b5050505050565b6003546001600160a01b031661103960208301836118a7565b6001600160a01b0316146110825760405162461bcd60e51b815260206004820152601060248201526f10b6b4b93937b921b7b73732b1ba37b960811b6044820152606401610632565b6004546000906001600160a01b0316639f0c04bf6110a360208501856118a7565b6110b360408601602087016118a7565b60408601356060870135608088013560a08901356110d460c08b018b611a93565b6040518963ffffffff1660e01b81526004016110f7989796959493929190611c78565b602060405180830381865afa158015611114573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111389190611b7d565b905061117b8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508792508591508a9050611360565b505050505050565b81516000906020840161119e64ffffffffff851682846114f9565b95945050505050565b60008160ff166000036111bc575060006112af565b6111cf8460181c6001600160601b031690565b6001600160601b03166111e560ff841685611ce0565b111561124d576111fe8460781c6001600160601b031690565b6112118560181c6001600160601b031690565b6040516378218d2960e01b81526001600160601b039283166004820152911660248201526044810184905260ff83166064820152608401610632565b60208260ff1611156112725760405163045df3f960e01b815260040160405180910390fd5b60088202600061128b8660781c6001600160601b031690565b6001600160601b031690506000600160ff1b60001984011d91860151909116925050505b9392505050565b42600255600180546001600160a01b0319166001600160a01b0383169081179091556040517f6ab4d119f23076e8ad491bc65ce85f017fb0591dce08755ba8591059cc51737a90600090a250565b600061132f7f0000000000000000000000000000000000000000000000000000000000000000611536565b6001600160a01b0316826001600160a01b0316149050919050565b600081831061135957816112af565b5090919050565b6101008451106113a15760405162461bcd60e51b815260206004820152600c60248201526b0e0e4dedecc40d8cadccee8d60a31b6044820152606401610632565b835183901c156113e45760405162461bcd60e51b815260206004820152600e60248201526d10b6b4b734b6b0b610383937b7b360911b6044820152606401610632565b60008381526009602052604090205460ff161561142b5760405162461bcd60e51b81526020600482015260056024820152641cdc195b9d60da1b6044820152606401610632565b60048054604051627436d360e01b81526000926001600160a01b0390921691627436d39161145f9189918991899101611cf3565b602060405180830381865afa15801561147c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a09190611b7d565b90508181146114da5760405162461bcd60e51b815260206004820152600660248201526510b83937b7b360d11b6044820152606401610632565b5050506000908152600960205260409020805460ff1916600117905550565b6000806115068385611ce0565b9050604051811115611516575060005b8060000361152b5762ffffff199150506112af565b61119e858585611694565b60006001600160a01b03821633146115615760405163253a6fc960e11b815260040160405180910390fd5b6000826001600160a01b031663ab5d89436040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c59190611d40565b6001600160a01b03166380648b026040518163ffffffff1660e01b8152600401602060405180830381865afa158015611602573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116269190611d40565b90506001600160a01b038116610b695760405162461bcd60e51b815260206004820152602d60248201527f4c6962417262697472756d4c313a2073797374656d206d65737361676573207760448201526c34ba3437baba1039b2b73232b960991b6064820152608401610632565b60006060601883856001600160601b038216821480156116bc575086816001600160601b0316145b6116f55760405162461bcd60e51b815260206004820152600a602482015269085d1c9d5b98d85d195960b21b6044820152606401610632565b96831b90961790911b90941790931b9392505050565b60006020828403121561171d57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051610180810167ffffffffffffffff8111828210171561175e5761175e611724565b60405290565b600082601f83011261177557600080fd5b813567ffffffffffffffff8082111561179057611790611724565b604051601f8301601f19908116603f011681019082821181831017156117b8576117b8611724565b816040528381528660208588010111156117d157600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561180457600080fd5b823567ffffffffffffffff8082111561181c57600080fd5b61182886838701611764565b9350602085013591508082111561183e57600080fd5b5061184b85828601611764565b9150509250929050565b60006020828403121561186757600080fd5b813567ffffffffffffffff81111561187e57600080fd5b61188a84828501611764565b949350505050565b6001600160a01b038116811461075e57600080fd5b6000602082840312156118b957600080fd5b81356112af81611892565b67ffffffffffffffff8116811461075e57600080fd5b600060e082840312156118ec57600080fd5b50919050565b600080600080600080600060c0888a03121561190d57600080fd5b8735611918816118c4565b96506020880135955060408801359450606088013567ffffffffffffffff8082111561194357600080fd5b818a0191508a601f83011261195757600080fd5b81358181111561196657600080fd5b8b60208260051b850101111561197b57600080fd5b6020830196508095505060808a0135935060a08a01359150808211156119a057600080fd5b506119ad8a828b016118da565b91505092959891949750929550565b6000815180845260005b818110156119e2576020818501810151868301820152016119c6565b506000602082860101526020601f19601f83011685010191505092915050565b606081526000611a1560608301866119bc565b8281036020840152611a2781866119bc565b91505060018060a01b0383166040830152949350505050565b604081526000611a5360408301856119bc565b905060018060a01b03831660208301529392505050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610b6957610b69611a6a565b6000808335601e19843603018112611aaa57600080fd5b83018035915067ffffffffffffffff821115611ac557600080fd5b602001915036819003821315611ada57600080fd5b9250929050565b6020815260006112af60208301846119bc565b600080600060608486031215611b0957600080fd5b8351925060208401519150604084015190509250925092565b600061010060018060a01b03808c1684528a602085015289604085015280891660608501528088166080850152508560a08401528460c08401528060e0840152611b6e818401856119bc565b9b9a5050505050505050505050565b600060208284031215611b8f57600080fd5b5051919050565b8051611ba1816118c4565b919050565b60006101808284031215611bb957600080fd5b611bc161173a565b825181526020830151602082015260408301516040820152611be560608401611b96565b6060820152611bf660808401611b96565b6080820152611c0760a08401611b96565b60a0820152611c1860c08401611b96565b60c0820152611c2960e08401611b96565b60e0820152610100611c3c818501611b96565b90820152610120611c4e848201611b96565b90820152610140611c60848201611b96565b90820152610160928301519281019290925250919050565b600060018060a01b03808b168352808a166020840152508760408301528660608301528560808301528460a083015260e060c08301528260e08301526101008385828501376000838501820152601f909301601f191690910190910198975050505050505050565b80820180821115610b6957610b69611a6a565b606080825284519082018190526000906020906080840190828801845b82811015611d2c57815184529284019290840190600101611d10565b505050908301949094525060400152919050565b600060208284031215611d5257600080fd5b81516112af8161189256fea2646970667358221220019042e2fa1ddf40ad2442b13da589ca89a15ac368f145ebe78777a555b27d1b64736f6c634300081100330000000000000000000000000000000000000000000000000000000000657468000000000000000000000000000000000000000000000000000000006172626f0000000000000000000000004dbd4fc535ac27206064b68ffcf827b0a60bab3f000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b9857ae2d4a3dbe74ffe1d7df045bb7f96e48400000000000000000000000000000000000000000000000000000002e90edd00000000000000000000000000000000000000000000000000000000000000cf85000000000000000000000000000000000000000000000000000000004a817c800
Deployed Bytecode
0x6080604052600436106101a05760003560e01c80639ab0563b116100ec578063ce11e6ab1161008a578063d69f9d6111610064578063d69f9d61146104d9578063db1b76591461050d578063e2ce3c641461052d578063fbd4006b1461054357600080fd5b8063ce11e6ab1461047c578063d1851c921461049c578063d232c220146104ba57600080fd5b8063b64d327e116100c6578063b64d327e14610411578063c5b350df14610427578063cb23bcb51461043c578063cc3942831461045c57600080fd5b80639ab0563b146103b15780639d4373a4146103d1578063b1f8100d146103f157600080fd5b80634ff746f6116101595780635f61e3ec116101335780635f61e3ec1461031c5780636a42b8f814610368578063715018a61461037e5780638da5cb5b1461039357600080fd5b80634ff746f6146102a857806352a9674b146102c85780635bd11efc146102fc57600080fd5b806305a79e06146101ac5780630fca49cd146101f157806314168416146102155780633327998d1461025e5780633cf52ffb1461028057806348e6fa231461029557600080fd5b366101a757005b600080fd5b3480156101b857600080fd5b506101dc6101c736600461170b565b60096020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b3480156101fd57600080fd5b5061020760065481565b6040519081526020016101e8565b34801561022157600080fd5b506102497f000000000000000000000000000000000000000000000000000000006172626f81565b60405163ffffffff90911681526020016101e8565b34801561026a57600080fd5b5061027e61027936600461170b565b610563565b005b34801561028c57600080fd5b50600254610207565b61027e6102a33660046117f1565b6105cf565b3480156102b457600080fd5b5061027e6102c3366004611855565b610684565b3480156102d457600080fd5b506102497f000000000000000000000000000000000000000000000000000000000065746881565b34801561030857600080fd5b5061027e6103173660046118a7565b61072a565b34801561032857600080fd5b506103507f000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e181565b6040516001600160a01b0390911681526020016101e8565b34801561037457600080fd5b5062093a80610207565b34801561038a57600080fd5b5061027e610761565b34801561039f57600080fd5b506000546001600160a01b0316610350565b3480156103bd57600080fd5b5061027e6103cc36600461170b565b610815565b3480156103dd57600080fd5b5061027e6103ec3660046118f2565b610881565b3480156103fd57600080fd5b5061027e61040c3660046118a7565b610a50565b34801561041d57600080fd5b5061020760075481565b34801561043357600080fd5b5061027e610aee565b34801561044857600080fd5b50600554610350906001600160a01b031681565b34801561046857600080fd5b50600354610350906001600160a01b031681565b34801561048857600080fd5b50600454610350906001600160a01b031681565b3480156104a857600080fd5b506001546001600160a01b0316610350565b3480156104c657600080fd5b506000546001600160a01b0316156101dc565b3480156104e557600080fd5b506103507f0000000000000000000000004dbd4fc535ac27206064b68ffcf827b0a60bab3f81565b34801561051957600080fd5b506101dc6105283660046118a7565b610b5e565b34801561053957600080fd5b5061020760085481565b34801561054f57600080fd5b5061027e61055e36600461170b565b610b6f565b6000546001600160a01b0316331461058e576040516311a8a1bb60e31b815260040160405180910390fd5b60065460408051918252602082018390527f8826388bbfa56ae5df40ee5607d9d354fa66549d854624242c77b5af2a5e4c3b910160405180910390a1600655565b336001600160a01b037f000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e1161461063b5760405162461bcd60e51b815260206004820152600c60248201526b10b937b7ba26b0b730b3b2b960a11b60448201526064015b60405180910390fd5b6106458282610bdb565b7fdcaa37a042a0087de79018c629bbd29cee82ca80bd9be394e1696bf9e935507782823360405161067893929190611a02565b60405180910390a15050565b336001600160a01b037f0000000000000000000000004dbd4fc535ac27206064b68ffcf827b0a60bab3f16146106e55760405162461bcd60e51b81526004016106329060208082526004908201526310a0a6a160e11b604082015260600190565b6106ee81610de4565b7fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced813360405161071f929190611a40565b60405180910390a150565b6000546001600160a01b03163314610755576040516311a8a1bb60e31b815260040160405180910390fd5b61075e81610dfd565b50565b6000546001600160a01b0316331461078c576040516311a8a1bb60e31b815260040160405180910390fd5b62093a806002544261079e9190611a80565b116107bc576040516324e0285f60e21b815260040160405180910390fd5b6002546000036107df57604051630e4b303f60e21b815260040160405180910390fd5b6001546001600160a01b031615610809576040516323295ef960e01b815260040160405180910390fd5b6108136000610e66565b565b6000546001600160a01b03163314610840576040516311a8a1bb60e31b815260040160405180910390fd5b60075460408051918252602082018390527f57bffb29c4c6b672a2e334fa00ea826dba286d6cb34d61bebc6c667abb579c62910160405180910390a1600755565b61088c878787610ecb565b6108998685858585611020565b6108a660c0820182611a93565b90506064146108e15760405162461bcd60e51b8152602060048201526007602482015266042d8cadccee8d60cb1b6044820152606401610632565b600061094560446020610938846108fb60c0880188611a93565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506111839050565b62ffffff191691906111a7565b60405163473ec9fd60e11b815263ffffffff7f000000000000000000000000000000000000000000000000000000006172626f166004820152602481018290529091507f000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e16001600160a01b031690638e7d93fa90604401600060405180830381600087803b1580156109d657600080fd5b505af11580156109ea573d6000803e3d6000fd5b505050507fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced81604051602001610a2291815260200190565b60408051601f1981840301815290829052610a3e913390611a40565b60405180910390a15050505050505050565b6000546001600160a01b03163314610a7b576040516311a8a1bb60e31b815260040160405180910390fd5b6001546001600160a01b038281169116148015610a99575060025415155b15610ab7576040516311bc066560e11b815260040160405180910390fd5b6000546001600160a01b03808316911603610ae557604051634a2fb73f60e11b815260040160405180910390fd5b61075e816112b6565b6001546001600160a01b03163314610b19576040516311a7f27160e11b815260040160405180910390fd5b62093a8060025442610b2b9190611a80565b11610b49576040516324e0285f60e21b815260040160405180910390fd5b600154610813906001600160a01b0316610e66565b6000610b6982611304565b92915050565b6000546001600160a01b03163314610b9a576040516311a8a1bb60e31b815260040160405180910390fd5b60065460408051918252602082018390527f7f46895145f361561c5e9bbaf45b71269a4399dc3064511f123ebf4c6f04e357910160405180910390a1600855565b8151602014610c165760405162461bcd60e51b8152602060048201526007602482015266042d8cadccee8d60cb1b6044820152606401610632565b6000634ff746f660e01b83604051602401610c319190611ae1565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091528251909150606014610ca65760405162461bcd60e51b815260206004820152600c60248201526b042c8c2e8c240d8cadccee8d60a31b6044820152606401610632565b600080600084806020019051810190610cbf9190611af4565b92509250925060007f0000000000000000000000004dbd4fc535ac27206064b68ffcf827b0a60bab3f6001600160a01b031663679b6ded34600360009054906101000a90046001600160a01b03166000610d1b8960065461134a565b6003546007546001600160a01b03909116908190610d3a908c9061134a565b610d468b60085461134a565b8e6040518a63ffffffff1660e01b8152600401610d6a989796959493929190611b22565b60206040518083038185885af1158015610d88573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610dad9190611b7d565b60405190915081907fde92b5b7839f4a2c640f5e3bbb66d415458dadc57a487b0c7fa562ed7c9c896f90600090a250505050505050565b6040516316c2fdb560e21b815260040160405180910390fd5b600354604080516001600160a01b03928316815291831660208301527fc77bec288fc88f168427f2f7da682eadb26cac89d8d591af6e443da98dff2bbc910160405180910390a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316178155600255600180549091169055565b604080516020808201849052818301859052825180830384018152606090920190925280519101206000906005546040516324b204d360e21b815267ffffffffffffffff871660048201529192506000916001600160a01b03909116906392c8134c9060240161018060405180830381865afa158015610f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f739190611ba6565b905081816040015114610fb75760405162461bcd60e51b815260206004820152600c60248201526b21636f6e6669726d4461746160a01b6044820152606401610632565b60008160c0015167ffffffffffffffff16118015610fe3575060008160e0015167ffffffffffffffff16115b6110195760405162461bcd60e51b8152602060048201526007602482015266085cdd185ad95960ca1b6044820152606401610632565b5050505050565b6003546001600160a01b031661103960208301836118a7565b6001600160a01b0316146110825760405162461bcd60e51b815260206004820152601060248201526f10b6b4b93937b921b7b73732b1ba37b960811b6044820152606401610632565b6004546000906001600160a01b0316639f0c04bf6110a360208501856118a7565b6110b360408601602087016118a7565b60408601356060870135608088013560a08901356110d460c08b018b611a93565b6040518963ffffffff1660e01b81526004016110f7989796959493929190611c78565b602060405180830381865afa158015611114573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111389190611b7d565b905061117b8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508792508591508a9050611360565b505050505050565b81516000906020840161119e64ffffffffff851682846114f9565b95945050505050565b60008160ff166000036111bc575060006112af565b6111cf8460181c6001600160601b031690565b6001600160601b03166111e560ff841685611ce0565b111561124d576111fe8460781c6001600160601b031690565b6112118560181c6001600160601b031690565b6040516378218d2960e01b81526001600160601b039283166004820152911660248201526044810184905260ff83166064820152608401610632565b60208260ff1611156112725760405163045df3f960e01b815260040160405180910390fd5b60088202600061128b8660781c6001600160601b031690565b6001600160601b031690506000600160ff1b60001984011d91860151909116925050505b9392505050565b42600255600180546001600160a01b0319166001600160a01b0383169081179091556040517f6ab4d119f23076e8ad491bc65ce85f017fb0591dce08755ba8591059cc51737a90600090a250565b600061132f7f0000000000000000000000004dbd4fc535ac27206064b68ffcf827b0a60bab3f611536565b6001600160a01b0316826001600160a01b0316149050919050565b600081831061135957816112af565b5090919050565b6101008451106113a15760405162461bcd60e51b815260206004820152600c60248201526b0e0e4dedecc40d8cadccee8d60a31b6044820152606401610632565b835183901c156113e45760405162461bcd60e51b815260206004820152600e60248201526d10b6b4b734b6b0b610383937b7b360911b6044820152606401610632565b60008381526009602052604090205460ff161561142b5760405162461bcd60e51b81526020600482015260056024820152641cdc195b9d60da1b6044820152606401610632565b60048054604051627436d360e01b81526000926001600160a01b0390921691627436d39161145f9189918991899101611cf3565b602060405180830381865afa15801561147c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a09190611b7d565b90508181146114da5760405162461bcd60e51b815260206004820152600660248201526510b83937b7b360d11b6044820152606401610632565b5050506000908152600960205260409020805460ff1916600117905550565b6000806115068385611ce0565b9050604051811115611516575060005b8060000361152b5762ffffff199150506112af565b61119e858585611694565b60006001600160a01b03821633146115615760405163253a6fc960e11b815260040160405180910390fd5b6000826001600160a01b031663ab5d89436040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c59190611d40565b6001600160a01b03166380648b026040518163ffffffff1660e01b8152600401602060405180830381865afa158015611602573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116269190611d40565b90506001600160a01b038116610b695760405162461bcd60e51b815260206004820152602d60248201527f4c6962417262697472756d4c313a2073797374656d206d65737361676573207760448201526c34ba3437baba1039b2b73232b960991b6064820152608401610632565b60006060601883856001600160601b038216821480156116bc575086816001600160601b0316145b6116f55760405162461bcd60e51b815260206004820152600a602482015269085d1c9d5b98d85d195960b21b6044820152606401610632565b96831b90961790911b90941790931b9392505050565b60006020828403121561171d57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051610180810167ffffffffffffffff8111828210171561175e5761175e611724565b60405290565b600082601f83011261177557600080fd5b813567ffffffffffffffff8082111561179057611790611724565b604051601f8301601f19908116603f011681019082821181831017156117b8576117b8611724565b816040528381528660208588010111156117d157600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561180457600080fd5b823567ffffffffffffffff8082111561181c57600080fd5b61182886838701611764565b9350602085013591508082111561183e57600080fd5b5061184b85828601611764565b9150509250929050565b60006020828403121561186757600080fd5b813567ffffffffffffffff81111561187e57600080fd5b61188a84828501611764565b949350505050565b6001600160a01b038116811461075e57600080fd5b6000602082840312156118b957600080fd5b81356112af81611892565b67ffffffffffffffff8116811461075e57600080fd5b600060e082840312156118ec57600080fd5b50919050565b600080600080600080600060c0888a03121561190d57600080fd5b8735611918816118c4565b96506020880135955060408801359450606088013567ffffffffffffffff8082111561194357600080fd5b818a0191508a601f83011261195757600080fd5b81358181111561196657600080fd5b8b60208260051b850101111561197b57600080fd5b6020830196508095505060808a0135935060a08a01359150808211156119a057600080fd5b506119ad8a828b016118da565b91505092959891949750929550565b6000815180845260005b818110156119e2576020818501810151868301820152016119c6565b506000602082860101526020601f19601f83011685010191505092915050565b606081526000611a1560608301866119bc565b8281036020840152611a2781866119bc565b91505060018060a01b0383166040830152949350505050565b604081526000611a5360408301856119bc565b905060018060a01b03831660208301529392505050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610b6957610b69611a6a565b6000808335601e19843603018112611aaa57600080fd5b83018035915067ffffffffffffffff821115611ac557600080fd5b602001915036819003821315611ada57600080fd5b9250929050565b6020815260006112af60208301846119bc565b600080600060608486031215611b0957600080fd5b8351925060208401519150604084015190509250925092565b600061010060018060a01b03808c1684528a602085015289604085015280891660608501528088166080850152508560a08401528460c08401528060e0840152611b6e818401856119bc565b9b9a5050505050505050505050565b600060208284031215611b8f57600080fd5b5051919050565b8051611ba1816118c4565b919050565b60006101808284031215611bb957600080fd5b611bc161173a565b825181526020830151602082015260408301516040820152611be560608401611b96565b6060820152611bf660808401611b96565b6080820152611c0760a08401611b96565b60a0820152611c1860c08401611b96565b60c0820152611c2960e08401611b96565b60e0820152610100611c3c818501611b96565b90820152610120611c4e848201611b96565b90820152610140611c60848201611b96565b90820152610160928301519281019290925250919050565b600060018060a01b03808b168352808a166020840152508760408301528660608301528560808301528460a083015260e060c08301528260e08301526101008385828501376000838501820152601f909301601f191690910190910198975050505050505050565b80820180821115610b6957610b69611a6a565b606080825284519082018190526000906020906080840190828801845b82811015611d2c57815184529284019290840190600101611d10565b505050908301949094525060400152919050565b600060208284031215611d5257600080fd5b81516112af8161189256fea2646970667358221220019042e2fa1ddf40ad2442b13da589ca89a15ac368f145ebe78777a555b27d1b64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000657468000000000000000000000000000000000000000000000000000000006172626f0000000000000000000000004dbd4fc535ac27206064b68ffcf827b0a60bab3f000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b9857ae2d4a3dbe74ffe1d7df045bb7f96e48400000000000000000000000000000000000000000000000000000002e90edd00000000000000000000000000000000000000000000000000000000000000cf85000000000000000000000000000000000000000000000000000000004a817c800
-----Decoded View---------------
Arg [0] : _domain (uint32): 6648936
Arg [1] : _mirrorDomain (uint32): 1634886255
Arg [2] : _amb (address): 0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f
Arg [3] : _rootManager (address): 0xd5d61E9dfb6680Cba8353988Ba0337802811C2e1
Arg [4] : _mirrorConnector (address): 0x0000000000000000000000000000000000000000
Arg [5] : _outbox (address): 0x0B9857ae2D4A3DBe74ffE1d7DF045bb7F96E4840
Arg [6] : _maxSubmissionCostCap (uint256): 200000000000
Arg [7] : _maxGasCap (uint256): 850000
Arg [8] : _gasPriceCap (uint256): 20000000000
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000657468
Arg [1] : 000000000000000000000000000000000000000000000000000000006172626f
Arg [2] : 0000000000000000000000004dbd4fc535ac27206064b68ffcf827b0a60bab3f
Arg [3] : 000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e1
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 0000000000000000000000000b9857ae2d4a3dbe74ffe1d7df045bb7f96e4840
Arg [6] : 0000000000000000000000000000000000000000000000000000002e90edd000
Arg [7] : 00000000000000000000000000000000000000000000000000000000000cf850
Arg [8] : 00000000000000000000000000000000000000000000000000000004a817c800
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.