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-04-24T01:16:18.116699Z
contracts/signal/SignalService.sol
// SPDX-License-Identifier: MIT pragma 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.xyz contract 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_SENDER(); error SS_INVALID_LAST_HOP_CHAINID(); error SS_INVALID_MID_HOP_CHAINID(); error SS_INVALID_STATE(); error SS_INVALID_VALUE(); error SS_SIGNAL_NOT_FOUND(); error SS_UNAUTHORIZED(); error SS_UNSUPPORTED(); modifier validSender(address _app) { if (_app == address(0)) revert SS_INVALID_SENDER(); _; } modifier nonZeroValue(bytes32 _input) { if (_input == 0) revert SS_INVALID_VALUE(); _; } /// @notice Initializes the contract. /// @param _owner The owner of this contract. msg.sender will be used if this value is zero. /// @param _addressManager The address of the {AddressManager} contract. function init(address _owner, address _addressManager) external initializer { __Essential_init(_owner, _addressManager); } /// @dev Authorize or deauthorize an address for calling syncChainData. /// @dev Note that addr is supposed to be TaikoL1 and TaikoL1 contracts deployed locally. /// @param _addr The address to be authorized or deauthorized. /// @param _authorize True if authorize, false otherwise. function authorize(address _addr, bool _authorize) external onlyOwner { if (isAuthorized[_addr] == _authorize) revert SS_INVALID_STATE(); isAuthorized[_addr] = _authorize; emit Authorized(_addr, _authorize); } /// @inheritdoc ISignalService function sendSignal(bytes32 _signal) external returns (bytes32) { return _sendSignal(msg.sender, _signal, _signal); } /// @inheritdoc ISignalService function syncChainData( uint64 _chainId, bytes32 _kind, uint64 _blockId, bytes32 _chainData ) external returns (bytes32) { if (!isAuthorized[msg.sender]) revert SS_UNAUTHORIZED(); return _syncChainData(_chainId, _kind, _blockId, _chainData); } /// @inheritdoc ISignalService /// @dev This function may revert. function proveSignalReceived( uint64 _chainId, address _app, bytes32 _signal, bytes calldata _proof ) external virtual whenNotPaused nonReentrant returns (uint256 numCacheOps_) { CacheAction[] memory actions = // actions for caching _verifySignalReceived(_chainId, _app, _signal, _proof, true); for (uint256 i; i < actions.length; ++i) { numCacheOps_ += _cache(actions[i]); } } /// @inheritdoc ISignalService /// @dev This function may revert. function verifySignalReceived( uint64 _chainId, address _app, bytes32 _signal, bytes calldata _proof ) external view { _verifySignalReceived(_chainId, _app, _signal, _proof, false); } /// @inheritdoc ISignalService function isChainDataSynced( uint64 _chainId, bytes32 _kind, uint64 _blockId, bytes32 _chainData ) public view nonZeroValue(_chainData) returns (bool) { bytes32 signal = signalForChainData(_chainId, _kind, _blockId); return _loadSignalValue(address(this), signal) == _chainData; } /// @inheritdoc ISignalService function isSignalSent(address _app, bytes32 _signal) public view returns (bool) { return _loadSignalValue(_app, _signal) != 0; } /// @inheritdoc ISignalService function getSyncedChainData( uint64 _chainId, bytes32 _kind, uint64 _blockId ) public view returns (uint64 blockId_, bytes32 chainData_) { blockId_ = _blockId != 0 ? _blockId : topBlockId[_chainId][_kind]; if (blockId_ != 0) { bytes32 signal = signalForChainData(_chainId, _kind, blockId_); chainData_ = _loadSignalValue(address(this), signal); if (chainData_ == 0) revert SS_SIGNAL_NOT_FOUND(); } } /// @inheritdoc ISignalService function signalForChainData( uint64 _chainId, bytes32 _kind, uint64 _blockId ) public pure returns (bytes32) { return keccak256(abi.encode(_chainId, _kind, _blockId)); } /// @notice Returns the slot for a signal. /// @param _chainId The chainId of the signal. /// @param _app The address that initiated the signal. /// @param _signal The signal (message) that was sent. /// @return The slot for the signal. function getSignalSlot( uint64 _chainId, address _app, bytes32 _signal ) public pure returns (bytes32) { return keccak256(abi.encodePacked(LibStrings.S_SIGNAL, _chainId, _app, _signal)); } function _verifyHopProof( uint64 _chainId, address _app, bytes32 _signal, bytes32 _value, HopProof memory _hop, address _signalService ) internal view virtual validSender(_app) nonZeroValue(_signal) nonZeroValue(_value) returns (bytes32) { return LibTrieProof.verifyMerkleProof( _hop.rootHash, _signalService, getSignalSlot(_chainId, _app, _signal), _value, _hop.accountProof, _hop.storageProof ); } function _authorizePause(address, bool) internal pure override { revert SS_UNSUPPORTED(); } function _syncChainData( uint64 _chainId, bytes32 _kind, uint64 _blockId, bytes32 _chainData ) private returns (bytes32 signal_) { signal_ = signalForChainData(_chainId, _kind, _blockId); _sendSignal(address(this), signal_, _chainData); if (topBlockId[_chainId][_kind] < _blockId) { topBlockId[_chainId][_kind] = _blockId; } emit ChainDataSynced(_chainId, _blockId, _kind, _chainData, signal_); } function _sendSignal( address _app, bytes32 _signal, bytes32 _value ) private validSender(_app) nonZeroValue(_signal) nonZeroValue(_value) returns (bytes32 slot_) { slot_ = getSignalSlot(uint64(block.chainid), _app, _signal); assembly { sstore(slot_, _value) } emit SignalSent(_app, _signal, slot_, _value); } function _cache(CacheAction memory _action) private returns (uint256 numCacheOps_) { // cache state root bool cacheStateRoot = _action.option == CacheOption.CACHE_BOTH || _action.option == CacheOption.CACHE_STATE_ROOT; if (cacheStateRoot && _action.isFullProof && !_action.isLastHop) { numCacheOps_ = 1; _syncChainData( _action.chainId, LibStrings.H_STATE_ROOT, _action.blockId, _action.rootHash ); } // cache signal root bool cacheSignalRoot = _action.option == CacheOption.CACHE_BOTH || _action.option == CacheOption.CACHE_SIGNAL_ROOT; if (cacheSignalRoot && (_action.isFullProof || !_action.isLastHop)) { numCacheOps_ += 1; _syncChainData( _action.chainId, LibStrings.H_SIGNAL_ROOT, _action.blockId, _action.signalRoot ); } } function _loadSignalValue( address _app, bytes32 _signal ) private view validSender(_app) nonZeroValue(_signal) returns (bytes32 value_) { bytes32 slot = getSignalSlot(uint64(block.chainid), _app, _signal); assembly { value_ := sload(slot) } } function _verifySignalReceived( uint64 _chainId, address _app, bytes32 _signal, bytes calldata _proof, bool _prepareCaching ) private view validSender(_app) nonZeroValue(_signal) returns (CacheAction[] memory actions) { HopProof[] memory hopProofs = abi.decode(_proof, (HopProof[])); if (hopProofs.length == 0) revert SS_EMPTY_PROOF(); uint64[] memory trace = new uint64[](hopProofs.length - 1); if (_prepareCaching) { actions = new CacheAction[](hopProofs.length); } uint64 chainId = _chainId; address app = _app; bytes32 signal = _signal; bytes32 value = _signal; address signalService = resolve(chainId, "signal_service", false); HopProof memory hop; bytes32 signalRoot; bool isFullProof; bool isLastHop; for (uint256 i; i < hopProofs.length; ++i) { hop = hopProofs[i]; for (uint256 j; j < i; ++j) { if (trace[j] == hop.chainId) revert SS_INVALID_HOPS_WITH_LOOP(); } signalRoot = _verifyHopProof(chainId, app, signal, value, hop, signalService); isLastHop = i == trace.length; if (isLastHop) { if (hop.chainId != block.chainid) revert SS_INVALID_LAST_HOP_CHAINID(); signalService = address(this); } else { trace[i] = hop.chainId; if (hop.chainId == 0 || hop.chainId == block.chainid) { revert SS_INVALID_MID_HOP_CHAINID(); } signalService = resolve(hop.chainId, "signal_service", false); } isFullProof = hop.accountProof.length != 0; if (_prepareCaching) { actions[i] = CacheAction( hop.rootHash, signalRoot, chainId, hop.blockId, isFullProof, isLastHop, hop.cacheOption ); } signal = signalForChainData( chainId, isFullProof ? LibStrings.H_STATE_ROOT : LibStrings.H_SIGNAL_ROOT, hop.blockId ); value = hop.rootHash; chainId = hop.chainId; app = signalService; } if (value == 0 || value != _loadSignalValue(address(this), signal)) { revert SS_SIGNAL_NOT_FOUND(); } } }
contracts/common/AddressResolver.sol
// SPDX-License-Identifier: MIT pragma 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.xyz abstract 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(); _; } /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } /// @inheritdoc IAddressResolver function resolve( bytes32 _name, bool _allowZeroAddress ) public view virtual returns (address payable) { return _resolve(uint64(block.chainid), _name, _allowZeroAddress); } /// @inheritdoc IAddressResolver function resolve( uint64 _chainId, bytes32 _name, bool _allowZeroAddress ) public view virtual returns (address payable) { return _resolve(_chainId, _name, _allowZeroAddress); } /// @dev Initialization method for setting up AddressManager reference. /// @param _addressManager Address of the AddressManager. function __AddressResolver_init(address _addressManager) internal virtual onlyInitializing { if (block.chainid > type(uint64).max) { revert RESOLVER_UNEXPECTED_CHAINID(); } addressManager = _addressManager; } /// @dev Helper method to resolve name-to-address. /// @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 addr_ Address associated with the given name on the specified /// chain. function _resolve( uint64 _chainId, bytes32 _name, bool _allowZeroAddress ) private view returns (address payable addr_) { address _addressManager = addressManager; if (_addressManager == address(0)) revert RESOLVER_INVALID_MANAGER(); addr_ = payable(IAddressManager(_addressManager).getAddress(_chainId, _name)); if (!_allowZeroAddress && addr_ == address(0)) { revert RESOLVER_ZERO_ADDR(_chainId, _name); } } }
contracts/common/EssentialContract.sol
// SPDX-License-Identifier: MIT pragma 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.xyz abstract 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 REENTRANT_CALL(); error INVALID_PAUSE_STATUS(); error ZERO_ADDR_MANAGER(); /// @dev Modifier that ensures the caller is the owner or resolved address of a given name. /// @param _name The name to check against. modifier onlyFromOwnerOrNamed(bytes32 _name) { if (msg.sender != owner() && msg.sender != resolve(_name, true)) revert RESOLVER_DENIED(); _; } modifier nonReentrant() { if (_loadReentryLock() == _TRUE) revert REENTRANT_CALL(); _storeReentryLock(_TRUE); _; _storeReentryLock(_FALSE); } modifier whenPaused() { if (!paused()) revert INVALID_PAUSE_STATUS(); _; } modifier whenNotPaused() { if (paused()) revert INVALID_PAUSE_STATUS(); _; } /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } /// @notice Pauses the contract. function pause() public virtual whenNotPaused { __paused = _TRUE; emit Paused(msg.sender); // We call the authorize function here to avoid: // Warning (5740): Unreachable code. _authorizePause(msg.sender, true); } /// @notice Unpauses the contract. function unpause() public virtual whenPaused { __paused = _FALSE; lastUnpausedAt = uint64(block.timestamp); emit Unpaused(msg.sender); // We call the authorize function here to avoid: // Warning (5740): Unreachable code. _authorizePause(msg.sender, false); } /// @notice Returns true if the contract is paused, and false otherwise. /// @return true if paused, false otherwise. function paused() public view returns (bool) { return __paused == _TRUE; } /// @notice Initializes the contract. /// @param _owner The owner of this contract. msg.sender will be used if this value is zero. /// @param _addressManager The address of the {AddressManager} contract. function __Essential_init(address _owner, address _addressManager) internal onlyInitializing { if (_addressManager == address(0)) revert ZERO_ADDR_MANAGER(); __Essential_init(_owner); __AddressResolver_init(_addressManager); } function __Essential_init(address _owner) internal virtual { _transferOwnership(_owner == address(0) ? msg.sender : _owner); __paused = _FALSE; } function _authorizeUpgrade(address) internal virtual override onlyOwner { } function _authorizePause(address, bool) internal virtual onlyOwner { } // Stores the reentry lock function _storeReentryLock(uint8 _reentry) internal virtual { if (LibNetwork.isDencunSupported(block.chainid)) { assembly { tstore(_REENTRY_SLOT, _reentry) } } else { __reentry = _reentry; } } // Loads the reentry lock function _loadReentryLock() internal view virtual returns (uint8 reentry_) { if (LibNetwork.isDencunSupported(block.chainid)) { assembly { reentry_ := tload(_REENTRY_SLOT) } } else { reentry_ = __reentry; } } function _inNonReentrant() internal view returns (bool) { return _loadReentryLock() == _TRUE; } }
contracts/common/IAddressManager.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /// @title IAddressManager /// @notice Manages a mapping of (chainId, name) pairs to Ethereum addresses. /// @custom:security-contact security@taiko.xyz interface 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: MIT pragma 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.xyz interface 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 ) external view returns (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 ) external view returns (address payable); }
contracts/common/LibStrings.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /// @title LibStrings /// @custom:security-contact security@taiko.xyz library LibStrings { bytes32 internal constant B_CHAIN_WATCHDOG = bytes32("chain_watchdog"); bytes32 internal constant B_WITHDRAWER = bytes32("withdrawer"); bytes32 internal constant B_PROPOSER = bytes32("proposer"); bytes32 internal constant B_PROPOSER_ONE = bytes32("proposer_one"); bytes32 internal constant B_SIGNAL_SERVICE = bytes32("signal_service"); bytes32 internal constant B_TAIKO_TOKEN = bytes32("taiko_token"); bytes32 internal constant B_TAIKO = bytes32("taiko"); bytes32 internal constant B_BRIDGE = bytes32("bridge"); bytes32 internal constant B_ERC20_VAULT = bytes32("erc20_vault"); bytes32 internal constant B_BRIDGED_ERC20 = bytes32("bridged_erc20"); bytes32 internal constant B_ERC1155_VAULT = bytes32("erc1155_vault"); bytes32 internal constant B_BRIDGED_ERC1155 = bytes32("bridged_erc1155"); bytes32 internal constant B_ERC721_VAULT = bytes32("erc721_vault"); bytes32 internal constant B_BRIDGED_ERC721 = bytes32("bridged_erc721"); bytes32 internal constant B_BRIDGE_WATCHDOG = bytes32("bridge_watchdog"); bytes32 internal constant B_SGX_WATCHDOG = bytes32("sgx_watchdog"); 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_TIER_GUARDIAN_MINORITY = bytes32("tier_guardian_minority"); bytes32 internal constant B_TIER_GUARDIAN = bytes32("tier_guardian"); bytes32 internal constant B_AUTOMATA_DCAP_ATTESTATION = bytes32("automata_dcap_attestation"); bytes32 internal constant B_PROVER_ASSIGNMENT = bytes32("PROVER_ASSIGNMENT"); bytes32 internal constant H_RETURN_LIVENESS_BOND = keccak256("RETURN_LIVENESS_BOND"); bytes32 internal constant H_STATE_ROOT = keccak256("STATE_ROOT"); bytes32 internal constant H_SIGNAL_ROOT = keccak256("SIGNAL_ROOT"); string internal constant S_SIGNAL = "SIGNAL"; }
contracts/libs/LibNetwork.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /// @title LibNetwork library 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_009; /// @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. /// @return true if the chain ID represents an internal Taiko devnet's base layer, false /// otherwise. function isTaikoDevnetL1(uint256 _chainId) internal pure returns (bool) { return _chainId >= 32_300 && _chainId <= 32_400; } /// @dev Checks if the chain supports Dencun hardfork. Note that this check doesn't need to be /// exhaustive. /// @param _chainId The chain ID. /// @return true if the chain supports Dencun hardfork, false otherwise. function isDencunSupported(uint256 _chainId) internal pure returns (bool) { return _chainId == LibNetwork.MAINNET || _chainId == LibNetwork.HOLESKY || _chainId == LibNetwork.SEPOLIA || isTaikoDevnetL1(_chainId); } }
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.xyz library 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 root function verifyMerkleProof( bytes32 _rootHash, address _addr, bytes32 _slot, bytes32 _value, bytes[] memory _accountProof, bytes[] memory _storageProof ) internal pure returns (bytes32 storageRoot_) { if (_accountProof.length != 0) { bytes memory rlpAccount = SecureMerkleTrie.get(abi.encodePacked(_addr), _accountProof, _rootHash); if (rlpAccount.length == 0) revert LTP_INVALID_ACCOUNT_PROOF(); RLPReader.RLPItem[] memory accountState = RLPReader.readList(rlpAccount); storageRoot_ = bytes32(RLPReader.readBytes(accountState[_ACCOUNT_FIELD_INDEX_STORAGE_HASH])); } else { storageRoot_ = _rootHash; } bool verified = SecureMerkleTrie.verifyInclusionProof( bytes.concat(_slot), RLPWriter.writeUint(uint256(_value)), _storageProof, storageRoot_ ); if (!verified) revert LTP_INVALID_INCLUSION_PROOF(); } }
contracts/signal/ISignalService.sol
// SPDX-License-Identifier: MIT pragma 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.xyz interface 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; /// @notice The signal service's storage proof. bytes[] storageProof; } /// @notice Emitted when a remote chain's state root or signal root is /// synced locally as a signal. /// @param chainId The remote chainId. /// @param blockId The chain data's corresponding blockId. /// @param kind A value to mark the data type. /// @param data The remote data. /// @param signal The signal for this chain data. event ChainDataSynced( uint64 indexed chainId, uint64 indexed blockId, bytes32 indexed kind, bytes32 data, bytes32 signal ); /// @notice Emitted when a signal is sent. /// @param app The address that initiated the signal. /// @param signal The signal (message) that was sent. /// @param slot The location in storage where this signal is stored. /// @param value The value of the signal. event SignalSent(address app, bytes32 signal, bytes32 slot, bytes32 value); /// @notice Emitted when an address is authorized or deauthorized. /// @param addr The address to be authorized or deauthorized. /// @param authrized True if authorized, false otherwise. event Authorized(address indexed addr, bool authrized); /// @notice Send a signal (message) by setting the storage slot to a value of 1. /// @param _signal The signal (message) to send. /// @return slot_ The location in storage where this signal is stored. function sendSignal(bytes32 _signal) external returns (bytes32 slot_); /// @notice Sync a data from a remote chain locally as a signal. The signal is calculated /// uniquely from chainId, kind, and data. /// @param _chainId The remote chainId. /// @param _kind A value to mark the data type. /// @param _blockId The chain data's corresponding blockId /// @param _chainData The remote data. /// @return signal_ The signal for this chain data. function syncChainData( uint64 _chainId, bytes32 _kind, uint64 _blockId, bytes32 _chainData ) external returns (bytes32 signal_); /// @notice Verifies if a signal has been received on the target chain. /// @param _chainId The identifier for the source chain from which the /// signal originated. /// @param _app The address that initiated the signal. /// @param _signal The signal (message) to send. /// @param _proof Merkle proof that the signal was persisted on the /// source chain. /// @return numCacheOps_ The number of newly cached items. function proveSignalReceived( uint64 _chainId, address _app, bytes32 _signal, bytes calldata _proof ) external returns (uint256 numCacheOps_); /// @notice Verifies if a signal has been received on the target chain. /// This is the "readonly" version of proveSignalReceived. /// @param _chainId The identifier for the source chain from which the /// signal originated. /// @param _app The address that initiated the signal. /// @param _signal The signal (message) to send. /// @param _proof Merkle proof that the signal was persisted on the /// source chain. function verifySignalReceived( uint64 _chainId, address _app, bytes32 _signal, bytes calldata _proof ) external view; /// @notice Verifies if a particular signal has already been sent. /// @param _app The address that initiated the signal. /// @param _signal The signal (message) that was sent. /// @return true if the signal has been sent, otherwise false. function isSignalSent(address _app, bytes32 _signal) external view returns (bool); /// @notice Checks if a chain data has been synced. /// uniquely from chainId, kind, and data. /// @param _chainId The remote chainId. /// @param _kind A value to mark the data type. /// @param _blockId The chain data's corresponding blockId /// @param _chainData The remote data. /// @return true if the data has been synced, otherwise false. function isChainDataSynced( uint64 _chainId, bytes32 _kind, uint64 _blockId, bytes32 _chainData ) external view returns (bool); /// @notice Returns the given block's chain data. /// @param _chainId Identifier of the chainId. /// @param _kind A value to mark the data type. /// @param _blockId The chain data's corresponding block id. If this value is 0, use the top /// block id. /// @return blockId_ The actual block id. /// @return chainData_ The synced chain data. function getSyncedChainData( uint64 _chainId, bytes32 _kind, uint64 _blockId ) external view returns (uint64 blockId_, bytes32 chainData_); /// @notice Returns the data to be used for caching slot generation. /// @param _chainId Identifier of the chainId. /// @param _kind A value to mark the data type. /// @param _blockId The chain data's corresponding block id. If this value is 0, use the top /// block id. /// @return signal_ The signal used for caching slot creation. function signalForChainData( uint64 _chainId, bytes32 _kind, uint64 _blockId ) external pure returns (bytes32 signal_); }
contracts/thirdparty/optimism/Bytes.sol
// SPDX-License-Identifier: MIT pragma 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 ) internal pure returns (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 // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } /// @notice Slices a byte array with a given starting index up to the end of the original byte /// array. Returns a new array rather than a pointer to the original. /// @param _bytes Byte array to slice. /// @param _start Starting index of the slice. /// @return Slice of the input byte array. function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) { if (_start >= _bytes.length) { return bytes(""); } return slice(_bytes, _start, _bytes.length - _start); } /// @notice Converts a byte array into a nibble array by splitting each byte into two nibbles. /// Resulting nibble array will be exactly twice as long as the input byte array. /// @param _bytes Input byte array to convert. /// @return Resulting nibble array. function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) { bytes memory _nibbles; assembly { // Grab a free memory offset for the new array _nibbles := mload(0x40) // Load the length of the passed bytes array from memory let bytesLength := mload(_bytes) // Calculate the length of the new nibble array // This is the length of the input array times 2 let nibblesLength := shl(0x01, bytesLength) // Update the free memory pointer to allocate memory for the new array. // To do this, we add the length of the new array + 32 bytes for the array length // rounded up to the nearest 32 byte boundary to the current free memory pointer. mstore(0x40, add(_nibbles, and(not(0x1F), add(nibblesLength, 0x3F)))) // Store the length of the new array in memory mstore(_nibbles, nibblesLength) // Store the memory offset of the _bytes array's contents on the stack let bytesStart := add(_bytes, 0x20) // Store the memory offset of the nibbles array's contents on the stack let nibblesStart := add(_nibbles, 0x20) // Loop through each byte in the input array for { let i := 0x00 } lt(i, bytesLength) { i := add(i, 0x01) } { // Get the starting offset of the next 2 bytes in the nibbles array let offset := add(nibblesStart, shl(0x01, i)) // Load the byte at the current index within the `_bytes` array let b := byte(0x00, mload(add(bytesStart, i))) // Pull out the first nibble and store it in the new array mstore8(offset, shr(0x04, b)) // Pull out the second nibble and store it in the new array mstore8(add(offset, 0x01), and(b, 0x0F)) } } return _nibbles; } /// @notice Compares two byte arrays by comparing their keccak256 hashes. /// @param _bytes First byte array to compare. /// @param _other Second byte array to compare. /// @return true if the two byte arrays are equal, false otherwise. function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) { return keccak256(_bytes) == keccak256(_other); } }
contracts/thirdparty/optimism/rlp/RLPReader.sol
// SPDX-License-Identifier: MIT pragma 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. 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" ); MemoryPointer ptr; assembly { ptr := add(_in, 32) } out_ = RLPItem({ length: _in.length, ptr: ptr }); } /// @notice Reads an RLP list value into a list of RLP items. /// @param _in RLP list value. /// @return out_ Decoded RLP list items. function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory out_) { (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in); require( itemType == RLPItemType.LIST_ITEM, "RLPReader: decoded item type for list is not a list item" ); require( listOffset + listLength == _in.length, "RLPReader: list item has an invalid data remainder" ); // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by // writing to the length. Since we can't know the number of RLP items without looping over // the entire input, we'd have to loop twice to accurately size this array. It's easier to // simply set a reasonable maximum list length and decrease the size before we finish. out_ = new RLPItem[](MAX_LIST_LENGTH); uint256 itemCount = 0; uint256 offset = listOffset; while (offset < _in.length) { (uint256 itemOffset, uint256 itemLength,) = _decodeLength( RLPItem({ length: _in.length - offset, ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset) }) ); // We don't need to check itemCount < out.length explicitly because Solidity already // handles this check on our behalf, we'd just be wasting gas. out_[itemCount] = RLPItem({ length: itemLength + itemOffset, ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset) }); itemCount += 1; offset += itemOffset + itemLength; } // Decrease the array size to match the actual item count. assembly { mstore(out_, itemCount) } } /// @notice Reads an RLP list value into a list of RLP items. /// @param _in RLP list value. /// @return out_ Decoded RLP list items. function readList(bytes memory _in) internal pure returns (RLPItem[] memory out_) { out_ = readList(toRLPItem(_in)); } /// @notice Reads an RLP bytes value into bytes. /// @param _in RLP bytes value. /// @return out_ Decoded bytes. function readBytes(RLPItem memory _in) internal pure returns (bytes memory out_) { (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in); require( itemType == RLPItemType.DATA_ITEM, "RLPReader: decoded item type for bytes is not a data item" ); require( _in.length == itemOffset + itemLength, "RLPReader: bytes value contains an invalid remainder" ); out_ = _copy(_in.ptr, itemOffset, itemLength); } /// @notice Reads an RLP bytes value into bytes. /// @param _in RLP bytes value. /// @return out_ Decoded bytes. function readBytes(bytes memory _in) internal pure returns (bytes memory out_) { out_ = readBytes(toRLPItem(_in)); } /// @notice Reads the raw bytes of an RLP item. /// @param _in RLP item to read. /// @return out_ Raw RLP bytes. function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory out_) { out_ = _copy(_in.ptr, 0, _in.length); } /// @notice Decodes the length of an RLP item. /// @param _in RLP item to decode. /// @return offset_ Offset of the encoded data. /// @return length_ Length of the encoded data. /// @return type_ RLP item type (LIST_ITEM or DATA_ITEM). function _decodeLength(RLPItem memory _in) private pure returns (uint256 offset_, uint256 length_, RLPItemType type_) { // Short-circuit if there's nothing to decode, note that we perform this check when // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass // that function and create an RLP item directly. So we need to check this anyway. require( _in.length > 0, "RLPReader: length of an RLP item must be greater than zero to be decodable" ); MemoryPointer ptr = _in.ptr; uint256 prefix; assembly { prefix := byte(0, mload(ptr)) } if (prefix <= 0x7f) { // Single byte. return (0, 1, RLPItemType.DATA_ITEM); } else if (prefix <= 0xb7) { // Short string. // slither-disable-next-line variable-scope uint256 strLen = prefix - 0x80; require( _in.length > strLen, "RLPReader: length of content must be greater than string length (short string)" ); bytes1 firstByteOfContent; assembly { firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff)) } require( strLen != 1 || firstByteOfContent >= 0x80, "RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)" ); return (1, strLen, RLPItemType.DATA_ITEM); } else if (prefix <= 0xbf) { // Long string. uint256 lenOfStrLen = prefix - 0xb7; require( _in.length > lenOfStrLen, "RLPReader: length of content must be > than length of string length (long string)" ); bytes1 firstByteOfContent; assembly { firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff)) } require( firstByteOfContent != 0x00, "RLPReader: length of content must not have any leading zeros (long string)" ); uint256 strLen; assembly { strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1))) } require( strLen > 55, "RLPReader: length of content must be greater than 55 bytes (long string)" ); require( _in.length > lenOfStrLen + strLen, "RLPReader: length of content must be greater than total length (long string)" ); return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM); } else if (prefix <= 0xf7) { // Short list. // slither-disable-next-line variable-scope uint256 listLen = prefix - 0xc0; require( _in.length > listLen, "RLPReader: length of content must be greater than list length (short list)" ); return (1, listLen, RLPItemType.LIST_ITEM); } else { // Long list. uint256 lenOfListLen = prefix - 0xf7; require( _in.length > lenOfListLen, "RLPReader: length of content must be > than length of list length (long list)" ); bytes1 firstByteOfContent; assembly { firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff)) } require( firstByteOfContent != 0x00, "RLPReader: length of content must not have any leading zeros (long list)" ); uint256 listLen; assembly { listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1))) } require( listLen > 55, "RLPReader: length of content must be greater than 55 bytes (long list)" ); require( _in.length > lenOfListLen + listLen, "RLPReader: length of content must be greater than total length (long list)" ); return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM); } } /// @notice Copies the bytes from a memory location. /// @param _src Pointer to the location to read from. /// @param _offset Offset to start reading from. /// @param _length Number of bytes to read. /// @return out_ Copied bytes. function _copy( MemoryPointer _src, uint256 _offset, uint256 _length ) private pure returns (bytes memory out_) { out_ = new bytes(_length); if (_length == 0) { return out_; } // Mostly based on Solidity's copy_memory_to_memory: // solhint-disable max-line-length // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114 uint256 src = MemoryPointer.unwrap(_src) + _offset; assembly { let dest := add(out_, 32) let i := 0 for { } lt(i, _length) { i := add(i, 32) } { mstore(add(dest, i), mload(add(src, i))) } if gt(i, _length) { mstore(add(dest, _length), 0) } } } }
contracts/thirdparty/optimism/rlp/RLPWriter.sol
// SPDX-License-Identifier: MIT pragma 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. 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; } out_ = new bytes(lenLen + 1); out_[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55); for (i = 1; i <= lenLen; i++) { out_[i] = bytes1(uint8((_len / (256 ** (lenLen - i))) % 256)); } } } /// @notice Encode integer in big endian binary form with no leading zeroes. /// @param _x The integer to encode. /// @return out_ RLP encoded bytes. function _toBinary(uint256 _x) private pure returns (bytes memory out_) { bytes memory b = abi.encodePacked(_x); uint256 i = 0; for (; i < 32; i++) { if (b[i] != 0) { break; } } out_ = new bytes(32 - i); for (uint256 j = 0; j < out_.length; j++) { out_[j] = b[i++]; } } }
contracts/thirdparty/optimism/trie/MerkleTrie.sol
// SPDX-License-Identifier: MIT pragma 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. /// @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 ) internal pure returns (bool valid_) { valid_ = Bytes.equal(_value, get(_key, _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 ) internal pure returns (bytes memory value_) { require(_key.length > 0, "MerkleTrie: empty key"); TrieNode[] memory proof = _parseProof(_proof); bytes memory key = Bytes.toNibbles(_key); bytes memory currentNodeID = abi.encodePacked(_root); uint256 currentKeyIndex = 0; // Proof is top-down, so we start at the first element (root). for (uint256 i = 0; i < proof.length; i++) { TrieNode memory currentNode = proof[i]; // Key index should never exceed total key length or we'll be out of bounds. require(currentKeyIndex <= key.length, "MerkleTrie: key index exceeds total key length"); if (currentKeyIndex == 0) { // First proof element is always the root node. require( Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID), "MerkleTrie: invalid root hash" ); } else if (currentNode.encoded.length >= 32) { // Nodes 32 bytes or larger are hashed inside branch nodes. require( Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID), "MerkleTrie: invalid large internal hash" ); } else { // Nodes smaller than 32 bytes aren't hashed. require( Bytes.equal(currentNode.encoded, currentNodeID), "MerkleTrie: invalid internal node hash" ); } if (currentNode.decoded.length == BRANCH_NODE_LENGTH) { if (currentKeyIndex == key.length) { // Value is the last element of the decoded list (for branch nodes). There's // some ambiguity in the Merkle trie specification because bytes(0) is a // valid value to place into the trie, but for branch nodes bytes(0) can exist // even when the value wasn't explicitly placed there. Geth treats a value of // bytes(0) as "key does not exist" and so we do the same. value_ = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]); require( value_.length > 0, "MerkleTrie: value length must be greater than zero (branch)" ); // Extra proof elements are not allowed. require( i == proof.length - 1, "MerkleTrie: value node must be last node in proof (branch)" ); return value_; } else { // We're not at the end of the key yet. // Figure out what the next node ID should be and continue. uint8 branchKey = uint8(key[currentKeyIndex]); RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey]; currentNodeID = _getNodeID(nextNode); currentKeyIndex += 1; } } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) { bytes memory path = _getNodePath(currentNode); uint8 prefix = uint8(path[0]); uint8 offset = 2 - (prefix % 2); bytes memory pathRemainder = Bytes.slice(path, offset); bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex); uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder); // Whether this is a leaf node or an extension node, the path remainder MUST be a // prefix of the key remainder (or be equal to the key remainder) or the proof is // considered invalid. require( pathRemainder.length == sharedNibbleLength, "MerkleTrie: path remainder must share all nibbles with key" ); if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) { // Prefix of 2 or 3 means this is a leaf node. For the leaf node to be valid, // the key remainder must be exactly equal to the path remainder. We already // did the necessary byte comparison, so it's more efficient here to check that // the key remainder length equals the shared nibble length, which implies // equality with the path remainder (since we already did the same check with // the path remainder and the shared nibble length). require( keyRemainder.length == sharedNibbleLength, "MerkleTrie: key remainder must be identical to path remainder" ); // Our Merkle Trie is designed specifically for the purposes of the Ethereum // state trie. Empty values are not allowed in the state trie, so we can safely // say that if the value is empty, the key should not exist and the proof is // invalid. value_ = RLPReader.readBytes(currentNode.decoded[1]); require( value_.length > 0, "MerkleTrie: value length must be greater than zero (leaf)" ); // Extra proof elements are not allowed. require( i == proof.length - 1, "MerkleTrie: value node must be last node in proof (leaf)" ); return value_; } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) { // Prefix of 0 or 1 means this is an extension node. We move onto the next node // in the proof and increment the key index by the length of the path remainder // which is equal to the shared nibble length. currentNodeID = _getNodeID(currentNode.decoded[1]); currentKeyIndex += sharedNibbleLength; } else { revert("MerkleTrie: received a node with an unknown prefix"); } } else { revert("MerkleTrie: received an unparseable node"); } } revert("MerkleTrie: ran out of proof elements"); } /// @notice Parses an array of proof elements into a new array that contains both the original /// encoded element and the RLP-decoded element. /// @param _proof Array of proof elements to parse. /// @return proof_ Proof parsed into easily accessible structs. function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory proof_) { uint256 length = _proof.length; proof_ = new TrieNode[](length); for (uint256 i = 0; i < length; ++i) { proof_[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) }); } } /// @notice Picks out the ID for a node. Node ID is referred to as the "hash" within the /// specification, but nodes < 32 bytes are not actually hashed. /// @param _node Node to pull an ID for. /// @return id_ ID for the node, depending on the size of its contents. function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory id_) { id_ = _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node); } /// @notice Gets the path for a leaf or extension node. /// @param _node Node to get a path for. /// @return nibbles_ Node path, converted to an array of nibbles. function _getNodePath(TrieNode memory _node) private pure returns (bytes memory nibbles_) { nibbles_ = Bytes.toNibbles(RLPReader.readBytes(_node.decoded[0])); } /// @notice Utility; determines the number of nibbles shared between two nibble arrays. /// @param _a First nibble array. /// @param _b Second nibble array. /// @return shared_ Number of shared nibbles. function _getSharedNibbleLength( bytes memory _a, bytes memory _b ) private pure returns (uint256 shared_) { uint256 max = (_a.length < _b.length) ? _a.length : _b.length; for (; shared_ < max && _a[shared_] == _b[shared_];) { unchecked { ++shared_; } } } }
contracts/thirdparty/optimism/trie/SecureMerkleTrie.sol
// SPDX-License-Identifier: MIT pragma 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 ) internal pure returns (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 ) internal pure returns (bytes memory value_) { bytes memory key = _getSecureKey(_key); value_ = MerkleTrie.get(key, _proof, _root); } /// @notice Computes the hashed version of the input key. /// @param _key Key to hash. /// @return hash_ Hashed version of the key. function _getSecureKey(bytes memory _key) private pure returns (bytes memory hash_) { hash_ = abi.encodePacked(keccak256(_key)); } }
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. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } /** * @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[49] private __gap; }
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(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @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[49] private __gap; }
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] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
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 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
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 1 bytes32 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; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } }
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-assignment address 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. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeTo(address newImplementation) public virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; }
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 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
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; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
Compiler Settings
{"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/"],"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"cancun"}
Contract ABI
[{"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_SENDER","inputs":[]},{"type":"error","name":"SS_INVALID_STATE","inputs":[]},{"type":"error","name":"SS_INVALID_VALUE","inputs":[]},{"type":"error","name":"SS_SIGNAL_NOT_FOUND","inputs":[]},{"type":"error","name":"SS_UNAUTHORIZED","inputs":[]},{"type":"error","name":"SS_UNSUPPORTED","inputs":[]},{"type":"error","name":"ZERO_ADDR_MANAGER","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":"authrized","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":"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"}]}]
Contract Creation Code
0x60a06040523060805234801562000014575f80fd5b506200001f6200002f565b620000296200002f565b620000ed565b5f54610100900460ff16156200009b5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff90811614620000eb575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6080516144bf620001225f395f8181610640015281816106890152818161081c0152818161085c015261093301526144bf5ff3fe6080604052600436106101af575f3560e01c806379ba5097116100e7578063ce9d082011610087578063e30c397811610062578063e30c3978146104f1578063f09a40161461050e578063f2fde38b1461052d578063fe9fbb801461054c575f80fd5b8063ce9d08201461046f578063dfc8ff1d1461048e578063e07baba6146104cc575f80fd5b8063910af6ed116100c2578063910af6ed146103f357806391f3f74b146104125780639b527cfa14610431578063a86f9d9e14610450575f80fd5b806379ba5097146103ae5780638456cb59146103c25780638da5cb5b146103d6575f80fd5b80633f4ba83a1161015257806352d1902d1161012d57806352d1902d146103475780635c975abb1461035b57806366ca2bc01461037b578063715018a61461039a575f80fd5b80633f4ba83a146102f35780634f1ef286146103075780634f90a6741461031a575f80fd5b80633659cfe61161018d5780633659cfe61461025f5780633ab76e9f1461027e5780633ced0e08146102b55780633eb6b8cf146102d4575f80fd5b80632d1fb389146101b357806332676bc6146101d4578063355bcc3d14610208575b5f80fd5b3480156101be575f80fd5b506101d26101cd3660046139e0565b61057a565b005b3480156101df575f80fd5b506101f36101ee366004613a13565b610620565b60405190151581526020015b60405180910390f35b348015610213575f80fd5b50610247610222366004613a53565b60fb60209081525f92835260408084209091529082529020546001600160401b031681565b6040516001600160401b0390911681526020016101ff565b34801561026a575f80fd5b506101d2610279366004613a6d565b610636565b348015610289575f80fd5b5060975461029d906001600160a01b031681565b6040516001600160a01b0390911681526020016101ff565b3480156102c0575f80fd5b506101f36102cf366004613a88565b61071c565b3480156102df575f80fd5b5061029d6102ee366004613ac9565b610763565b3480156102fe575f80fd5b506101d2610779565b6101d2610315366004613bd9565b610812565b348015610325575f80fd5b50610339610334366004613a88565b6108e1565b6040519081526020016101ff565b348015610352575f80fd5b50610339610927565b348015610366575f80fd5b506101f360c954610100900460ff1660021490565b348015610386575f80fd5b50610339610395366004613c25565b6109d8565b3480156103a5575f80fd5b506101d26109e4565b3480156103b9575f80fd5b506101d26109f5565b3480156103cd575f80fd5b506101d2610a6c565b3480156103e1575f80fd5b506033546001600160a01b031661029d565b3480156103fe575f80fd5b5061033961040d366004613c3c565b610aeb565b34801561041d575f80fd5b5061033961042c366004613cd0565b610bbb565b34801561043c575f80fd5b5061033961044b366004613d0c565b610c10565b34801561045b575f80fd5b5061029d61046a366004613d3c565b610c3c565b34801561047a575f80fd5b506101d2610489366004613c3c565b610c48565b348015610499575f80fd5b506104ad6104a8366004613d0c565b610c5e565b604080516001600160401b0390931683526020830191909152016101ff565b3480156104d7575f80fd5b5060c954610247906201000090046001600160401b031681565b3480156104fc575f80fd5b506065546001600160a01b031661029d565b348015610519575f80fd5b506101d2610528366004613d5d565b610cf2565b348015610538575f80fd5b506101d2610547366004613a6d565b610e01565b348015610557575f80fd5b506101f3610566366004613a6d565b60fc6020525f908152604090205460ff1681565b610582610e72565b6001600160a01b0382165f90815260fc602052604090205481151560ff9091161515036105c2576040516398f26f4560e01b815260040160405180910390fd5b6001600160a01b0382165f81815260fc6020908152604091829020805460ff191685151590811790915591519182527f4c0079b9bcd37cd5d29a13938effd97c881798cbc6bd52a3026a29d94b27d1bf910160405180910390a25050565b5f61062b8383610ecc565b151590505b92915050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036106875760405162461bcd60e51b815260040161067e90613d94565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166106cf5f80516020614443833981519152546001600160a01b031690565b6001600160a01b0316146106f55760405162461bcd60e51b815260040161067e90613de0565b6106fe81610f2e565b604080515f8082526020820190925261071991839190610f36565b50565b5f8180820361073e57604051630426d36960e31b815260040160405180910390fd5b5f61074a878787610c10565b9050836107573083610ecc565b14979650505050505050565b5f61076f8484846110a0565b90505b9392505050565b61078d60c954610100900460ff1660021490565b6107aa5760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461010069ffffffffffffffffff001990911662010000426001600160401b031602171790556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9060200160405180910390a1610810335f611191565b565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361085a5760405162461bcd60e51b815260040161067e90613d94565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166108a25f80516020614443833981519152546001600160a01b031690565b6001600160a01b0316146108c85760405162461bcd60e51b815260040161067e90613de0565b6108d182610f2e565b6108dd82826001610f36565b5050565b335f90815260fc602052604081205460ff1661091057604051631f67751f60e01b815260040160405180910390fd5b61091c858585856111aa565b90505b949350505050565b5f306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109c65760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161067e565b505f8051602061444383398151915290565b5f61063033838461128c565b6109ec610e72565b6108105f611365565b60655433906001600160a01b03168114610a635760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161067e565b61071981611365565b610a8060c954610100900460ff1660021490565b15610a9e5760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200160405180910390a1610810336001611191565b5f610b0060c954610100900460ff1660021490565b15610b1e5760405163bae6e2a960e01b815260040160405180910390fd5b6002610b2861137e565b60ff1603610b495760405163dfc60d8560e01b815260040160405180910390fd5b610b5360026113bd565b5f610b6387878787876001611405565b90505f5b8151811015610ba657610b92828281518110610b8557610b85613e2c565b6020026020010151611870565b610b9c9084613e54565b9250600101610b67565b5050610bb260016113bd565b95945050505050565b5f6040518060400160405280600681526020016514d251d3905360d21b815250848484604051602001610bf19493929190613e89565b6040516020818303038152906040528051906020012090509392505050565b604080516001600160401b03808616602083015291810184905290821660608201525f90608001610bf1565b5f6107724684846110a0565b610c5685858585855f611405565b505050505050565b5f80826001600160401b03165f03610c9a576001600160401b038086165f90815260fb6020908152604080832088845290915290205416610c9c565b825b91506001600160401b03821615610cea575f610cb9868685610c10565b9050610cc53082610ecc565b91505f829003610ce85760405163738afa0560e01b815260040160405180910390fd5b505b935093915050565b5f54610100900460ff1615808015610d1057505f54600160ff909116105b80610d295750303b158015610d2957505f5460ff166001145b610d8c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161067e565b5f805460ff191660011790558015610dad575f805461ff0019166101001790555b610db783836119b4565b8015610dfc575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b610e09610e72565b606580546001600160a01b0383166001600160a01b03199091168117909155610e3a6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6033546001600160a01b031633146108105760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161067e565b5f826001600160a01b038116610ef5576040516327e0ab1560e21b815260040160405180910390fd5b825f819003610f1757604051630426d36960e31b815260040160405180910390fd5b5f610f23468787610bbb565b549695505050505050565b610719610e72565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615610f6957610dfc83611a13565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610fc3575060408051601f3d908101601f19168201909252610fc091810190613ed9565b60015b6110265760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b606482015260840161067e565b5f8051602061444383398151915281146110945760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b606482015260840161067e565b50610dfc838383611aae565b6097545f906001600160a01b0316806110cc57604051638ed88b2560e01b815260040160405180910390fd5b604051630a3dc4f360e21b81526001600160401b0386166004820152602481018590526001600160a01b038216906328f713cc90604401602060405180830381865afa15801561111e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111429190613ef0565b91508215801561115957506001600160a01b038216155b1561118957604051632b0d65db60e01b81526001600160401b03861660048201526024810185905260440161067e565b509392505050565b60405163198bb9dd60e11b815260040160405180910390fd5b5f6111b6858585610c10565b90506111c330828461128c565b506001600160401b038581165f90815260fb602090815260408083208884529091529020548185169116101561122d576001600160401b038581165f90815260fb602090815260408083208884529091529020805467ffffffffffffffff19169185169190911790555b83836001600160401b0316866001600160401b03167fde247c825b1fb2d7ff9e0e771cba6f9e757ad04479fcdc135d88ae91fd50b37d858560405161127c929190918252602082015260400190565b60405180910390a4949350505050565b5f836001600160a01b0381166112b5576040516327e0ab1560e21b815260040160405180910390fd5b835f8190036112d757604051630426d36960e31b815260040160405180910390fd5b835f8190036112f957604051630426d36960e31b815260040160405180910390fd5b611304468888610bbb565b858155604080516001600160a01b038a16815260208101899052908101829052606081018790529094507f0ad2d108660a211f47bf7fb43a0443cae181624995d3d42b88ee6879d200e9739060800160405180910390a15050509392505050565b606580546001600160a01b031916905561071981611ad8565b5f61138846611b29565b156113b357507fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5c90565b5060c95460ff1690565b6113c646611b29565b156113f157807fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5d50565b60c9805460ff831660ff1990911617905550565b6060856001600160a01b03811661142f576040516327e0ab1560e21b815260040160405180910390fd5b855f81900361145157604051630426d36960e31b815260040160405180910390fd5b5f61145e86880188613fba565b905080515f0361148157604051630b92daef60e21b815260040160405180910390fd5b5f6001825161149091906140f8565b6001600160401b038111156114a7576114a7613b02565b6040519080825280602002602001820160405280156114d0578160200160208202803683370190505b50905085156115635781516001600160401b038111156114f2576114f2613b02565b60405190808252806020026020018201604052801561155f57816020015b61154c6040805160e0810182525f80825260208201819052918101829052606081018290526080810182905260a081018290529060c082015290565b8152602001906001900390816115105790505b5094505b8a8a8a805f611584856d7369676e616c5f7365727669636560901b83610763565b90506115be6040805160c0810182525f80825260208201819052918101829052906060820190815260200160608152602001606081525090565b5f805f805b8b51811015611824578b81815181106115de576115de613e2c565b602002602001015194505f5b8181101561164857855f01516001600160401b03168c828151811061161157611611613e2c565b60200260200101516001600160401b031603611640576040516348362c2760e11b815260040160405180910390fd5b6001016115ea565b506116578a8a8a8a898b611b56565b93508a518114915081156116975784516001600160401b0316461461168f576040516338bf822760e21b815260040160405180910390fd5b30955061171a565b845f01518b82815181106116ad576116ad613e2c565b6001600160401b03928316602091820292909201015285511615806116db575084516001600160401b031646145b156116f957604051637556223560e11b815260040160405180910390fd5b8451611717906d7369676e616c5f7365727669636560901b5f610763565b95505b608085015151151592508f156117ae576040518060e00160405280866040015181526020018581526020018b6001600160401b0316815260200186602001516001600160401b03168152602001841515815260200183151581526020018660600151600381111561178d5761178d61410b565b8152508f82815181106117a2576117a2613e2c565b60200260200101819052505b6118098a846117dd577fc6cdc4f2acf13acb10f410085b821f7b7113b303e9a4799023f928317396aaf56117ff565b7f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da1695b8760200151610c10565b604086015186519b50969950975094955087946001016115c3565b5085158061183b57506118373088610ecc565b8614155b156118595760405163738afa0560e01b815260040160405180910390fd5b505050505050505050505050509695505050505050565b5f8060038360c00151600381111561188a5761188a61410b565b14806118ab575060028360c0015160038111156118a9576118a961410b565b145b90508080156118bb575082608001515b80156118c957508260a00151155b1561190b576001915061190983604001517f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da1698560600151865f01516111aa565b505b5f60038460c0015160038111156119245761192461410b565b1480611945575060018460c0015160038111156119435761194361410b565b145b9050808015611961575083608001518061196157508360a00151155b156119ad57611971600184613e54565b92506119ab84604001517fc6cdc4f2acf13acb10f410085b821f7b7113b303e9a4799023f928317396aaf5866060015187602001516111aa565b505b5050919050565b5f54610100900460ff166119da5760405162461bcd60e51b815260040161067e9061411f565b6001600160a01b038116611a01576040516375cabfef60e11b815260040160405180910390fd5b611a0a82611bf5565b6108dd81611c25565b6001600160a01b0381163b611a805760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161067e565b5f8051602061444383398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b611ab783611c95565b5f82511180611ac35750805b15610dfc57611ad28383611cd4565b50505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f6001821480611b3a575061426882145b80611b47575062aa36a782145b80610630575061063082611cf9565b5f856001600160a01b038116611b7f576040516327e0ab1560e21b815260040160405180910390fd5b855f819003611ba157604051630426d36960e31b815260040160405180910390fd5b855f819003611bc357604051630426d36960e31b815260040160405180910390fd5b611be7866040015186611bd78d8d8d610bbb565b8a8a608001518b60a00151611d10565b9a9950505050505050505050565b611c136001600160a01b03821615611c0d5781611365565b33611365565b5060c9805461ff001916610100179055565b5f54610100900460ff16611c4b5760405162461bcd60e51b815260040161067e9061411f565b6001600160401b03461115611c735760405163a12e8fa960e01b815260040160405180910390fd5b609780546001600160a01b0319166001600160a01b0392909216919091179055565b611c9e81611a13565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060610772838360405180606001604052806027815260200161446360279139611e1d565b5f617e2c8210158015610630575050617e90101590565b5f82515f14611db8576040516bffffffffffffffffffffffff19606088901b1660208201525f90611d5490603401604051602081830303815290604052858a611e91565b905080515f03611d7757604051630414cd5b60e31b815260040160405180910390fd5b5f611d8182611eaa565b9050611da681600281518110611d9957611d99613e2c565b6020026020010151611ebd565b611daf9061416a565b92505050611dbb565b50855b5f611df286604051602001611dd291815260200190565b60408051601f19818403018152919052611deb87611fdd565b8585611ff0565b905080611e1257604051638d9a4db360e01b815260040160405180910390fd5b509695505050505050565b60605f80856001600160a01b031685604051611e399190614190565b5f60405180830381855af49150503d805f8114611e71576040519150601f19603f3d011682016040523d82523d5f602084013e611e76565b606091505b5091509150611e8786838387612009565b9695505050505050565b60605f611e9d85612081565b9050610bb28185856120b3565b6060610630611eb883612920565b612971565b60605f805f611ecb85612b8e565b919450925090505f816001811115611ee557611ee561410b565b14611f585760405162461bcd60e51b815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067e565b611f628284613e54565b855114611fce5760405162461bcd60e51b815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527330b71034b73b30b634b2103932b6b0b4b73232b960611b606482015260840161067e565b610bb285602001518484613235565b6060610630611feb836132c5565b6133d8565b5f80611ffb86612081565b9050611e8781868686613430565b606083156120775782515f03612070576001600160a01b0385163b6120705760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161067e565b508161091f565b61091f8383613456565b6060818051906020012060405160200161209d91815260200190565b6040516020818303038152906040529050919050565b60605f8451116120fd5760405162461bcd60e51b81526020600482015260156024820152744d65726b6c65547269653a20656d707479206b657960581b604482015260640161067e565b5f61210784613480565b90505f61211386613563565b90505f8460405160200161212991815260200190565b60405160208183030381529060405290505f805b84518110156128c9575f85828151811061215957612159613e2c565b6020026020010151905084518311156121cb5760405162461bcd60e51b815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201526d0e8c2d840d6caf240d8cadccee8d60931b606482015260840161067e565b825f036122695780518051602091820120604051612218926121f292910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6122645760405162461bcd60e51b815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067e565b61235f565b8051516020116122ef5780518051602091820120604051612293926121f292910190815260200190565b6122645760405162461bcd60e51b815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e6044820152660c2d840d0c2e6d60cb1b606482015260840161067e565b80518451602080870191909120825191909201201461235f5760405162461bcd60e51b815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f646044820152650ca40d0c2e6d60d31b606482015260840161067e565b61236b60106001613e54565b81602001515103612503578451830361249d576123988160200151601081518110611d9957611d99613e2c565b96505f8751116124105760405162461bcd60e51b815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067e565b6001865161241e91906140f8565b82146124925760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067e565b505050505050610772565b5f8584815181106124b0576124b0613e2c565b602001015160f81c60f81b60f81c90505f82602001518260ff16815181106124da576124da613e2c565b602002602001015190506124ed816135c4565b95506124fa600186613e54565b945050506128c0565b600281602001515103612867575f61251a826135e8565b90505f815f8151811061252f5761252f613e2c565b016020015160f81c90505f6125456002836141bf565b6125509060026141e0565b90505f612560848360ff1661360b565b90505f61256d8a8961360b565b90505f61257a8383613640565b9050808351146125f25760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067e565b60ff851660021480612607575060ff85166003145b156127a757808251146126825760405162461bcd60e51b815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067e565b61269c8760200151600181518110611d9957611d99613e2c565b9c505f8d51116127145760405162461bcd60e51b815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067e565b60018c5161272291906140f8565b88146127965760405162461bcd60e51b815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067e565b505050505050505050505050610772565b60ff851615806127ba575060ff85166001145b156127f9576127e687602001516001815181106127d9576127d9613e2c565b60200260200101516135c4565b99506127f2818a613e54565b985061285c565b60405162461bcd60e51b815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f64652077697468604482015271040c2dc40eadcd6dcdeeedc40e0e4caccd2f60731b606482015260840161067e565b5050505050506128c0565b60405162461bcd60e51b815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e706172736561604482015267626c65206e6f646560c01b606482015260840161067e565b5060010161213d565b5060405162461bcd60e51b815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c656044820152646d656e747360d81b606482015260840161067e565b604080518082019091525f80825260208201525f8251116129535760405162461bcd60e51b815260040161067e906141f9565b50604080518082019091528151815260209182019181019190915290565b60605f805f61297f85612b8e565b91945092509050600181600181111561299a5761299a61410b565b14612a0d5760405162461bcd60e51b815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067e565b8451612a198385613e54565b14612a815760405162461bcd60e51b815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e76616044820152713634b2103230ba30903932b6b0b4b73232b960711b606482015260840161067e565b604080516020808252610420820190925290816020015b604080518082019091525f8082526020820152815260200190600190039081612a985790505093505f835b8651811015612b82575f80612b076040518060400160405280858c5f0151612aeb91906140f8565b8152602001858c60200151612b009190613e54565b9052612b8e565b509150915060405180604001604052808383612b239190613e54565b8152602001848b60200151612b389190613e54565b815250888581518110612b4d57612b4d613e2c565b6020908102919091010152612b63600185613e54565b9350612b6f8183613e54565b612b799084613e54565b92505050612ac3565b50845250919392505050565b5f805f80845f015111612bb35760405162461bcd60e51b815260040161067e906141f9565b602084015180515f1a607f8111612bd5575f60015f945094509450505061322e565b60b78111612d2e575f612be96080836140f8565b905080875f015111612c675760405162461bcd60e51b815260206004820152604e60248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201526d2873686f727420737472696e672960901b608482015260a40161067e565b6001838101516001600160f81b0319169082141580612c945750600160ff1b6001600160f81b0319821610155b612d1c5760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201526c73686f727420737472696e672960981b608482015260a40161067e565b506001955093505f925061322e915050565b60bf8111612f67575f612d4260b7836140f8565b905080875f015111612dc35760405162461bcd60e51b815260206004820152605160248201525f8051602061442383398151915260448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527067746820286c6f6e6720737472696e672960781b608482015260a40161067e565b60018301516001600160f81b0319165f819003612e485760405162461bcd60e51b815260206004820152604a60248201525f8051602061442383398151915260448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f6064820152696e6720737472696e672960b01b608482015260a40161067e565b600184015160088302610100031c60378111612eca5760405162461bcd60e51b815260206004820152604860248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201526720737472696e672960c01b608482015260a40161067e565b612ed48184613e54565b895111612f4b5760405162461bcd60e51b815260206004820152604c60248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201526b6c6f6e6720737472696e672960a01b608482015260a40161067e565b612f56836001613e54565b975095505f945061322e9350505050565b60f78111613006575f612f7b60c0836140f8565b905080875f015111612ff55760405162461bcd60e51b815260206004820152604a60248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e206c697374206c656e677468202873606482015269686f7274206c6973742960b01b608482015260a40161067e565b60019550935084925061322e915050565b5f61301260f7836140f8565b905080875f01511161308f5760405162461bcd60e51b815260206004820152604d60248201525f8051602061442383398151915260448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201526c6820286c6f6e67206c6973742960981b608482015260a40161067e565b60018301516001600160f81b0319165f8190036131125760405162461bcd60e51b815260206004820152604860248201525f8051602061442383398151915260448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f6064820152676e67206c6973742960c01b608482015260a40161067e565b600184015160088302610100031c603781116131925760405162461bcd60e51b815260206004820152604660248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e20353520627974657320286c6f6e67606482015265206c6973742960d01b608482015260a40161067e565b61319c8184613e54565b8951116132115760405162461bcd60e51b815260206004820152604a60248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e20746f74616c206c656e67746820286064820152696c6f6e67206c6973742960b01b608482015260a40161067e565b61321c836001613e54565b975095506001945061322e9350505050565b9193909250565b6060816001600160401b0381111561324f5761324f613b02565b6040519080825280601f01601f191660200182016040528015613279576020820181803683370190505b5090508115610772575f61328d8486613e54565b9050602082015f5b848110156132ad578281015182820152602001613295565b848111156132bb575f858301525b5050509392505050565b60605f826040516020016132db91815260200190565b60405160208183030381529060405290505f5b60208110156133265781818151811061330957613309613e2c565b01602001516001600160f81b0319165f03613326576001016132ee565b6133318160206140f8565b6001600160401b0381111561334857613348613b02565b6040519080825280601f01601f191660200182016040528015613372576020820181803683370190505b5092505f5b83518110156119ab57828261338b81614269565b93508151811061339d5761339d613e2c565b602001015160f81c60f81b8482815181106133ba576133ba613e2c565b60200101906001600160f81b03191690815f1a905350600101613377565b60608151600114801561340457506080825f815181106133fa576133fa613e2c565b016020015160f81c105b1561340d575090565b613419825160806136c3565b8260405160200161209d929190614281565b919050565b5f61091c846134408786866120b3565b8051602091820120825192909101919091201490565b8151156134665781518083602001fd5b8060405162461bcd60e51b815260040161067e91906142af565b8051606090806001600160401b0381111561349d5761349d613b02565b6040519080825280602002602001820160405280156134e257816020015b60408051808201909152606080825260208201528152602001906001900390816134bb5790505b5091505f5b818110156119ad57604051806040016040528085838151811061350c5761350c613e2c565b6020026020010151815260200161353b86848151811061352e5761352e613e2c565b6020026020010151611eaa565b81525083828151811061355057613550613e2c565b60209081029190910101526001016134e7565b606080604051905082518060011b603f8101601f191683016040528083525060208401602083015f5b838110156135b9578060011b8201818401515f1a8060041c8253600f81166001830153505060010161358c565b509295945050505050565b60606020825f0151106135df576135da82611ebd565b610630565b61063082613868565b606061063061360683602001515f81518110611d9957611d99613e2c565b613563565b606082518210613629575060408051602081019091525f8152610630565b610772838384865161363b91906140f8565b61387c565b5f808251845110613652578251613655565b83515b90505b80821080156136ac575082828151811061367457613674613e2c565b602001015160f81c60f81b6001600160f81b03191684838151811061369b5761369b613e2c565b01602001516001600160f81b031916145b156136bc57816001019150613658565b5092915050565b6060603883101561372757604080516001808252818301909252906020820181803683370190505090506136f782846142e1565b60f81b815f8151811061370c5761370c613e2c565b60200101906001600160f81b03191690815f1a905350610630565b5f60015b61373581866142fa565b1561375b578161374481614269565b925061375490506101008261430d565b905061372b565b613766826001613e54565b6001600160401b0381111561377d5761377d613b02565b6040519080825280601f01601f1916602001820160405280156137a7576020820181803683370190505b5092506137b484836142e1565b6137bf9060376142e1565b60f81b835f815181106137d4576137d4613e2c565b60200101906001600160f81b03191690815f1a905350600190505b8181116138605761010061380382846140f8565b61380f90610100614404565b61381990876142fa565b613823919061440f565b60f81b83828151811061383857613838613e2c565b60200101906001600160f81b03191690815f1a9053508061385881614269565b9150506137ef565b505092915050565b606061063082602001515f845f0151613235565b60608182601f0110156138c25760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b604482015260640161067e565b8282840110156139055760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b604482015260640161067e565b8183018451101561394c5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b604482015260640161067e565b60608215801561396a5760405191505f8252602082016040526139b4565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156139a357805183526020928301920161398b565b5050858452601f01601f1916604052505b50949350505050565b6001600160a01b0381168114610719575f80fd5b8035801515811461342b575f80fd5b5f80604083850312156139f1575f80fd5b82356139fc816139bd565b9150613a0a602084016139d1565b90509250929050565b5f8060408385031215613a24575f80fd5b8235613a2f816139bd565b946020939093013593505050565b80356001600160401b038116811461342b575f80fd5b5f8060408385031215613a64575f80fd5b613a2f83613a3d565b5f60208284031215613a7d575f80fd5b8135610772816139bd565b5f805f8060808587031215613a9b575f80fd5b613aa485613a3d565b935060208501359250613ab960408601613a3d565b9396929550929360600135925050565b5f805f60608486031215613adb575f80fd5b613ae484613a3d565b925060208401359150613af9604085016139d1565b90509250925092565b634e487b7160e01b5f52604160045260245ffd5b60405160c081016001600160401b0381118282101715613b3857613b38613b02565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613b6657613b66613b02565b604052919050565b5f82601f830112613b7d575f80fd5b81356001600160401b03811115613b9657613b96613b02565b613ba9601f8201601f1916602001613b3e565b818152846020838601011115613bbd575f80fd5b816020850160208301375f918101602001919091529392505050565b5f8060408385031215613bea575f80fd5b8235613bf5816139bd565b915060208301356001600160401b03811115613c0f575f80fd5b613c1b85828601613b6e565b9150509250929050565b5f60208284031215613c35575f80fd5b5035919050565b5f805f805f60808688031215613c50575f80fd5b613c5986613a3d565b94506020860135613c69816139bd565b93506040860135925060608601356001600160401b0380821115613c8b575f80fd5b818801915088601f830112613c9e575f80fd5b813581811115613cac575f80fd5b896020828501011115613cbd575f80fd5b9699959850939650602001949392505050565b5f805f60608486031215613ce2575f80fd5b613ceb84613a3d565b92506020840135613cfb816139bd565b929592945050506040919091013590565b5f805f60608486031215613d1e575f80fd5b613d2784613a3d565b925060208401359150613af960408501613a3d565b5f8060408385031215613d4d575f80fd5b82359150613a0a602084016139d1565b5f8060408385031215613d6e575f80fd5b8235613d79816139bd565b91506020830135613d89816139bd565b809150509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082018082111561063057610630613e40565b5f5b83811015613e81578181015183820152602001613e69565b50505f910152565b5f8551613e9a818460208a01613e67565b60c09590951b6001600160c01b0319169190940190815260609290921b6bffffffffffffffffffffffff19166008830152601c820152603c0192915050565b5f60208284031215613ee9575f80fd5b5051919050565b5f60208284031215613f00575f80fd5b8151610772816139bd565b5f6001600160401b03821115613f2357613f23613b02565b5060051b60200190565b80356004811061342b575f80fd5b5f82601f830112613f4a575f80fd5b81356020613f5f613f5a83613f0b565b613b3e565b82815260059290921b84018101918181019086841115613f7d575f80fd5b8286015b84811015611e125780356001600160401b03811115613f9e575f80fd5b613fac8986838b0101613b6e565b845250918301918301613f81565b5f6020808385031215613fcb575f80fd5b82356001600160401b0380821115613fe1575f80fd5b818501915085601f830112613ff4575f80fd5b8135614002613f5a82613f0b565b81815260059190911b83018401908481019088831115614020575f80fd5b8585015b838110156140eb5780358581111561403a575f80fd5b860160c0818c03601f1901121561404f575f80fd5b614057613b16565b614062898301613a3d565b81526040614071818401613a3d565b8a830152606080840135828401526080915061408e828501613f2d565b9083015260a083810135898111156140a4575f80fd5b6140b28f8d83880101613f3b565b838501525060c08401359150888211156140ca575f80fd5b6140d88e8c84870101613f3b565b9083015250845250918601918601614024565b5098975050505050505050565b8181038181111561063057610630613e40565b634e487b7160e01b5f52602160045260245ffd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8051602080830151919081101561418a575f198160200360031b1b821691505b50919050565b5f82516141a1818460208701613e67565b9190910192915050565b634e487b7160e01b5f52601260045260245ffd5b5f60ff8316806141d1576141d16141ab565b8060ff84160691505092915050565b60ff828116828216039081111561063057610630613e40565b6020808252604a908201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60408201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606082015269206465636f6461626c6560b01b608082015260a00190565b5f6001820161427a5761427a613e40565b5060010190565b5f8351614292818460208801613e67565b8351908301906142a6818360208801613e67565b01949350505050565b602081525f82518060208401526142cd816040850160208701613e67565b601f01601f19169190910160400192915050565b60ff818116838216019081111561063057610630613e40565b5f82614308576143086141ab565b500490565b808202811582820484141761063057610630613e40565b600181815b8085111561435e57815f190482111561434457614344613e40565b8085161561435157918102915b93841c9390800290614329565b509250929050565b5f8261437457506001610630565b8161438057505f610630565b816001811461439657600281146143a0576143bc565b6001915050610630565b60ff8411156143b1576143b1613e40565b50506001821b610630565b5060208310610133831016604e8410600b84101617156143df575081810a610630565b6143e98383614324565b805f19048211156143fc576143fc613e40565b029392505050565b5f6107728383614366565b5f8261441d5761441d6141ab565b50069056fe524c505265616465723a206c656e677468206f6620636f6e74656e74206d7573360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e29e895c02458d38c6bbe6e811894076308d652ef2fd2a6d5f602d8eb56a14f464736f6c63430008180033
Deployed ByteCode
0x6080604052600436106101af575f3560e01c806379ba5097116100e7578063ce9d082011610087578063e30c397811610062578063e30c3978146104f1578063f09a40161461050e578063f2fde38b1461052d578063fe9fbb801461054c575f80fd5b8063ce9d08201461046f578063dfc8ff1d1461048e578063e07baba6146104cc575f80fd5b8063910af6ed116100c2578063910af6ed146103f357806391f3f74b146104125780639b527cfa14610431578063a86f9d9e14610450575f80fd5b806379ba5097146103ae5780638456cb59146103c25780638da5cb5b146103d6575f80fd5b80633f4ba83a1161015257806352d1902d1161012d57806352d1902d146103475780635c975abb1461035b57806366ca2bc01461037b578063715018a61461039a575f80fd5b80633f4ba83a146102f35780634f1ef286146103075780634f90a6741461031a575f80fd5b80633659cfe61161018d5780633659cfe61461025f5780633ab76e9f1461027e5780633ced0e08146102b55780633eb6b8cf146102d4575f80fd5b80632d1fb389146101b357806332676bc6146101d4578063355bcc3d14610208575b5f80fd5b3480156101be575f80fd5b506101d26101cd3660046139e0565b61057a565b005b3480156101df575f80fd5b506101f36101ee366004613a13565b610620565b60405190151581526020015b60405180910390f35b348015610213575f80fd5b50610247610222366004613a53565b60fb60209081525f92835260408084209091529082529020546001600160401b031681565b6040516001600160401b0390911681526020016101ff565b34801561026a575f80fd5b506101d2610279366004613a6d565b610636565b348015610289575f80fd5b5060975461029d906001600160a01b031681565b6040516001600160a01b0390911681526020016101ff565b3480156102c0575f80fd5b506101f36102cf366004613a88565b61071c565b3480156102df575f80fd5b5061029d6102ee366004613ac9565b610763565b3480156102fe575f80fd5b506101d2610779565b6101d2610315366004613bd9565b610812565b348015610325575f80fd5b50610339610334366004613a88565b6108e1565b6040519081526020016101ff565b348015610352575f80fd5b50610339610927565b348015610366575f80fd5b506101f360c954610100900460ff1660021490565b348015610386575f80fd5b50610339610395366004613c25565b6109d8565b3480156103a5575f80fd5b506101d26109e4565b3480156103b9575f80fd5b506101d26109f5565b3480156103cd575f80fd5b506101d2610a6c565b3480156103e1575f80fd5b506033546001600160a01b031661029d565b3480156103fe575f80fd5b5061033961040d366004613c3c565b610aeb565b34801561041d575f80fd5b5061033961042c366004613cd0565b610bbb565b34801561043c575f80fd5b5061033961044b366004613d0c565b610c10565b34801561045b575f80fd5b5061029d61046a366004613d3c565b610c3c565b34801561047a575f80fd5b506101d2610489366004613c3c565b610c48565b348015610499575f80fd5b506104ad6104a8366004613d0c565b610c5e565b604080516001600160401b0390931683526020830191909152016101ff565b3480156104d7575f80fd5b5060c954610247906201000090046001600160401b031681565b3480156104fc575f80fd5b506065546001600160a01b031661029d565b348015610519575f80fd5b506101d2610528366004613d5d565b610cf2565b348015610538575f80fd5b506101d2610547366004613a6d565b610e01565b348015610557575f80fd5b506101f3610566366004613a6d565b60fc6020525f908152604090205460ff1681565b610582610e72565b6001600160a01b0382165f90815260fc602052604090205481151560ff9091161515036105c2576040516398f26f4560e01b815260040160405180910390fd5b6001600160a01b0382165f81815260fc6020908152604091829020805460ff191685151590811790915591519182527f4c0079b9bcd37cd5d29a13938effd97c881798cbc6bd52a3026a29d94b27d1bf910160405180910390a25050565b5f61062b8383610ecc565b151590505b92915050565b6001600160a01b037f000000000000000000000000906a45e1f0275cd106baca1909f5626c83f4dd8f1630036106875760405162461bcd60e51b815260040161067e90613d94565b60405180910390fd5b7f000000000000000000000000906a45e1f0275cd106baca1909f5626c83f4dd8f6001600160a01b03166106cf5f80516020614443833981519152546001600160a01b031690565b6001600160a01b0316146106f55760405162461bcd60e51b815260040161067e90613de0565b6106fe81610f2e565b604080515f8082526020820190925261071991839190610f36565b50565b5f8180820361073e57604051630426d36960e31b815260040160405180910390fd5b5f61074a878787610c10565b9050836107573083610ecc565b14979650505050505050565b5f61076f8484846110a0565b90505b9392505050565b61078d60c954610100900460ff1660021490565b6107aa5760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461010069ffffffffffffffffff001990911662010000426001600160401b031602171790556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9060200160405180910390a1610810335f611191565b565b6001600160a01b037f000000000000000000000000906a45e1f0275cd106baca1909f5626c83f4dd8f16300361085a5760405162461bcd60e51b815260040161067e90613d94565b7f000000000000000000000000906a45e1f0275cd106baca1909f5626c83f4dd8f6001600160a01b03166108a25f80516020614443833981519152546001600160a01b031690565b6001600160a01b0316146108c85760405162461bcd60e51b815260040161067e90613de0565b6108d182610f2e565b6108dd82826001610f36565b5050565b335f90815260fc602052604081205460ff1661091057604051631f67751f60e01b815260040160405180910390fd5b61091c858585856111aa565b90505b949350505050565b5f306001600160a01b037f000000000000000000000000906a45e1f0275cd106baca1909f5626c83f4dd8f16146109c65760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161067e565b505f8051602061444383398151915290565b5f61063033838461128c565b6109ec610e72565b6108105f611365565b60655433906001600160a01b03168114610a635760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161067e565b61071981611365565b610a8060c954610100900460ff1660021490565b15610a9e5760405163bae6e2a960e01b815260040160405180910390fd5b60c9805461ff0019166102001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200160405180910390a1610810336001611191565b5f610b0060c954610100900460ff1660021490565b15610b1e5760405163bae6e2a960e01b815260040160405180910390fd5b6002610b2861137e565b60ff1603610b495760405163dfc60d8560e01b815260040160405180910390fd5b610b5360026113bd565b5f610b6387878787876001611405565b90505f5b8151811015610ba657610b92828281518110610b8557610b85613e2c565b6020026020010151611870565b610b9c9084613e54565b9250600101610b67565b5050610bb260016113bd565b95945050505050565b5f6040518060400160405280600681526020016514d251d3905360d21b815250848484604051602001610bf19493929190613e89565b6040516020818303038152906040528051906020012090509392505050565b604080516001600160401b03808616602083015291810184905290821660608201525f90608001610bf1565b5f6107724684846110a0565b610c5685858585855f611405565b505050505050565b5f80826001600160401b03165f03610c9a576001600160401b038086165f90815260fb6020908152604080832088845290915290205416610c9c565b825b91506001600160401b03821615610cea575f610cb9868685610c10565b9050610cc53082610ecc565b91505f829003610ce85760405163738afa0560e01b815260040160405180910390fd5b505b935093915050565b5f54610100900460ff1615808015610d1057505f54600160ff909116105b80610d295750303b158015610d2957505f5460ff166001145b610d8c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161067e565b5f805460ff191660011790558015610dad575f805461ff0019166101001790555b610db783836119b4565b8015610dfc575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b610e09610e72565b606580546001600160a01b0383166001600160a01b03199091168117909155610e3a6033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6033546001600160a01b031633146108105760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161067e565b5f826001600160a01b038116610ef5576040516327e0ab1560e21b815260040160405180910390fd5b825f819003610f1757604051630426d36960e31b815260040160405180910390fd5b5f610f23468787610bbb565b549695505050505050565b610719610e72565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615610f6957610dfc83611a13565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610fc3575060408051601f3d908101601f19168201909252610fc091810190613ed9565b60015b6110265760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b606482015260840161067e565b5f8051602061444383398151915281146110945760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b606482015260840161067e565b50610dfc838383611aae565b6097545f906001600160a01b0316806110cc57604051638ed88b2560e01b815260040160405180910390fd5b604051630a3dc4f360e21b81526001600160401b0386166004820152602481018590526001600160a01b038216906328f713cc90604401602060405180830381865afa15801561111e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111429190613ef0565b91508215801561115957506001600160a01b038216155b1561118957604051632b0d65db60e01b81526001600160401b03861660048201526024810185905260440161067e565b509392505050565b60405163198bb9dd60e11b815260040160405180910390fd5b5f6111b6858585610c10565b90506111c330828461128c565b506001600160401b038581165f90815260fb602090815260408083208884529091529020548185169116101561122d576001600160401b038581165f90815260fb602090815260408083208884529091529020805467ffffffffffffffff19169185169190911790555b83836001600160401b0316866001600160401b03167fde247c825b1fb2d7ff9e0e771cba6f9e757ad04479fcdc135d88ae91fd50b37d858560405161127c929190918252602082015260400190565b60405180910390a4949350505050565b5f836001600160a01b0381166112b5576040516327e0ab1560e21b815260040160405180910390fd5b835f8190036112d757604051630426d36960e31b815260040160405180910390fd5b835f8190036112f957604051630426d36960e31b815260040160405180910390fd5b611304468888610bbb565b858155604080516001600160a01b038a16815260208101899052908101829052606081018790529094507f0ad2d108660a211f47bf7fb43a0443cae181624995d3d42b88ee6879d200e9739060800160405180910390a15050509392505050565b606580546001600160a01b031916905561071981611ad8565b5f61138846611b29565b156113b357507fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5c90565b5060c95460ff1690565b6113c646611b29565b156113f157807fa5054f728453d3dbe953bdc43e4d0cb97e662ea32d7958190f3dc2da31d9721b5d50565b60c9805460ff831660ff1990911617905550565b6060856001600160a01b03811661142f576040516327e0ab1560e21b815260040160405180910390fd5b855f81900361145157604051630426d36960e31b815260040160405180910390fd5b5f61145e86880188613fba565b905080515f0361148157604051630b92daef60e21b815260040160405180910390fd5b5f6001825161149091906140f8565b6001600160401b038111156114a7576114a7613b02565b6040519080825280602002602001820160405280156114d0578160200160208202803683370190505b50905085156115635781516001600160401b038111156114f2576114f2613b02565b60405190808252806020026020018201604052801561155f57816020015b61154c6040805160e0810182525f80825260208201819052918101829052606081018290526080810182905260a081018290529060c082015290565b8152602001906001900390816115105790505b5094505b8a8a8a805f611584856d7369676e616c5f7365727669636560901b83610763565b90506115be6040805160c0810182525f80825260208201819052918101829052906060820190815260200160608152602001606081525090565b5f805f805b8b51811015611824578b81815181106115de576115de613e2c565b602002602001015194505f5b8181101561164857855f01516001600160401b03168c828151811061161157611611613e2c565b60200260200101516001600160401b031603611640576040516348362c2760e11b815260040160405180910390fd5b6001016115ea565b506116578a8a8a8a898b611b56565b93508a518114915081156116975784516001600160401b0316461461168f576040516338bf822760e21b815260040160405180910390fd5b30955061171a565b845f01518b82815181106116ad576116ad613e2c565b6001600160401b03928316602091820292909201015285511615806116db575084516001600160401b031646145b156116f957604051637556223560e11b815260040160405180910390fd5b8451611717906d7369676e616c5f7365727669636560901b5f610763565b95505b608085015151151592508f156117ae576040518060e00160405280866040015181526020018581526020018b6001600160401b0316815260200186602001516001600160401b03168152602001841515815260200183151581526020018660600151600381111561178d5761178d61410b565b8152508f82815181106117a2576117a2613e2c565b60200260200101819052505b6118098a846117dd577fc6cdc4f2acf13acb10f410085b821f7b7113b303e9a4799023f928317396aaf56117ff565b7f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da1695b8760200151610c10565b604086015186519b50969950975094955087946001016115c3565b5085158061183b57506118373088610ecc565b8614155b156118595760405163738afa0560e01b815260040160405180910390fd5b505050505050505050505050509695505050505050565b5f8060038360c00151600381111561188a5761188a61410b565b14806118ab575060028360c0015160038111156118a9576118a961410b565b145b90508080156118bb575082608001515b80156118c957508260a00151155b1561190b576001915061190983604001517f73e6d340850343cc6f001515dc593377337c95a6ffe034fe1e844d4dab5da1698560600151865f01516111aa565b505b5f60038460c0015160038111156119245761192461410b565b1480611945575060018460c0015160038111156119435761194361410b565b145b9050808015611961575083608001518061196157508360a00151155b156119ad57611971600184613e54565b92506119ab84604001517fc6cdc4f2acf13acb10f410085b821f7b7113b303e9a4799023f928317396aaf5866060015187602001516111aa565b505b5050919050565b5f54610100900460ff166119da5760405162461bcd60e51b815260040161067e9061411f565b6001600160a01b038116611a01576040516375cabfef60e11b815260040160405180910390fd5b611a0a82611bf5565b6108dd81611c25565b6001600160a01b0381163b611a805760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161067e565b5f8051602061444383398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b611ab783611c95565b5f82511180611ac35750805b15610dfc57611ad28383611cd4565b50505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f6001821480611b3a575061426882145b80611b47575062aa36a782145b80610630575061063082611cf9565b5f856001600160a01b038116611b7f576040516327e0ab1560e21b815260040160405180910390fd5b855f819003611ba157604051630426d36960e31b815260040160405180910390fd5b855f819003611bc357604051630426d36960e31b815260040160405180910390fd5b611be7866040015186611bd78d8d8d610bbb565b8a8a608001518b60a00151611d10565b9a9950505050505050505050565b611c136001600160a01b03821615611c0d5781611365565b33611365565b5060c9805461ff001916610100179055565b5f54610100900460ff16611c4b5760405162461bcd60e51b815260040161067e9061411f565b6001600160401b03461115611c735760405163a12e8fa960e01b815260040160405180910390fd5b609780546001600160a01b0319166001600160a01b0392909216919091179055565b611c9e81611a13565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b6060610772838360405180606001604052806027815260200161446360279139611e1d565b5f617e2c8210158015610630575050617e90101590565b5f82515f14611db8576040516bffffffffffffffffffffffff19606088901b1660208201525f90611d5490603401604051602081830303815290604052858a611e91565b905080515f03611d7757604051630414cd5b60e31b815260040160405180910390fd5b5f611d8182611eaa565b9050611da681600281518110611d9957611d99613e2c565b6020026020010151611ebd565b611daf9061416a565b92505050611dbb565b50855b5f611df286604051602001611dd291815260200190565b60408051601f19818403018152919052611deb87611fdd565b8585611ff0565b905080611e1257604051638d9a4db360e01b815260040160405180910390fd5b509695505050505050565b60605f80856001600160a01b031685604051611e399190614190565b5f60405180830381855af49150503d805f8114611e71576040519150601f19603f3d011682016040523d82523d5f602084013e611e76565b606091505b5091509150611e8786838387612009565b9695505050505050565b60605f611e9d85612081565b9050610bb28185856120b3565b6060610630611eb883612920565b612971565b60605f805f611ecb85612b8e565b919450925090505f816001811115611ee557611ee561410b565b14611f585760405162461bcd60e51b815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067e565b611f628284613e54565b855114611fce5760405162461bcd60e51b815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527330b71034b73b30b634b2103932b6b0b4b73232b960611b606482015260840161067e565b610bb285602001518484613235565b6060610630611feb836132c5565b6133d8565b5f80611ffb86612081565b9050611e8781868686613430565b606083156120775782515f03612070576001600160a01b0385163b6120705760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161067e565b508161091f565b61091f8383613456565b6060818051906020012060405160200161209d91815260200190565b6040516020818303038152906040529050919050565b60605f8451116120fd5760405162461bcd60e51b81526020600482015260156024820152744d65726b6c65547269653a20656d707479206b657960581b604482015260640161067e565b5f61210784613480565b90505f61211386613563565b90505f8460405160200161212991815260200190565b60405160208183030381529060405290505f805b84518110156128c9575f85828151811061215957612159613e2c565b6020026020010151905084518311156121cb5760405162461bcd60e51b815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201526d0e8c2d840d6caf240d8cadccee8d60931b606482015260840161067e565b825f036122695780518051602091820120604051612218926121f292910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6122645760405162461bcd60e51b815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067e565b61235f565b8051516020116122ef5780518051602091820120604051612293926121f292910190815260200190565b6122645760405162461bcd60e51b815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e6044820152660c2d840d0c2e6d60cb1b606482015260840161067e565b80518451602080870191909120825191909201201461235f5760405162461bcd60e51b815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f646044820152650ca40d0c2e6d60d31b606482015260840161067e565b61236b60106001613e54565b81602001515103612503578451830361249d576123988160200151601081518110611d9957611d99613e2c565b96505f8751116124105760405162461bcd60e51b815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067e565b6001865161241e91906140f8565b82146124925760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067e565b505050505050610772565b5f8584815181106124b0576124b0613e2c565b602001015160f81c60f81b60f81c90505f82602001518260ff16815181106124da576124da613e2c565b602002602001015190506124ed816135c4565b95506124fa600186613e54565b945050506128c0565b600281602001515103612867575f61251a826135e8565b90505f815f8151811061252f5761252f613e2c565b016020015160f81c90505f6125456002836141bf565b6125509060026141e0565b90505f612560848360ff1661360b565b90505f61256d8a8961360b565b90505f61257a8383613640565b9050808351146125f25760405162461bcd60e51b815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067e565b60ff851660021480612607575060ff85166003145b156127a757808251146126825760405162461bcd60e51b815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067e565b61269c8760200151600181518110611d9957611d99613e2c565b9c505f8d51116127145760405162461bcd60e51b815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067e565b60018c5161272291906140f8565b88146127965760405162461bcd60e51b815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067e565b505050505050505050505050610772565b60ff851615806127ba575060ff85166001145b156127f9576127e687602001516001815181106127d9576127d9613e2c565b60200260200101516135c4565b99506127f2818a613e54565b985061285c565b60405162461bcd60e51b815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f64652077697468604482015271040c2dc40eadcd6dcdeeedc40e0e4caccd2f60731b606482015260840161067e565b5050505050506128c0565b60405162461bcd60e51b815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e706172736561604482015267626c65206e6f646560c01b606482015260840161067e565b5060010161213d565b5060405162461bcd60e51b815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c656044820152646d656e747360d81b606482015260840161067e565b604080518082019091525f80825260208201525f8251116129535760405162461bcd60e51b815260040161067e906141f9565b50604080518082019091528151815260209182019181019190915290565b60605f805f61297f85612b8e565b91945092509050600181600181111561299a5761299a61410b565b14612a0d5760405162461bcd60e51b815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067e565b8451612a198385613e54565b14612a815760405162461bcd60e51b815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e76616044820152713634b2103230ba30903932b6b0b4b73232b960711b606482015260840161067e565b604080516020808252610420820190925290816020015b604080518082019091525f8082526020820152815260200190600190039081612a985790505093505f835b8651811015612b82575f80612b076040518060400160405280858c5f0151612aeb91906140f8565b8152602001858c60200151612b009190613e54565b9052612b8e565b509150915060405180604001604052808383612b239190613e54565b8152602001848b60200151612b389190613e54565b815250888581518110612b4d57612b4d613e2c565b6020908102919091010152612b63600185613e54565b9350612b6f8183613e54565b612b799084613e54565b92505050612ac3565b50845250919392505050565b5f805f80845f015111612bb35760405162461bcd60e51b815260040161067e906141f9565b602084015180515f1a607f8111612bd5575f60015f945094509450505061322e565b60b78111612d2e575f612be96080836140f8565b905080875f015111612c675760405162461bcd60e51b815260206004820152604e60248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201526d2873686f727420737472696e672960901b608482015260a40161067e565b6001838101516001600160f81b0319169082141580612c945750600160ff1b6001600160f81b0319821610155b612d1c5760405162461bcd60e51b815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201526c73686f727420737472696e672960981b608482015260a40161067e565b506001955093505f925061322e915050565b60bf8111612f67575f612d4260b7836140f8565b905080875f015111612dc35760405162461bcd60e51b815260206004820152605160248201525f8051602061442383398151915260448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527067746820286c6f6e6720737472696e672960781b608482015260a40161067e565b60018301516001600160f81b0319165f819003612e485760405162461bcd60e51b815260206004820152604a60248201525f8051602061442383398151915260448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f6064820152696e6720737472696e672960b01b608482015260a40161067e565b600184015160088302610100031c60378111612eca5760405162461bcd60e51b815260206004820152604860248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201526720737472696e672960c01b608482015260a40161067e565b612ed48184613e54565b895111612f4b5760405162461bcd60e51b815260206004820152604c60248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201526b6c6f6e6720737472696e672960a01b608482015260a40161067e565b612f56836001613e54565b975095505f945061322e9350505050565b60f78111613006575f612f7b60c0836140f8565b905080875f015111612ff55760405162461bcd60e51b815260206004820152604a60248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e206c697374206c656e677468202873606482015269686f7274206c6973742960b01b608482015260a40161067e565b60019550935084925061322e915050565b5f61301260f7836140f8565b905080875f01511161308f5760405162461bcd60e51b815260206004820152604d60248201525f8051602061442383398151915260448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201526c6820286c6f6e67206c6973742960981b608482015260a40161067e565b60018301516001600160f81b0319165f8190036131125760405162461bcd60e51b815260206004820152604860248201525f8051602061442383398151915260448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f6064820152676e67206c6973742960c01b608482015260a40161067e565b600184015160088302610100031c603781116131925760405162461bcd60e51b815260206004820152604660248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e20353520627974657320286c6f6e67606482015265206c6973742960d01b608482015260a40161067e565b61319c8184613e54565b8951116132115760405162461bcd60e51b815260206004820152604a60248201525f8051602061442383398151915260448201527f742062652067726561746572207468616e20746f74616c206c656e67746820286064820152696c6f6e67206c6973742960b01b608482015260a40161067e565b61321c836001613e54565b975095506001945061322e9350505050565b9193909250565b6060816001600160401b0381111561324f5761324f613b02565b6040519080825280601f01601f191660200182016040528015613279576020820181803683370190505b5090508115610772575f61328d8486613e54565b9050602082015f5b848110156132ad578281015182820152602001613295565b848111156132bb575f858301525b5050509392505050565b60605f826040516020016132db91815260200190565b60405160208183030381529060405290505f5b60208110156133265781818151811061330957613309613e2c565b01602001516001600160f81b0319165f03613326576001016132ee565b6133318160206140f8565b6001600160401b0381111561334857613348613b02565b6040519080825280601f01601f191660200182016040528015613372576020820181803683370190505b5092505f5b83518110156119ab57828261338b81614269565b93508151811061339d5761339d613e2c565b602001015160f81c60f81b8482815181106133ba576133ba613e2c565b60200101906001600160f81b03191690815f1a905350600101613377565b60608151600114801561340457506080825f815181106133fa576133fa613e2c565b016020015160f81c105b1561340d575090565b613419825160806136c3565b8260405160200161209d929190614281565b919050565b5f61091c846134408786866120b3565b8051602091820120825192909101919091201490565b8151156134665781518083602001fd5b8060405162461bcd60e51b815260040161067e91906142af565b8051606090806001600160401b0381111561349d5761349d613b02565b6040519080825280602002602001820160405280156134e257816020015b60408051808201909152606080825260208201528152602001906001900390816134bb5790505b5091505f5b818110156119ad57604051806040016040528085838151811061350c5761350c613e2c565b6020026020010151815260200161353b86848151811061352e5761352e613e2c565b6020026020010151611eaa565b81525083828151811061355057613550613e2c565b60209081029190910101526001016134e7565b606080604051905082518060011b603f8101601f191683016040528083525060208401602083015f5b838110156135b9578060011b8201818401515f1a8060041c8253600f81166001830153505060010161358c565b509295945050505050565b60606020825f0151106135df576135da82611ebd565b610630565b61063082613868565b606061063061360683602001515f81518110611d9957611d99613e2c565b613563565b606082518210613629575060408051602081019091525f8152610630565b610772838384865161363b91906140f8565b61387c565b5f808251845110613652578251613655565b83515b90505b80821080156136ac575082828151811061367457613674613e2c565b602001015160f81c60f81b6001600160f81b03191684838151811061369b5761369b613e2c565b01602001516001600160f81b031916145b156136bc57816001019150613658565b5092915050565b6060603883101561372757604080516001808252818301909252906020820181803683370190505090506136f782846142e1565b60f81b815f8151811061370c5761370c613e2c565b60200101906001600160f81b03191690815f1a905350610630565b5f60015b61373581866142fa565b1561375b578161374481614269565b925061375490506101008261430d565b905061372b565b613766826001613e54565b6001600160401b0381111561377d5761377d613b02565b6040519080825280601f01601f1916602001820160405280156137a7576020820181803683370190505b5092506137b484836142e1565b6137bf9060376142e1565b60f81b835f815181106137d4576137d4613e2c565b60200101906001600160f81b03191690815f1a905350600190505b8181116138605761010061380382846140f8565b61380f90610100614404565b61381990876142fa565b613823919061440f565b60f81b83828151811061383857613838613e2c565b60200101906001600160f81b03191690815f1a9053508061385881614269565b9150506137ef565b505092915050565b606061063082602001515f845f0151613235565b60608182601f0110156138c25760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b604482015260640161067e565b8282840110156139055760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b604482015260640161067e565b8183018451101561394c5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b604482015260640161067e565b60608215801561396a5760405191505f8252602082016040526139b4565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156139a357805183526020928301920161398b565b5050858452601f01601f1916604052505b50949350505050565b6001600160a01b0381168114610719575f80fd5b8035801515811461342b575f80fd5b5f80604083850312156139f1575f80fd5b82356139fc816139bd565b9150613a0a602084016139d1565b90509250929050565b5f8060408385031215613a24575f80fd5b8235613a2f816139bd565b946020939093013593505050565b80356001600160401b038116811461342b575f80fd5b5f8060408385031215613a64575f80fd5b613a2f83613a3d565b5f60208284031215613a7d575f80fd5b8135610772816139bd565b5f805f8060808587031215613a9b575f80fd5b613aa485613a3d565b935060208501359250613ab960408601613a3d565b9396929550929360600135925050565b5f805f60608486031215613adb575f80fd5b613ae484613a3d565b925060208401359150613af9604085016139d1565b90509250925092565b634e487b7160e01b5f52604160045260245ffd5b60405160c081016001600160401b0381118282101715613b3857613b38613b02565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613b6657613b66613b02565b604052919050565b5f82601f830112613b7d575f80fd5b81356001600160401b03811115613b9657613b96613b02565b613ba9601f8201601f1916602001613b3e565b818152846020838601011115613bbd575f80fd5b816020850160208301375f918101602001919091529392505050565b5f8060408385031215613bea575f80fd5b8235613bf5816139bd565b915060208301356001600160401b03811115613c0f575f80fd5b613c1b85828601613b6e565b9150509250929050565b5f60208284031215613c35575f80fd5b5035919050565b5f805f805f60808688031215613c50575f80fd5b613c5986613a3d565b94506020860135613c69816139bd565b93506040860135925060608601356001600160401b0380821115613c8b575f80fd5b818801915088601f830112613c9e575f80fd5b813581811115613cac575f80fd5b896020828501011115613cbd575f80fd5b9699959850939650602001949392505050565b5f805f60608486031215613ce2575f80fd5b613ceb84613a3d565b92506020840135613cfb816139bd565b929592945050506040919091013590565b5f805f60608486031215613d1e575f80fd5b613d2784613a3d565b925060208401359150613af960408501613a3d565b5f8060408385031215613d4d575f80fd5b82359150613a0a602084016139d1565b5f8060408385031215613d6e575f80fd5b8235613d79816139bd565b91506020830135613d89816139bd565b809150509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082018082111561063057610630613e40565b5f5b83811015613e81578181015183820152602001613e69565b50505f910152565b5f8551613e9a818460208a01613e67565b60c09590951b6001600160c01b0319169190940190815260609290921b6bffffffffffffffffffffffff19166008830152601c820152603c0192915050565b5f60208284031215613ee9575f80fd5b5051919050565b5f60208284031215613f00575f80fd5b8151610772816139bd565b5f6001600160401b03821115613f2357613f23613b02565b5060051b60200190565b80356004811061342b575f80fd5b5f82601f830112613f4a575f80fd5b81356020613f5f613f5a83613f0b565b613b3e565b82815260059290921b84018101918181019086841115613f7d575f80fd5b8286015b84811015611e125780356001600160401b03811115613f9e575f80fd5b613fac8986838b0101613b6e565b845250918301918301613f81565b5f6020808385031215613fcb575f80fd5b82356001600160401b0380821115613fe1575f80fd5b818501915085601f830112613ff4575f80fd5b8135614002613f5a82613f0b565b81815260059190911b83018401908481019088831115614020575f80fd5b8585015b838110156140eb5780358581111561403a575f80fd5b860160c0818c03601f1901121561404f575f80fd5b614057613b16565b614062898301613a3d565b81526040614071818401613a3d565b8a830152606080840135828401526080915061408e828501613f2d565b9083015260a083810135898111156140a4575f80fd5b6140b28f8d83880101613f3b565b838501525060c08401359150888211156140ca575f80fd5b6140d88e8c84870101613f3b565b9083015250845250918601918601614024565b5098975050505050505050565b8181038181111561063057610630613e40565b634e487b7160e01b5f52602160045260245ffd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8051602080830151919081101561418a575f198160200360031b1b821691505b50919050565b5f82516141a1818460208701613e67565b9190910192915050565b634e487b7160e01b5f52601260045260245ffd5b5f60ff8316806141d1576141d16141ab565b8060ff84160691505092915050565b60ff828116828216039081111561063057610630613e40565b6020808252604a908201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60408201527f206d7573742062652067726561746572207468616e207a65726f20746f206265606082015269206465636f6461626c6560b01b608082015260a00190565b5f6001820161427a5761427a613e40565b5060010190565b5f8351614292818460208801613e67565b8351908301906142a6818360208801613e67565b01949350505050565b602081525f82518060208401526142cd816040850160208701613e67565b601f01601f19169190910160400192915050565b60ff818116838216019081111561063057610630613e40565b5f82614308576143086141ab565b500490565b808202811582820484141761063057610630613e40565b600181815b8085111561435e57815f190482111561434457614344613e40565b8085161561435157918102915b93841c9390800290614329565b509250929050565b5f8261437457506001610630565b8161438057505f610630565b816001811461439657600281146143a0576143bc565b6001915050610630565b60ff8411156143b1576143b1613e40565b50506001821b610630565b5060208310610133831016604e8410600b84101617156143df575081810a610630565b6143e98383614324565b805f19048211156143fc576143fc613e40565b029392505050565b5f6107728383614366565b5f8261441d5761441d6141ab565b50069056fe524c505265616465723a206c656e677468206f6620636f6e74656e74206d7573360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e29e895c02458d38c6bbe6e811894076308d652ef2fd2a6d5f602d8eb56a14f464736f6c63430008180033