Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 4 from a total of 4 transactions
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
OptimismHubConnector
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 {TypedMemView} from "../../../shared/libraries/TypedMemView.sol"; import {IRootManager} from "../../interfaces/IRootManager.sol"; import {OptimismAmb} from "../../interfaces/ambs/optimism/OptimismAmb.sol"; import {IOptimismPortal} from "../../interfaces/ambs/optimism/IOptimismPortal.sol"; import {HubConnector} from "../HubConnector.sol"; import {Connector} from "../Connector.sol"; import {Types} from "./lib/Types.sol"; import {BaseOptimism} from "./BaseOptimism.sol"; contract OptimismHubConnector is HubConnector, BaseOptimism { // ============ Libraries ============ using TypedMemView for bytes; using TypedMemView for bytes29; // ============ Storage ============ IOptimismPortal public immutable OPTIMISM_PORTAL; // NOTE: This is needed because we need to track the roots we've // already sent across chains. When sending an optimism message, we send calldata // for Connector.processMessage. At any point these messages could be processed // before the timeout using `processFromRoot` or after the timeout using `process` // we track the roots sent here to ensure we process each root once mapping(bytes32 => bool) public processed; // ============ Constructor ============ constructor( uint32 _domain, uint32 _mirrorDomain, address _amb, address _rootManager, address _mirrorConnector, address _optimismPortal, uint256 _gasCap ) HubConnector(_domain, _mirrorDomain, _amb, _rootManager, _mirrorConnector) BaseOptimism(_gasCap) { OPTIMISM_PORTAL = IOptimismPortal(_optimismPortal); } // ============ Override Fns ============ function _verifySender(address _expected) internal view override returns (bool) { return _verifySender(AMB, _expected); } /** * @dev Sends `aggregateRoot` to messaging on l2 */ function _sendMessage(bytes memory _data, bytes memory) 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); // Dispatch message OptimismAmb(AMB).sendMessage(mirrorConnector, _calldata, uint32(gasCap)); } /** * @dev modified from: OptimismPortal contract * https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol#L208 */ function processMessageFromRoot( Types.WithdrawalTransaction memory _tx, uint256 _l2OutputIndex, Types.OutputRootProof calldata _outputRootProof, bytes[] calldata _withdrawalProof ) external { OPTIMISM_PORTAL.proveWithdrawalTransaction(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof); // Extract the argument from the data // uint256 _nonce, // address _sender, // address _target, // uint256 _value, // uint256 _minGasLimit, // bytes memory _message (, address _sender, address _target, , , bytes memory _message) = decodeCrossDomainMessageV1(_tx.data); // ensure the l2 connector sent the message require(_sender == mirrorConnector, "!mirror connector"); require(_target == address(this), "!target"); // get the data require(_message.length == 100, "!length"); // NOTE: TypedMemView only loads 32-byte chunks onto stack, which is fine in this case bytes29 _view = _message.ref(0); bytes32 root = _view.index(_view.len() - 32, 32); require(!processed[root], "processed"); // set root to processed processed[root] = true; // update the root on the root manager IRootManager(ROOT_MANAGER).aggregate(MIRROR_DOMAIN, root); emit MessageProcessed(_message, msg.sender); } /** * @notice Encodes a cross domain message based on the V1 (current) encoding. * * @param _encodedData cross domain message. * @return _nonce Message nonce. * @return _sender Address of the sender of the message. * @return _target Address of the target of the message. * @return _value ETH value to send to the target. * @return _gasLimit Gas limit to use for the message. * @return _data Data to send with the message. * */ function decodeCrossDomainMessageV1( bytes memory _encodedData ) internal pure returns (uint256 _nonce, address _sender, address _target, uint256 _value, uint256 _gasLimit, bytes memory _data) { bytes4 selector = bytes4(0); assembly { selector := mload(add(_encodedData, 32)) } // Make sure the function selector matches require(selector == bytes4(keccak256("relayMessage(uint256,address,address,uint256,uint256,bytes)")), "!selector"); uint256 start = 4; uint256 len = _encodedData.length - start; bytes memory sliced = new bytes(len); assembly { // Get the memory pointer to the start of the original data let src := add(_encodedData, add(32, start)) // Get the memory pointer to the start of the new sliced data let dest := add(sliced, 32) // Copy the data from src to dest for { let i := 0 } lt(i, len) { i := add(i, 32) } { mstore(add(dest, i), mload(add(src, i))) } } // Extract the argument from the data (_nonce, _sender, _target, _value, _gasLimit, _data) = abi.decode( sliced, (uint256, address, address, uint256, uint256, bytes) ); } }
// 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 {ProposedOwnable} from "../../shared/ProposedOwnable.sol"; abstract contract GasCap is ProposedOwnable { // ============ Storage ============ /** * @notice The gnosis amb requires destination gas to be specified on the origin. * The gas used will be passed in by the relayer to allow for real-time estimates, * but will be capped at the admin-set cap. */ uint256 gasCap; // ============ Events ============ /** * @notice Emitted when admin updates the gas cap * @param _previous The starting value * @param _updated The final value */ event GasCapUpdated(uint256 _previous, uint256 _updated); // ============ Constructor ============ constructor(uint256 _gasCap) { _setGasCap(_gasCap); } // ============ Admin Fns ============ function setGasCap(uint256 _gasCap) public onlyOwner { _setGasCap(_gasCap); } // ============ Internal Fns ============ /** * @notice Used (by admin) to update the gas cap * @param _gasCap The new value */ function _setGasCap(uint256 _gasCap) internal { emit GasCapUpdated(gasCap, _gasCap); gasCap = _gasCap; } /** * @notice Used to get the gas to use. Will be the original value IFF it * is less than the cap * @param _gas The proposed gas value */ function _getGas(uint256 _gas) internal view returns (uint256) { if (_gas > gasCap) { _gas = gasCap; } return _gas; } }
// 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 {OptimismAmb} from "../../interfaces/ambs/optimism/OptimismAmb.sol"; import {GasCap} from "../GasCap.sol"; abstract contract BaseOptimism is GasCap { // ============ Constructor ============ constructor(uint256 _gasCap) GasCap(_gasCap) {} // ============ Override Fns ============ function _verifySender(address _amb, address _expected) internal view returns (bool) { require(msg.sender == _amb, "!bridge"); return OptimismAmb(_amb).xDomainMessageSender() == _expected; } /** * @notice Using Optimism AMB, the gas is provided to `sendMessage` as an encoded uint */ function _getGasFromEncoded(bytes memory _encodedData) internal view returns (uint256 _gas) { // Should include gas info in specialized calldata require(_encodedData.length == 32, "!data length"); // Get the gas, if it is more than the cap use the cap _gas = _getGas(abi.decode(_encodedData, (uint256))); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /** * @title Types * @notice Contains various types used throughout the Optimism contract system. */ library Types { /** * @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1 * timestamp that the output root is posted. This timestamp is used to verify that the * finalization period has passed since the output root was submitted. * * @custom:field outputRoot Hash of the L2 output. * @custom:field timestamp Timestamp of the L1 block that the output root was submitted in. * @custom:field l2BlockNumber L2 block number that the output corresponds to. */ struct OutputProposal { bytes32 outputRoot; uint128 timestamp; uint128 l2BlockNumber; } /** * @notice Struct representing the elements that are hashed together to generate an output root * which itself represents a snapshot of the L2 state. * * @custom:field version Version of the output root. * @custom:field stateRoot Root of the state trie at the block of this output. * @custom:field messagePasserStorageRoot Root of the message passer storage trie. * @custom:field latestBlockhash Hash of the block this output was generated from. */ struct OutputRootProof { bytes32 version; bytes32 stateRoot; bytes32 messagePasserStorageRoot; bytes32 latestBlockhash; } /** * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end * user (as opposed to a system deposit transaction generated by the system). * * @custom:field from Address of the sender of the transaction. * @custom:field to Address of the recipient of the transaction. * @custom:field isCreation True if the transaction is a contract creation. * @custom:field value Value to send to the recipient. * @custom:field mint Amount of ETH to mint. * @custom:field gasLimit Gas limit of the transaction. * @custom:field data Data of the transaction. * @custom:field l1BlockHash Hash of the block the transaction was submitted in. * @custom:field logIndex Index of the log in the block the transaction was submitted in. */ struct UserDepositTransaction { address from; address to; bool isCreation; uint256 value; uint256 mint; uint64 gasLimit; bytes data; bytes32 l1BlockHash; uint256 logIndex; } /** * @notice Struct representing a withdrawal transaction. * * @custom:field nonce Nonce of the withdrawal transaction * @custom:field sender Address of the sender of the transaction. * @custom:field target Address of the recipient of the transaction. * @custom:field value Value to send to the recipient. * @custom:field gasLimit Gas limit of the transaction. * @custom:field data Data of the transaction. */ struct WithdrawalTransaction { uint256 nonce; address sender; address target; uint256 value; uint256 gasLimit; bytes data; } }
// 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 pragma solidity 0.8.17; import {Types} from "../../../connectors/optimism/lib/Types.sol"; /** * @dev An informal interface. Technically not an interface but a contract, since we need to reference * a mapping when interfacing with the real thing (and mappings cannot be declared in interfaces in solidity). */ interface IOptimismPortal { /** * @notice Proves a withdrawal transaction. * * @param _tx Withdrawal transaction to finalize. * @param _l2OutputIndex L2 output index to prove against. * @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root. * @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract. */ function proveWithdrawalTransaction( Types.WithdrawalTransaction memory _tx, uint256 _l2OutputIndex, Types.OutputRootProof calldata _outputRootProof, bytes[] calldata _withdrawalProof ) external; }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; /** * @dev The optimism bridge shares both of these functions, but it is important * to note that when going from L2 -> L1, the message cannot be processed by the * AMB until the challenge period elapses. * * HOWEVER, before the challenge elapses, you can read the state of the L2 as it is * placed on mainnet. By processing data from the L2 state, we are able to "circumvent" * this delay to a reasonable degree. * * This means that for messages going L1 -> L2, you can call "processMessage" and expect * the call to be executed to pass up the aggregate root. When going from L2 -> L1, you * must read the root from the L2 state * * L2 messenger: https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/L2CrossDomainMessenger.sol * L1 messenger: https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/L1CrossDomainMessenger.sol */ interface OptimismAmb { function sendMessage( address _target, bytes memory _message, uint32 _gasLimit ) external; function xDomainMessageSender() external view returns (address); }
// 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":"_optimismPortal","type":"address"},{"internalType":"uint256","name":"_gasCap","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Connector__processMessage_notUsed","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":"GasCapUpdated","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"},{"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":"OPTIMISM_PORTAL","outputs":[{"internalType":"contract IOptimismPortal","name":"","type":"address"}],"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":"mirrorConnector","outputs":[{"internalType":"address","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":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Types.WithdrawalTransaction","name":"_tx","type":"tuple"},{"internalType":"uint256","name":"_l2OutputIndex","type":"uint256"},{"components":[{"internalType":"bytes32","name":"version","type":"bytes32"},{"internalType":"bytes32","name":"stateRoot","type":"bytes32"},{"internalType":"bytes32","name":"messagePasserStorageRoot","type":"bytes32"},{"internalType":"bytes32","name":"latestBlockhash","type":"bytes32"}],"internalType":"struct Types.OutputRootProof","name":"_outputRootProof","type":"tuple"},{"internalType":"bytes[]","name":"_withdrawalProof","type":"bytes[]"}],"name":"processMessageFromRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"bytes","name":"_encodedData","type":"bytes"}],"name":"sendMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gasCap","type":"uint256"}],"name":"setGasCap","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
6101206040523480156200001257600080fd5b5060405162001c8c38038062001c8c8339810160408190526200003591620002eb565b8080888888888884848484846200004c33620001aa565b8463ffffffff16600003620000975760405162461bcd60e51b815260206004820152600c60248201526b32b6b83a3c903237b6b0b4b760a11b60448201526064015b60405180910390fd5b6001600160a01b038216620000e35760405162461bcd60e51b815260206004820152601160248201527032b6b83a3c903937b7ba26b0b730b3b2b960791b60448201526064016200008e565b63ffffffff8086166080526001600160a01b0380851660a05283811660c05290851660e0528116156200011b576200011b816200020f565b604080516001600160a01b0385811682528481166020830152831681830152905163ffffffff86811692908816917f4f9c27c2fe3f84576ea469d367d044da53c45e951617e8389f2b5ed8db9d25f09181900360600190a3505050505050505050506200018e816200027860201b60201c565b5050506001600160a01b03166101005250620003779350505050565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316178155600255600180549091169055565b600354604080516001600160a01b03928316815291831660208301527fc77bec288fc88f168427f2f7da682eadb26cac89d8d591af6e443da98dff2bbc910160405180910390a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b60045460408051918252602082018390527f877a02cb809da0364d23adca3cd50c451b53f279d3df632e1fc11eb66335bce5910160405180910390a1600455565b805163ffffffff81168114620002ce57600080fd5b919050565b80516001600160a01b0381168114620002ce57600080fd5b600080600080600080600060e0888a0312156200030757600080fd5b6200031288620002b9565b96506200032260208901620002b9565b95506200033260408901620002d3565b94506200034260608901620002d3565b93506200035260808901620002d3565b92506200036260a08901620002d3565b915060c0880151905092959891949750929550565b60805160a05160c05160e0516101005161189f620003ed600039600081816102f9015261060801526000818161014c015261081d0152600081816102420152818161046a015261085801526000818161041d0152818161051f01528181610ba80152610fe4015260006101ee015261189f6000f3fe60806040526004361061012e5760003560e01c80637850b020116100ab578063c5b350df1161006f578063c5b350df14610399578063cc394283146103ae578063d1851c92146103ce578063d232c220146103ec578063d69f9d611461040b578063db1b76591461043f57600080fd5b80637850b020146102c757806385734ee1146102e75780638da5cb5b1461031b578063b1f8100d14610339578063c1f0808a1461035957600080fd5b80635bd11efc116100f25780635bd11efc146102105780635f61e3ec146102305780636a42b8f81461027c5780637049138f14610292578063715018a6146102b257600080fd5b8063141684161461013a5780633cf52ffb1461018857806348e6fa23146101a75780634ff746f6146101bc57806352a9674b146101dc57600080fd5b3661013557005b600080fd5b34801561014657600080fd5b5061016e7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020015b60405180910390f35b34801561019457600080fd5b506002545b60405190815260200161017f565b6101ba6101b536600461126c565b61045f565b005b3480156101c857600080fd5b506101ba6101d73660046112d0565b610514565b3480156101e857600080fd5b5061016e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561021c57600080fd5b506101ba61022b366004611322565b6105ba565b34801561023c57600080fd5b506102647f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161017f565b34801561028857600080fd5b5062093a80610199565b34801561029e57600080fd5b506101ba6102ad3660046113a3565b6105f1565b3480156102be57600080fd5b506101ba6108f9565b3480156102d357600080fd5b506101ba6102e236600461149d565b6109ad565b3480156102f357600080fd5b506102647f000000000000000000000000000000000000000000000000000000000000000081565b34801561032757600080fd5b506000546001600160a01b0316610264565b34801561034557600080fd5b506101ba610354366004611322565b6109e1565b34801561036557600080fd5b5061038961037436600461149d565b60056020526000908152604090205460ff1681565b604051901515815260200161017f565b3480156103a557600080fd5b506101ba610a7f565b3480156103ba57600080fd5b50600354610264906001600160a01b031681565b3480156103da57600080fd5b506001546001600160a01b0316610264565b3480156103f857600080fd5b506000546001600160a01b031615610389565b34801561041757600080fd5b506102647f000000000000000000000000000000000000000000000000000000000000000081565b34801561044b57600080fd5b5061038961045a366004611322565b610aef565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104cb5760405162461bcd60e51b815260206004820152600c60248201526b10b937b7ba26b0b730b3b2b960a11b60448201526064015b60405180910390fd5b6104d58282610b00565b7fdcaa37a042a0087de79018c629bbd29cee82ca80bd9be394e1696bf9e935507782823360405161050893929190611506565b60405180910390a15050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105755760405162461bcd60e51b81526004016104c29060208082526004908201526310a0a6a160e11b604082015260600190565b61057e81610c17565b7fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced81336040516105af929190611544565b60405180910390a150565b6000546001600160a01b031633146105e5576040516311a8a1bb60e31b815260040160405180910390fd5b6105ee81610c30565b50565b604051634870496f60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634870496f906106459088908890889088908890600401611629565b600060405180830381600087803b15801561065f57600080fd5b505af1158015610673573d6000803e3d6000fd5b5050505060008060006106898860a00151610c99565b60035494985092965091945050506001600160a01b0380861691161490506106e75760405162461bcd60e51b815260206004820152601160248201527010b6b4b93937b91031b7b73732b1ba37b960791b60448201526064016104c2565b6001600160a01b03821630146107295760405162461bcd60e51b8152602060048201526007602482015266085d185c99d95d60ca1b60448201526064016104c2565b80516064146107645760405162461bcd60e51b8152602060048201526007602482015266042d8cadccee8d60cb1b60448201526064016104c2565b60006107708282610db6565b905060006107a761078f6020601885901c6001600160601b03166116f5565b62ffffff198416906001600160601b03166020610dda565b60008181526005602052604090205490915060ff16156107f55760405162461bcd60e51b81526020600482015260096024820152681c1c9bd8d95cdcd95960ba1b60448201526064016104c2565b60008181526005602052604090819020805460ff191660011790555163473ec9fd60e11b81527f000000000000000000000000000000000000000000000000000000000000000063ffffffff166004820152602481018290526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690638e7d93fa90604401600060405180830381600087803b15801561089c57600080fd5b505af11580156108b0573d6000803e3d6000fd5b505050507fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced83336040516108e5929190611544565b60405180910390a150505050505050505050565b6000546001600160a01b03163314610924576040516311a8a1bb60e31b815260040160405180910390fd5b62093a8060025442610936919061171c565b11610954576040516324e0285f60e21b815260040160405180910390fd5b60025460000361097757604051630e4b303f60e21b815260040160405180910390fd5b6001546001600160a01b0316156109a1576040516323295ef960e01b815260040160405180910390fd5b6109ab6000610ee9565b565b6000546001600160a01b031633146109d8576040516311a8a1bb60e31b815260040160405180910390fd5b6105ee81610f4e565b6000546001600160a01b03163314610a0c576040516311a8a1bb60e31b815260040160405180910390fd5b6001546001600160a01b038281169116148015610a2a575060025415155b15610a48576040516311bc066560e11b815260040160405180910390fd5b6000546001600160a01b03808316911603610a7657604051634a2fb73f60e11b815260040160405180910390fd5b6105ee81610f8f565b6001546001600160a01b03163314610aaa576040516311a7f27160e11b815260040160405180910390fd5b62093a8060025442610abc919061171c565b11610ada576040516324e0285f60e21b815260040160405180910390fd5b6001546109ab906001600160a01b0316610ee9565b6000610afa82610fdd565b92915050565b8151602014610b3b5760405162461bcd60e51b8152602060048201526007602482015266042d8cadccee8d60cb1b60448201526064016104c2565b6000634ff746f660e01b83604051602401610b56919061172f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600354600480549351633dbb202b60e01b81529294506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811694633dbb202b94610be09490921692879201611742565b600060405180830381600087803b158015610bfa57600080fd5b505af1158015610c0e573d6000803e3d6000fd5b50505050505050565b6040516316c2fdb560e21b815260040160405180910390fd5b600354604080516001600160a01b03928316815291831660208301527fc77bec288fc88f168427f2f7da682eadb26cac89d8d591af6e443da98dff2bbc910160405180910390a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b602081015160009081908190819081906060906001600160e01b0319811663d764ad0b60e01b14610cf85760405162461bcd60e51b815260206004820152600960248201526810b9b2b632b1ba37b960b91b60448201526064016104c2565b8751600490600090610d0b90839061171c565b905060008167ffffffffffffffff811115610d2857610d2861117e565b6040519080825280601f01601f191660200182016040528015610d52576020820181803683370190505b509050826020018b016020820160005b84811015610d7a578281015182820152602001610d62565b50505080806020019051810190610d91919061177c565b809a50819b50829c50839d50849e50859f505050505050505050505091939550919395565b815160009060208401610dd164ffffffffff85168284611009565b95945050505050565b60008160ff16600003610def57506000610ee2565b610e028460181c6001600160601b031690565b6001600160601b0316610e1860ff841685611839565b1115610e8057610e318460781c6001600160601b031690565b610e448560181c6001600160601b031690565b6040516378218d2960e01b81526001600160601b039283166004820152911660248201526044810184905260ff831660648201526084016104c2565b60208260ff161115610ea55760405163045df3f960e01b815260040160405180910390fd5b600882026000610ebe8660781c6001600160601b031690565b6001600160601b031690506000600160ff1b60001984011d91860151909116925050505b9392505050565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316178155600255600180549091169055565b60045460408051918252602082018390527f877a02cb809da0364d23adca3cd50c451b53f279d3df632e1fc11eb66335bce5910160405180910390a1600455565b42600255600180546001600160a01b0319166001600160a01b0383169081179091556040517f6ab4d119f23076e8ad491bc65ce85f017fb0591dce08755ba8591059cc51737a90600090a250565b6000610afa7f000000000000000000000000000000000000000000000000000000000000000083611046565b6000806110168385611839565b9050604051811115611026575060005b8060000361103b5762ffffff19915050610ee2565b610dd1858585611107565b6000336001600160a01b0384161461108a5760405162461bcd60e51b81526020600482015260076024820152662162726964676560c81b60448201526064016104c2565b816001600160a01b0316836001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f6919061184c565b6001600160a01b0316149392505050565b60006060601883856001600160601b0382168214801561112f575086816001600160601b0316145b6111685760405162461bcd60e51b815260206004820152600a602482015269085d1c9d5b98d85d195960b21b60448201526064016104c2565b96831b90961790911b90941790931b9392505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156111b7576111b761117e565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156111e6576111e661117e565b604052919050565b600067ffffffffffffffff8211156112085761120861117e565b50601f01601f191660200190565b600082601f83011261122757600080fd5b813561123a611235826111ee565b6111bd565b81815284602083860101111561124f57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561127f57600080fd5b823567ffffffffffffffff8082111561129757600080fd5b6112a386838701611216565b935060208501359150808211156112b957600080fd5b506112c685828601611216565b9150509250929050565b6000602082840312156112e257600080fd5b813567ffffffffffffffff8111156112f957600080fd5b61130584828501611216565b949350505050565b6001600160a01b03811681146105ee57600080fd5b60006020828403121561133457600080fd5b8135610ee28161130d565b60006080828403121561135157600080fd5b50919050565b60008083601f84011261136957600080fd5b50813567ffffffffffffffff81111561138157600080fd5b6020830191508360208260051b850101111561139c57600080fd5b9250929050565b600080600080600060e086880312156113bb57600080fd5b853567ffffffffffffffff808211156113d357600080fd5b9087019060c0828a0312156113e757600080fd5b6113ef611194565b8235815260208301356114018161130d565b602082015260408301356114148161130d565b80604083015250606083013560608201526080830135608082015260a08301358281111561144157600080fd5b61144d8b828601611216565b60a0830152509650602088013595506114698960408a0161133f565b945060c088013591508082111561147f57600080fd5b5061148c88828901611357565b969995985093965092949392505050565b6000602082840312156114af57600080fd5b5035919050565b60005b838110156114d15781810151838201526020016114b9565b50506000910152565b600081518084526114f28160208601602086016114b6565b601f01601f19169290920160200192915050565b60608152600061151960608301866114da565b828103602084015261152b81866114da565b91505060018060a01b0383166040830152949350505050565b60408152600061155760408301856114da565b905060018060a01b03831660208301529392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006020808501808196508560051b810191508460005b8781101561161c5782840389528135601e198836030181126115d257600080fd5b8701858101903567ffffffffffffffff8111156115ee57600080fd5b8036038213156115fd57600080fd5b61160886828461156e565b9a87019a95505050908401906001016115b1565b5091979650505050505050565b60e080825286519082015260208601516001600160a01b039081166101008301526040870151166101208201526060860151610140820152608086015161016082015260a086015160c061018083015260009061168a6101a08401826114da565b90508660208401526116c06040840187803582526020810135602083015260408101356040830152606081013560608301525050565b82810360c08401526116d3818587611597565b98975050505050505050565b634e487b7160e01b600052601160045260246000fd5b6001600160601b03828116828216039080821115611715576117156116df565b5092915050565b81810381811115610afa57610afa6116df565b602081526000610ee260208301846114da565b6001600160a01b0384168152606060208201819052600090611766908301856114da565b905063ffffffff83166040830152949350505050565b60008060008060008060c0878903121561179557600080fd5b8651955060208701516117a78161130d565b60408801519095506117b88161130d565b80945050606087015192506080870151915060a087015167ffffffffffffffff8111156117e457600080fd5b8701601f810189136117f557600080fd5b8051611803611235826111ee565b8181528a602083850101111561181857600080fd5b6118298260208301602086016114b6565b8093505050509295509295509295565b80820180821115610afa57610afa6116df565b60006020828403121561185e57600080fd5b8151610ee28161130d56fea2646970667358221220258002e9f2ddc0e82c69e3efb2e4471c487766b33f88fa3c38255a8b9b4605f264736f6c634300081100330000000000000000000000000000000000000000000000000000000000657468000000000000000000000000000000000000000000000000000000006f70746900000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa1000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000cf850
Deployed Bytecode
0x60806040526004361061012e5760003560e01c80637850b020116100ab578063c5b350df1161006f578063c5b350df14610399578063cc394283146103ae578063d1851c92146103ce578063d232c220146103ec578063d69f9d611461040b578063db1b76591461043f57600080fd5b80637850b020146102c757806385734ee1146102e75780638da5cb5b1461031b578063b1f8100d14610339578063c1f0808a1461035957600080fd5b80635bd11efc116100f25780635bd11efc146102105780635f61e3ec146102305780636a42b8f81461027c5780637049138f14610292578063715018a6146102b257600080fd5b8063141684161461013a5780633cf52ffb1461018857806348e6fa23146101a75780634ff746f6146101bc57806352a9674b146101dc57600080fd5b3661013557005b600080fd5b34801561014657600080fd5b5061016e7f000000000000000000000000000000000000000000000000000000006f70746981565b60405163ffffffff90911681526020015b60405180910390f35b34801561019457600080fd5b506002545b60405190815260200161017f565b6101ba6101b536600461126c565b61045f565b005b3480156101c857600080fd5b506101ba6101d73660046112d0565b610514565b3480156101e857600080fd5b5061016e7f000000000000000000000000000000000000000000000000000000000065746881565b34801561021c57600080fd5b506101ba61022b366004611322565b6105ba565b34801561023c57600080fd5b506102647f000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e181565b6040516001600160a01b03909116815260200161017f565b34801561028857600080fd5b5062093a80610199565b34801561029e57600080fd5b506101ba6102ad3660046113a3565b6105f1565b3480156102be57600080fd5b506101ba6108f9565b3480156102d357600080fd5b506101ba6102e236600461149d565b6109ad565b3480156102f357600080fd5b506102647f000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed81565b34801561032757600080fd5b506000546001600160a01b0316610264565b34801561034557600080fd5b506101ba610354366004611322565b6109e1565b34801561036557600080fd5b5061038961037436600461149d565b60056020526000908152604090205460ff1681565b604051901515815260200161017f565b3480156103a557600080fd5b506101ba610a7f565b3480156103ba57600080fd5b50600354610264906001600160a01b031681565b3480156103da57600080fd5b506001546001600160a01b0316610264565b3480156103f857600080fd5b506000546001600160a01b031615610389565b34801561041757600080fd5b506102647f00000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa181565b34801561044b57600080fd5b5061038961045a366004611322565b610aef565b336001600160a01b037f000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e116146104cb5760405162461bcd60e51b815260206004820152600c60248201526b10b937b7ba26b0b730b3b2b960a11b60448201526064015b60405180910390fd5b6104d58282610b00565b7fdcaa37a042a0087de79018c629bbd29cee82ca80bd9be394e1696bf9e935507782823360405161050893929190611506565b60405180910390a15050565b336001600160a01b037f00000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa116146105755760405162461bcd60e51b81526004016104c29060208082526004908201526310a0a6a160e11b604082015260600190565b61057e81610c17565b7fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced81336040516105af929190611544565b60405180910390a150565b6000546001600160a01b031633146105e5576040516311a8a1bb60e31b815260040160405180910390fd5b6105ee81610c30565b50565b604051634870496f60e01b81526001600160a01b037f000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed1690634870496f906106459088908890889088908890600401611629565b600060405180830381600087803b15801561065f57600080fd5b505af1158015610673573d6000803e3d6000fd5b5050505060008060006106898860a00151610c99565b60035494985092965091945050506001600160a01b0380861691161490506106e75760405162461bcd60e51b815260206004820152601160248201527010b6b4b93937b91031b7b73732b1ba37b960791b60448201526064016104c2565b6001600160a01b03821630146107295760405162461bcd60e51b8152602060048201526007602482015266085d185c99d95d60ca1b60448201526064016104c2565b80516064146107645760405162461bcd60e51b8152602060048201526007602482015266042d8cadccee8d60cb1b60448201526064016104c2565b60006107708282610db6565b905060006107a761078f6020601885901c6001600160601b03166116f5565b62ffffff198416906001600160601b03166020610dda565b60008181526005602052604090205490915060ff16156107f55760405162461bcd60e51b81526020600482015260096024820152681c1c9bd8d95cdcd95960ba1b60448201526064016104c2565b60008181526005602052604090819020805460ff191660011790555163473ec9fd60e11b81527f000000000000000000000000000000000000000000000000000000006f70746963ffffffff166004820152602481018290526001600160a01b037f000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e11690638e7d93fa90604401600060405180830381600087803b15801561089c57600080fd5b505af11580156108b0573d6000803e3d6000fd5b505050507fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced83336040516108e5929190611544565b60405180910390a150505050505050505050565b6000546001600160a01b03163314610924576040516311a8a1bb60e31b815260040160405180910390fd5b62093a8060025442610936919061171c565b11610954576040516324e0285f60e21b815260040160405180910390fd5b60025460000361097757604051630e4b303f60e21b815260040160405180910390fd5b6001546001600160a01b0316156109a1576040516323295ef960e01b815260040160405180910390fd5b6109ab6000610ee9565b565b6000546001600160a01b031633146109d8576040516311a8a1bb60e31b815260040160405180910390fd5b6105ee81610f4e565b6000546001600160a01b03163314610a0c576040516311a8a1bb60e31b815260040160405180910390fd5b6001546001600160a01b038281169116148015610a2a575060025415155b15610a48576040516311bc066560e11b815260040160405180910390fd5b6000546001600160a01b03808316911603610a7657604051634a2fb73f60e11b815260040160405180910390fd5b6105ee81610f8f565b6001546001600160a01b03163314610aaa576040516311a7f27160e11b815260040160405180910390fd5b62093a8060025442610abc919061171c565b11610ada576040516324e0285f60e21b815260040160405180910390fd5b6001546109ab906001600160a01b0316610ee9565b6000610afa82610fdd565b92915050565b8151602014610b3b5760405162461bcd60e51b8152602060048201526007602482015266042d8cadccee8d60cb1b60448201526064016104c2565b6000634ff746f660e01b83604051602401610b56919061172f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600354600480549351633dbb202b60e01b81529294506001600160a01b037f00000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa1811694633dbb202b94610be09490921692879201611742565b600060405180830381600087803b158015610bfa57600080fd5b505af1158015610c0e573d6000803e3d6000fd5b50505050505050565b6040516316c2fdb560e21b815260040160405180910390fd5b600354604080516001600160a01b03928316815291831660208301527fc77bec288fc88f168427f2f7da682eadb26cac89d8d591af6e443da98dff2bbc910160405180910390a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b602081015160009081908190819081906060906001600160e01b0319811663d764ad0b60e01b14610cf85760405162461bcd60e51b815260206004820152600960248201526810b9b2b632b1ba37b960b91b60448201526064016104c2565b8751600490600090610d0b90839061171c565b905060008167ffffffffffffffff811115610d2857610d2861117e565b6040519080825280601f01601f191660200182016040528015610d52576020820181803683370190505b509050826020018b016020820160005b84811015610d7a578281015182820152602001610d62565b50505080806020019051810190610d91919061177c565b809a50819b50829c50839d50849e50859f505050505050505050505091939550919395565b815160009060208401610dd164ffffffffff85168284611009565b95945050505050565b60008160ff16600003610def57506000610ee2565b610e028460181c6001600160601b031690565b6001600160601b0316610e1860ff841685611839565b1115610e8057610e318460781c6001600160601b031690565b610e448560181c6001600160601b031690565b6040516378218d2960e01b81526001600160601b039283166004820152911660248201526044810184905260ff831660648201526084016104c2565b60208260ff161115610ea55760405163045df3f960e01b815260040160405180910390fd5b600882026000610ebe8660781c6001600160601b031690565b6001600160601b031690506000600160ff1b60001984011d91860151909116925050505b9392505050565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316178155600255600180549091169055565b60045460408051918252602082018390527f877a02cb809da0364d23adca3cd50c451b53f279d3df632e1fc11eb66335bce5910160405180910390a1600455565b42600255600180546001600160a01b0319166001600160a01b0383169081179091556040517f6ab4d119f23076e8ad491bc65ce85f017fb0591dce08755ba8591059cc51737a90600090a250565b6000610afa7f00000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa183611046565b6000806110168385611839565b9050604051811115611026575060005b8060000361103b5762ffffff19915050610ee2565b610dd1858585611107565b6000336001600160a01b0384161461108a5760405162461bcd60e51b81526020600482015260076024820152662162726964676560c81b60448201526064016104c2565b816001600160a01b0316836001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f6919061184c565b6001600160a01b0316149392505050565b60006060601883856001600160601b0382168214801561112f575086816001600160601b0316145b6111685760405162461bcd60e51b815260206004820152600a602482015269085d1c9d5b98d85d195960b21b60448201526064016104c2565b96831b90961790911b90941790931b9392505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156111b7576111b761117e565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156111e6576111e661117e565b604052919050565b600067ffffffffffffffff8211156112085761120861117e565b50601f01601f191660200190565b600082601f83011261122757600080fd5b813561123a611235826111ee565b6111bd565b81815284602083860101111561124f57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561127f57600080fd5b823567ffffffffffffffff8082111561129757600080fd5b6112a386838701611216565b935060208501359150808211156112b957600080fd5b506112c685828601611216565b9150509250929050565b6000602082840312156112e257600080fd5b813567ffffffffffffffff8111156112f957600080fd5b61130584828501611216565b949350505050565b6001600160a01b03811681146105ee57600080fd5b60006020828403121561133457600080fd5b8135610ee28161130d565b60006080828403121561135157600080fd5b50919050565b60008083601f84011261136957600080fd5b50813567ffffffffffffffff81111561138157600080fd5b6020830191508360208260051b850101111561139c57600080fd5b9250929050565b600080600080600060e086880312156113bb57600080fd5b853567ffffffffffffffff808211156113d357600080fd5b9087019060c0828a0312156113e757600080fd5b6113ef611194565b8235815260208301356114018161130d565b602082015260408301356114148161130d565b80604083015250606083013560608201526080830135608082015260a08301358281111561144157600080fd5b61144d8b828601611216565b60a0830152509650602088013595506114698960408a0161133f565b945060c088013591508082111561147f57600080fd5b5061148c88828901611357565b969995985093965092949392505050565b6000602082840312156114af57600080fd5b5035919050565b60005b838110156114d15781810151838201526020016114b9565b50506000910152565b600081518084526114f28160208601602086016114b6565b601f01601f19169290920160200192915050565b60608152600061151960608301866114da565b828103602084015261152b81866114da565b91505060018060a01b0383166040830152949350505050565b60408152600061155760408301856114da565b905060018060a01b03831660208301529392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006020808501808196508560051b810191508460005b8781101561161c5782840389528135601e198836030181126115d257600080fd5b8701858101903567ffffffffffffffff8111156115ee57600080fd5b8036038213156115fd57600080fd5b61160886828461156e565b9a87019a95505050908401906001016115b1565b5091979650505050505050565b60e080825286519082015260208601516001600160a01b039081166101008301526040870151166101208201526060860151610140820152608086015161016082015260a086015160c061018083015260009061168a6101a08401826114da565b90508660208401526116c06040840187803582526020810135602083015260408101356040830152606081013560608301525050565b82810360c08401526116d3818587611597565b98975050505050505050565b634e487b7160e01b600052601160045260246000fd5b6001600160601b03828116828216039080821115611715576117156116df565b5092915050565b81810381811115610afa57610afa6116df565b602081526000610ee260208301846114da565b6001600160a01b0384168152606060208201819052600090611766908301856114da565b905063ffffffff83166040830152949350505050565b60008060008060008060c0878903121561179557600080fd5b8651955060208701516117a78161130d565b60408801519095506117b88161130d565b80945050606087015192506080870151915060a087015167ffffffffffffffff8111156117e457600080fd5b8701601f810189136117f557600080fd5b8051611803611235826111ee565b8181528a602083850101111561181857600080fd5b6118298260208301602086016114b6565b8093505050509295509295509295565b80820180821115610afa57610afa6116df565b60006020828403121561185e57600080fd5b8151610ee28161130d56fea2646970667358221220258002e9f2ddc0e82c69e3efb2e4471c487766b33f88fa3c38255a8b9b4605f264736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000657468000000000000000000000000000000000000000000000000000000006f70746900000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa1000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000cf850
-----Decoded View---------------
Arg [0] : _domain (uint32): 6648936
Arg [1] : _mirrorDomain (uint32): 1869640809
Arg [2] : _amb (address): 0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1
Arg [3] : _rootManager (address): 0xd5d61E9dfb6680Cba8353988Ba0337802811C2e1
Arg [4] : _mirrorConnector (address): 0x0000000000000000000000000000000000000000
Arg [5] : _optimismPortal (address): 0xbEb5Fc579115071764c7423A4f12eDde41f106Ed
Arg [6] : _gasCap (uint256): 850000
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000657468
Arg [1] : 000000000000000000000000000000000000000000000000000000006f707469
Arg [2] : 00000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa1
Arg [3] : 000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e1
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed
Arg [6] : 00000000000000000000000000000000000000000000000000000000000cf850
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.