Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
19139484 | 248 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
ExecutorFacet
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 9999999 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.8.20; // SPDX-License-Identifier: MIT import {Base} from "./Base.sol"; import {COMMIT_TIMESTAMP_NOT_OLDER, COMMIT_TIMESTAMP_APPROXIMATION_DELTA, EMPTY_STRING_KECCAK, L2_TO_L1_LOG_SERIALIZE_SIZE, MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES, PACKED_L2_BLOCK_TIMESTAMP_MASK, PUBLIC_INPUT_SHIFT} from "../Config.sol"; import {IExecutor, L2_LOG_ADDRESS_OFFSET, L2_LOG_KEY_OFFSET, L2_LOG_VALUE_OFFSET, SystemLogKey} from "../interfaces/IExecutor.sol"; import {PriorityQueue, PriorityOperation} from "../libraries/PriorityQueue.sol"; import {UncheckedMath} from "../../common/libraries/UncheckedMath.sol"; import {UnsafeBytes} from "../../common/libraries/UnsafeBytes.sol"; import {VerifierParams} from "../Storage.sol"; import {L2_BOOTLOADER_ADDRESS, L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR} from "../../common/L2ContractAddresses.sol"; // While formally the following import is not used, it is needed to inherit documentation from it import {IBase} from "../interfaces/IBase.sol"; /// @title zkSync Executor contract capable of processing events emitted in the zkSync protocol. /// @author Matter Labs /// @custom:security-contact [email protected] contract ExecutorFacet is Base, IExecutor { using UncheckedMath for uint256; using PriorityQueue for PriorityQueue.Queue; /// @inheritdoc IBase string public constant override getName = "ExecutorFacet"; /// @dev Process one batch commit using the previous batch StoredBatchInfo /// @dev returns new batch StoredBatchInfo /// @notice Does not change storage function _commitOneBatch( StoredBatchInfo memory _previousBatch, CommitBatchInfo calldata _newBatch, bytes32 _expectedSystemContractUpgradeTxHash ) internal view returns (StoredBatchInfo memory) { require(_newBatch.batchNumber == _previousBatch.batchNumber + 1, "f"); // only commit next batch // Check that batch contain all meta information for L2 logs. // Get the chained hash of priority transaction hashes. ( uint256 expectedNumberOfLayer1Txs, bytes32 expectedPriorityOperationsHash, bytes32 previousBatchHash, bytes32 stateDiffHash, bytes32 l2LogsTreeRoot, uint256 packedBatchAndL2BlockTimestamp ) = _processL2Logs(_newBatch, _expectedSystemContractUpgradeTxHash); require(_previousBatch.batchHash == previousBatchHash, "l"); // Check that the priority operation hash in the L2 logs is as expected require(expectedPriorityOperationsHash == _newBatch.priorityOperationsHash, "t"); // Check that the number of processed priority operations is as expected require(expectedNumberOfLayer1Txs == _newBatch.numberOfLayer1Txs, "ta"); // Check the timestamp of the new batch _verifyBatchTimestamp(packedBatchAndL2BlockTimestamp, _newBatch.timestamp, _previousBatch.timestamp); // Create batch commitment for the proof verification bytes32 commitment = _createBatchCommitment(_newBatch, stateDiffHash); return StoredBatchInfo( _newBatch.batchNumber, _newBatch.newStateRoot, _newBatch.indexRepeatedStorageChanges, _newBatch.numberOfLayer1Txs, _newBatch.priorityOperationsHash, l2LogsTreeRoot, _newBatch.timestamp, commitment ); } /// @notice checks that the timestamps of both the new batch and the new L2 block are correct. /// @param _packedBatchAndL2BlockTimestamp - packed batch and L2 block timestamp in a format of batchTimestamp * 2**128 + l2BatchTimestamp /// @param _expectedBatchTimestamp - expected batch timestamp /// @param _previousBatchTimestamp - the timestamp of the previous batch function _verifyBatchTimestamp( uint256 _packedBatchAndL2BlockTimestamp, uint256 _expectedBatchTimestamp, uint256 _previousBatchTimestamp ) internal view { // Check that the timestamp that came from the system context is expected uint256 batchTimestamp = _packedBatchAndL2BlockTimestamp >> 128; require(batchTimestamp == _expectedBatchTimestamp, "tb"); // While the fact that _previousBatchTimestamp < batchTimestamp is already checked on L2, // we double check it here for clarity require(_previousBatchTimestamp < batchTimestamp, "h3"); uint256 lastL2BlockTimestamp = _packedBatchAndL2BlockTimestamp & PACKED_L2_BLOCK_TIMESTAMP_MASK; // All L2 blocks have timestamps within the range of [batchTimestamp, lastL2BlockTimestamp]. // So here we need to only double check that: // - The timestamp of the batch is not too small. // - The timestamp of the last L2 block is not too big. require(block.timestamp - COMMIT_TIMESTAMP_NOT_OLDER <= batchTimestamp, "h1"); // New batch timestamp is too small require(lastL2BlockTimestamp <= block.timestamp + COMMIT_TIMESTAMP_APPROXIMATION_DELTA, "h2"); // The last L2 block timestamp is too big } /// @dev Check that L2 logs are proper and batch contain all meta information for them /// @dev The logs processed here should line up such that only one log for each key from the /// SystemLogKey enum in Constants.sol is processed per new batch. /// @dev Data returned from here will be used to form the batch commitment. function _processL2Logs( CommitBatchInfo calldata _newBatch, bytes32 _expectedSystemContractUpgradeTxHash ) internal pure returns ( uint256 numberOfLayer1Txs, bytes32 chainedPriorityTxsHash, bytes32 previousBatchHash, bytes32 stateDiffHash, bytes32 l2LogsTreeRoot, uint256 packedBatchAndL2BlockTimestamp ) { // Copy L2 to L1 logs into memory. bytes memory emittedL2Logs = _newBatch.systemLogs; // Used as bitmap to set/check log processing happens exactly once. // See SystemLogKey enum in Constants.sol for ordering. uint256 processedLogs; bytes32 providedL2ToL1PubdataHash = keccak256(_newBatch.totalL2ToL1Pubdata); // linear traversal of the logs for (uint256 i = 0; i < emittedL2Logs.length; i = i.uncheckedAdd(L2_TO_L1_LOG_SERIALIZE_SIZE)) { // Extract the values to be compared to/used such as the log sender, key, and value (address logSender, ) = UnsafeBytes.readAddress(emittedL2Logs, i + L2_LOG_ADDRESS_OFFSET); (uint256 logKey, ) = UnsafeBytes.readUint256(emittedL2Logs, i + L2_LOG_KEY_OFFSET); (bytes32 logValue, ) = UnsafeBytes.readBytes32(emittedL2Logs, i + L2_LOG_VALUE_OFFSET); // Ensure that the log hasn't been processed already require(!_checkBit(processedLogs, uint8(logKey)), "kp"); processedLogs = _setBit(processedLogs, uint8(logKey)); // Need to check that each log was sent by the correct address. if (logKey == uint256(SystemLogKey.L2_TO_L1_LOGS_TREE_ROOT_KEY)) { require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lm"); l2LogsTreeRoot = logValue; } else if (logKey == uint256(SystemLogKey.TOTAL_L2_TO_L1_PUBDATA_KEY)) { require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "ln"); require(providedL2ToL1PubdataHash == logValue, "wp"); } else if (logKey == uint256(SystemLogKey.STATE_DIFF_HASH_KEY)) { require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lb"); stateDiffHash = logValue; } else if (logKey == uint256(SystemLogKey.PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY)) { require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sc"); packedBatchAndL2BlockTimestamp = uint256(logValue); } else if (logKey == uint256(SystemLogKey.PREV_BATCH_HASH_KEY)) { require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sv"); previousBatchHash = logValue; } else if (logKey == uint256(SystemLogKey.CHAINED_PRIORITY_TXN_HASH_KEY)) { require(logSender == L2_BOOTLOADER_ADDRESS, "bl"); chainedPriorityTxsHash = logValue; } else if (logKey == uint256(SystemLogKey.NUMBER_OF_LAYER_1_TXS_KEY)) { require(logSender == L2_BOOTLOADER_ADDRESS, "bk"); numberOfLayer1Txs = uint256(logValue); } else if (logKey == uint256(SystemLogKey.EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY)) { require(logSender == L2_BOOTLOADER_ADDRESS, "bu"); require(_expectedSystemContractUpgradeTxHash == logValue, "ut"); } else { revert("ul"); } } // We only require 7 logs to be checked, the 8th is if we are expecting a protocol upgrade // Without the protocol upgrade we expect 7 logs: 2^7 - 1 = 127 // With the protocol upgrade we expect 8 logs: 2^8 - 1 = 255 if (_expectedSystemContractUpgradeTxHash == bytes32(0)) { require(processedLogs == 127, "b7"); } else { require(processedLogs == 255, "b8"); } } /// @inheritdoc IExecutor function commitBatches( StoredBatchInfo memory _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData ) external nonReentrant onlyValidator { // Check that we commit batches after last committed batch require(s.storedBatchHashes[s.totalBatchesCommitted] == _hashStoredBatchInfo(_lastCommittedBatchData), "i"); // incorrect previous batch data require(_newBatchesData.length > 0, "No batches to commit"); bytes32 systemContractsUpgradeTxHash = s.l2SystemContractsUpgradeTxHash; // Upgrades are rarely done so we optimize a case with no active system contracts upgrade. if (systemContractsUpgradeTxHash == bytes32(0) || s.l2SystemContractsUpgradeBatchNumber != 0) { _commitBatchesWithoutSystemContractsUpgrade(_lastCommittedBatchData, _newBatchesData); } else { _commitBatchesWithSystemContractsUpgrade( _lastCommittedBatchData, _newBatchesData, systemContractsUpgradeTxHash ); } s.totalBatchesCommitted = s.totalBatchesCommitted + _newBatchesData.length; } /// @dev Commits new batches without any system contracts upgrade. /// @param _lastCommittedBatchData The data of the last committed batch. /// @param _newBatchesData An array of batch data that needs to be committed. function _commitBatchesWithoutSystemContractsUpgrade( StoredBatchInfo memory _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData ) internal { for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) { _lastCommittedBatchData = _commitOneBatch(_lastCommittedBatchData, _newBatchesData[i], bytes32(0)); s.storedBatchHashes[_lastCommittedBatchData.batchNumber] = _hashStoredBatchInfo(_lastCommittedBatchData); emit BlockCommit( _lastCommittedBatchData.batchNumber, _lastCommittedBatchData.batchHash, _lastCommittedBatchData.commitment ); } } /// @dev Commits new batches with a system contracts upgrade transaction. /// @param _lastCommittedBatchData The data of the last committed batch. /// @param _newBatchesData An array of batch data that needs to be committed. /// @param _systemContractUpgradeTxHash The transaction hash of the system contract upgrade. function _commitBatchesWithSystemContractsUpgrade( StoredBatchInfo memory _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData, bytes32 _systemContractUpgradeTxHash ) internal { // The system contract upgrade is designed to be executed atomically with the new bootloader, a default account, // ZKP verifier, and other system parameters. Hence, we ensure that the upgrade transaction is // carried out within the first batch committed after the upgrade. // While the logic of the contract ensures that the s.l2SystemContractsUpgradeBatchNumber is 0 when this function is called, // this check is added just in case. Since it is a hot read, it does not encure noticeable gas cost. require(s.l2SystemContractsUpgradeBatchNumber == 0, "ik"); // Save the batch number where the upgrade transaction was executed. s.l2SystemContractsUpgradeBatchNumber = _newBatchesData[0].batchNumber; for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) { // The upgrade transaction must only be included in the first batch. bytes32 expectedUpgradeTxHash = i == 0 ? _systemContractUpgradeTxHash : bytes32(0); _lastCommittedBatchData = _commitOneBatch( _lastCommittedBatchData, _newBatchesData[i], expectedUpgradeTxHash ); s.storedBatchHashes[_lastCommittedBatchData.batchNumber] = _hashStoredBatchInfo(_lastCommittedBatchData); emit BlockCommit( _lastCommittedBatchData.batchNumber, _lastCommittedBatchData.batchHash, _lastCommittedBatchData.commitment ); } } /// @dev Pops the priority operations from the priority queue and returns a rolling hash of operations function _collectOperationsFromPriorityQueue(uint256 _nPriorityOps) internal returns (bytes32 concatHash) { concatHash = EMPTY_STRING_KECCAK; for (uint256 i = 0; i < _nPriorityOps; i = i.uncheckedInc()) { PriorityOperation memory priorityOp = s.priorityQueue.popFront(); concatHash = keccak256(abi.encode(concatHash, priorityOp.canonicalTxHash)); } } /// @dev Executes one batch /// @dev 1. Processes all pending operations (Complete priority requests) /// @dev 2. Finalizes batch on Ethereum /// @dev _executedBatchIdx is an index in the array of the batches that we want to execute together function _executeOneBatch(StoredBatchInfo memory _storedBatch, uint256 _executedBatchIdx) internal { uint256 currentBatchNumber = _storedBatch.batchNumber; require(currentBatchNumber == s.totalBatchesExecuted + _executedBatchIdx + 1, "k"); // Execute batches in order require( _hashStoredBatchInfo(_storedBatch) == s.storedBatchHashes[currentBatchNumber], "exe10" // executing batch should be committed ); bytes32 priorityOperationsHash = _collectOperationsFromPriorityQueue(_storedBatch.numberOfLayer1Txs); require(priorityOperationsHash == _storedBatch.priorityOperationsHash, "x"); // priority operations hash does not match to expected // Save root hash of L2 -> L1 logs tree s.l2LogsRootHashes[currentBatchNumber] = _storedBatch.l2LogsTreeRoot; } /// @inheritdoc IExecutor function executeBatches(StoredBatchInfo[] calldata _batchesData) external nonReentrant onlyValidator { uint256 nBatches = _batchesData.length; for (uint256 i = 0; i < nBatches; i = i.uncheckedInc()) { _executeOneBatch(_batchesData[i], i); emit BlockExecution(_batchesData[i].batchNumber, _batchesData[i].batchHash, _batchesData[i].commitment); } uint256 newTotalBatchesExecuted = s.totalBatchesExecuted + nBatches; s.totalBatchesExecuted = newTotalBatchesExecuted; require(newTotalBatchesExecuted <= s.totalBatchesVerified, "n"); // Can't execute batches more than committed and proven currently. uint256 batchWhenUpgradeHappened = s.l2SystemContractsUpgradeBatchNumber; if (batchWhenUpgradeHappened != 0 && batchWhenUpgradeHappened <= newTotalBatchesExecuted) { delete s.l2SystemContractsUpgradeTxHash; delete s.l2SystemContractsUpgradeBatchNumber; } } /// @inheritdoc IExecutor function proveBatches( StoredBatchInfo calldata _prevBatch, StoredBatchInfo[] calldata _committedBatches, ProofInput calldata _proof ) external nonReentrant onlyValidator { // Save the variables into the stack to save gas on reading them later uint256 currentTotalBatchesVerified = s.totalBatchesVerified; uint256 committedBatchesLength = _committedBatches.length; // Save the variable from the storage to memory to save gas VerifierParams memory verifierParams = s.verifierParams; // Initialize the array, that will be used as public input to the ZKP uint256[] memory proofPublicInput = new uint256[](committedBatchesLength); // Check that the batch passed by the validator is indeed the first unverified batch require(_hashStoredBatchInfo(_prevBatch) == s.storedBatchHashes[currentTotalBatchesVerified], "t1"); bytes32 prevBatchCommitment = _prevBatch.commitment; for (uint256 i = 0; i < committedBatchesLength; i = i.uncheckedInc()) { currentTotalBatchesVerified = currentTotalBatchesVerified.uncheckedInc(); require( _hashStoredBatchInfo(_committedBatches[i]) == s.storedBatchHashes[currentTotalBatchesVerified], "o1" ); bytes32 currentBatchCommitment = _committedBatches[i].commitment; proofPublicInput[i] = _getBatchProofPublicInput( prevBatchCommitment, currentBatchCommitment, verifierParams ); prevBatchCommitment = currentBatchCommitment; } require(currentTotalBatchesVerified <= s.totalBatchesCommitted, "q"); _verifyProof(proofPublicInput, _proof); emit BlocksVerification(s.totalBatchesVerified, currentTotalBatchesVerified); s.totalBatchesVerified = currentTotalBatchesVerified; } function _verifyProof(uint256[] memory proofPublicInput, ProofInput calldata _proof) internal view { // We can only process 1 batch proof at a time. require(proofPublicInput.length == 1, "t4"); bool successVerifyProof = s.verifier.verify( proofPublicInput, _proof.serializedProof, _proof.recursiveAggregationInput ); require(successVerifyProof, "p"); // Proof verification fail } /// @dev Gets zk proof public input function _getBatchProofPublicInput( bytes32 _prevBatchCommitment, bytes32 _currentBatchCommitment, VerifierParams memory _verifierParams ) internal pure returns (uint256) { return uint256( keccak256( abi.encodePacked( _prevBatchCommitment, _currentBatchCommitment, _verifierParams.recursionNodeLevelVkHash, _verifierParams.recursionLeafLevelVkHash ) ) ) >> PUBLIC_INPUT_SHIFT; } /// @inheritdoc IExecutor function revertBatches(uint256 _newLastBatch) external nonReentrant onlyValidator { require(s.totalBatchesCommitted > _newLastBatch, "v1"); // The last committed batch is less than new last batch require(_newLastBatch >= s.totalBatchesExecuted, "v2"); // Already executed batches cannot be reverted if (_newLastBatch < s.totalBatchesVerified) { s.totalBatchesVerified = _newLastBatch; } s.totalBatchesCommitted = _newLastBatch; // Reset the batch number of the executed system contracts upgrade transaction if the batch // where the system contracts upgrade was committed is among the reverted batches. if (s.l2SystemContractsUpgradeBatchNumber > _newLastBatch) { delete s.l2SystemContractsUpgradeBatchNumber; } emit BlocksRevert(s.totalBatchesCommitted, s.totalBatchesVerified, s.totalBatchesExecuted); } /// @dev Creates batch commitment from its data function _createBatchCommitment( CommitBatchInfo calldata _newBatchData, bytes32 _stateDiffHash ) internal view returns (bytes32) { bytes32 passThroughDataHash = keccak256(_batchPassThroughData(_newBatchData)); bytes32 metadataHash = keccak256(_batchMetaParameters()); bytes32 auxiliaryOutputHash = keccak256(_batchAuxiliaryOutput(_newBatchData, _stateDiffHash)); return keccak256(abi.encode(passThroughDataHash, metadataHash, auxiliaryOutputHash)); } function _batchPassThroughData(CommitBatchInfo calldata _batch) internal pure returns (bytes memory) { return abi.encodePacked( _batch.indexRepeatedStorageChanges, _batch.newStateRoot, uint64(0), // index repeated storage changes in zkPorter bytes32(0) // zkPorter batch hash ); } function _batchMetaParameters() internal view returns (bytes memory) { return abi.encodePacked(s.zkPorterIsAvailable, s.l2BootloaderBytecodeHash, s.l2DefaultAccountBytecodeHash); } function _batchAuxiliaryOutput( CommitBatchInfo calldata _batch, bytes32 _stateDiffHash ) internal pure returns (bytes memory) { require(_batch.systemLogs.length <= MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES, "pu"); bytes32 l2ToL1LogsHash = keccak256(_batch.systemLogs); return abi.encode( l2ToL1LogsHash, _stateDiffHash, _batch.bootloaderHeapInitialContentsHash, _batch.eventsQueueStateHash, // The following will be commitments to the EIP4844 blobs once they are supported on L1. bytes32(0), bytes32(0), bytes32(0), bytes32(0) ); } /// @notice Returns the keccak hash of the ABI-encoded StoredBatchInfo function _hashStoredBatchInfo(StoredBatchInfo memory _storedBatchInfo) internal pure returns (bytes32) { return keccak256(abi.encode(_storedBatchInfo)); } /// @notice Returns true if the bit at index {_index} is 1 function _checkBit(uint256 _bitMap, uint8 _index) internal pure returns (bool) { return (_bitMap & (1 << _index)) > 0; } /// @notice Sets the given bit in {_num} at index {_index} to 1. function _setBit(uint256 _bitMap, uint8 _index) internal pure returns (uint256) { return _bitMap | (1 << _index); } }
pragma solidity 0.8.20; // SPDX-License-Identifier: MIT /// @dev The address of the L2 deployer system contract. address constant L2_DEPLOYER_SYSTEM_CONTRACT_ADDR = address(0x8006); /// @dev The special reserved L2 address. It is located in the system contracts space but doesn't have deployed /// bytecode. /// @dev The L2 deployer system contract allows changing bytecodes on any address if the `msg.sender` is this address. /// @dev So, whenever the governor wants to redeploy system contracts, it just initiates the L1 upgrade call deployer /// system contract /// via the L1 -> L2 transaction with `sender == L2_FORCE_DEPLOYER_ADDR`. For more details see the /// `diamond-initializers` contracts. address constant L2_FORCE_DEPLOYER_ADDR = address(0x8007); /// @dev The address of the special smart contract that can send arbitrary length message as an L2 log address constant L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR = address(0x8008); /// @dev The formal address of the initial program of the system: the bootloader address constant L2_BOOTLOADER_ADDRESS = address(0x8001); /// @dev The address of the eth token system contract address constant L2_ETH_TOKEN_SYSTEM_CONTRACT_ADDR = address(0x800a); /// @dev The address of the known code storage system contract address constant L2_KNOWN_CODE_STORAGE_SYSTEM_CONTRACT_ADDR = address(0x8004); /// @dev The address of the context system contract address constant L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR = address(0x800b);
pragma solidity 0.8.20; // SPDX-License-Identifier: MIT /** * @author Matter Labs * @custom:security-contact [email protected] * @notice The library for unchecked math. */ library UncheckedMath { function uncheckedInc(uint256 _number) internal pure returns (uint256) { unchecked { return _number + 1; } } function uncheckedAdd(uint256 _lhs, uint256 _rhs) internal pure returns (uint256) { unchecked { return _lhs + _rhs; } } }
pragma solidity 0.8.20; // SPDX-License-Identifier: MIT /** * @author Matter Labs * @custom:security-contact [email protected] * @dev The library provides a set of functions that help read data from an "abi.encodePacked" byte array. * @dev Each of the functions accepts the `bytes memory` and the offset where data should be read and returns a value of a certain type. * * @dev WARNING! * 1) Functions don't check the length of the bytes array, so it can go out of bounds. * The user of the library must check for bytes length before using any functions from the library! * * 2) Read variables are not cleaned up - https://docs.soliditylang.org/en/v0.8.16/internals/variable_cleanup.html. * Using data in inline assembly can lead to unexpected behavior! */ library UnsafeBytes { function readUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32 result, uint256 offset) { assembly { offset := add(_start, 4) result := mload(add(_bytes, offset)) } } function readAddress(bytes memory _bytes, uint256 _start) internal pure returns (address result, uint256 offset) { assembly { offset := add(_start, 20) result := mload(add(_bytes, offset)) } } function readUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256 result, uint256 offset) { assembly { offset := add(_start, 32) result := mload(add(_bytes, offset)) } } function readBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32 result, uint256 offset) { assembly { offset := add(_start, 32) result := mload(add(_bytes, offset)) } } }
pragma solidity 0.8.20; // SPDX-License-Identifier: MIT /** * @custom:security-contact [email protected] * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. * * _Since v2.5.0:_ this module is now much more gas efficient, given net gas * metering changes introduced in the Istanbul hardfork. */ abstract contract ReentrancyGuard { /// @dev Address of lock flag variable. /// @dev Flag is placed at random memory location to not interfere with Storage contract. // keccak256("ReentrancyGuard") - 1; uint256 private constant LOCK_FLAG_ADDRESS = 0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4; // solhint-disable-next-line max-line-length // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/566a774222707e424896c0c390a84dc3c13bdcb2/contracts/security/ReentrancyGuard.sol // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; modifier reentrancyGuardInitializer() { _initializeReentrancyGuard(); _; } function _initializeReentrancyGuard() private { uint256 lockSlotOldValue; // Storing an initial non-zero value makes deployment a bit more // expensive but in exchange every call to nonReentrant // will be cheaper. assembly { lockSlotOldValue := sload(LOCK_FLAG_ADDRESS) sstore(LOCK_FLAG_ADDRESS, _NOT_ENTERED) } // Check that storage slot for reentrancy guard is empty to rule out possibility of slot conflict require(lockSlotOldValue == 0, "1B"); } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { uint256 _status; assembly { _status := sload(LOCK_FLAG_ADDRESS) } // On the first call to nonReentrant, _notEntered will be true require(_status == _NOT_ENTERED, "r1"); // Any calls to nonReentrant after this point will fail assembly { sstore(LOCK_FLAG_ADDRESS, _ENTERED) } _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) assembly { sstore(LOCK_FLAG_ADDRESS, _NOT_ENTERED) } } }
pragma solidity 0.8.20; // SPDX-License-Identifier: MIT /// @dev `keccak256("")` bytes32 constant EMPTY_STRING_KECCAK = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; /// @dev Bytes in raw L2 log /// @dev Equal to the bytes size of the tuple - (uint8 ShardId, bool isService, uint16 txNumberInBatch, address sender, /// bytes32 key, bytes32 value) uint256 constant L2_TO_L1_LOG_SERIALIZE_SIZE = 88; /// @dev The maximum length of the bytes array with L2 -> L1 logs uint256 constant MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES = 4 + L2_TO_L1_LOG_SERIALIZE_SIZE * 512; /// @dev The value of default leaf hash for L2 -> L1 logs Merkle tree /// @dev An incomplete fixed-size tree is filled with this value to be a full binary tree /// @dev Actually equal to the `keccak256(new bytes(L2_TO_L1_LOG_SERIALIZE_SIZE))` bytes32 constant L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH = 0x72abee45b59e344af8a6e520241c4744aff26ed411f4c4b00f8af09adada43ba; // TODO: change constant to the real root hash of empty Merkle tree (SMA-184) bytes32 constant DEFAULT_L2_LOGS_TREE_ROOT_HASH = bytes32(0); /// @dev Denotes the type of the zkSync transaction that came from L1. uint256 constant PRIORITY_OPERATION_L2_TX_TYPE = 255; /// @dev Denotes the type of the zkSync transaction that is used for system upgrades. uint256 constant SYSTEM_UPGRADE_L2_TX_TYPE = 254; /// @dev The maximal allowed difference between protocol versions in an upgrade. The 100 gap is needed /// in case a protocol version has been tested on testnet, but then not launched on mainnet, e.g. /// due to a bug found. uint256 constant MAX_ALLOWED_PROTOCOL_VERSION_DELTA = 100; /// @dev The amount of time in seconds the validator has to process the priority transaction /// NOTE: The constant is set to zero for the Alpha release period uint256 constant PRIORITY_EXPIRATION = 0 days; /// @dev Timestamp - seconds since unix epoch. uint256 constant COMMIT_TIMESTAMP_NOT_OLDER = 3 days; /// @dev Maximum available error between real commit batch timestamp and analog used in the verifier (in seconds) /// @dev Must be used cause miner's `block.timestamp` value can differ on some small value (as we know - 12 seconds) uint256 constant COMMIT_TIMESTAMP_APPROXIMATION_DELTA = 1 hours; /// @dev Shift to apply to verify public input before verifying. uint256 constant PUBLIC_INPUT_SHIFT = 32; /// @dev The maximum number of L2 gas that a user can request for an L2 transaction uint256 constant MAX_GAS_PER_TRANSACTION = 80000000; /// @dev Even though the price for 1 byte of pubdata is 16 L1 gas, we have a slightly increased /// value. uint256 constant L1_GAS_PER_PUBDATA_BYTE = 17; /// @dev The intrinsic cost of the L1->l2 transaction in computational L2 gas uint256 constant L1_TX_INTRINSIC_L2_GAS = 167157; /// @dev The intrinsic cost of the L1->l2 transaction in pubdata uint256 constant L1_TX_INTRINSIC_PUBDATA = 88; /// @dev The minimal base price for L1 transaction uint256 constant L1_TX_MIN_L2_GAS_BASE = 173484; /// @dev The number of L2 gas the transaction starts costing more with each 544 bytes of encoding uint256 constant L1_TX_DELTA_544_ENCODING_BYTES = 1656; /// @dev The number of L2 gas an L1->L2 transaction gains with each new factory dependency uint256 constant L1_TX_DELTA_FACTORY_DEPS_L2_GAS = 2473; /// @dev The number of L2 gas an L1->L2 transaction gains with each new factory dependency uint256 constant L1_TX_DELTA_FACTORY_DEPS_PUBDATA = 64; /// @dev The number of pubdata an L1->L2 transaction requires with each new factory dependency uint256 constant MAX_NEW_FACTORY_DEPS = 32; /// @dev The L2 gasPricePerPubdata required to be used in bridges. uint256 constant REQUIRED_L2_GAS_PRICE_PER_PUBDATA = 800; /// @dev The mask which should be applied to the packed batch and L2 block timestamp in order /// to obtain the L2 block timestamp. Applying this mask is equivalent to calculating modulo 2**128 uint256 constant PACKED_L2_BLOCK_TIMESTAMP_MASK = 0xffffffffffffffffffffffffffffffff; /// @dev The overhead for a transaction slot in L2 gas. /// It is roughly equal to 80kk/MAX_TRANSACTIONS_IN_BATCH, i.e. how many gas would an L1->L2 transaction /// need to pay to compensate for the batch being closed. /// @dev It is expected that the L1 contracts will enforce that the L2 gas price will be high enough to compensate /// the operator in case the batch is closed because of tx slots filling up. uint256 constant TX_SLOT_OVERHEAD_L2_GAS = 10000; /// @dev The overhead for each byte of the bootloader memory that the encoding of the transaction. /// It is roughly equal to 80kk/BOOTLOADER_MEMORY_FOR_TXS, i.e. how many gas would an L1->L2 transaction /// need to pay to compensate for the batch being closed. /// @dev It is expected that the L1 contracts will enforce that the L2 gas price will be high enough to compensate /// the operator in case the batch is closed because of the memory for transactions being filled up. uint256 constant MEMORY_OVERHEAD_GAS = 10;
pragma solidity 0.8.20; // SPDX-License-Identifier: MIT import {AppStorage} from "../Storage.sol"; import {ReentrancyGuard} from "../../common/ReentrancyGuard.sol"; /// @title Base contract containing functions accessible to the other facets. /// @author Matter Labs /// @custom:security-contact [email protected] contract Base is ReentrancyGuard { AppStorage internal s; /// @notice Checks that the message sender is an active governor modifier onlyGovernor() { require(msg.sender == s.governor, "1g"); // only by governor _; } /// @notice Checks that the message sender is an active governor or admin modifier onlyGovernorOrAdmin() { require(msg.sender == s.governor || msg.sender == s.admin, "1k"); _; } /// @notice Checks if validator is active modifier onlyValidator() { require(s.validators[msg.sender], "1h"); // validator is not active _; } }
pragma solidity 0.8.20; // SPDX-License-Identifier: UNLICENSED /// @title The interface of the zkSync contract, responsible for the main zkSync logic. /// @author Matter Labs /// @custom:security-contact [email protected] interface IBase { /// @return Returns facet name. function getName() external view returns (string memory); }
pragma solidity 0.8.20; // SPDX-License-Identifier: MIT import {IBase} from "./IBase.sol"; /// @dev Enum used by L2 System Contracts to differentiate logs. enum SystemLogKey { L2_TO_L1_LOGS_TREE_ROOT_KEY, TOTAL_L2_TO_L1_PUBDATA_KEY, STATE_DIFF_HASH_KEY, PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY, PREV_BATCH_HASH_KEY, CHAINED_PRIORITY_TXN_HASH_KEY, NUMBER_OF_LAYER_1_TXS_KEY, EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY } /// @dev Offset used to pull Address From Log. Equal to 4 (bytes for isService) uint256 constant L2_LOG_ADDRESS_OFFSET = 4; /// @dev Offset used to pull Key From Log. Equal to 4 (bytes for isService) + 20 (bytes for address) uint256 constant L2_LOG_KEY_OFFSET = 24; /// @dev Offset used to pull Value From Log. Equal to 4 (bytes for isService) + 20 (bytes for address) + 32 (bytes for key) uint256 constant L2_LOG_VALUE_OFFSET = 56; /// @title The interface of the zkSync Executor contract capable of processing events emitted in the zkSync protocol. /// @author Matter Labs /// @custom:security-contact [email protected] interface IExecutor is IBase { /// @notice Rollup batch stored data /// @param batchNumber Rollup batch number /// @param batchHash Hash of L2 batch /// @param indexRepeatedStorageChanges The serial number of the shortcut index that's used as a unique identifier for storage keys that were used twice or more /// @param numberOfLayer1Txs Number of priority operations to be processed /// @param priorityOperationsHash Hash of all priority operations from this batch /// @param l2LogsTreeRoot Root hash of tree that contains L2 -> L1 messages from this batch /// @param timestamp Rollup batch timestamp, have the same format as Ethereum batch constant /// @param commitment Verified input for the zkSync circuit struct StoredBatchInfo { uint64 batchNumber; bytes32 batchHash; uint64 indexRepeatedStorageChanges; uint256 numberOfLayer1Txs; bytes32 priorityOperationsHash; bytes32 l2LogsTreeRoot; uint256 timestamp; bytes32 commitment; } /// @notice Data needed to commit new batch /// @param batchNumber Number of the committed batch /// @param timestamp Unix timestamp denoting the start of the batch execution /// @param indexRepeatedStorageChanges The serial number of the shortcut index that's used as a unique identifier for storage keys that were used twice or more /// @param newStateRoot The state root of the full state tree /// @param numberOfLayer1Txs Number of priority operations to be processed /// @param priorityOperationsHash Hash of all priority operations from this batch /// @param bootloaderHeapInitialContentsHash Hash of the initial contents of the bootloader heap. In practice it serves as the commitment to the transactions in the batch. /// @param eventsQueueStateHash Hash of the events queue state. In practice it serves as the commitment to the events in the batch. /// @param systemLogs concatenation of all L2 -> L1 system logs in the batch /// @param totalL2ToL1Pubdata Total pubdata committed to as part of bootloader run. Contents are: l2Tol1Logs <> l2Tol1Messages <> publishedBytecodes <> stateDiffs struct CommitBatchInfo { uint64 batchNumber; uint64 timestamp; uint64 indexRepeatedStorageChanges; bytes32 newStateRoot; uint256 numberOfLayer1Txs; bytes32 priorityOperationsHash; bytes32 bootloaderHeapInitialContentsHash; bytes32 eventsQueueStateHash; bytes systemLogs; bytes totalL2ToL1Pubdata; } /// @notice Recursive proof input data (individual commitments are constructed onchain) struct ProofInput { uint256[] recursiveAggregationInput; uint256[] serializedProof; } /// @notice Function called by the operator to commit new batches. It is responsible for: /// - Verifying the correctness of their timestamps. /// - Processing their L2->L1 logs. /// - Storing batch commitments. /// @param _lastCommittedBatchData Stored data of the last committed batch. /// @param _newBatchesData Data of the new batches to be committed. function commitBatches( StoredBatchInfo calldata _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData ) external; /// @notice Batches commitment verification. /// @dev Only verifies batch commitments without any other processing. /// @param _prevBatch Stored data of the last committed batch. /// @param _committedBatches Stored data of the committed batches. /// @param _proof The zero knowledge proof. function proveBatches( StoredBatchInfo calldata _prevBatch, StoredBatchInfo[] calldata _committedBatches, ProofInput calldata _proof ) external; /// @notice The function called by the operator to finalize (execute) batches. It is responsible for: /// - Processing all pending operations (commpleting priority requests). /// - Finalizing this batch (i.e. allowing to withdraw funds from the system) /// @param _batchesData Data of the batches to be executed. function executeBatches(StoredBatchInfo[] calldata _batchesData) external; /// @notice Reverts unexecuted batches /// @param _newLastBatch batch number after which batches should be reverted /// NOTE: Doesn't delete the stored data about batches, but only decreases /// counters that are responsible for the number of batches function revertBatches(uint256 _newLastBatch) external; /// @notice Event emitted when a batch is committed /// @dev It has the name "BlockCommit" and not "BatchCommit" due to backward compatibility considerations event BlockCommit(uint256 indexed batchNumber, bytes32 indexed batchHash, bytes32 indexed commitment); /// @notice Event emitted when batches are verified /// @dev It has the name "BlocksVerification" and not "BatchesVerification" due to backward compatibility considerations event BlocksVerification(uint256 indexed previousLastVerifiedBatch, uint256 indexed currentLastVerifiedBatch); /// @notice Event emitted when a batch is executed /// @dev It has the name "BlockExecution" and not "BatchExecution" due to backward compatibility considerations event BlockExecution(uint256 indexed batchNumber, bytes32 indexed batchHash, bytes32 indexed commitment); /// @notice Event emitted when batches are reverted /// @dev It has the name "BlocksRevert" and not "BatchesRevert" due to backward compatibility considerations event BlocksRevert(uint256 totalBatchesCommitted, uint256 totalBatchesVerified, uint256 totalBatchesExecuted); }
pragma solidity 0.8.20; // SPDX-License-Identifier: MIT /// @title The interface of the Verifier contract, responsible for the zero knowledge proof verification. /// @author Matter Labs /// @custom:security-contact [email protected] interface IVerifier { /// @dev Verifies a zk-SNARK proof. /// @return A boolean value indicating whether the zk-SNARK proof is valid. /// Note: The function may revert execution instead of returning false in some cases. function verify( uint256[] calldata _publicInputs, uint256[] calldata _proof, uint256[] calldata _recursiveAggregationInput ) external view returns (bool); /// @notice Calculates a keccak256 hash of the runtime loaded verification keys. /// @return vkHash The keccak256 hash of the loaded verification keys. function verificationKeyHash() external pure returns (bytes32); }
pragma solidity 0.8.20; // SPDX-License-Identifier: MIT /// @notice The structure that contains meta information of the L2 transaction that was requested from L1 /// @dev The weird size of fields was selected specifically to minimize the structure storage size /// @param canonicalTxHash Hashed L2 transaction data that is needed to process it /// @param expirationTimestamp Expiration timestamp for this request (must be satisfied before) /// @param layer2Tip Additional payment to the validator as an incentive to perform the operation struct PriorityOperation { bytes32 canonicalTxHash; uint64 expirationTimestamp; uint192 layer2Tip; } /// @author Matter Labs /// @custom:security-contact [email protected] /// @dev The library provides the API to interact with the priority queue container /// @dev Order of processing operations from queue - FIFO (Fist in - first out) library PriorityQueue { using PriorityQueue for Queue; /// @notice Container that stores priority operations /// @param data The inner mapping that saves priority operation by its index /// @param head The pointer to the first unprocessed priority operation, equal to the tail if the queue is empty /// @param tail The pointer to the free slot struct Queue { mapping(uint256 priorityOpId => PriorityOperation priorityOp) data; uint256 tail; uint256 head; } /// @notice Returns zero if and only if no operations were processed from the queue /// @return Index of the oldest priority operation that wasn't processed yet function getFirstUnprocessedPriorityTx(Queue storage _queue) internal view returns (uint256) { return _queue.head; } /// @return The total number of priority operations that were added to the priority queue, including all processed ones function getTotalPriorityTxs(Queue storage _queue) internal view returns (uint256) { return _queue.tail; } /// @return The total number of unprocessed priority operations in a priority queue function getSize(Queue storage _queue) internal view returns (uint256) { return uint256(_queue.tail - _queue.head); } /// @return Whether the priority queue contains no operations function isEmpty(Queue storage _queue) internal view returns (bool) { return _queue.tail == _queue.head; } /// @notice Add the priority operation to the end of the priority queue function pushBack(Queue storage _queue, PriorityOperation memory _operation) internal { // Save value into the stack to avoid double reading from the storage uint256 tail = _queue.tail; _queue.data[tail] = _operation; _queue.tail = tail + 1; } /// @return The first unprocessed priority operation from the queue function front(Queue storage _queue) internal view returns (PriorityOperation memory) { require(!_queue.isEmpty(), "D"); // priority queue is empty return _queue.data[_queue.head]; } /// @notice Remove the first unprocessed priority operation from the queue /// @return priorityOperation that was popped from the priority queue function popFront(Queue storage _queue) internal returns (PriorityOperation memory priorityOperation) { require(!_queue.isEmpty(), "s"); // priority queue is empty // Save value into the stack to avoid double reading from the storage uint256 head = _queue.head; priorityOperation = _queue.data[head]; delete _queue.data[head]; _queue.head = head + 1; } }
pragma solidity 0.8.20; // SPDX-License-Identifier: MIT import {IVerifier} from "./../zksync/interfaces/IVerifier.sol"; import {PriorityQueue} from "./libraries/PriorityQueue.sol"; /// @notice Indicates whether an upgrade is initiated and if yes what type /// @param None Upgrade is NOT initiated /// @param Transparent Fully transparent upgrade is initiated, upgrade data is publicly known /// @param Shadow Shadow upgrade is initiated, upgrade data is hidden enum UpgradeState { None, Transparent, Shadow } /// @dev Logically separated part of the storage structure, which is responsible for everything related to proxy /// upgrades and diamond cuts /// @param proposedUpgradeHash The hash of the current upgrade proposal, zero if there is no active proposal /// @param state Indicates whether an upgrade is initiated and if yes what type /// @param securityCouncil Address which has the permission to approve instant upgrades (expected to be a Gnosis /// multisig) /// @param approvedBySecurityCouncil Indicates whether the security council has approved the upgrade /// @param proposedUpgradeTimestamp The timestamp when the upgrade was proposed, zero if there are no active proposals /// @param currentProposalId The serial number of proposed upgrades, increments when proposing a new one struct UpgradeStorage { bytes32 proposedUpgradeHash; UpgradeState state; address securityCouncil; bool approvedBySecurityCouncil; uint40 proposedUpgradeTimestamp; uint40 currentProposalId; } /// @dev The log passed from L2 /// @param l2ShardId The shard identifier, 0 - rollup, 1 - porter. All other values are not used but are reserved for /// the future /// @param isService A boolean flag that is part of the log along with `key`, `value`, and `sender` address. /// This field is required formally but does not have any special meaning. /// @param txNumberInBatch The L2 transaction number in the batch, in which the log was sent /// @param sender The L2 address which sent the log /// @param key The 32 bytes of information that was sent in the log /// @param value The 32 bytes of information that was sent in the log // Both `key` and `value` are arbitrary 32-bytes selected by the log sender struct L2Log { uint8 l2ShardId; bool isService; uint16 txNumberInBatch; address sender; bytes32 key; bytes32 value; } /// @dev An arbitrary length message passed from L2 /// @notice Under the hood it is `L2Log` sent from the special system L2 contract /// @param txNumberInBatch The L2 transaction number in the batch, in which the message was sent /// @param sender The address of the L2 account from which the message was passed /// @param data An arbitrary length message struct L2Message { uint16 txNumberInBatch; address sender; bytes data; } /// @notice Part of the configuration parameters of ZKP circuits struct VerifierParams { bytes32 recursionNodeLevelVkHash; bytes32 recursionLeafLevelVkHash; bytes32 recursionCircuitsSetVksHash; } /// @notice The struct that describes whether users will be charged for pubdata for L1->L2 transactions. /// @param Rollup The users are charged for pubdata & it is priced based on the gas price on Ethereum. /// @param Validium The pubdata is considered free with regard to the L1 gas price. enum PubdataPricingMode { Rollup, Validium } /// @notice The fee params for L1->L2 transactions for the network. /// @param pubdataPricingMode How the users will charged for pubdata in L1->L2 transactions. /// @param batchOverheadL1Gas The amount of L1 gas required to process the batch (except for the calldata). /// @param maxPubdataPerBatch The maximal number of pubdata that can be emitted per batch. /// @param priorityTxMaxPubdata The maximal amount of pubdata a priority transaction is allowed to publish. /// It can be slightly less than maxPubdataPerBatch in order to have some margin for the bootloader execution. /// @param minimalL2GasPrice The minimal L2 gas price to be used by L1->L2 transactions. It should represent /// the price that a single unit of compute costs. struct FeeParams { PubdataPricingMode pubdataPricingMode; uint32 batchOverheadL1Gas; uint32 maxPubdataPerBatch; uint32 maxL2GasPerBatch; uint32 priorityTxMaxPubdata; uint64 minimalL2GasPrice; } /// @dev storing all storage variables for zkSync facets /// NOTE: It is used in a proxy, so it is possible to add new variables to the end /// but NOT to modify already existing variables or change their order. /// NOTE: variables prefixed with '__DEPRECATED_' are deprecated and shouldn't be used. /// Their presence is maintained for compatibility and to prevent storage collision. struct AppStorage { /// @dev Storage of variables needed for deprecated diamond cut facet uint256[7] __DEPRECATED_diamondCutStorage; /// @notice Address which will exercise critical changes to the Diamond Proxy (upgrades, freezing & unfreezing) address governor; /// @notice Address that the governor proposed as one that will replace it address pendingGovernor; /// @notice List of permitted validators mapping(address validatorAddress => bool isValidator) validators; /// @dev Verifier contract. Used to verify aggregated proof for batches IVerifier verifier; /// @notice Total number of executed batches i.e. batches[totalBatchesExecuted] points at the latest executed batch /// (batch 0 is genesis) uint256 totalBatchesExecuted; /// @notice Total number of proved batches i.e. batches[totalBatchesProved] points at the latest proved batch uint256 totalBatchesVerified; /// @notice Total number of committed batches i.e. batches[totalBatchesCommitted] points at the latest committed /// batch uint256 totalBatchesCommitted; /// @dev Stored hashed StoredBatch for batch number mapping(uint256 batchNumber => bytes32 batchHash) storedBatchHashes; /// @dev Stored root hashes of L2 -> L1 logs mapping(uint256 batchNumber => bytes32 l2LogsRootHash) l2LogsRootHashes; /// @dev Container that stores transactions requested from L1 PriorityQueue.Queue priorityQueue; /// @dev The smart contract that manages the list with permission to call contract functions address __DEPRECATED_allowList; /// @notice Part of the configuration parameters of ZKP circuits. Used as an input for the verifier smart contract VerifierParams verifierParams; /// @notice Bytecode hash of bootloader program. /// @dev Used as an input to zkp-circuit. bytes32 l2BootloaderBytecodeHash; /// @notice Bytecode hash of default account (bytecode for EOA). /// @dev Used as an input to zkp-circuit. bytes32 l2DefaultAccountBytecodeHash; /// @dev Indicates that the porter may be touched on L2 transactions. /// @dev Used as an input to zkp-circuit. bool zkPorterIsAvailable; /// @dev The maximum number of the L2 gas that a user can request for L1 -> L2 transactions /// @dev This is the maximum number of L2 gas that is available for the "body" of the transaction, i.e. /// without overhead for proving the batch. uint256 priorityTxMaxGasLimit; /// @dev Storage of variables needed for upgrade facet UpgradeStorage __DEPRECATED_upgrades; /// @dev A mapping L2 batch number => message number => flag. /// @dev The L2 -> L1 log is sent for every withdrawal, so this mapping is serving as /// a flag to indicate that the message was already processed. /// @dev Used to indicate that eth withdrawal was already processed mapping(uint256 l2BatchNumber => mapping(uint256 l2ToL1MessageNumber => bool isFinalized)) isEthWithdrawalFinalized; /// @dev The most recent withdrawal time and amount reset uint256 __DEPRECATED_lastWithdrawalLimitReset; /// @dev The accumulated withdrawn amount during the withdrawal limit window uint256 __DEPRECATED_withdrawnAmountInWindow; /// @dev A mapping user address => the total deposited amount by the user mapping(address => uint256) __DEPRECATED_totalDepositedAmountPerUser; /// @dev Stores the protocol version. Note, that the protocol version may not only encompass changes to the /// smart contracts, but also to the node behavior. uint256 protocolVersion; /// @dev Hash of the system contract upgrade transaction. If 0, then no upgrade transaction needs to be done. bytes32 l2SystemContractsUpgradeTxHash; /// @dev Batch number where the upgrade transaction has happened. If 0, then no upgrade transaction has happened /// yet. uint256 l2SystemContractsUpgradeBatchNumber; /// @dev Address which will exercise non-critical changes to the Diamond Proxy (changing validator set & unfreezing) address admin; /// @notice Address that the governor or admin proposed as one that will replace admin role address pendingAdmin; /// @dev Fee params used to derive gasPrice for the L1->L2 transactions. For L2 transactions, /// the bootloader gives enough freedom to the operator. FeeParams feeParams; }
{ "optimizer": { "enabled": true, "runs": 9999999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"batchNumber","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"batchHash","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"commitment","type":"bytes32"}],"name":"BlockCommit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"batchNumber","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"batchHash","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"commitment","type":"bytes32"}],"name":"BlockExecution","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalBatchesCommitted","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalBatchesVerified","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalBatchesExecuted","type":"uint256"}],"name":"BlocksRevert","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"previousLastVerifiedBatch","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currentLastVerifiedBatch","type":"uint256"}],"name":"BlocksVerification","type":"event"},{"inputs":[{"components":[{"internalType":"uint64","name":"batchNumber","type":"uint64"},{"internalType":"bytes32","name":"batchHash","type":"bytes32"},{"internalType":"uint64","name":"indexRepeatedStorageChanges","type":"uint64"},{"internalType":"uint256","name":"numberOfLayer1Txs","type":"uint256"},{"internalType":"bytes32","name":"priorityOperationsHash","type":"bytes32"},{"internalType":"bytes32","name":"l2LogsTreeRoot","type":"bytes32"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes32","name":"commitment","type":"bytes32"}],"internalType":"struct IExecutor.StoredBatchInfo","name":"_lastCommittedBatchData","type":"tuple"},{"components":[{"internalType":"uint64","name":"batchNumber","type":"uint64"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"uint64","name":"indexRepeatedStorageChanges","type":"uint64"},{"internalType":"bytes32","name":"newStateRoot","type":"bytes32"},{"internalType":"uint256","name":"numberOfLayer1Txs","type":"uint256"},{"internalType":"bytes32","name":"priorityOperationsHash","type":"bytes32"},{"internalType":"bytes32","name":"bootloaderHeapInitialContentsHash","type":"bytes32"},{"internalType":"bytes32","name":"eventsQueueStateHash","type":"bytes32"},{"internalType":"bytes","name":"systemLogs","type":"bytes"},{"internalType":"bytes","name":"totalL2ToL1Pubdata","type":"bytes"}],"internalType":"struct IExecutor.CommitBatchInfo[]","name":"_newBatchesData","type":"tuple[]"}],"name":"commitBatches","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"batchNumber","type":"uint64"},{"internalType":"bytes32","name":"batchHash","type":"bytes32"},{"internalType":"uint64","name":"indexRepeatedStorageChanges","type":"uint64"},{"internalType":"uint256","name":"numberOfLayer1Txs","type":"uint256"},{"internalType":"bytes32","name":"priorityOperationsHash","type":"bytes32"},{"internalType":"bytes32","name":"l2LogsTreeRoot","type":"bytes32"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes32","name":"commitment","type":"bytes32"}],"internalType":"struct IExecutor.StoredBatchInfo[]","name":"_batchesData","type":"tuple[]"}],"name":"executeBatches","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"batchNumber","type":"uint64"},{"internalType":"bytes32","name":"batchHash","type":"bytes32"},{"internalType":"uint64","name":"indexRepeatedStorageChanges","type":"uint64"},{"internalType":"uint256","name":"numberOfLayer1Txs","type":"uint256"},{"internalType":"bytes32","name":"priorityOperationsHash","type":"bytes32"},{"internalType":"bytes32","name":"l2LogsTreeRoot","type":"bytes32"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes32","name":"commitment","type":"bytes32"}],"internalType":"struct IExecutor.StoredBatchInfo","name":"_prevBatch","type":"tuple"},{"components":[{"internalType":"uint64","name":"batchNumber","type":"uint64"},{"internalType":"bytes32","name":"batchHash","type":"bytes32"},{"internalType":"uint64","name":"indexRepeatedStorageChanges","type":"uint64"},{"internalType":"uint256","name":"numberOfLayer1Txs","type":"uint256"},{"internalType":"bytes32","name":"priorityOperationsHash","type":"bytes32"},{"internalType":"bytes32","name":"l2LogsTreeRoot","type":"bytes32"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes32","name":"commitment","type":"bytes32"}],"internalType":"struct IExecutor.StoredBatchInfo[]","name":"_committedBatches","type":"tuple[]"},{"components":[{"internalType":"uint256[]","name":"recursiveAggregationInput","type":"uint256[]"},{"internalType":"uint256[]","name":"serializedProof","type":"uint256[]"}],"internalType":"struct IExecutor.ProofInput","name":"_proof","type":"tuple"}],"name":"proveBatches","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newLastBatch","type":"uint256"}],"name":"revertBatches","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50612a60806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80637f61885c116100505780637f61885c146100d357806397c09d34146100e6578063c3d93e7c146100f957600080fd5b806317d7de7c1461006c578063701f58c5146100be575b600080fd5b6100a86040518060400160405280600d81526020017f4578656375746f7246616365740000000000000000000000000000000000000081525081565b6040516100b591906123f9565b60405180910390f35b6100d16100cc366004612576565b61010c565b005b6100d16100e136600461264b565b610391565b6100d16100f43660046126d5565b610802565b6100d16101073660046126ee565b610a96565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4546001811461019d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f723100000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60027f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4553360009081526009602052604090205460ff1661023a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f31680000000000000000000000000000000000000000000000000000000000006044820152606401610194565b61024384610d72565b600d546000908152600e6020526040902054146102bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f69000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b81610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f206261746368657320746f20636f6d6d69740000000000000000000000006044820152606401610194565b602254801580610334575060235415155b1561034957610344858585610e04565b610355565b61035585858584610eb0565b600d5461036390849061275f565b600d55505060017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf455505050565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4546001811461041d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f72310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60027f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4553360009081526009602052604090205460ff166104ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f31680000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600c54604080516060810182526014548152601554602082015260165491810191909152849060008267ffffffffffffffff8111156104fb576104fb612465565b604051908082528060200260200182016040528015610524578160200160208202803683370190505b506000858152600e602052604090205490915061054e610549368c90038c018c612772565b610d72565b146105b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f74310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60e089013560005b8481101561072757600186016000818152600e60205260409020549096506106078b8b848181106105f0576105f0612796565b905061010002018036038101906105499190612772565b1461066e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6f310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60008a8a8381811061068257610682612796565b9050610100020160e0013590506107008382878051602080830151604080518084018890529081018690526060810193909352608083015260009160a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120901c949350505050565b84838151811061071257610712612796565b602090810291909101015291506001016105bd565b50600d54851115610794576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f71000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b61079e828861101a565b600c546040518691907f22c9005dd88c18b552a1cd7e8b3b937fcde9ca69213c1f658f54d572e4877a8190600090a3505050600c91909155505060017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45550505050565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4546001811461088e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f72310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60027f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4553360009081526009602052604090205460ff1661092b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f31680000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600d548210610996576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f76310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600b54821015610a02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f76320000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600c54821015610a1257600c8290555b600d829055602354821015610a275760006023555b600d54600c54600b5460408051938452602084019290925282820152517f8bd4b15ea7d1bc41ea9abc3fc487ccb89cd678a00786584714faa9d751c84ee59181900360600190a160017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4555050565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45460018114610b22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f72310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60027f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4553360009081526009602052604090205460ff16610bbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f31680000000000000000000000000000000000000000000000000000000000006044820152606401610194565b8160005b81811015610c9e57610bfd858583818110610be057610be0612796565b90506101000201803603810190610bf79190612772565b8261118d565b848482818110610c0f57610c0f612796565b9050610100020160e00135858583818110610c2c57610c2c612796565b9050610100020160200135868684818110610c4957610c49612796565b610c609260206101009092020190810191506127c5565b67ffffffffffffffff167f2402307311a4d6604e4e7b4c8a15a7e1213edb39c16a31efa70afb06030d316560405160405180910390a4600101610bc3565b50600b54600090610cb090839061275f565b600b819055600c54909150811115610d24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f6e000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b6023548015801590610d365750818111155b15610d4657600060228190556023555b50505060017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf455505050565b600081604051602001610de7919060006101008201905067ffffffffffffffff8084511683526020840151602084015280604085015116604084015250606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015292915050565b604051602081830303815290604052805190602001209050919050565b60005b81811015610eaa57610e3e84848484818110610e2557610e25612796565b9050602002810190610e3791906127e0565b6000611337565b9350610e4984610d72565b845167ffffffffffffffff9081166000908152600e602090815260408083209490945560e088015190880151885194519194909316917f8f2916b2f2d78cc5890ead36c06c0f6d5d112c7e103589947e8e2f0d6eddb76391a4600101610e07565b50505050565b60235415610f1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f696b0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b82826000818110610f2d57610f2d612796565b9050602002810190610f3f91906127e0565b610f4d9060208101906127c5565b67ffffffffffffffff1660235560005b828110156110135760008115610f74576000610f76565b825b9050610fa686868685818110610f8e57610f8e612796565b9050602002810190610fa091906127e0565b83611337565b9550610fb186610d72565b865167ffffffffffffffff9081166000908152600e602090815260408083209490945560e08a0151908a01518a5194519194909316917f8f2916b2f2d78cc5890ead36c06c0f6d5d112c7e103589947e8e2f0d6eddb76391a450600101610f5d565b5050505050565b8151600114611085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f74340000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600a5460009073ffffffffffffffffffffffffffffffffffffffff166387d9d023846110b4602086018661281e565b6110be878061281e565b6040518663ffffffff1660e01b81526004016110de9594939291906128d1565b602060405180830381865afa1580156110fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111f9190612941565b905080611188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f70000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b505050565b8151600b5467ffffffffffffffff909116906111aa90839061275f565b6111b590600161275f565b811461121d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f6b000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b6000818152600e602052604090205461123584610d72565b1461129c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f65786531300000000000000000000000000000000000000000000000000000006044820152606401610194565b60006112ab846060015161164a565b90508360800151811461131a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f78000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b5060a0909201516000928352600f60205260409092209190915550565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091528351611385906001612963565b67ffffffffffffffff1661139c60208501856127c5565b67ffffffffffffffff161461140d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f66000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60008060008060008061142089896116d2565b955095509550955095509550838a6020015114611499576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f6c000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b8860a001358514611506576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f74000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b88608001358614611573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f74610000000000000000000000000000000000000000000000000000000000006044820152606401610194565b61159b8161158760408c0160208d016127c5565b67ffffffffffffffff168c60c00151611ecb565b60006115a78a856120a0565b604080516101008101909152909150806115c460208d018d6127c5565b67ffffffffffffffff16815260608c01803560208301526040918201916115ed91908e016127c5565b67ffffffffffffffff1681526020018b6080013581526020018b60a0013581526020018481526020018b602001602081019061162991906127c5565b67ffffffffffffffff168152602001919091529a9950505050505050505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060005b828110156116cc5760006116826010612156565b80516040519192506116a291859190602001918252602082015260400190565b604051602081830303815290604052805190602001209250506116c58160010190565b905061166e565b50919050565b60008080808080806116e86101008a018a61298b565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093945083925061172f9150506101208c018c61298b565b60405161173d9291906129f0565b6040518091039020905060005b8351811015611ddf5760006117728561176460048561275f565b601491810182015192910190565b50905060006117948661178660188661275f565b602091810182015192910190565b50905060006117a88761178660388761275f565b509050600160ff83161b86161561181b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6b700000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600160ff83161b86179550816118b45773ffffffffffffffffffffffffffffffffffffffff8316618008146118ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6c6d0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b809850611dd4565b600182036119ab5773ffffffffffffffffffffffffffffffffffffffff83166180081461193d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6c6e0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b8085146119a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f77700000000000000000000000000000000000000000000000000000000000006044820152606401610194565b611dd4565b60028203611a3c5773ffffffffffffffffffffffffffffffffffffffff831661800814611a34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6c620000000000000000000000000000000000000000000000000000000000006044820152606401610194565b809950611dd4565b60038203611acd5773ffffffffffffffffffffffffffffffffffffffff831661800b14611ac5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f73630000000000000000000000000000000000000000000000000000000000006044820152606401610194565b965086611dd4565b60048203611b5e5773ffffffffffffffffffffffffffffffffffffffff831661800b14611b56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f73760000000000000000000000000000000000000000000000000000000000006044820152606401610194565b809a50611dd4565b60058203611bef5773ffffffffffffffffffffffffffffffffffffffff831661800114611be7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f626c0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b809b50611dd4565b60068203611c805773ffffffffffffffffffffffffffffffffffffffff831661800114611c78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f626b0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b9b508b611dd4565b60078203611d725773ffffffffffffffffffffffffffffffffffffffff831661800114611d09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f62750000000000000000000000000000000000000000000000000000000000006044820152606401610194565b808e146119a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f75740000000000000000000000000000000000000000000000000000000000006044820152606401610194565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756c0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b50505060580161174a565b5089611e545781607f14611e4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f62370000000000000000000000000000000000000000000000000000000000006044820152606401610194565b611ebe565b8160ff14611ebe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f62380000000000000000000000000000000000000000000000000000000000006044820152606401610194565b5050509295509295509295565b608083901c828114611f39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f74620000000000000000000000000000000000000000000000000000000000006044820152606401610194565b808210611fa2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f68330000000000000000000000000000000000000000000000000000000000006044820152606401610194565b6fffffffffffffffffffffffffffffffff841681611fc36203f48042612a00565b111561202b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f68310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b612037610e104261275f565b811115611013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f68320000000000000000000000000000000000000000000000000000000000006044820152606401610194565b6000806120ac84612272565b80519060200120905060006120fc60195460175460185460405160ff909316151560f81b602084015260218301919091526041820152606090606101604051602081830303815290604052905090565b805190602001209050600061211186866122e4565b80516020918201206040805192830186905282018490526060820181905291506080016040516020818303038152906040528051906020012093505050505b92915050565b604080516060810182526000808252602082018190529181019190915260028201546001830154036121e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f73000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b5060028101546000818152602083815260408083208151606081018352815481526001808301805467ffffffffffffffff81168488015268010000000000000000900477ffffffffffffffffffffffffffffffffffffffffffffffff1694830194909452868652938790529084905592905590919061226490829061275f565b836002018190555050919050565b6060612283828201604084016127c5565b60405160c09190911b7fffffffffffffffff0000000000000000000000000000000000000000000000001660208201526060830135602882015260006048820181905260508201526070016040516020818303038152906040529050919050565b60606122f36058610200612a13565b6122fe90600461275f565b61230c61010085018561298b565b90501115612376576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f70750000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600061238661010085018561298b565b6040516123949291906129f0565b604080519182900382206020830181905290820185905260c086810135606084015260e0808801356080850152600060a08501819052918401829052830181905261010083015291506101200160405160208183030381529060405291505092915050565b600060208083528351808285015260005b818110156124265785810183015185820160400152820161240a565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b803567ffffffffffffffff811681146124ac57600080fd5b919050565b60006101008083850312156124c557600080fd5b6040519081019067ffffffffffffffff8211818310171561250f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8160405280925061251f84612494565b81526020840135602082015261253760408501612494565b6040820152606084013560608201526080840135608082015260a084013560a082015260c084013560c082015260e084013560e0820152505092915050565b6000806000610120848603121561258c57600080fd5b61259685856124b1565b925061010084013567ffffffffffffffff808211156125b457600080fd5b818601915086601f8301126125c857600080fd5b8135818111156125d757600080fd5b8760208260051b85010111156125ec57600080fd5b6020830194508093505050509250925092565b60008083601f84011261261157600080fd5b50813567ffffffffffffffff81111561262957600080fd5b6020830191508360208260081b850101111561264457600080fd5b9250929050565b60008060008084860361014081121561266357600080fd5b6101008082121561267357600080fd5b869550850135905067ffffffffffffffff8082111561269157600080fd5b61269d888389016125ff565b90955093506101208701359150808211156126b757600080fd5b508501604081880312156126ca57600080fd5b939692955090935050565b6000602082840312156126e757600080fd5b5035919050565b6000806020838503121561270157600080fd5b823567ffffffffffffffff81111561271857600080fd5b612724858286016125ff565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561215057612150612730565b6000610100828403121561278557600080fd5b61278f83836124b1565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156127d757600080fd5b61278f82612494565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261281457600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261285357600080fd5b83018035915067ffffffffffffffff82111561286e57600080fd5b6020019150600581901b360382131561264457600080fd5b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156128b857600080fd5b8260051b80836020870137939093016020019392505050565b606080825286519082018190526000906020906080840190828a01845b8281101561290a578151845292840192908401906001016128ee565b5050508381038285015261291f81888a612886565b9150508281036040840152612935818587612886565b98975050505050505050565b60006020828403121561295357600080fd5b8151801515811461278f57600080fd5b67ffffffffffffffff81811683821601908082111561298457612984612730565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126129c057600080fd5b83018035915067ffffffffffffffff8211156129db57600080fd5b60200191503681900382131561264457600080fd5b8183823760009101908152919050565b8181038181111561215057612150612730565b80820281158282048414176121505761215061273056fea264697066735822122052e435574f5b20feaad10370befd61664ed3bb620c0829dc6bad601d6a72b9fb64736f6c63430008140033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100675760003560e01c80637f61885c116100505780637f61885c146100d357806397c09d34146100e6578063c3d93e7c146100f957600080fd5b806317d7de7c1461006c578063701f58c5146100be575b600080fd5b6100a86040518060400160405280600d81526020017f4578656375746f7246616365740000000000000000000000000000000000000081525081565b6040516100b591906123f9565b60405180910390f35b6100d16100cc366004612576565b61010c565b005b6100d16100e136600461264b565b610391565b6100d16100f43660046126d5565b610802565b6100d16101073660046126ee565b610a96565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4546001811461019d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f723100000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60027f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4553360009081526009602052604090205460ff1661023a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f31680000000000000000000000000000000000000000000000000000000000006044820152606401610194565b61024384610d72565b600d546000908152600e6020526040902054146102bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f69000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b81610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f206261746368657320746f20636f6d6d69740000000000000000000000006044820152606401610194565b602254801580610334575060235415155b1561034957610344858585610e04565b610355565b61035585858584610eb0565b600d5461036390849061275f565b600d55505060017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf455505050565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4546001811461041d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f72310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60027f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4553360009081526009602052604090205460ff166104ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f31680000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600c54604080516060810182526014548152601554602082015260165491810191909152849060008267ffffffffffffffff8111156104fb576104fb612465565b604051908082528060200260200182016040528015610524578160200160208202803683370190505b506000858152600e602052604090205490915061054e610549368c90038c018c612772565b610d72565b146105b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f74310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60e089013560005b8481101561072757600186016000818152600e60205260409020549096506106078b8b848181106105f0576105f0612796565b905061010002018036038101906105499190612772565b1461066e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6f310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60008a8a8381811061068257610682612796565b9050610100020160e0013590506107008382878051602080830151604080518084018890529081018690526060810193909352608083015260009160a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120901c949350505050565b84838151811061071257610712612796565b602090810291909101015291506001016105bd565b50600d54851115610794576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f71000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b61079e828861101a565b600c546040518691907f22c9005dd88c18b552a1cd7e8b3b937fcde9ca69213c1f658f54d572e4877a8190600090a3505050600c91909155505060017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45550505050565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4546001811461088e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f72310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60027f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4553360009081526009602052604090205460ff1661092b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f31680000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600d548210610996576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f76310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600b54821015610a02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f76320000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600c54821015610a1257600c8290555b600d829055602354821015610a275760006023555b600d54600c54600b5460408051938452602084019290925282820152517f8bd4b15ea7d1bc41ea9abc3fc487ccb89cd678a00786584714faa9d751c84ee59181900360600190a160017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4555050565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45460018114610b22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f72310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60027f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4553360009081526009602052604090205460ff16610bbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f31680000000000000000000000000000000000000000000000000000000000006044820152606401610194565b8160005b81811015610c9e57610bfd858583818110610be057610be0612796565b90506101000201803603810190610bf79190612772565b8261118d565b848482818110610c0f57610c0f612796565b9050610100020160e00135858583818110610c2c57610c2c612796565b9050610100020160200135868684818110610c4957610c49612796565b610c609260206101009092020190810191506127c5565b67ffffffffffffffff167f2402307311a4d6604e4e7b4c8a15a7e1213edb39c16a31efa70afb06030d316560405160405180910390a4600101610bc3565b50600b54600090610cb090839061275f565b600b819055600c54909150811115610d24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f6e000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b6023548015801590610d365750818111155b15610d4657600060228190556023555b50505060017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf455505050565b600081604051602001610de7919060006101008201905067ffffffffffffffff8084511683526020840151602084015280604085015116604084015250606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015292915050565b604051602081830303815290604052805190602001209050919050565b60005b81811015610eaa57610e3e84848484818110610e2557610e25612796565b9050602002810190610e3791906127e0565b6000611337565b9350610e4984610d72565b845167ffffffffffffffff9081166000908152600e602090815260408083209490945560e088015190880151885194519194909316917f8f2916b2f2d78cc5890ead36c06c0f6d5d112c7e103589947e8e2f0d6eddb76391a4600101610e07565b50505050565b60235415610f1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f696b0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b82826000818110610f2d57610f2d612796565b9050602002810190610f3f91906127e0565b610f4d9060208101906127c5565b67ffffffffffffffff1660235560005b828110156110135760008115610f74576000610f76565b825b9050610fa686868685818110610f8e57610f8e612796565b9050602002810190610fa091906127e0565b83611337565b9550610fb186610d72565b865167ffffffffffffffff9081166000908152600e602090815260408083209490945560e08a0151908a01518a5194519194909316917f8f2916b2f2d78cc5890ead36c06c0f6d5d112c7e103589947e8e2f0d6eddb76391a450600101610f5d565b5050505050565b8151600114611085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f74340000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600a5460009073ffffffffffffffffffffffffffffffffffffffff166387d9d023846110b4602086018661281e565b6110be878061281e565b6040518663ffffffff1660e01b81526004016110de9594939291906128d1565b602060405180830381865afa1580156110fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111f9190612941565b905080611188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f70000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b505050565b8151600b5467ffffffffffffffff909116906111aa90839061275f565b6111b590600161275f565b811461121d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f6b000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b6000818152600e602052604090205461123584610d72565b1461129c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f65786531300000000000000000000000000000000000000000000000000000006044820152606401610194565b60006112ab846060015161164a565b90508360800151811461131a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f78000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b5060a0909201516000928352600f60205260409092209190915550565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091528351611385906001612963565b67ffffffffffffffff1661139c60208501856127c5565b67ffffffffffffffff161461140d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f66000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b60008060008060008061142089896116d2565b955095509550955095509550838a6020015114611499576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f6c000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b8860a001358514611506576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f74000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b88608001358614611573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f74610000000000000000000000000000000000000000000000000000000000006044820152606401610194565b61159b8161158760408c0160208d016127c5565b67ffffffffffffffff168c60c00151611ecb565b60006115a78a856120a0565b604080516101008101909152909150806115c460208d018d6127c5565b67ffffffffffffffff16815260608c01803560208301526040918201916115ed91908e016127c5565b67ffffffffffffffff1681526020018b6080013581526020018b60a0013581526020018481526020018b602001602081019061162991906127c5565b67ffffffffffffffff168152602001919091529a9950505050505050505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060005b828110156116cc5760006116826010612156565b80516040519192506116a291859190602001918252602082015260400190565b604051602081830303815290604052805190602001209250506116c58160010190565b905061166e565b50919050565b60008080808080806116e86101008a018a61298b565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093945083925061172f9150506101208c018c61298b565b60405161173d9291906129f0565b6040518091039020905060005b8351811015611ddf5760006117728561176460048561275f565b601491810182015192910190565b50905060006117948661178660188661275f565b602091810182015192910190565b50905060006117a88761178660388761275f565b509050600160ff83161b86161561181b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6b700000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600160ff83161b86179550816118b45773ffffffffffffffffffffffffffffffffffffffff8316618008146118ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6c6d0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b809850611dd4565b600182036119ab5773ffffffffffffffffffffffffffffffffffffffff83166180081461193d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6c6e0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b8085146119a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f77700000000000000000000000000000000000000000000000000000000000006044820152606401610194565b611dd4565b60028203611a3c5773ffffffffffffffffffffffffffffffffffffffff831661800814611a34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6c620000000000000000000000000000000000000000000000000000000000006044820152606401610194565b809950611dd4565b60038203611acd5773ffffffffffffffffffffffffffffffffffffffff831661800b14611ac5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f73630000000000000000000000000000000000000000000000000000000000006044820152606401610194565b965086611dd4565b60048203611b5e5773ffffffffffffffffffffffffffffffffffffffff831661800b14611b56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f73760000000000000000000000000000000000000000000000000000000000006044820152606401610194565b809a50611dd4565b60058203611bef5773ffffffffffffffffffffffffffffffffffffffff831661800114611be7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f626c0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b809b50611dd4565b60068203611c805773ffffffffffffffffffffffffffffffffffffffff831661800114611c78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f626b0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b9b508b611dd4565b60078203611d725773ffffffffffffffffffffffffffffffffffffffff831661800114611d09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f62750000000000000000000000000000000000000000000000000000000000006044820152606401610194565b808e146119a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f75740000000000000000000000000000000000000000000000000000000000006044820152606401610194565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756c0000000000000000000000000000000000000000000000000000000000006044820152606401610194565b50505060580161174a565b5089611e545781607f14611e4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f62370000000000000000000000000000000000000000000000000000000000006044820152606401610194565b611ebe565b8160ff14611ebe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f62380000000000000000000000000000000000000000000000000000000000006044820152606401610194565b5050509295509295509295565b608083901c828114611f39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f74620000000000000000000000000000000000000000000000000000000000006044820152606401610194565b808210611fa2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f68330000000000000000000000000000000000000000000000000000000000006044820152606401610194565b6fffffffffffffffffffffffffffffffff841681611fc36203f48042612a00565b111561202b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f68310000000000000000000000000000000000000000000000000000000000006044820152606401610194565b612037610e104261275f565b811115611013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f68320000000000000000000000000000000000000000000000000000000000006044820152606401610194565b6000806120ac84612272565b80519060200120905060006120fc60195460175460185460405160ff909316151560f81b602084015260218301919091526041820152606090606101604051602081830303815290604052905090565b805190602001209050600061211186866122e4565b80516020918201206040805192830186905282018490526060820181905291506080016040516020818303038152906040528051906020012093505050505b92915050565b604080516060810182526000808252602082018190529181019190915260028201546001830154036121e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f73000000000000000000000000000000000000000000000000000000000000006044820152606401610194565b5060028101546000818152602083815260408083208151606081018352815481526001808301805467ffffffffffffffff81168488015268010000000000000000900477ffffffffffffffffffffffffffffffffffffffffffffffff1694830194909452868652938790529084905592905590919061226490829061275f565b836002018190555050919050565b6060612283828201604084016127c5565b60405160c09190911b7fffffffffffffffff0000000000000000000000000000000000000000000000001660208201526060830135602882015260006048820181905260508201526070016040516020818303038152906040529050919050565b60606122f36058610200612a13565b6122fe90600461275f565b61230c61010085018561298b565b90501115612376576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f70750000000000000000000000000000000000000000000000000000000000006044820152606401610194565b600061238661010085018561298b565b6040516123949291906129f0565b604080519182900382206020830181905290820185905260c086810135606084015260e0808801356080850152600060a08501819052918401829052830181905261010083015291506101200160405160208183030381529060405291505092915050565b600060208083528351808285015260005b818110156124265785810183015185820160400152820161240a565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b803567ffffffffffffffff811681146124ac57600080fd5b919050565b60006101008083850312156124c557600080fd5b6040519081019067ffffffffffffffff8211818310171561250f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8160405280925061251f84612494565b81526020840135602082015261253760408501612494565b6040820152606084013560608201526080840135608082015260a084013560a082015260c084013560c082015260e084013560e0820152505092915050565b6000806000610120848603121561258c57600080fd5b61259685856124b1565b925061010084013567ffffffffffffffff808211156125b457600080fd5b818601915086601f8301126125c857600080fd5b8135818111156125d757600080fd5b8760208260051b85010111156125ec57600080fd5b6020830194508093505050509250925092565b60008083601f84011261261157600080fd5b50813567ffffffffffffffff81111561262957600080fd5b6020830191508360208260081b850101111561264457600080fd5b9250929050565b60008060008084860361014081121561266357600080fd5b6101008082121561267357600080fd5b869550850135905067ffffffffffffffff8082111561269157600080fd5b61269d888389016125ff565b90955093506101208701359150808211156126b757600080fd5b508501604081880312156126ca57600080fd5b939692955090935050565b6000602082840312156126e757600080fd5b5035919050565b6000806020838503121561270157600080fd5b823567ffffffffffffffff81111561271857600080fd5b612724858286016125ff565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561215057612150612730565b6000610100828403121561278557600080fd5b61278f83836124b1565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156127d757600080fd5b61278f82612494565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec183360301811261281457600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261285357600080fd5b83018035915067ffffffffffffffff82111561286e57600080fd5b6020019150600581901b360382131561264457600080fd5b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156128b857600080fd5b8260051b80836020870137939093016020019392505050565b606080825286519082018190526000906020906080840190828a01845b8281101561290a578151845292840192908401906001016128ee565b5050508381038285015261291f81888a612886565b9150508281036040840152612935818587612886565b98975050505050505050565b60006020828403121561295357600080fd5b8151801515811461278f57600080fd5b67ffffffffffffffff81811683821601908082111561298457612984612730565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126129c057600080fd5b83018035915067ffffffffffffffff8211156129db57600080fd5b60200191503681900382131561264457600080fd5b8183823760009101908152919050565b8181038181111561215057612150612730565b80820281158282048414176121505761215061273056fea264697066735822122052e435574f5b20feaad10370befd61664ed3bb620c0829dc6bad601d6a72b9fb64736f6c63430008140033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.