Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Bridge
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 2000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./AbsBridge.sol"; import "./IEthBridge.sol"; import "./Messages.sol"; import "../libraries/DelegateCallAware.sol"; /** * @title Staging ground for incoming and outgoing messages * @notice It is also the ETH escrow for value sent with these messages. */ contract Bridge is AbsBridge, IEthBridge { using AddressUpgradeable for address; /// @inheritdoc IEthBridge function initialize( IOwnable rollup_ ) external initializer onlyDelegated { _activeOutbox = EMPTY_ACTIVEOUTBOX; rollup = rollup_; } /// @inheritdoc IEthBridge function enqueueDelayedMessage( uint8 kind, address sender, bytes32 messageDataHash ) external payable returns (uint256) { return _enqueueDelayedMessage(kind, sender, messageDataHash, msg.value); } function _transferFunds( uint256 ) internal override { // do nothing as Eth transfer is part of TX execution } function _executeLowLevelCall( address to, uint256 value, bytes memory data ) internal override returns (bool success, bytes memory returnData) { // solhint-disable-next-line avoid-low-level-calls (success, returnData) = to.call{value: value}(data); } function _baseFeeToReport() internal view override returns (uint256) { return block.basefee; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import { NotContract, NotRollupOrOwner, NotDelayedInbox, NotSequencerInbox, NotOutbox, InvalidOutboxSet, BadSequencerMessageNumber } from "../libraries/Error.sol"; import "./IBridge.sol"; import "./Messages.sol"; import "../libraries/DelegateCallAware.sol"; import {L1MessageType_batchPostingReport} from "../libraries/MessageTypes.sol"; /** * @title Staging ground for incoming and outgoing messages * @notice Holds the inbox accumulator for sequenced and delayed messages. * Since the escrow is held here, this contract also contains a list of allowed * outboxes that can make calls from here and withdraw this escrow. */ abstract contract AbsBridge is Initializable, DelegateCallAware, IBridge { using AddressUpgradeable for address; struct InOutInfo { uint256 index; bool allowed; } mapping(address => InOutInfo) private allowedDelayedInboxesMap; mapping(address => InOutInfo) private allowedOutboxesMap; address[] public allowedDelayedInboxList; address[] public allowedOutboxList; address internal _activeOutbox; /// @inheritdoc IBridge bytes32[] public delayedInboxAccs; /// @inheritdoc IBridge bytes32[] public sequencerInboxAccs; IOwnable public rollup; address public sequencerInbox; uint256 public override sequencerReportedSubMessageCount; address internal constant EMPTY_ACTIVEOUTBOX = address(type(uint160).max); modifier onlyRollupOrOwner() { if (msg.sender != address(rollup)) { address rollupOwner = rollup.owner(); if (msg.sender != rollupOwner) { revert NotRollupOrOwner(msg.sender, address(rollup), rollupOwner); } } _; } /// @notice Allows the rollup owner to set another rollup address function updateRollupAddress( IOwnable _rollup ) external onlyRollupOrOwner { rollup = _rollup; emit RollupUpdated(address(_rollup)); } /// @dev returns the address of current active Outbox, or zero if no outbox is active function activeOutbox() public view returns (address) { address outbox = _activeOutbox; // address zero is returned if no outbox is set, but the value used in storage // is non-zero to save users some gas (as storage refunds are usually maxed out) // EIP-1153 would help here. // we don't return `EMPTY_ACTIVEOUTBOX` to avoid a breaking change on the current api if (outbox == EMPTY_ACTIVEOUTBOX) return address(0); return outbox; } function allowedDelayedInboxes( address inbox ) public view returns (bool) { return allowedDelayedInboxesMap[inbox].allowed; } function allowedOutboxes( address outbox ) public view returns (bool) { return allowedOutboxesMap[outbox].allowed; } modifier onlySequencerInbox() { if (msg.sender != sequencerInbox) revert NotSequencerInbox(msg.sender); _; } function enqueueSequencerMessage( bytes32 dataHash, uint256 afterDelayedMessagesRead, uint256 prevMessageCount, uint256 newMessageCount ) external onlySequencerInbox returns (uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc) { if ( sequencerReportedSubMessageCount != prevMessageCount && prevMessageCount != 0 && sequencerReportedSubMessageCount != 0 ) { revert BadSequencerMessageNumber(sequencerReportedSubMessageCount, prevMessageCount); } sequencerReportedSubMessageCount = newMessageCount; seqMessageIndex = sequencerInboxAccs.length; if (seqMessageIndex > 0) { beforeAcc = sequencerInboxAccs[seqMessageIndex - 1]; } if (afterDelayedMessagesRead > 0) { delayedAcc = delayedInboxAccs[afterDelayedMessagesRead - 1]; } acc = keccak256(abi.encodePacked(beforeAcc, dataHash, delayedAcc)); sequencerInboxAccs.push(acc); } /// @inheritdoc IBridge function submitBatchSpendingReport( address sender, bytes32 messageDataHash ) external onlySequencerInbox returns (uint256) { return addMessageToDelayedAccumulator( L1MessageType_batchPostingReport, sender, uint64(block.number), uint64(block.timestamp), // solhint-disable-line not-rely-on-time, block.basefee, messageDataHash ); } function _enqueueDelayedMessage( uint8 kind, address sender, bytes32 messageDataHash, uint256 amount ) internal returns (uint256) { if (!allowedDelayedInboxes(msg.sender)) revert NotDelayedInbox(msg.sender); uint256 messageCount = addMessageToDelayedAccumulator( kind, sender, uint64(block.number), uint64(block.timestamp), // solhint-disable-line not-rely-on-time _baseFeeToReport(), messageDataHash ); _transferFunds(amount); return messageCount; } function addMessageToDelayedAccumulator( uint8 kind, address sender, uint64 blockNumber, uint64 blockTimestamp, uint256 baseFeeL1, bytes32 messageDataHash ) internal returns (uint256) { uint256 count = delayedInboxAccs.length; bytes32 messageHash = Messages.messageHash( kind, sender, blockNumber, blockTimestamp, count, baseFeeL1, messageDataHash ); bytes32 prevAcc = 0; if (count > 0) { prevAcc = delayedInboxAccs[count - 1]; } delayedInboxAccs.push(Messages.accumulateInboxMessage(prevAcc, messageHash)); emit MessageDelivered( count, prevAcc, msg.sender, kind, sender, messageDataHash, baseFeeL1, blockTimestamp ); return count; } /// @inheritdoc IBridge function executeCall( address to, uint256 value, bytes calldata data ) external returns (bool success, bytes memory returnData) { if (!allowedOutboxes(msg.sender)) revert NotOutbox(msg.sender); if (data.length > 0 && !to.isContract()) revert NotContract(to); address prevOutbox = _activeOutbox; _activeOutbox = msg.sender; // We set and reset active outbox around external call so activeOutbox remains valid during call // We use a low level call here since we want to bubble up whether it succeeded or failed to the caller // rather than reverting on failure as well as allow contract and non-contract calls (success, returnData) = _executeLowLevelCall(to, value, data); _activeOutbox = prevOutbox; emit BridgeCallTriggered(msg.sender, to, value, data); } function setSequencerInbox( address _sequencerInbox ) external onlyRollupOrOwner { sequencerInbox = _sequencerInbox; emit SequencerInboxUpdated(_sequencerInbox); } function setDelayedInbox(address inbox, bool enabled) external onlyRollupOrOwner { InOutInfo storage info = allowedDelayedInboxesMap[inbox]; bool alreadyEnabled = info.allowed; emit InboxToggle(inbox, enabled); if (alreadyEnabled == enabled) { return; } if (enabled) { allowedDelayedInboxesMap[inbox] = InOutInfo(allowedDelayedInboxList.length, true); allowedDelayedInboxList.push(inbox); } else { allowedDelayedInboxList[info.index] = allowedDelayedInboxList[allowedDelayedInboxList.length - 1]; allowedDelayedInboxesMap[allowedDelayedInboxList[info.index]].index = info.index; allowedDelayedInboxList.pop(); delete allowedDelayedInboxesMap[inbox]; } } function setOutbox(address outbox, bool enabled) external onlyRollupOrOwner { if (outbox == EMPTY_ACTIVEOUTBOX) revert InvalidOutboxSet(outbox); InOutInfo storage info = allowedOutboxesMap[outbox]; bool alreadyEnabled = info.allowed; emit OutboxToggle(outbox, enabled); if (alreadyEnabled == enabled) { return; } if (enabled) { allowedOutboxesMap[outbox] = InOutInfo(allowedOutboxList.length, true); allowedOutboxList.push(outbox); } else { allowedOutboxList[info.index] = allowedOutboxList[allowedOutboxList.length - 1]; allowedOutboxesMap[allowedOutboxList[info.index]].index = info.index; allowedOutboxList.pop(); delete allowedOutboxesMap[outbox]; } } function setSequencerReportedSubMessageCount( uint256 newMsgCount ) external onlyRollupOrOwner { sequencerReportedSubMessageCount = newMsgCount; } function delayedMessageCount() external view override returns (uint256) { return delayedInboxAccs.length; } function sequencerMessageCount() external view returns (uint256) { return sequencerInboxAccs.length; } /// @dev For the classic -> nitro migration. TODO: remove post-migration. function acceptFundsFromOldBridge() external payable {} /// @dev transfer funds provided to pay for crosschain msg function _transferFunds( uint256 amount ) internal virtual; function _executeLowLevelCall( address to, uint256 value, bytes memory data ) internal virtual returns (bool success, bytes memory returnData); /// @dev get base fee which is emitted in `MessageDelivered` event and then picked up and /// used in ArbOs to calculate the submission fee for retryable ticket function _baseFeeToReport() internal view virtual returns (uint256); /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[40] private __gap; }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IOwnable.sol"; interface IBridge { /// @dev This is an instruction to offchain readers to inform them where to look /// for sequencer inbox batch data. This is not the type of data (eg. das, brotli encoded, or blob versioned hash) /// and this enum is not used in the state transition function, rather it informs an offchain /// reader where to find the data so that they can supply it to the replay binary enum BatchDataLocation { /// @notice The data can be found in the transaction call data TxInput, /// @notice The data can be found in an event emitted during the transaction SeparateBatchEvent, /// @notice This batch contains no data NoData, /// @notice The data can be found in the 4844 data blobs on this transaction Blob } struct TimeBounds { uint64 minTimestamp; uint64 maxTimestamp; uint64 minBlockNumber; uint64 maxBlockNumber; } 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); event RollupUpdated(address rollup); 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); function rollup() external view returns (IOwnable); 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); 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; function updateRollupAddress( IOwnable _rollup ) external; }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IOwnable.sol"; import "./IBridge.sol"; interface IEthBridge is IBridge { /** * @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); // ---------- initializer ---------- function initialize( IOwnable rollup_ ) external; }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.4.21 <0.9.0; interface IOwnable { function owner() external view returns (address); }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; pragma experimental ABIEncoderV2; library Messages { struct Message { uint8 kind; address sender; uint64 blockNumber; uint64 timestamp; uint256 inboxSeqNum; uint256 baseFeeL1; bytes32 messageDataHash; } function messageHash( Message memory message ) internal pure returns (bytes32) { return messageHash( message.kind, message.sender, message.blockNumber, message.timestamp, message.inboxSeqNum, message.baseFeeL1, message.messageDataHash ); } function messageHash( uint8 kind, address sender, uint64 blockNumber, uint64 timestamp, uint256 inboxSeqNum, uint256 baseFeeL1, bytes32 messageDataHash ) internal pure returns (bytes32) { return keccak256( abi.encodePacked( kind, sender, blockNumber, timestamp, inboxSeqNum, baseFeeL1, messageDataHash ) ); } function accumulateInboxMessage( bytes32 prevAcc, bytes32 message ) internal pure returns (bytes32) { return keccak256(abi.encodePacked(prevAcc, message)); } /// @dev Validates a delayed accumulator preimage /// @param delayedAcc The delayed accumulator to validate against /// @param beforeDelayedAcc The previous delayed accumulator /// @param message The message to validate function isValidDelayedAccPreimage( bytes32 delayedAcc, bytes32 beforeDelayedAcc, Message memory message ) internal pure returns (bool) { return delayedAcc == accumulateInboxMessage(beforeDelayedAcc, messageHash(message)); } }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {NotOwner} from "./Error.sol"; /// @dev A stateless contract that allows you to infer if the current call has been delegated or not /// Pattern used here is from UUPS implementation by the OpenZeppelin team abstract contract DelegateCallAware { address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegate call. This allows a function to be * callable on the proxy contract but not on the logic contract. */ modifier onlyDelegated() { require(address(this) != __self, "Function must be called through delegatecall"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "Function must not be called through delegatecall"); _; } /// @dev Check that msg.sender is the current EIP 1967 proxy admin modifier onlyProxyOwner() { // Storage slot with the admin of the proxy contract // This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1 bytes32 slot = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; address admin; assembly { admin := sload(slot) } if (msg.sender != admin) revert NotOwner(msg.sender, admin); _; } }
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; /// @dev Init was already called error AlreadyInit(); /// @dev Init was called with param set to zero that must be nonzero error HadZeroInit(); /// @dev Thrown when post upgrade init validation fails error BadPostUpgradeInit(); /// @dev Thrown when the caller is not a codeless origin error NotCodelessOrigin(); /// @dev Thrown when non owner tries to access an only-owner function /// @param sender The msg.sender who is not the owner /// @param owner The owner address error NotOwner(address sender, address owner); /// @dev Thrown when an address that is not the rollup tries to call an only-rollup function /// @param sender The sender who is not the rollup /// @param rollup The rollup address authorized to call this function error NotRollup(address sender, address rollup); /// @dev Thrown when the contract was not called directly from the origin ie msg.sender != tx.origin error NotOrigin(); /// @dev Provided data was too large /// @param dataLength The length of the data that is too large /// @param maxDataLength The max length the data can be error DataTooLarge(uint256 dataLength, uint256 maxDataLength); /// @dev The provided is not a contract and was expected to be /// @param addr The adddress in question error NotContract(address addr); /// @dev The merkle proof provided was too long /// @param actualLength The length of the merkle proof provided /// @param maxProofLength The max length a merkle proof can have error MerkleProofTooLong(uint256 actualLength, uint256 maxProofLength); /// @dev Thrown when an un-authorized address tries to access an admin function /// @param sender The un-authorized sender /// @param rollup The rollup, which would be authorized /// @param owner The rollup's owner, which would be authorized error NotRollupOrOwner(address sender, address rollup, address owner); // Bridge Errors /// @dev Thrown when an un-authorized address tries to access an only-inbox function /// @param sender The un-authorized sender error NotDelayedInbox(address sender); /// @dev Thrown when an un-authorized address tries to access an only-sequencer-inbox function /// @param sender The un-authorized sender error NotSequencerInbox(address sender); /// @dev Thrown when an un-authorized address tries to access an only-outbox function /// @param sender The un-authorized sender error NotOutbox(address sender); /// @dev the provided outbox address isn't valid /// @param outbox address of outbox being set error InvalidOutboxSet(address outbox); /// @dev The provided token address isn't valid /// @param token address of token being set error InvalidTokenSet(address token); /// @dev Call to this specific address is not allowed /// @param target address of the call receiver error CallTargetNotAllowed(address target); /// @dev Call that changes the balance of ERC20Bridge is not allowed error CallNotAllowed(); // Inbox Errors /// @dev msg.value sent to the inbox isn't high enough error InsufficientValue(uint256 expected, uint256 actual); /// @dev submission cost provided isn't enough to create retryable ticket error InsufficientSubmissionCost(uint256 expected, uint256 actual); /// @dev address not allowed to interact with the given contract error NotAllowedOrigin(address origin); /// @dev used to convey retryable tx data in eth calls without requiring a tx trace /// this follows a pattern similar to EIP-3668 where reverts surface call information error RetryableData( address from, address to, uint256 l2CallValue, uint256 deposit, uint256 maxSubmissionCost, address excessFeeRefundAddress, address callValueRefundAddress, uint256 gasLimit, uint256 maxFeePerGas, bytes data ); /// @dev Thrown when a L1 chainId fork is detected error L1Forked(); /// @dev Thrown when a L1 chainId fork is not detected error NotForked(); /// @dev The provided gasLimit is larger than uint64 error GasLimitTooLarge(); /// @dev The provided amount cannot be adjusted to 18 decimals due to overflow error AmountTooLarge(uint256 amount); /// @dev Number of native token's decimals is restricted to enable conversions to 18 decimals error NativeTokenDecimalsTooLarge(uint256 decimals); // Outbox Errors /// @dev The provided proof was too long /// @param proofLength The length of the too-long proof error ProofTooLong(uint256 proofLength); /// @dev The output index was greater than the maximum /// @param index The output index /// @param maxIndex The max the index could be error PathNotMinimal(uint256 index, uint256 maxIndex); /// @dev The calculated root does not exist /// @param root The calculated root error UnknownRoot(bytes32 root); /// @dev The record has already been spent /// @param index The index of the spent record error AlreadySpent(uint256 index); /// @dev A call to the bridge failed with no return data error BridgeCallFailed(); // Sequencer Inbox Errors /// @dev Thrown when someone attempts to read fewer messages than have already been read error DelayedBackwards(); /// @dev Thrown when someone attempts to read more messages than exist error DelayedTooFar(); /// @dev Force include can only read messages more blocks old than the delay period error ForceIncludeBlockTooSoon(); /// @dev The message provided did not match the hash in the delayed inbox error IncorrectMessagePreimage(); /// @dev This can only be called by the batch poster error NotBatchPoster(); /// @dev The sequence number provided to this message was inconsistent with the number of batches already included error BadSequencerNumber(uint256 stored, uint256 received); /// @dev The sequence message number provided to this message was inconsistent with the previous one error BadSequencerMessageNumber(uint256 stored, uint256 received); /// @dev Tried to create an already valid Data Availability Service keyset error AlreadyValidDASKeyset(bytes32); /// @dev Tried to use or invalidate an already invalid Data Availability Service keyset error NoSuchKeyset(bytes32); /// @dev Thrown when the provided address is not the designated batch poster manager error NotBatchPosterManager(address); /// @dev Thrown when a data blob feature is attempted to be used on a chain that doesnt support it error DataBlobsNotSupported(); /// @dev Thrown when batches are posted without buffer proof, this is only allowed in a sync state or when no new delayed messages are read error DelayProofRequired(); /// @dev The DelayedAccPreimage is invalid error InvalidDelayedAccPreimage(); /// @dev Thrown when the sequencer attempts to post a batch with delay / sync proofs without delay bufferability enabled error NotDelayBufferable(); /// @dev Thrown when an init param was supplied as empty error InitParamZero(string name); /// @dev Thrown when data hashes where expected but not where present on the tx error MissingDataHashes(); /// @dev Thrown when rollup is not updated with updateRollupAddress error RollupNotChanged(); /// @dev Unsupported header flag was provided error InvalidHeaderFlag(bytes1); /// @dev SequencerInbox and Bridge are not in the same feeToken/ETH mode error NativeTokenMismatch(); /// @dev Thrown when a deprecated function is called error Deprecated(); /// @dev Thrown when any component of maxTimeVariation is over uint64 error BadMaxTimeVariation(); /// @dev Thrown when any component of bufferConfig is zero error BadBufferConfig(); /// @dev Thrown when extra gas is not a uint64 error ExtraGasNotUint64(); /// @dev Thrown when keysetBytes is too large error KeysetTooLarge();
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; uint8 constant L2_MSG = 3; uint8 constant L1MessageType_L2FundedByL1 = 7; uint8 constant L1MessageType_submitRetryableTx = 9; uint8 constant L1MessageType_ethDeposit = 12; uint8 constant L1MessageType_batchPostingReport = 13; uint8 constant L2MessageType_unsignedEOATx = 0; uint8 constant L2MessageType_unsignedContractTx = 1; uint8 constant ROLLUP_PROTOCOL_EVENT_TYPE = 8; uint8 constant INITIALIZATION_MSG_TYPE = 11;
{ "optimizer": { "enabled": true, "runs": 2000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"stored","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"BadSequencerMessageNumber","type":"error"},{"inputs":[{"internalType":"address","name":"outbox","type":"address"}],"name":"InvalidOutboxSet","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"NotContract","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"NotDelayedInbox","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"NotOutbox","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"rollup","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"NotRollupOrOwner","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"NotSequencerInbox","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"outbox","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"BridgeCallTriggered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"inbox","type":"address"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"InboxToggle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"messageIndex","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"beforeInboxAcc","type":"bytes32"},{"indexed":false,"internalType":"address","name":"inbox","type":"address"},{"indexed":false,"internalType":"uint8","name":"kind","type":"uint8"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes32","name":"messageDataHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"baseFeeL1","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"timestamp","type":"uint64"}],"name":"MessageDelivered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"outbox","type":"address"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"OutboxToggle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rollup","type":"address"}],"name":"RollupUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newSequencerInbox","type":"address"}],"name":"SequencerInboxUpdated","type":"event"},{"inputs":[],"name":"acceptFundsFromOldBridge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"activeOutbox","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allowedDelayedInboxList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"inbox","type":"address"}],"name":"allowedDelayedInboxes","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allowedOutboxList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"outbox","type":"address"}],"name":"allowedOutboxes","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"delayedInboxAccs","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delayedMessageCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"kind","type":"uint8"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"bytes32","name":"messageDataHash","type":"bytes32"}],"name":"enqueueDelayedMessage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"uint256","name":"afterDelayedMessagesRead","type":"uint256"},{"internalType":"uint256","name":"prevMessageCount","type":"uint256"},{"internalType":"uint256","name":"newMessageCount","type":"uint256"}],"name":"enqueueSequencerMessage","outputs":[{"internalType":"uint256","name":"seqMessageIndex","type":"uint256"},{"internalType":"bytes32","name":"beforeAcc","type":"bytes32"},{"internalType":"bytes32","name":"delayedAcc","type":"bytes32"},{"internalType":"bytes32","name":"acc","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeCall","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOwnable","name":"rollup_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rollup","outputs":[{"internalType":"contract IOwnable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sequencerInbox","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"sequencerInboxAccs","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sequencerMessageCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sequencerReportedSubMessageCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"inbox","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setDelayedInbox","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"outbox","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setOutbox","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sequencerInbox","type":"address"}],"name":"setSequencerInbox","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMsgCount","type":"uint256"}],"name":"setSequencerReportedSubMessageCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bytes32","name":"messageDataHash","type":"bytes32"}],"name":"submitBatchSpendingReport","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOwnable","name":"_rollup","type":"address"}],"name":"updateRollupAddress","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040523060805234801561001457600080fd5b50608051611a6e6100306000396000610f270152611a6e6000f3fe60806040526004361061017f5760003560e01c80639e5d4c49116100d6578063d5719dc21161007f578063eca067ad11610059578063eca067ad14610457578063ee35f3271461046c578063f81ff3b31461048c57600080fd5b8063d5719dc214610417578063e76f5c8d14610437578063e77145f41461023457600080fd5b8063c4d66de8116100b0578063c4d66de8146103b7578063cb23bcb5146103d7578063cee3d728146103f757600080fd5b80639e5d4c4914610337578063ab5d894314610365578063ae60bd131461037a57600080fd5b80635fca4a16116101385780638db5993b116101125780638db5993b146102cc578063919cc706146102df578063945e1147146102ff57600080fd5b80635fca4a16146102565780637a88b1071461026c57806386598a561461028c57600080fd5b8063413b35bd11610169578063413b35bd146101c857806347fb24c5146102145780634f61f8501461023657600080fd5b806284120c1461018457806316bf5579146101a8575b600080fd5b34801561019057600080fd5b506007545b6040519081526020015b60405180910390f35b3480156101b457600080fd5b506101956101c336600461175e565b6104ac565b3480156101d457600080fd5b506102046101e336600461178c565b6001600160a01b031660009081526002602052604090206001015460ff1690565b604051901515815260200161019f565b34801561022057600080fd5b5061023461022f3660046117b0565b6104cd565b005b34801561024257600080fd5b5061023461025136600461178c565b6107d3565b34801561026257600080fd5b50610195600a5481565b34801561027857600080fd5b506101956102873660046117ee565b6108ff565b34801561029857600080fd5b506102ac6102a736600461181a565b610960565b60408051948552602085019390935291830152606082015260800161019f565b6101956102da36600461184c565b610af6565b3480156102eb57600080fd5b506102346102fa36600461178c565b610b0c565b34801561030b57600080fd5b5061031f61031a36600461175e565b610c31565b6040516001600160a01b03909116815260200161019f565b34801561034357600080fd5b50610357610352366004611893565b610c5b565b60405161019f929190611940565b34801561037157600080fd5b5061031f610df1565b34801561038657600080fd5b5061020461039536600461178c565b6001600160a01b03166000908152600160208190526040909120015460ff1690565b3480156103c357600080fd5b506102346103d236600461178c565b610e34565b3480156103e357600080fd5b5060085461031f906001600160a01b031681565b34801561040357600080fd5b506102346104123660046117b0565b611058565b34801561042357600080fd5b5061019561043236600461175e565b6113c6565b34801561044357600080fd5b5061031f61045236600461175e565b6113d6565b34801561046357600080fd5b50600654610195565b34801561047857600080fd5b5060095461031f906001600160a01b031681565b34801561049857600080fd5b506102346104a736600461175e565b6113e6565b600781815481106104bc57600080fd5b600091825260209091200154905081565b6008546001600160a01b0316331461059c5760085460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d919061197c565b9050336001600160a01b0382161461059a57600854604051630739600760e01b81523360048201526001600160a01b03918216602482015290821660448201526064015b60405180910390fd5b505b6001600160a01b0382166000818152600160208181526040928390209182015492518515158152919360ff90931692917f6675ce8882cb71637de5903a193d218cc0544be9c0650cb83e0955f6aa2bf521910160405180910390a2821515811515036106085750505050565b82156106a357604080518082018252600380548252600160208084018281526001600160a01b038a166000818152928490529582209451855551938201805460ff1916941515949094179093558154908101825591527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff191690911790556107cc565b600380546106b390600190611999565b815481106106c3576106c36119ba565b6000918252602090912001548254600380546001600160a01b039093169290919081106106f2576106f26119ba565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508160000154600160006003856000015481548110610740576107406119ba565b60009182526020808320909101546001600160a01b031683528201929092526040019020556003805480610776576107766119d0565b600082815260208082208301600019908101805473ffffffffffffffffffffffffffffffffffffffff191690559092019092556001600160a01b03861682526001908190526040822091825501805460ff191690555b50505b5050565b6008546001600160a01b0316331461089d5760085460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa15801561082f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610853919061197c565b9050336001600160a01b0382161461089b57600854604051630739600760e01b81523360048201526001600160a01b0391821660248201529082166044820152606401610591565b505b6009805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527f8c1e6003ed33ca6748d4ad3dd4ecc949065c89dceb31fdf546a5289202763c6a906020015b60405180910390a150565b6009546000906001600160a01b03163314610948576040517f88f84f04000000000000000000000000000000000000000000000000000000008152336004820152602401610591565b610957600d84434248876114b5565b90505b92915050565b6009546000908190819081906001600160a01b031633146109af576040517f88f84f04000000000000000000000000000000000000000000000000000000008152336004820152602401610591565b85600a54141580156109c057508515155b80156109cd5750600a5415155b15610a1257600a546040517fe2051feb000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052604401610591565b600a85905560075493508315610a4d576007610a2f600186611999565b81548110610a3f57610a3f6119ba565b906000526020600020015492505b8615610a7e576006610a60600189611999565b81548110610a7057610a706119ba565b906000526020600020015491505b60408051602081018590529081018990526060810183905260800160408051601f198184030181529190528051602090910120600780546001810182556000919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688018190559398929750909550919350915050565b6000610b0484848434611687565b949350505050565b6008546001600160a01b03163314610bd65760085460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8c919061197c565b9050336001600160a01b03821614610bd457600854604051630739600760e01b81523360048201526001600160a01b0391821660248201529082166044820152606401610591565b505b6008805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fae1f5aa15f6ff844896347ceca2a3c24c8d3a27785efdeacd581a0a95172784a906020016108f4565b60048181548110610c4157600080fd5b6000918252602090912001546001600160a01b0316905081565b3360009081526002602052604081206001015460609060ff16610cac576040517f32ea82ab000000000000000000000000000000000000000000000000000000008152336004820152602401610591565b8215801590610cc357506001600160a01b0386163b155b15610d05576040517fb5cf5b8f0000000000000000000000000000000000000000000000000000000081526001600160a01b0387166004820152602401610591565b6005805473ffffffffffffffffffffffffffffffffffffffff1981163317909155604080516020601f87018190048102820181019092528581526001600160a01b0390921691610d73918991899189908990819084018382808284376000920191909152506116ef92505050565b6005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038581169190911790915560405192955090935088169033907f2d9d115ef3e4a606d698913b1eae831a3cdfe20d9a83d48007b0526749c3d46690610ddf908a908a908a906119e6565b60405180910390a35094509492505050565b6005546000906001600160a01b03167fffffffffffffffffffffffff00000000000000000000000000000000000000018101610e2f57600091505090565b919050565b600054610100900460ff1615808015610e545750600054600160ff909116105b80610e6e5750303b158015610e6e575060005460ff166001145b610efa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610591565b6000805460ff191660011790558015610f1d576000805461ff0019166101001790555b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610fd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610591565b600580546001600160a01b0373ffffffffffffffffffffffffffffffffffffffff1991821681179092556008805490911691841691909117905580156107cf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6008546001600160a01b031633146111225760085460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa1580156110b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d8919061197c565b9050336001600160a01b0382161461112057600854604051630739600760e01b81523360048201526001600160a01b0391821660248201529082166044820152606401610591565b505b7fffffffffffffffffffffffff00000000000000000000000000000000000000016001600160a01b0383160161118f576040517f77abed100000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610591565b6001600160a01b038216600081815260026020908152604091829020600181015492518515158152909360ff90931692917f49477e7356dbcb654ab85d7534b50126772d938130d1350e23e2540370c8dffa910160405180910390a2821515811515036111fc5750505050565b821561129857604080518082018252600480548252600160208084018281526001600160a01b038a16600081815260029093529582209451855551938201805460ff1916941515949094179093558154908101825591527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01805473ffffffffffffffffffffffffffffffffffffffff191690911790556107cc565b600480546112a890600190611999565b815481106112b8576112b86119ba565b6000918252602090912001548254600480546001600160a01b039093169290919081106112e7576112e76119ba565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508160000154600260006004856000015481548110611335576113356119ba565b60009182526020808320909101546001600160a01b03168352820192909252604001902055600480548061136b5761136b6119d0565b600082815260208082208301600019908101805473ffffffffffffffffffffffffffffffffffffffff191690559092019092556001600160a01b03861682526002905260408120908155600101805460ff1916905550505050565b600681815481106104bc57600080fd5b60038181548110610c4157600080fd5b6008546001600160a01b031633146114b05760085460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015611442573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611466919061197c565b9050336001600160a01b038216146114ae57600854604051630739600760e01b81523360048201526001600160a01b0391821660248201529082166044820152606401610591565b505b600a55565b600654604080517fff0000000000000000000000000000000000000000000000000000000000000060f88a901b166020808301919091527fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b1660218301527fffffffffffffffff00000000000000000000000000000000000000000000000060c089811b8216603585015288901b16603d830152604582018490526065820186905260858083018690528351808403909101815260a5909201909252805191012060009190600082156115b2576006611594600185611999565b815481106115a4576115a46119ba565b906000526020600020015490505b6040805160208082018490528183018590528251808303840181526060830180855281519190920120600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f015533905260ff8c1660808201526001600160a01b038b1660a082015260c0810187905260e0810188905267ffffffffffffffff89166101008201529051829185917f5e3c1311ea442664e8b1611bfabef659120ea7a0a2cfc0667700bebc69cbffe1918190036101200190a3509098975050505050505050565b3360009081526001602081905260408220015460ff166116d5576040517fb6c60ea3000000000000000000000000000000000000000000000000000000008152336004820152602401610591565b60006116e58686434248896114b5565b9695505050505050565b60006060846001600160a01b0316848460405161170c9190611a1c565b60006040518083038185875af1925050503d8060008114611749576040519150601f19603f3d011682016040523d82523d6000602084013e61174e565b606091505b5090969095509350505050565b50565b60006020828403121561177057600080fd5b5035919050565b6001600160a01b038116811461175b57600080fd5b60006020828403121561179e57600080fd5b81356117a981611777565b9392505050565b600080604083850312156117c357600080fd5b82356117ce81611777565b9150602083013580151581146117e357600080fd5b809150509250929050565b6000806040838503121561180157600080fd5b823561180c81611777565b946020939093013593505050565b6000806000806080858703121561183057600080fd5b5050823594602084013594506040840135936060013592509050565b60008060006060848603121561186157600080fd5b833560ff8116811461187257600080fd5b9250602084013561188281611777565b929592945050506040919091013590565b600080600080606085870312156118a957600080fd5b84356118b481611777565b935060208501359250604085013567ffffffffffffffff808211156118d857600080fd5b818701915087601f8301126118ec57600080fd5b8135818111156118fb57600080fd5b88602082850101111561190d57600080fd5b95989497505060200194505050565b60005b8381101561193757818101518382015260200161191f565b50506000910152565b8215158152604060208201526000825180604084015261196781606085016020870161191c565b601f01601f1916919091016060019392505050565b60006020828403121561198e57600080fd5b81516117a981611777565b8181038181111561095a57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60008251611a2e81846020870161191c565b919091019291505056fea2646970667358221220bae7eaf18c61f7d8559a1edc92b1ee8dea4400c55ec0b1b0c4df659b4984b6f764736f6c63430008110033
Deployed Bytecode
0x60806040526004361061017f5760003560e01c80639e5d4c49116100d6578063d5719dc21161007f578063eca067ad11610059578063eca067ad14610457578063ee35f3271461046c578063f81ff3b31461048c57600080fd5b8063d5719dc214610417578063e76f5c8d14610437578063e77145f41461023457600080fd5b8063c4d66de8116100b0578063c4d66de8146103b7578063cb23bcb5146103d7578063cee3d728146103f757600080fd5b80639e5d4c4914610337578063ab5d894314610365578063ae60bd131461037a57600080fd5b80635fca4a16116101385780638db5993b116101125780638db5993b146102cc578063919cc706146102df578063945e1147146102ff57600080fd5b80635fca4a16146102565780637a88b1071461026c57806386598a561461028c57600080fd5b8063413b35bd11610169578063413b35bd146101c857806347fb24c5146102145780634f61f8501461023657600080fd5b806284120c1461018457806316bf5579146101a8575b600080fd5b34801561019057600080fd5b506007545b6040519081526020015b60405180910390f35b3480156101b457600080fd5b506101956101c336600461175e565b6104ac565b3480156101d457600080fd5b506102046101e336600461178c565b6001600160a01b031660009081526002602052604090206001015460ff1690565b604051901515815260200161019f565b34801561022057600080fd5b5061023461022f3660046117b0565b6104cd565b005b34801561024257600080fd5b5061023461025136600461178c565b6107d3565b34801561026257600080fd5b50610195600a5481565b34801561027857600080fd5b506101956102873660046117ee565b6108ff565b34801561029857600080fd5b506102ac6102a736600461181a565b610960565b60408051948552602085019390935291830152606082015260800161019f565b6101956102da36600461184c565b610af6565b3480156102eb57600080fd5b506102346102fa36600461178c565b610b0c565b34801561030b57600080fd5b5061031f61031a36600461175e565b610c31565b6040516001600160a01b03909116815260200161019f565b34801561034357600080fd5b50610357610352366004611893565b610c5b565b60405161019f929190611940565b34801561037157600080fd5b5061031f610df1565b34801561038657600080fd5b5061020461039536600461178c565b6001600160a01b03166000908152600160208190526040909120015460ff1690565b3480156103c357600080fd5b506102346103d236600461178c565b610e34565b3480156103e357600080fd5b5060085461031f906001600160a01b031681565b34801561040357600080fd5b506102346104123660046117b0565b611058565b34801561042357600080fd5b5061019561043236600461175e565b6113c6565b34801561044357600080fd5b5061031f61045236600461175e565b6113d6565b34801561046357600080fd5b50600654610195565b34801561047857600080fd5b5060095461031f906001600160a01b031681565b34801561049857600080fd5b506102346104a736600461175e565b6113e6565b600781815481106104bc57600080fd5b600091825260209091200154905081565b6008546001600160a01b0316331461059c5760085460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d919061197c565b9050336001600160a01b0382161461059a57600854604051630739600760e01b81523360048201526001600160a01b03918216602482015290821660448201526064015b60405180910390fd5b505b6001600160a01b0382166000818152600160208181526040928390209182015492518515158152919360ff90931692917f6675ce8882cb71637de5903a193d218cc0544be9c0650cb83e0955f6aa2bf521910160405180910390a2821515811515036106085750505050565b82156106a357604080518082018252600380548252600160208084018281526001600160a01b038a166000818152928490529582209451855551938201805460ff1916941515949094179093558154908101825591527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff191690911790556107cc565b600380546106b390600190611999565b815481106106c3576106c36119ba565b6000918252602090912001548254600380546001600160a01b039093169290919081106106f2576106f26119ba565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508160000154600160006003856000015481548110610740576107406119ba565b60009182526020808320909101546001600160a01b031683528201929092526040019020556003805480610776576107766119d0565b600082815260208082208301600019908101805473ffffffffffffffffffffffffffffffffffffffff191690559092019092556001600160a01b03861682526001908190526040822091825501805460ff191690555b50505b5050565b6008546001600160a01b0316331461089d5760085460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa15801561082f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610853919061197c565b9050336001600160a01b0382161461089b57600854604051630739600760e01b81523360048201526001600160a01b0391821660248201529082166044820152606401610591565b505b6009805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527f8c1e6003ed33ca6748d4ad3dd4ecc949065c89dceb31fdf546a5289202763c6a906020015b60405180910390a150565b6009546000906001600160a01b03163314610948576040517f88f84f04000000000000000000000000000000000000000000000000000000008152336004820152602401610591565b610957600d84434248876114b5565b90505b92915050565b6009546000908190819081906001600160a01b031633146109af576040517f88f84f04000000000000000000000000000000000000000000000000000000008152336004820152602401610591565b85600a54141580156109c057508515155b80156109cd5750600a5415155b15610a1257600a546040517fe2051feb000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052604401610591565b600a85905560075493508315610a4d576007610a2f600186611999565b81548110610a3f57610a3f6119ba565b906000526020600020015492505b8615610a7e576006610a60600189611999565b81548110610a7057610a706119ba565b906000526020600020015491505b60408051602081018590529081018990526060810183905260800160408051601f198184030181529190528051602090910120600780546001810182556000919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688018190559398929750909550919350915050565b6000610b0484848434611687565b949350505050565b6008546001600160a01b03163314610bd65760085460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8c919061197c565b9050336001600160a01b03821614610bd457600854604051630739600760e01b81523360048201526001600160a01b0391821660248201529082166044820152606401610591565b505b6008805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fae1f5aa15f6ff844896347ceca2a3c24c8d3a27785efdeacd581a0a95172784a906020016108f4565b60048181548110610c4157600080fd5b6000918252602090912001546001600160a01b0316905081565b3360009081526002602052604081206001015460609060ff16610cac576040517f32ea82ab000000000000000000000000000000000000000000000000000000008152336004820152602401610591565b8215801590610cc357506001600160a01b0386163b155b15610d05576040517fb5cf5b8f0000000000000000000000000000000000000000000000000000000081526001600160a01b0387166004820152602401610591565b6005805473ffffffffffffffffffffffffffffffffffffffff1981163317909155604080516020601f87018190048102820181019092528581526001600160a01b0390921691610d73918991899189908990819084018382808284376000920191909152506116ef92505050565b6005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038581169190911790915560405192955090935088169033907f2d9d115ef3e4a606d698913b1eae831a3cdfe20d9a83d48007b0526749c3d46690610ddf908a908a908a906119e6565b60405180910390a35094509492505050565b6005546000906001600160a01b03167fffffffffffffffffffffffff00000000000000000000000000000000000000018101610e2f57600091505090565b919050565b600054610100900460ff1615808015610e545750600054600160ff909116105b80610e6e5750303b158015610e6e575060005460ff166001145b610efa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610591565b6000805460ff191660011790558015610f1d576000805461ff0019166101001790555b6001600160a01b037f000000000000000000000000ed26e46f38957763f83f2c45f6fb6702cfebc7d8163003610fd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610591565b600580546001600160a01b0373ffffffffffffffffffffffffffffffffffffffff1991821681179092556008805490911691841691909117905580156107cf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6008546001600160a01b031633146111225760085460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa1580156110b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d8919061197c565b9050336001600160a01b0382161461112057600854604051630739600760e01b81523360048201526001600160a01b0391821660248201529082166044820152606401610591565b505b7fffffffffffffffffffffffff00000000000000000000000000000000000000016001600160a01b0383160161118f576040517f77abed100000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610591565b6001600160a01b038216600081815260026020908152604091829020600181015492518515158152909360ff90931692917f49477e7356dbcb654ab85d7534b50126772d938130d1350e23e2540370c8dffa910160405180910390a2821515811515036111fc5750505050565b821561129857604080518082018252600480548252600160208084018281526001600160a01b038a16600081815260029093529582209451855551938201805460ff1916941515949094179093558154908101825591527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01805473ffffffffffffffffffffffffffffffffffffffff191690911790556107cc565b600480546112a890600190611999565b815481106112b8576112b86119ba565b6000918252602090912001548254600480546001600160a01b039093169290919081106112e7576112e76119ba565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508160000154600260006004856000015481548110611335576113356119ba565b60009182526020808320909101546001600160a01b03168352820192909252604001902055600480548061136b5761136b6119d0565b600082815260208082208301600019908101805473ffffffffffffffffffffffffffffffffffffffff191690559092019092556001600160a01b03861682526002905260408120908155600101805460ff1916905550505050565b600681815481106104bc57600080fd5b60038181548110610c4157600080fd5b6008546001600160a01b031633146114b05760085460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015611442573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611466919061197c565b9050336001600160a01b038216146114ae57600854604051630739600760e01b81523360048201526001600160a01b0391821660248201529082166044820152606401610591565b505b600a55565b600654604080517fff0000000000000000000000000000000000000000000000000000000000000060f88a901b166020808301919091527fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b1660218301527fffffffffffffffff00000000000000000000000000000000000000000000000060c089811b8216603585015288901b16603d830152604582018490526065820186905260858083018690528351808403909101815260a5909201909252805191012060009190600082156115b2576006611594600185611999565b815481106115a4576115a46119ba565b906000526020600020015490505b6040805160208082018490528183018590528251808303840181526060830180855281519190920120600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f015533905260ff8c1660808201526001600160a01b038b1660a082015260c0810187905260e0810188905267ffffffffffffffff89166101008201529051829185917f5e3c1311ea442664e8b1611bfabef659120ea7a0a2cfc0667700bebc69cbffe1918190036101200190a3509098975050505050505050565b3360009081526001602081905260408220015460ff166116d5576040517fb6c60ea3000000000000000000000000000000000000000000000000000000008152336004820152602401610591565b60006116e58686434248896114b5565b9695505050505050565b60006060846001600160a01b0316848460405161170c9190611a1c565b60006040518083038185875af1925050503d8060008114611749576040519150601f19603f3d011682016040523d82523d6000602084013e61174e565b606091505b5090969095509350505050565b50565b60006020828403121561177057600080fd5b5035919050565b6001600160a01b038116811461175b57600080fd5b60006020828403121561179e57600080fd5b81356117a981611777565b9392505050565b600080604083850312156117c357600080fd5b82356117ce81611777565b9150602083013580151581146117e357600080fd5b809150509250929050565b6000806040838503121561180157600080fd5b823561180c81611777565b946020939093013593505050565b6000806000806080858703121561183057600080fd5b5050823594602084013594506040840135936060013592509050565b60008060006060848603121561186157600080fd5b833560ff8116811461187257600080fd5b9250602084013561188281611777565b929592945050506040919091013590565b600080600080606085870312156118a957600080fd5b84356118b481611777565b935060208501359250604085013567ffffffffffffffff808211156118d857600080fd5b818701915087601f8301126118ec57600080fd5b8135818111156118fb57600080fd5b88602082850101111561190d57600080fd5b95989497505060200194505050565b60005b8381101561193757818101518382015260200161191f565b50506000910152565b8215158152604060208201526000825180604084015261196781606085016020870161191c565b601f01601f1916919091016060019392505050565b60006020828403121561198e57600080fd5b81516117a981611777565b8181038181111561095a57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60008251611a2e81846020870161191c565b919091019291505056fea2646970667358221220bae7eaf18c61f7d8559a1edc92b1ee8dea4400c55ec0b1b0c4df659b4984b6f764736f6c63430008110033
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.