Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- SignalService
- Optimization enabled
- true
- Compiler version
- v0.8.24+commit.e11b9ed9
- Optimization runs
- 200
- EVM Version
- cancun
- Verified at
- 2024-05-27T09:04:02.960268Z
contracts/signal/SignalService.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;import "../common/EssentialContract.sol";import "../common/LibStrings.sol";import "../libs/LibTrieProof.sol";import "./ISignalService.sol";/// @title SignalService/// @notice See the documentation in {ISignalService} for more details./// @dev Labeled in AddressResolver as "signal_service"./// @custom:security-contact security@taiko.xyzcontract SignalService is EssentialContract, ISignalService {/// @notice Mapping to store the top blockId./// @dev Slot 1.mapping(uint64 chainId => mapping(bytes32 kind => uint64 blockId)) public topBlockId;/// @notice Mapping to store the authorized addresses./// @dev Slot 2.mapping(address addr => bool authorized) public isAuthorized;uint256[48] private __gap;struct CacheAction {bytes32 rootHash;bytes32 signalRoot;uint64 chainId;uint64 blockId;bool isFullProof;bool isLastHop;CacheOption option;}error SS_EMPTY_PROOF();error SS_INVALID_HOPS_WITH_LOOP();error SS_INVALID_LAST_HOP_CHAINID();error SS_INVALID_MID_HOP_CHAINID();error SS_INVALID_STATE();error SS_SIGNAL_NOT_FOUND();error SS_UNAUTHORIZED();
contracts/common/AddressResolver.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";import "./IAddressManager.sol";import "./IAddressResolver.sol";/// @title AddressResolver/// @notice See the documentation in {IAddressResolver}./// @custom:security-contact security@taiko.xyzabstract contract AddressResolver is IAddressResolver, Initializable {/// @notice Address of the AddressManager.address public addressManager;uint256[49] private __gap;error RESOLVER_DENIED();error RESOLVER_INVALID_MANAGER();error RESOLVER_UNEXPECTED_CHAINID();error RESOLVER_ZERO_ADDR(uint64 chainId, bytes32 name);/// @dev Modifier that ensures the caller is the resolved address of a given/// name./// @param _name The name to check against.modifier onlyFromNamed(bytes32 _name) {if (msg.sender != resolve(_name, true)) revert RESOLVER_DENIED();_;}/// @dev Modifier that ensures the caller is a resolved address to either _name1 or _name2/// name./// @param _name1 The first name to check against./// @param _name2 The second name to check against.modifier onlyFromNamedEither(bytes32 _name1, bytes32 _name2) {if (msg.sender != resolve(_name1, true) && msg.sender != resolve(_name2, true)) {revert RESOLVER_DENIED();}_;}/// @custom:oz-upgrades-unsafe-allow constructorconstructor() {
contracts/common/EssentialContract.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";import "./AddressResolver.sol";import "../libs/LibNetwork.sol";/// @title EssentialContract/// @custom:security-contact security@taiko.xyzabstract contract EssentialContract is UUPSUpgradeable, Ownable2StepUpgradeable, AddressResolver {uint8 private constant _FALSE = 1;uint8 private constant _TRUE = 2;/// @dev The slot in transient storage of the reentry lock./// This is the result of keccak256("ownerUUPS.reentry_slot") plus 1. The addition aims to/// prevent hash collisions with slots defined in EIP-1967, where slots are derived by/// keccak256("something") - 1, and with slots in SignalService, calculated directly with/// keccak256("something").bytes32 private constant _REENTRY_SLOT =0xa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b;/// @dev Slot 1.uint8 private __reentry;uint8 private __paused;uint64 public lastUnpausedAt;uint256[49] private __gap;/// @notice Emitted when the contract is paused./// @param account The account that paused the contract.event Paused(address account);/// @notice Emitted when the contract is unpaused./// @param account The account that unpaused the contract.event Unpaused(address account);error INVALID_PAUSE_STATUS();error FUNC_NOT_IMPLEMENTED();error REENTRANT_CALL();
contracts/common/IAddressManager.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;/// @title IAddressManager/// @notice Manages a mapping of (chainId, name) pairs to Ethereum addresses./// @custom:security-contact security@taiko.xyzinterface IAddressManager {/// @notice Gets the address mapped to a specific chainId-name pair./// @dev Note that in production, this method shall be a pure function/// without any storage access./// @param _chainId The chainId for which the address needs to be fetched./// @param _name The name for which the address needs to be fetched./// @return Address associated with the chainId-name pair.function getAddress(uint64 _chainId, bytes32 _name) external view returns (address);}
contracts/common/IAddressResolver.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;/// @title IAddressResolver/// @notice This contract acts as a bridge for name-to-address resolution./// It delegates the resolution to the AddressManager. By separating the logic,/// we can maintain flexibility in address management without affecting the/// resolving process./// @dev Note that the address manager should be changed using upgradability, there/// is no setAddressManager() function to guarantee atomicity across all/// contracts that are resolvers./// @custom:security-contact security@taiko.xyzinterface IAddressResolver {/// @notice Resolves a name to its address deployed on this chain./// @param _name Name whose address is to be resolved./// @param _allowZeroAddress If set to true, does not throw if the resolved/// address is `address(0)`./// @return Address associated with the given name.function resolve(bytes32 _name,bool _allowZeroAddress)externalviewreturns (address payable);/// @notice Resolves a name to its address deployed on a specified chain./// @param _chainId The chainId of interest./// @param _name Name whose address is to be resolved./// @param _allowZeroAddress If set to true, does not throw if the resolved/// address is `address(0)`./// @return Address associated with the given name on the specified/// chain.function resolve(uint64 _chainId,bytes32 _name,bool _allowZeroAddress)externalviewreturns (address payable);
contracts/common/LibStrings.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;/// @title LibStrings/// @custom:security-contact security@taiko.xyzlibrary LibStrings {bytes32 internal constant B_ASSIGNMENT_HOOK = bytes32("assignment_hook");bytes32 internal constant B_AUTOMATA_DCAP_ATTESTATION = bytes32("automata_dcap_attestation");bytes32 internal constant B_BRIDGE = bytes32("bridge");bytes32 internal constant B_BRIDGE_WATCHDOG = bytes32("bridge_watchdog");bytes32 internal constant B_BRIDGED_ERC1155 = bytes32("bridged_erc1155");bytes32 internal constant B_BRIDGED_ERC20 = bytes32("bridged_erc20");bytes32 internal constant B_BRIDGED_ERC721 = bytes32("bridged_erc721");bytes32 internal constant B_CHAIN_WATCHDOG = bytes32("chain_watchdog");bytes32 internal constant B_ERC1155_VAULT = bytes32("erc1155_vault");bytes32 internal constant B_ERC20_VAULT = bytes32("erc20_vault");bytes32 internal constant B_ERC721_VAULT = bytes32("erc721_vault");bytes32 internal constant B_PROPOSER = bytes32("proposer");bytes32 internal constant B_PROPOSER_ONE = bytes32("proposer_one");bytes32 internal constant B_PROVER_ASSIGNMENT = bytes32("PROVER_ASSIGNMENT");bytes32 internal constant B_PROVER_SET = bytes32("prover_set");bytes32 internal constant B_QUOTA_MANAGER = bytes32("quota_manager");bytes32 internal constant B_SGX_WATCHDOG = bytes32("sgx_watchdog");bytes32 internal constant B_SIGNAL_SERVICE = bytes32("signal_service");bytes32 internal constant B_TAIKO = bytes32("taiko");bytes32 internal constant B_TAIKO_TOKEN = bytes32("taiko_token");bytes32 internal constant B_TIER_GUARDIAN = bytes32("tier_guardian");bytes32 internal constant B_TIER_GUARDIAN_MINORITY = bytes32("tier_guardian_minority");bytes32 internal constant B_TIER_PROVIDER = bytes32("tier_provider");bytes32 internal constant B_TIER_SGX = bytes32("tier_sgx");bytes32 internal constant B_TIER_SGX_ZKVM = bytes32("tier_sgx_zkvm");bytes32 internal constant B_WITHDRAWER = bytes32("withdrawer");bytes32 internal constant H_RETURN_LIVENESS_BOND = keccak256("RETURN_LIVENESS_BOND");bytes32 internal constant H_SIGNAL_ROOT = keccak256("SIGNAL_ROOT");bytes32 internal constant H_STATE_ROOT = keccak256("STATE_ROOT");}
contracts/libs/LibNetwork.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;/// @title LibNetworklibrary LibNetwork {uint256 internal constant MAINNET = 1;uint256 internal constant ROPSTEN = 2;uint256 internal constant RINKEBY = 4;uint256 internal constant GOERLI = 5;uint256 internal constant KOVAN = 42;uint256 internal constant HOLESKY = 17_000;uint256 internal constant SEPOLIA = 11_155_111;uint64 internal constant TAIKO = 167_000;/// @dev Checks if the chain ID represents an Ethereum testnet./// @param _chainId The chain ID./// @return true if the chain ID represents an Ethereum testnet, false otherwise.function isEthereumTestnet(uint256 _chainId) internal pure returns (bool) {return _chainId == LibNetwork.ROPSTEN || _chainId == LibNetwork.RINKEBY|| _chainId == LibNetwork.GOERLI || _chainId == LibNetwork.KOVAN|| _chainId == LibNetwork.HOLESKY || _chainId == LibNetwork.SEPOLIA;}/// @dev Checks if the chain ID represents an Ethereum testnet or the Etheruem mainnet./// @param _chainId The chain ID./// @return true if the chain ID represents an Ethereum testnet or the Etheruem mainnet, false/// otherwise.function isEthereumMainnetOrTestnet(uint256 _chainId) internal pure returns (bool) {return _chainId == LibNetwork.MAINNET || isEthereumTestnet(_chainId);}/// @dev Checks if the chain ID represents the Taiko L2 mainnet./// @param _chainId The chain ID./// @return true if the chain ID represents the Taiko L2 mainnet.function isTaikoMainnet(uint256 _chainId) internal pure returns (bool) {return _chainId == TAIKO;}/// @dev Checks if the chain ID represents an internal Taiko devnet's base layer./// @param _chainId The chain ID.
contracts/libs/LibTrieProof.sol
// SPDX-License-Identifier: MIT// _____ _ _ _ _// |_ _|_ _(_) |_____ | | __ _| |__ ___// | |/ _` | | / / _ \ | |__/ _` | '_ (_-<// |_|\__,_|_|_\_\___/ |____\__,_|_.__/__/pragma solidity 0.8.24;import "../thirdparty/optimism/rlp/RLPReader.sol";import "../thirdparty/optimism/rlp/RLPWriter.sol";import "../thirdparty/optimism/trie/SecureMerkleTrie.sol";/// @title LibTrieProof/// @custom:security-contact security@taiko.xyzlibrary LibTrieProof {// The consensus format representing account is RLP encoded in the// following order: nonce, balance, storageHash, codeHash.uint256 private constant _ACCOUNT_FIELD_INDEX_STORAGE_HASH = 2;error LTP_INVALID_ACCOUNT_PROOF();error LTP_INVALID_INCLUSION_PROOF();/// @notice Verifies that the value of a slot in the storage of an account is value.////// @param _rootHash The merkle root of state tree or the account tree. If accountProof's length/// is zero, it is used as the account's storage root, otherwise it will be used as the state/// root./// @param _addr The address of contract./// @param _slot The slot in the contract./// @param _value The value to be verified./// @param _accountProof The account proof/// @param _storageProof The storage proof/// @return storageRoot_ The account's storage rootfunction verifyMerkleProof(bytes32 _rootHash,address _addr,bytes32 _slot,bytes32 _value,bytes[] memory _accountProof,bytes[] memory _storageProof)
contracts/signal/ISignalService.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;/// @title ISignalService/// @notice The SignalService contract serves as a secure cross-chain message/// passing system. It defines methods for sending and verifying signals with/// merkle proofs. The trust assumption is that the target chain has secure/// access to the merkle root (such as Taiko injects it in the anchor/// transaction). With this, verifying a signal is reduced to simply verifying/// a merkle proof./// @custom:security-contact security@taiko.xyzinterface ISignalService {enum CacheOption {CACHE_NOTHING,CACHE_SIGNAL_ROOT,CACHE_STATE_ROOT,CACHE_BOTH}struct HopProof {/// @notice This hop's destination chain ID. If there is a next hop, this ID is the next/// hop's source chain ID.uint64 chainId;/// @notice The ID of a source chain block whose state root has been synced to the hop's/// destination chain./// Note that this block ID must be greater than or equal to the block ID where the signal/// was sent on the source chain.uint64 blockId;/// @notice The state root or signal root of the source chain at the above blockId. This/// value has been synced to the destination chain./// @dev To get both the blockId and the rootHash, apps should subscribe to the/// ChainDataSynced event or query `topBlockId` first using the source chain's ID and/// LibStrings.H_STATE_ROOT to get the most recent block ID synced, then call/// `getSyncedChainData` to read the synchronized data.bytes32 rootHash;/// @notice Options to cache either the state roots or signal roots of middle-hops to the/// current chain.CacheOption cacheOption;/// @notice The signal service's account proof. If this value is empty, then `rootHash` will/// be used as the signal root, otherwise, `rootHash` will be used as the state root.bytes[] accountProof;
contracts/thirdparty/optimism/Bytes.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;/// @title Bytes/// @notice Bytes is a library for manipulating byte arrays.library Bytes {/// @custom:attribution https://github.com/GNSPS/solidity-bytes-utils/// @notice Slices a byte array with a given starting index and length. Returns a new byte array/// as opposed to a pointer to the original array. Will throw if trying to slice more/// bytes than exist in the array./// @param _bytes Byte array to slice./// @param _start Starting index of the slice./// @param _length Length of the slice./// @return Slice of the input byte array.function slice(bytes memory _bytes,uint256 _start,uint256 _length)internalpurereturns (bytes memory){unchecked {require(_length + 31 >= _length, "slice_overflow");require(_start + _length >= _start, "slice_overflow");require(_bytes.length >= _start + _length, "slice_outOfBounds");}bytes memory tempBytes;assembly {switch iszero(_length)case 0 {// Get a location of some free memory and store it in tempBytes as// Solidity does for memory variables.tempBytes := mload(0x40)// The first word of the slice result is potentially a partial// word read from the original array. To read it, we calculate// the length of that partial word and start copying that many
contracts/thirdparty/optimism/rlp/RLPReader.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;/// @custom:attribution https://github.com/hamdiallam/Solidity-RLP/// @title RLPReader/// @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted/// from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with/// various tweaks to improve readability. (A shout-out to Optimism !)library RLPReader {/// @notice Custom pointer type to avoid confusion between pointers and uint256s.type MemoryPointer is uint256;/// @notice RLP item types./// @custom:value DATA_ITEM Represents an RLP data item (NOT a list)./// @custom:value LIST_ITEM Represents an RLP list item.enum RLPItemType {DATA_ITEM,LIST_ITEM}/// @notice Struct representing an RLP item./// @custom:field length Length of the RLP item./// @custom:field ptr Pointer to the RLP item in memory.struct RLPItem {uint256 length;MemoryPointer ptr;}/// @notice Max list length that this library will accept.uint256 internal constant MAX_LIST_LENGTH = 32;/// @notice Converts bytes to a reference to memory position and length./// @param _in Input bytes to convert./// @return out_ Output memory reference.function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory out_) {// Empty arrays are not RLP items.require(_in.length > 0,"RLPReader: length of an RLP item must be greater than zero to be decodable");
contracts/thirdparty/optimism/rlp/RLPWriter.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;/// @custom:attribution https://github.com/bakaoh/solidity-rlp-encode/// @title RLPWriter/// @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's/// RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor/// modifications to improve legibility. (A shout-out to Optimism !)library RLPWriter {/// @notice RLP encodes a byte string./// @param _in The byte string to encode./// @return out_ The RLP encoded string in bytes.function writeBytes(bytes memory _in) internal pure returns (bytes memory out_) {if (_in.length == 1 && uint8(_in[0]) < 128) {out_ = _in;} else {out_ = abi.encodePacked(_writeLength(_in.length, 128), _in);}}/// @notice RLP encodes a uint./// @param _in The uint256 to encode./// @return out_ The RLP encoded uint256 in bytes.function writeUint(uint256 _in) internal pure returns (bytes memory out_) {out_ = writeBytes(_toBinary(_in));}/// @notice Encode the first byte and then the `len` in binary form if `length` is more than 55./// @param _len The length of the string or the payload./// @param _offset 128 if item is string, 192 if item is list./// @return out_ RLP encoded bytes.function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory out_) {if (_len < 56) {out_ = new bytes(1);out_[0] = bytes1(uint8(_len) + uint8(_offset));} else {uint256 lenLen;uint256 i = 1;while (_len / i != 0) {lenLen++;i *= 256;
contracts/thirdparty/optimism/trie/MerkleTrie.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;import { Bytes } from "../Bytes.sol";import { RLPReader } from "../rlp/RLPReader.sol";/// @title MerkleTrie/// @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie/// inclusion proofs. By default, this library assumes a hexary trie. One can change the/// trie radix constant to support other trie radixes.library MerkleTrie {/// @notice Struct representing a node in the trie./// @custom:field encoded The RLP-encoded node./// @custom:field decoded The RLP-decoded node.struct TrieNode {bytes encoded;RLPReader.RLPItem[] decoded;}/// @notice Determines the number of elements per branch node.uint256 internal constant TREE_RADIX = 16;/// @notice Branch nodes have TREE_RADIX elements and one value element.uint256 internal constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;/// @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.uint256 internal constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;/// @notice Prefix for even-nibbled extension node paths.uint8 internal constant PREFIX_EXTENSION_EVEN = 0;/// @notice Prefix for odd-nibbled extension node paths.uint8 internal constant PREFIX_EXTENSION_ODD = 1;/// @notice Prefix for even-nibbled leaf node paths.uint8 internal constant PREFIX_LEAF_EVEN = 2;/// @notice Prefix for odd-nibbled leaf node paths.uint8 internal constant PREFIX_LEAF_ODD = 3;/// @notice Verifies a proof that a given key/value pair is present in the trie.
contracts/thirdparty/optimism/trie/SecureMerkleTrie.sol
// SPDX-License-Identifier: MITpragma solidity 0.8.24;import { MerkleTrie } from "./MerkleTrie.sol";/// @title SecureMerkleTrie/// @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input/// keys. Ethereum's state trie hashes input keys before storing them.library SecureMerkleTrie {/// @notice Verifies a proof that a given key/value pair is present in the Merkle trie./// @param _key Key of the node to search for, as a hex string./// @param _value Value of the node to search for, as a hex string./// @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle/// trees, this proof is executed top-down and consists of a list of RLP-encoded/// nodes that make a path down to the target node./// @param _root Known root of the Merkle trie. Used to verify that the included proof is/// correctly constructed./// @return valid_ Whether or not the proof is valid.function verifyInclusionProof(bytes memory _key,bytes memory _value,bytes[] memory _proof,bytes32 _root)internalpurereturns (bool valid_){bytes memory key = _getSecureKey(_key);valid_ = MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);}/// @notice Retrieves the value associated with a given key./// @param _key Key to search for, as hex bytes./// @param _proof Merkle trie inclusion proof for the key./// @param _root Known root of the Merkle trie./// @return value_ Value of the key if it exists.function get(bytes memory _key,bytes[] memory _proof,bytes32 _root
node_modules/@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)pragma solidity ^0.8.0;import "./OwnableUpgradeable.sol";import {Initializable} from "../proxy/utils/Initializable.sol";/*** @dev Contract module which provides 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 {transferOwnership} and {acceptOwnership}.** This module is used through inheritance. It will make available all functions* from parent (Ownable).*/abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {address private _pendingOwner;event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);function __Ownable2Step_init() internal onlyInitializing {__Ownable_init_unchained();}function __Ownable2Step_init_unchained() internal onlyInitializing {}/*** @dev Returns the address of the pending owner.*/function pendingOwner() public view virtual returns (address) {return _pendingOwner;}/*** @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.* Can only be called by the current owner.*/
node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)pragma solidity ^0.8.0;import "../utils/ContextUpgradeable.sol";import {Initializable} from "../proxy/utils/Initializable.sol";/*** @dev Contract module which provides a basic access control mechanism, where* there is an account (an owner) that can be granted exclusive access to* specific functions.** By default, the owner account will be the one that deploys the contract. This* can later be changed with {transferOwnership}.** This module is used through inheritance. It will make available the modifier* `onlyOwner`, which can be applied to your functions to restrict their use to* the owner.*/abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {address private _owner;event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);/*** @dev Initializes the contract setting the deployer as the initial owner.*/function __Ownable_init() internal onlyInitializing {__Ownable_init_unchained();}function __Ownable_init_unchained() internal onlyInitializing {_transferOwnership(_msgSender());}/*** @dev Throws if called by any account other than the owner.*/modifier onlyOwner() {_checkOwner();
node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)pragma solidity ^0.8.2;import "../../utils/AddressUpgradeable.sol";/*** @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.** The initialization functions use a version number. Once a version number is used, it is consumed and cannot be* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in* case an upgrade adds a module that needs to be initialized.** For example:** [.hljs-theme-light.nopadding]* ```solidity* contract MyToken is ERC20Upgradeable {* function initialize() initializer public {* __ERC20_init("MyToken", "MTK");* }* }** contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {* function initializeV2() reinitializer(2) public {* __ERC20Permit_init("MyToken");* }* }* ```** TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.** CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.** [CAUTION]
node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)pragma solidity ^0.8.1;/*** @dev Collection of functions related to the address type*/library AddressUpgradeable {/*** @dev Returns true if `account` is a contract.** [IMPORTANT]* ====* It is unsafe to assume that an address for which this function returns* false is an externally-owned account (EOA) and not a contract.** Among others, `isContract` will return false for the following* types of addresses:** - an externally-owned account* - a contract in construction* - an address where a contract will be created* - an address where a contract lived, but was destroyed** Furthermore, `isContract` will also return true if the target contract within* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,* which only has an effect at the end of a transaction.* ====** [IMPORTANT]* ====* You shouldn't rely on `isContract` to protect against flash loan attacks!** Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract* constructor.* ====*/function isContract(address account) internal view returns (bool) {// This method relies on extcodesize/address.code.length, which returns 0
node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)pragma solidity ^0.8.0;import {Initializable} from "../proxy/utils/Initializable.sol";/*** @dev Provides information about the current execution context, including the* sender of the transaction and its data. While these are generally available* via msg.sender and msg.data, they should not be accessed in such a direct* manner, since when dealing with meta-transactions the account sending and* paying for execution may not be the actual sender (as far as an application* is concerned).** This contract is only required for intermediate, library-like contracts.*/abstract contract ContextUpgradeable is Initializable {function __Context_init() internal onlyInitializing {}function __Context_init_unchained() internal onlyInitializing {}function _msgSender() internal view virtual returns (address) {return msg.sender;}function _msgData() internal view virtual returns (bytes calldata) {return msg.data;}function _contextSuffixLength() internal view virtual returns (uint256) {return 0;}/*** @dev This empty reserved space is put in place to allow future versions to add new* variables without shifting down storage in the inheritance chain.* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps*/uint256[50] private __gap;}
node_modules/@openzeppelin/contracts/interfaces/IERC1967.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)pragma solidity ^0.8.0;/*** @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.** _Available since v4.8.3._*/interface IERC1967 {/*** @dev Emitted when the implementation is upgraded.*/event Upgraded(address indexed implementation);/*** @dev Emitted when the admin account has changed.*/event AdminChanged(address previousAdmin, address newAdmin);/*** @dev Emitted when the beacon is changed.*/event BeaconUpgraded(address indexed beacon);}
node_modules/@openzeppelin/contracts/interfaces/draft-IERC1822.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)pragma solidity ^0.8.0;/*** @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified* proxy whose upgrades are fully controlled by the current implementation.*/interface IERC1822Proxiable {/*** @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation* address.** IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this* function revert if invoked through a proxy.*/function proxiableUUID() external view returns (bytes32);}
node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)pragma solidity ^0.8.2;import "../beacon/IBeacon.sol";import "../../interfaces/IERC1967.sol";import "../../interfaces/draft-IERC1822.sol";import "../../utils/Address.sol";import "../../utils/StorageSlot.sol";/*** @dev This abstract contract provides getters and event emitting update functions for* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.** _Available since v4.1._*/abstract contract ERC1967Upgrade is IERC1967 {// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;/*** @dev Storage slot with the address of the current implementation.* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is* validated in the constructor.*/bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;/*** @dev Returns the current implementation address.*/function _getImplementation() internal view returns (address) {return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;}/*** @dev Stores a new address in the EIP1967 implementation slot.*/function _setImplementation(address newImplementation) private {require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
node_modules/@openzeppelin/contracts/proxy/beacon/IBeacon.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)pragma solidity ^0.8.0;/*** @dev This is the interface that {BeaconProxy} expects of its beacon.*/interface IBeacon {/*** @dev Must return an address that can be used as a delegate call target.** {BeaconProxy} will check that this address is a contract.*/function implementation() external view returns (address);}
node_modules/@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)pragma solidity ^0.8.0;import "../../interfaces/draft-IERC1822.sol";import "../ERC1967/ERC1967Upgrade.sol";/*** @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.** A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing* `UUPSUpgradeable` with a custom implementation of upgrades.** The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.** _Available since v4.1._*/abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignmentaddress private immutable __self = address(this);/*** @dev Check that the execution is being performed through a delegatecall call and that the execution context is* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to* fail.*/modifier onlyProxy() {require(address(this) != __self, "Function must be called through delegatecall");require(_getImplementation() == __self, "Function must be called through active proxy");_;}/*** @dev Check that the execution is not being performed through a delegate call. This allows a function to be* callable on the implementing contract but not through proxies.*/
node_modules/@openzeppelin/contracts/utils/Address.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)pragma solidity ^0.8.1;/*** @dev Collection of functions related to the address type*/library Address {/*** @dev Returns true if `account` is a contract.** [IMPORTANT]* ====* It is unsafe to assume that an address for which this function returns* false is an externally-owned account (EOA) and not a contract.** Among others, `isContract` will return false for the following* types of addresses:** - an externally-owned account* - a contract in construction* - an address where a contract will be created* - an address where a contract lived, but was destroyed** Furthermore, `isContract` will also return true if the target contract within* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,* which only has an effect at the end of a transaction.* ====** [IMPORTANT]* ====* You shouldn't rely on `isContract` to protect against flash loan attacks!** Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract* constructor.* ====*/function isContract(address account) internal view returns (bool) {// This method relies on extcodesize/address.code.length, which returns 0
node_modules/@openzeppelin/contracts/utils/StorageSlot.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.pragma solidity ^0.8.0;/*** @dev Library for reading and writing primitive types to specific storage slots.** Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.* This library helps with reading and writing to such slots without the need for inline assembly.** The functions in this library return Slot structs that contain a `value` member that can be used to read or write.** Example usage to set ERC1967 implementation slot:* ```solidity* contract ERC1967 {* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;** function _getImplementation() internal view returns (address) {* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;* }** function _setImplementation(address newImplementation) internal {* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;* }* }* ```** _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._* _Available since v4.9 for `string`, `bytes`._*/library StorageSlot {struct AddressSlot {address value;}struct BooleanSlot {bool value;}
Compiler Settings
{"viaIR":false,"remappings":["@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/","@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/","solady/=node_modules/solady/","forge-std/=node_modules/forge-std/","ds-test/=node_modules/ds-test/src/","p256-verifier/=node_modules/p256-verifier/","forge-safe/=node_modules/forge-safe/"],"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"cancun"}
Contract ABI
[{"type":"error","name":"FUNC_NOT_IMPLEMENTED","inputs":[]},{"type":"error","name":"INVALID_PAUSE_STATUS","inputs":[]},{"type":"error","name":"LTP_INVALID_ACCOUNT_PROOF","inputs":[]},{"type":"error","name":"LTP_INVALID_INCLUSION_PROOF","inputs":[]},{"type":"error","name":"REENTRANT_CALL","inputs":[]},{"type":"error","name":"RESOLVER_DENIED","inputs":[]},{"type":"error","name":"RESOLVER_INVALID_MANAGER","inputs":[]},{"type":"error","name":"RESOLVER_UNEXPECTED_CHAINID","inputs":[]},{"type":"error","name":"RESOLVER_ZERO_ADDR","inputs":[{"type":"uint64","name":"chainId","internalType":"uint64"},{"type":"bytes32","name":"name","internalType":"bytes32"}]},{"type":"error","name":"SS_EMPTY_PROOF","inputs":[]},{"type":"error","name":"SS_INVALID_HOPS_WITH_LOOP","inputs":[]},{"type":"error","name":"SS_INVALID_LAST_HOP_CHAINID","inputs":[]},{"type":"error","name":"SS_INVALID_MID_HOP_CHAINID","inputs":[]},{"type":"error","name":"SS_INVALID_STATE","inputs":[]},{"type":"error","name":"SS_SIGNAL_NOT_FOUND","inputs":[]},{"type":"error","name":"SS_UNAUTHORIZED","inputs":[]},{"type":"error","name":"ZERO_ADDRESS","inputs":[]},{"type":"error","name":"ZERO_VALUE","inputs":[]},{"type":"event","name":"AdminChanged","inputs":[{"type":"address","name":"previousAdmin","internalType":"address","indexed":false},{"type":"address","name":"newAdmin","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Authorized","inputs":[{"type":"address","name":"addr","internalType":"address","indexed":true},{"type":"bool","name":"authorized","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"BeaconUpgraded","inputs":[{"type":"address","name":"beacon","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ChainDataSynced","inputs":[{"type":"uint64","name":"chainId","internalType":"uint64","indexed":true},{"type":"uint64","name":"blockId","internalType":"uint64","indexed":true},{"type":"bytes32","name":"kind","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"data","internalType":"bytes32","indexed":false},{"type":"bytes32","name":"signal","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"type":"uint8","name":"version","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferStarted","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"SignalSent","inputs":[{"type":"address","name":"app","internalType":"address","indexed":false},{"type":"bytes32","name":"signal","internalType":"bytes32","indexed":false},{"type":"bytes32","name":"slot","internalType":"bytes32","indexed":false},{"type":"bytes32","name":"value","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Upgraded","inputs":[{"type":"address","name":"implementation","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"addressManager","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"authorize","inputs":[{"type":"address","name":"_addr","internalType":"address"},{"type":"bool","name":"_authorize","internalType":"bool"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getSignalSlot","inputs":[{"type":"uint64","name":"_chainId","internalType":"uint64"},{"type":"address","name":"_app","internalType":"address"},{"type":"bytes32","name":"_signal","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"blockId_","internalType":"uint64"},{"type":"bytes32","name":"chainData_","internalType":"bytes32"}],"name":"getSyncedChainData","inputs":[{"type":"uint64","name":"_chainId","internalType":"uint64"},{"type":"bytes32","name":"_kind","internalType":"bytes32"},{"type":"uint64","name":"_blockId","internalType":"uint64"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"impl","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"inNonReentrant","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"init","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_addressManager","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"authorized","internalType":"bool"}],"name":"isAuthorized","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isChainDataSynced","inputs":[{"type":"uint64","name":"_chainId","internalType":"uint64"},{"type":"bytes32","name":"_kind","internalType":"bytes32"},{"type":"uint64","name":"_blockId","internalType":"uint64"},{"type":"bytes32","name":"_chainData","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isSignalSent","inputs":[{"type":"address","name":"_app","internalType":"address"},{"type":"bytes32","name":"_signal","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"lastUnpausedAt","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingOwner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"numCacheOps_","internalType":"uint256"}],"name":"proveSignalReceived","inputs":[{"type":"uint64","name":"_chainId","internalType":"uint64"},{"type":"address","name":"_app","internalType":"address"},{"type":"bytes32","name":"_signal","internalType":"bytes32"},{"type":"bytes","name":"_proof","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"proxiableUUID","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"resolve","inputs":[{"type":"uint64","name":"_chainId","internalType":"uint64"},{"type":"bytes32","name":"_name","internalType":"bytes32"},{"type":"bool","name":"_allowZeroAddress","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"resolve","inputs":[{"type":"bytes32","name":"_name","internalType":"bytes32"},{"type":"bool","name":"_allowZeroAddress","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"sendSignal","inputs":[{"type":"bytes32","name":"_signal","internalType":"bytes32"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"signalForChainData","inputs":[{"type":"uint64","name":"_chainId","internalType":"uint64"},{"type":"bytes32","name":"_kind","internalType":"bytes32"},{"type":"uint64","name":"_blockId","internalType":"uint64"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"syncChainData","inputs":[{"type":"uint64","name":"_chainId","internalType":"uint64"},{"type":"bytes32","name":"_kind","internalType":"bytes32"},{"type":"uint64","name":"_blockId","internalType":"uint64"},{"type":"bytes32","name":"_chainData","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"blockId","internalType":"uint64"}],"name":"topBlockId","inputs":[{"type":"uint64","name":"chainId","internalType":"uint64"},{"type":"bytes32","name":"kind","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"upgradeTo","inputs":[{"type":"address","name":"newImplementation","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"upgradeToAndCall","inputs":[{"type":"address","name":"newImplementation","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[],"name":"verifySignalReceived","inputs":[{"type":"uint64","name":"_chainId","internalType":"uint64"},{"type":"address","name":"_app","internalType":"address"},{"type":"bytes32","name":"_signal","internalType":"bytes32"},{"type":"bytes","name":"_proof","internalType":"bytes"}]}]
Deployed ByteCode
0x6080604052600436106101c5575f3560e01c806379ba5097116100f2578063a86f9d9e11610092578063e30c397811610062578063e30c39781461052f578063f09a40161461054c578063f2fde38b1461056b578063fe9fbb801461058a575f80fd5b8063a86f9d9e1461048e578063ce9d0820146104ad578063dfc8ff1d146104cc578063e07baba61461050a575f80fd5b80638da5cb5b116100cd5780638da5cb5b14610414578063910af6ed1461043157806391f3f74b146104505780639b527cfa1461046f575f80fd5b806379ba5097146103d85780638456cb59146103ec5780638abf607714610400575f80fd5b80633eb6b8cf1161016857806352d1902d1161013857806352d1902d146103715780635c975abb1461038557806366ca2bc0146103a5578063715018a6146103c4575f80fd5b80633eb6b8cf146102fe5780633f4ba83a1461031d5780634f1ef286146103315780634f90a67414610344575f80fd5b8063355bcc3d116101a3578063355bcc3d146102325780633659cfe6146102895780633ab76e9f146102a85780633ced0e08146102df575f80fd5b80632d1fb389146101c95780633075db56146101ea57806332676bc614610213575b5f80fd5b3480156101d4575f80fd5b506101e86101e3366004613ad5565b6105b8565b005b3480156101f5575f80fd5b506101fe61065e565b60405190151581526020015b60405180910390f35b34801561021e575f80fd5b506101fe61022d366004613b08565b610672565b34801561023d575f80fd5b5061027161024c366004613b48565b60fb60209081525f92835260408084209091529082529020546001600160401b031681565b6040516001600160401b03909116815260200161020a565b348015610294575f80fd5b506101e86102a3366004613b62565b610688565b3480156102b3575f80fd5b506097546102c7906001600160a01b031681565b6040516001600160a01b03909116815260200161020a565b3480156102ea575f80fd5b506101fe6102f9366004613b7d565b610758565b348015610309575f80fd5b506102c7610318366004613bbe565b61079f565b348015610328575f80fd5b506101e86107b5565b6101e861033f366004613cce565b6107c9565b34801561034f575f80fd5b5061036361035e366004613b7d565b610882565b60405190815260200161020a565b34801561037c575f80fd5b506103636108c8565b348015610390575f80fd5b506101fe60c954610100900460ff1660021490565b3480156103b0575f80fd5b506103636103bf366004613d1a565b610979565b3480156103cf575f80fd5b506101e8610985565b3480156103e3575f80fd5b506101e8610996565b3480156103f7575f80fd5b506101e8610a0d565b34801561040b575f80fd5b506102c7610a20565b34801561041f575f80fd5b506033546001600160a01b03166102c7565b34801561043c575f80fd5b5061036361044b366004613d31565b610a2e565b34801561045b575f80fd5b5061036361046a366004613dc5565b610afe565b34801561047a575f80fd5b50610363610489366004613e01565b610b69565b348015610499575f80fd5b506102c76104a8366004613e31565b610b95565b3480156104b8575f80fd5b506101e86104c7366004613d31565b610ba1565b3480156104d7575f80fd5b506104eb6104e6366004613e01565b610bb7565b604080516001600160401b03909316835260208301919091520161020a565b348015610515575f80fd5b5060c954610271906201000090046001600160401b031681565b34801561053a575f80fd5b506065546001600160a01b03166102c7565b348015610557575f80fd5b506101e8610566366004613e52565b610c4b565b348015610576575f80fd5b506101e8610585366004613b62565b610d5a565b348015610595575f80fd5b506101fe6105a4366004613b62565b60fc6020525f908152604090205460ff1681565b6105c0610dcb565b6001600160a01b0382165f90815260fc602052604090205481151560ff909116151503610600576040516398f26f4560e01b815260040160405180910390fd5b6001600160a01b0382165f81815260fc6020908152604091829020805460ff191685151590811790915591519182527f4c0079b9bcd37cd5d29a13938effd97c881798cbc6bd52a3026a29d94b27d1bf910160405180910390a25050565b5f6002610669610e25565b60ff1614905090565b5f61067d8383610e64565b151590505b92915050565b6001600160a01b037f00000000000000000000000001670000000000000000000000000000000000051630036106d95760405162461bcd60e51b81526004016106d090613e89565b60405180910390fd5b7f00000000000000000000000001670000000000000000000000000000000000056001600160a01b031661070b610ec6565b6001600160a01b0316146107315760405162461bcd60e51b81526004016106d090613ed5565b61073a81610ee1565b604080515f8082526020820190925261075591839190610ee9565b50565b5f8180820361077a5760405163ec73295960e01b815260040160405180910390fd5b5f610786878787610b69565b9050836107933083610e64565b14979650505050505050565b5f6107ab848484611053565b90505b9392505050565b6107bd611144565b6107c7335f6111d4565b565b6001600160a01b037f00000000000000000000000001670000000000000000000000000000000000051630036108115760405162461bcd60e51b81526004016106d090613e89565b7f00000000000000000000000001670000000000000000000000000000000000056001600160a01b0316610843610ec6565b6001600160a01b0316146108695760405162461bcd60e51b81526004016106d090613ed5565b61087282610ee1565b61087e82826001610ee9565b5050565b335f90815260fc602052604081205460ff166108b157604051631f67751f60e01b815260040160405180910390fd5b6108bd858585856111ed565b90505b949350505050565b5f306001600160a01b037f000000000000000000000000016700000000000000000000000000000000000516146109675760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016106d0565b505f805160206144e883398151915290565b5f6106823383846112cf565b61098d610dcb565b6107c75f6113a8565b60655433906001600160a01b03168114610a045760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016106d0565b610755816113a8565b610a156113c1565b6107c73360016111d4565b5f610a29610ec6565b905090565b5f610a4360c954610100900460ff1660021490565b15610a615760405163bae6e2a960e01b815260040160405180910390fd5b6002610a6b610e25565b60ff1603610a8c5760405163dfc60d8560e01b815260040160405180910390fd5b610a966002611432565b5f610aa68787878787600161147a565b90505f5b8151811015610ae957610ad5828281518110610ac857610ac8613f21565b6020026020010151611936565b610adf9084613f49565b9250600101610aaa565b5050610af56001611432565b95945050505050565b6040516514d251d3905360d21b60208201526001600160c01b031960c085901b1660268201526bffffffffffffffffffffffff19606084901b16602e820152604281018290525f906062015b6040516020818303038152906040528051906020012090509392505050565b604080516001600160401b03808616602083015291810184905290821660608201525f90608001610b4a565b5f6107ae468484611053565b610baf85858585855f61147a565b505050505050565b5f80826001600160401b03165f03610bf3576001600160401b038086165f90815260fb6020908152604080832088845290915290205416610bf5565b825b91506001600160401b03821615610c43575f610c12868685610b69565b9050610c1e3082610e64565b91505f829003610c415760405163738afa0560e01b815260040160405180910390fd5b505b935093915050565b5f54610100900460ff1615808015610c6957505f54600160ff909116105b80610c825750303b158015610c8257505f5460ff166001145b610ce55760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106d0565b5f805460ff191660011790558015610d06575f805461ff0019166101001790555b610d108383611a7a565b8015610d55575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b610d62610dcb565b606580546001600160a01b0383166001600160a01b03199091168117909155610d936033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6033546001600160a01b031633146107c75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106d0565b5f610e2f46611ab4565b15610e5a57507fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5c90565b5060c95460ff1690565b5f826001600160a01b038116610e8d5760405163538ba4f960e01b815260040160405180910390fd5b825f819003610eaf5760405163ec73295960e01b815260040160405180910390fd5b5f610ebb468787610afe565b549695505050505050565b5f805160206144e8833981519152546001600160a01b031690565b610755610dcb565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615610f1c57610d5583611ae1565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610f76575060408051601f3d908101601f19168201909252610f7391810190613f5c565b60015b610fd95760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016106d0565b5f805160206144e883398151915281146110475760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016106d0565b50610d55838383611b7c565b6097545f906001600160a01b03168061107f57604051638ed88b2560e01b815260040160405180910390fd5b604051630a3dc4f360e21b81526001600160401b0386166004820152602481018590526001600160a01b038216906328f713cc90604401602060405180830381865afa1580156110d1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110f59190613f73565b91508215801561110c57506001600160a01b038216155b1561113c57604051632b0d65db60e01b81526001600160401b0386166004820152602481018590526044016106d0565b509392505050565b61115860c954610100900460ff1660021490565b6111755760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461010069ffffffffffffffffff001990911662010000426001600160401b031602171790556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b604051630c2b8f8f60e11b815260040160405180910390fd5b5f6111f9858585610b69565b90506112063082846112cf565b506001600160401b038581165f90815260fb6020908152604080832088845290915290205481851691161015611270576001600160401b038581165f90815260fb602090815260408083208884529091529020805467ffffffffffffffff19169185169190911790555b83836001600160401b0316866001600160401b03167fde247c825b1fb2d7ff9e0e771cba6f9e757ad04479fcdc135d88ae91fd50b37d85856040516112bf929190918252602082015260400190565b60405180910390a4949350505050565b5f836001600160a01b0381166112f85760405163538ba4f960e01b815260040160405180910390fd5b835f81900361131a5760405163ec73295960e01b815260040160405180910390fd5b835f81900361133c5760405163ec73295960e01b815260040160405180910390fd5b611347468888610afe565b858155604080516001600160a01b038a16815260208101899052908101829052606081018790529094507f0ad2d108660a211f47bf7fb43a0443cae181624995d3d42b88ee6879d200e9739060800160405180910390a15050509392505050565b606580546001600160a01b031916905561075581611ba6565b6113d560c954610100900460ff1660021490565b156113f35760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020016111ca565b61143b46611ab4565b1561146657807fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5d50565b60c9805460ff831660ff1990911617905550565b6060856001600160a01b0381166114a45760405163538ba4f960e01b815260040160405180910390fd5b855f8190036114c65760405163ec73295960e01b815260040160405180910390fd5b5f6114d38688018861403d565b905080515f036114f657604051630b92daef60e21b815260040160405180910390fd5b5f60018251611505919061417b565b6001600160401b0381111561151c5761151c613bf7565b604051908082528060200260200182016040528015611545578160200160208202803683370190505b50905085156115d85781516001600160401b0381111561156757611567613bf7565b6040519080825280602002602001820160405280156115d457816020015b6115c16040805160e0810182525f80825260208201819052918101829052606081018290526080810182905260a081018290529060c082015290565b8152602001906001900390816115855790505b5094505b8a8a8a805f6115f9856d7369676e616c5f7365727669636560901b8361079f565b9050306001600160a01b0382160361162457604051637556223560e11b815260040160405180910390fd5b61165c6040805160c0810182525f80825260208201819052918101829052906060820190815260200160608152602001606081525090565b5f805f805b8b518110156118ea578b818151811061167c5761167c613f21565b602002602001015194505f5b818110156116e657855f01516001600160401b03168c82815181106116af576116af613f21565b60200260200101516001600160401b0316036116de576040516348362c2760e11b815260040160405180910390fd5b600101611688565b506116f58a8a8a8a898b611bf7565b93508a518114915081156117355784516001600160401b0316461461172d576040516338bf822760e21b815260040160405180910390fd5b3095506117e0565b845f01518b828151811061174b5761174b613f21565b6001600160401b0392831660209182029290920101528551161580611779575084516001600160401b031646145b1561179757604051637556223560e11b815260040160405180910390fd5b84516117b5906d7369676e616c5f7365727669636560901b5f61079f565b9550306001600160a01b038716036117e057604051637556223560e11b815260040160405180910390fd5b608085015151151592508f15611874576040518060e00160405280866040015181526020018581526020018b6001600160401b0316815260200186602001516001600160401b0316815260200184151581526020018315158152602001866060015160038111156118535761185361418e565b8152508f828151811061186857611868613f21565b60200260200101819052505b6118cf8a846118a3577fc6cdc4f2acf13acb10f410085b821f7b7113b303e9a4799023f928317396aaf56118c5565b7f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da1695b8760200151610b69565b604086015186519b5096995097509495508794600101611661565b5085158061190157506118fd3088610e64565b8614155b1561191f5760405163738afa0560e01b815260040160405180910390fd5b505050505050505050505050509695505050505050565b5f8060038360c0015160038111156119505761195061418e565b1480611971575060028360c00151600381111561196f5761196f61418e565b145b9050808015611981575082608001515b801561198f57508260a00151155b156119d157600191506119cf83604001517f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da1698560600151865f01516111ed565b505b5f60038460c0015160038111156119ea576119ea61418e565b1480611a0b575060018460c001516003811115611a0957611a0961418e565b145b9050808015611a275750836080015180611a2757508360a00151155b15611a7357611a37600184613f49565b9250611a7184604001517fc6cdc4f2acf13acb10f410085b821f7b7113b303e9a4799023f928317396aaf5866060015187602001516111ed565b505b5050919050565b806001600160a01b038116611aa25760405163538ba4f960e01b815260040160405180910390fd5b611aab83611c96565b610d5582611cf4565b5f6001821480611ac5575061426882145b80611ad2575062aa36a782145b80610682575061068282611d64565b6001600160a01b0381163b611b4e5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016106d0565b5f805160206144e883398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b611b8583611d7b565b5f82511180611b915750805b15610d5557611ba08383611dba565b50505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f856001600160a01b038116611c205760405163538ba4f960e01b815260040160405180910390fd5b855f819003611c425760405163ec73295960e01b815260040160405180910390fd5b855f819003611c645760405163ec73295960e01b815260040160405180910390fd5b611c88866040015186611c788d8d8d610afe565b8a8a608001518b60a00151611ddf565b9a9950505050505050505050565b5f54610100900460ff16611cbc5760405162461bcd60e51b81526004016106d0906141a2565b611cc4611eec565b611ce26001600160a01b03821615611cdc57816113a8565b336113a8565b5060c9805461ff001916610100179055565b5f54610100900460ff16611d1a5760405162461bcd60e51b81526004016106d0906141a2565b6001600160401b03461115611d425760405163a12e8fa960e01b815260040160405180910390fd5b609780546001600160a01b0319166001600160a01b0392909216919091179055565b5f617e2c8210158015610682575050617e90101590565b611d8481611ae1565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606107ae838360405180606001604052806027815260200161450860279139611f12565b5f82515f14611e87576040516bffffffffffffffffffffffff19606088901b1660208201525f90611e2390603401604051602081830303815290604052858a611f86565b905080515f03611e4657604051630414cd5b60e31b815260040160405180910390fd5b5f611e5082611f9f565b9050611e7581600281518110611e6857611e68613f21565b6020026020010151611fb2565b611e7e906141ed565b92505050611e8a565b50855b5f611ec186604051602001611ea191815260200190565b60408051601f19818403018152919052611eba876120d2565b85856120e5565b905080611ee157604051638d9a4db360e01b815260040160405180910390fd5b509695505050505050565b5f54610100900460ff166107c75760405162461bcd60e51b81526004016106d0906141a2565b60605f80856001600160a01b031685604051611f2e9190614235565b5f60405180830381855af49150503d805f8114611f66576040519150601f19603f3d011682016040523d82523d5f602084013e611f6b565b606091505b5091509150611f7c868383876120fe565b9695505050505050565b60605f611f9285612176565b9050610af58185856121a8565b6060610682611fad83612a15565b612a66565b60605f805f611fc085612c83565b919450925090505f816001811115611fda57611fda61418e565b1461204d5760405162461bcd60e51b815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d0000000000000060648201526084016106d0565b6120578284613f49565b8551146120c35760405162461bcd60e51b815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527330b71034b73b30b634b2103932b6b0b4b73232b960611b60648201526084016106d0565b610af58560200151848461332a565b60606106826120e0836133ba565b6134cd565b5f806120f086612176565b9050611f7c81868686613525565b6060831561216c5782515f03612165576001600160a01b0385163b6121655760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106d0565b50816108c0565b6108c0838361354b565b6060818051906020012060405160200161219291815260200190565b6040516020818303038152906040529050919050565b60605f8451116121f25760405162461bcd60e51b81526020600482015260156024820152744d65726b6c65547269653a20656d707479206b657960581b60448201526064016106d0565b5f6121fc84613575565b90505f61220886613658565b90505f8460405160200161221e91815260200190565b60405160208183030381529060405290505f805b84518110156129be575f85828151811061224e5761224e613f21565b6020026020010151905084518311156122c05760405162461bcd60e51b815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201526d0e8c2d840d6caf240d8cadccee8d60931b60648201526084016106d0565b825f0361235e578051805160209182012060405161230d926122e792910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6123595760405162461bcd60e51b815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016106d0565b612454565b8051516020116123e45780518051602091820120604051612388926122e792910190815260200190565b6123595760405162461bcd60e51b815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e6044820152660c2d840d0c2e6d60cb1b60648201526084016106d0565b8051845160208087019190912082519190920120146124545760405162461bcd60e51b815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f646044820152650ca40d0c2e6d60d31b60648201526084016106d0565b61246060106001613f49565b816020015151036125f857845183036125925761248d8160200151601081518110611e6857611e68613f21565b96505f8751116125055760405162461bcd60e51b815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e636829000000000060648201526084016106d0565b60018651612513919061417b565b82146125875760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e63682900000000000060648201526084016106d0565b5050505050506107ae565b5f8584815181106125a5576125a5613f21565b602001015160f81c60f81b60f81c90505f82602001518260ff16815181106125cf576125cf613f21565b602002602001015190506125e2816136b9565b95506125ef600186613f49565b945050506129b5565b60028160200151510361295c575f61260f826136dd565b90505f815f8151811061262457612624613f21565b016020015160f81c90505f61263a600283614264565b612645906002614285565b90505f612655848360ff16613700565b90505f6126628a89613700565b90505f61266f8383613735565b9050808351146126e75760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b657900000000000060648201526084016106d0565b60ff8516600214806126fc575060ff85166003145b1561289c57808251146127775760405162461bcd60e51b815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e64657200000060648201526084016106d0565b6127918760200151600181518110611e6857611e68613f21565b9c505f8d51116128095760405162461bcd60e51b815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c656166290000000000000060648201526084016106d0565b60018c51612817919061417b565b881461288b5760405162461bcd60e51b815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c65616629000000000000000060648201526084016106d0565b5050505050505050505050506107ae565b60ff851615806128af575060ff85166001145b156128ee576128db87602001516001815181106128ce576128ce613f21565b60200260200101516136b9565b99506128e7818a613f49565b9850612951565b60405162461bcd60e51b815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f64652077697468604482015271040c2dc40eadcd6dcdeeedc40e0e4caccd2f60731b60648201526084016106d0565b5050505050506129b5565b60405162461bcd60e51b815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e706172736561604482015267626c65206e6f646560c01b60648201526084016106d0565b50600101612232565b5060405162461bcd60e51b815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c656044820152646d656e747360d81b60648201526084016106d0565b604080518082019091525f80825260208201525f825111612a485760405162461bcd60e51b81526004016106d09061429e565b50604080518082019091528151815260209182019181019190915290565b60605f805f612a7485612c83565b919450925090506001816001811115612a8f57612a8f61418e565b14612b025760405162461bcd60e51b815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d000000000000000060648201526084016106d0565b8451612b0e8385613f49565b14612b765760405162461bcd60e51b815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e76616044820152713634b2103230ba30903932b6b0b4b73232b960711b60648201526084016106d0565b604080516020808252610420820190925290816020015b604080518082019091525f8082526020820152815260200190600190039081612b8d5790505093505f835b8651811015612c77575f80612bfc6040518060400160405280858c5f0151612be0919061417b565b8152602001858c60200151612bf59190613f49565b9052612c83565b509150915060405180604001604052808383612c189190613f49565b8152602001848b60200151612c2d9190613f49565b815250888581518110612c4257612c42613f21565b6020908102919091010152612c58600185613f49565b9350612c648183613f49565b612c6e9084613f49565b92505050612bb8565b50845250919392505050565b5f805f80845f015111612ca85760405162461bcd60e51b81526004016106d09061429e565b602084015180515f1a607f8111612cca575f60015f9450945094505050613323565b60b78111612e23575f612cde60808361417b565b905080875f015111612d5c5760405162461bcd60e51b815260206004820152604e60248201525f805160206144c883398151915260448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201526d2873686f727420737472696e672960901b608482015260a4016106d0565b6001838101516001600160f81b0319169082141580612d895750600160ff1b6001600160f81b0319821610155b612e115760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201526c73686f727420737472696e672960981b608482015260a4016106d0565b506001955093505f9250613323915050565b60bf811161305c575f612e3760b78361417b565b905080875f015111612eb85760405162461bcd60e51b815260206004820152605160248201525f805160206144c883398151915260448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527067746820286c6f6e6720737472696e672960781b608482015260a4016106d0565b60018301516001600160f81b0319165f819003612f3d5760405162461bcd60e51b815260206004820152604a60248201525f805160206144c883398151915260448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f6064820152696e6720737472696e672960b01b608482015260a4016106d0565b600184015160088302610100031c60378111612fbf5760405162461bcd60e51b815260206004820152604860248201525f805160206144c883398151915260448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201526720737472696e672960c01b608482015260a4016106d0565b612fc98184613f49565b8951116130405760405162461bcd60e51b815260206004820152604c60248201525f805160206144c883398151915260448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201526b6c6f6e6720737472696e672960a01b608482015260a4016106d0565b61304b836001613f49565b975095505f94506133239350505050565b60f781116130fb575f61307060c08361417b565b905080875f0151116130ea5760405162461bcd60e51b815260206004820152604a60248201525f805160206144c883398151915260448201527f742062652067726561746572207468616e206c697374206c656e677468202873606482015269686f7274206c6973742960b01b608482015260a4016106d0565b600195509350849250613323915050565b5f61310760f78361417b565b905080875f0151116131845760405162461bcd60e51b815260206004820152604d60248201525f805160206144c883398151915260448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201526c6820286c6f6e67206c6973742960981b608482015260a4016106d0565b60018301516001600160f81b0319165f8190036132075760405162461bcd60e51b815260206004820152604860248201525f805160206144c883398151915260448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f6064820152676e67206c6973742960c01b608482015260a4016106d0565b600184015160088302610100031c603781116132875760405162461bcd60e51b815260206004820152604660248201525f805160206144c883398151915260448201527f742062652067726561746572207468616e20353520627974657320286c6f6e67606482015265206c6973742960d01b608482015260a4016106d0565b6132918184613f49565b8951116133065760405162461bcd60e51b815260206004820152604a60248201525f805160206144c883398151915260448201527f742062652067726561746572207468616e20746f74616c206c656e67746820286064820152696c6f6e67206c6973742960b01b608482015260a4016106d0565b613311836001613f49565b97509550600194506133239350505050565b9193909250565b6060816001600160401b0381111561334457613344613bf7565b6040519080825280601f01601f19166020018201604052801561336e576020820181803683370190505b50905081156107ae575f6133828486613f49565b9050602082015f5b848110156133a257828101518282015260200161338a565b848111156133b0575f858301525b5050509392505050565b60605f826040516020016133d091815260200190565b60405160208183030381529060405290505f5b602081101561341b578181815181106133fe576133fe613f21565b01602001516001600160f81b0319165f0361341b576001016133e3565b61342681602061417b565b6001600160401b0381111561343d5761343d613bf7565b6040519080825280601f01601f191660200182016040528015613467576020820181803683370190505b5092505f5b8351811015611a715782826134808161430e565b93508151811061349257613492613f21565b602001015160f81c60f81b8482815181106134af576134af613f21565b60200101906001600160f81b03191690815f1a90535060010161346c565b6060815160011480156134f957506080825f815181106134ef576134ef613f21565b016020015160f81c105b15613502575090565b61350e825160806137b8565b82604051602001612192929190614326565b919050565b5f6108bd846135358786866121a8565b8051602091820120825192909101919091201490565b81511561355b5781518083602001fd5b8060405162461bcd60e51b81526004016106d09190614354565b8051606090806001600160401b0381111561359257613592613bf7565b6040519080825280602002602001820160405280156135d757816020015b60408051808201909152606080825260208201528152602001906001900390816135b05790505b5091505f5b81811015611a7357604051806040016040528085838151811061360157613601613f21565b6020026020010151815260200161363086848151811061362357613623613f21565b6020026020010151611f9f565b81525083828151811061364557613645613f21565b60209081029190910101526001016135dc565b606080604051905082518060011b603f8101601f191683016040528083525060208401602083015f5b838110156136ae578060011b8201818401515f1a8060041c8253600f811660018301535050600101613681565b509295945050505050565b60606020825f0151106136d4576136cf82611fb2565b610682565b6106828261395d565b60606106826136fb83602001515f81518110611e6857611e68613f21565b613658565b60608251821061371e575060408051602081019091525f8152610682565b6107ae8383848651613730919061417b565b613971565b5f80825184511061374757825161374a565b83515b90505b80821080156137a1575082828151811061376957613769613f21565b602001015160f81c60f81b6001600160f81b03191684838151811061379057613790613f21565b01602001516001600160f81b031916145b156137b15781600101915061374d565b5092915050565b6060603883101561381c57604080516001808252818301909252906020820181803683370190505090506137ec8284614386565b60f81b815f8151811061380157613801613f21565b60200101906001600160f81b03191690815f1a905350610682565b5f60015b61382a818661439f565b1561385057816138398161430e565b92506138499050610100826143b2565b9050613820565b61385b826001613f49565b6001600160401b0381111561387257613872613bf7565b6040519080825280601f01601f19166020018201604052801561389c576020820181803683370190505b5092506138a98483614386565b6138b4906037614386565b60f81b835f815181106138c9576138c9613f21565b60200101906001600160f81b03191690815f1a905350600190505b818111613955576101006138f8828461417b565b613904906101006144a9565b61390e908761439f565b61391891906144b4565b60f81b83828151811061392d5761392d613f21565b60200101906001600160f81b03191690815f1a9053508061394d8161430e565b9150506138e4565b505092915050565b606061068282602001515f845f015161332a565b60608182601f0110156139b75760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b60448201526064016106d0565b8282840110156139fa5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b60448201526064016106d0565b81830184511015613a415760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b60448201526064016106d0565b606082158015613a5f5760405191505f825260208201604052613aa9565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015613a98578051835260209283019201613a80565b5050858452601f01601f1916604052505b50949350505050565b6001600160a01b0381168114610755575f80fd5b80358015158114613520575f80fd5b5f8060408385031215613ae6575f80fd5b8235613af181613ab2565b9150613aff60208401613ac6565b90509250929050565b5f8060408385031215613b19575f80fd5b8235613b2481613ab2565b946020939093013593505050565b80356001600160401b0381168114613520575f80fd5b5f8060408385031215613b59575f80fd5b613b2483613b32565b5f60208284031215613b72575f80fd5b81356107ae81613ab2565b5f805f8060808587031215613b90575f80fd5b613b9985613b32565b935060208501359250613bae60408601613b32565b9396929550929360600135925050565b5f805f60608486031215613bd0575f80fd5b613bd984613b32565b925060208401359150613bee60408501613ac6565b90509250925092565b634e487b7160e01b5f52604160045260245ffd5b60405160c081016001600160401b0381118282101715613c2d57613c2d613bf7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613c5b57613c5b613bf7565b604052919050565b5f82601f830112613c72575f80fd5b81356001600160401b03811115613c8b57613c8b613bf7565b613c9e601f8201601f1916602001613c33565b818152846020838601011115613cb2575f80fd5b816020850160208301375f918101602001919091529392505050565b5f8060408385031215613cdf575f80fd5b8235613cea81613ab2565b915060208301356001600160401b03811115613d04575f80fd5b613d1085828601613c63565b9150509250929050565b5f60208284031215613d2a575f80fd5b5035919050565b5f805f805f60808688031215613d45575f80fd5b613d4e86613b32565b94506020860135613d5e81613ab2565b93506040860135925060608601356001600160401b0380821115613d80575f80fd5b818801915088601f830112613d93575f80fd5b813581811115613da1575f80fd5b896020828501011115613db2575f80fd5b9699959850939650602001949392505050565b5f805f60608486031215613dd7575f80fd5b613de084613b32565b92506020840135613df081613ab2565b929592945050506040919091013590565b5f805f60608486031215613e13575f80fd5b613e1c84613b32565b925060208401359150613bee60408501613b32565b5f8060408385031215613e42575f80fd5b82359150613aff60208401613ac6565b5f8060408385031215613e63575f80fd5b8235613e6e81613ab2565b91506020830135613e7e81613ab2565b809150509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082018082111561068257610682613f35565b5f60208284031215613f6c575f80fd5b5051919050565b5f60208284031215613f83575f80fd5b81516107ae81613ab2565b5f6001600160401b03821115613fa657613fa6613bf7565b5060051b60200190565b803560048110613520575f80fd5b5f82601f830112613fcd575f80fd5b81356020613fe2613fdd83613f8e565b613c33565b82815260059290921b84018101918181019086841115614000575f80fd5b8286015b84811015611ee15780356001600160401b03811115614021575f80fd5b61402f8986838b0101613c63565b845250918301918301614004565b5f602080838503121561404e575f80fd5b82356001600160401b0380821115614064575f80fd5b818501915085601f830112614077575f80fd5b8135614085613fdd82613f8e565b81815260059190911b830184019084810190888311156140a3575f80fd5b8585015b8381101561416e578035858111156140bd575f80fd5b860160c0818c03601f190112156140d2575f80fd5b6140da613c0b565b6140e5898301613b32565b815260406140f4818401613b32565b8a8301526060808401358284015260809150614111828501613fb0565b9083015260a08381013589811115614127575f80fd5b6141358f8d83880101613fbe565b838501525060c084013591508882111561414d575f80fd5b61415b8e8c84870101613fbe565b90830152508452509186019186016140a7565b5098975050505050505050565b8181038181111561068257610682613f35565b634e487b7160e01b5f52602160045260245ffd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8051602080830151919081101561420d575f198160200360031b1b821691505b50919050565b5f5b8381101561422d578181015183820152602001614215565b50505f910152565b5f8251614246818460208701614213565b9190910192915050565b634e487b7160e01b5f52601260045260245ffd5b5f60ff83168061427657614276614250565b8060ff84160691505092915050565b60ff828116828216039081111561068257610682613f35565b6020808252604a908201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60408201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606082015269206465636f6461626c6560b01b608082015260a00190565b5f6001820161431f5761431f613f35565b5060010190565b5f8351614337818460208801614213565b83519083019061434b818360208801614213565b01949350505050565b602081525f8251806020840152614372816040850160208701614213565b601f01601f19169190910160400192915050565b60ff818116838216019081111561068257610682613f35565b5f826143ad576143ad614250565b500490565b808202811582820484141761068257610682613f35565b600181815b8085111561440357815f19048211156143e9576143e9613f35565b808516156143f657918102915b93841c93908002906143ce565b509250929050565b5f8261441957506001610682565b8161442557505f610682565b816001811461443b576002811461444557614461565b6001915050610682565b60ff84111561445657614456613f35565b50506001821b610682565b5060208310610133831016604e8410600b8410161715614484575081810a610682565b61448e83836143c9565b805f19048211156144a1576144a1613f35565b029392505050565b5f6107ae838361440b565b5f826144c2576144c2614250565b50069056fe524c505265616465723a206c656e677468206f6620636f6e74656e74206d7573360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212205659405515807d049e6589a2728fe0863d5c3072540f53ef4e8701e75661788864736f6c63430008180033