Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
CanonicalStateChain
Compiler Version
v0.8.22+commit.4fc1097e
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
/// @custom:proxied
/// @title Canonical State Chain
/// @author LightLink Hummingbird
/// @custom:version v1.1.0-beta
/// @notice The Canonical State Chain (CSC) is the source of truth for the layer two chain.
/// All layer two blocks will eventually be bundled up by the hummingbird publisher
/// and published to the CSC. The chain can only be rolled back by the challenge contract,
/// assuming the block is within the challenge/pending window.
///
/// The chain is append only, and the publisher is the only address that can add new blocks
/// to the chain. The owner of the contract can replace the publisher address, and is expected
/// to be the DAO Governance contract.
contract CanonicalStateChain is UUPSUpgradeable, OwnableUpgradeable {
/// @notice The header of a L1 rollup block.
/// @param epoch - Refers to a block number on the Ethereum blockchain
/// @param l2Height - The index of the Last L2 Block in this bundle.
/// @param prevHash - The hash of the previous block bundle.
/// @param outputRoot - The output root = keccack(version_hash || keccack(state_root || withdrawal_root || latest_block_hash))
/// @param celestiaPointers - Pointer to the blocks contents on celestia.
/// See `Span` from https://docs.celestia.org/developers/blobstream-offchain#defining-a-chain
struct Header {
uint64 epoch;
uint64 l2Height;
bytes32 prevHash;
bytes32 outputRoot;
CelestiaPointer[] celestiaPointers;
}
/// @notice A pointer to a block on Celestia.
/// @param height - The height of the block on Celestia.
/// @param shareStart - The start index of shares in block on Celestia.
/// @param shareLen - The length of the shares in block on Celestia.
struct CelestiaPointer {
uint64 height;
uint24 shareStart;
uint16 shareLen;
}
/// @notice The metadata of a block header.
/// @param timestamp - The timestamp the block was added.
/// @param publisher - The address of the publisher that added the block.
struct HeaderMetadata {
uint64 timestamp;
address publisher;
}
/// @notice Emitted when a new block is added to the chain.
/// @param blockNumber - The block number of the new block.
event BlockAdded(uint256 indexed blockNumber);
/// @notice Emitted when the chain is rolled back.
/// @param blockNumber - The block number the chain was rolled back to.
event RolledBack(uint256 indexed blockNumber);
/// @notice Emitted when the publisher address is changed.
/// @param publisher - The new publisher address.
event PublisherChanged(address indexed publisher);
/// @notice Emitted when the challenge contract address is changed.
/// @param challenge - The new challenge contract address.
event ChallengeChanged(address indexed challenge);
/// @notice Emitted when an output is proposed.
/// @param outputRoot The output root.
/// @param l2OutputIndex The index of the output in the l2Outputs array.
/// @param l2BlockNumber The L2 block number of the output root.
/// @param l1Timestamp The L1 timestamp when proposed.
event OutputProposed(
bytes32 indexed outputRoot,
uint256 indexed l2OutputIndex,
uint256 indexed l2BlockNumber,
uint256 l1Timestamp
);
/// @notice The address of the publisher. The publisher is the only address
/// that can add new blocks to the chain.
address public publisher;
/// @notice The challenge contract is the address of the challenge contract.
/// This contract can rollback the chain after a successful challenge is made.
address public challenge;
/// @notice The index of the last block in the chain.
uint256 public chainHead;
/// @notice The maximum number of celestia pointers a block can have.
uint8 public maxPointers;
/// @notice The canonical chain of block headers.
mapping(bytes32 => Header) private headers;
/// @notice The metadata of a block header.
mapping(bytes32 => HeaderMetadata) public headerMetadata;
/// @notice The canonical chain of block hashes.
mapping(uint256 => bytes32) public chain;
/// @notice This function is a special internal function that's part of
/// the UUPS upgradeable contract's lifecycle. When you want to
/// upgrade the contract to a new version, _authorizeUpgrade is
/// called to check whether the upgrade is authorized, thus
/// preventing anyone from just upgrading the contract.
/// @dev Only the owner can call this function.
function _authorizeUpgrade(address) internal override onlyOwner {}
/// @notice Initializes the contract with the publisher and the genesis block.
/// @param _publisher - The address of the publisher.
/// @param _header - The genesis block header.
function initialize(
address _publisher,
Header memory _header
) public initializer {
__Ownable_init(msg.sender);
publisher = _publisher;
// Add the genesis block.
bytes32 _hash = calculateHeaderHash(_header);
headers[_hash] = _header;
chain[0] = _hash;
// Save the genesis block metadata.
headerMetadata[_hash] = HeaderMetadata(
uint64(block.timestamp),
msg.sender
);
maxPointers = 21;
}
/// @notice Optimistically pushes block headers to the canonical chain.
/// The only fields that are checked are the epoch, prevHash and that the
/// block has atleast one celestia pointer. Other fields are optimistically
/// assumed to be correct, however they can be challenged and rolled back
/// via challenge contract.
/// @param _header - The block header to add.
function pushBlock(Header calldata _header) external {
require(msg.sender == publisher, "only publisher can add blocks");
// Check that the epoch is greater than the previous epoch.
require(
_header.epoch > headers[chain[chainHead]].epoch,
"epoch must be greater than previous epoch"
);
require(
_header.prevHash == chain[chainHead],
"prevHash must be the previous block hash"
);
require(
_header.celestiaPointers.length > 0,
"block must have atleast one celestia pointer"
);
require(
_header.celestiaPointers.length <= maxPointers,
"block has too many celestia pointers"
);
// check that the block is not already in the chain.
bytes32 _hash = calculateHeaderHash(_header);
require(headers[_hash].epoch == 0, "block already exists");
// Add the block to the chain.
chainHead++;
headers[_hash] = _header;
chain[chainHead] = _hash;
// Save the metadata.
headerMetadata[_hash] = HeaderMetadata(
uint64(block.timestamp),
msg.sender
);
emit BlockAdded(chainHead);
emit OutputProposed(
_header.outputRoot,
chainHead,
_header.l2Height,
block.timestamp
);
}
/// @notice Returns the hash of a block header.
/// @param _header - The block header to hash.
/// @return The hash of the block header.
function calculateHeaderHash(
Header memory _header
) public pure returns (bytes32) {
return keccak256(abi.encode(_header));
}
/// @notice Returns the block header at a given block number.
/// @param _index - The block number to get the header for.
/// @return The block header.
function getHeaderByNum(
uint256 _index
) public view returns (Header memory) {
return headers[chain[_index]];
}
struct Output {
bytes32 outputRoot;
uint64 timestamp;
}
function getL2Output(uint256 _index) public view returns (Output memory) {
bytes32 _hash = chain[_index];
return
Output(headers[_hash].outputRoot, headerMetadata[_hash].timestamp);
}
function startingTimestamp() public view returns (uint64) {
return headerMetadata[chain[0]].timestamp;
}
/// @notice Returns the block header at the head of the chain.
/// @return The block header.
function getHead() public view returns (Header memory) {
return headers[chain[chainHead]];
}
/// @notice Rolls back the chain to a previous block number. This function can only be
/// called by the challenge contract.
/// @param _blockNumber - The block number to roll back to.
/// @param _blockHash - The hash the block being purged.
function rollback(uint256 _blockNumber, bytes32 _blockHash) external {
require(
msg.sender == challenge,
"only challenge contract can rollback chain"
);
require(
_blockNumber < chainHead,
"block number must be less than chain head"
);
require(
chain[_blockNumber + 1] == _blockHash,
"block hash must match block numbers parent block hash"
);
// Remove all blocks after the block number.
for (uint256 i = _blockNumber + 1; i <= chainHead; i++) {
delete headers[chain[i]];
delete headerMetadata[chain[i]];
delete chain[i];
}
chainHead = _blockNumber;
emit RolledBack(_blockNumber);
}
/// @notice Sets the publisher address.
/// @param _publisher - The new publisher address.
/// @dev Only the owner can call this function.
function setPublisher(address _publisher) external onlyOwner {
publisher = _publisher;
emit PublisherChanged(_publisher);
}
/// @notice Sets the challenge contract address.
/// @param _challenge - The new challenge contract address.
/// @dev Only the owner can call this function.
function setChallengeContract(address _challenge) external onlyOwner {
challenge = _challenge;
emit ChallengeChanged(_challenge);
}
/// @notice Returns the block header hash at a given block number.
/// @param _hash - The hash of the block header to get.
function getHeaderByHash(
bytes32 _hash
) public view returns (Header memory) {
return headers[_hash];
}
/// @notice Sets the maximum number of celestia pointers a block can have.
/// @param _maxPointers - The new maximum number of celestia pointers.
/// @dev Only the owner can call this function.
function setMaxPointers(uint8 _maxPointers) external onlyOwner {
maxPointers = _maxPointers;
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Ownable
struct OwnableStorage {
address _owner;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;
function _getOwnableStorage() private pure returns (OwnableStorage storage $) {
assembly {
$.slot := OwnableStorageLocation
}
}
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
function __Ownable_init(address initialOwner) internal onlyInitializing {
__Ownable_init_unchained(initialOwner);
}
function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
OwnableStorage storage $ = _getOwnableStorage();
return $._owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
OwnableStorage storage $ = _getOwnableStorage();
address oldOwner = $._owner;
$._owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @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]
* ```solidity
* 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 Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 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.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._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.
*
* 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.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* 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.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._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() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @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.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.20;
import {IERC1822Proxiable} from "@openzeppelin/contracts/interfaces/draft-IERC1822.sol";
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
import {Initializable} from "./Initializable.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*/
abstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
address private immutable __self = address(this);
/**
* @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`
* and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,
* while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.
* If the getter returns `"5.0.0"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must
* be the empty byte string if no function should be called, making it impossible to invoke the `receive` function
* during an upgrade.
*/
string public constant UPGRADE_INTERFACE_VERSION = "5.0.0";
/**
* @dev The call is from an unauthorized context.
*/
error UUPSUnauthorizedCallContext();
/**
* @dev The storage `slot` is unsupported as a UUID.
*/
error UUPSUnsupportedProxiableUUID(bytes32 slot);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
_checkProxy();
_;
}
/**
* @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() {
_checkNotDelegated();
_;
}
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate the implementation's compatibility when performing an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual notDelegated returns (bytes32) {
return ERC1967Utils.IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, data);
}
/**
* @dev Reverts if the execution is not performed via delegatecall or the execution
* context is not of a proxy with an ERC1967-compliant implementation pointing to self.
* See {_onlyProxy}.
*/
function _checkProxy() internal view virtual {
if (
address(this) == __self || // Must be called through delegatecall
ERC1967Utils.getImplementation() != __self // Must be called through an active proxy
) {
revert UUPSUnauthorizedCallContext();
}
}
/**
* @dev Reverts if the execution is performed via delegatecall.
* See {notDelegated}.
*/
function _checkNotDelegated() internal view virtual {
if (address(this) != __self) {
// Must not be called through delegatecall
revert UUPSUnauthorizedCallContext();
}
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
/**
* @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.
*
* As a security check, {proxiableUUID} is invoked in the new implementation, and the return value
* is expected to be the implementation slot in ERC1967.
*
* Emits an {IERC1967-Upgraded} event.
*/
function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {
try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {
revert UUPSUnsupportedProxiableUUID(slot);
}
ERC1967Utils.upgradeToAndCall(newImplementation, data);
} catch {
// The implementation is not UUPS
revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.20;
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822Proxiable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.20;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {UpgradeableBeacon} will check that this address is a contract.
*/
function implementation() external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)
pragma solidity ^0.8.20;
import {IBeacon} from "../beacon/IBeacon.sol";
import {Address} from "../../utils/Address.sol";
import {StorageSlot} from "../../utils/StorageSlot.sol";
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*/
library ERC1967Utils {
// We re-declare ERC-1967 events here because they can't be used directly from IERC1967.
// This will be fixed in Solidity 0.8.21. At that point we should remove these events.
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev The `implementation` of the proxy is invalid.
*/
error ERC1967InvalidImplementation(address implementation);
/**
* @dev The `admin` of the proxy is invalid.
*/
error ERC1967InvalidAdmin(address admin);
/**
* @dev The `beacon` of the proxy is invalid.
*/
error ERC1967InvalidBeacon(address beacon);
/**
* @dev An upgrade function sees `msg.value > 0` that may be lost.
*/
error ERC1967NonPayable();
/**
* @dev Returns the current implementation address.
*/
function getImplementation() internal view returns (address) {
return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
if (newImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(newImplementation);
}
StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Performs implementation upgrade with additional setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
if (data.length > 0) {
Address.functionDelegateCall(newImplementation, data);
} else {
_checkNonPayable();
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
* the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function getAdmin() internal view returns (address) {
return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
if (newAdmin == address(0)) {
revert ERC1967InvalidAdmin(address(0));
}
StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {IERC1967-AdminChanged} event.
*/
function changeAdmin(address newAdmin) internal {
emit AdminChanged(getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function getBeacon() internal view returns (address) {
return StorageSlot.getAddressSlot(BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
if (newBeacon.code.length == 0) {
revert ERC1967InvalidBeacon(newBeacon);
}
StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
address beaconImplementation = IBeacon(newBeacon).implementation();
if (beaconImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(beaconImplementation);
}
}
/**
* @dev Change the beacon and trigger a setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-BeaconUpgraded} event.
*
* CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
* it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
* efficiency.
*/
function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
} else {
_checkNonPayable();
}
}
/**
* @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
* if an upgrade doesn't perform an initialization call.
*/
function _checkNonPayable() private {
if (msg.value > 0) {
revert ERC1967NonPayable();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @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 or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* 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.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @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`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// 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 FailedInnerCall();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.20;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```solidity
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(newImplementation.code.length > 0);
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
/**
* @dev Returns an `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"viaIR": true,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"}],"name":"ERC1967InvalidImplementation","type":"error"},{"inputs":[],"name":"ERC1967NonPayable","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"UUPSUnauthorizedCallContext","type":"error"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"name":"UUPSUnsupportedProxiableUUID","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"BlockAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"challenge","type":"address"}],"name":"ChallengeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"outputRoot","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"l2OutputIndex","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"l2BlockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"l1Timestamp","type":"uint256"}],"name":"OutputProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"publisher","type":"address"}],"name":"PublisherChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"RolledBack","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"UPGRADE_INTERFACE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"epoch","type":"uint64"},{"internalType":"uint64","name":"l2Height","type":"uint64"},{"internalType":"bytes32","name":"prevHash","type":"bytes32"},{"internalType":"bytes32","name":"outputRoot","type":"bytes32"},{"components":[{"internalType":"uint64","name":"height","type":"uint64"},{"internalType":"uint24","name":"shareStart","type":"uint24"},{"internalType":"uint16","name":"shareLen","type":"uint16"}],"internalType":"struct CanonicalStateChain.CelestiaPointer[]","name":"celestiaPointers","type":"tuple[]"}],"internalType":"struct CanonicalStateChain.Header","name":"_header","type":"tuple"}],"name":"calculateHeaderHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"chain","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chainHead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"challenge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHead","outputs":[{"components":[{"internalType":"uint64","name":"epoch","type":"uint64"},{"internalType":"uint64","name":"l2Height","type":"uint64"},{"internalType":"bytes32","name":"prevHash","type":"bytes32"},{"internalType":"bytes32","name":"outputRoot","type":"bytes32"},{"components":[{"internalType":"uint64","name":"height","type":"uint64"},{"internalType":"uint24","name":"shareStart","type":"uint24"},{"internalType":"uint16","name":"shareLen","type":"uint16"}],"internalType":"struct CanonicalStateChain.CelestiaPointer[]","name":"celestiaPointers","type":"tuple[]"}],"internalType":"struct CanonicalStateChain.Header","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"}],"name":"getHeaderByHash","outputs":[{"components":[{"internalType":"uint64","name":"epoch","type":"uint64"},{"internalType":"uint64","name":"l2Height","type":"uint64"},{"internalType":"bytes32","name":"prevHash","type":"bytes32"},{"internalType":"bytes32","name":"outputRoot","type":"bytes32"},{"components":[{"internalType":"uint64","name":"height","type":"uint64"},{"internalType":"uint24","name":"shareStart","type":"uint24"},{"internalType":"uint16","name":"shareLen","type":"uint16"}],"internalType":"struct CanonicalStateChain.CelestiaPointer[]","name":"celestiaPointers","type":"tuple[]"}],"internalType":"struct CanonicalStateChain.Header","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getHeaderByNum","outputs":[{"components":[{"internalType":"uint64","name":"epoch","type":"uint64"},{"internalType":"uint64","name":"l2Height","type":"uint64"},{"internalType":"bytes32","name":"prevHash","type":"bytes32"},{"internalType":"bytes32","name":"outputRoot","type":"bytes32"},{"components":[{"internalType":"uint64","name":"height","type":"uint64"},{"internalType":"uint24","name":"shareStart","type":"uint24"},{"internalType":"uint16","name":"shareLen","type":"uint16"}],"internalType":"struct CanonicalStateChain.CelestiaPointer[]","name":"celestiaPointers","type":"tuple[]"}],"internalType":"struct CanonicalStateChain.Header","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getL2Output","outputs":[{"components":[{"internalType":"bytes32","name":"outputRoot","type":"bytes32"},{"internalType":"uint64","name":"timestamp","type":"uint64"}],"internalType":"struct CanonicalStateChain.Output","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"headerMetadata","outputs":[{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"address","name":"publisher","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_publisher","type":"address"},{"components":[{"internalType":"uint64","name":"epoch","type":"uint64"},{"internalType":"uint64","name":"l2Height","type":"uint64"},{"internalType":"bytes32","name":"prevHash","type":"bytes32"},{"internalType":"bytes32","name":"outputRoot","type":"bytes32"},{"components":[{"internalType":"uint64","name":"height","type":"uint64"},{"internalType":"uint24","name":"shareStart","type":"uint24"},{"internalType":"uint16","name":"shareLen","type":"uint16"}],"internalType":"struct CanonicalStateChain.CelestiaPointer[]","name":"celestiaPointers","type":"tuple[]"}],"internalType":"struct CanonicalStateChain.Header","name":"_header","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxPointers","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publisher","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"epoch","type":"uint64"},{"internalType":"uint64","name":"l2Height","type":"uint64"},{"internalType":"bytes32","name":"prevHash","type":"bytes32"},{"internalType":"bytes32","name":"outputRoot","type":"bytes32"},{"components":[{"internalType":"uint64","name":"height","type":"uint64"},{"internalType":"uint24","name":"shareStart","type":"uint24"},{"internalType":"uint16","name":"shareLen","type":"uint16"}],"internalType":"struct CanonicalStateChain.CelestiaPointer[]","name":"celestiaPointers","type":"tuple[]"}],"internalType":"struct CanonicalStateChain.Header","name":"_header","type":"tuple"}],"name":"pushBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockNumber","type":"uint256"},{"internalType":"bytes32","name":"_blockHash","type":"bytes32"}],"name":"rollback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_challenge","type":"address"}],"name":"setChallengeContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_maxPointers","type":"uint8"}],"name":"setMaxPointers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_publisher","type":"address"}],"name":"setPublisher","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startingTimestamp","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"}]Contract Creation Code
60a0806040523461002a5730608052611a1190816100308239608051818181610c580152610d370152f35b600080fdfe608060409080825260048036101561001657600080fd5b600092833560e01c9283628f51c6146114a95750826328a8d0e41461146857826334c9bca51461122e57826341d3ecd814610f5f5782634411470314610f225782634f1ef28614610cbc57826352d1902d14610c445782635852cc0c14610c1c578263691bc74a14610bfa5782636d1005c514610bc5578263715018a614610b5b5782637255f37e14610a675782638878627214610a2e5782638c72c54e14610a065782638da5cb5b146109d05782638f74b7391461052d578263a25ae557146104bb578263ad3cb1cc14610441578263b37256b9146103d9578263b76971ce146102eb578263cab6366114610285578263d2ef739814610258578263dc281aff1461015c57505063f2fde38b1461012d57600080fd5b34610159576020366003190112610159576101566101496114c5565b6101516118de565b61186a565b80f35b80fd5b9091503461025457826003193601126102545782906101796117f3565b5060025482526020926006845281832054835283528082209281519261019e84611511565b8454916001600160401b0383818095168752851c168186015260036001966001810154868801526002810154606088015201908154926101dd8461157c565b946101ea87519687611547565b84865282860193825282822091935b85851061021857608089018790528751806102148b826116bb565b0390f35b898481928a516102278161152c565b61ffff8c62ffffff895480928a821686521c168584015260581c168c8201528152019301940193916101f9565b8280fd5b83903461028157816003193601126102815760015490516001600160a01b039091168152602090f35b5080fd5b83346101595760203660031901126101595761029f6114c5565b6102a76118de565b81546001600160a01b0319166001600160a01b039190911690811782557f55eb99d77b0e1ed261c0a8d11f026f811b8af01455a2b45189bcc87b93dfbbb78280a280f35b9091503461025457602091826003193601126103d55761030c9392936117f3565b508035835283528082209281519261032384611511565b8454916001600160401b0383818095168752851c168186015260036001966001810154868801526002810154606088015201908154926103628461157c565b9461036f87519687611547565b84865282860193825282822091935b85851061039957608089018790528751806102148b826116bb565b898481928a516103a88161152c565b61ffff8c62ffffff895480928a821686521c168584015260581c168c82015281520193019401939161037e565b8380fd5b8334610159576020366003190112610159576103f36114c5565b6103fb6118de565b600180546001600160a01b0319166001600160a01b039290921691821790557fe06eac444661557e3ac16a5251a66b82c3f985c3e3b15eac7ea4b4fac6eeac2c8280a280f35b839034610281578160031936011261028157805161045e816114e0565b60058152602090640352e302e360dc1b6020820152825193849260208452825192836020860152825b8481106104a557505050828201840152601f01601f19168101030190f35b8181018301518882018801528795508201610487565b838234610281576020908160031936011261025457828285516104dd816114e0565b828152015280358352600682528383205483528152826002818420015492600583526001600160401b03918291205416828551610519816114e0565b858152019081528451938452511690820152f35b8390346102815760031992602036850181136103d5578135916001600160401b03908184116109cc5760a08482019785360301126109cc5785546001600160a01b031633036109895761057f87611821565b9660025497888852600685528688205488528285528380888a2054169116111561093457604485013590888852600685528688205482036108e05760848601956105c98783611835565b905015610888576105da8783611835565b905060ff6003541610610839576105f96105f43684611593565b6117ca565b93848a5280875285898b2054166107ff5761061a6106589a9b93929361175b565b600255848b52865261069d888b2097600360648861063786611821565b16956001600160401b031996878d5416178c55610685602482019e8f611821565b8d546fffffffffffffffff0000000000000000191660409190911b67ffffffffffffffff60401b16178d55565b60019760018d01550135998a60028201550192611835565b92906106a98484611780565b918b52868b20908b925b84841061077957505050505050907fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2929160025488526006835280868920558551906106fe826114e0565b428316825233848301908152908952600584528689209151825491516001600160e01b03199092169084161790871b600160401b600160e01b031617905560025494519561077090867fa37f9fb2f8e66e6e5746e84c33d55fc62d920182d22358f2adc6855d3ac4d4378a80a2611821565b1694428152a480f35b8761078382611821565b16828454161783558881013562ffffff811681036107fb5783546affffff0000000000000000191660409190911b62ffffff60401b161783558a8101359061ffff821682036107fb57835461ffff60581b191660589290921b61ffff60581b16919091178355859081906060019301930192916106b3565b8d80fd5b885162461bcd60e51b81529081018790526014602482015273626c6f636b20616c72656164792065786973747360601b6044820152606490fd5b875162461bcd60e51b81528085018790526024808201527f626c6f636b2068617320746f6f206d616e792063656c657374696120706f696e6044820152637465727360e01b6064820152608490fd5b875162461bcd60e51b8152808501879052602c60248201527f626c6f636b206d75737420686176652061746c65617374206f6e652063656c6560448201526b39ba34b0903837b4b73a32b960a11b6064820152608490fd5b865162461bcd60e51b8152808401869052602860248201527f7072657648617368206d757374206265207468652070726576696f757320626c6044820152670dec6d640d0c2e6d60c31b6064820152608490fd5b855162461bcd60e51b8152808301859052602960248201527f65706f6368206d7573742062652067726561746572207468616e2070726576696044820152680deeae640cae0dec6d60bb1b6064820152608490fd5b845162461bcd60e51b8152908101839052601d60248201527f6f6e6c79207075626c69736865722063616e2061646420626c6f636b730000006044820152606490fd5b8580fd5b8390346102815781600319360112610281576000805160206119bc8339815191525490516001600160a01b039091168152602090f35b839034610281578160031936011261028157905490516001600160a01b039091168152602090f35b8390346102815781600319360112610281576001600160401b038183806020955260068552818120548152600585522054169051908152f35b9091503461025457602091826003193601126103d557610a889392936117f3565b508035835260068452818320548352835280822092815192610aa984611511565b8454916001600160401b0383818095168752851c16818601526003600196600181015486880152600281015460608801520190815492610ae88461157c565b94610af587519687611547565b84865282860193825282822091935b858510610b1f57608089018790528751806102148b826116bb565b898481928a51610b2e8161152c565b61ffff8c62ffffff895480928a821686521c168584015260581c168c820152815201930194019391610b04565b8334610159578060031936011261015957610b746118de565b6000805160206119bc83398151915280546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b838234610281576020366003190112610281573560ff811680910361028157610bec6118de565b60ff19600354161760035580f35b83903461028157816003193601126102815760209060ff600354169051908152f35b9150346102545760203660031901126102545760209282913581526006845220549051908152f35b8334610159578060031936011261015957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163003610caf57602090517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b5163703e46dd60e11b8152fd5b8091925060031936011261025457610cd26114c5565b9060249384356001600160401b03811161028157366023820112156102815780850135610cfe816116a0565b94610d0b85519687611547565b81865260209182870193368a83830101116109cc578186928b8693018737880101526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116308114908115610ef4575b50610ee457610d706118de565b81169585516352d1902d60e01b815283818a818b5afa869181610eb1575b50610daa575050505050505191634c9c8ce360e01b8352820152fd5b9088888894938c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91828103610e9c5750853b15610e88575080546001600160a01b031916821790558451889392917fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8580a2825115610e6a575050610e5c9582915190845af4913d15610e60573d610e4e610e45826116a0565b92519283611547565b81528581943d92013e611958565b5080f35b5060609250611958565b955095505050505034610e7c57505080f35b63b398979f60e01b8152fd5b8651634c9c8ce360e01b8152808501849052fd5b8751632a87526960e21b815280860191909152fd5b9091508481813d8311610edd575b610ec98183611547565b81010312610ed957519038610d8e565b8680fd5b503d610ebf565b855163703e46dd60e11b81528890fd5b9050817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5416141538610d63565b8334610159576020366003190112610159578235906001600160401b03821161015957506105f4602093610f5892369101611593565b9051908152f35b915034610254578160031936011261025457610f796114c5565b6001600160401b03926024358481116109cc57610f999036908501611593565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0094855460ff81851c16159282821695861580611227575b6001809814908161121d575b159081611214575b506112045767ffffffffffffffff1983811688178a5592856111e5575b5061100e929192611917565b611016611917565b61101f3361186a565b89546001600160a01b0319166001600160a01b0391909116178955611043826117ca565b91828a52602097885260806003878c208684511685825416178155611090878c86015116829067ffffffffffffffff60401b82549160401b169067ffffffffffffffff60401b1916179055565b888401518a820155606084015160028201550191015191888351936110b58585611780565b01918b52888b2090888c935b8b86861061117957505050505050508780526006865280848920558351916110e8836114e0565b428116835233878401908152918952600587528489209251835492516001600160e01b031990931691161790841b600160401b600160e01b03161790556003805460ff1916601517905561113a578480f35b7fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29368ff000000000000000019815416905551908152a1388080808480f35b816111d761ffff8d8695518d815116898b5416178a556111ba62ffffff87830151168b9062ffffff60401b82549160401b169062ffffff60401b1916179055565b0151885461ffff60581b1916911660581b61ffff60581b16178755565b0193019301929189906110c1565b68ffffffffffffffffff19166801000000000000000117895538611002565b855163f92ee8a960e01b81528890fd5b90501538610fe5565b303b159150610fdd565b5084610fd1565b83903461028157806003193601126102815760018054843592906001600160a01b0316330361141357600280548410156113be5760018401958685116113ab5786865260069160209160068352602435858920540361134a5785969798955b6112bf575b8888806002557fbd56a1ce5e71ef906a2c86c43372d012f8ab2422ff19bfdba9b686ac0936f86f8280a280f35b81548611611345578587968a52848452858a20548a528184526003868b208b81558b898201558b85820155018054908b815581611328575b505080611322918b52858552868b20548b52600585528a87812055808b528585528a8781205561175b565b9561128d565b8b52848b20908101905b818110156112f7578b8155899801611332565b611292565b845162461bcd60e51b8152908101839052603560248201527f626c6f636b2068617368206d757374206d6174636820626c6f636b206e756d626044820152740cae4e640e0c2e4cadce840c4d8dec6d640d0c2e6d605b1b6064820152608490fd5b634e487b7160e01b865260119052602485fd5b815162461bcd60e51b8152602081880152602960248201527f626c6f636b206e756d626572206d757374206265206c657373207468616e20636044820152681a185a5b881a19585960ba1b6064820152608490fd5b5162461bcd60e51b8152602081860152602a60248201527f6f6e6c79206368616c6c656e676520636f6e74726163742063616e20726f6c6c6044820152693130b1b59031b430b4b760b11b6064820152608490fd5b91503461025457602036600319011261025457918192358152600560205220548151906001600160401b038116825260018060a01b0390831c166020820152f35b8490346102815781600319360112610281576020906002548152f35b600435906001600160a01b03821682036114db57565b600080fd5b604081019081106001600160401b038211176114fb57604052565b634e487b7160e01b600052604160045260246000fd5b60a081019081106001600160401b038211176114fb57604052565b606081019081106001600160401b038211176114fb57604052565b90601f801991011681019081106001600160401b038211176114fb57604052565b35906001600160401b03821682036114db57565b6001600160401b0381116114fb5760051b60200190565b919060a0838203126114db576040928351906115ae82611511565b81946115b982611568565b835260206115c8818401611568565b818501528183013582850152606092606081013560608601526080810135906001600160401b0382116114db57019185601f840112156114db5782359061160e8261157c565b9661161b82519889611547565b828852836060818a019402860101948186116114db578401925b858410611649575050505050505060800152565b86848303126114db5782519061165e8261152c565b61166785611568565b82528585013562ffffff811681036114db5786830152838501359061ffff821682036114db57828792868b950152815201930192611635565b6001600160401b0381116114fb57601f01601f191660200190565b90602080835260c08301906001600160401b0380845116828601528184015193816040951660408701528260e0608060408401519360609460608b01526060810151828b015201519760a0808201528851809752019601946000925b858410611728575050505050505090565b86518051821689528086015162ffffff168987015282015161ffff16888301529682019695840195600190930192611717565b600019811461176a5760010190565b634e487b7160e01b600052601160045260246000fd5b6801000000000000000082116114fb578054918082558281106117a257505050565b600091600052602060002092830192015b8281106117bf57505050565b8181556001016117b3565b6040516117ed816117df6020820194856116bb565b03601f198101835282611547565b51902090565b6040519061180082611511565b60606080836000815260006020820152600060408201526000838201520152565b356001600160401b03811681036114db5790565b903590601e19813603018212156114db57018035906001600160401b0382116114db576020019160608202360383136114db57565b6001600160a01b039081169081156118c5576000805160206119bc83398151915280546001600160a01b031981168417909155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b604051631e4fbdf760e01b815260006004820152602490fd5b6000805160206119bc833981519152546001600160a01b031633036118ff57565b60405163118cdaa760e01b8152336004820152602490fd5b60ff7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460401c161561194657565b604051631afcd79f60e31b8152600490fd5b9061197f575080511561196d57805190602001fd5b604051630a12f52160e11b8152600490fd5b815115806119b2575b611990575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b1561198856fe9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300a26469706673582212200f6996667def21600b5dbc4a17eae0cad6528c73a82d712c9613fe502bdbd11564736f6c63430008160033
Deployed Bytecode
0x608060409080825260048036101561001657600080fd5b600092833560e01c9283628f51c6146114a95750826328a8d0e41461146857826334c9bca51461122e57826341d3ecd814610f5f5782634411470314610f225782634f1ef28614610cbc57826352d1902d14610c445782635852cc0c14610c1c578263691bc74a14610bfa5782636d1005c514610bc5578263715018a614610b5b5782637255f37e14610a675782638878627214610a2e5782638c72c54e14610a065782638da5cb5b146109d05782638f74b7391461052d578263a25ae557146104bb578263ad3cb1cc14610441578263b37256b9146103d9578263b76971ce146102eb578263cab6366114610285578263d2ef739814610258578263dc281aff1461015c57505063f2fde38b1461012d57600080fd5b34610159576020366003190112610159576101566101496114c5565b6101516118de565b61186a565b80f35b80fd5b9091503461025457826003193601126102545782906101796117f3565b5060025482526020926006845281832054835283528082209281519261019e84611511565b8454916001600160401b0383818095168752851c168186015260036001966001810154868801526002810154606088015201908154926101dd8461157c565b946101ea87519687611547565b84865282860193825282822091935b85851061021857608089018790528751806102148b826116bb565b0390f35b898481928a516102278161152c565b61ffff8c62ffffff895480928a821686521c168584015260581c168c8201528152019301940193916101f9565b8280fd5b83903461028157816003193601126102815760015490516001600160a01b039091168152602090f35b5080fd5b83346101595760203660031901126101595761029f6114c5565b6102a76118de565b81546001600160a01b0319166001600160a01b039190911690811782557f55eb99d77b0e1ed261c0a8d11f026f811b8af01455a2b45189bcc87b93dfbbb78280a280f35b9091503461025457602091826003193601126103d55761030c9392936117f3565b508035835283528082209281519261032384611511565b8454916001600160401b0383818095168752851c168186015260036001966001810154868801526002810154606088015201908154926103628461157c565b9461036f87519687611547565b84865282860193825282822091935b85851061039957608089018790528751806102148b826116bb565b898481928a516103a88161152c565b61ffff8c62ffffff895480928a821686521c168584015260581c168c82015281520193019401939161037e565b8380fd5b8334610159576020366003190112610159576103f36114c5565b6103fb6118de565b600180546001600160a01b0319166001600160a01b039290921691821790557fe06eac444661557e3ac16a5251a66b82c3f985c3e3b15eac7ea4b4fac6eeac2c8280a280f35b839034610281578160031936011261028157805161045e816114e0565b60058152602090640352e302e360dc1b6020820152825193849260208452825192836020860152825b8481106104a557505050828201840152601f01601f19168101030190f35b8181018301518882018801528795508201610487565b838234610281576020908160031936011261025457828285516104dd816114e0565b828152015280358352600682528383205483528152826002818420015492600583526001600160401b03918291205416828551610519816114e0565b858152019081528451938452511690820152f35b8390346102815760031992602036850181136103d5578135916001600160401b03908184116109cc5760a08482019785360301126109cc5785546001600160a01b031633036109895761057f87611821565b9660025497888852600685528688205488528285528380888a2054169116111561093457604485013590888852600685528688205482036108e05760848601956105c98783611835565b905015610888576105da8783611835565b905060ff6003541610610839576105f96105f43684611593565b6117ca565b93848a5280875285898b2054166107ff5761061a6106589a9b93929361175b565b600255848b52865261069d888b2097600360648861063786611821565b16956001600160401b031996878d5416178c55610685602482019e8f611821565b8d546fffffffffffffffff0000000000000000191660409190911b67ffffffffffffffff60401b16178d55565b60019760018d01550135998a60028201550192611835565b92906106a98484611780565b918b52868b20908b925b84841061077957505050505050907fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2929160025488526006835280868920558551906106fe826114e0565b428316825233848301908152908952600584528689209151825491516001600160e01b03199092169084161790871b600160401b600160e01b031617905560025494519561077090867fa37f9fb2f8e66e6e5746e84c33d55fc62d920182d22358f2adc6855d3ac4d4378a80a2611821565b1694428152a480f35b8761078382611821565b16828454161783558881013562ffffff811681036107fb5783546affffff0000000000000000191660409190911b62ffffff60401b161783558a8101359061ffff821682036107fb57835461ffff60581b191660589290921b61ffff60581b16919091178355859081906060019301930192916106b3565b8d80fd5b885162461bcd60e51b81529081018790526014602482015273626c6f636b20616c72656164792065786973747360601b6044820152606490fd5b875162461bcd60e51b81528085018790526024808201527f626c6f636b2068617320746f6f206d616e792063656c657374696120706f696e6044820152637465727360e01b6064820152608490fd5b875162461bcd60e51b8152808501879052602c60248201527f626c6f636b206d75737420686176652061746c65617374206f6e652063656c6560448201526b39ba34b0903837b4b73a32b960a11b6064820152608490fd5b865162461bcd60e51b8152808401869052602860248201527f7072657648617368206d757374206265207468652070726576696f757320626c6044820152670dec6d640d0c2e6d60c31b6064820152608490fd5b855162461bcd60e51b8152808301859052602960248201527f65706f6368206d7573742062652067726561746572207468616e2070726576696044820152680deeae640cae0dec6d60bb1b6064820152608490fd5b845162461bcd60e51b8152908101839052601d60248201527f6f6e6c79207075626c69736865722063616e2061646420626c6f636b730000006044820152606490fd5b8580fd5b8390346102815781600319360112610281576000805160206119bc8339815191525490516001600160a01b039091168152602090f35b839034610281578160031936011261028157905490516001600160a01b039091168152602090f35b8390346102815781600319360112610281576001600160401b038183806020955260068552818120548152600585522054169051908152f35b9091503461025457602091826003193601126103d557610a889392936117f3565b508035835260068452818320548352835280822092815192610aa984611511565b8454916001600160401b0383818095168752851c16818601526003600196600181015486880152600281015460608801520190815492610ae88461157c565b94610af587519687611547565b84865282860193825282822091935b858510610b1f57608089018790528751806102148b826116bb565b898481928a51610b2e8161152c565b61ffff8c62ffffff895480928a821686521c168584015260581c168c820152815201930194019391610b04565b8334610159578060031936011261015957610b746118de565b6000805160206119bc83398151915280546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b838234610281576020366003190112610281573560ff811680910361028157610bec6118de565b60ff19600354161760035580f35b83903461028157816003193601126102815760209060ff600354169051908152f35b9150346102545760203660031901126102545760209282913581526006845220549051908152f35b8334610159578060031936011261015957507f000000000000000000000000efe38bd58addf23efab1ffa163120303849292896001600160a01b03163003610caf57602090517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b5163703e46dd60e11b8152fd5b8091925060031936011261025457610cd26114c5565b9060249384356001600160401b03811161028157366023820112156102815780850135610cfe816116a0565b94610d0b85519687611547565b81865260209182870193368a83830101116109cc578186928b8693018737880101526001600160a01b037f000000000000000000000000efe38bd58addf23efab1ffa163120303849292898116308114908115610ef4575b50610ee457610d706118de565b81169585516352d1902d60e01b815283818a818b5afa869181610eb1575b50610daa575050505050505191634c9c8ce360e01b8352820152fd5b9088888894938c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91828103610e9c5750853b15610e88575080546001600160a01b031916821790558451889392917fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8580a2825115610e6a575050610e5c9582915190845af4913d15610e60573d610e4e610e45826116a0565b92519283611547565b81528581943d92013e611958565b5080f35b5060609250611958565b955095505050505034610e7c57505080f35b63b398979f60e01b8152fd5b8651634c9c8ce360e01b8152808501849052fd5b8751632a87526960e21b815280860191909152fd5b9091508481813d8311610edd575b610ec98183611547565b81010312610ed957519038610d8e565b8680fd5b503d610ebf565b855163703e46dd60e11b81528890fd5b9050817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5416141538610d63565b8334610159576020366003190112610159578235906001600160401b03821161015957506105f4602093610f5892369101611593565b9051908152f35b915034610254578160031936011261025457610f796114c5565b6001600160401b03926024358481116109cc57610f999036908501611593565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0094855460ff81851c16159282821695861580611227575b6001809814908161121d575b159081611214575b506112045767ffffffffffffffff1983811688178a5592856111e5575b5061100e929192611917565b611016611917565b61101f3361186a565b89546001600160a01b0319166001600160a01b0391909116178955611043826117ca565b91828a52602097885260806003878c208684511685825416178155611090878c86015116829067ffffffffffffffff60401b82549160401b169067ffffffffffffffff60401b1916179055565b888401518a820155606084015160028201550191015191888351936110b58585611780565b01918b52888b2090888c935b8b86861061117957505050505050508780526006865280848920558351916110e8836114e0565b428116835233878401908152918952600587528489209251835492516001600160e01b031990931691161790841b600160401b600160e01b03161790556003805460ff1916601517905561113a578480f35b7fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29368ff000000000000000019815416905551908152a1388080808480f35b816111d761ffff8d8695518d815116898b5416178a556111ba62ffffff87830151168b9062ffffff60401b82549160401b169062ffffff60401b1916179055565b0151885461ffff60581b1916911660581b61ffff60581b16178755565b0193019301929189906110c1565b68ffffffffffffffffff19166801000000000000000117895538611002565b855163f92ee8a960e01b81528890fd5b90501538610fe5565b303b159150610fdd565b5084610fd1565b83903461028157806003193601126102815760018054843592906001600160a01b0316330361141357600280548410156113be5760018401958685116113ab5786865260069160209160068352602435858920540361134a5785969798955b6112bf575b8888806002557fbd56a1ce5e71ef906a2c86c43372d012f8ab2422ff19bfdba9b686ac0936f86f8280a280f35b81548611611345578587968a52848452858a20548a528184526003868b208b81558b898201558b85820155018054908b815581611328575b505080611322918b52858552868b20548b52600585528a87812055808b528585528a8781205561175b565b9561128d565b8b52848b20908101905b818110156112f7578b8155899801611332565b611292565b845162461bcd60e51b8152908101839052603560248201527f626c6f636b2068617368206d757374206d6174636820626c6f636b206e756d626044820152740cae4e640e0c2e4cadce840c4d8dec6d640d0c2e6d605b1b6064820152608490fd5b634e487b7160e01b865260119052602485fd5b815162461bcd60e51b8152602081880152602960248201527f626c6f636b206e756d626572206d757374206265206c657373207468616e20636044820152681a185a5b881a19585960ba1b6064820152608490fd5b5162461bcd60e51b8152602081860152602a60248201527f6f6e6c79206368616c6c656e676520636f6e74726163742063616e20726f6c6c6044820152693130b1b59031b430b4b760b11b6064820152608490fd5b91503461025457602036600319011261025457918192358152600560205220548151906001600160401b038116825260018060a01b0390831c166020820152f35b8490346102815781600319360112610281576020906002548152f35b600435906001600160a01b03821682036114db57565b600080fd5b604081019081106001600160401b038211176114fb57604052565b634e487b7160e01b600052604160045260246000fd5b60a081019081106001600160401b038211176114fb57604052565b606081019081106001600160401b038211176114fb57604052565b90601f801991011681019081106001600160401b038211176114fb57604052565b35906001600160401b03821682036114db57565b6001600160401b0381116114fb5760051b60200190565b919060a0838203126114db576040928351906115ae82611511565b81946115b982611568565b835260206115c8818401611568565b818501528183013582850152606092606081013560608601526080810135906001600160401b0382116114db57019185601f840112156114db5782359061160e8261157c565b9661161b82519889611547565b828852836060818a019402860101948186116114db578401925b858410611649575050505050505060800152565b86848303126114db5782519061165e8261152c565b61166785611568565b82528585013562ffffff811681036114db5786830152838501359061ffff821682036114db57828792868b950152815201930192611635565b6001600160401b0381116114fb57601f01601f191660200190565b90602080835260c08301906001600160401b0380845116828601528184015193816040951660408701528260e0608060408401519360609460608b01526060810151828b015201519760a0808201528851809752019601946000925b858410611728575050505050505090565b86518051821689528086015162ffffff168987015282015161ffff16888301529682019695840195600190930192611717565b600019811461176a5760010190565b634e487b7160e01b600052601160045260246000fd5b6801000000000000000082116114fb578054918082558281106117a257505050565b600091600052602060002092830192015b8281106117bf57505050565b8181556001016117b3565b6040516117ed816117df6020820194856116bb565b03601f198101835282611547565b51902090565b6040519061180082611511565b60606080836000815260006020820152600060408201526000838201520152565b356001600160401b03811681036114db5790565b903590601e19813603018212156114db57018035906001600160401b0382116114db576020019160608202360383136114db57565b6001600160a01b039081169081156118c5576000805160206119bc83398151915280546001600160a01b031981168417909155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b604051631e4fbdf760e01b815260006004820152602490fd5b6000805160206119bc833981519152546001600160a01b031633036118ff57565b60405163118cdaa760e01b8152336004820152602490fd5b60ff7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460401c161561194657565b604051631afcd79f60e31b8152600490fd5b9061197f575080511561196d57805190602001fd5b604051630a12f52160e11b8152600490fd5b815115806119b2575b611990575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b1561198856fe9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300a26469706673582212200f6996667def21600b5dbc4a17eae0cad6528c73a82d712c9613fe502bdbd11564736f6c63430008160033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.