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
Loading...
Loading
Contract Name:
Outbox
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 100 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 "./AbsOutbox.sol";
contract Outbox is AbsOutbox {
/// @inheritdoc AbsOutbox
function _defaultContextAmount() internal pure override returns (uint256) {
// In ETH-based chains withdrawal amount can be read from msg.value. For that reason
// amount slot in context will never be accessed and it has 0 default value
return 0;
}
/// @inheritdoc AbsOutbox
function _getAmountToUnlock(uint256 value) internal pure override returns (uint256) {
return value;
}
/// @inheritdoc AbsOutbox
function _amountToSetInContext(uint256) internal pure override returns (uint256) {
// In ETH-based chains withdrawal amount can be read from msg.value. For that reason
// amount slot in context will never be accessed, we keep it as 0 all the time
return 0;
}
}// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/nitro/blob/master/LICENSE
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.4;
import {
AlreadyInit,
NotRollup,
ProofTooLong,
PathNotMinimal,
UnknownRoot,
AlreadySpent,
BridgeCallFailed,
HadZeroInit,
BadPostUpgradeInit,
RollupNotChanged
} from "../libraries/Error.sol";
import "./IBridge.sol";
import "./IOutbox.sol";
import "../libraries/MerkleLib.sol";
import "../libraries/DelegateCallAware.sol";
/// @dev this error is thrown since certain functions are only expected to be used in simulations, not in actual txs
error SimulationOnlyEntrypoint();
abstract contract AbsOutbox is DelegateCallAware, IOutbox {
address public rollup; // the rollup contract
IBridge public bridge; // the bridge contract
mapping(uint256 => bytes32) public spent; // packed spent bitmap
mapping(bytes32 => bytes32) public roots; // maps root hashes => L2 block hash
// we're packing this struct into 4 storage slots
// 1st slot: timestamp, l2Block (128 bits each, max ~3.4*10^38)
// 2nd slot: outputId (256 bits)
// 3rd slot: l1Block (96 bits, max ~7.9*10^28), sender (address 160 bits)
// 4th slot: withdrawalAmount (256 bits)
struct L2ToL1Context {
uint128 l2Block;
uint128 timestamp;
bytes32 outputId;
address sender;
uint96 l1Block;
uint256 withdrawalAmount;
}
// Note, these variables are set and then wiped during a single transaction.
// Therefore their values don't need to be maintained, and their slots will
// hold default values (which are interpreted as empty values) outside of transactions
L2ToL1Context internal context;
// default context values to be used in storage instead of zero, to save on storage refunds
// it is assumed that arb-os never assigns these values to a valid leaf to be redeemed
uint128 private constant L2BLOCK_DEFAULT_CONTEXT = type(uint128).max;
uint96 private constant L1BLOCK_DEFAULT_CONTEXT = type(uint96).max;
uint128 private constant TIMESTAMP_DEFAULT_CONTEXT = type(uint128).max;
bytes32 private constant OUTPUTID_DEFAULT_CONTEXT = bytes32(type(uint256).max);
address private constant SENDER_DEFAULT_CONTEXT = address(type(uint160).max);
uint128 public constant OUTBOX_VERSION = 2;
function initialize(IBridge _bridge) external onlyDelegated {
if (address(_bridge) == address(0)) revert HadZeroInit();
if (address(bridge) != address(0)) revert AlreadyInit();
// address zero is returned if no context is set, but the values used in storage
// are non-zero to save users some gas (as storage refunds are usually maxed out)
// EIP-1153 would help here
context = L2ToL1Context({
l2Block: L2BLOCK_DEFAULT_CONTEXT,
l1Block: L1BLOCK_DEFAULT_CONTEXT,
timestamp: TIMESTAMP_DEFAULT_CONTEXT,
outputId: OUTPUTID_DEFAULT_CONTEXT,
sender: SENDER_DEFAULT_CONTEXT,
withdrawalAmount: _defaultContextAmount()
});
bridge = _bridge;
rollup = address(_bridge.rollup());
}
function postUpgradeInit() external onlyDelegated onlyProxyOwner {
// prevent postUpgradeInit within a withdrawal
if (context.l2Block != L2BLOCK_DEFAULT_CONTEXT) revert BadPostUpgradeInit();
context = L2ToL1Context({
l2Block: L2BLOCK_DEFAULT_CONTEXT,
l1Block: L1BLOCK_DEFAULT_CONTEXT,
timestamp: TIMESTAMP_DEFAULT_CONTEXT,
outputId: OUTPUTID_DEFAULT_CONTEXT,
sender: SENDER_DEFAULT_CONTEXT,
withdrawalAmount: _defaultContextAmount()
});
}
/// @notice Allows the rollup owner to sync the rollup address
function updateRollupAddress() external {
if (msg.sender != IOwnable(rollup).owner())
revert NotOwner(msg.sender, IOwnable(rollup).owner());
address newRollup = address(bridge.rollup());
if (rollup == newRollup) revert RollupNotChanged();
rollup = newRollup;
}
function updateSendRoot(bytes32 root, bytes32 l2BlockHash) external {
if (msg.sender != rollup) revert NotRollup(msg.sender, rollup);
roots[root] = l2BlockHash;
emit SendRootUpdated(root, l2BlockHash);
}
/// @inheritdoc IOutbox
function l2ToL1Sender() external view returns (address) {
address sender = context.sender;
// we don't return the default context value to avoid a breaking change in the API
if (sender == SENDER_DEFAULT_CONTEXT) return address(0);
return sender;
}
/// @inheritdoc IOutbox
function l2ToL1Block() external view returns (uint256) {
uint128 l2Block = context.l2Block;
// we don't return the default context value to avoid a breaking change in the API
if (l2Block == L2BLOCK_DEFAULT_CONTEXT) return uint256(0);
return uint256(l2Block);
}
/// @inheritdoc IOutbox
function l2ToL1EthBlock() external view returns (uint256) {
uint96 l1Block = context.l1Block;
// we don't return the default context value to avoid a breaking change in the API
if (l1Block == L1BLOCK_DEFAULT_CONTEXT) return uint256(0);
return uint256(l1Block);
}
/// @inheritdoc IOutbox
function l2ToL1Timestamp() external view returns (uint256) {
uint128 timestamp = context.timestamp;
// we don't return the default context value to avoid a breaking change in the API
if (timestamp == TIMESTAMP_DEFAULT_CONTEXT) return uint256(0);
return uint256(timestamp);
}
/// @notice batch number is deprecated and now always returns 0
function l2ToL1BatchNum() external pure returns (uint256) {
return 0;
}
/// @inheritdoc IOutbox
function l2ToL1OutputId() external view returns (bytes32) {
bytes32 outputId = context.outputId;
// we don't return the default context value to avoid a breaking change in the API
if (outputId == OUTPUTID_DEFAULT_CONTEXT) return bytes32(0);
return outputId;
}
/// @inheritdoc IOutbox
function executeTransaction(
bytes32[] calldata proof,
uint256 index,
address l2Sender,
address to,
uint256 l2Block,
uint256 l1Block,
uint256 l2Timestamp,
uint256 value,
bytes calldata data
) external {
bytes32 userTx = calculateItemHash(
l2Sender,
to,
l2Block,
l1Block,
l2Timestamp,
value,
data
);
recordOutputAsSpent(proof, index, userTx);
executeTransactionImpl(index, l2Sender, to, l2Block, l1Block, l2Timestamp, value, data);
}
/// @inheritdoc IOutbox
function executeTransactionSimulation(
uint256 index,
address l2Sender,
address to,
uint256 l2Block,
uint256 l1Block,
uint256 l2Timestamp,
uint256 value,
bytes calldata data
) external {
if (msg.sender != address(0)) revert SimulationOnlyEntrypoint();
executeTransactionImpl(index, l2Sender, to, l2Block, l1Block, l2Timestamp, value, data);
}
function executeTransactionImpl(
uint256 outputId,
address l2Sender,
address to,
uint256 l2Block,
uint256 l1Block,
uint256 l2Timestamp,
uint256 value,
bytes calldata data
) internal {
emit OutBoxTransactionExecuted(to, l2Sender, 0, outputId);
// get amount to unlock based on provided value. It might differ in case
// of native token which uses number of decimals different than 18
uint256 amountToUnlock = _getAmountToUnlock(value);
// we temporarily store the previous values so the outbox can naturally
// unwind itself when there are nested calls to `executeTransaction`
L2ToL1Context memory prevContext = context;
context = L2ToL1Context({
sender: l2Sender,
l2Block: uint128(l2Block),
l1Block: uint96(l1Block),
timestamp: uint128(l2Timestamp),
outputId: bytes32(outputId),
withdrawalAmount: _amountToSetInContext(amountToUnlock)
});
// set and reset vars around execution so they remain valid during call
executeBridgeCall(to, amountToUnlock, data);
context = prevContext;
}
function _calcSpentIndexOffset(uint256 index)
internal
view
returns (
uint256,
uint256,
bytes32
)
{
uint256 spentIndex = index / 255; // Note: Reserves the MSB.
uint256 bitOffset = index % 255;
bytes32 replay = spent[spentIndex];
return (spentIndex, bitOffset, replay);
}
function _isSpent(uint256 bitOffset, bytes32 replay) internal pure returns (bool) {
return ((replay >> bitOffset) & bytes32(uint256(1))) != bytes32(0);
}
/// @inheritdoc IOutbox
function isSpent(uint256 index) external view returns (bool) {
(, uint256 bitOffset, bytes32 replay) = _calcSpentIndexOffset(index);
return _isSpent(bitOffset, replay);
}
function recordOutputAsSpent(
bytes32[] memory proof,
uint256 index,
bytes32 item
) internal {
if (proof.length >= 256) revert ProofTooLong(proof.length);
if (index >= 2**proof.length) revert PathNotMinimal(index, 2**proof.length);
// Hash the leaf an extra time to prove it's a leaf
bytes32 calcRoot = calculateMerkleRoot(proof, index, item);
if (roots[calcRoot] == bytes32(0)) revert UnknownRoot(calcRoot);
(uint256 spentIndex, uint256 bitOffset, bytes32 replay) = _calcSpentIndexOffset(index);
if (_isSpent(bitOffset, replay)) revert AlreadySpent(index);
spent[spentIndex] = (replay | bytes32(1 << bitOffset));
}
function executeBridgeCall(
address to,
uint256 value,
bytes memory data
) internal {
(bool success, bytes memory returndata) = bridge.executeCall(to, value, data);
if (!success) {
if (returndata.length > 0) {
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert BridgeCallFailed();
}
}
}
function calculateItemHash(
address l2Sender,
address to,
uint256 l2Block,
uint256 l1Block,
uint256 l2Timestamp,
uint256 value,
bytes calldata data
) public pure returns (bytes32) {
return
keccak256(abi.encodePacked(l2Sender, to, l2Block, l1Block, l2Timestamp, value, data));
}
function calculateMerkleRoot(
bytes32[] memory proof,
uint256 path,
bytes32 item
) public pure returns (bytes32) {
return MerkleLib.calculateRoot(proof, path, keccak256(abi.encodePacked(item)));
}
/// @notice default value to be used for 'amount' field in L2ToL1Context outside of transaction execution.
/// @return default 'amount' in case of ERC20-based rollup is type(uint256).max, or 0 in case of ETH-based rollup
function _defaultContextAmount() internal pure virtual returns (uint256);
/// @notice based on provided value, get amount of ETH/token to unlock. In case of ETH-based rollup this amount
/// will always equal the provided value. In case of ERC20-based rollup, amount will be re-adjusted to
/// reflect the number of decimals used by native token, in case it is different than 18.
function _getAmountToUnlock(uint256 value) internal view virtual returns (uint256);
/// @notice value to be set for 'amount' field in L2ToL1Context during L2 to L1 transaction execution.
/// In case of ERC20-based rollup this is the amount of native token being withdrawn. In case of standard ETH-based
/// rollup this amount shall always be 0, because amount of ETH being withdrawn can be read from msg.value.
/// @return amount of native token being withdrawn in case of ERC20-based rollup, or 0 in case of ETH-based rollup
function _amountToSetInContext(uint256 value) internal pure 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[42] 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 "./IBridge.sol";
interface IOutbox {
event SendRootUpdated(bytes32 indexed outputRoot, bytes32 indexed l2BlockHash);
event OutBoxTransactionExecuted(
address indexed to,
address indexed l2Sender,
uint256 indexed zero,
uint256 transactionIndex
);
function initialize(IBridge _bridge) external;
function rollup() external view returns (address); // the rollup contract
function bridge() external view returns (IBridge); // the bridge contract
function spent(uint256) external view returns (bytes32); // packed spent bitmap
function roots(bytes32) external view returns (bytes32); // maps root hashes => L2 block hash
// solhint-disable-next-line func-name-mixedcase
function OUTBOX_VERSION() external view returns (uint128); // the outbox version
function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external;
function updateRollupAddress() external;
/// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account
/// When the return value is zero, that means this is a system message
/// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies
function l2ToL1Sender() external view returns (address);
/// @return l2Block return L2 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active
function l2ToL1Block() external view returns (uint256);
/// @return l1Block return L1 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active
function l2ToL1EthBlock() external view returns (uint256);
/// @return timestamp return L2 timestamp when the L2 tx was initiated or 0 if no L2 to L1 transaction is active
function l2ToL1Timestamp() external view returns (uint256);
/// @return outputId returns the unique output identifier of the L2 to L1 tx or 0 if no L2 to L1 transaction is active
function l2ToL1OutputId() external view returns (bytes32);
/**
* @notice Executes a messages in an Outbox entry.
* @dev Reverts if dispute period hasn't expired, since the outbox entry
* is only created once the rollup confirms the respective assertion.
* @dev it is not possible to execute any L2-to-L1 transaction which contains data
* to a contract address without any code (as enforced by the Bridge contract).
* @param proof Merkle proof of message inclusion in send root
* @param index Merkle path to message
* @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1)
* @param to destination address for L1 contract call
* @param l2Block l2 block number at which sendTxToL1 call was made
* @param l1Block l1 block number at which sendTxToL1 call was made
* @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made
* @param value wei in L1 message
* @param data abi-encoded L1 message data
*/
function executeTransaction(
bytes32[] calldata proof,
uint256 index,
address l2Sender,
address to,
uint256 l2Block,
uint256 l1Block,
uint256 l2Timestamp,
uint256 value,
bytes calldata data
) external;
/**
* @dev function used to simulate the result of a particular function call from the outbox
* it is useful for things such as gas estimates. This function includes all costs except for
* proof validation (which can be considered offchain as a somewhat of a fixed cost - it's
* not really a fixed cost, but can be treated as so with a fixed overhead for gas estimation).
* We can't include the cost of proof validation since this is intended to be used to simulate txs
* that are included in yet-to-be confirmed merkle roots. The simulation entrypoint could instead pretend
* to confirm a pending merkle root, but that would be less practical for integrating with tooling.
* It is only possible to trigger it when the msg sender is address zero, which should be impossible
* unless under simulation in an eth_call or eth_estimateGas
*/
function executeTransactionSimulation(
uint256 index,
address l2Sender,
address to,
uint256 l2Block,
uint256 l1Block,
uint256 l2Timestamp,
uint256 value,
bytes calldata data
) external;
/**
* @param index Merkle path to message
* @return true if the message has been spent
*/
function isSpent(uint256 index) external view returns (bool);
function calculateItemHash(
address l2Sender,
address to,
uint256 l2Block,
uint256 l1Block,
uint256 l2Timestamp,
uint256 value,
bytes calldata data
) external pure returns (bytes32);
function calculateMerkleRoot(
bytes32[] memory proof,
uint256 path,
bytes32 item
) external pure returns (bytes32);
/**
* @dev function to be called one time during the outbox upgrade process
* this is used to fix the storage slots
*/
function postUpgradeInit() 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
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 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 Force include can only read messages more seconds old than the delay period
error ForceIncludeTimeTooSoon();
/// @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 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();// 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 {MerkleProofTooLong} from "./Error.sol";
library MerkleLib {
function generateRoot(bytes32[] memory _hashes) internal pure returns (bytes32) {
bytes32[] memory prevLayer = _hashes;
while (prevLayer.length > 1) {
bytes32[] memory nextLayer = new bytes32[]((prevLayer.length + 1) / 2);
for (uint256 i = 0; i < nextLayer.length; i++) {
if (2 * i + 1 < prevLayer.length) {
nextLayer[i] = keccak256(
abi.encodePacked(prevLayer[2 * i], prevLayer[2 * i + 1])
);
} else {
nextLayer[i] = prevLayer[2 * i];
}
}
prevLayer = nextLayer;
}
return prevLayer[0];
}
function calculateRoot(
bytes32[] memory nodes,
uint256 route,
bytes32 item
) internal pure returns (bytes32) {
uint256 proofItems = nodes.length;
if (proofItems > 256) revert MerkleProofTooLong(proofItems, 256);
bytes32 h = item;
for (uint256 i = 0; i < proofItems; ) {
bytes32 node = nodes[i];
if ((route & (1 << i)) == 0) {
assembly {
mstore(0x00, h)
mstore(0x20, node)
h := keccak256(0x00, 0x40)
}
} else {
assembly {
mstore(0x00, node)
mstore(0x20, h)
h := keccak256(0x00, 0x40)
}
}
unchecked {
++i;
}
}
return h;
}
}{
"optimizer": {
"enabled": true,
"runs": 100
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract ABI
API[{"inputs":[],"name":"AlreadyInit","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"AlreadySpent","type":"error"},{"inputs":[],"name":"BadPostUpgradeInit","type":"error"},{"inputs":[],"name":"BridgeCallFailed","type":"error"},{"inputs":[],"name":"HadZeroInit","type":"error"},{"inputs":[{"internalType":"uint256","name":"actualLength","type":"uint256"},{"internalType":"uint256","name":"maxProofLength","type":"uint256"}],"name":"MerkleProofTooLong","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"NotOwner","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"rollup","type":"address"}],"name":"NotRollup","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"maxIndex","type":"uint256"}],"name":"PathNotMinimal","type":"error"},{"inputs":[{"internalType":"uint256","name":"proofLength","type":"uint256"}],"name":"ProofTooLong","type":"error"},{"inputs":[],"name":"RollupNotChanged","type":"error"},{"inputs":[],"name":"SimulationOnlyEntrypoint","type":"error"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"UnknownRoot","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"l2Sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"zero","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"transactionIndex","type":"uint256"}],"name":"OutBoxTransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"outputRoot","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"l2BlockHash","type":"bytes32"}],"name":"SendRootUpdated","type":"event"},{"inputs":[],"name":"OUTBOX_VERSION","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract IBridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"l2Sender","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"l2Block","type":"uint256"},{"internalType":"uint256","name":"l1Block","type":"uint256"},{"internalType":"uint256","name":"l2Timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"calculateItemHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"path","type":"uint256"},{"internalType":"bytes32","name":"item","type":"bytes32"}],"name":"calculateMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"l2Sender","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"l2Block","type":"uint256"},{"internalType":"uint256","name":"l1Block","type":"uint256"},{"internalType":"uint256","name":"l2Timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"l2Sender","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"l2Block","type":"uint256"},{"internalType":"uint256","name":"l1Block","type":"uint256"},{"internalType":"uint256","name":"l2Timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeTransactionSimulation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IBridge","name":"_bridge","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"isSpent","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1BatchNum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"l2ToL1Block","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1EthBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1OutputId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1Sender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1Timestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"postUpgradeInit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rollup","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"roots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spent","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateRollupAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"bytes32","name":"l2BlockHash","type":"bytes32"}],"name":"updateSendRoot","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523060805234801561001457600080fd5b506080516116d36100376000396000818161067a015261088501526116d36000f3fe608060405234801561001057600080fd5b506004361061012b5760003560e01c806395fcea78116100ad578063c4d66de811610071578063c4d66de81461023e578063c75184df14610251578063cb23bcb514610271578063d5b5cc2314610284578063e78cea92146102a457600080fd5b806395fcea78146101e85780639f0c04bf146101f0578063a04cee6014610203578063ae6dead714610216578063b0f305371461023657600080fd5b80635a129efe116100f45780635a129efe1461018d5780636ae71f12146101b057806372f2a8c7146101b857806380648b02146101c05780638515bc6a146101e057600080fd5b80627436d31461013057806308635a9514610156578063119852711461016b578063288e5b10146101725780634654779014610185575b600080fd5b61014361013e366004610fa9565b6102b7565b6040519081526020015b60405180910390f35b6101696101643660046110c9565b6102f4565b005b6000610143565b6101696101803660046111bd565b610367565b6101436103a2565b6101a061019b366004611258565b6103d1565b604051901515815260200161014d565b6101696103ee565b6101436105fb565b6101c8610618565b6040516001600160a01b03909116815260200161014d565b610143610639565b61016961066f565b6101436101fe366004611271565b610792565b6101696102113660046112ff565b6107d7565b610143610224366004611258565b60036020526000908152604090205481565b610143610852565b61016961024c366004611321565b61087a565b610259600281565b6040516001600160801b03909116815260200161014d565b6000546101c8906001600160a01b031681565b610143610292366004611258565b60026020526000908152604090205481565b6001546101c8906001600160a01b031681565b60006102ec8484846040516020016102d191815260200190565b60405160208183030381529060405280519060200120610a19565b949350505050565b60006103068989898989898989610792565b90506103488c8c808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508e9250859150610abc9050565b6103598a8a8a8a8a8a8a8a8a610bc5565b505050505050505050505050565b331561038657604051630e13b69d60e01b815260040160405180910390fd5b610397898989898989898989610bc5565b505050505050505050565b6004546000906001600160801b03908116908114156103c357600091505090565b6001600160801b0316919050565b60008060006103df84610e4f565b92509250506102ec8282610e8c565b60008054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561043a57600080fd5b505afa15801561044e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104729190611345565b6001600160a01b0316336001600160a01b03161461052a5760005460408051638da5cb5b60e01b8152905133926001600160a01b031691638da5cb5b916004808301926020929190829003018186803b1580156104ce57600080fd5b505afa1580156104e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105069190611345565b604051631194af8760e11b8152600401610521929190611362565b60405180910390fd5b6001546040805163cb23bcb560e01b815290516000926001600160a01b03169163cb23bcb5916004808301926020929190829003018186803b15801561056f57600080fd5b505afa158015610583573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a79190611345565b6000549091506001600160a01b03808316911614156105d95760405163d054909f60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60055460009060001981141561061357506000919050565b919050565b6006546000906001600160a01b039081169081141561061357600091505090565b6006546000906001600160601b03600160a01b90910481169081141561066157600091505090565b6001600160601b0316919050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614156106b85760405162461bcd60e51b81526004016105219061137c565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038054336001600160a01b03821614610708573381604051631194af8760e11b8152600401610521929190611362565b6004546001600160801b03908116146107345760405163d0afb66160e01b815260040160405180910390fd5b50506040805160c0810182526001600160801b0380825260208201526000199181018290526001600160a01b0360608201526001600160601b036080820152600060a090910181905260048290556005829055600691909155600755565b600088888888888888886040516020016107b39897969594939291906113c8565b60405160208183030381529060405280519060200120905098975050505050505050565b6000546001600160a01b0316331461081357600054604051630e4cf1bf60e21b81526105219133916001600160a01b0390911690600401611362565b60008281526003602052604080822083905551829184917fb4df3847300f076a369cd76d2314b470a1194d9e8a6bb97f1860aee88a5f67489190a35050565b6004546000906001600160801b03600160801b9091048116908114156103c357600091505090565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614156108c35760405162461bcd60e51b81526004016105219061137c565b6001600160a01b0381166108ea57604051631ad0f74360e01b815260040160405180910390fd5b6001546001600160a01b03161561091457604051633bcd329760e21b815260040160405180910390fd5b6040805160c0810182526001600160801b038082526020808301919091526000198284018190526001600160a01b03606084018190526001600160601b036080850152600060a090940184905260048281556005839055600692909255600793909355600180546001600160a01b0319169386169384179055835163cb23bcb560e01b81529351929363cb23bcb59381830193929091829003018186803b1580156109be57600080fd5b505afa1580156109d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f69190611345565b600080546001600160a01b0319166001600160a01b039290921691909117905550565b8251600090610100811115610a4c57604051637ed6198f60e11b8152600481018290526101006024820152604401610521565b8260005b82811015610ab2576000878281518110610a6c57610a6c61141c565b60200260200101519050816001901b871660001415610a9957826000528060205260406000209250610aa9565b8060005282602052604060002092505b50600101610a50565b5095945050505050565b610100835110610ae457825160405163ab6a068360e01b815260040161052191815260200190565b8251610af190600261152c565b8210610b28578183516002610b06919061152c565b604051630b8a724b60e01b815260048101929092526024820152604401610521565b6000610b358484846102b7565b600081815260036020526040902054909150610b67576040516310e61af960e31b815260048101829052602401610521565b6000806000610b7586610e4f565b925092509250610b858282610e8c565b15610ba657604051639715b8d360e01b815260048101879052602401610521565b600092835260026020526040909220600190911b909117905550505050565b6000886001600160a01b0316886001600160a01b03167f20af7f3bbfe38132b8900ae295cd9c8d1914be7052d061a511f3f728dab189648c604051610c0c91815260200190565b60405180910390a46000839050600060046040518060c00160405290816000820160009054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020016000820160109054906101000a90046001600160801b03166001600160801b03166001600160801b03168152602001600182015481526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016002820160149054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160038201548152505090506040518060c00160405280896001600160801b03168152602001876001600160801b031681526020018c60001b81526020018b6001600160a01b03168152602001886001600160601b03168152602001610d52600090565b905280516020808301516001600160801b03908116600160801b02921691909117600455604080830151600555606083015160808401516001600160601b0316600160a01b026001600160a01b039091161760065560a0909201516007558151601f8601829004820281018201909252848252610dee918b918591908890889081908401838280828437600092019190915250610e9b92505050565b805160208201516001600160801b03908116600160801b029116176004556040810151600555606081015160808201516001600160601b0316600160a01b026001600160a01b039091161760065560a0015160075550505050505050505050565b6000808080610e5f60ff8661154e565b90506000610e6e60ff87611562565b60008381526002602052604090205492979096509194509092505050565b80821c60011615155b92915050565b600154604051639e5d4c4960e01b815260009182916001600160a01b0390911690639e5d4c4990610ed4908890889088906004016115a6565b600060405180830381600087803b158015610eee57600080fd5b505af1158015610f02573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f2a91908101906115ef565b9150915081610f5c57805115610f435780518082602001fd5b604051631bb7daad60e11b815260040160405180910390fd5b5050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715610fa157610fa1610f63565b604052919050565b600080600060608486031215610fbe57600080fd5b83356001600160401b0380821115610fd557600080fd5b818601915086601f830112610fe957600080fd5b8135602082821115610ffd57610ffd610f63565b8160051b925061100e818401610f79565b828152928401810192818101908a85111561102857600080fd5b948201945b848610156110465785358252948201949082019061102d565b9a918901359950506040909701359695505050505050565b6001600160a01b038116811461107357600080fd5b50565b80356106138161105e565b60008083601f84011261109357600080fd5b5081356001600160401b038111156110aa57600080fd5b6020830191508360208285010111156110c257600080fd5b9250929050565b60008060008060008060008060008060006101208c8e0312156110eb57600080fd5b8b356001600160401b038082111561110257600080fd5b818e0191508e601f83011261111657600080fd5b81358181111561112557600080fd5b8f60208260051b850101111561113a57600080fd5b60208381019e50909c508e01359a5061115560408f01611076565b995061116360608f01611076565b985060808e0135975060a08e0135965060c08e0135955060e08e013594506101008e013591508082111561119657600080fd5b506111a38e828f01611081565b915080935050809150509295989b509295989b9093969950565b60008060008060008060008060006101008a8c0312156111dc57600080fd5b8935985060208a01356111ee8161105e565b975060408a01356111fe8161105e565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a01356001600160401b0381111561123557600080fd5b6112418c828d01611081565b915080935050809150509295985092959850929598565b60006020828403121561126a57600080fd5b5035919050565b60008060008060008060008060e0898b03121561128d57600080fd5b88356112988161105e565b975060208901356112a88161105e565b965060408901359550606089013594506080890135935060a0890135925060c08901356001600160401b038111156112df57600080fd5b6112eb8b828c01611081565b999c989b5096995094979396929594505050565b6000806040838503121561131257600080fd5b50508035926020909101359150565b60006020828403121561133357600080fd5b813561133e8161105e565b9392505050565b60006020828403121561135757600080fd5b815161133e8161105e565b6001600160a01b0392831681529116602082015260400190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b60006001600160601b0319808b60601b168352808a60601b16601484015250876028830152866048830152856068830152846088830152828460a8840137506000910160a801908152979650505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561148357816000190482111561146957611469611432565b8085161561147657918102915b93841c939080029061144d565b509250929050565b60008261149a57506001610e95565b816114a757506000610e95565b81600181146114bd57600281146114c7576114e3565b6001915050610e95565b60ff8411156114d8576114d8611432565b50506001821b610e95565b5060208310610133831016604e8410600b8410161715611506575081810a610e95565b6115108383611448565b806000190482111561152457611524611432565b029392505050565b600061133e838361148b565b634e487b7160e01b600052601260045260246000fd5b60008261155d5761155d611538565b500490565b60008261157157611571611538565b500690565b60005b83811015611591578181015183820152602001611579565b838111156115a0576000848401525b50505050565b60018060a01b038416815282602082015260606040820152600082518060608401526115d9816080850160208701611576565b601f01601f191691909101608001949350505050565b6000806040838503121561160257600080fd5b8251801515811461161257600080fd5b60208401519092506001600160401b038082111561162f57600080fd5b818501915085601f83011261164357600080fd5b81518181111561165557611655610f63565b611668601f8201601f1916602001610f79565b915080825286602082850101111561167f57600080fd5b611690816020840160208601611576565b508092505050925092905056fea2646970667358221220a71c0b2b1bb378b4e87b3d74997da580d1aeddfa0020bf7828e35ac6e461bac064736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061012b5760003560e01c806395fcea78116100ad578063c4d66de811610071578063c4d66de81461023e578063c75184df14610251578063cb23bcb514610271578063d5b5cc2314610284578063e78cea92146102a457600080fd5b806395fcea78146101e85780639f0c04bf146101f0578063a04cee6014610203578063ae6dead714610216578063b0f305371461023657600080fd5b80635a129efe116100f45780635a129efe1461018d5780636ae71f12146101b057806372f2a8c7146101b857806380648b02146101c05780638515bc6a146101e057600080fd5b80627436d31461013057806308635a9514610156578063119852711461016b578063288e5b10146101725780634654779014610185575b600080fd5b61014361013e366004610fa9565b6102b7565b6040519081526020015b60405180910390f35b6101696101643660046110c9565b6102f4565b005b6000610143565b6101696101803660046111bd565b610367565b6101436103a2565b6101a061019b366004611258565b6103d1565b604051901515815260200161014d565b6101696103ee565b6101436105fb565b6101c8610618565b6040516001600160a01b03909116815260200161014d565b610143610639565b61016961066f565b6101436101fe366004611271565b610792565b6101696102113660046112ff565b6107d7565b610143610224366004611258565b60036020526000908152604090205481565b610143610852565b61016961024c366004611321565b61087a565b610259600281565b6040516001600160801b03909116815260200161014d565b6000546101c8906001600160a01b031681565b610143610292366004611258565b60026020526000908152604090205481565b6001546101c8906001600160a01b031681565b60006102ec8484846040516020016102d191815260200190565b60405160208183030381529060405280519060200120610a19565b949350505050565b60006103068989898989898989610792565b90506103488c8c808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508e9250859150610abc9050565b6103598a8a8a8a8a8a8a8a8a610bc5565b505050505050505050505050565b331561038657604051630e13b69d60e01b815260040160405180910390fd5b610397898989898989898989610bc5565b505050505050505050565b6004546000906001600160801b03908116908114156103c357600091505090565b6001600160801b0316919050565b60008060006103df84610e4f565b92509250506102ec8282610e8c565b60008054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561043a57600080fd5b505afa15801561044e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104729190611345565b6001600160a01b0316336001600160a01b03161461052a5760005460408051638da5cb5b60e01b8152905133926001600160a01b031691638da5cb5b916004808301926020929190829003018186803b1580156104ce57600080fd5b505afa1580156104e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105069190611345565b604051631194af8760e11b8152600401610521929190611362565b60405180910390fd5b6001546040805163cb23bcb560e01b815290516000926001600160a01b03169163cb23bcb5916004808301926020929190829003018186803b15801561056f57600080fd5b505afa158015610583573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a79190611345565b6000549091506001600160a01b03808316911614156105d95760405163d054909f60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60055460009060001981141561061357506000919050565b919050565b6006546000906001600160a01b039081169081141561061357600091505090565b6006546000906001600160601b03600160a01b90910481169081141561066157600091505090565b6001600160601b0316919050565b306001600160a01b037f000000000000000000000000511cbbd4a8c7866b86da3607ae7f65f7d8bf8b561614156106b85760405162461bcd60e51b81526004016105219061137c565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038054336001600160a01b03821614610708573381604051631194af8760e11b8152600401610521929190611362565b6004546001600160801b03908116146107345760405163d0afb66160e01b815260040160405180910390fd5b50506040805160c0810182526001600160801b0380825260208201526000199181018290526001600160a01b0360608201526001600160601b036080820152600060a090910181905260048290556005829055600691909155600755565b600088888888888888886040516020016107b39897969594939291906113c8565b60405160208183030381529060405280519060200120905098975050505050505050565b6000546001600160a01b0316331461081357600054604051630e4cf1bf60e21b81526105219133916001600160a01b0390911690600401611362565b60008281526003602052604080822083905551829184917fb4df3847300f076a369cd76d2314b470a1194d9e8a6bb97f1860aee88a5f67489190a35050565b6004546000906001600160801b03600160801b9091048116908114156103c357600091505090565b306001600160a01b037f000000000000000000000000511cbbd4a8c7866b86da3607ae7f65f7d8bf8b561614156108c35760405162461bcd60e51b81526004016105219061137c565b6001600160a01b0381166108ea57604051631ad0f74360e01b815260040160405180910390fd5b6001546001600160a01b03161561091457604051633bcd329760e21b815260040160405180910390fd5b6040805160c0810182526001600160801b038082526020808301919091526000198284018190526001600160a01b03606084018190526001600160601b036080850152600060a090940184905260048281556005839055600692909255600793909355600180546001600160a01b0319169386169384179055835163cb23bcb560e01b81529351929363cb23bcb59381830193929091829003018186803b1580156109be57600080fd5b505afa1580156109d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f69190611345565b600080546001600160a01b0319166001600160a01b039290921691909117905550565b8251600090610100811115610a4c57604051637ed6198f60e11b8152600481018290526101006024820152604401610521565b8260005b82811015610ab2576000878281518110610a6c57610a6c61141c565b60200260200101519050816001901b871660001415610a9957826000528060205260406000209250610aa9565b8060005282602052604060002092505b50600101610a50565b5095945050505050565b610100835110610ae457825160405163ab6a068360e01b815260040161052191815260200190565b8251610af190600261152c565b8210610b28578183516002610b06919061152c565b604051630b8a724b60e01b815260048101929092526024820152604401610521565b6000610b358484846102b7565b600081815260036020526040902054909150610b67576040516310e61af960e31b815260048101829052602401610521565b6000806000610b7586610e4f565b925092509250610b858282610e8c565b15610ba657604051639715b8d360e01b815260048101879052602401610521565b600092835260026020526040909220600190911b909117905550505050565b6000886001600160a01b0316886001600160a01b03167f20af7f3bbfe38132b8900ae295cd9c8d1914be7052d061a511f3f728dab189648c604051610c0c91815260200190565b60405180910390a46000839050600060046040518060c00160405290816000820160009054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020016000820160109054906101000a90046001600160801b03166001600160801b03166001600160801b03168152602001600182015481526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016002820160149054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160038201548152505090506040518060c00160405280896001600160801b03168152602001876001600160801b031681526020018c60001b81526020018b6001600160a01b03168152602001886001600160601b03168152602001610d52600090565b905280516020808301516001600160801b03908116600160801b02921691909117600455604080830151600555606083015160808401516001600160601b0316600160a01b026001600160a01b039091161760065560a0909201516007558151601f8601829004820281018201909252848252610dee918b918591908890889081908401838280828437600092019190915250610e9b92505050565b805160208201516001600160801b03908116600160801b029116176004556040810151600555606081015160808201516001600160601b0316600160a01b026001600160a01b039091161760065560a0015160075550505050505050505050565b6000808080610e5f60ff8661154e565b90506000610e6e60ff87611562565b60008381526002602052604090205492979096509194509092505050565b80821c60011615155b92915050565b600154604051639e5d4c4960e01b815260009182916001600160a01b0390911690639e5d4c4990610ed4908890889088906004016115a6565b600060405180830381600087803b158015610eee57600080fd5b505af1158015610f02573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f2a91908101906115ef565b9150915081610f5c57805115610f435780518082602001fd5b604051631bb7daad60e11b815260040160405180910390fd5b5050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715610fa157610fa1610f63565b604052919050565b600080600060608486031215610fbe57600080fd5b83356001600160401b0380821115610fd557600080fd5b818601915086601f830112610fe957600080fd5b8135602082821115610ffd57610ffd610f63565b8160051b925061100e818401610f79565b828152928401810192818101908a85111561102857600080fd5b948201945b848610156110465785358252948201949082019061102d565b9a918901359950506040909701359695505050505050565b6001600160a01b038116811461107357600080fd5b50565b80356106138161105e565b60008083601f84011261109357600080fd5b5081356001600160401b038111156110aa57600080fd5b6020830191508360208285010111156110c257600080fd5b9250929050565b60008060008060008060008060008060006101208c8e0312156110eb57600080fd5b8b356001600160401b038082111561110257600080fd5b818e0191508e601f83011261111657600080fd5b81358181111561112557600080fd5b8f60208260051b850101111561113a57600080fd5b60208381019e50909c508e01359a5061115560408f01611076565b995061116360608f01611076565b985060808e0135975060a08e0135965060c08e0135955060e08e013594506101008e013591508082111561119657600080fd5b506111a38e828f01611081565b915080935050809150509295989b509295989b9093969950565b60008060008060008060008060006101008a8c0312156111dc57600080fd5b8935985060208a01356111ee8161105e565b975060408a01356111fe8161105e565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a01356001600160401b0381111561123557600080fd5b6112418c828d01611081565b915080935050809150509295985092959850929598565b60006020828403121561126a57600080fd5b5035919050565b60008060008060008060008060e0898b03121561128d57600080fd5b88356112988161105e565b975060208901356112a88161105e565b965060408901359550606089013594506080890135935060a0890135925060c08901356001600160401b038111156112df57600080fd5b6112eb8b828c01611081565b999c989b5096995094979396929594505050565b6000806040838503121561131257600080fd5b50508035926020909101359150565b60006020828403121561133357600080fd5b813561133e8161105e565b9392505050565b60006020828403121561135757600080fd5b815161133e8161105e565b6001600160a01b0392831681529116602082015260400190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b60006001600160601b0319808b60601b168352808a60601b16601484015250876028830152866048830152856068830152846088830152828460a8840137506000910160a801908152979650505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561148357816000190482111561146957611469611432565b8085161561147657918102915b93841c939080029061144d565b509250929050565b60008261149a57506001610e95565b816114a757506000610e95565b81600181146114bd57600281146114c7576114e3565b6001915050610e95565b60ff8411156114d8576114d8611432565b50506001821b610e95565b5060208310610133831016604e8410600b8410161715611506575081810a610e95565b6115108383611448565b806000190482111561152457611524611432565b029392505050565b600061133e838361148b565b634e487b7160e01b600052601260045260246000fd5b60008261155d5761155d611538565b500490565b60008261157157611571611538565b500690565b60005b83811015611591578181015183820152602001611579565b838111156115a0576000848401525b50505050565b60018060a01b038416815282602082015260606040820152600082518060608401526115d9816080850160208701611576565b601f01601f191691909101608001949350505050565b6000806040838503121561160257600080fd5b8251801515811461161257600080fd5b60208401519092506001600160401b038082111561162f57600080fd5b818501915085601f83011261164357600080fd5b81518181111561165557611655610f63565b611668601f8201601f1916602001610f79565b915080825286602082850101111561167f57600080fd5b611690816020840160208601611576565b508092505050925092905056fea2646970667358221220a71c0b2b1bb378b4e87b3d74997da580d1aeddfa0020bf7828e35ac6e461bac064736f6c63430008090033
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.