| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
LayerZero Block Relay
Compiler Version
vyper:0.4.3
Contract Source Code (Vyper Json-Input format)
# pragma version 0.4.3 # pragma optimize gas """ @title LayerZero Block Relay @notice Layer Zero messenger for block hashes. This contract should be deployed on multiple chains along with BlockOracle and MainnetBlockView. Main functionality includes requesting lzRead of recent ethereum mainnet blockhashes from MainnetBlockView. Upon receiving LZ message in lzReceive, the blockhash is committed to the BlockOracle, and if it was a read request, the contract will attempt to broadcast the blockhash to other chains. If chain is read-enabled, it will be able to read the blockhash from MainnetBlockView and broadcast it to other chains. If chain is not read-enabled, it will only be able to receive blockhashes from other chains. @license Copyright (c) Curve.Fi, 2025 - all rights reserved @author curve.fi @custom:security [email protected] """ ################################################################ # INTERFACES # ################################################################ interface IBlockOracle: def commit_block(block_number: uint256, block_hash: bytes32) -> bool: nonpayable def last_confirmed_block_number() -> uint256: view def get_block_hash(block_number: uint256) -> bytes32: view ################################################################ # MODULES # ################################################################ # Import ownership management from snekmate.auth import ownable initializes: ownable exports: ( ownable.owner, ownable.transfer_ownership, ownable.renounce_ownership, ) # Import LayerZero module for cross-chain messaging from ..modules.oapp_vyper.src import OApp # main module from ..modules.oapp_vyper.src import OptionsBuilder # module for creating options from ..modules.oapp_vyper.src import ReadCmdCodecV1 # module for reading commands initializes: OApp[ownable := ownable] exports: ( OApp.endpoint, OApp.peers, OApp.setPeer, OApp.setDelegate, OApp.isComposeMsgSender, OApp.allowInitializePath, OApp.nextNonce, ) ################################################################ # CONSTANTS # ################################################################ MAX_N_BROADCAST: constant(uint256) = 32 GET_BLOCKHASH_SELECTOR: constant(Bytes[4]) = method_id("get_blockhash(uint256,bool)") READ_RETURN_SIZE: constant(uint32) = 64 ################################################################ # STORAGE # ################################################################ # Read configuration read_enabled: public(bool) read_channel: public(uint32) mainnet_eid: public(uint32) mainnet_block_view: public(address) # Block oracle block_oracle: public(IBlockOracle) # Structs for cached broadcast info struct BroadcastTarget: eid: uint32 fee: uint256 struct BroadcastData: targets: DynArray[BroadcastTarget, MAX_N_BROADCAST] gas_limit: uint128 # Broadcast targets broadcast_data: HashMap[bytes32, BroadcastData] # guid -> (targets: (eid, fee), gas_limit) # lzRead received blocks received_blocks: HashMap[uint256, bytes32] # block_number -> block_hash ################################################################ # EVENTS # ################################################################ event BlockHashBroadcast: block_number: indexed(uint256) block_hash: indexed(bytes32) targets: DynArray[BroadcastTarget, MAX_N_BROADCAST] ################################################################ # CONSTRUCTOR # ################################################################ @deploy def __init__( _endpoint: address, ): """ @notice Initialize contract with core settings @dev Can only be called once, assumes caller is owner, sets as delegate @param _endpoint LayerZero endpoint address @param _lz_receive_gas_limit Gas limit for lzReceive """ ownable.__init__() ownable._transfer_ownership(tx.origin) # origin to enable createx deployment OApp.__init__(_endpoint, tx.origin) # origin also set as delegate ################################################################ # OWNER FUNCTIONS # ################################################################ @external def set_read_config( _is_enabled: bool, _read_channel: uint32, _mainnet_eid: uint32, _mainnet_view: address ): """ @notice Configure read functionality @param _is_enabled Whether this contract can initiate reads @param _read_channel LZ read channel ID @param _mainnet_eid Mainnet endpoint ID @param _mainnet_view MainnetBlockView contract address """ ownable._check_owner() assert _read_channel > OApp.READ_CHANNEL_THRESHOLD, "Invalid read channel" assert (_is_enabled and _mainnet_eid != 0 and _mainnet_view != empty(address)) or ( not _is_enabled and _mainnet_eid == 0 and _mainnet_view == empty(address) ), "Invalid read config" # Clean up old peer if switching channels while read is enabled # This prevents leaving stale peer mappings when changing read channels if self.read_enabled and self.read_channel != _read_channel: OApp._setPeer(self.read_channel, convert(empty(address), bytes32)) self.read_enabled = _is_enabled self.read_channel = _read_channel self.mainnet_eid = _mainnet_eid self.mainnet_block_view = _mainnet_view peer: bytes32 = convert(self, bytes32) if _is_enabled else convert(empty(address), bytes32) OApp._setPeer(_read_channel, peer) @external def set_peers(_eids: DynArray[uint32, MAX_N_BROADCAST], _peers: DynArray[address, MAX_N_BROADCAST]): """ @notice Set peers for a corresponding endpoints. Batched version of OApp.setPeer that accept address (EVM only). @param _eids The endpoint IDs. @param _peers Addresses of the peers to be associated with the corresponding endpoints. """ ownable._check_owner() assert len(_eids) == len(_peers), "Invalid peer arrays" for i: uint256 in range(0, len(_eids), bound=MAX_N_BROADCAST): OApp._setPeer(_eids[i], convert(_peers[i], bytes32)) @external def set_block_oracle(_oracle: address): """ @notice Set the block oracle address @param _oracle Block oracle address """ ownable._check_owner() self.block_oracle = IBlockOracle(_oracle) @external def withdraw_eth(_amount: uint256): """ @notice Withdraw ETH from contract @dev ETH can be accumulated from LZ refunds @param _amount Amount to withdraw """ ownable._check_owner() assert self.balance >= _amount, "Insufficient balance" send(msg.sender, _amount) ################################################################ # INTERNAL FUNCTIONS # ################################################################ @internal def _commit_block(_block_number: uint256, _block_hash: bytes32): """ @notice Commit block hash to oracle """ assert self.block_oracle != empty(IBlockOracle), "Oracle not configured" extcall self.block_oracle.commit_block(_block_number, _block_hash) @internal @view def _prepare_read_request(_block_number: uint256) -> Bytes[OApp.MAX_MESSAGE_SIZE]: """ @notice Prepare complete read request message for MainnetBlockView @param _block_number Block number to request (0 for latest) @return Prepared LayerZero message bytes """ # 1. Build calldata calldata: Bytes[ReadCmdCodecV1.MAX_CALLDATA_SIZE] = abi_encode( _block_number, True, method_id=GET_BLOCKHASH_SELECTOR ) # 2. Prepare ReadCmdRequestV1 struct request: ReadCmdCodecV1.EVMCallRequestV1 = ReadCmdCodecV1.EVMCallRequestV1( appRequestLabel=1, targetEid=self.mainnet_eid, isBlockNum=False, blockNumOrTimestamp=convert(block.timestamp, uint64), confirmations=1, # low confirmations because MainnetBlockView returns aged blockhashes to=self.mainnet_block_view, callData=calldata, ) # 3. Encode request encoded_message: Bytes[ReadCmdCodecV1.MAX_MESSAGE_SIZE] = ReadCmdCodecV1.encode( 1, [request] ) # 1 is _appCmdLabel # dev: ReadCmdCodecV1.MAX_MESSAGE_SIZE is opposed to OApp.MAX_MESSAGE_SIZE intentionally so code fails if they are not equal return encoded_message @internal @payable def _request_block_hash( _block_number: uint256, _target_eids: DynArray[uint32, MAX_N_BROADCAST], _target_fees: DynArray[uint256, MAX_N_BROADCAST], _lz_receive_gas_limit: uint128, _read_gas_limit: uint128, ): """ @notice Internal function to request block hash from mainnet and broadcast to specified targets @param _block_number Block number to request @param _target_eids Target EIDs to broadcast to @param _target_fees Target fees to pay per broadcast @param _lz_receive_gas_limit Gas limit for lzReceive @param _read_gas_limit Gas limit for read operation """ # Store target EIDs and fees for lzReceive cached_targets: DynArray[BroadcastTarget, MAX_N_BROADCAST] = [] sum_target_fees: uint256 = 0 for i: uint256 in range(0, len(_target_eids), bound=MAX_N_BROADCAST): cached_targets.append(BroadcastTarget(eid=_target_eids[i], fee=_target_fees[i])) sum_target_fees += _target_fees[i] assert sum_target_fees <= msg.value, "Insufficient value" # dev: check is here because we sum here message: Bytes[OApp.MAX_MESSAGE_SIZE] = self._prepare_read_request(_block_number) # Create options using OptionsBuilder module options: Bytes[OptionsBuilder.MAX_OPTIONS_TOTAL_SIZE] = OptionsBuilder.newOptions() options = OptionsBuilder.addExecutorLzReadOption( options, _read_gas_limit, READ_RETURN_SIZE, convert(sum_target_fees, uint128) ) # Send message fees: OApp.MessagingFee = OApp.MessagingFee(nativeFee=msg.value, lzTokenFee=0) # Fees = read fee + broadcast fees (value of read return message) receipt: OApp.MessagingReceipt = OApp._lzSend( self.read_channel, message, options, fees, msg.sender # dev: refund excess fee to sender ) # Store targets for lzReceive using receipt.guid as key self.broadcast_data[receipt.guid] = BroadcastData( targets=cached_targets, gas_limit=_lz_receive_gas_limit, ) @internal def _broadcast_block( _block_number: uint256, _block_hash: bytes32, _broadcast_data: BroadcastData, _refund_address: address, ): """ @notice Internal function to broadcast block hash to multiple chains @param _block_number Block number to broadcast @param _block_hash Block hash to broadcast @param _broadcast_data Data for broadcasting @param _refund_address Excess fees receiver """ message: Bytes[OApp.MAX_MESSAGE_SIZE] = abi_encode(_block_number, _block_hash) # Сreate options using OptionsBuilder module (same options for all targets) options: Bytes[OptionsBuilder.MAX_OPTIONS_TOTAL_SIZE] = OptionsBuilder.newOptions() options = OptionsBuilder.addExecutorLzReceiveOption( options, _broadcast_data.gas_limit, 0 ) for target: BroadcastTarget in _broadcast_data.targets: # Skip if peer is not set if OApp.peers[target.eid] == empty(bytes32): continue # Send message fees: OApp.MessagingFee = OApp.MessagingFee(nativeFee=target.fee, lzTokenFee=0) OApp._lzSend(target.eid, message, options, fees, _refund_address) log BlockHashBroadcast( block_number=_block_number, block_hash=_block_hash, targets=_broadcast_data.targets, ) ################################################################ # EXTERNAL FUNCTIONS # ################################################################ @external @payable def __default__(): """ @notice Default function to receive ETH @dev This is needed to receive refunds from LayerZero """ pass @external @view def quote_read_fee( _read_gas_limit: uint128, _value: uint128, ) -> uint256: """ @notice Quote fee for reading block hash from mainnet @param _read_gas_limit Gas to be provided in return message @param _value Value to be provided in return message @return Fee in native tokens required for the read operation """ assert self.read_enabled, "Read not enabled - call set_read_config" message: Bytes[OApp.MAX_MESSAGE_SIZE] = self._prepare_read_request(0) # dev: 0 for latest block # Create options using OptionsBuilder module options: Bytes[OptionsBuilder.MAX_OPTIONS_TOTAL_SIZE] = OptionsBuilder.newOptions() options = OptionsBuilder.addExecutorLzReadOption( options, _read_gas_limit, READ_RETURN_SIZE, _value ) return OApp._quote( self.read_channel, message, options, False, ).nativeFee @external @view def quote_broadcast_fees( _target_eids: DynArray[uint32, MAX_N_BROADCAST], _lz_receive_gas_limit: uint128, ) -> DynArray[uint256, MAX_N_BROADCAST]: """ @notice Quote fees for broadcasting block hash to specified targets @param _target_eids List of chain IDs to broadcast to @param _lz_receive_gas_limit Gas limit for lzReceive @return Array of fees per target chain (0 if target not configured) """ # Prepare dummy broadcast message (uint256 number, bytes32 hash) message: Bytes[OApp.MAX_MESSAGE_SIZE] = abi_encode(empty(uint256), empty(bytes32)) # Prepare array of fees per chain fees: DynArray[uint256, MAX_N_BROADCAST] = [] # Prepare options (same for all targets) options: Bytes[OptionsBuilder.MAX_OPTIONS_TOTAL_SIZE] = OptionsBuilder.newOptions() options = OptionsBuilder.addExecutorLzReceiveOption(options, _lz_receive_gas_limit, 0) # Cycle through targets for eid: uint32 in _target_eids: target: bytes32 = OApp.peers[eid] # Use peers directly if target == empty(bytes32): fees.append(0) continue # Get fee for target EID and append to array fees.append(OApp._quote(eid, message, options, False).nativeFee) return fees @external @payable def request_block_hash( _target_eids: DynArray[uint32, MAX_N_BROADCAST], _target_fees: DynArray[uint256, MAX_N_BROADCAST], _lz_receive_gas_limit: uint128, _read_gas_limit: uint128, _block_number: uint256 = 0, ): """ @notice Request block hash from mainnet and broadcast to specified targets @param _target_eids List of chain IDs to broadcast to @param _target_fees List of fees per chain (must match _target_eids length) @param _lz_receive_gas_limit Gas limit for lzReceive (same for all targets) @param _read_gas_limit Gas limit for read operation @param _block_number Optional block number (0 means latest) @dev User must ensure msg.value is sufficient: - must cover read fee (quote_read_fee) - must cover broadcast fees (quote_broadcast_fees) """ assert self.read_enabled, "Read not enabled" assert len(_target_eids) == len(_target_fees), "Length mismatch" self._request_block_hash( _block_number, _target_eids, _target_fees, _lz_receive_gas_limit, _read_gas_limit, ) @external @payable def broadcast_latest_block( _target_eids: DynArray[uint32, MAX_N_BROADCAST], _target_fees: DynArray[uint256, MAX_N_BROADCAST], _lz_receive_gas_limit: uint128, ): """ @notice Broadcast latest confirmed block hash to specified chains @param _target_eids List of chain IDs to broadcast to @param _target_fees List of fees per chain (must match _target_eids length) @param _lz_receive_gas_limit Gas limit for lzReceive (same for all targets) @dev Only broadcast what was received via lzRead to prevent potentially malicious hashes from other sources """ assert self.read_enabled, "Can only broadcast from read-enabled chains" assert self.block_oracle != empty(IBlockOracle), "Oracle not configured" assert len(_target_eids) == len(_target_fees), "Length mismatch" # Get latest block from oracle block_number: uint256 = staticcall self.block_oracle.last_confirmed_block_number() block_hash: bytes32 = staticcall self.block_oracle.get_block_hash(block_number) assert block_hash != empty(bytes32), "No confirmed blocks" # Only broadcast if this block was received via lzRead assert self.received_blocks[block_number] == block_hash, "Unknown source" # Prepare broadcast targets broadcast_targets: DynArray[BroadcastTarget, MAX_N_BROADCAST] = [] for i: uint256 in range(0, len(_target_eids), bound=MAX_N_BROADCAST): broadcast_targets.append(BroadcastTarget(eid=_target_eids[i], fee=_target_fees[i])) self._broadcast_block( block_number, block_hash, BroadcastData(targets=broadcast_targets, gas_limit=_lz_receive_gas_limit), msg.sender, ) @payable @external def lzReceive( _origin: OApp.Origin, _guid: bytes32, _message: Bytes[OApp.MAX_MESSAGE_SIZE], _executor: address, _extraData: Bytes[OApp.MAX_EXTRA_DATA_SIZE], ): """ @notice Handle messages: read responses, and regular messages @dev Two types of messages: 1. Read responses (from read channel) 2. Regular messages (block hash broadcasts from other chains) @param _origin Origin information containing srcEid, sender, and nonce @param _guid Global unique identifier for the message @param _message The encoded message payload containing block number and hash @param _executor Address of the executor for the message @param _extraData Additional data passed by the executor """ # Verify message source OApp._lzReceive(_origin, _guid, _message, _executor, _extraData) if _origin.srcEid == self.read_channel: # Only handle read response if read is enabled assert self.read_enabled, "Read not enabled" # Decode block hash and number from response block_number: uint256 = 0 block_hash: bytes32 = empty(bytes32) block_number, block_hash = abi_decode(_message, (uint256, bytes32)) if block_hash == empty(bytes32): return # Invalid response # Store received block hash self.received_blocks[block_number] = block_hash # Commit block hash to oracle self._commit_block(block_number, block_hash) broadcast_data: BroadcastData = self.broadcast_data[_guid] if len(broadcast_data.targets) > 0: # Verify that attached value covers requested broadcast fees total_fee: uint256 = 0 for target: BroadcastTarget in broadcast_data.targets: total_fee += target.fee assert msg.value >= total_fee, "Insufficient msg.value" # Perform broadcast self._broadcast_block( block_number, block_hash, broadcast_data, self, # dev: refund excess fee to self ) else: # Regular message - decode and commit block hash block_number: uint256 = 0 block_hash: bytes32 = empty(bytes32) block_number, block_hash = abi_decode(_message, (uint256, bytes32)) self._commit_block(block_number, block_hash)
# pragma version ~=0.4.3
# pragma nonreentrancy off
"""
@title Owner-Based Access Control Functions
@custom:contract-name ownable
@license GNU Affero General Public License v3.0 only
@author pcaversaccio
@notice These functions can be used to implement a basic access
control mechanism, where there is an account (an owner)
that can be granted exclusive access to specific functions.
By default, the owner account will be the one that deploys
the contract. This can later be changed with `transfer_ownership`.
An exemplary integration can be found in the ERC-20 implementation here:
https://github.com/pcaversaccio/snekmate/blob/main/src/snekmate/tokens/erc20.vy.
The implementation is inspired by OpenZeppelin's implementation here:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol.
"""
# @dev Returns the address of the current owner.
# @notice If you declare a variable as `public`,
# Vyper automatically generates an `external`
# getter function for the variable.
owner: public(address)
# @dev Emitted when the ownership is transferred
# from `previous_owner` to `new_owner`.
event OwnershipTransferred:
previous_owner: indexed(address)
new_owner: indexed(address)
@deploy
@payable
def __init__():
"""
@dev To omit the opcodes for checking the `msg.value`
in the creation-time EVM bytecode, the constructor
is declared as `payable`.
@notice The `owner` role will be assigned to
the `msg.sender`.
"""
self._transfer_ownership(msg.sender)
@external
def transfer_ownership(new_owner: address):
"""
@dev Transfers the ownership of the contract
to a new account `new_owner`.
@notice Note that this function can only be
called by the current `owner`. Also,
the `new_owner` cannot be the zero address.
@param new_owner The 20-byte address of the new owner.
"""
self._check_owner()
assert new_owner != empty(address), "ownable: new owner is the zero address"
self._transfer_ownership(new_owner)
@external
def renounce_ownership():
"""
@dev Leaves the contract without an owner.
@notice Renouncing ownership will leave the
contract without an owner, thereby
removing any functionality that is
only available to the owner.
"""
self._check_owner()
self._transfer_ownership(empty(address))
@internal
def _check_owner():
"""
@dev Throws if the sender is not the owner.
"""
assert msg.sender == self.owner, "ownable: caller is not the owner"
@internal
def _transfer_ownership(new_owner: address):
"""
@dev Transfers the ownership of the contract
to a new account `new_owner`.
@notice This is an `internal` function without
access restriction.
@param new_owner The 20-byte address of the new owner.
"""
old_owner: address = self.owner
self.owner = new_owner
log OwnershipTransferred(previous_owner=old_owner, new_owner=new_owner)# pragma version 0.4.3 """ @title LayerZero Vyper Constants @license Copyright (c) Curve.Fi, 2025 - all rights reserved @notice Vyper does not allow truly dynamic byte arrays, and requires constants to cap the size of the array. This file contains such constants for the LayerZero OApp. @dev IMPORTANT: Tune these down as much as possible according to intended use case to save on gas. @author curve.fi @custom:security [email protected] """ # dev: THESE CONSTANTS WERE TUNED DOWN TO THE LIMITS OF LZBLOCKRELAY FUNCTIONALITY # Options size limits MAX_OPTIONS_TOTAL_SIZE: constant(uint256) = 54 MAX_OPTION_SINGLE_SIZE: constant(uint256) = 48 # Message size limits MAX_MESSAGE_SIZE: constant(uint256) = 183 MAX_EXTRA_DATA_SIZE: constant(uint256) = 64 # ReadCmdCodecV1 limits MAX_CALLDATA_SIZE: constant(uint256) = 68
# pragma version 0.4.3 """ @title OApp (LayerZero V2 OApp Standard) @notice Vyper implementation of LayerZero OApp standard. This contract implements the OApp interface for cross-chain messaging via LayerZero. It combines the functionality of OAppCore, OAppSender, OAppReceiver, and OAppRead into a single contract. To use _quote/_lzSend, you must provide _options. To build options, OptionsBuilder.vy should be used in your app. To use lzRead functionality, you must use ReadCmdCodecV1.vy to encode read requests. @dev Vyper implementation differs from Solidity OApp in: - message size limits are handled differently (Vyper does not allow infinite bytes arrays, must be capped) - fees are handled differently (payNative, payLzToken are inlined and allow many sends in single tx) @license Copyright (c) Curve.Fi, 2025 - all rights reserved @author curve.fi @custom:security [email protected] """ ################################################################ # MODULES # ################################################################ # Ownership management. Must be initialized in main contract. from snekmate.auth import ownable uses: ownable # Vyper-specific constants from . import VyperConstants as constants ################################################################ # INTERFACES # ################################################################ # ERC20 interface is needed for lzToken fee payment from ethereum.ercs import IERC20 # LayerZero EndpointV2 interface interface ILayerZeroEndpointV2: def quote(_params: MessagingParams, _sender: address) -> MessagingFee: view def send(_params: MessagingParams, _refundAddress: address) -> MessagingReceipt: payable def setDelegate(_delegate: address): nonpayable def eid() -> uint32: view def lzToken() -> address: view ################################################################ # EVENTS # ################################################################ event PeerSet: eid: uint32 peer: bytes32 ################################################################ # CONSTANTS # ################################################################ # Message size limits MAX_MESSAGE_SIZE: constant(uint256) = constants.MAX_MESSAGE_SIZE MAX_OPTIONS_TOTAL_SIZE: constant(uint256) = constants.MAX_OPTIONS_TOTAL_SIZE MAX_EXTRA_DATA_SIZE: constant(uint256) = constants.MAX_EXTRA_DATA_SIZE # Offspec constant, useful for read messages detection READ_CHANNEL_THRESHOLD: constant( uint32 ) = 4294965694 # max(uint32)-1601, 1600 channels reserved for read ################################################################ # STORAGE # ################################################################ # The LayerZero endpoint associated with the given OApp endpoint: public(immutable(ILayerZeroEndpointV2)) # Mapping to store peers associated with corresponding endpoints peers: public(HashMap[uint32, bytes32]) ################################################################ # STRUCTS # ################################################################ struct MessagingParams: dstEid: uint32 receiver: bytes32 message: Bytes[MAX_MESSAGE_SIZE] options: Bytes[MAX_OPTIONS_TOTAL_SIZE] payInLzToken: bool struct MessagingReceipt: guid: bytes32 nonce: uint64 fee: MessagingFee struct MessagingFee: nativeFee: uint256 lzTokenFee: uint256 struct Origin: srcEid: uint32 sender: bytes32 nonce: uint64 ################################################################ # CONSTRUCTOR # ################################################################ @deploy def __init__(_endpoint: address, _delegate: address): """ @notice Initialize OApp with endpoint and delegate @param _endpoint LayerZero endpoint address @param _delegate Address that can manage LZ configurations """ assert _endpoint != empty(address), "Invalid endpoint" assert _delegate != empty(address), "Invalid delegate" # Set up endpoint endpoint = ILayerZeroEndpointV2(_endpoint) # Set delegate for endpoint config extcall endpoint.setDelegate(_delegate) ################################################################ # OAppCore # ################################################################ @external def setPeer(_eid: uint32, _peer: bytes32): """ @notice Sets the peer address (OApp instance) for a corresponding endpoint. @param _eid The endpoint ID. @param _peer The address of the peer to be associated with the corresponding endpoint. @dev Only the owner/admin of the OApp can call this function. @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. @dev Set this to bytes32(0) to remove the peer address. @dev Peer is a bytes32 to accommodate non-evm chains. """ ownable._check_owner() self._setPeer(_eid, _peer) @internal def _setPeer(_eid: uint32, _peer: bytes32): """ @notice Internal function to set peer address @param _eid The endpoint ID. @param _peer The address of the peer to be associated with the corresponding endpoint. """ self.peers[_eid] = _peer log PeerSet(eid=_eid, peer=_peer) @view @internal def _getPeerOrRevert(_eid: uint32) -> bytes32: """ @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set. @param _eid The endpoint ID. @return peer The address of the peer associated with the specified endpoint. """ peer: bytes32 = self.peers[_eid] assert peer != empty(bytes32), "OApp: no peer" return peer @external def setDelegate(_delegate: address): """ @notice Sets the delegate address for the OApp. @param _delegate The address of the delegate to be set. @dev Only the owner/admin of the OApp can call this function. @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract. """ ownable._check_owner() extcall endpoint.setDelegate(_delegate) ################################################################ # OAppRead # ################################################################ @external def setReadChannel(_channelId: uint32, _active: bool): """ @notice Set or unset a read channel for this OApp @param _channelId The channel ID to use for read requests @param _active Whether to activate or deactivate the channel """ ownable._check_owner() peer: bytes32 = convert(self, bytes32) if _active else convert(empty(address), bytes32) self._setPeer(_channelId, peer) ################################################################ # OAppReceiver # ################################################################ # Vyper-specific: # oAppVersion - not implemented @external @view def isComposeMsgSender( _origin: Origin, _message: Bytes[MAX_MESSAGE_SIZE], _sender: address ) -> bool: """ @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. @param _origin The origin information containing the source endpoint and sender address. @param _message The lzReceive payload. @param _sender The sender address. @return isSender Is a valid sender. """ return _sender == self @external @view def allowInitializePath(_origin: Origin) -> bool: """ @notice Checks if the path initialization is allowed based on the provided origin. @param _origin The origin information containing the source endpoint and sender address. @return Whether the path has been initialized. @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received. @dev This defaults to assuming if a peer has been set, its initialized. """ return self.peers[_origin.srcEid] == _origin.sender @external @pure def nextNonce(_srcEid: uint32, _sender: bytes32) -> uint64: """ @notice Retrieves the next nonce for a given source endpoint and sender address. @dev Vyper-specific: If your app relies on ordered execution, you must change this function. @param _srcEid The source endpoint ID. @param _sender The sender address. @return nonce The next nonce. @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement. @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered. @dev This is also enforced by the OApp. @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0. """ return 0 @internal @view def _lzReceive( _origin: Origin, _guid: bytes32, _message: Bytes[MAX_MESSAGE_SIZE], _executor: address, _extraData: Bytes[MAX_EXTRA_DATA_SIZE], ): """ @dev Vyper-specific: This must be called first in external lzReceive implementation. Name changed to _lzReceive due to internal nature of the function. @notice Entry point for receiving messages or packets from the endpoint. @param _origin The origin information containing the source endpoint and sender address. - srcEid: The source chain endpoint ID. - sender: The sender address on the src chain. - nonce: The nonce of the message. @param _guid The unique identifier for the received LayerZero message. @param _message The payload of the received message. @param _executor The address of the executor for the received message. @param _extraData Additional arbitrary data provided by the corresponding executor. """ # Verify that the sender is the endpoint assert msg.sender == endpoint.address, "OApp: only endpoint" # Verify that the message comes from a trusted peer assert self._getPeerOrRevert(_origin.srcEid) == _origin.sender, "OApp: invalid sender" ################################################################ # OAppSender # ################################################################ # Vyper-specific: # oAppVersion - not implemented @internal @view def _quote( _dstEid: uint32, _message: Bytes[MAX_MESSAGE_SIZE], _options: Bytes[MAX_OPTIONS_TOTAL_SIZE], _payInLzToken: bool, ) -> MessagingFee: """ @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation. @param _dstEid The destination endpoint ID. @param _message The message payload. @param _options Additional options for the message. @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens. @return fee The calculated MessagingFee for the message. - nativeFee: The native fee for the message. - lzTokenFee: The LZ token fee for the message. """ return staticcall endpoint.quote( MessagingParams( dstEid=_dstEid, receiver=self._getPeerOrRevert(_dstEid), message=_message, options=_options, payInLzToken=_payInLzToken, ), self, ) @internal @payable def _lzSend( _dstEid: uint32, _message: Bytes[MAX_MESSAGE_SIZE], _options: Bytes[MAX_OPTIONS_TOTAL_SIZE], _fee: MessagingFee, _refundAddress: address, ) -> MessagingReceipt: """ @dev Vyper-specific: fees are treated differently than in Solidity OApp. - _payNative and _payLzToken are inlined. - Multiple sends are supported within single transaction (msg.value >= native_fee) instead of '=='. @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message. @param _dstEid The destination endpoint ID. @param _message The message payload. @param _options Additional options for the message. @param _fee The calculated LayerZero fee for the message. - nativeFee: The native fee. - lzTokenFee: The lzToken fee. @param _refundAddress The address to receive any excess fee values sent to the endpoint. @return receipt The receipt for the sent message. - guid: The unique identifier for the sent message. - nonce: The nonce of the sent message. - fee: The LayerZero fee incurred for the message. """ # Get the peer address for the destination or revert if not set peer: bytes32 = self._getPeerOrRevert(_dstEid) # Handle native fee native_fee: uint256 = _fee.nativeFee if native_fee > 0: assert msg.value >= native_fee, "OApp: not enough fee" lzToken_fee: uint256 = _fee.lzTokenFee if lzToken_fee > 0: # Pay LZ token fee by sending tokens to the endpoint. lzToken: address = staticcall endpoint.lzToken() assert lzToken != empty(address), "OApp: LZ token unavailable" assert extcall IERC20(lzToken).transferFrom(msg.sender, endpoint.address, lzToken_fee, default_return_value=True), "OApp: token transfer failed" return extcall endpoint.send( MessagingParams( dstEid=_dstEid, receiver=peer, message=_message, options=_options, payInLzToken=_fee.lzTokenFee > 0, ), _refundAddress, value=native_fee, )
# pragma version 0.4.3 """ @title LayerZero Options Builder @license Copyright (c) Curve.Fi, 2025 - all rights reserved @author curve.fi @custom:security [email protected] """ # Vyper-specific constants from . import VyperConstants as constants ################################################################ # CONSTANTS # ################################################################ MAX_OPTIONS_TOTAL_SIZE: constant(uint256) = constants.MAX_OPTIONS_TOTAL_SIZE MAX_OPTION_SINGLE_SIZE: constant(uint256) = constants.MAX_OPTION_SINGLE_SIZE # LayerZero protocol constants TYPE_1: constant(uint16) = 1 TYPE_2: constant(uint16) = 2 TYPE_3: constant(uint16) = 3 EXECUTOR_WORKER_ID: constant(uint8) = 1 DVN_WORKER_ID: constant(uint8) = 2 # Option types OPTION_TYPE_LZRECEIVE: constant(uint8) = 1 OPTION_TYPE_NATIVE_DROP: constant(uint8) = 2 OPTION_TYPE_LZCOMPOSE: constant(uint8) = 3 OPTION_TYPE_ORDERED_EXECUTION: constant(uint8) = 4 OPTION_TYPE_LZREAD: constant(uint8) = 5 # DVN option types OPTION_TYPE_DVN: constant(uint8) = 10 OPTION_TYPE_DVN_PRECRIME: constant(uint8) = 1 ################################################################ # OptionsBuilder # ################################################################ # Includes partial implementation of ExecutorOptions.sol @internal @pure def newOptions() -> Bytes[MAX_OPTIONS_TOTAL_SIZE]: """ @notice Creates a new options container with type 3. @return options The newly created options container. """ options: Bytes[MAX_OPTIONS_TOTAL_SIZE] = concat(convert(TYPE_3, bytes2), b"") return options @internal @pure def addExecutorOption( _options: Bytes[MAX_OPTIONS_TOTAL_SIZE], _optionType: uint8, _option: Bytes[MAX_OPTION_SINGLE_SIZE], ) -> Bytes[MAX_OPTIONS_TOTAL_SIZE]: """ @dev Adds an executor option to the existing options. @param _options The existing options container. @param _optionType The type of the executor option. @param _option The encoded data for the executor option. @return options The updated options container. """ assert convert(slice(_options, 0, 2), uint16) == TYPE_3, "OApp: invalid option type" # Account for header bytes: 1 worker + 2 size + 1 type = 4 bytes assert (len(_options) + len(_option) + 4 <= MAX_OPTIONS_TOTAL_SIZE), "OApp: options size exceeded" return concat( convert(_options, Bytes[MAX_OPTIONS_TOTAL_SIZE - MAX_OPTION_SINGLE_SIZE - 4]), # downcast Bytes size, -4 for header convert(EXECUTOR_WORKER_ID, bytes1), convert(convert(len(_option) + 1, uint16), bytes2), # +1 for optionType convert(_optionType, bytes1), _option, ) @internal @pure def addExecutorLzReceiveOption( _options: Bytes[MAX_OPTIONS_TOTAL_SIZE], _gas: uint128, _value: uint128 ) -> Bytes[MAX_OPTIONS_TOTAL_SIZE]: """ @notice Adds an executor LZ receive option to the existing options. @param _options The existing options container. @param _gas The gasLimit used on the lzReceive() function in the OApp. @param _value The msg.value passed to the lzReceive() function in the OApp. @return options The updated options container. @dev When multiples of this option are added, they are summed by the executor eg. if (_gas: 200k, and _value: 1 ether) AND (_gas: 100k, _value: 0.5 ether) are sent in an option to the LayerZeroEndpoint, that becomes (300k, 1.5 ether) when the message is executed on the remote lzReceive() function. @dev Vyper-specific: ExecutorOptions.encodeLzReceiveOption is inlined here. OnlyType3 is not checked here as it is checked in addExecutorOption. """ option: Bytes[MAX_OPTION_SINGLE_SIZE] = b"" gas_bytes: bytes16 = convert(_gas, bytes16) if _value > 0: value_bytes: bytes16 = convert(_value, bytes16) option = concat(gas_bytes, value_bytes) else: option = concat(gas_bytes, b"") # bytes -> Bytes return self.addExecutorOption(_options, OPTION_TYPE_LZRECEIVE, option) @internal @pure def addExecutorNativeDropOption( _options: Bytes[MAX_OPTIONS_TOTAL_SIZE], _amount: uint128, _receiver: bytes32 ) -> Bytes[MAX_OPTIONS_TOTAL_SIZE]: """ @dev Adds an executor native drop option to the existing options. @param _options The existing options container. @param _amount The amount for the native value that is airdropped to the 'receiver'. @param _receiver The receiver address for the native drop option. @return options The updated options container. @dev When multiples of this option are added, they are summed by the executor on the remote chain. """ option: Bytes[MAX_OPTION_SINGLE_SIZE] = concat(convert(_amount, bytes16), _receiver) return self.addExecutorOption(_options, OPTION_TYPE_NATIVE_DROP, option) @internal @pure def addExecutorLzComposeOption( _options: Bytes[MAX_OPTIONS_TOTAL_SIZE], _index: uint16, _gas: uint128, _value: uint128, ) -> Bytes[MAX_OPTIONS_TOTAL_SIZE]: """ @dev Adds an executor LZ compose option to the existing options. @param _options The existing options container. @param _index The index for the lzCompose() function call. @param _gas The gasLimit for the lzCompose() function call. @param _value The msg.value for the lzCompose() function call. @return options The updated options container. @dev When multiples of this option are added, they are summed PER index by the executor on the remote chain. @dev If the OApp sends N lzCompose calls on the remote, you must provide N incremented indexes starting with 0. @dev ie. When your remote OApp composes (N = 3) messages, you must set this option for index 0,1,2 """ option: Bytes[MAX_OPTION_SINGLE_SIZE] = b"" index_bytes: bytes2 = convert(_index, bytes2) gas_bytes: bytes16 = convert(_gas, bytes16) if _value > 0: value_bytes: bytes16 = convert(_value, bytes16) option = concat(index_bytes, gas_bytes, value_bytes) else: option = concat(index_bytes, gas_bytes) return self.addExecutorOption(_options, OPTION_TYPE_LZCOMPOSE, option) @internal @pure def addExecutorOrderedExecutionOption( _options: Bytes[MAX_OPTIONS_TOTAL_SIZE], ) -> Bytes[MAX_OPTIONS_TOTAL_SIZE]: """ @dev Adds an executor ordered execution option to the existing options. @param _options The existing options container. @return options The updated options container. """ return self.addExecutorOption(_options, OPTION_TYPE_ORDERED_EXECUTION, b"") @internal @pure def addExecutorLzReadOption( _options: Bytes[MAX_OPTIONS_TOTAL_SIZE], _gas: uint128, _size: uint32, _value: uint128 ) -> Bytes[MAX_OPTIONS_TOTAL_SIZE]: """ @dev Adds an executor LZ read option to the existing options. @param _options The existing options container. @param _gas The gasLimit for the lzRead() function call. @param _size The size of the lzRead() function call. @param _value The msg.value for the lzRead return function call. @return options The updated options container. """ option: Bytes[MAX_OPTION_SINGLE_SIZE] = b"" gas_bytes: bytes16 = convert(_gas, bytes16) size_bytes: bytes4 = convert(_size, bytes4) if _value > 0: value_bytes: bytes16 = convert(_value, bytes16) option = concat(gas_bytes, size_bytes, value_bytes) else: option = concat(gas_bytes, size_bytes) return self.addExecutorOption(_options, OPTION_TYPE_LZREAD, option) @internal @pure def addDVNOption( _options: Bytes[MAX_OPTIONS_TOTAL_SIZE], _dvnIdx: uint8, _optionType: uint8, _option: Bytes[MAX_OPTION_SINGLE_SIZE], ) -> Bytes[MAX_OPTIONS_TOTAL_SIZE]: """ @dev Adds a DVN option to the existing options. @param _options The existing options container. @param _dvnIdx The DVN index for the DVN option. @param _optionType The type of the DVN option. @param _option The encoded data for the DVN option. @return options The updated options container. """ assert convert(slice(_options, 0, 2), uint16) == TYPE_3, "OApp: invalid option type" # Account for header bytes: 1 worker + 2 size + 1 dvnIdx + 1 type = 5 bytes assert (len(_options) + len(_option) + 5 <= MAX_OPTIONS_TOTAL_SIZE), "OApp: dvn options size exceeded" return concat( convert(_options, Bytes[MAX_OPTIONS_TOTAL_SIZE - MAX_OPTION_SINGLE_SIZE - 5]), # downcast Bytes size convert(DVN_WORKER_ID, bytes1), convert(convert(len(_option) + 2, uint16), bytes2), # +2 for optionType and dvnIdx convert(_dvnIdx, bytes1), convert(_optionType, bytes1), _option, ) @internal @pure def addDVNPreCrimeOption( _options: Bytes[MAX_OPTIONS_TOTAL_SIZE], _dvnIdx: uint8 ) -> Bytes[MAX_OPTIONS_TOTAL_SIZE]: """ @dev Adds a DVN pre-crime option to the existing options. @param _options The existing options container. @param _dvnIdx The DVN index for the pre-crime option. @return options The updated options container. """ return self.addDVNOption(_options, _dvnIdx, OPTION_TYPE_DVN_PRECRIME, b"")
# pragma version 0.4.3 """ @title LayerZero Read Command Codec V1 @license Copyright (c) Curve.Fi, 2025 - all rights reserved @author curve.fi @custom:security [email protected] """ # Vyper-specific constants from . import VyperConstants as constants ################################################################ # CONSTANTS # ################################################################ # Vyper Byte size limits MAX_MESSAGE_SIZE: constant(uint256) = constants.MAX_MESSAGE_SIZE MAX_CALLDATA_SIZE: constant(uint256) = constants.MAX_CALLDATA_SIZE MAX_EVM_CALL_REQUESTS: constant(uint256) = (MAX_MESSAGE_SIZE - 6 - 39) // (MAX_CALLDATA_SIZE + 42) # +6 is general header, see encode() # +39 is single compute command length, see appendEVMCallComputeV1 # +42 is per-call header length, see appendEVMCallRequestV1 # Read codec constants CMD_VERSION: constant(uint16) = 1 REQUEST_VERSION: constant(uint8) = 1 RESOLVER_TYPE_SINGLE_VIEW_EVM_CALL: constant(uint16) = 1 COMPUTE_VERSION: constant(uint8) = 1 COMPUTE_TYPE_SINGLE_VIEW_EVM_CALL: constant(uint16) = 1 # Compute settings COMPUTE_SETTING_MAP_ONLY: constant(uint8) = 0 COMPUTE_SETTING_REDUCE_ONLY: constant(uint8) = 1 COMPUTE_SETTING_MAP_REDUCE: constant(uint8) = 2 COMPUTE_SETTING_NONE: constant(uint8) = 3 ################################################################ # STRUCTS # ################################################################ struct EVMCallRequestV1: appRequestLabel: uint16 # Label identifying the application or type of request (can be use in lzCompute) targetEid: uint32 # Target endpoint ID (representing a target blockchain) isBlockNum: bool # True if the request = block number, false if timestamp blockNumOrTimestamp: uint64 # Block number or timestamp to use in the request confirmations: uint16 # Number of block confirmations on top of the requested block number or timestamp before the view function can be called to: address # Address of the target contract on the target chain callData: Bytes[MAX_CALLDATA_SIZE] # Calldata for the contract call struct EVMCallComputeV1: computeSetting: uint8 # Compute setting (0 = map only, 1 = reduce only, 2 = map reduce) targetEid: uint32 # Target endpoint ID (representing a target blockchain) isBlockNum: bool # True if the request = block number, false if timestamp blockNumOrTimestamp: uint64 # Block number or timestamp to use in the request confirmations: uint16 # Number of block confirmations on top of the requested block number or timestamp before the view function can be called to: address # Address of the target contract on the target chain # ################################################################ # # ReadCmdCodecV1 LIBRARY # # ################################################################ # Vyper-specific: # decode - not implemented # decodeRequestsV1 - not implemented # decodeEVMCallRequestV1 - not implemented # decodeEVMCallComputeV1 - not implemented @internal @pure def _decodeCmdAppLabel(_cmd: Bytes[MAX_MESSAGE_SIZE]) -> uint16: cmdVersion: uint16 = convert(slice(_cmd, 0, 2), uint16) assert cmdVersion == CMD_VERSION, "OApp: InvalidVersion" return convert(slice(_cmd, 2, 2), uint16) @internal @pure def _decodeRequestV1AppRequestLabel(_request: Bytes[MAX_MESSAGE_SIZE]) -> uint16: requestVersion: uint8 = convert(slice(_request, 0, 1), uint8) assert requestVersion == REQUEST_VERSION, "OApp: InvalidVersion" return convert(slice(_request, 1, 2), uint16) @internal @pure def encode( _appCmdLabel: uint16, _evmCallRequests: DynArray[EVMCallRequestV1, MAX_EVM_CALL_REQUESTS], _evmCallCompute: EVMCallComputeV1 = empty(EVMCallComputeV1), ) -> Bytes[MAX_MESSAGE_SIZE]: cmd: Bytes[MAX_MESSAGE_SIZE] = concat( convert(CMD_VERSION, bytes2), convert(_appCmdLabel, bytes2), convert(convert(len(_evmCallRequests), uint16), bytes2), ) for call_request: EVMCallRequestV1 in _evmCallRequests: cmd = self.appendEVMCallRequestV1(cmd, call_request) if _evmCallCompute.targetEid != 0: cmd = self.appendEVMCallComputeV1(cmd, _evmCallCompute) return cmd @internal @pure def appendEVMCallRequestV1( _cmd: Bytes[MAX_MESSAGE_SIZE], _request: EVMCallRequestV1 ) -> Bytes[MAX_MESSAGE_SIZE]: """ @notice Appends an EVM call request to the command @param _cmd The existing command bytes @param _request The EVM call request to append @return The updated command bytes """ # dev: assert that appending new request to existing command will not exceed the max size assert (len(_cmd) + MAX_CALLDATA_SIZE + 42 <= MAX_MESSAGE_SIZE), "OApp: Command too large" # dev: 42 is length of all fields excluding existing command and callData return concat( # current cmd convert(_cmd, Bytes[MAX_MESSAGE_SIZE - MAX_CALLDATA_SIZE - 42]), # downcast Bytes size # newCmd convert(REQUEST_VERSION, bytes1), convert(_request.appRequestLabel, bytes2), convert(RESOLVER_TYPE_SINGLE_VIEW_EVM_CALL, bytes2), convert(convert(len(_request.callData) + 35, uint16), bytes2), convert(_request.targetEid, bytes4), # new request convert(_request.isBlockNum, bytes1), convert(_request.blockNumOrTimestamp, bytes8), convert(_request.confirmations, bytes2), convert(_request.to, bytes20), _request.callData, ) @internal @pure def appendEVMCallComputeV1( _cmd: Bytes[MAX_MESSAGE_SIZE], _compute: EVMCallComputeV1 ) -> Bytes[MAX_MESSAGE_SIZE]: """ @notice Appends an EVM call compute to the command @param _cmd The existing command bytes @param _compute The EVM call compute to append @return The updated command bytes """ assert len(_cmd) + 39 <= MAX_MESSAGE_SIZE, "OApp: Command too large" # dev: 39 is length of all fields excluding existing command return concat( convert(_cmd, Bytes[MAX_MESSAGE_SIZE - 39]), # downcast Bytes size convert(COMPUTE_VERSION, bytes1), convert(COMPUTE_TYPE_SINGLE_VIEW_EVM_CALL, bytes2), convert(_compute.computeSetting, bytes1), convert(_compute.targetEid, bytes4), convert(_compute.isBlockNum, bytes1), convert(_compute.blockNumOrTimestamp, bytes8), convert(_compute.confirmations, bytes2), convert(_compute.to, bytes20), )
{
"outputSelection": {
"0/1/contracts/messengers/LZBlockRelay.vy": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
},
"search_paths": [
"0/1/contracts",
"0/1",
"0/1/.venv/lib/python3.12/site-packages",
"."
],
"evmVersion": "paris"
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"name":"block_number","type":"uint256"},{"indexed":true,"name":"block_hash","type":"bytes32"},{"components":[{"name":"eid","type":"uint32"},{"name":"fee","type":"uint256"}],"indexed":false,"name":"targets","type":"tuple[]"}],"name":"BlockHashBroadcast","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previous_owner","type":"address"},{"indexed":true,"name":"new_owner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"eid","type":"uint32"},{"indexed":false,"name":"peer","type":"bytes32"}],"name":"PeerSet","type":"event"},{"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"new_owner","type":"address"}],"name":"transfer_ownership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounce_ownership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"arg0","type":"uint32"}],"name":"peers","outputs":[{"name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_eid","type":"uint32"},{"name":"_peer","type":"bytes32"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"srcEid","type":"uint32"},{"name":"sender","type":"bytes32"},{"name":"nonce","type":"uint64"}],"name":"_origin","type":"tuple"},{"name":"_message","type":"bytes"},{"name":"_sender","type":"address"}],"name":"isComposeMsgSender","outputs":[{"name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"name":"srcEid","type":"uint32"},{"name":"sender","type":"bytes32"},{"name":"nonce","type":"uint64"}],"name":"_origin","type":"tuple"}],"name":"allowInitializePath","outputs":[{"name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_srcEid","type":"uint32"},{"name":"_sender","type":"bytes32"}],"name":"nextNonce","outputs":[{"name":"","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[{"name":"_is_enabled","type":"bool"},{"name":"_read_channel","type":"uint32"},{"name":"_mainnet_eid","type":"uint32"},{"name":"_mainnet_view","type":"address"}],"name":"set_read_config","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_eids","type":"uint32[]"},{"name":"_peers","type":"address[]"}],"name":"set_peers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_oracle","type":"address"}],"name":"set_block_oracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_amount","type":"uint256"}],"name":"withdraw_eth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"name":"_read_gas_limit","type":"uint128"},{"name":"_value","type":"uint128"}],"name":"quote_read_fee","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_target_eids","type":"uint32[]"},{"name":"_lz_receive_gas_limit","type":"uint128"}],"name":"quote_broadcast_fees","outputs":[{"name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_target_eids","type":"uint32[]"},{"name":"_target_fees","type":"uint256[]"},{"name":"_lz_receive_gas_limit","type":"uint128"},{"name":"_read_gas_limit","type":"uint128"}],"name":"request_block_hash","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"name":"_target_eids","type":"uint32[]"},{"name":"_target_fees","type":"uint256[]"},{"name":"_lz_receive_gas_limit","type":"uint128"},{"name":"_read_gas_limit","type":"uint128"},{"name":"_block_number","type":"uint256"}],"name":"request_block_hash","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"name":"_target_eids","type":"uint32[]"},{"name":"_target_fees","type":"uint256[]"},{"name":"_lz_receive_gas_limit","type":"uint128"}],"name":"broadcast_latest_block","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"name":"srcEid","type":"uint32"},{"name":"sender","type":"bytes32"},{"name":"nonce","type":"uint64"}],"name":"_origin","type":"tuple"},{"name":"_guid","type":"bytes32"},{"name":"_message","type":"bytes"},{"name":"_executor","type":"address"},{"name":"_extraData","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"read_enabled","outputs":[{"name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"read_channel","outputs":[{"name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainnet_eid","outputs":[{"name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainnet_block_view","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"block_oracle","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_endpoint","type":"address"}],"outputs":[],"stateMutability":"nonpayable","type":"constructor"}]Contract Creation Code
6130df5150346101e45760206133006000396000518060a01c6101e45761014052610028610093565b32604052610034610059565b61014051604052326060526100476100a1565b6130df6101e9610000396130ff610000f35b6001546060526040516001556040516060517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060006080a3565b3360405261009f610059565b565b6040516101235760208060e05260106080527f496e76616c696420656e64706f696e740000000000000000000000000000000060a05260808160e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060c0528060040160dcfd5b6060516101a55760208060e05260106080527f496e76616c69642064656c65676174650000000000000000000000000000000060a05260808160e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060c0528060040160dcfd5b6040516130df526130df5163ca5eb5e160805260605160a052803b156101e457600060806024609c6000855af16101e1573d600060003e3d6000fd5b50565b600080fd60003560e01c60026015820660011b6130b501601e39600051565b638da5cb5b811861003657346130b05760015460405260206040f35b63bb0b6a538118610073576024361034176130b0576004358060201c6130b057604052600260405160205260005260406000205460605260206060f35b63ca5eb5e181186117ce576024361034176130b0576004358060a01c6130b0576101005261009f6117d0565b60206130df60003960005163ca5eb5e1610120526101005161014052803b156130b0576000610120602461013c6000855af16100e0573d600060003e3d6000fd5b50005b63f0350c0481186101d0576024361034176130b0576004358060a01c6130b0576101005261010f6117d0565b610100516101bf576020806101a0526026610120527f6f776e61626c653a206e6577206f776e657220697320746865207a65726f2061610140527f646472657373000000000000000000000000000000000000000000000000000061016052610120816101a00160468160468460045afa156130b0578051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610180528060040161019cfd5b610100516040526101ce611857565b005b63bf23b95a81186117ce576044361034176130b05760043560040160208135116130b0578035600081602081116130b057801561022f57905b8060051b6020850101358060201c6130b0578160051b6101200152600101818118610209575b50508061010052505060243560040160208135116130b0578035600081602081116130b057801561028257905b8060051b6020850101358060a01c6130b0578160051b610540015260010181811861025c575b5050806105205250506102936117d0565b61052051610100511815610323576020806109a0526013610940527f496e76616c69642070656572206172726179730000000000000000000000000061096052610940816109a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610980528060040161099cfd5b600061010051602081116130b057801561038557905b806109405261094051610100518110156130b05760051b610120015160405261094051610520518110156130b05760051b610540015160605261037a611891565b600101818118610339575b5050005b63b15e13ee81186103b057346130b0576103a16117d0565b60006040526103ae611857565b005b6313137d6581186117ce5760e33611156130b0576004358060201c6130b05761184052602435611860526044358060401c6130b05761188052608435600401803560b781116130b05750602081350180826118a037505060a4358060a01c6130b0576119805260c4356004018035604081116130b057506060816119a037506118405161014052611860516101605261188051610180526064356101a05260206118a05101806101c0826118a060045afa156130b05750611980516102a05260606102c060606119a060045afa156130b05761048a612e98565b60045461184051186107255760035461051f57602080611a60526010611a00527f52656164206e6f7420656e61626c656400000000000000000000000000000000611a2052611a0081611a600181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0611a405280600401611a5cfd5b604036611a003760406118a051186130b0576118a0516118c001611900116130b0576118c051611a40526118e051611a6052611a408051611a00526020810151611a205250611a20511561078057611a20516009611a0051602052600052604060002055611a0051604052611a2051606052610599612fd0565b60086064356020526000526040600020805460208160061b01600081601f0160051c604181116130b05780156105e357905b808501548160051b611a4001526001018181186105cb575b5050505060418101546122605250611a405115610780576000612280526000611a4051602081116130b057801561065357905b8060061b611a600180516122a05260208101516122c05250612280516122c0518082018281106130b0579050905061228052600101818118610616575b5050612280513410156106e2576020806123005260166122a0527f496e73756666696369656e74206d73672e76616c7565000000000000000000006122c0526122a0816123000181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06122e052806004016122fcfd5b611a005161062052611a205161064052611a405160208160061b018061066082611a4060045afa156130b057505061226051610e805230610ea052610780612ca6565b604036611a003760406118a051186130b0576118a0516118c001611900116130b0576118c051611a40526118e051611a6052611a408051611a00526020810151611a205250611a0051604052611a2051606052610780612fd0565b005b635e280f1181186107a057346130b05760206130df60403960206040f35b636eb7385a8118610973576044361034176130b0576004358060801c6130b057610d20526024358060801c6130b057610d405260035461088257602080610de0526027610d60527f52656164206e6f7420656e61626c6564202d2063616c6c207365745f72656164610d80527f5f636f6e66696700000000000000000000000000000000000000000000000000610da052610d6081610de00160478160478460045afa156130b0578051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610dc05280600401610ddcfd5b600061098052610893610e40611e68565b610e40602081510180610d60828460045afa156130b05750506108b7610ea0611f71565b610ea06056610e4060568360045afa156130b0575060566102206056610e4060045afa156130b057610d20516102805260406102a052610d40516102c052610900610ea06121cc565b610ea06056610f0060568360045afa156130b057506056610e406056610f0060045afa156130b0576020600454610140526020610d6051018061016082610d6060045afa156130b0575060566102406056610e4060045afa156130b05760006102a05261096e610ea0612380565b610ea0f35b63994283aa81186117ce5760633611156130b05760043560040160208135116130b0578035600081602081116130b05780156109d157905b8060051b6020850101358060201c6130b0578160051b61186001526001018181186109ab575b50508061184052505060243560040160208135116130b057803560208160051b018083611c60375050506044358060801c6130b05761208052600354610ab95760208061212052602b6120a0527f43616e206f6e6c792062726f6164636173742066726f6d20726561642d656e616120c0527f626c656420636861696e730000000000000000000000000000000000000000006120e0526120a08161212001604b81604b8460045afa156130b0578051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0612100528060040161211cfd5b600754610b42576020806121005260156120a0527f4f7261636c65206e6f7420636f6e6669677572656400000000000000000000006120c0526120a0816121000181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06120e052806004016120fcfd5b611c6051611840511815610bd25760208061210052600f6120a0527f4c656e677468206d69736d6174636800000000000000000000000000000000006120c0526120a0816121000181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06120e052806004016120fcfd5b60075463017a494d6120c05260206120c060046120dc845afa610bfa573d600060003e3d6000fd5b60203d106130b0576120c09050516120a052600754639724283f6120e0526120a0516121005260206120e060246120fc845afa610c3c573d600060003e3d6000fd5b60203d106130b0576120e09050516120c0526120c051610cd8576020806121405260136120e0527f4e6f20636f6e6669726d656420626c6f636b7300000000000000000000000000612100526120e0816121400181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0612120528060040161213cfd5b6120c05160096120a0516020526000526040600020541815610d765760208061214052600e6120e0527f556e6b6e6f776e20736f75726365000000000000000000000000000000000000612100526120e0816121400181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0612120528060040161213cfd5b60006120e052600061184051602081116130b0578015610df557905b80612900526120e051601f81116130b0578060061b6121000161290051611840518110156130b05760051b6118600151815261290051611c60518110156130b05760051b611c800151602082015250600181016120e05250600101818118610d92575b50506120a051610620526120c051610640526120e05160208160061b0180610660826120e060045afa156130b057505061208051610e805233610ea052610e3a612ca6565b005b633400288b8118610e7f576044361034176130b0576004358060201c6130b05761010052610e686117d0565b61010051604052602435606052610e7d611891565b005b6382413eac81186117ce5760a4361034176130b0576004358060201c6130b0576040526024356060526044358060401c6130b057608052606435600401803560b781116130b057506020813501808260a03750506084358060a01c6130b057610180523061018051146101a05260206101a0f35b63ff7bd03d8118610f48576064361034176130b0576004358060201c6130b0576040526024356060526044358060401c6130b05760805260605160026040516020526000526040600020541460a052602060a0f35b638d00131681186117ce57346130b05760045460405260206040f35b637d25a05e81186117ce576044361034176130b0576004358060201c6130b057604052600060605260206060f35b632be655cd81186117ce576084361034176130b0576004358060011c6130b057610100526024358060201c6130b057610120526044358060201c6130b057610140526064358060a01c6130b05761016052610feb6117d0565b63fffff9bf61012051121561107c576020806101e0526014610180527f496e76616c69642072656164206368616e6e656c0000000000000000000000006101a052610180816101e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06101c052806004016101dcfd5b6101005161108b5760006110a2565b610140511561109f576101605115156110a2565b60005b6110ce57610100516110c757610140516110c05761016051156110d1565b60006110d1565b60006110d1565b60015b611157576020806101e0526013610180527f496e76616c6964207265616420636f6e666967000000000000000000000000006101a052610180816101e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06101c052806004016101dcfd5b60035461116557600061116f565b6101205160045414155b15611187576004546040526000606052611187611891565b61010051600355610120516004556101405160055561016051600655610100516111b25760006111b4565b305b6101805261012051604052610180516060526111ce611891565b005b63bd0a229481186117ce576024361034176130b0576004358060a01c6130b057610100526111fc6117d0565b61010051600755005b6330a95e6781186112c4576024361034176130b0576112226117d0565b6004354710156112ae57602080610160526014610100527f496e73756666696369656e742062616c616e636500000000000000000000000061012052610100816101600181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610140528060040161015cfd5b6000600060006000600435336000f1156130b057005b633516c5be81186117ce57346130b05760035460405260206040f35b63742a6dcb8118611535576044361034176130b05760043560040160208135116130b0578035600081602081116130b057801561133f57905b8060051b6020850101358060201c6130b0578160051b6105400152600101818118611319575b5050806105205250506024358060801c6130b05761094052604036610a60376040610a4052610a40606061096060608360045afa156130b057506000610a405261138a610ec0611f71565b610ec06056610e6060568360045afa156130b0575060566102206056610e6060045afa156130b057610940516102805260006102a0526113cb610ec061249a565b610ec06056610f2060568360045afa156130b057506056610e606056610f2060045afa156130b057600061052051602081116130b05780156114d457905b8060051b6105400151610ec0526002610ec051602052600052604060002054610ee052610ee05161145957610a4051601f81116130b05760008160051b610a60015260018101610a4052506114c9565b610ec0516101405260206109605101806101608261096060045afa156130b0575060566102406056610e6060045afa156130b05760006102a05261149e610f00612380565b610f0051610f4052610a4051601f81116130b057610f40518160051b610a60015260018101610a4052505b600101818118611409575b5050602080610ec05280610ec0016000610a40518083528060051b600082602081116130b057801561152057905b8060051b610a6001518160051b602088010152600101818118611502575b50508201602001915050905081019050610ec0f35b634193098181186117ce5760a33611156130b057608435612900525b60043560040160208135116130b0578035600081602081116130b057801561159b57905b8060051b6020850101358060201c6130b0578160051b6120a00152600101818118611575575b50508061208052505060243560040160208135116130b057803560208160051b0180836124a0375050506044358060801c6130b0576128c0526064358060801c6130b0576128e05260035461166c57602080612980526010612920527f52656164206e6f7420656e61626c65640000000000000000000000000000000061294052612920816129800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0612960528060040161297cfd5b6124a0516120805118156116fc5760208061298052600f612920527f4c656e677468206d69736d61746368000000000000000000000000000000000061294052612920816129800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0612960528060040161297cfd5b61290051610d20526120805160208160051b0180610d408261208060045afa156130b05750506124a05160208160051b0180611160826124a060045afa156130b05750506128c051611580526128e0516115a0526117586129d3565b005b63b5775a2c81186117ce5760833611156130b057600061290052611551565b63b5c3cbd081186117ce57346130b05760055460405260206040f35b6386e3938581186117ce57346130b05760065460405260206040f35b636959a37f81186117ce57346130b05760075460405260206040f35b5b005b6001543318156118555760208060a05260206040527f6f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b565b6001546060526040516001556040516060517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060006080a3565b60605160026040516020526000526040600020557f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b60405160805260605160a05260406080a1565b60b7604051604481018181106130b0579050602a81018181106130b05790501115611980576020806102c0526017610260527f4f4170703a20436f6d6d616e6420746f6f206c6172676500000000000000000061028052610260816102c00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06102a052806004016102bcfd5b60006049604051116130b057604080516020820183610280018281848460045afa156130b057505080830192505050600160f81b816102800152600181019050610120518060f01b9050816102800152600281019050600160f01b8161028001526002810190506101e051602381018181106130b05790508060101c6130b0578060f01b9050816102800152600281019050610140518060e01b9050816102800152600481019050610160518060f81b9050816102800152600181019050610180518060c01b90508161028001526008810190506101a0518060f01b90508161028001526002810190506101c0518060601b90508161028001526014810190506101e051816102800181818361020060045afa156130b057508082019150508061026052610260905060208151018083828460045afa156130b057505050565b60b7604051602781018181106130b05790501115611b5a576020806102405260176101e0527f4f4170703a20436f6d6d616e6420746f6f206c61726765000000000000000000610200526101e0816102400181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610220528060040161023cfd5b60006090604051116130b057604080516020820183610200018281848460045afa156130b057505080830192505050600160f81b816102000152600181019050600160f01b816102000152600281019050610120518060f81b9050816102000152600181019050610140518060e01b9050816102000152600481019050610160518060f81b9050816102000152600181019050610180518060c01b90508161020001526008810190506101a0518060f01b90508161020001526002810190506101c0518060601b9050816102000152601481019050806101e0526101e0905060208151018083828460045afa156130b057505050565b6000600160f01b816106a00152600281019050610360518060f01b9050816106a00152600281019050610380518060101c6130b0578060f01b9050816106a001526002810190508061068052610680905080516105a05260208101516105c05250600061038051600181116130b0578015611dbd57905b61014081026103a00180516106805260208101516106a05260408101516106c05260608101516106e05260808101516107005260a08101516107205260c08101606461074060648360045afa156130b057505060206105a05101806040826105a060045afa156130b0575061068051610120526106a051610140526106c051610160526106e05161018052610700516101a052610720516101c05260646101e0606461074060045afa156130b057611d806107c06118d9565b6107c06020815101806108a0828460045afa156130b057505060206108a05101806105a0826108a060045afa156130b05750600101818118611cc7575b50506105005115611e4e5760206105a05101806040826105a060045afa156130b057506104e05161012052610500516101405261052051610160526105405161018052610560516101a052610580516101c052611e1b610680611ac0565b610680602081510180610760828460045afa156130b057505060206107605101806105a08261076060045afa156130b057505b60206105a051018082826105a060045afa156130b0575050565b637b754d2d610a2452600461098051610a44526001610a6452604001610a2052610a2060646109a060648360045afa156130b057506001610a2052600554610a40526000610a6052428060401c6130b057610a80526001610aa052600654610ac0526064610ae060646109a060045afa156130b057600161036052610a20516103a052610a40516103c052610a60516103e052610a805161040052610aa05161042052610ac0516104405260646104606064610ae060045afa156130b05760016103805260c0366104e037611f3e610c40611c50565b610c40602081510180610b60828460045afa156130b05750506020610b605101808282610b6060045afa156130b0575050565b6000600360f01b8160e001526002810190506020600060a05260a0018160e00150508060c05260c0905080516040526020810151606052506056816056604060045afa156130b05750565b6003600160405111156130b057606051610140526002610120526101206020810151815160200360031b1c90501815612071576020806101c0526019610160527f4f4170703a20696e76616c6964206f7074696f6e20747970650000000000000061018052610160816101c00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06101a052806004016101bcfd5b603660405160c0518082018281106130b05790509050600481018181106130b0579050111561211c5760208061018052601b610120527f4f4170703a206f7074696f6e732073697a65206578636565646564000000000061014052610120816101800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610160528060040161017cfd5b60006002604051116130b0576040805160208201836101400181518152505080830192505050600160f81b81610140015260018101905060c051600181018181106130b05790508060101c6130b0578060f01b905081610140015260028101905060a0518060f81b905081610140015260018101905060c051816101400181818360e060045afa156130b057508082019150508061012052610120905060568260568360045afa156130b0575050565b60006102e052610280518060801b9050610340526102a0518060e01b90506103605260016102c051121561223b57600061034051816103a0015260108101905061036051816103a001526004810190508061038052610380905080516102e05260208101516103005250612298565b6102c0518060801b905061038052600061034051816103c0015260108101905061036051816103c0015260048101905061038051816103c00152601081019050806103a0526103a0905060446102e060448360045afa156130b057505b60566040605661022060045afa156130b057600560a052605060c060506102e060045afa156130b0576122cc610380611fbc565b61038060568260568360045afa156130b0575050565b60026040516020526000526040600020546060526060516123785760208060e052600d6080527f4f4170703a206e6f20706565720000000000000000000000000000000000000060a05260808160e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060c0528060040160dcfd5b606051815250565b60206130df60003960005163ddc28c586102e05260408061030052806103000160a0610140518252610140516040526123ba6102c06122e2565b6102c05160208301528060408301528082016020610160510180828261016060045afa156130b057508051806020830101601f82600003163682375050601f19601f82516020010116905081019050806060830152808201605681605661024060045afa156130b0578051806020830101601f82600003163682375050601f19601f825160200101169050810190506102a051608083015290508101905030610320525060406102e06102246102fc845afa61247b573d600060003e3d6000fd5b60403d106130b0576102e0905080518252602081015160208301525050565b60006102c052610280518060801b90506103205260016102a05112156124fe57600061032051816103800152601081019050602060006103405261034001816103800150508061036052610360905080516102c05260208101516102e05250612549565b6102a0518060801b905061034052600061032051816103800152601081019050610340518161038001526010810190508061036052610360905080516102c05260208101516102e052505b60566040605661022060045afa156130b057600160a052605060c060506102c060045afa156130b05761257d610340611fbc565b61034060568260568360045afa156130b0575050565b610140516040526125a56103206122e2565b61032051610300526102a05161032052610320511561264b576103205134101561264b576020806103a0526014610340527f4f4170703a206e6f7420656e6f7567682066656500000000000000000000000061036052610340816103a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610380528060040161039cfd5b6102c0516103405261034051156128575760206130df60003960005163e4fe1d94610380526020610380600461039c845afa61268c573d600060003e3d6000fd5b3d602081183d602010021880610380016103a0116130b057610380518060a01c6130b0576103c052506103c09050516103605261036051612749576020806103e052601a610380527f4f4170703a204c5a20746f6b656e20756e617661696c61626c650000000000006103a052610380816103e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06103c052806004016103dcfd5b610360516323b872dd61038052336103a05260206130df6103c039610340516103e0526020610380606461039c6000855af161278a573d600060003e3d6000fd5b3d6127a157803b156130b0576001610400526127cb565b3d602081183d602010021880610380016103a0116130b057610380518060011c6130b05761040052505b6104009050516128575760208061048052601b610420527f4f4170703a20746f6b656e207472616e73666572206661696c6564000000000061044052610420816104800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610460528060040161047cfd5b60206130df600039600051632637a4506103605260408061038052806103800160a06101405182526103005160208301528060408301528082016020610160510180828261016060045afa156130b057508051806020830101601f82600003163682375050601f19601f82516020010116905081019050806060830152808201605681605661024060045afa156130b0578051806020830101601f82600003163682375050601f19601f825160200101169050810190506102c051151560808301529050810190506102e0516103a05250608061036061022461037c61032051855af1612949573d600060003e3d6000fd5b3d608081183d608010021880610360016103e0116130b05780610360016103e0116130b057610360516105a052610380518060401c6130b0576105c05280610360016103e0116130b0576103a0516105e0526103c05161060052506105a0905080518252602081015160208301526040810160408301815181526020820151602082015250505050565b60006115c0526000611de0526000610d4051602081116130b0578015612a8557905b80611e00526115c051601f81116130b0578060061b6115e001611e0051610d40518110156130b05760051b610d6001518152611e0051611160518110156130b05760051b6111800151602082015250600181016115c05250611de051611e0051611160518110156130b05760051b61118001518082018281106130b05790509050611de0526001018181186129f5575b505034611de0511115612b1457602080611e60526012611e00527f496e73756666696369656e742076616c75650000000000000000000000000000611e2052611e0081611e600181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0611e405280600401611e5cfd5b610d205161098052612b27611ee0611e68565b611ee0602081510180611e00828460045afa156130b0575050612b4b611f40611f71565b611f406056611ee060568360045afa156130b0575060566102206056611ee060045afa156130b0576115a0516102805260406102a052611de0518060801c6130b0576102c052612b9c611f406121cc565b611f406056611fa060568360045afa156130b057506056611ee06056611fa060045afa156130b05734611f40526000611f6052600454610140526020611e0051018061016082611e0060045afa156130b0575060566102406056611ee060045afa156130b057611f40516102a052611f60516102c052336102e052612c22612000612593565b6120008051611f80526020810151611fa052604081018051611fc0526020810151611fe05250506008611f805160205260005260406000206115c05160208160061b01600081601f0160051c604181116130b0578015612c9657905b8060051b6115c0015181860155600101818118612c7e575b5050505061158051604182015550565b61062051610fc05261064051610fe0526040610fa052610fa06060610ec060608360045afa156130b05750612cdc611000611f71565b6110006056610fa060568360045afa156130b0575060566102206056610fa060045afa156130b057610e80516102805260006102a052612d1d61100061249a565b611000605661106060568360045afa156130b057506056610fa0605661106060045afa156130b057600061066051602081116130b0578015612dff57905b8060061b610680018051611000526020810151611020525060026110005160205260005260406000205415612df457611020516110405260006110605261100051610140526020610ec051018061016082610ec060045afa156130b0575060566102406056610fa060045afa156130b057611040516102a052611060516102c052610ea0516102e052612def611080612593565b611080505b600101818118612d5b575b505061064051610620517f12a7d4a99e6a8e491eb7429684890e803da2899b11916334f8486a84d538c99f6020806110005280611000016000610660518083528060061b600082602081116130b0578015612e8257905b8060061b610680018160061b602088010181518152602082015160208201525050600101818118612e56575b50508201602001915050905081019050611000a3565b60206130df600039600051331815612f2c57602080610380526013610320527f4f4170703a206f6e6c7920656e64706f696e740000000000000000000000000061034052610320816103800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610360528060040161037cfd5b6101605161014051604052612f426103206122e2565b610320511815612fce576020806103a0526014610340527f4f4170703a20696e76616c69642073656e64657200000000000000000000000061036052610340816103a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610380528060040161039cfd5b565b6007546130525760208060e05260156080527f4f7261636c65206e6f7420636f6e66696775726564000000000000000000000060a05260808160e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060c0528060040160dcfd5b60075463939074b160805260405160a05260605160c052602060806044609c6000855af1613085573d600060003e3d6000fd5b3d602081183d60201002188060800160a0116130b0576080518060011c6130b05760e0525060e05050565b600080fd038917cd0f6411d017cd0f9200e317cd0ef3001a17cd175a17cd078217950e3c177917cd120517b112e08558208fb5198b48d36d068c84bd5c9a6a870170c9a18f6c7aa1b83582264d32d3d2941930df81182a1820a16576797065728300040300380000000000000000000000001a44076050125825900e736c501f859c50fe728c
Deployed Bytecode
0x60003560e01c60026015820660011b6130b501601e39600051565b638da5cb5b811861003657346130b05760015460405260206040f35b63bb0b6a538118610073576024361034176130b0576004358060201c6130b057604052600260405160205260005260406000205460605260206060f35b63ca5eb5e181186117ce576024361034176130b0576004358060a01c6130b0576101005261009f6117d0565b60206130df60003960005163ca5eb5e1610120526101005161014052803b156130b0576000610120602461013c6000855af16100e0573d600060003e3d6000fd5b50005b63f0350c0481186101d0576024361034176130b0576004358060a01c6130b0576101005261010f6117d0565b610100516101bf576020806101a0526026610120527f6f776e61626c653a206e6577206f776e657220697320746865207a65726f2061610140527f646472657373000000000000000000000000000000000000000000000000000061016052610120816101a00160468160468460045afa156130b0578051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610180528060040161019cfd5b610100516040526101ce611857565b005b63bf23b95a81186117ce576044361034176130b05760043560040160208135116130b0578035600081602081116130b057801561022f57905b8060051b6020850101358060201c6130b0578160051b6101200152600101818118610209575b50508061010052505060243560040160208135116130b0578035600081602081116130b057801561028257905b8060051b6020850101358060a01c6130b0578160051b610540015260010181811861025c575b5050806105205250506102936117d0565b61052051610100511815610323576020806109a0526013610940527f496e76616c69642070656572206172726179730000000000000000000000000061096052610940816109a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610980528060040161099cfd5b600061010051602081116130b057801561038557905b806109405261094051610100518110156130b05760051b610120015160405261094051610520518110156130b05760051b610540015160605261037a611891565b600101818118610339575b5050005b63b15e13ee81186103b057346130b0576103a16117d0565b60006040526103ae611857565b005b6313137d6581186117ce5760e33611156130b0576004358060201c6130b05761184052602435611860526044358060401c6130b05761188052608435600401803560b781116130b05750602081350180826118a037505060a4358060a01c6130b0576119805260c4356004018035604081116130b057506060816119a037506118405161014052611860516101605261188051610180526064356101a05260206118a05101806101c0826118a060045afa156130b05750611980516102a05260606102c060606119a060045afa156130b05761048a612e98565b60045461184051186107255760035461051f57602080611a60526010611a00527f52656164206e6f7420656e61626c656400000000000000000000000000000000611a2052611a0081611a600181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0611a405280600401611a5cfd5b604036611a003760406118a051186130b0576118a0516118c001611900116130b0576118c051611a40526118e051611a6052611a408051611a00526020810151611a205250611a20511561078057611a20516009611a0051602052600052604060002055611a0051604052611a2051606052610599612fd0565b60086064356020526000526040600020805460208160061b01600081601f0160051c604181116130b05780156105e357905b808501548160051b611a4001526001018181186105cb575b5050505060418101546122605250611a405115610780576000612280526000611a4051602081116130b057801561065357905b8060061b611a600180516122a05260208101516122c05250612280516122c0518082018281106130b0579050905061228052600101818118610616575b5050612280513410156106e2576020806123005260166122a0527f496e73756666696369656e74206d73672e76616c7565000000000000000000006122c0526122a0816123000181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06122e052806004016122fcfd5b611a005161062052611a205161064052611a405160208160061b018061066082611a4060045afa156130b057505061226051610e805230610ea052610780612ca6565b604036611a003760406118a051186130b0576118a0516118c001611900116130b0576118c051611a40526118e051611a6052611a408051611a00526020810151611a205250611a0051604052611a2051606052610780612fd0565b005b635e280f1181186107a057346130b05760206130df60403960206040f35b636eb7385a8118610973576044361034176130b0576004358060801c6130b057610d20526024358060801c6130b057610d405260035461088257602080610de0526027610d60527f52656164206e6f7420656e61626c6564202d2063616c6c207365745f72656164610d80527f5f636f6e66696700000000000000000000000000000000000000000000000000610da052610d6081610de00160478160478460045afa156130b0578051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610dc05280600401610ddcfd5b600061098052610893610e40611e68565b610e40602081510180610d60828460045afa156130b05750506108b7610ea0611f71565b610ea06056610e4060568360045afa156130b0575060566102206056610e4060045afa156130b057610d20516102805260406102a052610d40516102c052610900610ea06121cc565b610ea06056610f0060568360045afa156130b057506056610e406056610f0060045afa156130b0576020600454610140526020610d6051018061016082610d6060045afa156130b0575060566102406056610e4060045afa156130b05760006102a05261096e610ea0612380565b610ea0f35b63994283aa81186117ce5760633611156130b05760043560040160208135116130b0578035600081602081116130b05780156109d157905b8060051b6020850101358060201c6130b0578160051b61186001526001018181186109ab575b50508061184052505060243560040160208135116130b057803560208160051b018083611c60375050506044358060801c6130b05761208052600354610ab95760208061212052602b6120a0527f43616e206f6e6c792062726f6164636173742066726f6d20726561642d656e616120c0527f626c656420636861696e730000000000000000000000000000000000000000006120e0526120a08161212001604b81604b8460045afa156130b0578051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0612100528060040161211cfd5b600754610b42576020806121005260156120a0527f4f7261636c65206e6f7420636f6e6669677572656400000000000000000000006120c0526120a0816121000181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06120e052806004016120fcfd5b611c6051611840511815610bd25760208061210052600f6120a0527f4c656e677468206d69736d6174636800000000000000000000000000000000006120c0526120a0816121000181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06120e052806004016120fcfd5b60075463017a494d6120c05260206120c060046120dc845afa610bfa573d600060003e3d6000fd5b60203d106130b0576120c09050516120a052600754639724283f6120e0526120a0516121005260206120e060246120fc845afa610c3c573d600060003e3d6000fd5b60203d106130b0576120e09050516120c0526120c051610cd8576020806121405260136120e0527f4e6f20636f6e6669726d656420626c6f636b7300000000000000000000000000612100526120e0816121400181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0612120528060040161213cfd5b6120c05160096120a0516020526000526040600020541815610d765760208061214052600e6120e0527f556e6b6e6f776e20736f75726365000000000000000000000000000000000000612100526120e0816121400181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0612120528060040161213cfd5b60006120e052600061184051602081116130b0578015610df557905b80612900526120e051601f81116130b0578060061b6121000161290051611840518110156130b05760051b6118600151815261290051611c60518110156130b05760051b611c800151602082015250600181016120e05250600101818118610d92575b50506120a051610620526120c051610640526120e05160208160061b0180610660826120e060045afa156130b057505061208051610e805233610ea052610e3a612ca6565b005b633400288b8118610e7f576044361034176130b0576004358060201c6130b05761010052610e686117d0565b61010051604052602435606052610e7d611891565b005b6382413eac81186117ce5760a4361034176130b0576004358060201c6130b0576040526024356060526044358060401c6130b057608052606435600401803560b781116130b057506020813501808260a03750506084358060a01c6130b057610180523061018051146101a05260206101a0f35b63ff7bd03d8118610f48576064361034176130b0576004358060201c6130b0576040526024356060526044358060401c6130b05760805260605160026040516020526000526040600020541460a052602060a0f35b638d00131681186117ce57346130b05760045460405260206040f35b637d25a05e81186117ce576044361034176130b0576004358060201c6130b057604052600060605260206060f35b632be655cd81186117ce576084361034176130b0576004358060011c6130b057610100526024358060201c6130b057610120526044358060201c6130b057610140526064358060a01c6130b05761016052610feb6117d0565b63fffff9bf61012051121561107c576020806101e0526014610180527f496e76616c69642072656164206368616e6e656c0000000000000000000000006101a052610180816101e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06101c052806004016101dcfd5b6101005161108b5760006110a2565b610140511561109f576101605115156110a2565b60005b6110ce57610100516110c757610140516110c05761016051156110d1565b60006110d1565b60006110d1565b60015b611157576020806101e0526013610180527f496e76616c6964207265616420636f6e666967000000000000000000000000006101a052610180816101e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06101c052806004016101dcfd5b60035461116557600061116f565b6101205160045414155b15611187576004546040526000606052611187611891565b61010051600355610120516004556101405160055561016051600655610100516111b25760006111b4565b305b6101805261012051604052610180516060526111ce611891565b005b63bd0a229481186117ce576024361034176130b0576004358060a01c6130b057610100526111fc6117d0565b61010051600755005b6330a95e6781186112c4576024361034176130b0576112226117d0565b6004354710156112ae57602080610160526014610100527f496e73756666696369656e742062616c616e636500000000000000000000000061012052610100816101600181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610140528060040161015cfd5b6000600060006000600435336000f1156130b057005b633516c5be81186117ce57346130b05760035460405260206040f35b63742a6dcb8118611535576044361034176130b05760043560040160208135116130b0578035600081602081116130b057801561133f57905b8060051b6020850101358060201c6130b0578160051b6105400152600101818118611319575b5050806105205250506024358060801c6130b05761094052604036610a60376040610a4052610a40606061096060608360045afa156130b057506000610a405261138a610ec0611f71565b610ec06056610e6060568360045afa156130b0575060566102206056610e6060045afa156130b057610940516102805260006102a0526113cb610ec061249a565b610ec06056610f2060568360045afa156130b057506056610e606056610f2060045afa156130b057600061052051602081116130b05780156114d457905b8060051b6105400151610ec0526002610ec051602052600052604060002054610ee052610ee05161145957610a4051601f81116130b05760008160051b610a60015260018101610a4052506114c9565b610ec0516101405260206109605101806101608261096060045afa156130b0575060566102406056610e6060045afa156130b05760006102a05261149e610f00612380565b610f0051610f4052610a4051601f81116130b057610f40518160051b610a60015260018101610a4052505b600101818118611409575b5050602080610ec05280610ec0016000610a40518083528060051b600082602081116130b057801561152057905b8060051b610a6001518160051b602088010152600101818118611502575b50508201602001915050905081019050610ec0f35b634193098181186117ce5760a33611156130b057608435612900525b60043560040160208135116130b0578035600081602081116130b057801561159b57905b8060051b6020850101358060201c6130b0578160051b6120a00152600101818118611575575b50508061208052505060243560040160208135116130b057803560208160051b0180836124a0375050506044358060801c6130b0576128c0526064358060801c6130b0576128e05260035461166c57602080612980526010612920527f52656164206e6f7420656e61626c65640000000000000000000000000000000061294052612920816129800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0612960528060040161297cfd5b6124a0516120805118156116fc5760208061298052600f612920527f4c656e677468206d69736d61746368000000000000000000000000000000000061294052612920816129800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0612960528060040161297cfd5b61290051610d20526120805160208160051b0180610d408261208060045afa156130b05750506124a05160208160051b0180611160826124a060045afa156130b05750506128c051611580526128e0516115a0526117586129d3565b005b63b5775a2c81186117ce5760833611156130b057600061290052611551565b63b5c3cbd081186117ce57346130b05760055460405260206040f35b6386e3938581186117ce57346130b05760065460405260206040f35b636959a37f81186117ce57346130b05760075460405260206040f35b5b005b6001543318156118555760208060a05260206040527f6f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b565b6001546060526040516001556040516060517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060006080a3565b60605160026040516020526000526040600020557f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b60405160805260605160a05260406080a1565b60b7604051604481018181106130b0579050602a81018181106130b05790501115611980576020806102c0526017610260527f4f4170703a20436f6d6d616e6420746f6f206c6172676500000000000000000061028052610260816102c00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06102a052806004016102bcfd5b60006049604051116130b057604080516020820183610280018281848460045afa156130b057505080830192505050600160f81b816102800152600181019050610120518060f01b9050816102800152600281019050600160f01b8161028001526002810190506101e051602381018181106130b05790508060101c6130b0578060f01b9050816102800152600281019050610140518060e01b9050816102800152600481019050610160518060f81b9050816102800152600181019050610180518060c01b90508161028001526008810190506101a0518060f01b90508161028001526002810190506101c0518060601b90508161028001526014810190506101e051816102800181818361020060045afa156130b057508082019150508061026052610260905060208151018083828460045afa156130b057505050565b60b7604051602781018181106130b05790501115611b5a576020806102405260176101e0527f4f4170703a20436f6d6d616e6420746f6f206c61726765000000000000000000610200526101e0816102400181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610220528060040161023cfd5b60006090604051116130b057604080516020820183610200018281848460045afa156130b057505080830192505050600160f81b816102000152600181019050600160f01b816102000152600281019050610120518060f81b9050816102000152600181019050610140518060e01b9050816102000152600481019050610160518060f81b9050816102000152600181019050610180518060c01b90508161020001526008810190506101a0518060f01b90508161020001526002810190506101c0518060601b9050816102000152601481019050806101e0526101e0905060208151018083828460045afa156130b057505050565b6000600160f01b816106a00152600281019050610360518060f01b9050816106a00152600281019050610380518060101c6130b0578060f01b9050816106a001526002810190508061068052610680905080516105a05260208101516105c05250600061038051600181116130b0578015611dbd57905b61014081026103a00180516106805260208101516106a05260408101516106c05260608101516106e05260808101516107005260a08101516107205260c08101606461074060648360045afa156130b057505060206105a05101806040826105a060045afa156130b0575061068051610120526106a051610140526106c051610160526106e05161018052610700516101a052610720516101c05260646101e0606461074060045afa156130b057611d806107c06118d9565b6107c06020815101806108a0828460045afa156130b057505060206108a05101806105a0826108a060045afa156130b05750600101818118611cc7575b50506105005115611e4e5760206105a05101806040826105a060045afa156130b057506104e05161012052610500516101405261052051610160526105405161018052610560516101a052610580516101c052611e1b610680611ac0565b610680602081510180610760828460045afa156130b057505060206107605101806105a08261076060045afa156130b057505b60206105a051018082826105a060045afa156130b0575050565b637b754d2d610a2452600461098051610a44526001610a6452604001610a2052610a2060646109a060648360045afa156130b057506001610a2052600554610a40526000610a6052428060401c6130b057610a80526001610aa052600654610ac0526064610ae060646109a060045afa156130b057600161036052610a20516103a052610a40516103c052610a60516103e052610a805161040052610aa05161042052610ac0516104405260646104606064610ae060045afa156130b05760016103805260c0366104e037611f3e610c40611c50565b610c40602081510180610b60828460045afa156130b05750506020610b605101808282610b6060045afa156130b0575050565b6000600360f01b8160e001526002810190506020600060a05260a0018160e00150508060c05260c0905080516040526020810151606052506056816056604060045afa156130b05750565b6003600160405111156130b057606051610140526002610120526101206020810151815160200360031b1c90501815612071576020806101c0526019610160527f4f4170703a20696e76616c6964206f7074696f6e20747970650000000000000061018052610160816101c00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06101a052806004016101bcfd5b603660405160c0518082018281106130b05790509050600481018181106130b0579050111561211c5760208061018052601b610120527f4f4170703a206f7074696f6e732073697a65206578636565646564000000000061014052610120816101800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610160528060040161017cfd5b60006002604051116130b0576040805160208201836101400181518152505080830192505050600160f81b81610140015260018101905060c051600181018181106130b05790508060101c6130b0578060f01b905081610140015260028101905060a0518060f81b905081610140015260018101905060c051816101400181818360e060045afa156130b057508082019150508061012052610120905060568260568360045afa156130b0575050565b60006102e052610280518060801b9050610340526102a0518060e01b90506103605260016102c051121561223b57600061034051816103a0015260108101905061036051816103a001526004810190508061038052610380905080516102e05260208101516103005250612298565b6102c0518060801b905061038052600061034051816103c0015260108101905061036051816103c0015260048101905061038051816103c00152601081019050806103a0526103a0905060446102e060448360045afa156130b057505b60566040605661022060045afa156130b057600560a052605060c060506102e060045afa156130b0576122cc610380611fbc565b61038060568260568360045afa156130b0575050565b60026040516020526000526040600020546060526060516123785760208060e052600d6080527f4f4170703a206e6f20706565720000000000000000000000000000000000000060a05260808160e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060c0528060040160dcfd5b606051815250565b60206130df60003960005163ddc28c586102e05260408061030052806103000160a0610140518252610140516040526123ba6102c06122e2565b6102c05160208301528060408301528082016020610160510180828261016060045afa156130b057508051806020830101601f82600003163682375050601f19601f82516020010116905081019050806060830152808201605681605661024060045afa156130b0578051806020830101601f82600003163682375050601f19601f825160200101169050810190506102a051608083015290508101905030610320525060406102e06102246102fc845afa61247b573d600060003e3d6000fd5b60403d106130b0576102e0905080518252602081015160208301525050565b60006102c052610280518060801b90506103205260016102a05112156124fe57600061032051816103800152601081019050602060006103405261034001816103800150508061036052610360905080516102c05260208101516102e05250612549565b6102a0518060801b905061034052600061032051816103800152601081019050610340518161038001526010810190508061036052610360905080516102c05260208101516102e052505b60566040605661022060045afa156130b057600160a052605060c060506102c060045afa156130b05761257d610340611fbc565b61034060568260568360045afa156130b0575050565b610140516040526125a56103206122e2565b61032051610300526102a05161032052610320511561264b576103205134101561264b576020806103a0526014610340527f4f4170703a206e6f7420656e6f7567682066656500000000000000000000000061036052610340816103a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610380528060040161039cfd5b6102c0516103405261034051156128575760206130df60003960005163e4fe1d94610380526020610380600461039c845afa61268c573d600060003e3d6000fd5b3d602081183d602010021880610380016103a0116130b057610380518060a01c6130b0576103c052506103c09050516103605261036051612749576020806103e052601a610380527f4f4170703a204c5a20746f6b656e20756e617661696c61626c650000000000006103a052610380816103e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a06103c052806004016103dcfd5b610360516323b872dd61038052336103a05260206130df6103c039610340516103e0526020610380606461039c6000855af161278a573d600060003e3d6000fd5b3d6127a157803b156130b0576001610400526127cb565b3d602081183d602010021880610380016103a0116130b057610380518060011c6130b05761040052505b6104009050516128575760208061048052601b610420527f4f4170703a20746f6b656e207472616e73666572206661696c6564000000000061044052610420816104800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610460528060040161047cfd5b60206130df600039600051632637a4506103605260408061038052806103800160a06101405182526103005160208301528060408301528082016020610160510180828261016060045afa156130b057508051806020830101601f82600003163682375050601f19601f82516020010116905081019050806060830152808201605681605661024060045afa156130b0578051806020830101601f82600003163682375050601f19601f825160200101169050810190506102c051151560808301529050810190506102e0516103a05250608061036061022461037c61032051855af1612949573d600060003e3d6000fd5b3d608081183d608010021880610360016103e0116130b05780610360016103e0116130b057610360516105a052610380518060401c6130b0576105c05280610360016103e0116130b0576103a0516105e0526103c05161060052506105a0905080518252602081015160208301526040810160408301815181526020820151602082015250505050565b60006115c0526000611de0526000610d4051602081116130b0578015612a8557905b80611e00526115c051601f81116130b0578060061b6115e001611e0051610d40518110156130b05760051b610d6001518152611e0051611160518110156130b05760051b6111800151602082015250600181016115c05250611de051611e0051611160518110156130b05760051b61118001518082018281106130b05790509050611de0526001018181186129f5575b505034611de0511115612b1457602080611e60526012611e00527f496e73756666696369656e742076616c75650000000000000000000000000000611e2052611e0081611e600181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0611e405280600401611e5cfd5b610d205161098052612b27611ee0611e68565b611ee0602081510180611e00828460045afa156130b0575050612b4b611f40611f71565b611f406056611ee060568360045afa156130b0575060566102206056611ee060045afa156130b0576115a0516102805260406102a052611de0518060801c6130b0576102c052612b9c611f406121cc565b611f406056611fa060568360045afa156130b057506056611ee06056611fa060045afa156130b05734611f40526000611f6052600454610140526020611e0051018061016082611e0060045afa156130b0575060566102406056611ee060045afa156130b057611f40516102a052611f60516102c052336102e052612c22612000612593565b6120008051611f80526020810151611fa052604081018051611fc0526020810151611fe05250506008611f805160205260005260406000206115c05160208160061b01600081601f0160051c604181116130b0578015612c9657905b8060051b6115c0015181860155600101818118612c7e575b5050505061158051604182015550565b61062051610fc05261064051610fe0526040610fa052610fa06060610ec060608360045afa156130b05750612cdc611000611f71565b6110006056610fa060568360045afa156130b0575060566102206056610fa060045afa156130b057610e80516102805260006102a052612d1d61100061249a565b611000605661106060568360045afa156130b057506056610fa0605661106060045afa156130b057600061066051602081116130b0578015612dff57905b8060061b610680018051611000526020810151611020525060026110005160205260005260406000205415612df457611020516110405260006110605261100051610140526020610ec051018061016082610ec060045afa156130b0575060566102406056610fa060045afa156130b057611040516102a052611060516102c052610ea0516102e052612def611080612593565b611080505b600101818118612d5b575b505061064051610620517f12a7d4a99e6a8e491eb7429684890e803da2899b11916334f8486a84d538c99f6020806110005280611000016000610660518083528060061b600082602081116130b0578015612e8257905b8060061b610680018160061b602088010181518152602082015160208201525050600101818118612e56575b50508201602001915050905081019050611000a3565b60206130df600039600051331815612f2c57602080610380526013610320527f4f4170703a206f6e6c7920656e64706f696e740000000000000000000000000061034052610320816103800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610360528060040161037cfd5b6101605161014051604052612f426103206122e2565b610320511815612fce576020806103a0526014610340527f4f4170703a20696e76616c69642073656e64657200000000000000000000000061036052610340816103a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610380528060040161039cfd5b565b6007546130525760208060e05260156080527f4f7261636c65206e6f7420636f6e66696775726564000000000000000000000060a05260808160e00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060c0528060040160dcfd5b60075463939074b160805260405160a05260605160c052602060806044609c6000855af1613085573d600060003e3d6000fd5b3d602081183d60201002188060800160a0116130b0576080518060011c6130b05760e0525060e05050565b600080fd038917cd0f6411d017cd0f9200e317cd0ef3001a17cd175a17cd078217950e3c177917cd120517b112e00000000000000000000000001a44076050125825900e736c501f859c50fe728c
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001a44076050125825900e736c501f859c50fe728c
-----Decoded View---------------
Arg [0] : _endpoint (address): 0x1a44076050125825900e736c501f859c50fE728c
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000001a44076050125825900e736c501f859c50fe728c
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$30.62
Net Worth in FRAX
36.652613
Token Allocations
ETH
54.74%
POL
38.71%
BNB
3.96%
Others
2.58%
Multichain Portfolio | 35 Chains
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.