Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Multichain Info
No addresses found
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
PerpetualState
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity Standard Json-Input format)
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "PerpetualEscapes.sol"; import "UpdatePerpetualState.sol"; import "Configuration.sol"; import "ForcedTradeActionState.sol"; import "ForcedWithdrawalActionState.sol"; import "Freezable.sol"; import "MainGovernance.sol"; import "StarkExOperator.sol"; import "AcceptModifications.sol"; import "StateRoot.sol"; import "TokenQuantization.sol"; import "SubContractor.sol"; contract PerpetualState is MainGovernance, SubContractor, Configuration, StarkExOperator, Freezable, AcceptModifications, TokenQuantization, ForcedTradeActionState, ForcedWithdrawalActionState, StateRoot, PerpetualEscapes, UpdatePerpetualState { // Empty state is 8 words (256 bytes) To pass as uint[] we need also head & len fields (64). uint256 constant INITIALIZER_SIZE = 384; // Padded address(32), uint(32), Empty state(256+64). /* Initialization flow: 1. Extract initialization parameters from data. 2. Call internalInitializer with those parameters. */ function initialize(bytes calldata data) external override { // This initializer sets roots etc. It must not be applied twice. // I.e. it can run only when the state is still empty. require(sharedStateHash == bytes32(0x0), "STATE_ALREADY_INITIALIZED"); require(configurationHash[GLOBAL_CONFIG_KEY] == bytes32(0x0), "STATE_ALREADY_INITIALIZED"); require(data.length == INITIALIZER_SIZE, "INCORRECT_INIT_DATA_SIZE_384"); ( address escapeVerifierAddress_, uint256 initialSequenceNumber, uint256[] memory initialState ) = abi.decode(data, (address, uint256, uint256[])); initGovernance(); Configuration.initialize(PERPETUAL_CONFIGURATION_DELAY); StarkExOperator.initialize(); // The StateRoot struct has room for 3 trees for compatability with StarkEx. // Perpertual only uses two of these trees. StateRoot.initialize( initialSequenceNumber, uint256(-1), // NOT IN USE. initialState[0], // PositionTreeRoots. initialState[2], // OrderTreeRoots. uint256(-1), // NOT IN USE. initialState[1], // PositionTreeHeights. initialState[3] // OrderTreeHeights. ); sharedStateHash = keccak256(abi.encodePacked(initialState)); PerpetualEscapes.initialize(escapeVerifierAddress_); } /* The call to initializerSize is done from MainDispatcherBase using delegatecall, thus the existing state is already accessible. */ function initializerSize() external view override returns (uint256) { return INITIALIZER_SIZE; } function validatedSelectors() external pure override returns (bytes4[] memory selectors) { uint256 len_ = 1; uint256 index_ = 0; selectors = new bytes4[](len_); selectors[index_++] = PerpetualEscapes.escape.selector; require(index_ == len_, "INCORRECT_SELECTORS_ARRAY_LENGTH"); } function identify() external pure override returns (string memory) { return "StarkWare_PerpetualState_2022_3"; } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "LibConstants.sol"; import "MAcceptModifications.sol"; import "MTokenQuantization.sol"; import "MainStorage.sol"; /* Interface containing actions a verifier can invoke on the state. The contract containing the state should implement these and verify correctness. */ abstract contract AcceptModifications is MainStorage, LibConstants, MAcceptModifications, MTokenQuantization { event LogWithdrawalAllowed( uint256 ownerKey, uint256 assetType, uint256 nonQuantizedAmount, uint256 quantizedAmount ); event LogNftWithdrawalAllowed(uint256 ownerKey, uint256 assetId); event LogAssetWithdrawalAllowed(uint256 ownerKey, uint256 assetId, uint256 quantizedAmount); event LogMintableWithdrawalAllowed(uint256 ownerKey, uint256 assetId, uint256 quantizedAmount); /* Transfers funds from the on-chain deposit area to the off-chain area. Implemented in the Deposits contracts. */ function acceptDeposit( uint256 ownerKey, uint256 vaultId, uint256 assetId, uint256 quantizedAmount ) internal virtual override { // Fetch deposit. require( pendingDeposits[ownerKey][assetId][vaultId] >= quantizedAmount, "DEPOSIT_INSUFFICIENT" ); // Subtract accepted quantized amount. pendingDeposits[ownerKey][assetId][vaultId] -= quantizedAmount; } /* Transfers funds from the off-chain area to the on-chain withdrawal area. */ function allowWithdrawal( uint256 ownerKey, uint256 assetId, uint256 quantizedAmount ) internal override { // Fetch withdrawal. uint256 withdrawal = pendingWithdrawals[ownerKey][assetId]; // Add accepted quantized amount. withdrawal += quantizedAmount; require(withdrawal >= quantizedAmount, "WITHDRAWAL_OVERFLOW"); // Store withdrawal. pendingWithdrawals[ownerKey][assetId] = withdrawal; // Log event. uint256 presumedAssetType = assetId; if (registeredAssetType[presumedAssetType]) { emit LogWithdrawalAllowed( ownerKey, presumedAssetType, fromQuantized(presumedAssetType, quantizedAmount), quantizedAmount ); } else if (assetId == ((assetId & MASK_240) | MINTABLE_ASSET_ID_FLAG)) { emit LogMintableWithdrawalAllowed(ownerKey, assetId, quantizedAmount); } else { // Default case is Non-Mintable ERC721 or ERC1155 asset id. // In ERC721 and ERC1155 cases, assetId is not the assetType. require(assetId == assetId & MASK_250, "INVALID_ASSET_ID"); // If withdrawal amount is 1, the asset could be either NFT or SFT. In that case, both // NFT and general events will be emitted so that the listened for event is captured. // When withdrawal is greater than 1, it must be SFT and only one event will be emitted. if (withdrawal <= 1) { emit LogNftWithdrawalAllowed(ownerKey, assetId); } emit LogAssetWithdrawalAllowed(ownerKey, assetId, quantizedAmount); } } // Verifier authorizes withdrawal. function acceptWithdrawal( uint256 ownerKey, uint256 assetId, uint256 quantizedAmount ) internal virtual override { allowWithdrawal(ownerKey, assetId, quantizedAmount); } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "MainStorage.sol"; import "LibConstants.sol"; /* Calculation action hash for the various forced actions in a generic manner. */ contract ActionHash is MainStorage, LibConstants { function getActionHash(string memory actionName, bytes memory packedActionParameters) internal pure returns (bytes32 actionHash) { actionHash = keccak256(abi.encodePacked(actionName, packedActionParameters)); } function setActionHash(bytes32 actionHash, bool premiumCost) internal { // The rate of forced trade requests is restricted. // First restriction is by capping the number of requests in a block. // User can override this cap by requesting with a permium flag set, // in this case, the gas cost is high (~1M) but no "technical" limit is set. // However, the high gas cost creates an obvious limitation due to the block gas limit. if (premiumCost) { for (uint256 i = 0; i < 21129; i++) {} } else { require( forcedRequestsInBlock[block.number] < MAX_FORCED_ACTIONS_REQS_PER_BLOCK, "MAX_REQUESTS_PER_BLOCK_REACHED" ); forcedRequestsInBlock[block.number] += 1; } forcedActionRequests[actionHash] = block.timestamp; actionHashList.push(actionHash); } function getActionCount() external view returns (uint256) { return actionHashList.length; } function getActionHashByIndex(uint256 actionIndex) external view returns (bytes32) { require(actionIndex < actionHashList.length, "ACTION_INDEX_TOO_HIGH"); return actionHashList[actionIndex]; } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; /* Common Utility Libraries. I. Addresses (extending address). */ library Addresses { /* Note: isContract function has some known limitation. See https://github.com/OpenZeppelin/ openzeppelin-contracts/blob/master/contracts/utils/Address.sol. */ function isContract(address account) internal view returns (bool) { uint256 size; assembly { size := extcodesize(account) } return size > 0; } function performEthTransfer(address recipient, uint256 amount) internal { if (amount == 0) return; (bool success, ) = recipient.call{value: amount}(""); // NOLINT: low-level-calls. require(success, "ETH_TRANSFER_FAILED"); } /* Safe wrapper around ERC20/ERC721 calls. This is required because many deployed ERC20 contracts don't return a value. See https://github.com/ethereum/solidity/issues/4116. */ function safeTokenContractCall(address tokenAddress, bytes memory callData) internal { require(isContract(tokenAddress), "BAD_TOKEN_ADDRESS"); // NOLINTNEXTLINE: low-level-calls. (bool success, bytes memory returndata) = tokenAddress.call(callData); require(success, string(returndata)); if (returndata.length > 0) { require(abi.decode(returndata, (bool)), "TOKEN_OPERATION_FAILED"); } } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "PerpetualConstants.sol"; import "PerpetualStorage.sol"; import "MGovernance.sol"; /** Configuration contract facilitates storing system configuration hashes. A configuration item hash can be stored only once, and cannot be altered or removed. If there is a need for a configuration change (not addition of new one), it shall be performed via upgrade using a dedicated External Initializing Contract (EIC). */ abstract contract Configuration is PerpetualStorage, PerpetualConstants, MGovernance { // This key is used in for the actionsTimeLock. uint256 constant GLOBAL_CONFIG_KEY = uint256(~0); event LogGlobalConfigurationRegistered(bytes32 configHash); event LogGlobalConfigurationApplied(bytes32 configHash); event LogGlobalConfigurationRemoved(bytes32 configHash); event LogAssetConfigurationRegistered(uint256 assetId, bytes32 configHash); event LogAssetConfigurationApplied(uint256 assetId, bytes32 configHash); event LogAssetConfigurationRemoved(uint256 assetId, bytes32 configHash); /* Configuration delay is set during initialization. It is designed to be changed only through upgrade cycle, by altering the storage variable. */ function initialize(uint256 delay) internal { configurationDelay = delay; } /* Register global configuration hash, for applying once configuration delay time-lock expires. */ function registerGlobalConfigurationChange(bytes32 configHash) external onlyGovernance { require(uint256(configHash) < K_MODULUS, "INVALID_CONFIG_HASH"); bytes32 actionKey = keccak256(abi.encodePacked(GLOBAL_CONFIG_KEY, configHash)); actionsTimeLock[actionKey] = block.timestamp + configurationDelay; emit LogGlobalConfigurationRegistered(configHash); } /* Applies global configuration hash. */ function applyGlobalConfigurationChange(bytes32 configHash) external onlyGovernance { bytes32 actionKey = keccak256(abi.encode(GLOBAL_CONFIG_KEY, configHash)); uint256 activationTime = actionsTimeLock[actionKey]; require(activationTime > 0, "CONFIGURATION_NOT_REGSITERED"); require(activationTime <= block.timestamp, "CONFIGURATION_NOT_ENABLE_YET"); globalConfigurationHash = configHash; emit LogGlobalConfigurationApplied(configHash); } function removeGlobalConfigurationChange(bytes32 configHash) external onlyGovernance { bytes32 actionKey = keccak256(abi.encodePacked(GLOBAL_CONFIG_KEY, configHash)); require(actionsTimeLock[actionKey] > 0, "CONFIGURATION_NOT_REGSITERED"); delete actionsTimeLock[actionKey]; emit LogGlobalConfigurationRemoved(configHash); } /* Register an asset configuration hash, for applying once configuration delay time-lock expires. */ function registerAssetConfigurationChange(uint256 assetId, bytes32 configHash) external onlyGovernance { require(assetId < PERPETUAL_ASSET_ID_UPPER_BOUND, "INVALID_ASSET_ID"); require(uint256(configHash) < K_MODULUS, "INVALID_CONFIG_HASH"); bytes32 actionKey = keccak256(abi.encode(assetId, configHash)); actionsTimeLock[actionKey] = block.timestamp + configurationDelay; emit LogAssetConfigurationRegistered(assetId, configHash); } /* Applies asset configuration hash. */ function applyAssetConfigurationChange(uint256 assetId, bytes32 configHash) external onlyGovernance { bytes32 actionKey = keccak256(abi.encode(assetId, configHash)); uint256 activationTime = actionsTimeLock[actionKey]; require(activationTime > 0, "CONFIGURATION_NOT_REGSITERED"); require(activationTime <= block.timestamp, "CONFIGURATION_NOT_ENABLE_YET"); configurationHash[assetId] = configHash; emit LogAssetConfigurationApplied(assetId, configHash); } function removeAssetConfigurationChange(uint256 assetId, bytes32 configHash) external onlyGovernance { bytes32 actionKey = keccak256(abi.encode(assetId, configHash)); require(actionsTimeLock[actionKey] > 0, "CONFIGURATION_NOT_REGSITERED"); delete actionsTimeLock[actionKey]; emit LogAssetConfigurationRemoved(assetId, configHash); } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "PerpetualStorage.sol"; import "MForcedTradeActionState.sol"; import "ActionHash.sol"; /* ForcedTrade specific action hashses. */ contract ForcedTradeActionState is PerpetualStorage, ActionHash, MForcedTradeActionState { function forcedTradeActionHash( uint256 starkKeyA, uint256 starkKeyB, uint256 vaultIdA, uint256 vaultIdB, uint256 collateralAssetId, uint256 syntheticAssetId, uint256 amountCollateral, uint256 amountSynthetic, bool aIsBuyingSynthetic, uint256 nonce ) internal pure override returns (bytes32) { return getActionHash( "FORCED_TRADE", abi.encodePacked( starkKeyA, starkKeyB, vaultIdA, vaultIdB, collateralAssetId, syntheticAssetId, amountCollateral, amountSynthetic, aIsBuyingSynthetic, nonce ) ); } function clearForcedTradeRequest( uint256 starkKeyA, uint256 starkKeyB, uint256 vaultIdA, uint256 vaultIdB, uint256 collateralAssetId, uint256 syntheticAssetId, uint256 amountCollateral, uint256 amountSynthetic, bool aIsBuyingSynthetic, uint256 nonce ) internal override { /* We don't clear the entry, but set the time to max so that it cannot be replayed. */ bytes32 actionHash = forcedTradeActionHash( starkKeyA, starkKeyB, vaultIdA, vaultIdB, collateralAssetId, syntheticAssetId, amountCollateral, amountSynthetic, aIsBuyingSynthetic, nonce ); // A cleared ForcedTrade action is marked with ~0 and not zero, to prevent party A from // replaying the trade without a new signature from party B. require(forcedActionRequests[actionHash] != uint256(~0), "ACTION_ALREADY_CLEARED"); require(forcedActionRequests[actionHash] != 0, "NON_EXISTING_ACTION"); forcedActionRequests[actionHash] = uint256(~0); } function getForcedTradeRequest( uint256 starkKeyA, uint256 starkKeyB, uint256 vaultIdA, uint256 vaultIdB, uint256 collateralAssetId, uint256 syntheticAssetId, uint256 amountCollateral, uint256 amountSynthetic, bool aIsBuyingSynthetic, uint256 nonce ) public view override returns (uint256) { return forcedActionRequests[ forcedTradeActionHash( starkKeyA, starkKeyB, vaultIdA, vaultIdB, collateralAssetId, syntheticAssetId, amountCollateral, amountSynthetic, aIsBuyingSynthetic, nonce ) ]; } function setForcedTradeRequest( uint256 starkKeyA, uint256 starkKeyB, uint256 vaultIdA, uint256 vaultIdB, uint256 collateralAssetId, uint256 syntheticAssetId, uint256 amountCollateral, uint256 amountSynthetic, bool aIsBuyingSynthetic, uint256 nonce, bool premiumCost ) internal override { bytes32 actionHash = forcedTradeActionHash( starkKeyA, starkKeyB, vaultIdA, vaultIdB, collateralAssetId, syntheticAssetId, amountCollateral, amountSynthetic, aIsBuyingSynthetic, nonce ); // NOLINTNEXTLINE: timestamp. require(forcedActionRequests[actionHash] == 0, "FORCED_TRADE_REPLAYED"); setActionHash(actionHash, premiumCost); } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "PerpetualStorage.sol"; import "MForcedWithdrawalActionState.sol"; import "ActionHash.sol"; /* ForcedWithdrawal specific action hashses. */ contract ForcedWithdrawalActionState is PerpetualStorage, ActionHash, MForcedWithdrawalActionState { function forcedWithdrawActionHash( uint256 starkKey, uint256 vaultId, uint256 quantizedAmount ) internal pure override returns (bytes32) { return getActionHash("FORCED_WITHDRAWAL", abi.encode(starkKey, vaultId, quantizedAmount)); } function clearForcedWithdrawalRequest( uint256 starkKey, uint256 vaultId, uint256 quantizedAmount ) internal override { bytes32 actionHash = forcedWithdrawActionHash(starkKey, vaultId, quantizedAmount); require(forcedActionRequests[actionHash] != 0, "NON_EXISTING_ACTION"); delete forcedActionRequests[actionHash]; } function getForcedWithdrawalRequest( uint256 starkKey, uint256 vaultId, uint256 quantizedAmount ) public view override returns (uint256) { // Return request value. Expect zero if the request doesn't exist or has been serviced, and // a non-zero value otherwise. return forcedActionRequests[forcedWithdrawActionHash(starkKey, vaultId, quantizedAmount)]; } function setForcedWithdrawalRequest( uint256 starkKey, uint256 vaultId, uint256 quantizedAmount, bool premiumCost ) internal override { setActionHash(forcedWithdrawActionHash(starkKey, vaultId, quantizedAmount), premiumCost); } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "LibConstants.sol"; import "MFreezable.sol"; import "MGovernance.sol"; import "MainStorage.sol"; /* Implements MFreezable. */ abstract contract Freezable is MainStorage, LibConstants, MGovernance, MFreezable { event LogFrozen(); event LogUnFrozen(); function isFrozen() public view override returns (bool) { return stateFrozen; } function validateFreezeRequest(uint256 requestTime) internal override { require(requestTime != 0, "FORCED_ACTION_UNREQUESTED"); // Verify timer on escape request. uint256 freezeTime = requestTime + FREEZE_GRACE_PERIOD; // Prevent wraparound. assert(freezeTime >= FREEZE_GRACE_PERIOD); require(block.timestamp >= freezeTime, "FORCED_ACTION_PENDING"); // NOLINT: timestamp. // Forced action requests placed before freeze, are no longer valid after the un-freeze. require(freezeTime > unFreezeTime, "REFREEZE_ATTEMPT"); } function freeze() internal override notFrozen { unFreezeTime = block.timestamp + UNFREEZE_DELAY; // Update state. stateFrozen = true; // Log event. emit LogFrozen(); } function unFreeze() external onlyFrozen onlyGovernance { require(block.timestamp >= unFreezeTime, "UNFREEZE_NOT_ALLOWED_YET"); // Update state. stateFrozen = false; // Increment roots to invalidate them, w/o losing information. validiumVaultRoot += 1; rollupVaultRoot += 1; orderRoot += 1; // Log event. emit LogUnFrozen(); } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "MGovernance.sol"; /* Implements Generic Governance, applicable for both proxy and main contract, and possibly others. Notes: The use of the same function names by both the Proxy and a delegated implementation is not possible since calling the implementation functions is done via the default function of the Proxy. For this reason, for example, the implementation of MainContract (MainGovernance) exposes mainIsGovernor, which calls the internal _isGovernor method. */ struct GovernanceInfoStruct { mapping(address => bool) effectiveGovernors; address candidateGovernor; bool initialized; } abstract contract Governance is MGovernance { event LogNominatedGovernor(address nominatedGovernor); event LogNewGovernorAccepted(address acceptedGovernor); event LogRemovedGovernor(address removedGovernor); event LogNominationCancelled(); function getGovernanceInfo() internal view virtual returns (GovernanceInfoStruct storage); /* Current code intentionally prevents governance re-initialization. This may be a problem in an upgrade situation, in a case that the upgrade-to implementation performs an initialization (for real) and within that calls initGovernance(). Possible workarounds: 1. Clearing the governance info altogether by changing the MAIN_GOVERNANCE_INFO_TAG. This will remove existing main governance information. 2. Modify the require part in this function, so that it will exit quietly when trying to re-initialize (uncomment the lines below). */ function initGovernance() internal { GovernanceInfoStruct storage gub = getGovernanceInfo(); require(!gub.initialized, "ALREADY_INITIALIZED"); gub.initialized = true; // to ensure acceptNewGovernor() won't fail. // Add the initial governer. acceptNewGovernor(msg.sender); } function _isGovernor(address user) internal view override returns (bool) { GovernanceInfoStruct storage gub = getGovernanceInfo(); return gub.effectiveGovernors[user]; } /* Cancels the nomination of a governor candidate. */ function _cancelNomination() internal onlyGovernance { GovernanceInfoStruct storage gub = getGovernanceInfo(); if (gub.candidateGovernor != address(0x0)) { gub.candidateGovernor = address(0x0); emit LogNominationCancelled(); } } function _nominateNewGovernor(address newGovernor) internal onlyGovernance { GovernanceInfoStruct storage gub = getGovernanceInfo(); require(newGovernor != address(0x0), "BAD_ADDRESS"); require(!_isGovernor(newGovernor), "ALREADY_GOVERNOR"); require(gub.candidateGovernor == address(0x0), "OTHER_CANDIDATE_PENDING"); gub.candidateGovernor = newGovernor; emit LogNominatedGovernor(newGovernor); } /* The acceptNewGovernor is called in two cases: 1. by _acceptGovernance when a new governor accepts its role. 2. by initGovernance to add the initial governor. The difference is that the init path skips the nominate step that would fail because of the onlyGovernance modifier. */ function acceptNewGovernor(address newGovernor) private { require(!_isGovernor(newGovernor), "ALREADY_GOVERNOR"); GovernanceInfoStruct storage gub = getGovernanceInfo(); gub.effectiveGovernors[newGovernor] = true; // Emit governance information. emit LogNewGovernorAccepted(newGovernor); } function _acceptGovernance() internal { // The new governor was proposed as a candidate by the current governor. GovernanceInfoStruct storage gub = getGovernanceInfo(); require(msg.sender == gub.candidateGovernor, "ONLY_CANDIDATE_GOVERNOR"); // Update state. acceptNewGovernor(msg.sender); gub.candidateGovernor = address(0x0); } /* Remove a governor from office. */ function _removeGovernor(address governorForRemoval) internal onlyGovernance { require(msg.sender != governorForRemoval, "GOVERNOR_SELF_REMOVE"); GovernanceInfoStruct storage gub = getGovernanceInfo(); require(_isGovernor(governorForRemoval), "NOT_GOVERNOR"); gub.effectiveGovernors[governorForRemoval] = false; emit LogRemovedGovernor(governorForRemoval); } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import {GovernanceInfoStruct} from "Governance.sol"; /* Holds the governance slots for ALL entities, including proxy and the main contract. */ contract GovernanceStorage { // A map from a Governor tag to its own GovernanceInfoStruct. mapping(string => GovernanceInfoStruct) internal governanceInfo; //NOLINT uninitialized-state. }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; /* The Fact Registry design pattern is a way to separate cryptographic verification from the business logic of the contract flow. A fact registry holds a hash table of verified "facts" which are represented by a hash of claims that the registry hash check and found valid. This table may be queried by accessing the isValid() function of the registry with a given hash. In addition, each fact registry exposes a registry specific function for submitting new claims together with their proofs. The information submitted varies from one registry to the other depending of the type of fact requiring verification. For further reading on the Fact Registry design pattern see this `StarkWare blog post <https://medium.com/starkware/the-fact-registry-a64aafb598b6>`_. */ interface IFactRegistry { /* Returns true if the given fact was previously registered in the contract. */ function isValid(bytes32 fact) external view returns (bool); }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; interface Identity { /* Allows a caller to ensure that the provided address is of the expected type and version. */ function identify() external pure returns (string memory); }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; contract LibConstants { // Durations for time locked mechanisms (in seconds). // Note that it is known that miners can manipulate block timestamps // up to a deviation of a few seconds. // This mechanism should not be used for fine grained timing. // The time required to cancel a deposit, in the case the operator does not move the funds // to the off-chain storage. uint256 public constant DEPOSIT_CANCEL_DELAY = 2 days; // The time required to freeze the exchange, in the case the operator does not execute a // requested full withdrawal. uint256 public constant FREEZE_GRACE_PERIOD = 7 days; // The time after which the exchange may be unfrozen after it froze. This should be enough time // for users to perform escape hatches to get back their funds. uint256 public constant UNFREEZE_DELAY = 365 days; // Maximal number of verifiers which may co-exist. uint256 public constant MAX_VERIFIER_COUNT = uint256(64); // The time required to remove a verifier in case of a verifier upgrade. uint256 public constant VERIFIER_REMOVAL_DELAY = FREEZE_GRACE_PERIOD + (21 days); address constant ZERO_ADDRESS = address(0x0); uint256 constant K_MODULUS = 0x800000000000011000000000000000000000000000000000000000000000001; uint256 constant K_BETA = 0x6f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e89; uint256 internal constant MASK_250 = 0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; uint256 internal constant MASK_240 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; uint256 public constant MAX_FORCED_ACTIONS_REQS_PER_BLOCK = 10; uint256 constant QUANTUM_UPPER_BOUND = 2**128; uint256 internal constant MINTABLE_ASSET_ID_FLAG = 1 << 250; // The 64th bit (indexed 63, counting from 0) is a flag indicating a rollup vault id. uint256 constant ROLLUP_VAULTS_BIT = 63; }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; /* Interface containing actions a verifier can invoke on the state. The contract containing the state should implement these and verify correctness. */ abstract contract MAcceptModifications { function acceptDeposit( uint256 ownerKey, uint256 vaultId, uint256 assetId, uint256 quantizedAmount ) internal virtual; function allowWithdrawal( uint256 ownerKey, uint256 assetId, uint256 quantizedAmount ) internal virtual; function acceptWithdrawal( uint256 ownerKey, uint256 assetId, uint256 quantizedAmount ) internal virtual; }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; abstract contract MForcedTradeActionState { function forcedTradeActionHash( uint256 starkKeyA, uint256 starkKeyB, uint256 vaultIdA, uint256 vaultIdB, uint256 collateralAssetId, uint256 syntheticAssetId, uint256 amountCollateral, uint256 amountSynthetic, bool aIsBuyingSynthetic, uint256 nonce ) internal pure virtual returns (bytes32); function clearForcedTradeRequest( uint256 starkKeyA, uint256 starkKeyB, uint256 vaultIdA, uint256 vaultIdB, uint256 collateralAssetId, uint256 syntheticAssetId, uint256 amountCollateral, uint256 amountSynthetic, bool aIsBuyingSynthetic, uint256 nonce ) internal virtual; // NOLINTNEXTLINE: external-function. function getForcedTradeRequest( uint256 starkKeyA, uint256 starkKeyB, uint256 vaultIdA, uint256 vaultIdB, uint256 collateralAssetId, uint256 syntheticAssetId, uint256 amountCollateral, uint256 amountSynthetic, bool aIsBuyingSynthetic, uint256 nonce ) public view virtual returns (uint256 res); function setForcedTradeRequest( uint256 starkKeyA, uint256 starkKeyB, uint256 vaultIdA, uint256 vaultIdB, uint256 collateralAssetId, uint256 syntheticAssetId, uint256 amountCollateral, uint256 amountSynthetic, bool aIsBuyingSynthetic, uint256 nonce, bool premiumCost ) internal virtual; }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; abstract contract MForcedWithdrawalActionState { function forcedWithdrawActionHash( uint256 starkKey, uint256 vaultId, uint256 quantizedAmount ) internal pure virtual returns (bytes32); function clearForcedWithdrawalRequest( uint256 starkKey, uint256 vaultId, uint256 quantizedAmount ) internal virtual; // NOLINTNEXTLINE: external-function. function getForcedWithdrawalRequest( uint256 starkKey, uint256 vaultId, uint256 quantizedAmount ) public view virtual returns (uint256 res); function setForcedWithdrawalRequest( uint256 starkKey, uint256 vaultId, uint256 quantizedAmount, bool premiumCost ) internal virtual; }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; abstract contract MFreezable { /* Returns true if the exchange is frozen. */ function isFrozen() public view virtual returns (bool); // NOLINT: external-function. /* Forbids calling the function if the exchange is frozen. */ modifier notFrozen() { require(!isFrozen(), "STATE_IS_FROZEN"); _; } function validateFreezeRequest(uint256 requestTime) internal virtual; /* Allows calling the function only if the exchange is frozen. */ modifier onlyFrozen() { require(isFrozen(), "STATE_NOT_FROZEN"); _; } /* Freezes the exchange. */ function freeze() internal virtual; }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; abstract contract MGovernance { function _isGovernor(address user) internal view virtual returns (bool); /* Allows calling the function only by a Governor. */ modifier onlyGovernance() { require(_isGovernor(msg.sender), "ONLY_GOVERNANCE"); _; } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "MGovernance.sol"; abstract contract MOperator { event LogOperatorAdded(address operator); event LogOperatorRemoved(address operator); function isOperator(address user) public view virtual returns (bool); modifier onlyOperator() { require(isOperator(msg.sender), "ONLY_OPERATOR"); _; } function registerOperator(address newOperator) external virtual; function unregisterOperator(address removedOperator) external virtual; function getOperators() internal view virtual returns (mapping(address => bool) storage); }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; abstract contract MStateRoot { function getValidiumVaultRoot() public view virtual returns (uint256); function getValidiumTreeHeight() public view virtual returns (uint256); function getRollupVaultRoot() public view virtual returns (uint256); function getRollupTreeHeight() public view virtual returns (uint256); /* Returns true iff vaultId is in the valid vault ids range, i.e. could appear in either the validium or rollup vaults trees. */ function isVaultInRange(uint256 vaultId) internal view virtual returns (bool); /* Returns true if vaultId is a valid validium vault id. Note: when this function returns false it might mean that vaultId is invalid and does not guarantee that vaultId is a valid rollup vault id. */ function isValidiumVault(uint256 vaultId) internal view virtual returns (bool); /* Returns true if vaultId is a valid rollup vault id. Note: when this function returns false it might mean that vaultId is invalid and does not guarantee that vaultId is a valid validium vault id. */ function isRollupVault(uint256 vaultId) internal view virtual returns (bool); /* Given a valid vaultId, returns its leaf index in the validium/rollup tree. Note: this function does not assert the validity of vaultId, make sure to explicitly assert it when required. */ function getVaultLeafIndex(uint256 vaultId) internal pure virtual returns (uint256); }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; abstract contract MTokenQuantization { function fromQuantized(uint256 presumedAssetType, uint256 quantizedAmount) internal view virtual returns (uint256 amount); // NOLINTNEXTLINE: external-function. function getQuantum(uint256 presumedAssetType) public view virtual returns (uint256 quantum); function toQuantized(uint256 presumedAssetType, uint256 amount) internal view virtual returns (uint256 quantizedAmount); }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "Governance.sol"; import "GovernanceStorage.sol"; /** The StarkEx contract is governed by one or more Governors of which the initial one is the deployer of the contract. A governor has the sole authority to perform the following operations: 1. Nominate additional governors (:sol:func:`mainNominateNewGovernor`) 2. Remove other governors (:sol:func:`mainRemoveGovernor`) 3. Add new :sol:mod:`Verifiers` and :sol:mod:`AvailabilityVerifiers` 4. Remove :sol:mod:`Verifiers` and :sol:mod:`AvailabilityVerifiers` after a timelock allows it 5. Nominate Operators (see :sol:mod:`Operator`) and Token Administrators (see :sol:mod:`TokenRegister`) Adding governors is performed in a two step procedure: 1. First, an existing governor nominates a new governor (:sol:func:`mainNominateNewGovernor`) 2. Then, the new governor must accept governance to become a governor (:sol:func:`mainAcceptGovernance`) This two step procedure ensures that a governor public key cannot be nominated unless there is an entity that has the corresponding private key. This is intended to prevent errors in the addition process. The governor private key should typically be held in a secure cold wallet. */ /* Implements Governance for the StarkDex main contract. The wrapper methods (e.g. mainIsGovernor wrapping _isGovernor) are needed to give the method unique names. Both Proxy and StarkExchange inherit from Governance. Thus, the logical contract method names must have unique names in order for the proxy to successfully delegate to them. */ contract MainGovernance is GovernanceStorage, Governance { // The tag is the sting key that is used in the Governance storage mapping. string public constant MAIN_GOVERNANCE_INFO_TAG = "StarkEx.Main.2019.GovernorsInformation"; /* Returns the GovernanceInfoStruct associated with the governance tag. */ function getGovernanceInfo() internal view override returns (GovernanceInfoStruct storage) { return governanceInfo[MAIN_GOVERNANCE_INFO_TAG]; } function mainIsGovernor(address user) external view returns (bool) { return _isGovernor(user); } function mainNominateNewGovernor(address newGovernor) external { _nominateNewGovernor(newGovernor); } function mainRemoveGovernor(address governorForRemoval) external { _removeGovernor(governorForRemoval); } function mainAcceptGovernance() external { _acceptGovernance(); } function mainCancelNomination() external { _cancelNomination(); } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "ProxyStorage.sol"; import "Addresses.sol"; import {ApprovalChainData} from "StarkExTypes.sol"; /* Holds ALL the main contract state (storage) variables. */ contract MainStorage is ProxyStorage { uint256 internal constant LAYOUT_LENGTH = 2**64; address escapeVerifierAddress; // NOLINT: constable-states. // Global dex-frozen flag. bool stateFrozen; // NOLINT: constable-states. // Time when unFreeze can be successfully called (UNFREEZE_DELAY after freeze). uint256 unFreezeTime; // NOLINT: constable-states. // Pending deposits. // A map STARK key => asset id => vault id => quantized amount. mapping(uint256 => mapping(uint256 => mapping(uint256 => uint256))) pendingDeposits; // Cancellation requests. // A map STARK key => asset id => vault id => request timestamp. mapping(uint256 => mapping(uint256 => mapping(uint256 => uint256))) cancellationRequests; // Pending withdrawals. // A map STARK key => asset id => quantized amount. mapping(uint256 => mapping(uint256 => uint256)) pendingWithdrawals; // vault_id => escape used boolean. mapping(uint256 => bool) escapesUsed; // Number of escapes that were performed when frozen. uint256 escapesUsedCount; // NOLINT: constable-states. // NOTE: fullWithdrawalRequests is deprecated, and replaced by forcedActionRequests. // NOLINTNEXTLINE naming-convention. mapping(uint256 => mapping(uint256 => uint256)) fullWithdrawalRequests_DEPRECATED; // State sequence number. uint256 sequenceNumber; // NOLINT: constable-states uninitialized-state. // Validium Vaults Tree Root & Height. uint256 validiumVaultRoot; // NOLINT: constable-states uninitialized-state. uint256 validiumTreeHeight; // NOLINT: constable-states uninitialized-state. // Order Tree Root & Height. uint256 orderRoot; // NOLINT: constable-states uninitialized-state. uint256 orderTreeHeight; // NOLINT: constable-states uninitialized-state. // True if and only if the address is allowed to add tokens. mapping(address => bool) tokenAdmins; // This mapping is no longer in use, remains for backwards compatibility. mapping(address => bool) userAdmins_DEPRECATED; // NOLINT: naming-convention. // True if and only if the address is an operator (allowed to update state). mapping(address => bool) operators; // NOLINT: uninitialized-state. // Mapping of contract ID to asset data. mapping(uint256 => bytes) assetTypeToAssetInfo; // NOLINT: uninitialized-state. // Mapping of registered contract IDs. mapping(uint256 => bool) registeredAssetType; // NOLINT: uninitialized-state. // Mapping from contract ID to quantum. mapping(uint256 => uint256) assetTypeToQuantum; // NOLINT: uninitialized-state. // This mapping is no longer in use, remains for backwards compatibility. mapping(address => uint256) starkKeys_DEPRECATED; // NOLINT: naming-convention. // Mapping from STARK public key to the Ethereum public key of its owner. mapping(uint256 => address) ethKeys; // NOLINT: uninitialized-state. // Timelocked state transition and availability verification chain. ApprovalChainData verifiersChain; ApprovalChainData availabilityVerifiersChain; // Batch id of last accepted proof. uint256 lastBatchId; // NOLINT: constable-states uninitialized-state. // Mapping between sub-contract index to sub-contract address. mapping(uint256 => address) subContracts; // NOLINT: uninitialized-state. mapping(uint256 => bool) permissiveAssetType_DEPRECATED; // NOLINT: naming-convention. // ---- END OF MAIN STORAGE AS DEPLOYED IN STARKEX2.0 ---- // Onchain-data version configured for the system. uint256 onchainDataVersion_DEPRECATED; // NOLINT: naming-convention constable-states. // Counter of forced action request in block. The key is the block number. mapping(uint256 => uint256) forcedRequestsInBlock; // ForcedAction requests: actionHash => requestTime. mapping(bytes32 => uint256) forcedActionRequests; // Mapping for timelocked actions. // A actionKey => activation time. mapping(bytes32 => uint256) actionsTimeLock; // Append only list of requested forced action hashes. bytes32[] actionHashList; // ---- END OF MAIN STORAGE AS DEPLOYED IN STARKEX3.0 ---- // ---- END OF MAIN STORAGE AS DEPLOYED IN STARKEX4.0 ---- // Rollup Vaults Tree Root & Height. uint256 rollupVaultRoot; // NOLINT: constable-states uninitialized-state. uint256 rollupTreeHeight; // NOLINT: constable-states uninitialized-state. uint256 globalConfigCode; // NOLINT: constable-states uninitialized-state. // Reserved storage space for Extensibility. // Every added MUST be added above the end gap, and the __endGap size must be reduced // accordingly. // NOLINTNEXTLINE: naming-convention. uint256[LAYOUT_LENGTH - 40] private __endGap; // __endGap complements layout to LAYOUT_LENGTH. }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; library OnchainDataFactTreeEncoder { struct DataAvailabilityFact { uint256 onchainDataHash; uint256 onchainDataSize; } // The number of additional words appended to the public input when using the // OnchainDataFactTreeEncoder format. uint256 internal constant ONCHAIN_DATA_FACT_ADDITIONAL_WORDS = 2; /* Encodes a GPS fact Merkle tree where the root has two children. The left child contains the data we care about and the right child contains on-chain data for the fact. */ function encodeFactWithOnchainData( uint256[] calldata programOutput, DataAvailabilityFact memory factData ) internal pure returns (bytes32) { // The state transition fact is computed as a Merkle tree, as defined in // GpsOutputParser. // // In our case the fact tree looks as follows: // The root has two children. // The left child is a leaf that includes the main part - the information regarding // the state transition required by this contract. // The right child contains the onchain-data which shouldn't be accessed by this // contract, so we are only given its hash and length // (it may be a leaf or an inner node, this has no effect on this contract). // Compute the hash without the two additional fields. uint256 mainPublicInputLen = programOutput.length; bytes32 mainPublicInputHash = keccak256(abi.encodePacked(programOutput)); // Compute the hash of the fact Merkle tree. bytes32 hashResult = keccak256( abi.encodePacked( mainPublicInputHash, mainPublicInputLen, factData.onchainDataHash, mainPublicInputLen + factData.onchainDataSize ) ); // Add one to the hash to indicate it represents an inner node, rather than a leaf. return bytes32(uint256(hashResult) + 1); } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "MOperator.sol"; import "MGovernance.sol"; /** The Operator of the contract is the entity entitled to submit state update requests by calling :sol:func:`updateState`. An Operator may be instantly appointed or removed by the contract Governor (see :sol:mod:`Governance`). Typically, the Operator is the hot wallet of the service submitting proofs for state updates. */ abstract contract Operator is MGovernance, MOperator { function registerOperator(address newOperator) external override onlyGovernance { if (!isOperator(newOperator)) { getOperators()[newOperator] = true; emit LogOperatorAdded(newOperator); } } function unregisterOperator(address removedOperator) external override onlyGovernance { if (isOperator(removedOperator)) { getOperators()[removedOperator] = false; emit LogOperatorRemoved(removedOperator); } } function isOperator(address user) public view override returns (bool) { return getOperators()[user]; } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "LibConstants.sol"; contract PerpetualConstants is LibConstants { uint256 constant PERPETUAL_POSITION_ID_UPPER_BOUND = 2**64; uint256 constant PERPETUAL_AMOUNT_UPPER_BOUND = 2**64; uint256 constant PERPETUAL_TIMESTAMP_BITS = 32; uint256 constant PERPETUAL_ASSET_ID_UPPER_BOUND = 2**120; uint256 constant PERPETUAL_SYSTEM_TIME_LAG_BOUND = 7 days; uint256 constant PERPETUAL_SYSTEM_TIME_ADVANCE_BOUND = 4 hours; uint256 constant PERPETUAL_CONFIGURATION_DELAY = 0; }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "LibConstants.sol"; import "MAcceptModifications.sol"; import "MFreezable.sol"; import "IFactRegistry.sol"; import "PerpetualStorage.sol"; /** Escaping the exchange is the last resort for users that wish to withdraw their funds without relying on off-chain exchange services. The Escape functionality may only be invoked once the contract has become frozen. This will be as the result of an unserviced forcedAction request At that point, any escaper entity may perform an escape operation as follows: 1. Escapers call the :sol:mod:`PerpetualEscapeVerifier` contract with the Merkle proof for the vault to be evicted and the shared state. If the proof is valid, this results in the registration of said proof. 2. Escapers call :sol:func:`escape` function with the starkKey, vaultId and quantizedAmount matching the proof from step 1. 3. The owner of the vault may then withdraw this amount from the pending withdrawals account by calling the normal withdraw function (see :sol:mod:`Withdrawals`) to transfer the funds to the users ERC20 account. Note that while anyone can perform the initial steps of the escape operation (including the exchange operator, for example), only the owner of the vault may perform the final step of transferring the funds. */ abstract contract PerpetualEscapes is PerpetualStorage, MAcceptModifications, MFreezable { function initialize(address escapeVerifier) internal { escapeVerifierAddress = escapeVerifier; } /* Escape when the contract is frozen. */ function escape( uint256 starkKey, uint256 vaultId, uint256 quantizedAmount ) external onlyFrozen { require(!escapesUsed[vaultId], "ESCAPE_ALREADY_USED"); // Escape can be used only once. escapesUsed[vaultId] = true; escapesUsedCount += 1; bytes32 claimHash = keccak256( abi.encode(starkKey, quantizedAmount, sharedStateHash, vaultId) ); IFactRegistry escapeVerifier = IFactRegistry(escapeVerifierAddress); require(escapeVerifier.isValid(claimHash), "ESCAPE_LACKS_PROOF"); allowWithdrawal(starkKey, systemAssetType, quantizedAmount); } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "MainStorage.sol"; /* Extends MainStorage, holds Perpetual App specific state (storage) variables. ALL State variables that are common to all applications, reside in MainStorage, whereas ALL the Perpetual app specific ones reside here. */ contract PerpetualStorage is MainStorage { uint256 systemAssetType; // NOLINT: constable-states uninitialized-state. bytes32 public globalConfigurationHash; // NOLINT: constable-states uninitialized-state. mapping(uint256 => bytes32) public configurationHash; // NOLINT: uninitialized-state. bytes32 sharedStateHash; // NOLINT: constable-states uninitialized-state. // Configuration apply time-lock. // The delay is held in storage (and not constant) // So that it can be modified during upgrade. uint256 public configurationDelay; // NOLINT: constable-states. // Reserved storage space for Extensibility. // Every added MUST be added above the end gap, and the __endGap size must be reduced // accordingly. // NOLINTNEXTLINE: naming-convention shadowing-abstract. uint256[LAYOUT_LENGTH - 5] private __endGap; // __endGap complements layout to LAYOUT_LENGTH. }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; contract ProgramOutputOffsets { // The following constants are offsets of data expected in the program output. // The offsets here are of the fixed fields. uint256 internal constant PROG_OUT_GENERAL_CONFIG_HASH = 0; uint256 internal constant PROG_OUT_DATA_AVAILABILTY_MODE = 1; uint256 internal constant PROG_OUT_N_ASSET_CONFIGS = 2; uint256 internal constant PROG_OUT_ASSET_CONFIG_HASHES = 3; /* Additional mandatory fields of a single word: - Previous state size 3 - New state size 4 - Vault tree height 5 - Order tree height 6 - Expiration timestamp 7 - No. of Modifications 8. */ uint256 internal constant PROG_OUT_N_WORDS_MIN_SIZE = 9; uint256 internal constant PROG_OUT_N_WORDS_PER_ASSET_CONFIG = 2; uint256 internal constant PROG_OUT_N_WORDS_PER_MODIFICATION = 3; uint256 internal constant ASSET_CONFIG_OFFSET_ASSET_ID = 0; uint256 internal constant ASSET_CONFIG_OFFSET_CONFIG_HASH = 1; uint256 internal constant MODIFICATIONS_OFFSET_STARKKEY = 0; uint256 internal constant MODIFICATIONS_OFFSET_POS_ID = 1; uint256 internal constant MODIFICATIONS_OFFSET_BIASED_DIFF = 2; uint256 internal constant STATE_OFFSET_VAULTS_ROOT = 0; uint256 internal constant STATE_OFFSET_VAULTS_HEIGHT = 1; uint256 internal constant STATE_OFFSET_ORDERS_ROOT = 2; uint256 internal constant STATE_OFFSET_ORDERS_HEIGHT = 3; uint256 internal constant STATE_OFFSET_N_FUNDING = 4; uint256 internal constant STATE_OFFSET_FUNDING = 5; // Data availability mode. uint256 internal constant VALIDIUM_MODE = 0; uint256 internal constant ROLLUP_MODE = 1; // The following constants are offsets of data expected in the application data. uint256 internal constant APP_DATA_BATCH_ID_OFFSET = 0; uint256 internal constant APP_DATA_PREVIOUS_BATCH_ID_OFFSET = 1; uint256 internal constant APP_DATA_N_CONDITIONAL_TRANSFER = 2; uint256 internal constant APP_DATA_CONDITIONAL_TRANSFER_DATA_OFFSET = 3; uint256 internal constant APP_DATA_N_WORDS_PER_CONDITIONAL_TRANSFER = 2; }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "GovernanceStorage.sol"; /* Holds the Proxy-specific state variables. This contract is inherited by the GovernanceStorage (and indirectly by MainStorage) to prevent collision hazard. */ contract ProxyStorage is GovernanceStorage { // NOLINTNEXTLINE: naming-convention uninitialized-state. mapping(address => bytes32) internal initializationHash_DEPRECATED; // The time after which we can switch to the implementation. // Hash(implementation, data, finalize) => time. mapping(bytes32 => uint256) internal enabledTime; // A central storage of the flags whether implementation has been initialized. // Note - it can be used flexibly enough to accommodate multiple levels of initialization // (i.e. using different key salting schemes for different initialization levels). mapping(bytes32 => bool) internal initialized; }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "Operator.sol"; import "MainStorage.sol"; /** Operator implementation for StarkEx (StarkExchange & StarkPerpetual). */ abstract contract StarkExOperator is MainStorage, Operator { function initialize() internal { getOperators()[msg.sender] = true; emit LogOperatorAdded(msg.sender); } function getOperators() internal view override returns (mapping(address => bool) storage) { return operators; } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; // Structure representing a list of verifiers (validity/availability). // A statement is valid only if all the verifiers in the list agree on it. // Adding a verifier to the list is immediate - this is used for fast resolution of // any soundness issues. // Removing a verifier from the list is time-locked, to ensure that any user of the system // not content with the announced removal has ample time to leave the system before it is // removed. struct ApprovalChainData { address[] verifiers; // Represents the time after which the verifier with the given address can be removed. // Removal of the verifier with address A is allowed only in the case the value // of verifierAllowedRemovalTime[A] != 0 and verifierAllowedRemovalTime[A] < (current time). mapping(address => uint256) verifierAllowedRemovalTime; }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "MStateRoot.sol"; import "MainStorage.sol"; import "LibConstants.sol"; contract StateRoot is MainStorage, LibConstants, MStateRoot { function initialize( uint256 initialSequenceNumber, uint256 initialValidiumVaultRoot, uint256 initialRollupVaultRoot, uint256 initialOrderRoot, uint256 initialValidiumTreeHeight, uint256 initialRollupTreeHeight, uint256 initialOrderTreeHeight ) internal { sequenceNumber = initialSequenceNumber; validiumVaultRoot = initialValidiumVaultRoot; rollupVaultRoot = initialRollupVaultRoot; orderRoot = initialOrderRoot; validiumTreeHeight = initialValidiumTreeHeight; rollupTreeHeight = initialRollupTreeHeight; orderTreeHeight = initialOrderTreeHeight; } function getValidiumVaultRoot() public view override returns (uint256) { return validiumVaultRoot; } function getValidiumTreeHeight() public view override returns (uint256) { return validiumTreeHeight; } function getRollupVaultRoot() public view override returns (uint256) { return rollupVaultRoot; } function getRollupTreeHeight() public view override returns (uint256) { return rollupTreeHeight; } function getOrderRoot() external view returns (uint256) { return orderRoot; } function getOrderTreeHeight() external view returns (uint256) { return orderTreeHeight; } function getSequenceNumber() external view returns (uint256) { return sequenceNumber; } function getLastBatchId() external view returns (uint256) { return lastBatchId; } function getGlobalConfigCode() external view returns (uint256) { return globalConfigCode; } function isVaultInRange(uint256 vaultId) internal view override returns (bool) { return (isValidiumVault(vaultId) || isRollupVault(vaultId)); } function isValidiumVault(uint256 vaultId) internal view override returns (bool) { // Return true iff vaultId is in the validium vaults tree. return vaultId < 2**getValidiumTreeHeight(); } function isRollupVault(uint256 vaultId) internal view override returns (bool) { // Return true iff vaultId is in the rollup vaults tree. uint256 rollupLowerBound = 2**ROLLUP_VAULTS_BIT; uint256 rollupUpperBound = rollupLowerBound + 2**getRollupTreeHeight(); return (rollupLowerBound <= vaultId && vaultId < rollupUpperBound); } function getVaultLeafIndex(uint256 vaultId) internal pure override returns (uint256) { // Return the index of vaultId leaf in its tree, which doesn't include the rollup bit flag. return (vaultId & (2**ROLLUP_VAULTS_BIT - 1)); } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "Identity.sol"; interface SubContractor is Identity { function initialize(bytes calldata data) external; function initializerSize() external view returns (uint256); /* Returns an array with selectors for validation. These selectors are the critical ones for maintaining self custody and anti censorship. During the upgrade process, as part of the sub-contract validation, the MainDispatcher validates that the selectos are mapped to the correct sub-contract. */ function validatedSelectors() external pure returns (bytes4[] memory); }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "MainStorage.sol"; import "MTokenQuantization.sol"; contract TokenQuantization is MainStorage, MTokenQuantization { function fromQuantized(uint256 presumedAssetType, uint256 quantizedAmount) internal view override returns (uint256 amount) { uint256 quantum = getQuantum(presumedAssetType); amount = quantizedAmount * quantum; require(amount / quantum == quantizedAmount, "DEQUANTIZATION_OVERFLOW"); } function getQuantum(uint256 presumedAssetType) public view override returns (uint256 quantum) { if (!registeredAssetType[presumedAssetType]) { // Default quantization, for NFTs etc. quantum = 1; } else { // Retrieve registration. quantum = assetTypeToQuantum[presumedAssetType]; } } function toQuantized(uint256 presumedAssetType, uint256 amount) internal view override returns (uint256 quantizedAmount) { uint256 quantum = getQuantum(presumedAssetType); require(amount % quantum == 0, "INVALID_AMOUNT"); quantizedAmount = amount / quantum; } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "PerpetualStorage.sol"; import "MForcedTradeActionState.sol"; import "MForcedWithdrawalActionState.sol"; import "PerpetualConstants.sol"; import "ProgramOutputOffsets.sol"; import "OnchainDataFactTreeEncoder.sol"; import "VerifyFactChain.sol"; import "MAcceptModifications.sol"; import "MFreezable.sol"; import "MOperator.sol"; import "Addresses.sol"; /** TO-DO:DOC. */ abstract contract UpdatePerpetualState is PerpetualStorage, PerpetualConstants, MForcedTradeActionState, MForcedWithdrawalActionState, VerifyFactChain, MAcceptModifications, MFreezable, MOperator, ProgramOutputOffsets { event LogUpdateState(uint256 sequenceNumber, uint256 batchId); event LogStateTransitionFact(bytes32 stateTransitionFact); enum ForcedAction { Withdrawal, Trade } struct ProgramOutputMarkers { uint256 globalConfigurationHash; uint256 nAssets; uint256 assetConfigOffset; uint256 prevSharedStateSize; uint256 prevSharedStateOffset; uint256 newSharedStateSize; uint256 newSharedStateOffset; uint256 newVaultsRoot; uint256 newVaultsHeight; uint256 newOrdersRoot; uint256 newOrdersHeight; uint256 newSystemTime; uint256 dataAvailabilityMode; uint256 expirationTimestamp; uint256 nModifications; uint256 modificationsOffset; uint256 forcedActionsSize; uint256 nForcedActions; uint256 forcedActionsOffset; uint256 nConditions; uint256 conditionsOffset; } function updateState(uint256[] calldata programOutput, uint256[] calldata applicationData) external notFrozen onlyOperator { ProgramOutputMarkers memory outputMarkers = parseProgramOutput(programOutput); require( outputMarkers.expirationTimestamp < 2**PERPETUAL_TIMESTAMP_BITS, "Expiration timestamp is out of range." ); require( outputMarkers.newSystemTime > (block.timestamp - PERPETUAL_SYSTEM_TIME_LAG_BOUND), "SYSTEM_TIME_OUTDATED" ); require( outputMarkers.newSystemTime < (block.timestamp + PERPETUAL_SYSTEM_TIME_ADVANCE_BOUND), "SYSTEM_TIME_INVALID" ); require( outputMarkers.expirationTimestamp > block.timestamp / 3600, "BATCH_TIMESTAMP_EXPIRED" ); require( outputMarkers.newVaultsHeight == programOutput[outputMarkers.prevSharedStateOffset + STATE_OFFSET_VAULTS_HEIGHT], "INCONSISTENT_POSITION_TREE_HEIGHT" ); require( outputMarkers.newOrdersHeight == programOutput[outputMarkers.prevSharedStateOffset + STATE_OFFSET_ORDERS_HEIGHT], "INCONSISTENT_ORDER_TREE_HEIGHT" ); validateConfigHashes(programOutput, outputMarkers); // Caclulate previous shared state hash, and compare with stored one. bytes32 prevStateHash = keccak256( abi.encodePacked( programOutput[outputMarkers.prevSharedStateOffset:outputMarkers .prevSharedStateOffset + outputMarkers.prevSharedStateSize] ) ); require(prevStateHash == sharedStateHash, "INVALID_PREVIOUS_SHARED_STATE"); require( applicationData[APP_DATA_PREVIOUS_BATCH_ID_OFFSET] == lastBatchId, "WRONG_PREVIOUS_BATCH_ID" ); bytes32 stateTransitionFact; if (outputMarkers.dataAvailabilityMode == VALIDIUM_MODE) { stateTransitionFact = keccak256(abi.encodePacked(programOutput)); } else { require( outputMarkers.dataAvailabilityMode == ROLLUP_MODE, "UNSUPPORTED_DATA_AVAILABILITY_MODE" ); require( programOutput.length >= outputMarkers.forcedActionsOffset + OnchainDataFactTreeEncoder.ONCHAIN_DATA_FACT_ADDITIONAL_WORDS, "programOutput does not contain all required fields." ); stateTransitionFact = OnchainDataFactTreeEncoder.encodeFactWithOnchainData( programOutput[:programOutput.length - OnchainDataFactTreeEncoder.ONCHAIN_DATA_FACT_ADDITIONAL_WORDS], OnchainDataFactTreeEncoder.DataAvailabilityFact({ onchainDataHash: programOutput[programOutput.length - 2], onchainDataSize: programOutput[programOutput.length - 1] }) ); } emit LogStateTransitionFact(stateTransitionFact); verifyFact( verifiersChain, stateTransitionFact, "NO_STATE_TRANSITION_VERIFIERS", "NO_STATE_TRANSITION_PROOF" ); if (outputMarkers.dataAvailabilityMode == VALIDIUM_MODE) { bytes32 availabilityFact = keccak256( abi.encodePacked( outputMarkers.newVaultsRoot, outputMarkers.newVaultsHeight, outputMarkers.newOrdersRoot, outputMarkers.newOrdersHeight, sequenceNumber + 1 ) ); verifyFact( availabilityVerifiersChain, availabilityFact, "NO_AVAILABILITY_VERIFIERS", "NO_AVAILABILITY_PROOF" ); } performUpdateState(programOutput, outputMarkers, applicationData); } function validateConfigHashes( uint256[] calldata programOutput, ProgramOutputMarkers memory markers ) internal view { require(globalConfigurationHash != bytes32(0), "GLOBAL_CONFIGURATION_NOT_SET"); require( globalConfigurationHash == bytes32(markers.globalConfigurationHash), "GLOBAL_CONFIGURATION_MISMATCH" ); uint256 offset = markers.assetConfigOffset; for (uint256 i = 0; i < markers.nAssets; i++) { uint256 assetId = programOutput[offset + ASSET_CONFIG_OFFSET_ASSET_ID]; bytes32 assetConfigHash = bytes32( programOutput[offset + ASSET_CONFIG_OFFSET_CONFIG_HASH] ); require(configurationHash[assetId] == assetConfigHash, "ASSET_CONFIGURATION_MISMATCH"); offset += PROG_OUT_N_WORDS_PER_ASSET_CONFIG; } } function parseProgramOutput(uint256[] calldata programOutput) internal pure returns (ProgramOutputMarkers memory) { require( programOutput.length >= PROG_OUT_N_WORDS_MIN_SIZE, "programOutput does not contain all required fields." ); ProgramOutputMarkers memory markers; // NOLINT: uninitialized-local. markers.globalConfigurationHash = programOutput[PROG_OUT_GENERAL_CONFIG_HASH]; markers.dataAvailabilityMode = programOutput[PROG_OUT_DATA_AVAILABILTY_MODE]; markers.nAssets = programOutput[PROG_OUT_N_ASSET_CONFIGS]; require(markers.nAssets < 2**16, "ILLEGAL_NUMBER_OF_ASSETS"); uint256 offset = PROG_OUT_ASSET_CONFIG_HASHES; markers.assetConfigOffset = offset; offset += markers.nAssets * PROG_OUT_N_WORDS_PER_ASSET_CONFIG; require( programOutput.length >= offset + 1, // Adding +1 for the next mandatory field. "programOutput invalid size (nAssetConfig)" ); markers.prevSharedStateSize = programOutput[offset++]; markers.prevSharedStateOffset = offset; offset += markers.prevSharedStateSize; require( programOutput.length >= offset + 1, // Adding +1 for the next mandatory field. "programOutput invalid size (prevState)" ); markers.newSharedStateSize = programOutput[offset++]; markers.newSharedStateOffset = offset; offset += markers.newSharedStateSize; require( programOutput.length >= offset + 2, // Adding +2 for the next mandatory fields. "programOutput invalid size (newState)" ); // System time is the last field in the state. markers.newSystemTime = programOutput[offset - 1]; markers.newVaultsRoot = programOutput[ markers.newSharedStateOffset + STATE_OFFSET_VAULTS_ROOT ]; markers.newVaultsHeight = programOutput[ markers.newSharedStateOffset + STATE_OFFSET_VAULTS_HEIGHT ]; markers.newOrdersRoot = programOutput[ markers.newSharedStateOffset + STATE_OFFSET_ORDERS_ROOT ]; markers.newOrdersHeight = programOutput[ markers.newSharedStateOffset + STATE_OFFSET_ORDERS_HEIGHT ]; markers.expirationTimestamp = programOutput[offset++]; markers.nModifications = programOutput[offset++]; markers.modificationsOffset = offset; offset += markers.nModifications * PROG_OUT_N_WORDS_PER_MODIFICATION; markers.forcedActionsSize = programOutput[offset++]; markers.nForcedActions = programOutput[offset++]; markers.forcedActionsOffset = offset; offset += markers.forcedActionsSize; markers.nConditions = programOutput[offset++]; markers.conditionsOffset = offset; offset += markers.nConditions; // In ROLLUP_MODE the Onchain Data info appears at the end of programOutput. if (markers.dataAvailabilityMode == ROLLUP_MODE) { offset += OnchainDataFactTreeEncoder.ONCHAIN_DATA_FACT_ADDITIONAL_WORDS; } require( programOutput.length == offset, "programOutput invalid size (mods/forced/conditions)" ); return markers; } function performUpdateState( uint256[] calldata programOutput, ProgramOutputMarkers memory markers, uint256[] calldata applicationData ) internal { sharedStateHash = keccak256( abi.encodePacked( programOutput[markers.newSharedStateOffset:markers.newSharedStateOffset + markers.newSharedStateSize] ) ); sequenceNumber += 1; uint256 batchId = applicationData[APP_DATA_BATCH_ID_OFFSET]; lastBatchId = batchId; sendModifications(programOutput, markers, applicationData); verifyConditionalTransfers(programOutput, markers, applicationData); clearForcedActionsFlags(programOutput, markers); emit LogUpdateState(sequenceNumber, batchId); } /* Goes through the program output forced actions section, extract each forced action, and if valid and its flag exists, clears it. If invalid, or not flag not exist - revert. */ function clearForcedActionsFlags( uint256[] calldata programOutput, ProgramOutputMarkers memory markers ) private { uint256 offset = markers.forcedActionsOffset; for (uint256 i = 0; i < markers.nForcedActions; i++) { ForcedAction forcedActionType = ForcedAction(programOutput[offset++]); if (forcedActionType == ForcedAction.Withdrawal) { offset = clearForcedWithdrawal(programOutput, offset); } else if (forcedActionType == ForcedAction.Trade) { offset = clearForcedTrade(programOutput, offset); } else { revert("UNKNOWN_FORCED_ACTION_TYPE"); } } // Ensure all sizes are matching (this is not checked in parsing). require(markers.forcedActionsOffset + markers.forcedActionsSize == offset, "SIZE_MISMATCH"); } function clearForcedWithdrawal(uint256[] calldata programOutput, uint256 offset) private returns (uint256) { uint256 starkKey = programOutput[offset++]; uint256 vaultId = programOutput[offset++]; uint256 quantizedAmount = programOutput[offset++]; clearForcedWithdrawalRequest(starkKey, vaultId, quantizedAmount); return offset; } function clearForcedTrade(uint256[] calldata programOutput, uint256 offset) private returns (uint256) { uint256 starkKeyA = programOutput[offset++]; uint256 starkKeyB = programOutput[offset++]; uint256 vaultIdA = programOutput[offset++]; uint256 vaultIdB = programOutput[offset++]; // CollateralAssetId Not taken from progOutput. We use systemAssetType. uint256 syntheticAssetId = programOutput[offset++]; uint256 amountCollateral = programOutput[offset++]; uint256 amountSynthetic = programOutput[offset++]; bool aIsBuyingSynthetic = (programOutput[offset++] != 0); uint256 nonce = programOutput[offset++]; clearForcedTradeRequest( starkKeyA, starkKeyB, vaultIdA, vaultIdB, systemAssetType, syntheticAssetId, amountCollateral, amountSynthetic, aIsBuyingSynthetic, nonce ); return offset; } function verifyConditionalTransfers( uint256[] calldata programOutput, ProgramOutputMarkers memory markers, uint256[] calldata applicationData ) private view { require(applicationData.length >= APP_DATA_N_CONDITIONAL_TRANSFER, "APP_DATA_TOO_SHORT"); require( applicationData[APP_DATA_N_CONDITIONAL_TRANSFER] == markers.nConditions, "N_CONDITIONS_MISMATCH" ); require( applicationData.length >= APP_DATA_CONDITIONAL_TRANSFER_DATA_OFFSET + markers.nConditions * APP_DATA_N_WORDS_PER_CONDITIONAL_TRANSFER, "BAD_APP_DATA_SIZE" ); uint256 conditionsOffset = markers.conditionsOffset; uint256 preImageOffset = APP_DATA_CONDITIONAL_TRANSFER_DATA_OFFSET; // Conditional Transfers appear after all other modifications. for (uint256 i = 0; i < markers.nConditions; i++) { address transferRegistry = address(applicationData[preImageOffset]); bytes32 transferFact = bytes32(applicationData[preImageOffset + 1]); uint256 condition = programOutput[conditionsOffset]; // The condition is the 250 LS bits of keccak256 of the fact registry & fact. require( condition == uint256(keccak256(abi.encodePacked(transferRegistry, transferFact))) & MASK_250, "Condition mismatch." ); // NOLINTNEXTLINE: low-level-calls-loop reentrancy-events. (bool success, bytes memory returndata) = transferRegistry.staticcall( abi.encodeWithSignature("isValid(bytes32)", transferFact) ); require(success && returndata.length == 32, "BAD_FACT_REGISTRY_CONTRACT"); require( abi.decode(returndata, (bool)), "Condition for the conditional transfer was not met." ); conditionsOffset += 1; preImageOffset += APP_DATA_N_WORDS_PER_CONDITIONAL_TRANSFER; } } function sendModifications( uint256[] calldata programOutput, ProgramOutputMarkers memory markers, uint256[] calldata /*applicationData*/ ) private { uint256 assetId = systemAssetType; require(assetId < K_MODULUS, "Asset id >= PRIME"); uint256 offset = markers.modificationsOffset; for (uint256 i = 0; i < markers.nModifications; i++) { uint256 starkKey = programOutput[offset + MODIFICATIONS_OFFSET_STARKKEY]; uint256 vaultId = programOutput[offset + MODIFICATIONS_OFFSET_POS_ID]; uint256 biasedDiff = programOutput[offset + MODIFICATIONS_OFFSET_BIASED_DIFF]; // Biased representation. // biased_delta is in range [0, 2**65), where 2**64 means 0 change. // The effective difference is biased_delta - 2**64. require(biasedDiff < (1 << 65), "Illegal Balance Diff"); int256 balanceDiff = int256(biasedDiff - (1 << 64)); require(starkKey < K_MODULUS, "Stark key >= PRIME"); if (balanceDiff > 0) { // This is a deposit. acceptDeposit(starkKey, vaultId, assetId, uint256(balanceDiff)); } else if (balanceDiff < 0) { // This is a withdrawal. acceptWithdrawal(starkKey, assetId, uint256(-balanceDiff)); } offset += PROG_OUT_N_WORDS_PER_MODIFICATION; } } }
/* Copyright 2019-2022 StarkWare Industries Ltd. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.starkware.co/open-source-license/ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // SPDX-License-Identifier: Apache-2.0. pragma solidity ^0.6.12; import "MainStorage.sol"; import "IFactRegistry.sol"; import {ApprovalChainData} from "StarkExTypes.sol"; contract VerifyFactChain is MainStorage { function verifyFact( ApprovalChainData storage chain, bytes32 fact, string memory noVerifiersErrorMessage, string memory invalidFactErrorMessage ) internal view { address[] storage verifiers = chain.verifiers; uint256 n_entries = verifiers.length; require(n_entries > 0, noVerifiersErrorMessage); for (uint256 i = 0; i < n_entries; i++) { // NOLINTNEXTLINE: calls-loop. require(IFactRegistry(verifiers[i]).isValid(fact), invalidFactErrorMessage); } } }
{ "metadata": { "useLiteralContent": true }, "libraries": {}, "remappings": [], "optimizer": { "enabled": true, "runs": 100 }, "evmVersion": "istanbul", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"assetId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"LogAssetConfigurationApplied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"assetId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"LogAssetConfigurationRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"assetId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"LogAssetConfigurationRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"ownerKey","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quantizedAmount","type":"uint256"}],"name":"LogAssetWithdrawalAllowed","type":"event"},{"anonymous":false,"inputs":[],"name":"LogFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"LogGlobalConfigurationApplied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"LogGlobalConfigurationRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"LogGlobalConfigurationRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"ownerKey","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quantizedAmount","type":"uint256"}],"name":"LogMintableWithdrawalAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"acceptedGovernor","type":"address"}],"name":"LogNewGovernorAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"ownerKey","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetId","type":"uint256"}],"name":"LogNftWithdrawalAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nominatedGovernor","type":"address"}],"name":"LogNominatedGovernor","type":"event"},{"anonymous":false,"inputs":[],"name":"LogNominationCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"LogOperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"LogOperatorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"removedGovernor","type":"address"}],"name":"LogRemovedGovernor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"stateTransitionFact","type":"bytes32"}],"name":"LogStateTransitionFact","type":"event"},{"anonymous":false,"inputs":[],"name":"LogUnFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"sequenceNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"batchId","type":"uint256"}],"name":"LogUpdateState","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"ownerKey","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nonQuantizedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quantizedAmount","type":"uint256"}],"name":"LogWithdrawalAllowed","type":"event"},{"inputs":[],"name":"DEPOSIT_CANCEL_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FREEZE_GRACE_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAIN_GOVERNANCE_INFO_TAG","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FORCED_ACTIONS_REQS_PER_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VERIFIER_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNFREEZE_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERIFIER_REMOVAL_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetId","type":"uint256"},{"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"applyAssetConfigurationChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"applyGlobalConfigurationChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"configurationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"configurationHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"starkKey","type":"uint256"},{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"quantizedAmount","type":"uint256"}],"name":"escape","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getActionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"actionIndex","type":"uint256"}],"name":"getActionHashByIndex","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"starkKeyA","type":"uint256"},{"internalType":"uint256","name":"starkKeyB","type":"uint256"},{"internalType":"uint256","name":"vaultIdA","type":"uint256"},{"internalType":"uint256","name":"vaultIdB","type":"uint256"},{"internalType":"uint256","name":"collateralAssetId","type":"uint256"},{"internalType":"uint256","name":"syntheticAssetId","type":"uint256"},{"internalType":"uint256","name":"amountCollateral","type":"uint256"},{"internalType":"uint256","name":"amountSynthetic","type":"uint256"},{"internalType":"bool","name":"aIsBuyingSynthetic","type":"bool"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"getForcedTradeRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"starkKey","type":"uint256"},{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"quantizedAmount","type":"uint256"}],"name":"getForcedWithdrawalRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalConfigCode","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastBatchId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOrderRoot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOrderTreeHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"presumedAssetType","type":"uint256"}],"name":"getQuantum","outputs":[{"internalType":"uint256","name":"quantum","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRollupTreeHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRollupVaultRoot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSequenceNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidiumTreeHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidiumVaultRoot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalConfigurationHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"identify","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initializerSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainAcceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mainCancelNomination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"mainIsGovernor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newGovernor","type":"address"}],"name":"mainNominateNewGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"governorForRemoval","type":"address"}],"name":"mainRemoveGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetId","type":"uint256"},{"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"registerAssetConfigurationChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"registerGlobalConfigurationChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOperator","type":"address"}],"name":"registerOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetId","type":"uint256"},{"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"removeAssetConfigurationChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"removeGlobalConfigurationChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unFreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"removedOperator","type":"address"}],"name":"unregisterOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"programOutput","type":"uint256[]"},{"internalType":"uint256[]","name":"applicationData","type":"uint256[]"}],"name":"updateState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validatedSelectors","outputs":[{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"stateMutability":"pure","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50614138806100206000396000f3fe608060405234801561001057600080fd5b50600436106102895760003560e01c806380f235b01161015c578063b7663112116100ce578063e6de628211610087578063e6de62821461076c578063e9aa2d6b14610774578063eeb728661461077c578063f00cec4b14610784578063f2011f66146107dc578063fc86484a146107f957610289565b8063b7663112146106b2578063bb7c3d32146106ba578063c1a85130146106c2578063c23b60ef146106ca578063dd7202d814610747578063e30a5cff1461076457610289565b8063993f363911610120578063993f3639146106195780639bd4f229146106215780639f8a504414610644578063a1cc921e14610661578063ad54846714610687578063adac3e15146106aa57610289565b806380f235b0146105a057806381b47796146105bd5780638c4bce1c146105c55780638ed31439146105eb57806396115bc2146105f357610289565b806342af35fd116102005780635eecd218116101b95780635eecd218146105525780636d70f7ae1461055a57806372eb36881461058057806377e84e0d146105885780637cf12b90146105905780637e9da4c51461059857610289565b806342af35fd146103d3578063439fab91146103db57806345f5cd9714610449578063515535e81461046f578063538f9406146104775780635e586cd11461053557610289565b806328700a151161025257806328700a151461035057806333eeb14714610358578063366a2670146103745780633682a4501461039d5780633a8cc4fc146103c35780633cc660ad146103cb57610289565b80627175421461028e5780630dded952146102a85780630ebdac03146102b05780631829057714610308578063260e96dd14610327575b600080fd5b61029661081c565b60408051918252519081900360200190f35b610296610823565b6102b8610829565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102f45781810151838201526020016102dc565b505050509050019250505060405180910390f35b6103256004803603602081101561031e57600080fd5b50356108dd565b005b6102966004803603606081101561033d57600080fd5b50803590602081013590604001356109ef565b610325610a18565b610360610a22565b604080519115158252519081900360200190f35b6103256004803603606081101561038a57600080fd5b5080359060208101359060400135610a32565b610325600480360360208110156103b357600080fd5b50356001600160a01b0316610c11565b610296610cd3565b610296610cd9565b610296610cdf565b610325600480360360208110156103f157600080fd5b810190602081018135600160201b81111561040b57600080fd5b82018360208201111561041d57600080fd5b803590602001918460018302840111600160201b8311171561043e57600080fd5b509092509050610ce5565b6103606004803603602081101561045f57600080fd5b50356001600160a01b0316610fae565b610296610fc1565b6103256004803603604081101561048d57600080fd5b810190602081018135600160201b8111156104a757600080fd5b8201836020820111156104b957600080fd5b803590602001918460208302840111600160201b831117156104da57600080fd5b919390929091602081019035600160201b8111156104f757600080fd5b82018360208201111561050957600080fd5b803590602001918460208302840111600160201b8311171561052a57600080fd5b509092509050610fc7565b6102966004803603602081101561054b57600080fd5b5035611666565b6102966116d6565b6103606004803603602081101561057057600080fd5b50356001600160a01b03166116dc565b610325611709565b610296611711565b610325611718565b610296611857565b610325600480360360208110156105b657600080fd5b503561185d565b6102966119be565b610325600480360360208110156105db57600080fd5b50356001600160a01b03166119c4565b6102966119cd565b6103256004803603602081101561060957600080fd5b50356001600160a01b03166119d3565b610296611a95565b6103256004803603604081101561063757600080fd5b5080359060200135611a9d565b6103256004803603602081101561065a57600080fd5b5035611c10565b6103256004803603602081101561067757600080fd5b50356001600160a01b0316611d34565b6103256004803603604081101561069d57600080fd5b5080359060200135611d3d565b610296611eb0565b610296611ebc565b610296611ec3565b610296611ec9565b6106d2611ed5565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561070c5781810151838201526020016106f4565b50505050905090810190601f1680156107395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102966004803603602081101561075d57600080fd5b5035611ef1565b610296611f22565b610296611f27565b610296611f2c565b6106d2611f32565b610296600480360361014081101561079b57600080fd5b5080359060208101359060408101359060608101359060808101359060a08101359060c08101359060e0810135906101008101351515906101200135611f69565b610296600480360360208110156107f257600080fd5b5035611fa0565b6103256004803603604081101561080f57600080fd5b5080359060200135611fb8565b62093a8081565b600f5490565b60408051600180825281830190925260609190600090826020808301908036833750508151919450506001820191630366a26760e41b91859190811061086b57fe5b6001600160e01b0319909216602092830291909101909101528082146108d8576040805162461bcd60e51b815260206004820181905260248201527f494e434f52524543545f53454c4543544f52535f41525241595f4c454e475448604482015290519081900360640190fd5b505090565b6108e6336120ce565b610929576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b604080516000196020808301919091528183018490528251808303840181526060909201835281519181019190912060008181526023909252919020546109a5576040805162461bcd60e51b815260206004820152601c6024820152600080516020613fc1833981519152604482015290519081900360640190fd5b600081815260236020908152604080832092909255815184815291517f21e13101b7a52038b3abfab6f17d3a3d091c620b978b98c9de7f3aa91e7ac0639281900390910190a15050565b600060226000610a008686866120fd565b81526020019081526020016000205490509392505050565b610a20612169565b565b600454600160a01b900460ff1690565b610a3a610a22565b610a7e576040805162461bcd60e51b815260206004820152601060248201526f29aa20aa22afa727aa2fa32927ad22a760811b604482015290519081900360640190fd5b60008281526009602052604090205460ff1615610ad8576040805162461bcd60e51b81526020600482015260136024820152721154d0d0541157d053149150511657d554d151606a1b604482015290519081900360640190fd5b600082815260096020908152604091829020805460ff19166001908117909155600a805490910190556003600160401b01548251808301879052808401859052606081019190915260808082018690528351808303909101815260a08201808552815191840191909120600454636a93856760e01b90925260a4830181905293516001600160a01b03909116928392636a9385679260c48083019392829003018186803b158015610b8857600080fd5b505afa158015610b9c573d6000803e3d6000fd5b505050506040513d6020811015610bb257600080fd5b5051610bfa576040805162461bcd60e51b815260206004820152601260248201527122a9a1a0a822afa620a1a5a9afa82927a7a360711b604482015290519081900360640190fd5b610c0a85600160401b54856121ed565b5050505050565b610c1a336120ce565b610c5d576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b610c66816116dc565b610cd0576001610c7461240f565b6001600160a01b03831660008181526020928352604090819020805460ff191694151594909417909355825190815291517f50a18c352ee1c02ffe058e15c2eb6e58be387c81e73cc1e17035286e54c19a579281900390910190a15b50565b600d5490565b61018090565b600c5490565b6003600160401b015415610d3c576040805162461bcd60e51b815260206004820152601960248201527814d510551157d053149150511657d253925512505312569151603a1b604482015290519081900360640190fd5b6000196000526002600160401b016020527f2c5bd237f717a902f05528dc77f82cade6aa0a080972f06685282ae7786cdd4b5415610dbd576040805162461bcd60e51b815260206004820152601960248201527814d510551157d053149150511657d253925512505312569151603a1b604482015290519081900360640190fd5b6101808114610e13576040805162461bcd60e51b815260206004820152601c60248201527f494e434f52524543545f494e49545f444154415f53495a455f33383400000000604482015290519081900360640190fd5b600080606084846060811015610e2857600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610e5757600080fd5b820183602082011115610e6957600080fd5b803590602001918460208302840111600160201b83111715610e8a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250979a50959850909650610ed39550612414945050505050565b610edd6000612496565b610ee56124a1565b610f488260001983600081518110610ef957fe5b602002602001015184600281518110610f0e57fe5b602002602001015160001986600181518110610f2657fe5b602002602001015187600381518110610f3b57fe5b60200260200101516124ff565b8060405160200180828051906020019060200280838360005b83811015610f79578181015183820152602001610f61565b50505050905001915050604051602081830303815290604052805190602001206003600160401b0181905550610c0a8361251f565b6000610fb9826120ce565b90505b919050565b601d5490565b610fcf610a22565b15611013576040805162461bcd60e51b815260206004820152600f60248201526e29aa20aa22afa4a9afa32927ad22a760891b604482015290519081900360640190fd5b61101c336116dc565b61105d576040805162461bcd60e51b815260206004820152600d60248201526c27a7262cafa7a822a920aa27a960991b604482015290519081900360640190fd5b611065613e7c565b61106f8585612541565b9050602060020a816101a00151106110b85760405162461bcd60e51b81526004018080602001828103825260258152602001806140856025913960400191505060405180910390fd5b62093a8042038161016001511161110d576040805162461bcd60e51b815260206004820152601460248201527314d654d5115357d512535157d3d555111055115160621b604482015290519081900360640190fd5b613840420181610160015110611160576040805162461bcd60e51b815260206004820152601360248201527214d654d5115357d512535157d2539590531251606a1b604482015290519081900360640190fd5b610e104204816101a00151116111b7576040805162461bcd60e51b815260206004820152601760248201527610905510d217d512535154d510535417d1561412549151604a1b604482015290519081900360640190fd5b848460018360800151018181106111ca57fe5b90506020020135816101000151146112135760405162461bcd60e51b8152600401808060200182810382526021815260200180613fa06021913960400191505060405180910390fd5b8484600383608001510181811061122657fe5b9050602002013581610140015114611285576040805162461bcd60e51b815260206004820152601e60248201527f494e434f4e53495354454e545f4f524445525f545245455f4845494748540000604482015290519081900360640190fd5b61129085858361293e565b608081015160608201516000916112ab918101908789613f1c565b6040516020018083836020028082843780830192505050925050506040516020818303038152906040528051906020012090506003600160401b0154811461133a576040805162461bcd60e51b815260206004820152601d60248201527f494e56414c49445f50524556494f55535f5348415245445f5354415445000000604482015290519081900360640190fd5b601d548484600181811061134a57fe5b905060200201351461139d576040805162461bcd60e51b815260206004820152601760248201527615d493d391d7d41491559253d554d7d0905510d217d251604a1b604482015290519081900360640190fd5b60008083610180015114156113e65786866040516020018083836020028082843780830192505050925050506040516020818303038152906040528051906020012090506114d0565b60018361018001511461142a5760405162461bcd60e51b81526004018080602001828103825260228152602001806140636022913960400191505060405180910390fd5b6102408301516002018610156114715760405162461bcd60e51b8152600401808060200182810382526033815260200180613f6d6033913960400191505060405180910390fd5b6114cd61148560011988016000898b613f1c565b60408051808201909152808b8b60011981018181106114a057fe5b9050602002013581526020018b8b60018e8e9050038181106114be57fe5b90506020020135815250612ab7565b90505b6040805182815290517f9866f8ddfe70bb512b2f2b28b49d4017c43f7ba775f1a20c61c13eea8cdac1119181900360200190a16115766019826040518060400160405280601d81526020017f4e4f5f53544154455f5452414e534954494f4e5f564552494649455253000000815250604051806040016040528060198152602001782727afa9aa20aa22afaa2920a729a4aa24a7a72fa82927a7a360391b815250612b42565b6101808301516116505760008360e00151846101000151856101200151866101400151600c54600101604051602001808681526020018581526020018481526020018381526020018281526020019550505050505060405160208183030381529060405280519060200120905061164e601b82604051806040016040528060198152602001784e4f5f415641494c4142494c4954595f56455249464945525360381b815250604051806040016040528060158152602001742727afa0ab20a4a620a124a624aa2cafa82927a7a360591b815250612b42565b505b61165d8787858888612cba565b50505050505050565b60245460009082106116b7576040805162461bcd60e51b815260206004820152601560248201527408286a8929e9cbe929c888ab0bea89e9ebe90928e9605b1b604482015290519081900360640190fd5b602482815481106116c457fe5b90600052602060002001549050919050565b60245490565b60006116e661240f565b6001600160a01b0392909216600090815260209290925250604090205460ff1690565b610a20612d9b565b6202a30081565b611720610a22565b611764576040805162461bcd60e51b815260206004820152601060248201526f29aa20aa22afa727aa2fa32927ad22a760811b604482015290519081900360640190fd5b61176d336120ce565b6117b0576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b600554421015611802576040805162461bcd60e51b8152602060048201526018602482015277155391949151569157d393d517d0531313d5d15117d6515560421b604482015290519081900360640190fd5b6004805460ff60a01b19169055600d805460019081019091556025805482019055600f805490910190556040517f07017fe9180629cfffba412f65a9affcf9a121de02294179f5c058f881dcc9f890600090a1565b60105490565b611866336120ce565b6118a9576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6040805160001960208083019190915281830184905282518083038401815260609092018352815191810191909120600081815260239092529190205480611926576040805162461bcd60e51b815260206004820152601c6024820152600080516020613fc1833981519152604482015290519081900360640190fd5b4281111561197b576040805162461bcd60e51b815260206004820152601c60248201527f434f4e46494755524154494f4e5f4e4f545f454e41424c455f59455400000000604482015290519081900360640190fd5b6001600160401b018390556040805184815290517f215e2cbb35cc7dd3f085fdb4ede08d32f4619001c73f5b10419389e7949c28ba9181900360200190a1505050565b60265490565b610cd081612e45565b60255490565b6119dc336120ce565b611a1f576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b611a28816116dc565b15610cd0576000611a3761240f565b6001600160a01b03831660008181526020928352604090819020805460ff191694151594909417909355825190815291517fec5f6c3a91a1efb1f9a308bb33c6e9e66bf9090fad0732f127dfdbf516d0625d9281900390910190a150565b6301e1338081565b611aa6336120ce565b611ae9576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b60408051602080820185905281830184905282518083038401815260609092018352815191810191909120600081815260239092529190205480611b62576040805162461bcd60e51b815260206004820152601c6024820152600080516020613fc1833981519152604482015290519081900360640190fd5b42811115611bb7576040805162461bcd60e51b815260206004820152601c60248201527f434f4e46494755524154494f4e5f4e4f545f454e41424c455f59455400000000604482015290519081900360640190fd5b60008481526002600160401b016020908152604091829020859055815186815290810185905281517f617a24590fcf7d5a2650aa9c10572915cb4bf853b1ef135cc1918460946a7a2f929181900390910190a150505050565b611c19336120ce565b611c5c576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b600167080000000000001160c01b018110611cb4576040805162461bcd60e51b81526020600482015260136024820152720929cac82989288be869e9c8c928ebe9082a69606b1b604482015290519081900360640190fd5b60408051600019602080830191909152818301849052825180830384018152606083018085528151918301919091206004600160401b015460008281526023909452928590204290930190925584905291517ffae91148d75f3789f216345abe08b5415e0e727d51cab9f4e41efc23f71193f79181900360800190a15050565b610cd081612fe5565b611d46336120ce565b611d89576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b600160781b8210611dd4576040805162461bcd60e51b815260206004820152601060248201526f1253959053125117d054d4d15517d25160821b604482015290519081900360640190fd5b600167080000000000001160c01b018110611e2c576040805162461bcd60e51b81526020600482015260136024820152720929cac82989288be869e9c8c928ebe9082a69606b1b604482015290519081900360640190fd5b604080516020808201859052818301849052825180830384018152606083018085528151918301919091206004600160401b01546000828152602390945292859020429093019092558590526080820184905291517ffbe49fc520438bdf956c8964ba0394d2da4fa3f34686e826a2ded762fa687c2d9181900360a00190a1505050565b6001600160401b015481565b6224ea0081565b600e5490565b6004600160401b015481565b604051806060016040528060268152602001613fe16026913981565b60008181526015602052604081205460ff16611f0f57506001610fbc565b5060009081526016602052604090205490565b600a81565b604081565b60275490565b60408051808201909152601f81527f537461726b576172655f50657270657475616c53746174655f323032325f3300602082015290565b600060226000611f818d8d8d8d8d8d8d8d8d8d613132565b81526020019081526020016000205490509a9950505050505050505050565b6002600160401b016020526000908152604090205481565b611fc1336120ce565b612004576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b60408051602080820185905281830184905282518083038401815260609092018352815191810191909120600081815260239092529190205461207c576040805162461bcd60e51b815260206004820152601c6024820152600080516020613fc1833981519152604482015290519081900360640190fd5b600081815260236020908152604080832092909255815185815290810184905281517fbedb78be82c75282d73923c8287b6b3e3ef57379cdc69f7fbd3d227a9969b48e929181900390910190a1505050565b6000806120d96131d5565b6001600160a01b039390931660009081526020939093525050604090205460ff1690565b6000612161604051806040016040528060118152602001701193d490d15117d5d2551211149055d053607a1b815250858585604051602001808481526020018381526020018281526020019350505050604051602081830303815290604052613252565b949350505050565b60006121736131d5565b60018101549091506001600160a01b031633146121d1576040805162461bcd60e51b815260206004820152601760248201527627a7262cafa1a0a72224a220aa22afa3a7ab22a92727a960491b604482015290519081900360640190fd5b6121da33613314565b60010180546001600160a01b0319169055565b6000838152600860209081526040808320858452909152902054810181811015612254576040805162461bcd60e51b81526020600482015260136024820152725749544844524157414c5f4f564552464c4f5760681b604482015290519081900360640190fd5b600084815260086020908152604080832086845282528083208490556015909152902054839060ff16156122d8577f03c10a82c955f7bcd0c934147fb39cafca947a4294425b1751d884c8ac95428785826122af84876133c8565b6040805193845260208401929092528282015260608201869052519081900360800190a1610c0a565b600160fa1b6001600160f01b0385161784141561233457604080518681526020810186905280820185905290517f2acce0cedb29dc4927e6c891b57ef5bc8858eea4bf52787ea94873aebd4aeca09181900360600190a1610c0a565b6001600160fa1b0384168414612384576040805162461bcd60e51b815260206004820152601060248201526f1253959053125117d054d4d15517d25160821b604482015290519081900360640190fd5b600182116123c857604080518681526020810186905281517ff07608f26256bce78d87220cfc0e7b1cc69b48e55104bfa591b2818161386627929181900390910190a15b604080518681526020810186905280820185905290517fd31f59c968eb53320f624721416cf88605da9aadbaa723405e52affe9de4b07f9181900360600190a15050505050565b601390565b600061241e6131d5565b6001810154909150600160a01b900460ff1615612478576040805162461bcd60e51b81526020600482015260136024820152721053149150511657d253925512505312569151606a1b604482015290519081900360640190fd5b60018101805460ff60a01b1916600160a01b179055610cd033613314565b6004600160401b0155565b60016124ab61240f565b3360008181526020928352604090819020805460ff191694151594909417909355825190815291517f50a18c352ee1c02ffe058e15c2eb6e58be387c81e73cc1e17035286e54c19a579281900390910190a1565b600c96909655600d94909455602592909255600f55600e55602655601055565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b612549613e7c565b60098210156125895760405162461bcd60e51b8152600401808060200182810382526033815260200180613f6d6033913960400191505060405180910390fd5b612591613e7c565b8383600081811061259e57fe5b6020029190910135825250838360018181106125b657fe5b602002919091013561018083015250838360028181106125d257fe5b60209081029290920135918301829052506201000011612634576040805162461bcd60e51b8152602060048201526018602482015277494c4c4547414c5f4e554d4245525f4f465f41535345545360401b604482015290519081900360640190fd5b60036040820181905260208201516002029081019060040184101561268a5760405162461bcd60e51b815260040180806020018281038252602981526020018061403a6029913960400191505060405180910390fd5b84848280600101935081811061269c57fe5b60200291909101356060840181905260808401839052919091019050600181018410156126fa5760405162461bcd60e51b81526004018080602001828103825260268152602001806140dd6026913960400191505060405180910390fd5b84848280600101935081811061270c57fe5b602002919091013560a0840181905260c084018390529190910190506002810184101561276a5760405162461bcd60e51b8152600401808060200182810382526025815260200180613f486025913960400191505060405180910390fd5b84846001830381811061277957fe5b60200291909101356101608401525060c08201518590859081811061279a57fe5b905060200201358260e0018181525050848460018460c00151018181106127bd57fe5b9050602002013582610100018181525050848460028460c00151018181106127e157fe5b9050602002013582610120018181525050848460038460c001510181811061280557fe5b60200291909101356101408401525060018101908590859081811061282657fe5b60200291909101356101a08401525060018101908590859081811061284757fe5b60200291909101356101c084018190526101e084018390526003029091016001810191508590859081811061287857fe5b60200291909101356102008401525060018101908590859081811061289957fe5b6020029190910135610220840152506102408201819052610200820151016001810190859085908181106128c957fe5b6020029190910135610260840181905261028084018390526101808401519201916001141590506128f8576002015b8381146129365760405162461bcd60e51b81526004018080602001828103825260338152602001806140076033913960400191505060405180910390fd5b509392505050565b6001600160401b0154612998576040805162461bcd60e51b815260206004820152601c60248201527f474c4f42414c5f434f4e46494755524154494f4e5f4e4f545f53455400000000604482015290519081900360640190fd5b80516001600160401b0154146129f5576040805162461bcd60e51b815260206004820152601d60248201527f474c4f42414c5f434f4e46494755524154494f4e5f4d49534d41544348000000604482015290519081900360640190fd5b604081015160005b8260200151811015610c0a576000858584818110612a1757fe5b9050602002013590506000868660018601818110612a3157fe5b60008581526002600160401b016020908152604090912054910292909201359250508114612aa6576040805162461bcd60e51b815260206004820152601c60248201527f41535345545f434f4e46494755524154494f4e5f4d49534d4154434800000000604482015290519081900360640190fd5b5050600291909101906001016129fd565b600080848490509050600085856040516020018083836020028082843760408051601f199490920182810394909401825283815281516020928301208b518c840151848701929092528286018b905260608601529098016080808501919091528851808503909101815260a09093019097525080519501949094206001019450505050509392505050565b835484908381612bd05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612b95578181015183820152602001612b7d565b50505050905090810190601f168015612bc25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060005b8181101561165d57828181548110612be857fe5b6000918252602091829020015460408051636a93856760e01b8152600481018a905290516001600160a01b0390921692636a93856792602480840193829003018186803b158015612c3857600080fd5b505afa158015612c4c573d6000803e3d6000fd5b505050506040513d6020811015612c6257600080fd5b50518490612cb15760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612b95578181015183820152602001612b7d565b50600101612bd4565b60c083015160a0840151612cd391908101908688613f1c565b604051602001808383602002808284376040805191909301818103601f190182529092525080516020909101206003600160401b01555050600c8054600101905550600082828281612d2157fe5b90506020020135905080601d81905550612d3e8686868686613439565b612d4b86868686866135f6565b612d5686868661399d565b600c54604080519182526020820183905280517f2672b53d25204094519f7b0fba8d2b5cd0cc1e426f49554c89461cdb9dcec08f9281900390910190a1505050505050565b612da4336120ce565b612de7576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6000612df16131d5565b60018101549091506001600160a01b031615610cd0576001810180546001600160a01b03191690556040517f7a8dc7dd7fffb43c4807438fa62729225156941e641fd877938f4edade3429f590600090a150565b612e4e336120ce565b612e91576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6000612e9b6131d5565b90506001600160a01b038216612ee6576040805162461bcd60e51b815260206004820152600b60248201526a4241445f4144445245535360a81b604482015290519081900360640190fd5b612eef826120ce565b15612f34576040805162461bcd60e51b815260206004820152601060248201526f20a62922a0a22cafa3a7ab22a92727a960811b604482015290519081900360640190fd5b60018101546001600160a01b031615612f8e576040805162461bcd60e51b81526020600482015260176024820152764f544845525f43414e4449444154455f50454e44494e4760481b604482015290519081900360640190fd5b6001810180546001600160a01b0384166001600160a01b0319909116811790915560408051918252517f6166272c8d3f5f579082f2827532732f97195007983bb5b83ac12c56700b01a69181900360200190a15050565b612fee336120ce565b613031576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b336001600160a01b0382161415613086576040805162461bcd60e51b8152602060048201526014602482015273474f5645524e4f525f53454c465f52454d4f564560601b604482015290519081900360640190fd5b60006130906131d5565b905061309b826120ce565b6130db576040805162461bcd60e51b815260206004820152600c60248201526b2727aa2fa3a7ab22a92727a960a11b604482015290519081900360640190fd5b6001600160a01b03821660008181526020838152604091829020805460ff19169055815192835290517fd75f94825e770b8b512be8e74759e252ad00e102e38f50cce2f7c6f868a295999281900390910190a15050565b604080518082018252600c81526b464f524345445f545241444560a01b60208083019190915282519081018d90528083018c9052606081018b9052608081018a905260a0810189905260c0810188905260e08101879052610100810186905284151560f81b610120820152610121808201859052835180830390910181526101419091019092526000916131c69190613252565b9b9a5050505050505050505050565b600080604051806060016040528060268152602001613fe1602691396040518082805190602001908083835b602083106132205780518252601f199092019160209182019101613201565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209392505050565b600082826040516020018083805190602001908083835b602083106132885780518252601f199092019160209182019101613269565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106132d05780518252601f1990920191602091820191016132b1565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405280519060200120905092915050565b61331d816120ce565b15613362576040805162461bcd60e51b815260206004820152601060248201526f20a62922a0a22cafa3a7ab22a92727a960811b604482015290519081900360640190fd5b600061336c6131d5565b6001600160a01b03831660008181526020838152604091829020805460ff19166001179055815192835290519293507fcfb473e6c03f9a29ddaf990e736fa3de5188a0bd85d684f5b6e164ebfbfff5d292918290030190a15050565b6000806133d484611ef1565b90508083029150828183816133e557fe5b0414613432576040805162461bcd60e51b815260206004820152601760248201527644455155414e54495a4154494f4e5f4f564552464c4f5760481b604482015290519081900360640190fd5b5092915050565b600160401b54600167080000000000001160c01b018110613495576040805162461bcd60e51b81526020600482015260116024820152704173736574206964203e3d205052494d4560781b604482015290519081900360640190fd5b6101e084015160005b856101c001518110156135ec5760008888848181106134b957fe5b90506020020135905060008989600186018181106134d357fe5b90506020020135905060008a8a600287018181106134ed57fe5b905060200201359050600160411b8110613545576040805162461bcd60e51b815260206004820152601460248201527324b63632b3b0b6102130b630b731b2902234b33360611b604482015290519081900360640190fd5b67ffffffffffffffff198101600167080000000000001160c01b0184106135a8576040805162461bcd60e51b8152602060048201526012602482015271537461726b206b6579203e3d205052494d4560701b604482015290519081900360640190fd5b60008113156135c2576135bd84848984613acd565b6135d9565b60008112156135d9576135d9848883600003613b68565b505050600392909201915060010161349e565b5050505050505050565b6002811015613641576040805162461bcd60e51b815260206004820152601260248201527110541417d110551057d513d3d7d4d213d49560721b604482015290519081900360640190fd5b8261026001518282600281811061365457fe5b90506020020135146136a5576040805162461bcd60e51b815260206004820152601560248201527409cbe869e9c8892a8929e9ca6be9a92a69a82a8869605b1b604482015290519081900360640190fd5b6002836102600151026003018282905010156136fc576040805162461bcd60e51b81526020600482015260116024820152704241445f4150505f444154415f53495a4560781b604482015290519081900360640190fd5b610280830151600360005b8561026001518110156135ec57600085858481811061372257fe5b905060200201359050600086868560010181811061373c57fe5b9050602002013560001b905060008a8a8781811061375657fe5b9050602002013590506001600160fa1b03838360405160200180836001600160a01b031660601b8152601401828152602001925050506040516020818303038152906040528051906020012060001c1681146137ef576040805162461bcd60e51b815260206004820152601360248201527221b7b73234ba34b7b71036b4b9b6b0ba31b41760691b604482015290519081900360640190fd5b60408051602480820185905282518083039091018152604490910182526020810180516001600160e01b0316636a93856760e01b178152915181516000936060936001600160a01b038916939092909182918083835b602083106138645780518252601f199092019160209182019101613845565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146138c4576040519150601f19603f3d011682016040523d82523d6000602084013e6138c9565b606091505b50915091508180156138dc575080516020145b61392d576040805162461bcd60e51b815260206004820152601a60248201527f4241445f464143545f52454749535452595f434f4e5452414354000000000000604482015290519081900360640190fd5b80806020019051602081101561394257600080fd5b505161397f5760405162461bcd60e51b81526004018080602001828103825260338152602001806140aa6033913960400191505060405180910390fd5b60018801975060028701965050505050508080600101915050613707565b61024081015160005b826102200151811015613a765760008585848060010195508181106139c757fe5b9050602002013560018111156139d957fe5b905060008160018111156139e957fe5b1415613a01576139fa868685613b78565b9250613a6d565b6001816001811115613a0f57fe5b1415613a20576139fa868685613be6565b6040805162461bcd60e51b815260206004820152601a60248201527f554e4b4e4f574e5f464f524345445f414354494f4e5f54595045000000000000604482015290519081900360640190fd5b506001016139a6565b50808261020001518361024001510114613ac7576040805162461bcd60e51b815260206004820152600d60248201526c0a692b48abe9a92a69a82a8869609b1b604482015290519081900360640190fd5b50505050565b60008481526006602090815260408083208584528252808320868452909152902054811115613b3a576040805162461bcd60e51b815260206004820152601460248201527311115413d4d25517d25394d551919250d251539560621b604482015290519081900360640190fd5b6000938452600660209081526040808620938652928152828520938552929092529091208054919091039055565b613b738383836121ed565b505050565b600080848484806001019550818110613b8d57fe5b9050602002013590506000858585806001019650818110613baa57fe5b9050602002013590506000868686806001019750818110613bc757fe5b905060200201359050613bdb838383613d18565b509295945050505050565b600080848484806001019550818110613bfb57fe5b9050602002013590506000858585806001019650818110613c1857fe5b9050602002013590506000868686806001019750818110613c3557fe5b9050602002013590506000878787806001019850818110613c5257fe5b9050602002013590506000888888806001019950818110613c6f57fe5b9050602002013590506000898989806001019a50818110613c8c57fe5b90506020020135905060008a8a8a806001019b50818110613ca957fe5b90506020020135905060008b8b8b806001019c50818110613cc657fe5b9050602002013560001415905060008c8c8c806001019d50818110613ce757fe5b905060200201359050613d0789898989600160401b548a8a8a8a8a613d92565b50989b9a5050505050505050505050565b6000613d258484846120fd565b600081815260226020526040902054909150613d7e576040805162461bcd60e51b81526020600482015260136024820152722727a72fa2ac24a9aa24a723afa0a1aa24a7a760691b604482015290519081900360640190fd5b600090815260226020526040812055505050565b6000613da68b8b8b8b8b8b8b8b8b8b613132565b6000818152602260205260409020549091506000191415613e07576040805162461bcd60e51b81526020600482015260166024820152751050d51253d397d053149150511657d0d3115054915160521b604482015290519081900360640190fd5b600081815260226020526040902054613e5d576040805162461bcd60e51b81526020600482015260136024820152722727a72fa2ac24a9aa24a723afa0a1aa24a7a760691b604482015290519081900360640190fd5b6000908152602260205260409020600019905550505050505050505050565b604051806102a001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60008085851115613f2b578182fd5b83861115613f37578182fd5b505060208302019391909203915056fe70726f6772616d4f757470757420696e76616c69642073697a6520286e657753746174652970726f6772616d4f757470757420646f6573206e6f7420636f6e7461696e20616c6c207265717569726564206669656c64732e494e434f4e53495354454e545f504f534954494f4e5f545245455f484549474854434f4e46494755524154494f4e5f4e4f545f5245475349544552454400000000537461726b45782e4d61696e2e323031392e476f7665726e6f7273496e666f726d6174696f6e70726f6772616d4f757470757420696e76616c69642073697a6520286d6f64732f666f726365642f636f6e646974696f6e732970726f6772616d4f757470757420696e76616c69642073697a6520286e4173736574436f6e66696729554e535550504f525445445f444154415f415641494c4142494c4954595f4d4f444545787069726174696f6e2074696d657374616d70206973206f7574206f662072616e67652e436f6e646974696f6e20666f722074686520636f6e646974696f6e616c207472616e7366657220776173206e6f74206d65742e70726f6772616d4f757470757420696e76616c69642073697a65202870726576537461746529a2646970667358221220afeb13a8f6766dc158217bf653e1f163aad1111e5938b9c2809f946e26ac116c64736f6c634300060c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102895760003560e01c806380f235b01161015c578063b7663112116100ce578063e6de628211610087578063e6de62821461076c578063e9aa2d6b14610774578063eeb728661461077c578063f00cec4b14610784578063f2011f66146107dc578063fc86484a146107f957610289565b8063b7663112146106b2578063bb7c3d32146106ba578063c1a85130146106c2578063c23b60ef146106ca578063dd7202d814610747578063e30a5cff1461076457610289565b8063993f363911610120578063993f3639146106195780639bd4f229146106215780639f8a504414610644578063a1cc921e14610661578063ad54846714610687578063adac3e15146106aa57610289565b806380f235b0146105a057806381b47796146105bd5780638c4bce1c146105c55780638ed31439146105eb57806396115bc2146105f357610289565b806342af35fd116102005780635eecd218116101b95780635eecd218146105525780636d70f7ae1461055a57806372eb36881461058057806377e84e0d146105885780637cf12b90146105905780637e9da4c51461059857610289565b806342af35fd146103d3578063439fab91146103db57806345f5cd9714610449578063515535e81461046f578063538f9406146104775780635e586cd11461053557610289565b806328700a151161025257806328700a151461035057806333eeb14714610358578063366a2670146103745780633682a4501461039d5780633a8cc4fc146103c35780633cc660ad146103cb57610289565b80627175421461028e5780630dded952146102a85780630ebdac03146102b05780631829057714610308578063260e96dd14610327575b600080fd5b61029661081c565b60408051918252519081900360200190f35b610296610823565b6102b8610829565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102f45781810151838201526020016102dc565b505050509050019250505060405180910390f35b6103256004803603602081101561031e57600080fd5b50356108dd565b005b6102966004803603606081101561033d57600080fd5b50803590602081013590604001356109ef565b610325610a18565b610360610a22565b604080519115158252519081900360200190f35b6103256004803603606081101561038a57600080fd5b5080359060208101359060400135610a32565b610325600480360360208110156103b357600080fd5b50356001600160a01b0316610c11565b610296610cd3565b610296610cd9565b610296610cdf565b610325600480360360208110156103f157600080fd5b810190602081018135600160201b81111561040b57600080fd5b82018360208201111561041d57600080fd5b803590602001918460018302840111600160201b8311171561043e57600080fd5b509092509050610ce5565b6103606004803603602081101561045f57600080fd5b50356001600160a01b0316610fae565b610296610fc1565b6103256004803603604081101561048d57600080fd5b810190602081018135600160201b8111156104a757600080fd5b8201836020820111156104b957600080fd5b803590602001918460208302840111600160201b831117156104da57600080fd5b919390929091602081019035600160201b8111156104f757600080fd5b82018360208201111561050957600080fd5b803590602001918460208302840111600160201b8311171561052a57600080fd5b509092509050610fc7565b6102966004803603602081101561054b57600080fd5b5035611666565b6102966116d6565b6103606004803603602081101561057057600080fd5b50356001600160a01b03166116dc565b610325611709565b610296611711565b610325611718565b610296611857565b610325600480360360208110156105b657600080fd5b503561185d565b6102966119be565b610325600480360360208110156105db57600080fd5b50356001600160a01b03166119c4565b6102966119cd565b6103256004803603602081101561060957600080fd5b50356001600160a01b03166119d3565b610296611a95565b6103256004803603604081101561063757600080fd5b5080359060200135611a9d565b6103256004803603602081101561065a57600080fd5b5035611c10565b6103256004803603602081101561067757600080fd5b50356001600160a01b0316611d34565b6103256004803603604081101561069d57600080fd5b5080359060200135611d3d565b610296611eb0565b610296611ebc565b610296611ec3565b610296611ec9565b6106d2611ed5565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561070c5781810151838201526020016106f4565b50505050905090810190601f1680156107395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102966004803603602081101561075d57600080fd5b5035611ef1565b610296611f22565b610296611f27565b610296611f2c565b6106d2611f32565b610296600480360361014081101561079b57600080fd5b5080359060208101359060408101359060608101359060808101359060a08101359060c08101359060e0810135906101008101351515906101200135611f69565b610296600480360360208110156107f257600080fd5b5035611fa0565b6103256004803603604081101561080f57600080fd5b5080359060200135611fb8565b62093a8081565b600f5490565b60408051600180825281830190925260609190600090826020808301908036833750508151919450506001820191630366a26760e41b91859190811061086b57fe5b6001600160e01b0319909216602092830291909101909101528082146108d8576040805162461bcd60e51b815260206004820181905260248201527f494e434f52524543545f53454c4543544f52535f41525241595f4c454e475448604482015290519081900360640190fd5b505090565b6108e6336120ce565b610929576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b604080516000196020808301919091528183018490528251808303840181526060909201835281519181019190912060008181526023909252919020546109a5576040805162461bcd60e51b815260206004820152601c6024820152600080516020613fc1833981519152604482015290519081900360640190fd5b600081815260236020908152604080832092909255815184815291517f21e13101b7a52038b3abfab6f17d3a3d091c620b978b98c9de7f3aa91e7ac0639281900390910190a15050565b600060226000610a008686866120fd565b81526020019081526020016000205490509392505050565b610a20612169565b565b600454600160a01b900460ff1690565b610a3a610a22565b610a7e576040805162461bcd60e51b815260206004820152601060248201526f29aa20aa22afa727aa2fa32927ad22a760811b604482015290519081900360640190fd5b60008281526009602052604090205460ff1615610ad8576040805162461bcd60e51b81526020600482015260136024820152721154d0d0541157d053149150511657d554d151606a1b604482015290519081900360640190fd5b600082815260096020908152604091829020805460ff19166001908117909155600a805490910190556003600160401b01548251808301879052808401859052606081019190915260808082018690528351808303909101815260a08201808552815191840191909120600454636a93856760e01b90925260a4830181905293516001600160a01b03909116928392636a9385679260c48083019392829003018186803b158015610b8857600080fd5b505afa158015610b9c573d6000803e3d6000fd5b505050506040513d6020811015610bb257600080fd5b5051610bfa576040805162461bcd60e51b815260206004820152601260248201527122a9a1a0a822afa620a1a5a9afa82927a7a360711b604482015290519081900360640190fd5b610c0a85600160401b54856121ed565b5050505050565b610c1a336120ce565b610c5d576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b610c66816116dc565b610cd0576001610c7461240f565b6001600160a01b03831660008181526020928352604090819020805460ff191694151594909417909355825190815291517f50a18c352ee1c02ffe058e15c2eb6e58be387c81e73cc1e17035286e54c19a579281900390910190a15b50565b600d5490565b61018090565b600c5490565b6003600160401b015415610d3c576040805162461bcd60e51b815260206004820152601960248201527814d510551157d053149150511657d253925512505312569151603a1b604482015290519081900360640190fd5b6000196000526002600160401b016020527f2c5bd237f717a902f05528dc77f82cade6aa0a080972f06685282ae7786cdd4b5415610dbd576040805162461bcd60e51b815260206004820152601960248201527814d510551157d053149150511657d253925512505312569151603a1b604482015290519081900360640190fd5b6101808114610e13576040805162461bcd60e51b815260206004820152601c60248201527f494e434f52524543545f494e49545f444154415f53495a455f33383400000000604482015290519081900360640190fd5b600080606084846060811015610e2857600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610e5757600080fd5b820183602082011115610e6957600080fd5b803590602001918460208302840111600160201b83111715610e8a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250979a50959850909650610ed39550612414945050505050565b610edd6000612496565b610ee56124a1565b610f488260001983600081518110610ef957fe5b602002602001015184600281518110610f0e57fe5b602002602001015160001986600181518110610f2657fe5b602002602001015187600381518110610f3b57fe5b60200260200101516124ff565b8060405160200180828051906020019060200280838360005b83811015610f79578181015183820152602001610f61565b50505050905001915050604051602081830303815290604052805190602001206003600160401b0181905550610c0a8361251f565b6000610fb9826120ce565b90505b919050565b601d5490565b610fcf610a22565b15611013576040805162461bcd60e51b815260206004820152600f60248201526e29aa20aa22afa4a9afa32927ad22a760891b604482015290519081900360640190fd5b61101c336116dc565b61105d576040805162461bcd60e51b815260206004820152600d60248201526c27a7262cafa7a822a920aa27a960991b604482015290519081900360640190fd5b611065613e7c565b61106f8585612541565b9050602060020a816101a00151106110b85760405162461bcd60e51b81526004018080602001828103825260258152602001806140856025913960400191505060405180910390fd5b62093a8042038161016001511161110d576040805162461bcd60e51b815260206004820152601460248201527314d654d5115357d512535157d3d555111055115160621b604482015290519081900360640190fd5b613840420181610160015110611160576040805162461bcd60e51b815260206004820152601360248201527214d654d5115357d512535157d2539590531251606a1b604482015290519081900360640190fd5b610e104204816101a00151116111b7576040805162461bcd60e51b815260206004820152601760248201527610905510d217d512535154d510535417d1561412549151604a1b604482015290519081900360640190fd5b848460018360800151018181106111ca57fe5b90506020020135816101000151146112135760405162461bcd60e51b8152600401808060200182810382526021815260200180613fa06021913960400191505060405180910390fd5b8484600383608001510181811061122657fe5b9050602002013581610140015114611285576040805162461bcd60e51b815260206004820152601e60248201527f494e434f4e53495354454e545f4f524445525f545245455f4845494748540000604482015290519081900360640190fd5b61129085858361293e565b608081015160608201516000916112ab918101908789613f1c565b6040516020018083836020028082843780830192505050925050506040516020818303038152906040528051906020012090506003600160401b0154811461133a576040805162461bcd60e51b815260206004820152601d60248201527f494e56414c49445f50524556494f55535f5348415245445f5354415445000000604482015290519081900360640190fd5b601d548484600181811061134a57fe5b905060200201351461139d576040805162461bcd60e51b815260206004820152601760248201527615d493d391d7d41491559253d554d7d0905510d217d251604a1b604482015290519081900360640190fd5b60008083610180015114156113e65786866040516020018083836020028082843780830192505050925050506040516020818303038152906040528051906020012090506114d0565b60018361018001511461142a5760405162461bcd60e51b81526004018080602001828103825260228152602001806140636022913960400191505060405180910390fd5b6102408301516002018610156114715760405162461bcd60e51b8152600401808060200182810382526033815260200180613f6d6033913960400191505060405180910390fd5b6114cd61148560011988016000898b613f1c565b60408051808201909152808b8b60011981018181106114a057fe5b9050602002013581526020018b8b60018e8e9050038181106114be57fe5b90506020020135815250612ab7565b90505b6040805182815290517f9866f8ddfe70bb512b2f2b28b49d4017c43f7ba775f1a20c61c13eea8cdac1119181900360200190a16115766019826040518060400160405280601d81526020017f4e4f5f53544154455f5452414e534954494f4e5f564552494649455253000000815250604051806040016040528060198152602001782727afa9aa20aa22afaa2920a729a4aa24a7a72fa82927a7a360391b815250612b42565b6101808301516116505760008360e00151846101000151856101200151866101400151600c54600101604051602001808681526020018581526020018481526020018381526020018281526020019550505050505060405160208183030381529060405280519060200120905061164e601b82604051806040016040528060198152602001784e4f5f415641494c4142494c4954595f56455249464945525360381b815250604051806040016040528060158152602001742727afa0ab20a4a620a124a624aa2cafa82927a7a360591b815250612b42565b505b61165d8787858888612cba565b50505050505050565b60245460009082106116b7576040805162461bcd60e51b815260206004820152601560248201527408286a8929e9cbe929c888ab0bea89e9ebe90928e9605b1b604482015290519081900360640190fd5b602482815481106116c457fe5b90600052602060002001549050919050565b60245490565b60006116e661240f565b6001600160a01b0392909216600090815260209290925250604090205460ff1690565b610a20612d9b565b6202a30081565b611720610a22565b611764576040805162461bcd60e51b815260206004820152601060248201526f29aa20aa22afa727aa2fa32927ad22a760811b604482015290519081900360640190fd5b61176d336120ce565b6117b0576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b600554421015611802576040805162461bcd60e51b8152602060048201526018602482015277155391949151569157d393d517d0531313d5d15117d6515560421b604482015290519081900360640190fd5b6004805460ff60a01b19169055600d805460019081019091556025805482019055600f805490910190556040517f07017fe9180629cfffba412f65a9affcf9a121de02294179f5c058f881dcc9f890600090a1565b60105490565b611866336120ce565b6118a9576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6040805160001960208083019190915281830184905282518083038401815260609092018352815191810191909120600081815260239092529190205480611926576040805162461bcd60e51b815260206004820152601c6024820152600080516020613fc1833981519152604482015290519081900360640190fd5b4281111561197b576040805162461bcd60e51b815260206004820152601c60248201527f434f4e46494755524154494f4e5f4e4f545f454e41424c455f59455400000000604482015290519081900360640190fd5b6001600160401b018390556040805184815290517f215e2cbb35cc7dd3f085fdb4ede08d32f4619001c73f5b10419389e7949c28ba9181900360200190a1505050565b60265490565b610cd081612e45565b60255490565b6119dc336120ce565b611a1f576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b611a28816116dc565b15610cd0576000611a3761240f565b6001600160a01b03831660008181526020928352604090819020805460ff191694151594909417909355825190815291517fec5f6c3a91a1efb1f9a308bb33c6e9e66bf9090fad0732f127dfdbf516d0625d9281900390910190a150565b6301e1338081565b611aa6336120ce565b611ae9576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b60408051602080820185905281830184905282518083038401815260609092018352815191810191909120600081815260239092529190205480611b62576040805162461bcd60e51b815260206004820152601c6024820152600080516020613fc1833981519152604482015290519081900360640190fd5b42811115611bb7576040805162461bcd60e51b815260206004820152601c60248201527f434f4e46494755524154494f4e5f4e4f545f454e41424c455f59455400000000604482015290519081900360640190fd5b60008481526002600160401b016020908152604091829020859055815186815290810185905281517f617a24590fcf7d5a2650aa9c10572915cb4bf853b1ef135cc1918460946a7a2f929181900390910190a150505050565b611c19336120ce565b611c5c576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b600167080000000000001160c01b018110611cb4576040805162461bcd60e51b81526020600482015260136024820152720929cac82989288be869e9c8c928ebe9082a69606b1b604482015290519081900360640190fd5b60408051600019602080830191909152818301849052825180830384018152606083018085528151918301919091206004600160401b015460008281526023909452928590204290930190925584905291517ffae91148d75f3789f216345abe08b5415e0e727d51cab9f4e41efc23f71193f79181900360800190a15050565b610cd081612fe5565b611d46336120ce565b611d89576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b600160781b8210611dd4576040805162461bcd60e51b815260206004820152601060248201526f1253959053125117d054d4d15517d25160821b604482015290519081900360640190fd5b600167080000000000001160c01b018110611e2c576040805162461bcd60e51b81526020600482015260136024820152720929cac82989288be869e9c8c928ebe9082a69606b1b604482015290519081900360640190fd5b604080516020808201859052818301849052825180830384018152606083018085528151918301919091206004600160401b01546000828152602390945292859020429093019092558590526080820184905291517ffbe49fc520438bdf956c8964ba0394d2da4fa3f34686e826a2ded762fa687c2d9181900360a00190a1505050565b6001600160401b015481565b6224ea0081565b600e5490565b6004600160401b015481565b604051806060016040528060268152602001613fe16026913981565b60008181526015602052604081205460ff16611f0f57506001610fbc565b5060009081526016602052604090205490565b600a81565b604081565b60275490565b60408051808201909152601f81527f537461726b576172655f50657270657475616c53746174655f323032325f3300602082015290565b600060226000611f818d8d8d8d8d8d8d8d8d8d613132565b81526020019081526020016000205490509a9950505050505050505050565b6002600160401b016020526000908152604090205481565b611fc1336120ce565b612004576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b60408051602080820185905281830184905282518083038401815260609092018352815191810191909120600081815260239092529190205461207c576040805162461bcd60e51b815260206004820152601c6024820152600080516020613fc1833981519152604482015290519081900360640190fd5b600081815260236020908152604080832092909255815185815290810184905281517fbedb78be82c75282d73923c8287b6b3e3ef57379cdc69f7fbd3d227a9969b48e929181900390910190a1505050565b6000806120d96131d5565b6001600160a01b039390931660009081526020939093525050604090205460ff1690565b6000612161604051806040016040528060118152602001701193d490d15117d5d2551211149055d053607a1b815250858585604051602001808481526020018381526020018281526020019350505050604051602081830303815290604052613252565b949350505050565b60006121736131d5565b60018101549091506001600160a01b031633146121d1576040805162461bcd60e51b815260206004820152601760248201527627a7262cafa1a0a72224a220aa22afa3a7ab22a92727a960491b604482015290519081900360640190fd5b6121da33613314565b60010180546001600160a01b0319169055565b6000838152600860209081526040808320858452909152902054810181811015612254576040805162461bcd60e51b81526020600482015260136024820152725749544844524157414c5f4f564552464c4f5760681b604482015290519081900360640190fd5b600084815260086020908152604080832086845282528083208490556015909152902054839060ff16156122d8577f03c10a82c955f7bcd0c934147fb39cafca947a4294425b1751d884c8ac95428785826122af84876133c8565b6040805193845260208401929092528282015260608201869052519081900360800190a1610c0a565b600160fa1b6001600160f01b0385161784141561233457604080518681526020810186905280820185905290517f2acce0cedb29dc4927e6c891b57ef5bc8858eea4bf52787ea94873aebd4aeca09181900360600190a1610c0a565b6001600160fa1b0384168414612384576040805162461bcd60e51b815260206004820152601060248201526f1253959053125117d054d4d15517d25160821b604482015290519081900360640190fd5b600182116123c857604080518681526020810186905281517ff07608f26256bce78d87220cfc0e7b1cc69b48e55104bfa591b2818161386627929181900390910190a15b604080518681526020810186905280820185905290517fd31f59c968eb53320f624721416cf88605da9aadbaa723405e52affe9de4b07f9181900360600190a15050505050565b601390565b600061241e6131d5565b6001810154909150600160a01b900460ff1615612478576040805162461bcd60e51b81526020600482015260136024820152721053149150511657d253925512505312569151606a1b604482015290519081900360640190fd5b60018101805460ff60a01b1916600160a01b179055610cd033613314565b6004600160401b0155565b60016124ab61240f565b3360008181526020928352604090819020805460ff191694151594909417909355825190815291517f50a18c352ee1c02ffe058e15c2eb6e58be387c81e73cc1e17035286e54c19a579281900390910190a1565b600c96909655600d94909455602592909255600f55600e55602655601055565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b612549613e7c565b60098210156125895760405162461bcd60e51b8152600401808060200182810382526033815260200180613f6d6033913960400191505060405180910390fd5b612591613e7c565b8383600081811061259e57fe5b6020029190910135825250838360018181106125b657fe5b602002919091013561018083015250838360028181106125d257fe5b60209081029290920135918301829052506201000011612634576040805162461bcd60e51b8152602060048201526018602482015277494c4c4547414c5f4e554d4245525f4f465f41535345545360401b604482015290519081900360640190fd5b60036040820181905260208201516002029081019060040184101561268a5760405162461bcd60e51b815260040180806020018281038252602981526020018061403a6029913960400191505060405180910390fd5b84848280600101935081811061269c57fe5b60200291909101356060840181905260808401839052919091019050600181018410156126fa5760405162461bcd60e51b81526004018080602001828103825260268152602001806140dd6026913960400191505060405180910390fd5b84848280600101935081811061270c57fe5b602002919091013560a0840181905260c084018390529190910190506002810184101561276a5760405162461bcd60e51b8152600401808060200182810382526025815260200180613f486025913960400191505060405180910390fd5b84846001830381811061277957fe5b60200291909101356101608401525060c08201518590859081811061279a57fe5b905060200201358260e0018181525050848460018460c00151018181106127bd57fe5b9050602002013582610100018181525050848460028460c00151018181106127e157fe5b9050602002013582610120018181525050848460038460c001510181811061280557fe5b60200291909101356101408401525060018101908590859081811061282657fe5b60200291909101356101a08401525060018101908590859081811061284757fe5b60200291909101356101c084018190526101e084018390526003029091016001810191508590859081811061287857fe5b60200291909101356102008401525060018101908590859081811061289957fe5b6020029190910135610220840152506102408201819052610200820151016001810190859085908181106128c957fe5b6020029190910135610260840181905261028084018390526101808401519201916001141590506128f8576002015b8381146129365760405162461bcd60e51b81526004018080602001828103825260338152602001806140076033913960400191505060405180910390fd5b509392505050565b6001600160401b0154612998576040805162461bcd60e51b815260206004820152601c60248201527f474c4f42414c5f434f4e46494755524154494f4e5f4e4f545f53455400000000604482015290519081900360640190fd5b80516001600160401b0154146129f5576040805162461bcd60e51b815260206004820152601d60248201527f474c4f42414c5f434f4e46494755524154494f4e5f4d49534d41544348000000604482015290519081900360640190fd5b604081015160005b8260200151811015610c0a576000858584818110612a1757fe5b9050602002013590506000868660018601818110612a3157fe5b60008581526002600160401b016020908152604090912054910292909201359250508114612aa6576040805162461bcd60e51b815260206004820152601c60248201527f41535345545f434f4e46494755524154494f4e5f4d49534d4154434800000000604482015290519081900360640190fd5b5050600291909101906001016129fd565b600080848490509050600085856040516020018083836020028082843760408051601f199490920182810394909401825283815281516020928301208b518c840151848701929092528286018b905260608601529098016080808501919091528851808503909101815260a09093019097525080519501949094206001019450505050509392505050565b835484908381612bd05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612b95578181015183820152602001612b7d565b50505050905090810190601f168015612bc25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060005b8181101561165d57828181548110612be857fe5b6000918252602091829020015460408051636a93856760e01b8152600481018a905290516001600160a01b0390921692636a93856792602480840193829003018186803b158015612c3857600080fd5b505afa158015612c4c573d6000803e3d6000fd5b505050506040513d6020811015612c6257600080fd5b50518490612cb15760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612b95578181015183820152602001612b7d565b50600101612bd4565b60c083015160a0840151612cd391908101908688613f1c565b604051602001808383602002808284376040805191909301818103601f190182529092525080516020909101206003600160401b01555050600c8054600101905550600082828281612d2157fe5b90506020020135905080601d81905550612d3e8686868686613439565b612d4b86868686866135f6565b612d5686868661399d565b600c54604080519182526020820183905280517f2672b53d25204094519f7b0fba8d2b5cd0cc1e426f49554c89461cdb9dcec08f9281900390910190a1505050505050565b612da4336120ce565b612de7576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6000612df16131d5565b60018101549091506001600160a01b031615610cd0576001810180546001600160a01b03191690556040517f7a8dc7dd7fffb43c4807438fa62729225156941e641fd877938f4edade3429f590600090a150565b612e4e336120ce565b612e91576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6000612e9b6131d5565b90506001600160a01b038216612ee6576040805162461bcd60e51b815260206004820152600b60248201526a4241445f4144445245535360a81b604482015290519081900360640190fd5b612eef826120ce565b15612f34576040805162461bcd60e51b815260206004820152601060248201526f20a62922a0a22cafa3a7ab22a92727a960811b604482015290519081900360640190fd5b60018101546001600160a01b031615612f8e576040805162461bcd60e51b81526020600482015260176024820152764f544845525f43414e4449444154455f50454e44494e4760481b604482015290519081900360640190fd5b6001810180546001600160a01b0384166001600160a01b0319909116811790915560408051918252517f6166272c8d3f5f579082f2827532732f97195007983bb5b83ac12c56700b01a69181900360200190a15050565b612fee336120ce565b613031576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b336001600160a01b0382161415613086576040805162461bcd60e51b8152602060048201526014602482015273474f5645524e4f525f53454c465f52454d4f564560601b604482015290519081900360640190fd5b60006130906131d5565b905061309b826120ce565b6130db576040805162461bcd60e51b815260206004820152600c60248201526b2727aa2fa3a7ab22a92727a960a11b604482015290519081900360640190fd5b6001600160a01b03821660008181526020838152604091829020805460ff19169055815192835290517fd75f94825e770b8b512be8e74759e252ad00e102e38f50cce2f7c6f868a295999281900390910190a15050565b604080518082018252600c81526b464f524345445f545241444560a01b60208083019190915282519081018d90528083018c9052606081018b9052608081018a905260a0810189905260c0810188905260e08101879052610100810186905284151560f81b610120820152610121808201859052835180830390910181526101419091019092526000916131c69190613252565b9b9a5050505050505050505050565b600080604051806060016040528060268152602001613fe1602691396040518082805190602001908083835b602083106132205780518252601f199092019160209182019101613201565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209392505050565b600082826040516020018083805190602001908083835b602083106132885780518252601f199092019160209182019101613269565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106132d05780518252601f1990920191602091820191016132b1565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405280519060200120905092915050565b61331d816120ce565b15613362576040805162461bcd60e51b815260206004820152601060248201526f20a62922a0a22cafa3a7ab22a92727a960811b604482015290519081900360640190fd5b600061336c6131d5565b6001600160a01b03831660008181526020838152604091829020805460ff19166001179055815192835290519293507fcfb473e6c03f9a29ddaf990e736fa3de5188a0bd85d684f5b6e164ebfbfff5d292918290030190a15050565b6000806133d484611ef1565b90508083029150828183816133e557fe5b0414613432576040805162461bcd60e51b815260206004820152601760248201527644455155414e54495a4154494f4e5f4f564552464c4f5760481b604482015290519081900360640190fd5b5092915050565b600160401b54600167080000000000001160c01b018110613495576040805162461bcd60e51b81526020600482015260116024820152704173736574206964203e3d205052494d4560781b604482015290519081900360640190fd5b6101e084015160005b856101c001518110156135ec5760008888848181106134b957fe5b90506020020135905060008989600186018181106134d357fe5b90506020020135905060008a8a600287018181106134ed57fe5b905060200201359050600160411b8110613545576040805162461bcd60e51b815260206004820152601460248201527324b63632b3b0b6102130b630b731b2902234b33360611b604482015290519081900360640190fd5b67ffffffffffffffff198101600167080000000000001160c01b0184106135a8576040805162461bcd60e51b8152602060048201526012602482015271537461726b206b6579203e3d205052494d4560701b604482015290519081900360640190fd5b60008113156135c2576135bd84848984613acd565b6135d9565b60008112156135d9576135d9848883600003613b68565b505050600392909201915060010161349e565b5050505050505050565b6002811015613641576040805162461bcd60e51b815260206004820152601260248201527110541417d110551057d513d3d7d4d213d49560721b604482015290519081900360640190fd5b8261026001518282600281811061365457fe5b90506020020135146136a5576040805162461bcd60e51b815260206004820152601560248201527409cbe869e9c8892a8929e9ca6be9a92a69a82a8869605b1b604482015290519081900360640190fd5b6002836102600151026003018282905010156136fc576040805162461bcd60e51b81526020600482015260116024820152704241445f4150505f444154415f53495a4560781b604482015290519081900360640190fd5b610280830151600360005b8561026001518110156135ec57600085858481811061372257fe5b905060200201359050600086868560010181811061373c57fe5b9050602002013560001b905060008a8a8781811061375657fe5b9050602002013590506001600160fa1b03838360405160200180836001600160a01b031660601b8152601401828152602001925050506040516020818303038152906040528051906020012060001c1681146137ef576040805162461bcd60e51b815260206004820152601360248201527221b7b73234ba34b7b71036b4b9b6b0ba31b41760691b604482015290519081900360640190fd5b60408051602480820185905282518083039091018152604490910182526020810180516001600160e01b0316636a93856760e01b178152915181516000936060936001600160a01b038916939092909182918083835b602083106138645780518252601f199092019160209182019101613845565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146138c4576040519150601f19603f3d011682016040523d82523d6000602084013e6138c9565b606091505b50915091508180156138dc575080516020145b61392d576040805162461bcd60e51b815260206004820152601a60248201527f4241445f464143545f52454749535452595f434f4e5452414354000000000000604482015290519081900360640190fd5b80806020019051602081101561394257600080fd5b505161397f5760405162461bcd60e51b81526004018080602001828103825260338152602001806140aa6033913960400191505060405180910390fd5b60018801975060028701965050505050508080600101915050613707565b61024081015160005b826102200151811015613a765760008585848060010195508181106139c757fe5b9050602002013560018111156139d957fe5b905060008160018111156139e957fe5b1415613a01576139fa868685613b78565b9250613a6d565b6001816001811115613a0f57fe5b1415613a20576139fa868685613be6565b6040805162461bcd60e51b815260206004820152601a60248201527f554e4b4e4f574e5f464f524345445f414354494f4e5f54595045000000000000604482015290519081900360640190fd5b506001016139a6565b50808261020001518361024001510114613ac7576040805162461bcd60e51b815260206004820152600d60248201526c0a692b48abe9a92a69a82a8869609b1b604482015290519081900360640190fd5b50505050565b60008481526006602090815260408083208584528252808320868452909152902054811115613b3a576040805162461bcd60e51b815260206004820152601460248201527311115413d4d25517d25394d551919250d251539560621b604482015290519081900360640190fd5b6000938452600660209081526040808620938652928152828520938552929092529091208054919091039055565b613b738383836121ed565b505050565b600080848484806001019550818110613b8d57fe5b9050602002013590506000858585806001019650818110613baa57fe5b9050602002013590506000868686806001019750818110613bc757fe5b905060200201359050613bdb838383613d18565b509295945050505050565b600080848484806001019550818110613bfb57fe5b9050602002013590506000858585806001019650818110613c1857fe5b9050602002013590506000868686806001019750818110613c3557fe5b9050602002013590506000878787806001019850818110613c5257fe5b9050602002013590506000888888806001019950818110613c6f57fe5b9050602002013590506000898989806001019a50818110613c8c57fe5b90506020020135905060008a8a8a806001019b50818110613ca957fe5b90506020020135905060008b8b8b806001019c50818110613cc657fe5b9050602002013560001415905060008c8c8c806001019d50818110613ce757fe5b905060200201359050613d0789898989600160401b548a8a8a8a8a613d92565b50989b9a5050505050505050505050565b6000613d258484846120fd565b600081815260226020526040902054909150613d7e576040805162461bcd60e51b81526020600482015260136024820152722727a72fa2ac24a9aa24a723afa0a1aa24a7a760691b604482015290519081900360640190fd5b600090815260226020526040812055505050565b6000613da68b8b8b8b8b8b8b8b8b8b613132565b6000818152602260205260409020549091506000191415613e07576040805162461bcd60e51b81526020600482015260166024820152751050d51253d397d053149150511657d0d3115054915160521b604482015290519081900360640190fd5b600081815260226020526040902054613e5d576040805162461bcd60e51b81526020600482015260136024820152722727a72fa2ac24a9aa24a723afa0a1aa24a7a760691b604482015290519081900360640190fd5b6000908152602260205260409020600019905550505050505050505050565b604051806102a001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60008085851115613f2b578182fd5b83861115613f37578182fd5b505060208302019391909203915056fe70726f6772616d4f757470757420696e76616c69642073697a6520286e657753746174652970726f6772616d4f757470757420646f6573206e6f7420636f6e7461696e20616c6c207265717569726564206669656c64732e494e434f4e53495354454e545f504f534954494f4e5f545245455f484549474854434f4e46494755524154494f4e5f4e4f545f5245475349544552454400000000537461726b45782e4d61696e2e323031392e476f7665726e6f7273496e666f726d6174696f6e70726f6772616d4f757470757420696e76616c69642073697a6520286d6f64732f666f726365642f636f6e646974696f6e732970726f6772616d4f757470757420696e76616c69642073697a6520286e4173736574436f6e66696729554e535550504f525445445f444154415f415641494c4142494c4954595f4d4f444545787069726174696f6e2074696d657374616d70206973206f7574206f662072616e67652e436f6e646974696f6e20666f722074686520636f6e646974696f6e616c207472616e7366657220776173206e6f74206d65742e70726f6772616d4f757470757420696e76616c69642073697a65202870726576537461746529a2646970667358221220afeb13a8f6766dc158217bf653e1f163aad1111e5938b9c2809f946e26ac116c64736f6c634300060c0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.