Transaction Hash:
Block:
12351094 at May-01-2021 10:38:27 PM +UTC
Transaction Fee:
0.00176514 ETH
$7.54
Gas Used:
67,890 Gas / 26 Gwei
Emitted Events:
321 |
Proxy.0xcab1cf17c190e4e2195a7b8f7b362023246fa774390432b4704ab6b29d56b07b( 0xcab1cf17c190e4e2195a7b8f7b362023246fa774390432b4704ab6b29d56b07b, 00000000000000000000000007916fd6e30d4ee7bc12d0e525046eca0d854500, 03b906f5366beb2efd5c45aefb845b897d225be90964fc404321cecf93a91f5c, 00000000000000000000000007916fd6e30d4ee7bc12d0e525046eca0d854500 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x07916fD6...a0d854500 |
0.001981053999999997 Eth
Nonce: 21
|
0.000215913999999997 Eth
Nonce: 22
| 0.00176514 | ||
0x5A0b54D5...D3E029c4c
Miner
| (Spark Pool) | 28.925223471851291704 Eth | 28.926988611851291704 Eth | 0.00176514 | |
0xD54f502e...c462D69c8 | (dYdX: L2 Perpetual Smart Contract) |
Execution Trace
Proxy.dd2414d4( )
StarkPerpetual.dd2414d4( )
PerpetualTokensAndRamping.registerUser( ethKey=0x07916fD6e30d4ee7Bc12D0E525046eca0d854500, starkKey=1683853274130073383792247724466369769697877915027028533114227619624563318620, signature=0x2C6A0FD058247DC6BAFECE8D18848EA3CC6AB7144ADA31F9E703F2EB7B15D87D1C6417B48589545CB08CEFA7D00A5486000A07E9B8F11FF91811C157DF966D8A1C )
-
Null: 0x000...005.00000000( )
-
Null: 0x000...001.f19fa407( )
-
File 1 of 3: Proxy
File 2 of 3: StarkPerpetual
File 3 of 3: PerpetualTokensAndRamping
1{"Common.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\nYou may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governingpermissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/*\n Common Utilitylibrarries.\n I. Addresses (extending address).\n*/\nlibrary Addresses {\n function isContract(address account) internal view returns (bool){\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size \u003e 0;\n }\n\nfunction performEthTransfer(address recipient, uint256 amount) internal {\n (bool success, ) = recipient.call{value: amount}(\"\"); //NOLINT: low-level-calls.\n require(success, \"ETH_TRANSFER_FAILED\");\n }\n\n /*\n Safe wrapper around ERC20/ERC721 calls.\nThis is required because many deployed ERC20 contracts don\u0027t return a value.\n See https://github.com/ethereum/solidity/issues/4116.\n*/\n function safeTokenContractCall(address tokenAddress, bytes memory callData) internal {\n require(isContract(tokenAddress),\"BAD_TOKEN_ADDRESS\");\n // NOLINTNEXTLINE: low-level-calls.\n (bool success, bytes memory returndata) = tokenAddress.call(callData);\n require(success, string(returndata));\n\n if (returndata.length \u003e 0) {\n require(abi.decode(returndata, (bool)),\"TOKEN_OPERATION_FAILED\");\n }\n }\n\n /*\n Similar to safeTokenContractCall, but always ignores the return value.\n\nAssumes some other method is used to detect the failures\n (e.g. balance is checked before and after the call).\n */\n functionuncheckedTokenContractCall(address tokenAddress, bytes memory callData) internal {\n // NOLINTNEXTLINE: low-level-calls.\n (boolsuccess, bytes memory returndata) = tokenAddress.call(callData);\n require(success, string(returndata));\n }\n\n}\n\nlibrary UintArray{\n function hashSubArray(uint256[] memory array, uint256 subArrayStart, uint256 subArraySize)\n internal pure\n returns(bytes32subArrayHash)\n {\n require(array.length \u003e= subArrayStart + subArraySize, \"ILLEGAL_SUBARRAY_DIMENSIONS\");\n uint256startOffsetBytes = 0x20 * (1 + subArrayStart);\n uint256 dataSizeBytes = 0x20 * subArraySize;\n assembly {\n subArrayHash:= keccak256(add(array, startOffsetBytes), dataSizeBytes)\n }\n }\n\n /*\n Returns the address of a cell in offset within auint256[] array.\n This allows assigning new variable of dynamic unit256[] pointing to a sub_array\n with a layout of serialied uint256[](i.e. length+content).\n */\n function extractSerializedUintArray(uint256[] memory programOutput, uint256 offset)\n internal pure\nreturns (uint256[] memory addr)\n {\n uint256 memOffset = 0x20 * (offset + 1);\n assembly {\n addr := add(programOutput, memOffset)\n }\n }\n\n}\n\n/*\n II. StarkExTypes - Common data types.\n*/\nlibrary StarkExTypes {\n\n // Structurerepresenting a list of verifiers (validity/availability).\n // A statement is valid only if all the verifiers in the list agree on it.\n //Adding a verifier to the list is immediate - this is used for fast resolution of\n // any soundness issues.\n // Removing from the list istime-locked, to ensure that any user of the system\n // not content with the announced removal has ample time to leave the system before it is\n// removed.\n struct ApprovalChainData {\n address[] list;\n // Represents the time after which the verifier with the givenaddress can be removed.\n // Removal of the verifier with address A is allowed only in the case the value\n // ofunlockedForRemovalTime[A] != 0 and unlockedForRemovalTime[A] \u003c (current time).\n mapping (address =\u003e uint256)unlockedForRemovalTime;\n }\n}\n"},"Governance.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under theApache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of theLicense at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n softwaredistributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"GovernanceStorage.sol\";\nimport \"MGovernance.sol\";\n\n/*\n Implements Generic Governance, applicablefor both proxy and main contract, and possibly others.\n Notes:\n 1. This class is virtual (getGovernanceTag is not implemented).\n 2. The useof the same function names by both the Proxy and a delegated implementation\n is not possible since calling the implementation functions isdone via the default function\n of the Proxy. For this reason, for example, the implementation of MainContract (MainGovernance)\n exposesmainIsGovernor, which calls the internal isGovernor method.\n*/\nabstract contract Governance is GovernanceStorage, MGovernance {\n eventLogNominatedGovernor(address nominatedGovernor);\n event LogNewGovernorAccepted(address acceptedGovernor);\n event LogRemovedGovernor(addressremovedGovernor);\n event LogNominationCancelled();\n\n /*\n Returns a string which uniquely identifies the type of the governancemechanism.\n */\n function getGovernanceTag()\n virtual\n internal\n pure\n returns (string memory);\n\n /*\nReturns the GovernanceInfoStruct associated with the governance tag.\n */\n function contractGovernanceInfo()\n internal\nview\n returns (GovernanceInfoStruct storage) {\n string memory tag = getGovernanceTag();\n GovernanceInfoStruct storage gub= governanceInfo[tag];\n require(gub.initialized, \"NOT_INITIALIZED\");\n return gub;\n }\n\n /*\n Current codeintentionally prevents governance re-initialization.\n This may be a problem in an upgrade situation, in a case that the upgrade-toimplementation\n performs an initialization (for real) and within that calls initGovernance().\n\n Possible workarounds:\n 1.Clearing the governance info altogether by changing the MAIN_GOVERNANCE_INFO_TAG.\n This will remove existing main governance information.\n 2. Modify the require part in this function, so that it will exit quietly\n when trying to re-initialize (uncomment the linesbelow).\n */\n function initGovernance()\n internal\n {\n string memory tag = getGovernanceTag();\nGovernanceInfoStruct storage gub = governanceInfo[tag];\n require(!gub.initialized, \"ALREADY_INITIALIZED\");\n gub.initialized =true; // to ensure addGovernor() won\u0027t fail.\n // Add the initial governer.\n addGovernor(msg.sender);\n }\n\n modifieronlyGovernance () override\n {\n require(isGovernor(msg.sender), \"ONLY_GOVERNANCE\");\n _;\n }\n\n function isGovernor(address testGovernor)\n internal view\n returns (bool addressIsGovernor){\n GovernanceInfoStruct storage gub =contractGovernanceInfo();\n addressIsGovernor = gub.effectiveGovernors[testGovernor];\n }\n\n /*\n Cancels the nomination of agovernor candidate.\n */\n function cancelNomination() internal onlyGovernance() {\n GovernanceInfoStruct storage gub =contractGovernanceInfo();\n gub.candidateGovernor = address(0x0);\n emit LogNominationCancelled();\n }\n\n functionnominateNewGovernor(address newGovernor) internal onlyGovernance() {\n GovernanceInfoStruct storage gub = contractGovernanceInfo();\nrequire(!isGovernor(newGovernor), \"ALREADY_GOVERNOR\");\n gub.candidateGovernor = newGovernor;\n emit LogNominatedGovernor(newGovernor);\n }\n\n /*\n The addGovernor is called in two cases:\n 1. by acceptGovernance when a new governor accepts its role.\n 2. by initGovernance to add the initial governor.\n The difference is that the init path skips the nominate step\n that wouldfail because of the onlyGovernance modifier.\n */\n function addGovernor(address newGovernor) private {\n require(!isGovernor(newGovernor), \"ALREADY_GOVERNOR\");\n GovernanceInfoStruct storage gub = contractGovernanceInfo();\n gub.effectiveGovernors[newGovernor] = true;\n }\n\n function acceptGovernance()\n internal\n {\n // The new governor wasproposed as a candidate by the current governor.\n GovernanceInfoStruct storage gub = contractGovernanceInfo();\n require(msg.sender== gub.candidateGovernor, \"ONLY_CANDIDATE_GOVERNOR\");\n\n // Update state.\n addGovernor(gub.candidateGovernor);\n gub.candidateGovernor = address(0x0);\n\n // Send a notification about the change of governor.\n emit LogNewGovernorAccepted(msg.sender);\n }\n\n /*\n Remove a governor from office.\n */\n function removeGovernor(address governorForRemoval) internal onlyGovernance() {\n require(msg.sender != governorForRemoval, \"GOVERNOR_SELF_REMOVE\");\n GovernanceInfoStruct storage gub =contractGovernanceInfo();\n require (isGovernor(governorForRemoval), \"NOT_GOVERNOR\");\n gub.effectiveGovernors[governorForRemoval]= false;\n emit LogRemovedGovernor(governorForRemoval);\n }\n}\n"},"GovernanceStorage.sol":{"content":"/*\n Copyright 2019,2020StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliancewith the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicablelaw or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OFANY KIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/*\n Holds the governance slots for ALL entities, including proxy and themain contract.\n*/\ncontract GovernanceStorage {\n\n struct GovernanceInfoStruct {\n mapping (address =\u003e bool) effectiveGovernors;\naddress candidateGovernor;\n bool initialized;\n }\n\n // A map from a Governor tag to its own GovernanceInfoStruct.\nmapping (string =\u003e GovernanceInfoStruct) internal governanceInfo;\n}\n"},"MGovernance.sol":{"content":"/*\n Copyright 2019,2020 StarkWareIndustries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with theLicense.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law oragreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n//SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nabstract contract MGovernance {\n /*\n Allows calling the function onlyby a Governor.\n */\n modifier onlyGovernance () virtual; // NOLINT incorrect-modifier.\n}\n"},"Proxy.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except incompliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required byapplicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under theLicense.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"ProxyGovernance.sol\";\nimport \"ProxyStorage.sol\";\nimport \"StorageSlots.sol\";\nimport \"Common.sol\";\n\n/**\n The Proxy contract implements delegation of calls to other contracts(`implementations`), with\n proper forwarding of return values and revert reasons. This pattern allows retaining the contract\n storage whilereplacing implementation code.\n\n The following operations are supported by the proxy contract:\n\n - :sol:func:`addImplementation`: Defines anew implementation, the data with which it should be initialized and whether this will be the last version of implementation.\n - :sol:func:`upgradeTo`: Once an implementation is added, the governor may upgrade to that implementation only after a safety time period has passed (timelock), the current implementation is not the last version and the implementation is not frozen (see :sol:mod:`FullWithdrawals`).\n - :sol:func:`removeImplementation`: Any announced implementation may be removed. Removing an implementation is especially important once it has been used foran upgrade in order to avoid an additional unwanted revert to an older version.\n\n The only entity allowed to perform the above operations is theproxy governor\n (see :sol:mod:`ProxyGovernance`).\n\n Every implementation is required to have an `initialize` function that replaces theconstructor\n of a normal contract. Furthermore, the only parameter of this function is an array of bytes\n (`data`) which may be decodedarbitrarily by the `initialize` function. It is up to the\n implementation to ensure that this function cannot be run more than once if so desired.\n\n When an implementation is added (:sol:func:`addImplementation`) the initialization `data` is also\n announced, allowing users of thecontract to analyze the full effect of an upgrade to the new\n implementation. During an :sol:func:`upgradeTo`, the `data` is provided again andonly if it is\n identical to the announced `data` is the upgrade performed by pointing the proxy to the new\n implementation and calling its`initialize` function with this `data`.\n\n It is the responsibility of the implementation not to overwrite any storage belonging to the\n proxy(`ProxyStorage`). In addition, upon upgrade, the new implementation is assumed to be\n backward compatible with previous implementations withrespect to the storage used until that\n point.\n*/\ncontract Proxy is ProxyStorage, ProxyGovernance, StorageSlots {\n\n // Emitted when theactive implementation is replaced.\n event Upgraded(address indexed implementation);\n\n // Emitted when an implementation is submitted as anupgrade candidate and a time lock\n // is activated.\n event ImplementationAdded(address indexed implementation, bytes initializer, boolfinalize);\n\n // Emitted when an implementation is removed from the list of upgrade candidates.\n event ImplementationRemoved(addressindexed implementation);\n\n // Emitted when the implementation is finalized.\n event FinalizedImplementation(address indexed implementation);\n\n using Addresses for address;\n\n constructor (uint256 upgradeActivationDelay)\n public\n {\n initGovernance();\nsetUpgradeActivationDelay(upgradeActivationDelay);\n }\n\n function setUpgradeActivationDelay(uint256 delayInSeconds) private {\nbytes32 slot = UPGRADE_DELAY_SLOT;\n assembly {\n sstore(slot, delayInSeconds)\n }\n }\n\n functiongetUpgradeActivationDelay() public view returns (uint256 delay) {\n bytes32 slot = UPGRADE_DELAY_SLOT;\n assembly {\ndelay := sload(slot)\n }\n return delay;\n }\n\n /*\n Returns true if the implementation is frozen.\n If theimplementation was not assigned yet, returns false.\n */\n function implementationIsFrozen() private returns (bool) {\n address_implementation = implementation();\n\n // We can\u0027t call low level implementation before it\u0027s assigned. (i.e. ZERO).\n if(_implementation == address(0x0)) {\n return false;\n }\n\n // NOLINTNEXTLINE: low-level-calls.\n (bool success,bytes memory returndata) = _implementation.delegatecall(\n abi.encodeWithSignature(\"isFrozen()\"));\n require(success, string(returndata));\n return abi.decode(returndata, (bool));\n }\n\n /*\n This method blocks delegation to initialize().\n OnlyupgradeTo should be able to delegate call to initialize().\n */\n function initialize(bytes calldata /*data*/)\n external pure\n{\n revert(\"CANNOT_CALL_INITIALIZE\");\n }\n\n modifier notFinalized()\n {\n require(isNotFinalized(),\"IMPLEMENTATION_FINALIZED\");\n _;\n }\n\n /*\n Forbids calling the function if the implementation is frozen.\n Thismodifier relies on the lower level (logical contract) implementation of isFrozen().\n */\n modifier notFrozen()\n {\n require(!implementationIsFrozen(), \"STATE_IS_FROZEN\");\n _;\n }\n\n /*\n Contract\u0027s default function. Delegates execution to theimplementation contract.\n It returns back to the external caller whatever the implementation delegated code returns.\n */\n fallback()external payable {\n address _implementation = implementation();\n require (_implementation != address(0x0),\"MISSING_IMPLEMENTATION\");\n\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n// block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\ncalldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 for now, as we don\u0027t knowthe out size yet.\n let result := delegatecall(gas(), _implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\ncase 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n\n /*\n Sets theimplementation address of the proxy.\n */\n function setImplementation(address newImplementation) private {\n bytes32 slot =IMPLEMENTATION_SLOT;\n assembly {\n sstore(slot, newImplementation)\n }\n }\n\n /*\n Returns true if thecontract is not in the finalized state.\n */\n function isNotFinalized() public view returns (bool notFinal) {\n bytes32 slot =FINALIZED_STATE_SLOT;\n uint256 slotValue;\n assembly {\n slotValue := sload(slot)\n }\n notFinal =(slotValue == 0);\n }\n\n /*\n Marks the current implementation as finalized.\n */\n function setFinalizedFlag() private {\nbytes32 slot = FINALIZED_STATE_SLOT;\n assembly {\n sstore(slot, 0x1)\n }\n }\n\n /*\n Introduce animplementation and its initialization vector,\n and start the time-lock before it can be upgraded to.\n addImplementation is not blockedwhen frozen or finalized.\n (upgradeTo API is blocked when finalized or frozen).\n */\n function addImplementation(addressnewImplementation, bytes calldata data, bool finalize)\n external onlyGovernance {\n require(newImplementation.isContract(),\"ADDRESS_NOT_CONTRACT\");\n\n bytes32 init_hash = keccak256(abi.encode(data, finalize));\n initializationHash[newImplementation] =init_hash;\n\n uint256 activation_time = block.timestamp + getUpgradeActivationDelay();\n\n // First implementation should not havetime-lock.\n if (implementation() == address(0x0)) {\n activation_time = block.timestamp;\n }\n\nenabledTime[newImplementation] = activation_time;\n emit ImplementationAdded(newImplementation, data, finalize);\n }\n\n /*\nRemoves a candidate implementation.\n Note that it is possible to remove the current implementation. Doing so doesn\u0027t affect the\ncurrent implementation, but rather revokes it as a future candidate.\n */\n function removeImplementation(address newImplementation)\nexternal onlyGovernance {\n\n // If we have initializer, we set the hash of it.\n uint256 activation_time =enabledTime[newImplementation];\n\n require(activation_time \u003e 0, \"ADDRESS_NOT_UPGRADE_CANDIDATE\");\n\nenabledTime[newImplementation] = 0;\n\n initializationHash[newImplementation] = 0;\n emit ImplementationRemoved(newImplementation);\n}\n\n /*\n Upgrades the proxy to a new implementation, with its initialization.\n to upgrade successfully, implementation must havebeen added time-lock agreeably\n before, and the init vector must be identical ot the one submitted before.\n\n Upon assignment of newimplementation address,\n its initialize will be called with the initializing vector (even if empty).\n Therefore, the implementationMUST must have such a method.\n\n Note - Initialization data is committed to in advance, therefore it must remain valid\n until theactual contract upgrade takes place.\n\n Care should be taken regarding initialization data and flow when planning the contract upgrade.\n\nWhen planning contract upgrade, special care is also needed with regard to governance\n (See comments in Governance.sol).\n */\n //NOLINTNEXTLINE: reentrancy-events timestamp.\n function upgradeTo(address newImplementation, bytes calldata data, bool finalize)\nexternal payable onlyGovernance notFinalized notFrozen {\n uint256 activation_time = enabledTime[newImplementation];\n require(activation_time \u003e 0, \"ADDRESS_NOT_UPGRADE_CANDIDATE\");\n require(newImplementation.isContract(), \"ADDRESS_NOT_CONTRACT\");\n// NOLINTNEXTLINE: timestamp.\n require(activation_time \u003c= block.timestamp, \"UPGRADE_NOT_ENABLED_YET\");\n\n bytes32init_vector_hash = initializationHash[newImplementation];\n require(init_vector_hash == keccak256(abi.encode(data, finalize)),\"CHANGED_INITIALIZER\");\n setImplementation(newImplementation);\n\n // NOLINTNEXTLINE: low-level-calls controlled-delegatecall.\n(bool success, bytes memory returndata) = newImplementation.delegatecall(\n abi.encodeWithSelector(this.initialize.selector, data));\n require(success, string(returndata));\n\n // Verify that the new implementation is not frozen post initialization.\n //NOLINTNEXTLINE: low-level-calls controlled-delegatecall.\n (success, returndata) = newImplementation.delegatecall(\n abi.encodeWithSignature(\"isFrozen()\"));\n require(success, \"CALL_TO_ISFROZEN_REVERTED\");\n require(!abi.decode(returndata, (bool)),\"NEW_IMPLEMENTATION_FROZEN\");\n\n if (finalize) {\n setFinalizedFlag();\n emit FinalizedImplementation(newImplementation);\n }\n\n emit Upgraded(newImplementation);\n }\n}\n"},"ProxyGovernance.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except incompliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required byapplicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under theLicense.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"Governance.sol\";\n\n/**\n The Proxy contract isgoverned by one or more Governors of which the initial one is the\n deployer of the contract.\n\n A governor has the sole authority to performthe following operations:\n\n 1. Nominate additional governors (:sol:func:`proxyNominateNewGovernor`)\n 2. Remove other governors (:sol:func:`proxyRemoveGovernor`)\n 3. Add new `implementations` (proxied contracts)\n 4. Remove (new or old) `implementations`\n 5. Update`implementations` after a timelock allows it\n\n Adding governors is performed in a two step procedure:\n\n 1. First, an existing governornominates a new governor (:sol:func:`proxyNominateNewGovernor`)\n 2. Then, the new governor must accept governance to become a governor (:sol:func:`proxyAcceptGovernance`)\n\n This two step procedure ensures that a governor public key cannot be nominated unless there is an\n entity that hasthe corresponding private key. This is intended to prevent errors in the addition\n process.\n\n The governor private key should typically beheld in a secure cold wallet or managed via a\n multi-sig contract.\n*/\n/*\n Implements Governance for the proxy contract.\n It is a thinwrapper to the Governance contract,\n which is needed so that it can have non-colliding function names,\n and a specific tag (key) to allowunique state storage.\n*/\ncontract ProxyGovernance is Governance {\n\n // The tag is the string key that is used in the Governance storagemapping.\n string public constant PROXY_GOVERNANCE_TAG = \"StarkEx.Proxy.2019.GovernorsInformation\";\n\n function getGovernanceTag()\ninternal\n pure\n override\n returns (string memory tag) {\n tag = PROXY_GOVERNANCE_TAG;\n }\n\n functionproxyIsGovernor(address testGovernor) external view returns (bool) {\n return isGovernor(testGovernor);\n }\n\n functionproxyNominateNewGovernor(address newGovernor) external {\n nominateNewGovernor(newGovernor);\n }\n\n function proxyRemoveGovernor(address governorForRemoval) external {\n removeGovernor(governorForRemoval);\n }\n\n function proxyAcceptGovernance()\nexternal\n {\n acceptGovernance();\n }\n\n function proxyCancelNomination() external {\n cancelNomination();\n }\n}\n"},"ProxyStorage.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the\"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License isdistributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specificlanguage governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"GovernanceStorage.sol\";\n\n/*\n Holds the Proxy-specific state variables.\n This contract is inherited by the GovernanceStorage(and indirectly by MainStorage)\n to prevent collision hazard.\n*/\ncontract ProxyStorage is GovernanceStorage {\n\n // Stores the hash of theinitialization vector of the added implementation.\n // Upon upgradeTo the implementation, the initialization vector is verified\n // to beidentical to the one submitted when adding the implementation.\n mapping (address =\u003e bytes32) internal initializationHash;\n\n // Thetime after which we can switch to the implementation.\n mapping (address =\u003e uint256) internal enabledTime;\n\n // A central storage ofthe flags whether implementation has been initialized.\n // Note - it can be used flexibly enough to accommodate multiple levels ofinitialization\n // (i.e. using different key salting schemes for different initialization levels).\n mapping (bytes32 =\u003e bool) internalinitialized;\n}\n"},"StorageSlots.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License,Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\nhttps://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under theLicense is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License forthe specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/**\n StorageSlots holds the arbitrary storage slots used throughout the Proxy pattern.\n Storage address slots are a mechanism todefine an arbitrary location, that will not be\n overlapped by the logical contracts.\n*/\ncontract StorageSlots {\n /*\n Returns theaddress of the current implementation.\n */\n // NOLINTNEXTLINE external-function.\n function implementation() public view returns(address_implementation) {\n bytes32 slot = IMPLEMENTATION_SLOT;\n assembly {\n _implementation := sload(slot)\n }\n}\n\n // Storage slot with the address of the current implementation.\n // The address of the slot is keccak256(\"StarkWare2019.implemntation-slot\").\n // We need to keep this variable stored outside of the commonly used space,\n // so that it\u0027s not overrun by the logicalimplementation (the proxied contract).\n bytes32 internal constant IMPLEMENTATION_SLOT =\n0x177667240aeeea7e35eabe3a35e18306f336219e1386f7710a6bf8783f761b24;\n\n // Storage slot with the address of the call-proxy currentimplementation.\n // The address of the slot is keccak256(\"\u0027StarkWare2020.CallProxy.Implemntation.Slot\u0027\").\n // We need to keepthis variable stored outside of the commonly used space.\n // so that it\u0027s not overrun by the logical implementation (the proxied contract).\n bytes32 internal constant CALL_PROXY_IMPL_SLOT =\n 0x7184681641399eb4ad2fdb92114857ee6ff239f94ad635a1779978947b8843be;\n\n // Thisstorage slot stores the finalization flag.\n // Once the value stored in this slot is set to non-zero\n // the proxy blocks implementationupgrades.\n // The current implementation is then referred to as Finalized.\n // Web3.solidityKeccak([\u0027string\u0027], [\"StarkWare2019.finalization-flag-slot\"]).\n bytes32 internal constant FINALIZED_STATE_SLOT =\n0x7d433c6f837e8f93009937c466c82efbb5ba621fae36886d0cac433c5d0aa7d2;\n\n // Storage slot to hold the upgrade delay (time-lock).\n // Theintention of this slot is to allow modification using an EIC.\n // Web3.solidityKeccak([\u0027string\u0027], [\u0027StarkWare.Upgradibility.Delay.Slot\u0027]).\n bytes32 public constant UPGRADE_DELAY_SLOT =\n 0xc21dbb3089fcb2c4f4c6a67854ab4db2b0f233ea4b21b21f912d52d18fc5db1f;\n\n// Storage slot to hold the MainDispatcher init safeguard.\n // Web3.solidityKeccak([\u0027string\u0027], [\u0027StarkWare.MainDispatcher.Init.Safeguard.Slot\u0027]).\n bytes32 public constant MAIN_DISPATCHER_SAFEGUARD_SLOT =\n0xf3afa5472f846c7817e22b15110d7b184f2d3d6417baee645a1e963b8fac7e24;\n}\n"}}
File 2 of 3: StarkPerpetual
1{"Common.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\nYou may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governingpermissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/*\n Common Utilitylibrarries.\n I. Addresses (extending address).\n*/\nlibrary Addresses {\n function isContract(address account) internal view returns (bool){\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size \u003e 0;\n }\n\nfunction performEthTransfer(address recipient, uint256 amount) internal {\n (bool success, ) = recipient.call{value: amount}(\"\"); //NOLINT: low-level-calls.\n require(success, \"ETH_TRANSFER_FAILED\");\n }\n\n /*\n Safe wrapper around ERC20/ERC721 calls.\nThis is required because many deployed ERC20 contracts don\u0027t return a value.\n See https://github.com/ethereum/solidity/issues/4116.\n*/\n function safeTokenContractCall(address tokenAddress, bytes memory callData) internal {\n require(isContract(tokenAddress),\"BAD_TOKEN_ADDRESS\");\n // NOLINTNEXTLINE: low-level-calls.\n (bool success, bytes memory returndata) = tokenAddress.call(callData);\n require(success, string(returndata));\n\n if (returndata.length \u003e 0) {\n require(abi.decode(returndata, (bool)),\"TOKEN_OPERATION_FAILED\");\n }\n }\n\n /*\n Similar to safeTokenContractCall, but always ignores the return value.\n\nAssumes some other method is used to detect the failures\n (e.g. balance is checked before and after the call).\n */\n functionuncheckedTokenContractCall(address tokenAddress, bytes memory callData) internal {\n // NOLINTNEXTLINE: low-level-calls.\n (boolsuccess, bytes memory returndata) = tokenAddress.call(callData);\n require(success, string(returndata));\n }\n\n}\n\nlibrary UintArray{\n function hashSubArray(uint256[] memory array, uint256 subArrayStart, uint256 subArraySize)\n internal pure\n returns(bytes32subArrayHash)\n {\n require(array.length \u003e= subArrayStart + subArraySize, \"ILLEGAL_SUBARRAY_DIMENSIONS\");\n uint256startOffsetBytes = 0x20 * (1 + subArrayStart);\n uint256 dataSizeBytes = 0x20 * subArraySize;\n assembly {\n subArrayHash:= keccak256(add(array, startOffsetBytes), dataSizeBytes)\n }\n }\n\n /*\n Returns the address of a cell in offset within auint256[] array.\n This allows assigning new variable of dynamic unit256[] pointing to a sub_array\n with a layout of serialied uint256[](i.e. length+content).\n */\n function extractSerializedUintArray(uint256[] memory programOutput, uint256 offset)\n internal pure\nreturns (uint256[] memory addr)\n {\n uint256 memOffset = 0x20 * (offset + 1);\n assembly {\n addr := add(programOutput, memOffset)\n }\n }\n\n}\n\n/*\n II. StarkExTypes - Common data types.\n*/\nlibrary StarkExTypes {\n\n // Structurerepresenting a list of verifiers (validity/availability).\n // A statement is valid only if all the verifiers in the list agree on it.\n //Adding a verifier to the list is immediate - this is used for fast resolution of\n // any soundness issues.\n // Removing from the list istime-locked, to ensure that any user of the system\n // not content with the announced removal has ample time to leave the system before it is\n// removed.\n struct ApprovalChainData {\n address[] list;\n // Represents the time after which the verifier with the givenaddress can be removed.\n // Removal of the verifier with address A is allowed only in the case the value\n // ofunlockedForRemovalTime[A] != 0 and unlockedForRemovalTime[A] \u003c (current time).\n mapping (address =\u003e uint256)unlockedForRemovalTime;\n }\n}\n"},"GovernanceStorage.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed underthe Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy ofthe License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n softwaredistributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/*\n Holds the governance slots for ALL entities, including proxy and the main contract.\n*/\ncontractGovernanceStorage {\n\n struct GovernanceInfoStruct {\n mapping (address =\u003e bool) effectiveGovernors;\n addresscandidateGovernor;\n bool initialized;\n }\n\n // A map from a Governor tag to its own GovernanceInfoStruct.\n mapping (string=\u003e GovernanceInfoStruct) internal governanceInfo;\n}\n"},"Identity.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\nLicensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You mayobtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressor implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\ninterface Identity {\n\n /*\n Allows a caller, typically another contract,\n toensure that the provided address is of the expected type and version.\n */\n function identify()\n external pure\n returns(string memory);\n}\n"},"IDispatcherBase.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the ApacheLicense, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the Licenseat\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed underthe License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the Licensefor the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity^0.6.11;\n\n/*\n Interface for generic dispatcher to use,\n which the concrete dispatcher must implement.\n\n I contains the functions that arespecific to the concrete dispatcher instance.\n\n The interface is implemented as contract, because interface implies all methods external.\n*/\nabstract contract IDispatcherBase {\n\n function getSubContract(bytes4 selector) internal view virtual returns (address);\n\n functionsetSubContractAddress(uint256 index, address subContract) internal virtual;\n\n function getNumSubcontracts() internal pure virtual returns(uint256);\n\n function validateSubContractIndex(uint256 index, address subContract) internal pure virtual;\n\n /*\n Ensures initializercan be called. Reverts otherwise.\n */\n function initializationSentinel() internal view virtual;\n}\n"},"IFactRegistry.sol":{"content":"/*\nCopyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this fileexcept in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unlessrequired by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUTWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n andlimitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/*\n The Fact Registry design pattern isa way to separate cryptographic verification from the\n business logic of the contract flow.\n\n A fact registry holds a hash table of verified\"facts\" which are represented by a hash of claims\n that the registry hash check and found valid. This table may be queried by accessing the\nisValid() function of the registry with a given hash.\n\n In addition, each fact registry exposes a registry specific function for submitting newclaims\n together with their proofs. The information submitted varies from one registry to the other\n depending of the type of fact requiringverification.\n\n For further reading on the Fact Registry design pattern see this\n `StarkWare blog post \u003chttps://medium.com/starkware/the-fact-registry-a64aafb598b6\u003e`_.\n*/\ninterface IFactRegistry {\n /*\n Returns true if the given fact was previously registered in thecontract.\n */\n function isValid(bytes32 fact)\n external view\n returns(bool);\n}\n"},"MainDispatcher.sol":{"content":"/*\nCopyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this fileexcept in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unlessrequired by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUTWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n andlimitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"MainStorage.sol\";\nimport\"MainDispatcherBase.sol\";\n\nabstract contract MainDispatcher is MainStorage, MainDispatcherBase {\n\n uint256 constant SUBCONTRACT_BITS = 4;\n\n function magicSalt() internal pure virtual returns(uint256);\n function handlerMapSection(uint256 section) internal view virtualreturns(uint256);\n function expectedIdByIndex(uint256 index) internal pure virtual returns (string memory id);\n\n functionvalidateSubContractIndex(uint256 index, address subContract) internal pure override {\n string memory id = SubContractor(subContract).identify();\n bytes32 hashed_expected_id = keccak256(abi.encodePacked(expectedIdByIndex(index)));\n require(\nhashed_expected_id == keccak256(abi.encodePacked(id)),\n \"MISPLACED_INDEX_OR_BAD_CONTRACT_ID\"\n );\n }\n\n functiongetSubContract(bytes4 selector) internal view override returns (address) {\n uint256 location = 0xFF \u0026 uint256(keccak256(abi.encodePacked(selector, magicSalt())));\n uint256 subContractIdx;\n uint256 offset = (SUBCONTRACT_BITS * location) % 256;\n\n// We have 64 locations in each register, hence the \u003e\u003e6 (i.e. location // 64).\n subContractIdx = (handlerMapSection(location\u003e\u003e 6) \u003e\u003e offset) \u0026 0xF;\n return subContracts[subContractIdx];\n }\n\n function setSubContractAddress(uint256index, address subContractAddress) internal override {\n subContracts[index] = subContractAddress;\n }\n}\n"},"MainDispatcherBase.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You maynot use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\"BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governingpermissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"SubContractor.sol\";\nimport \"IDispatcherBase.sol\";\nimport \"Common.sol\";\nimport \"StorageSlots.sol\";\n\nabstract contract MainDispatcherBase isIDispatcherBase, StorageSlots {\n\n using Addresses for address;\n\n constructor( ) internal {\n bytes32 slot =MAIN_DISPATCHER_SAFEGUARD_SLOT;\n assembly {\n sstore(slot, 42)\n }\n }\n\n modifier notCalledDirectly() {\n{ // Prevent too many local variables in stack.\n uint256 safeGuardValue;\n bytes32 slot = MAIN_DISPATCHER_SAFEGUARD_SLOT;\nassembly {\n safeGuardValue := sload(slot)\n }\n require(safeGuardValue == 0,\"DIRECT_CALL_DISALLOWED\");\n }\n _;\n }\n\n fallback() external payable { //NOLINT locked-ether.\n addresssubContractAddress = getSubContract(msg.sig);\n require(subContractAddress != address(0x0), \"NO_CONTRACT_FOR_FUNCTION\");\n\nassembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not returnto Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n// Call the implementation.\n // out and outsize are 0 for now, as we don\"t know the out size yet.\n let result :=delegatecall(gas(), subContractAddress, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0,returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\nrevert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n}\n }\n\n /*\n 1. Extract subcontracts.\n 2. Verify correct sub-contract initializer size.\n 3. Extract sub-contractinitializer data.\n 4. Call sub-contract initializer.\n\n The init data bytes passed to initialize are structed as following:\n I. Nslots (uin256 size) addresses of the deployed sub-contracts.\n II. An address of an external initialization contract (optional, orZERO_ADDRESS).\n III. (Up to) N bytes sections of the sub-contracts initializers.\n\n If already initialized (i.e. upgrade) we expect theinit data to be consistent with this.\n and if a different size of init data is expected when upgrading, the initializerSize should\nreflect this.\n\n If an external initializer contract is not used, ZERO_ADDRESS is passed in its slot.\n If the external initializercontract is used, all the remaining init data is passed to it,\n and internal initialization will not occur.\n\n External InitializationContract\n --------------------------------\n External Initialization Contract (EIC) is a hook for custom initialization.\nTypically in an upgrade flow, the expected initialization contains only the addresses of\n the sub-contracts. Normal initialization of the sub-contracts is such that is not needed\n in an upgrade, and actually may be very dangerous, as changing of state on a working system\n maycorrupt it.\n\n In the event that some state initialization is required, the EIC is a hook that allows this.\n It may be deployed andcalled specifically for this purpose.\n\n The address of the EIC must be provided (if at all) when a new implementation is added to\n aProxy contract (as part of the initialization vector).\n Hence, it is considered part of the code open to reviewers prior to a time-lockedupgrade.\n\n When a custom initialization is performed using an EIC,\n the main dispatcher initialize extracts and stores the sub-contracts addresses, and then\n yields to the EIC, skipping the rest of its initialization code.\n\n\n Flow of MainDispatcherinitialize\n ---------------------------------\n 1. Extraction and assignment of subcontracts addresses\n Main dispatcher expectsa valid and consistent set of addresses in the passed data.\n It validates that, extracts the addresses from the data, and validates thatthe addresses\n are of the expected type and order. Then those addresses are stored.\n\n 2. Extraction of EIC address\n Theaddress of the EIC is extracted from the data.\n External Initializer Contract is optional. ZERO_ADDRESS indicates it is not used.\n\n3a. EIC is used\n Dispatcher calls the EIC initialize function with the remaining data.\n Note - In this option 3b is notperformed.\n\n 3b. EIC is not used\n If there is additional initialization data then:\n I. Sentitenl function is called topermit subcontracts initialization.\n II. Dispatcher loops through the subcontracts and for each one it extracts the\ninitializing data and passes it to the subcontract\u0027s initialize function.\n\n */\n // NOLINTNEXTLINE: external-function.\n functioninitialize(bytes memory data) public virtual\n notCalledDirectly()\n {\n // Number of sub-contracts.\n uint256nSubContracts = getNumSubcontracts();\n\n // We support currently 4 bits per contract, i.e. 16, reserving 00 leads to 15.\n require(nSubContracts \u003c= 15, \"TOO_MANY_SUB_CONTRACTS\");\n\n // Init data MUST include addresses for all sub-contracts + EIC.\nrequire(data.length \u003e= 32 * (nSubContracts + 1), \"SUB_CONTRACTS_NOT_PROVIDED\");\n\n // Ensure implementation is a valid contract.\nrequire(implementation().isContract(), \"INVALID_IMPLEMENTATION\");\n\n // Size of passed data, excluding sub-contract addresses.\nuint256 additionalDataSize = data.length - 32 * (nSubContracts + 1);\n\n // Sum of subcontract initializers. Aggregated forverification near the end.\n uint256 totalInitSizes = 0;\n\n // Offset (within data) of sub-contract initializer vector.\n //Just past the sub-contract addresses.\n uint256 initDataContractsOffset = 32 * (nSubContracts + 1);\n\n // Extract \u0026 updatecontract addresses.\n for (uint256 nContract = 1; nContract \u003c= nSubContracts; nContract++) {\n address contractAddress;\n\n// Extract sub-contract address.\n assembly {\n contractAddress := mload(add(data, mul(32, nContract)))\n}\n\n validateSubContractIndex(nContract, contractAddress);\n\n // Contracts are indexed from 1 and 0 is not in usehere.\n setSubContractAddress(nContract, contractAddress);\n }\n\n // Check if we have an external initializer contract.\naddress externalInitializerAddr;\n\n // 2. Extract sub-contract address, again. It\u0027s cheaper than reading from storage.\nassembly {\n externalInitializerAddr := mload(add(data, mul(32, add(nSubContracts, 1))))\n }\n\n // 3(a). Yield to EICinitialization.\n if (externalInitializerAddr != address(0x0)) {\n callExternalInitializer(data, externalInitializerAddr,additionalDataSize);\n return;\n }\n\n // 3(b). Subcontracts initialization.\n // I. If no init data passed besidessub-contracts, return.\n if (additionalDataSize == 0) {\n return;\n }\n\n // Just to be on the safe side.\nassert(externalInitializerAddr == address(0x0));\n\n // II. Gate further initialization.\n initializationSentinel();\n\n //III. Loops through the subcontracts, extracts their data and calls their initializer.\n for (uint256 nContract = 1; nContract \u003c=nSubContracts; nContract++) {\n address contractAddress;\n\n // Extract sub-contract address, again. It\u0027s cheaper thanreading from storage.\n assembly {\n contractAddress := mload(add(data, mul(32, nContract)))\n }\n// The initializerSize returns the expected size, with respect also to the state status.\n // i.e. different size if it\u0027s a firstinit (clean state) or upgrade init (alive state).\n // NOLINTNEXTLINE: calls-loop.\n\n // The initializerSize is called viadelegatecall, so that it can relate to the state,\n // and not only to the new contract code. (e.g. return 0 if state-intialized else192).\n // NOLINTNEXTLINE: reentrancy-events low-level-calls calls-loop.\n (bool success, bytes memory returndata) =contractAddress.delegatecall(\n abi.encodeWithSelector(SubContractor(contractAddress).initializerSize.selector));\nrequire(success, string(returndata));\n uint256 initSize = abi.decode(returndata, (uint256));\n require(initSize \u003c=additionalDataSize, \"INVALID_INITIALIZER_SIZE\");\n require(totalInitSizes + initSize \u003c= additionalDataSize,\"INVALID_INITIALIZER_SIZE\");\n\n if (initSize == 0) {\n continue;\n }\n\n // Extract sub-contractinit vector.\n bytes memory subContractInitData = new bytes(initSize);\n for (uint256 trgOffset = 32; trgOffset \u003c=initSize; trgOffset += 32) {\n assembly {\n mstore(\n add(subContractInitData, trgOffset),\n mload(add(add(data, trgOffset), initDataContractsOffset))\n )\n }\n }\n\n// Call sub-contract initializer.\n // NOLINTNEXTLINE: low-level-calls.\n (success, returndata) = contractAddress.delegatecall(\n abi.encodeWithSelector(this.initialize.selector, subContractInitData)\n );\n require(success,string(returndata));\n totalInitSizes += initSize;\n initDataContractsOffset += initSize;\n }\n require(\nadditionalDataSize == totalInitSizes,\n \"MISMATCHING_INIT_DATA_SIZE\");\n }\n\n function callExternalInitializer(\nbytes memory data,\n address externalInitializerAddr,\n uint256 dataSize)\n private {\n require(externalInitializerAddr.isContract(), \"NOT_A_CONTRACT\");\n require(dataSize \u003c= data.length, \"INVALID_DATA_SIZE\");\n bytesmemory extInitData = new bytes(dataSize);\n\n // Prepare memcpy pointers.\n uint256 srcDataOffset = 32 + data.length - dataSize;\nuint256 srcData;\n uint256 trgData;\n\n assembly {\n srcData := add(data, srcDataOffset)\n trgData := add(extInitData, 32)\n }\n\n // Copy initializer data to be passed to the EIC.\n for (uint256 seek = 0; seek \u003c dataSize;seek += 32) {\n assembly {\n mstore(\n add(trgData, seek),\n mload(add(srcData,seek))\n )\n }\n }\n\n // NOLINTNEXTLINE: low-level-calls.\n (bool success, bytes memory returndata)= externalInitializerAddr.delegatecall(\n abi.encodeWithSelector(this.initialize.selector, extInitData)\n );\n require(success, string(returndata));\n require(returndata.length == 0, string(returndata));\n }\n}\n"},"MainStorage.sol":{"content":"/*\nCopyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this fileexcept in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unlessrequired by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUTWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n andlimitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"IFactRegistry.sol\";\nimport\"ProxyStorage.sol\";\nimport \"Common.sol\";\n/*\n Holds ALL the main contract state (storage) variables.\n*/\ncontract MainStorage isProxyStorage {\n\n uint256 constant internal LAYOUT_LENGTH = 2**64;\n\n IFactRegistry escapeVerifier_;\n\n // Global dex-frozen flag.\nbool stateFrozen; // NOLINT: constable-states.\n\n // Time when unFreeze can be successfully called(UNFREEZE_DELAY after freeze).\n uint256 unFreezeTime; // NOLINT: constable-states.\n\n // Pending deposits.\n// A map STARK key =\u003e asset id =\u003e vault id =\u003e quantized amount.\n mapping (uint256 =\u003e mapping (uint256 =\u003e mapping(uint256 =\u003e uint256))) pendingDeposits;\n\n // Cancellation requests.\n // A map STARK key =\u003e asset id =\u003e vault id =\u003erequest timestamp.\n mapping (uint256 =\u003e mapping (uint256 =\u003e mapping (uint256 =\u003e uint256))) cancellationRequests;\n\n //Pending withdrawals.\n // A map STARK key =\u003e asset id =\u003e quantized amount.\n mapping (uint256 =\u003e mapping (uint256 =\u003euint256)) pendingWithdrawals;\n\n // vault_id =\u003e escape used boolean.\n mapping (uint256 =\u003e bool) escapesUsed;\n\n // Number ofescapes that were performed when frozen.\n uint256 escapesUsedCount; // NOLINT: constable-states.\n\n // NOTE:fullWithdrawalRequests is deprecated, and replaced by forcedActionRequests.\n // NOLINTNEXTLINE naming-convention.\n mapping (uint256 =\u003emapping (uint256 =\u003e uint256)) fullWithdrawalRequests_DEPRECATED;\n\n // State sequence number.\n uint256 sequenceNumber;// NOLINT: constable-states uninitialized-state.\n\n // Vaults Tree Root \u0026 Height.\n uint256 vaultRoot;// NOLINT: constable-states uninitialized-state.\n uint256 vaultTreeHeight; // NOLINT: constable-statesuninitialized-state.\n\n // Order Tree Root \u0026 Height.\n uint256 orderRoot; // NOLINT: constable-statesuninitialized-state.\n uint256 orderTreeHeight; // NOLINT: constable-states uninitialized-state.\n\n // True if andonly if the address is allowed to add tokens.\n mapping (address =\u003e bool) tokenAdmins;\n\n // True if and only if the address is allowedto register users.\n mapping (address =\u003e bool) userAdmins;\n\n // True if and only if the address is an operator (allowed to updatestate).\n mapping (address =\u003e bool) operators;\n\n // Mapping of contract ID to asset data.\n mapping (uint256 =\u003e bytes)assetTypeToAssetInfo; // NOLINT: uninitialized-state.\n\n // Mapping of registered contract IDs.\n mapping (uint256 =\u003e bool)registeredAssetType; // NOLINT: uninitialized-state.\n\n // Mapping from contract ID to quantum.\n mapping (uint256 =\u003e uint256)assetTypeToQuantum; // NOLINT: uninitialized-state.\n\n // This mapping is no longer in use, remains for backwards compatibility.\nmapping (address =\u003e uint256) starkKeys_DEPRECATED; // NOLINT: naming-convention.\n\n // Mapping from STARK public key to the Ethereumpublic key of its owner.\n mapping (uint256 =\u003e address) ethKeys; // NOLINT: uninitialized-state.\n\n // Timelocked statetransition and availability verification chain.\n StarkExTypes.ApprovalChainData verifiersChain;\n StarkExTypes.ApprovalChainDataavailabilityVerifiersChain;\n\n // Batch id of last accepted proof.\n uint256 lastBatchId; // NOLINT: constable-states uninitialized-state.\n\n // Mapping between sub-contract index to sub-contract address.\n mapping(uint256 =\u003e address)subContracts; // NOLINT: uninitialized-state.\n\n mapping (uint256 =\u003e bool) permissiveAssetType_DEPRECATED; // NOLINT: naming-convention.\n // ---- END OF MAIN STORAGE AS DEPLOYED IN STARKEX2.0 ----\n\n // Onchain-data version configured for the system.\n uint256onchainDataVersion; // NOLINT: constable-states uninitialized-state.\n\n // Counter of forced action request in block. Thekey is the block number.\n mapping(uint256 =\u003e uint256) forcedRequestsInBlock;\n\n // ForcedAction requests: actionHash =\u003erequestTime.\n mapping(bytes32 =\u003e uint256) forcedActionRequests;\n\n // Mapping for timelocked actions.\n // A actionKey =\u003eactivation time.\n mapping (bytes32 =\u003e uint256) actionsTimeLock;\n\n // Reserved storage space for Extensibility.\n // Every addedMUST be added above the end gap, and the __endGap size must be reduced\n // accordingly.\n // NOLINTNEXTLINE: naming-convention.\nuint256[LAYOUT_LENGTH - 36] private __endGap; // __endGap complements layout to LAYOUT_LENGTH.\n}\n"},"PerpetualStorage.sol":{"content":"/*\nCopyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this fileexcept in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unlessrequired by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUTWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n andlimitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"MainStorage.sol\";\n\n/*\nExtends MainStorage, holds Perpetual App specific state (storage) variables.\n\n ALL State variables that are common to all applications, residein MainStorage,\n whereas ALL the Perpetual app specific ones reside here.\n*/\ncontract PerpetualStorage is MainStorage {\n uint256systemAssetType; // NOLINT: constable-states uninitialized-state.\n\n bytes32 public globalConfigurationHash; //NOLINT: constable-states uninitialized-state.\n\n mapping(uint256 =\u003e bytes32) public configurationHash; // NOLINT: uninitialized-state.\n\nbytes32 sharedStateHash; // NOLINT: constable-states uninitialized-state.\n\n // Configuration apply time-lock.\n //The delay is held in storage (and not constant)\n // So that it can be modified during upgrade.\n uint256 public configurationDelay;// NOLINT: constable-states.\n\n // Reserved storage space for Extensibility.\n // Every added MUST be added above the end gap, and the__endGap size must be reduced\n // accordingly.\n // NOLINTNEXTLINE: naming-convention shadowing-abstract.\n uint256[LAYOUT_LENGTH - 5]private __endGap; // __endGap complements layout to LAYOUT_LENGTH.\n}\n"},"ProxyStorage.sol":{"content":"/*\n Copyright 2019,2020 StarkWareIndustries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with theLicense.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law oragreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n//SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"GovernanceStorage.sol\";\n\n/*\n Holds the Proxy-specific statevariables.\n This contract is inherited by the GovernanceStorage (and indirectly by MainStorage)\n to prevent collision hazard.\n*/\ncontractProxyStorage is GovernanceStorage {\n\n // Stores the hash of the initialization vector of the added implementation.\n // Upon upgradeTo theimplementation, the initialization vector is verified\n // to be identical to the one submitted when adding the implementation.\n mapping(address =\u003e bytes32) internal initializationHash;\n\n // The time after which we can switch to the implementation.\n mapping (address=\u003e uint256) internal enabledTime;\n\n // A central storage of the flags whether implementation has been initialized.\n // Note - it canbe used flexibly enough to accommodate multiple levels of initialization\n // (i.e. using different key salting schemes for differentinitialization levels).\n mapping (bytes32 =\u003e bool) internal initialized;\n}\n"},"StarkPerpetual.sol":{"content":"/*\n Copyright 2019,2020StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliancewith the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicablelaw or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OFANY KIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"MainDispatcher.sol\";\nimport \"PerpetualStorage.sol\";\n\ncontractStarkPerpetual is MainDispatcher, PerpetualStorage {\n string public constant VERSION = \"1.0.0\";\n\n // Salt for a 8 bit unique spread ofall relevant selectors. Pre-caclulated.\n // ---------- The following code was auto-generated. PLEASE DO NOT EDIT. ----------\n uint256constant MAGIC_SALT = 15691;\n uint256 constant IDX_MAP_0 = 0x3000000002000200000000000220022100000102300010000030103200010000;\n uint256constant IDX_MAP_1 = 0x1410000000002200200000002003321010000210132000020000;\n uint256 constant IDX_MAP_2 =0x3031200400000004003320020000000012022120020030000003000020;\n uint256 constant IDX_MAP_3 =0x100200003000100000000000000320000410000003000030000101210000000;\n // ---------- End of auto-generated code. ----------\n\n functiongetNumSubcontracts() internal pure override returns (uint256) {\n return 4;\n }\n\n function magicSalt() internal pure overridereturns(uint256) {\n return MAGIC_SALT;\n }\n\n function handlerMapSection(uint256 section) internal view override returns(uint256){\n if(section == 0) {\n return IDX_MAP_0;\n }\n else if(section == 1) {\n return IDX_MAP_1;\n}\n else if(section == 2) {\n return IDX_MAP_2;\n }\n else if(section == 3) {\n return IDX_MAP_3;\n}\n revert(\"BAD_IDX_MAP_SECTION\");\n }\n\n function expectedIdByIndex(uint256 index)\n internal pure override returns(string memory id) {\n if (index == 1){\n id = \"StarkWare_AllVerifiers_2020_1\";\n } else if (index == 2){\nid = \"StarkWare_PerpetualTokensAndRamping_2020_1\";\n } else if (index == 3){\n id = \"StarkWare_PerpetualState_2020_1\";\n} else if (index == 4){\n id = \"StarkWare_PerpetualForcedActions_2020_1\";\n } else {\n revert(\"UNEXPECTED_INDEX\");\n }\n }\n\n function initializationSentinel() internal view override {\n string memory REVERT_MSG =\"INITIALIZATION_BLOCKED\";\n // This initializer sets state etc. It must not be applied twice.\n // I.e. it can run only when thestate is still empty.\n require(int(sharedStateHash) == 0, REVERT_MSG);\n require(int(globalConfigurationHash) == 0, REVERT_MSG);\nrequire(systemAssetType == 0, REVERT_MSG);\n }\n}\n"},"StorageSlots.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n Youmay obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to inwriting,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, eitherexpress or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/**\n StorageSlots holds the arbitrary storage slots used throughout the Proxy pattern.\nStorage address slots are a mechanism to define an arbitrary location, that will not be\n overlapped by the logical contracts.\n*/\ncontractStorageSlots {\n /*\n Returns the address of the current implementation.\n */\n // NOLINTNEXTLINE external-function.\n functionimplementation() public view returns(address _implementation) {\n bytes32 slot = IMPLEMENTATION_SLOT;\n assembly {\n_implementation := sload(slot)\n }\n }\n\n // Storage slot with the address of the current implementation.\n // The address of theslot is keccak256(\"StarkWare2019.implemntation-slot\").\n // We need to keep this variable stored outside of the commonly used space,\n //so that it\u0027s not overrun by the logical implementation (the proxied contract).\n bytes32 internal constant IMPLEMENTATION_SLOT =\n0x177667240aeeea7e35eabe3a35e18306f336219e1386f7710a6bf8783f761b24;\n\n // Storage slot with the address of the call-proxy currentimplementation.\n // The address of the slot is keccak256(\"\u0027StarkWare2020.CallProxy.Implemntation.Slot\u0027\").\n // We need to keepthis variable stored outside of the commonly used space.\n // so that it\u0027s not overrun by the logical implementation (the proxied contract).\n bytes32 internal constant CALL_PROXY_IMPL_SLOT =\n 0x7184681641399eb4ad2fdb92114857ee6ff239f94ad635a1779978947b8843be;\n\n // Thisstorage slot stores the finalization flag.\n // Once the value stored in this slot is set to non-zero\n // the proxy blocks implementationupgrades.\n // The current implementation is then referred to as Finalized.\n // Web3.solidityKeccak([\u0027string\u0027], [\"StarkWare2019.finalization-flag-slot\"]).\n bytes32 internal constant FINALIZED_STATE_SLOT =\n0x7d433c6f837e8f93009937c466c82efbb5ba621fae36886d0cac433c5d0aa7d2;\n\n // Storage slot to hold the upgrade delay (time-lock).\n // Theintention of this slot is to allow modification using an EIC.\n // Web3.solidityKeccak([\u0027string\u0027], [\u0027StarkWare.Upgradibility.Delay.Slot\u0027]).\n bytes32 public constant UPGRADE_DELAY_SLOT =\n 0xc21dbb3089fcb2c4f4c6a67854ab4db2b0f233ea4b21b21f912d52d18fc5db1f;\n\n// Storage slot to hold the MainDispatcher init safeguard.\n // Web3.solidityKeccak([\u0027string\u0027], [\u0027StarkWare.MainDispatcher.Init.Safeguard.Slot\u0027]).\n bytes32 public constant MAIN_DISPATCHER_SAFEGUARD_SLOT =\n0xf3afa5472f846c7817e22b15110d7b184f2d3d6417baee645a1e963b8fac7e24;\n}\n"},"SubContractor.sol":{"content":"/*\n Copyright 2019,2020 StarkWareIndustries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with theLicense.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law oragreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n//SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"Identity.sol\";\n\ninterface SubContractor is Identity {\n\n functioninitialize(bytes calldata data)\n external;\n\n function initializerSize()\n external view\n returns(uint256);\n}\n"}}
File 3 of 3: PerpetualTokensAndRamping
1{"AcceptModifications.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the\"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License isdistributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specificlanguage governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"LibConstants.sol\";\nimport \"MAcceptModifications.sol\";\nimport \"MTokenQuantization.sol\";\nimport \"MainStorage.sol\";\n\n/*\nInterface containing actions a verifier can invoke on the state.\n The contract containing the state should implement these and verify correctness.\n*/\nabstract contract AcceptModifications is\n MainStorage,\n LibConstants,\n MAcceptModifications,\n MTokenQuantization\n{\nevent LogWithdrawalAllowed(\n uint256 starkKey,\n uint256 assetType,\n uint256 nonQuantizedAmount,\n uint256quantizedAmount\n );\n\n event LogNftWithdrawalAllowed(uint256 starkKey, uint256 assetId);\n\n event LogMintableWithdrawalAllowed(\nuint256 starkKey,\n uint256 assetId,\n uint256 quantizedAmount\n );\n\n /*\n Transfers funds from the on-chain depositarea to the off-chain area.\n Implemented in the Deposits contracts.\n */\n function acceptDeposit(\n uint256 starkKey,\nuint256 vaultId,\n uint256 assetId,\n uint256 quantizedAmount\n ) internal virtual override {\n // Fetch deposit.\nrequire(\n pendingDeposits[starkKey][assetId][vaultId] \u003e= quantizedAmount,\n \"DEPOSIT_INSUFFICIENT\"\n );\n\n// Subtract accepted quantized amount.\n pendingDeposits[starkKey][assetId][vaultId] -= quantizedAmount;\n }\n\n /*\nTransfers funds from the off-chain area to the on-chain withdrawal area.\n */\n function allowWithdrawal(\n uint256 starkKey,\nuint256 assetId,\n uint256 quantizedAmount\n )\n internal\n override\n {\n // Fetch withdrawal.\n uint256withdrawal = pendingWithdrawals[starkKey][assetId];\n\n // Add accepted quantized amount.\n withdrawal += quantizedAmount;\nrequire(withdrawal \u003e= quantizedAmount, \"WITHDRAWAL_OVERFLOW\");\n\n // Store withdrawal.\npendingWithdrawals[starkKey][assetId] = withdrawal;\n\n // Log event.\n uint256 presumedAssetType = assetId;\n if(registeredAssetType[presumedAssetType]) {\n emit LogWithdrawalAllowed(\n starkKey,\n presumedAssetType,\nfromQuantized(presumedAssetType, quantizedAmount),\n quantizedAmount\n );\n } else if(assetId ==((assetId \u0026 MASK_240) | STARKEX_MINTABLE_ASSET_ID_FLAG)) {\n emit LogMintableWithdrawalAllowed(\n starkKey,\nassetId,\n quantizedAmount\n );\n }\n else {\n // In ERC721 case, assetId is not theassetType.\n require(withdrawal \u003c= 1, \"INVALID_NFT_AMOUNT\");\n emit LogNftWithdrawalAllowed(starkKey, assetId);\n}\n }\n\n // Verifier authorizes withdrawal.\n function acceptWithdrawal(\n uint256 starkKey,\n uint256 assetId,\nuint256 quantizedAmount\n ) internal virtual override {\n allowWithdrawal(starkKey, assetId, quantizedAmount);\n }\n}\n"},"ActionHash.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n Youmay not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\"BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governingpermissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"MainStorage.sol\";\nimport \"LibConstants.sol\";\n\n/*\n Calculation action hash for the various forced actions in a generic manner.\n*/\ncontract ActionHashis MainStorage , LibConstants{\n\n function getActionHash(string memory actionName, bytes memory packedActionParameters)\n internal\npure\n returns(bytes32 actionHash)\n {\n actionHash = keccak256(abi.encodePacked(actionName, packedActionParameters));\n}\n\n function setActionHash(bytes32 actionHash, bool premiumCost) internal\n {\n // The rate of forced trade requests is restricted.\n // First restriction is by capping the number of requests in a block.\n // User can override this cap by requesting with apermium flag set,\n // in this case, the gas cost is high (~1M) but no \"technical\" limit is set.\n // However, the high gas costcreates an obvious limitation due to the block gas limit.\n if (premiumCost) {\n for (uint256 i = 0; i \u003c 22231; i++) {}\n} else {\n require(\n forcedRequestsInBlock[block.number] \u003c MAX_FORCED_ACTIONS_REQS_PER_BLOCK,\n\"MAX_REQUESTS_PER_BLOCK_REACHED\");\n forcedRequestsInBlock[block.number] += 1;\n }\n forcedActionRequests[actionHash] =block.timestamp;\n }\n}\n"},"Common.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License,Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\nhttps://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under theLicense is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License forthe specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/*\n Common Utility librarries.\n I. Addresses (extending address).\n*/\nlibrary Addresses {\n function isContract(address account)internal view returns (bool) {\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size\u003e 0;\n }\n\n function performEthTransfer(address recipient, uint256 amount) internal {\n (bool success, ) = recipient.call{value:amount}(\"\"); // NOLINT: low-level-calls.\n require(success, \"ETH_TRANSFER_FAILED\");\n }\n\n /*\n Safe wrapper around ERC20/ERC721 calls.\n This is required because many deployed ERC20 contracts don\u0027t return a value.\n See https://github.com/ethereum/solidity/issues/4116.\n */\n function safeTokenContractCall(address tokenAddress, bytes memory callData) internal {\n require(isContract(tokenAddress), \"BAD_TOKEN_ADDRESS\");\n // NOLINTNEXTLINE: low-level-calls.\n (bool success, bytes memory returndata) =tokenAddress.call(callData);\n require(success, string(returndata));\n\n if (returndata.length \u003e 0) {\n require(abi.decode(returndata, (bool)), \"TOKEN_OPERATION_FAILED\");\n }\n }\n\n /*\n Similar to safeTokenContractCall, but always ignoresthe return value.\n\n Assumes some other method is used to detect the failures\n (e.g. balance is checked before and after the call).\n*/\n function uncheckedTokenContractCall(address tokenAddress, bytes memory callData) internal {\n // NOLINTNEXTLINE: low-level-calls.\n (bool success, bytes memory returndata) = tokenAddress.call(callData);\n require(success, string(returndata));\n}\n\n}\n\nlibrary UintArray {\n function hashSubArray(uint256[] memory array, uint256 subArrayStart, uint256 subArraySize)\n internalpure\n returns(bytes32 subArrayHash)\n {\n require(array.length \u003e= subArrayStart + subArraySize,\"ILLEGAL_SUBARRAY_DIMENSIONS\");\n uint256 startOffsetBytes = 0x20 * (1 + subArrayStart);\n uint256 dataSizeBytes = 0x20 *subArraySize;\n assembly {\n subArrayHash := keccak256(add(array, startOffsetBytes), dataSizeBytes)\n }\n }\n\n /*\nReturns the address of a cell in offset within a uint256[] array.\n This allows assigning new variable of dynamic unit256[] pointing to asub_array\n with a layout of serialied uint256[] (i.e. length+content).\n */\n function extractSerializedUintArray(uint256[] memoryprogramOutput, uint256 offset)\n internal pure\n returns (uint256[] memory addr)\n {\n uint256 memOffset = 0x20 * (offset +1);\n assembly {\n addr := add(programOutput, memOffset)\n }\n }\n\n}\n\n/*\n II. StarkExTypes - Common data types.\n*/\nlibrary StarkExTypes {\n\n // Structure representing a list of verifiers (validity/availability).\n // A statement is valid only if allthe verifiers in the list agree on it.\n // Adding a verifier to the list is immediate - this is used for fast resolution of\n // anysoundness issues.\n // Removing from the list is time-locked, to ensure that any user of the system\n // not content with the announcedremoval has ample time to leave the system before it is\n // removed.\n struct ApprovalChainData {\n address[] list;\n //Represents the time after which the verifier with the given address can be removed.\n // Removal of the verifier with address A is allowedonly in the case the value\n // of unlockedForRemovalTime[A] != 0 and unlockedForRemovalTime[A] \u003c (current time).\n mapping(address =\u003e uint256) unlockedForRemovalTime;\n }\n}\n"},"Deposits.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\nLicensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You mayobtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressor implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"LibConstants.sol\";\nimport \"MAcceptModifications.sol\";\nimport\"MTokenQuantization.sol\";\nimport \"TokenAssetData.sol\";\nimport \"MFreezable.sol\";\nimport \"MKeyGetters.sol\";\nimport \"MTokens.sol\";\nimport \"MainStorage.sol\";\n\n/**\n For a user to perform a deposit to the contract two calls need to take place:\n\n 1. A call to an ERC20contract, authorizing this contract to transfer funds on behalf of the user.\n 2. A call to :sol:func:`deposit` indicating the starkKey, amount,asset type and target vault ID to which to send the deposit.\n\n The amount should be quantized, according to the specific quantization definedfor the asset type.\n\n The result of the operation, assuming all requirements are met, is that an amount of ERC20 tokens\n equaling the amountspecified in the :sol:func:`deposit` call times the quantization factor is\n transferred on behalf of the user to the contract. In addition, thecontract adds the funds to an\n accumulator of pending deposits for the provided user, asset ID and vault ID.\n\n Once a deposit is made, theexchange may include it in a proof which will result in addition\n of the amount(s) deposited to the off-chain vault with the specified ID. Whenthe contract\n receives such valid proof, it deducts the transfered funds from the pending deposits for the\n specified Stark key, asset ID andvault ID.\n\n The exchange will not be able to move the deposited funds to the off-chain vault if the Stark key\n is not registered in the system.\n\n Until that point, the user may cancel the deposit by performing a time-locked cancel-deposit\n operation consisting of two calls:\n\n 1. Acall to :sol:func:`depositCancel`, setting a timer to enable reclaiming the deposit. Until this timer expires the user cannot reclaim funds as theexchange may still be processing the deposit for inclusion in the off chain vault.\n 2. A call to :sol:func:`depositReclaim`, to perform theactual transfer of funds from the contract back to the ERC20 contract. This will only succeed if the timer set in the previous call has expired.The result should be the transfer of all funds not accounted for in proofs for off-chain inclusion, back to the user account on the ERC20 contract.\n\n Calling depositCancel and depositReclaim can only be done via an ethKey that is associated with\n that vault\u0027s starkKey. This isenforced by the contract.\n\n*/\nabstract contract Deposits is\n MainStorage,\n LibConstants,\n MAcceptModifications,\nMTokenQuantization,\n TokenAssetData,\n MFreezable,\n MKeyGetters,\n MTokens\n{\n event LogDeposit(\n address depositorEthKey,\n uint256 starkKey,\n uint256 vaultId,\n uint256 assetType,\n uint256 nonQuantizedAmount,\n uint256quantizedAmount\n );\n\n event LogNftDeposit(\n address depositorEthKey,\n uint256 starkKey,\n uint256 vaultId,\nuint256 assetType,\n uint256 tokenId,\n uint256 assetId\n );\n\n event LogDepositCancel(uint256 starkKey, uint256 vaultId,uint256 assetId);\n\n event LogDepositCancelReclaimed(\n uint256 starkKey,\n uint256 vaultId,\n uint256 assetType,\nuint256 nonQuantizedAmount,\n uint256 quantizedAmount\n );\n\n event LogDepositNftCancelReclaimed(\n uint256 starkKey,\nuint256 vaultId,\n uint256 assetType,\n uint256 tokenId,\n uint256 assetId\n );\n\n function getDepositBalance(\nuint256 starkKey,\n uint256 assetId,\n uint256 vaultId\n ) external view returns (uint256 balance) {\n uint256presumedAssetType = assetId;\n balance = fromQuantized(presumedAssetType, pendingDeposits[starkKey][assetId][vaultId]);\n }\n\nfunction getQuantizedDepositBalance(\n uint256 starkKey,\n uint256 assetId,\n uint256 vaultId\n ) external view returns(uint256 balance) {\n balance = pendingDeposits[starkKey][assetId][vaultId];\n }\n\n function depositNft(\n uint256 starkKey,\nuint256 assetType,\n uint256 vaultId,\n uint256 tokenId\n ) external notFrozen()\n {\n require(vaultId \u003c=STARKEX_MAX_VAULT_ID, \"OUT_OF_RANGE_VAULT_ID\");\n // starkKey must be registered.\n require(ethKeys[starkKey] != ZERO_ADDRESS,\"INVALID_STARK_KEY\");\n require(!isMintableAssetType(assetType), \"MINTABLE_ASSET_TYPE\");\n require(!isFungibleAssetType(assetType), \"FUNGIBLE_ASSET_TYPE\");\n uint256 assetId = calculateNftAssetId(assetType, tokenId);\n\n // Update the balance.\npendingDeposits[starkKey][assetId][vaultId] = 1;\n\n // Disable the cancellationRequest timeout when users deposit into their own account.\nif (isMsgSenderStarkKeyOwner(starkKey) \u0026\u0026\n cancellationRequests[starkKey][assetId][vaultId] != 0) {\ndelete cancellationRequests[starkKey][assetId][vaultId];\n }\n\n // Transfer the tokens to the Deposit contract.\ntransferInNft(assetType, tokenId);\n\n // Log event.\n emit LogNftDeposit(msg.sender, starkKey, vaultId, assetType, tokenId, assetId);\n }\n\n function getCancellationRequest(\n uint256 starkKey,\n uint256 assetId,\n uint256 vaultId\n ) externalview returns (uint256 request) {\n request = cancellationRequests[starkKey][assetId][vaultId];\n }\n\n function deposit(\nuint256 starkKey,\n uint256 assetType,\n uint256 vaultId,\n uint256 quantizedAmount\n ) public notFrozen()\n {\n// The vaultId is not validated but should be in the allowed range supported by the\n // exchange. If not, it will be ignored by theexchange and the starkKey owner may reclaim\n // the funds by using depositCancel + depositReclaim.\n\n // No need to verify amount\u003e 0, a deposit with amount = 0 can be used to undo cancellation.\n // starkKey must be registered.\n require(ethKeys[starkKey] != ZERO_ADDRESS, \"INVALID_STARK_KEY\");\n require(!isMintableAssetType(assetType), \"MINTABLE_ASSET_TYPE\");\n require(isFungibleAssetType(assetType), \"NON_FUNGIBLE_ASSET_TYPE\");\n uint256 assetId = assetType;\n\n // Update the balance.\npendingDeposits[starkKey][assetId][vaultId] += quantizedAmount;\n require(\n pendingDeposits[starkKey][assetId][vaultId] \u003e=quantizedAmount,\n \"DEPOSIT_OVERFLOW\"\n );\n\n // Disable the cancellationRequest timeout when users deposit into theirown account.\n if (isMsgSenderStarkKeyOwner(starkKey) \u0026\u0026\n cancellationRequests[starkKey][assetId][vaultId] != 0){\n delete cancellationRequests[starkKey][assetId][vaultId];\n }\n\n // Transfer the tokens to the Deposit contract.\ntransferIn(assetType, quantizedAmount);\n\n // Log event.\n emit LogDeposit(\n msg.sender,\n starkKey,\nvaultId,\n assetType,\n fromQuantized(assetType, quantizedAmount),\n quantizedAmount\n );\n}\n\n function deposit( // NOLINT: locked-ether.\n uint256 starkKey,\n uint256 assetType,\n uint256 vaultId\n ) externalpayable {\n require(isEther(assetType), \"INVALID_ASSET_TYPE\");\n deposit(starkKey, assetType, vaultId, toQuantized(assetType, msg.value));\n }\n\n function depositCancel(\n uint256 starkKey,\n uint256 assetId,\n uint256 vaultId\n )\nexternal\n isSenderStarkKey(starkKey)\n // No notFrozen modifier: This function can always be used, even when frozen.\n {\n\n// Start the timeout.\n cancellationRequests[starkKey][assetId][vaultId] = block.timestamp;\n\n // Log event.\n emitLogDepositCancel(starkKey, vaultId, assetId);\n }\n\n function depositReclaim(\n uint256 starkKey,\n uint256 assetId,\nuint256 vaultId\n )\n external\n isSenderStarkKey(starkKey)\n // No notFrozen modifier: This function can always be used, evenwhen frozen.\n {\n uint256 assetType = assetId;\n\n // Make sure enough time has passed.\n uint256 requestTime =cancellationRequests[starkKey][assetId][vaultId];\n require(requestTime != 0, \"DEPOSIT_NOT_CANCELED\");\n uint256 freeTime =requestTime + DEPOSIT_CANCEL_DELAY;\n assert(freeTime \u003e= DEPOSIT_CANCEL_DELAY);\n require(block.timestamp \u003e= freeTime,\"DEPOSIT_LOCKED\"); // NOLINT: timestamp.\n\n // Clear deposit.\n uint256 quantizedAmount =pendingDeposits[starkKey][assetId][vaultId];\n delete pendingDeposits[starkKey][assetId][vaultId];\n deletecancellationRequests[starkKey][assetId][vaultId];\n\n // Refund deposit.\n transferOut(msg.sender, assetType, quantizedAmount);\n\n// Log event.\n emit LogDepositCancelReclaimed(\n starkKey,\n vaultId,\n assetType,\nfromQuantized(assetType, quantizedAmount),\n quantizedAmount\n );\n }\n\n function depositNftReclaim(\n uint256starkKey,\n uint256 assetType,\n uint256 vaultId,\n uint256 tokenId\n )\n external\n isSenderStarkKey(starkKey)\n // No notFrozen modifier: This function can always be used, even when frozen.\n {\n require(vaultId \u003c=STARKEX_MAX_VAULT_ID, \"OUT_OF_RANGE_VAULT_ID\");\n\n // assetId is the id for the deposits/withdrawals.\n // equivalent for theusage of assetType for ERC20.\n uint256 assetId = calculateNftAssetId(assetType, tokenId);\n\n // Make sure enough time has passed.\nuint256 requestTime = cancellationRequests[starkKey][assetId][vaultId];\n require(requestTime != 0, \"DEPOSIT_NOT_CANCELED\");\nuint256 freeTime = requestTime + DEPOSIT_CANCEL_DELAY;\n assert(freeTime \u003e= DEPOSIT_CANCEL_DELAY);\n require(block.timestamp\u003e= freeTime, \"DEPOSIT_LOCKED\");\n\n // Clear deposit.\n uint256 amount = pendingDeposits[starkKey][assetId][vaultId];\ndelete pendingDeposits[starkKey][assetId][vaultId];\n delete cancellationRequests[starkKey][assetId][vaultId];\n\n if (amount \u003e0) {\n // Refund deposit.\n transferOutNft(msg.sender, assetType, tokenId);\n\n // Log event.\n emitLogDepositNftCancelReclaimed(starkKey, vaultId, assetType, tokenId, assetId);\n }\n }\n}\n"},"ERC721Receiver.sol":{"content":"/*\nCopyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this fileexcept in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unlessrequired by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUTWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n andlimitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"IERC721Receiver.sol\";\n\n/*\nERC721 token receiver interface\n EIP-721 requires any contract receiving ERC721 tokens to implement IERC721Receiver interface.\n By EIP,safeTransferFrom API of ERC721 shall call onERC721Received on the receiving contract.\n\n Have the receiving contract failed to respond asexpected, the safeTransferFrom shall be reverted.\n\n Params:\n `operator` The address which called `safeTransferFrom` function\n `from` Theaddress which previously owned the token\n `tokenId` The NFT identifier which is being transferred\n `data` Additional data with no specifiedformat\n\n Returns: fixed value:`bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`.\n*/\ncontract ERC721Receiver isIERC721Receiver {\n // NOLINTNEXTLINE: external-function.\n function onERC721Received(\n address /*operator*/, // The address whichcalled `safeTransferFrom` function.\n address /*from*/, // The address which previously owned the token.\n uint256 /*tokenId*/, //The NFT identifier which is being transferred.\n bytes memory /*data*/) // Additional data with no specified format.\n externaloverride returns (bytes4)\n {\n return this.onERC721Received.selector;\n }\n}\n"},"Freezable.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except incompliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required byapplicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under theLicense.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"LibConstants.sol\";\nimport \"MFreezable.sol\";\nimport\"MGovernance.sol\";\nimport \"MainStorage.sol\";\n\n/*\n Implements MFreezable.\n*/\nabstract contract Freezable is MainStorage, LibConstants,MGovernance, MFreezable {\n event LogFrozen();\n event LogUnFrozen();\n\n function isFrozen() public view override returns (bool) {\nreturn stateFrozen;\n }\n\n function validateFreezeRequest(uint256 requestTime) internal override {\n require(requestTime != 0,\"FORCED_ACTION_UNREQUESTED\");\n // Verify timer on escape request.\n uint256 freezeTime = requestTime + FREEZE_GRACE_PERIOD;\n\n// Prevent wraparound.\n assert(freezeTime \u003e= FREEZE_GRACE_PERIOD);\n require(block.timestamp \u003e= freezeTime,\"FORCED_ACTION_PENDING\"); // NOLINT: timestamp.\n\n // Forced action requests placed before freeze, are no longer valid after the un-freeze.\n require(freezeTime \u003e unFreezeTime, \"REFREEZE_ATTEMPT\");\n }\n\n function freeze()\n internal\noverride\n notFrozen()\n {\n unFreezeTime = block.timestamp + UNFREEZE_DELAY;\n\n // Update state.\n stateFrozen =true;\n\n // Log event.\n emit LogFrozen();\n }\n\n function unFreeze()\n external\n onlyFrozen()\nonlyGovernance()\n {\n require(block.timestamp \u003e= unFreezeTime, \"UNFREEZE_NOT_ALLOWED_YET\");\n\n // Update state.\nstateFrozen = false;\n\n // Increment roots to invalidate them, w/o losing information.\n vaultRoot += 1;\n orderRoot += 1;\n\n // Log event.\n emit LogUnFrozen();\n }\n\n}\n"},"Governance.sol":{"content":"/*\n Copyright 2019,2020 StarkWare IndustriesLtd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to inwriting,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, eitherexpress or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"GovernanceStorage.sol\";\nimport \"MGovernance.sol\";\n\n/*\n Implements GenericGovernance, applicable for both proxy and main contract, and possibly others.\n Notes:\n 1. This class is virtual (getGovernanceTag is notimplemented).\n 2. The use of the same function names by both the Proxy and a delegated implementation\n is not possible since calling theimplementation functions is done via the default function\n of the Proxy. For this reason, for example, the implementation of MainContract(MainGovernance)\n exposes mainIsGovernor, which calls the internal isGovernor method.\n*/\nabstract contract Governance is GovernanceStorage,MGovernance {\n event LogNominatedGovernor(address nominatedGovernor);\n event LogNewGovernorAccepted(address acceptedGovernor);\n eventLogRemovedGovernor(address removedGovernor);\n event LogNominationCancelled();\n\n /*\n Returns a string which uniquely identifies thetype of the governance mechanism.\n */\n function getGovernanceTag()\n virtual\n internal\n pure\n returns(string memory);\n\n /*\n Returns the GovernanceInfoStruct associated with the governance tag.\n */\n function contractGovernanceInfo()\n internal\n view\n returns (GovernanceInfoStruct storage) {\n string memory tag = getGovernanceTag();\nGovernanceInfoStruct storage gub = governanceInfo[tag];\n require(gub.initialized, \"NOT_INITIALIZED\");\n return gub;\n }\n\n/*\n Current code intentionally prevents governance re-initialization.\n This may be a problem in an upgrade situation, in a case thatthe upgrade-to implementation\n performs an initialization (for real) and within that calls initGovernance().\n\n Possible workarounds:\n1. Clearing the governance info altogether by changing the MAIN_GOVERNANCE_INFO_TAG.\n This will remove existing main governanceinformation.\n 2. Modify the require part in this function, so that it will exit quietly\n when trying to re-initialize (uncomment thelines below).\n */\n function initGovernance()\n internal\n {\n string memory tag = getGovernanceTag();\nGovernanceInfoStruct storage gub = governanceInfo[tag];\n require(!gub.initialized, \"ALREADY_INITIALIZED\");\n gub.initialized =true; // to ensure addGovernor() won\u0027t fail.\n // Add the initial governer.\n addGovernor(msg.sender);\n }\n\n modifieronlyGovernance () override\n {\n require(isGovernor(msg.sender), \"ONLY_GOVERNANCE\");\n _;\n }\n\n function isGovernor(address testGovernor)\n internal view\n returns (bool addressIsGovernor){\n GovernanceInfoStruct storage gub =contractGovernanceInfo();\n addressIsGovernor = gub.effectiveGovernors[testGovernor];\n }\n\n /*\n Cancels the nomination of agovernor candidate.\n */\n function cancelNomination() internal onlyGovernance() {\n GovernanceInfoStruct storage gub =contractGovernanceInfo();\n gub.candidateGovernor = address(0x0);\n emit LogNominationCancelled();\n }\n\n functionnominateNewGovernor(address newGovernor) internal onlyGovernance() {\n GovernanceInfoStruct storage gub = contractGovernanceInfo();\nrequire(!isGovernor(newGovernor), \"ALREADY_GOVERNOR\");\n gub.candidateGovernor = newGovernor;\n emit LogNominatedGovernor(newGovernor);\n }\n\n /*\n The addGovernor is called in two cases:\n 1. by acceptGovernance when a new governor accepts its role.\n 2. by initGovernance to add the initial governor.\n The difference is that the init path skips the nominate step\n that wouldfail because of the onlyGovernance modifier.\n */\n function addGovernor(address newGovernor) private {\n require(!isGovernor(newGovernor), \"ALREADY_GOVERNOR\");\n GovernanceInfoStruct storage gub = contractGovernanceInfo();\n gub.effectiveGovernors[newGovernor] = true;\n }\n\n function acceptGovernance()\n internal\n {\n // The new governor wasproposed as a candidate by the current governor.\n GovernanceInfoStruct storage gub = contractGovernanceInfo();\n require(msg.sender== gub.candidateGovernor, \"ONLY_CANDIDATE_GOVERNOR\");\n\n // Update state.\n addGovernor(gub.candidateGovernor);\n gub.candidateGovernor = address(0x0);\n\n // Send a notification about the change of governor.\n emit LogNewGovernorAccepted(msg.sender);\n }\n\n /*\n Remove a governor from office.\n */\n function removeGovernor(address governorForRemoval) internal onlyGovernance() {\n require(msg.sender != governorForRemoval, \"GOVERNOR_SELF_REMOVE\");\n GovernanceInfoStruct storage gub =contractGovernanceInfo();\n require (isGovernor(governorForRemoval), \"NOT_GOVERNOR\");\n gub.effectiveGovernors[governorForRemoval]= false;\n emit LogRemovedGovernor(governorForRemoval);\n }\n}\n"},"GovernanceStorage.sol":{"content":"/*\n Copyright 2019,2020StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliancewith the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicablelaw or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OFANY KIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/*\n Holds the governance slots for ALL entities, including proxy and themain contract.\n*/\ncontract GovernanceStorage {\n\n struct GovernanceInfoStruct {\n mapping (address =\u003e bool) effectiveGovernors;\naddress candidateGovernor;\n bool initialized;\n }\n\n // A map from a Governor tag to its own GovernanceInfoStruct.\nmapping (string =\u003e GovernanceInfoStruct) internal governanceInfo;\n}\n"},"Identity.sol":{"content":"/*\n Copyright 2019,2020 StarkWareIndustries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with theLicense.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law oragreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n//SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\ninterface Identity {\n\n /*\n Allows a caller, typically another contract,\n to ensure that the provided address is of the expected type and version.\n */\n function identify()\n external pure\nreturns(string memory);\n}\n"},"IERC20.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License,Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\nhttps://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under theLicense is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License forthe specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/*\n Interface of the ERC20 standard as defined in the EIP. Does not include\n the optional functions; to access them see{ERC20Detailed}.\n*/\ninterface IERC20 {\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address account)external view returns (uint256);\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function transferFrom(address sender, address recipient, uint256 amount)\n external returns (bool);\n\n event Transfer(addressindexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"},"IERC721Receiver.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the\"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License isdistributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specificlanguage governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\ninterface IERC721Receiver {\n function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)\nexternal returns (bytes4);\n}\n"},"IFactRegistry.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under theApache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of theLicense at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n softwaredistributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/*\n The Fact Registry design pattern is a way to separate cryptographic verification from the\n business logic ofthe contract flow.\n\n A fact registry holds a hash table of verified \"facts\" which are represented by a hash of claims\n that the registryhash check and found valid. This table may be queried by accessing the\n isValid() function of the registry with a given hash.\n\n In addition,each fact registry exposes a registry specific function for submitting new claims\n together with their proofs. The information submitted variesfrom one registry to the other\n depending of the type of fact requiring verification.\n\n For further reading on the Fact Registry designpattern see this\n `StarkWare blog post \u003chttps://medium.com/starkware/the-fact-registry-a64aafb598b6\u003e`_.\n*/\ninterface IFactRegistry{\n /*\n Returns true if the given fact was previously registered in the contract.\n */\n function isValid(bytes32 fact)\nexternal view\n returns(bool);\n}\n"},"KeyGetters.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed underthe Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy ofthe License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n softwaredistributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"MainStorage.sol\";\nimport \"MKeyGetters.sol\";\n\n/*\n Implements MKeyGetters.\n*/\ncontract KeyGettersis MainStorage, MKeyGetters {\n function getEthKey(uint256 starkKey) public view\n override returns (address ethKey) {\n // Fetchthe user\u0027s Ethereum key.\n ethKey = ethKeys[starkKey];\n require(ethKey != address(0x0), \"USER_UNREGISTERED\");\n }\n\nfunction isMsgSenderStarkKeyOwner(uint256 starkKey) internal view\n override returns (bool) {\n return msg.sender == getEthKey(starkKey);\n }\n\n modifier isSenderStarkKey(uint256 starkKey) override {\n // Require the calling user to own the stark key.\nrequire(isMsgSenderStarkKeyOwner(starkKey), \"MISMATCHING_STARK_ETH_KEYS\");\n _;\n }\n}\n"},"LibConstants.sol":{"content":"/*\nCopyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this fileexcept in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unlessrequired by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUTWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n andlimitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\ncontract LibConstants {\n // Durationsfor time locked mechanisms (in seconds).\n // Note that it is known that miners can manipulate block timestamps\n // up to a deviation of afew seconds.\n // This mechanism should not be used for fine grained timing.\n\n // The time required to cancel a deposit, in the case theoperator does not move the funds\n // to the off-chain storage.\n uint256 public constant DEPOSIT_CANCEL_DELAY = 7 days;\n\n // The timerequired to freeze the exchange, in the case the operator does not execute a\n // requested full withdrawal.\n uint256 public constantFREEZE_GRACE_PERIOD = 14 days;\n\n // The time after which the exchange may be unfrozen after it froze. This should be enough time\n // forusers to perform escape hatches to get back their funds.\n uint256 public constant UNFREEZE_DELAY = 365 days;\n\n // Maximal number ofverifiers which may co-exist.\n uint256 public constant MAX_VERIFIER_COUNT = uint256(64);\n\n // The time required to remove a verifier incase of a verifier upgrade.\n uint256 public constant VERIFIER_REMOVAL_DELAY = FREEZE_GRACE_PERIOD + (21 days);\n\n address constantZERO_ADDRESS = address(0x0);\n\n uint256 constant K_MODULUS =\n 0x800000000000011000000000000000000000000000000000000000000000001;\n\nuint256 constant K_BETA =\n 0x6f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e89;\n\n uint256 internal constant MASK_250 =\n0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n uint256 internal constant MASK_240 =\n0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant MAX_FORCED_ACTIONS_REQS_PER_BLOCK = 10;\n\n //======================================================\n // StarkEx specific constants\n //======================================================\n uint256 constant STARKEX_MAX_VAULT_ID = 2**31 - 1;\n uint256 constantSTARKEX_MAX_QUANTUM = 2**128 - 1;\n uint256 constant STARKEX_EXPIRATION_TIMESTAMP_BITS = 22;\n uint256 internal constantSTARKEX_MINTABLE_ASSET_ID_FLAG = 1\u003c\u003c250;\n\n // ======================================================\n // StarkExspecific constants\n // ======================================================\n uint256 constant PERPETUAL_POSITION_ID_UPPER_BOUND = 2**64;\n uint256 constant PERPETUAL_AMOUNT_UPPER_BOUND = 2**64;\n uint256 constant PERPETUAL_TIMESTAMP_BITS = 32;\n uint256 constantPERPETUAL_ASSET_ID_UPPER_BOUND = 2**120;\n uint256 constant PERPETUAL_SYSTEM_TIME_LAG_BOUND = 14 days;\n uint256 constantPERPETUAL_SYSTEM_TIME_ADVANCE_BOUND = 4 hours;\n uint256 constant PERPETUAL_CONFIGURATION_DELAY = 0;\n}\n"},"MAcceptModifications.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You maynot use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\"BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governingpermissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\n/*\n Interfacecontaining actions a verifier can invoke on the state.\n The contract containing the state should implement these and verify correctness.\n*/\nabstract contract MAcceptModifications {\n\n function acceptDeposit(\n uint256 starkKey,\n uint256 vaultId,\n uint256assetId,\n uint256 quantizedAmount\n )\n internal virtual;\n\n function allowWithdrawal(\n uint256 starkKey,\nuint256 assetId,\n uint256 quantizedAmount\n )\n internal virtual;\n\n function acceptWithdrawal(\n uint256 starkKey,\nuint256 assetId,\n uint256 quantizedAmount\n )\n internal virtual;\n\n}\n"},"MainGovernance.sol":{"content":"/*\n Copyright2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except incompliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required byapplicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under theLicense.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"Governance.sol\";\n\n/**\n The StarkEx contract isgoverned by one or more Governors of which the initial one is the\n deployer of the contract.\n\n A governor has the sole authority to performthe following operations:\n\n 1. Nominate additional governors (:sol:func:`mainNominateNewGovernor`)\n 2. Remove other governors (:sol:func:`mainRemoveGovernor`)\n 3. Add new :sol:mod:`Verifiers` and :sol:mod:`AvailabilityVerifiers`\n 4. Remove :sol:mod:`Verifiers` and :sol:mod:`AvailabilityVerifiers` after a timelock allows it\n 5. Nominate Operators (see :sol:mod:`Operator`) and Token Administrators (see :sol:mod:`Tokens`)\n\n Adding governors is performed in a two step procedure:\n\n 1. First, an existing governor nominates a new governor (:sol:func:`mainNominateNewGovernor`)\n 2. Then, the new governor must accept governance to become a governor (:sol:func:`mainAcceptGovernance`)\n\n Thistwo step procedure ensures that a governor public key cannot be nominated unless there is an\n entity that has the corresponding private key. Thisis intended to prevent errors in the addition\n process.\n\n The governor private key should typically be held in a secure cold wallet.\n*/\n/*\nImplements Governance for the StarkDex main contract.\n The wrapper methods (e.g. mainIsGovernor wrapping isGovernor) are needed to give\n themethod unique names.\n Both Proxy and StarkExchange inherit from Governance. Thus, the logical contract method names\n must have unique names inorder for the proxy to successfully delegate to them.\n*/\ncontract MainGovernance is Governance {\n\n // The tag is the sting key that is usedin the Governance storage mapping.\n string public constant MAIN_GOVERNANCE_INFO_TAG = \"StarkEx.Main.2019.GovernorsInformation\";\n\nfunction getGovernanceTag()\n internal\n pure\n override\n returns (string memory tag) {\n tag =MAIN_GOVERNANCE_INFO_TAG;\n }\n\n function mainIsGovernor(address testGovernor) external view returns (bool) {\n return isGovernor(testGovernor);\n }\n\n function mainNominateNewGovernor(address newGovernor) external {\n nominateNewGovernor(newGovernor);\n}\n\n function mainRemoveGovernor(address governorForRemoval) external {\n removeGovernor(governorForRemoval);\n }\n\n functionmainAcceptGovernance()\n external\n {\n acceptGovernance();\n }\n\n function mainCancelNomination() external {\ncancelNomination();\n }\n\n}\n"},"MainStorage.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under theApache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of theLicense at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n softwaredistributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"IFactRegistry.sol\";\nimport \"ProxyStorage.sol\";\nimport \"Common.sol\";\n/*\n Holds ALL the maincontract state (storage) variables.\n*/\ncontract MainStorage is ProxyStorage {\n\n uint256 constant internal LAYOUT_LENGTH = 2**64;\n\nIFactRegistry escapeVerifier_;\n\n // Global dex-frozen flag.\n bool stateFrozen; // NOLINT: constable-states.\n\n // Time when unFreeze can be successfully called (UNFREEZE_DELAY after freeze).\n uint256 unFreezeTime; //NOLINT: constable-states.\n\n // Pending deposits.\n // A map STARK key =\u003e asset id =\u003e vault id =\u003e quantized amount.\nmapping (uint256 =\u003e mapping (uint256 =\u003e mapping (uint256 =\u003e uint256))) pendingDeposits;\n\n // Cancellation requests.\n // Amap STARK key =\u003e asset id =\u003e vault id =\u003e request timestamp.\n mapping (uint256 =\u003e mapping (uint256 =\u003e mapping (uint256=\u003e uint256))) cancellationRequests;\n\n // Pending withdrawals.\n // A map STARK key =\u003e asset id =\u003e quantized amount.\nmapping (uint256 =\u003e mapping (uint256 =\u003e uint256)) pendingWithdrawals;\n\n // vault_id =\u003e escape used boolean.\n mapping(uint256 =\u003e bool) escapesUsed;\n\n // Number of escapes that were performed when frozen.\n uint256 escapesUsedCount;// NOLINT: constable-states.\n\n // NOTE: fullWithdrawalRequests is deprecated, and replaced by forcedActionRequests.\n // NOLINTNEXTLINEnaming-convention.\n mapping (uint256 =\u003e mapping (uint256 =\u003e uint256)) fullWithdrawalRequests_DEPRECATED;\n\n // State sequencenumber.\n uint256 sequenceNumber; // NOLINT: constable-states uninitialized-state.\n\n // Vaults Tree Root \u0026Height.\n uint256 vaultRoot; // NOLINT: constable-states uninitialized-state.\n uint256 vaultTreeHeight;// NOLINT: constable-states uninitialized-state.\n\n // Order Tree Root \u0026 Height.\n uint256 orderRoot;// NOLINT: constable-states uninitialized-state.\n uint256 orderTreeHeight; // NOLINT: constable-statesuninitialized-state.\n\n // True if and only if the address is allowed to add tokens.\n mapping (address =\u003e bool) tokenAdmins;\n\n //True if and only if the address is allowed to register users.\n mapping (address =\u003e bool) userAdmins;\n\n // True if and only if theaddress is an operator (allowed to update state).\n mapping (address =\u003e bool) operators;\n\n // Mapping of contract ID to asset data.\nmapping (uint256 =\u003e bytes) assetTypeToAssetInfo; // NOLINT: uninitialized-state.\n\n // Mapping of registered contract IDs.\nmapping (uint256 =\u003e bool) registeredAssetType; // NOLINT: uninitialized-state.\n\n // Mapping from contract ID to quantum.\nmapping (uint256 =\u003e uint256) assetTypeToQuantum; // NOLINT: uninitialized-state.\n\n // This mapping is no longer in use, remains forbackwards compatibility.\n mapping (address =\u003e uint256) starkKeys_DEPRECATED; // NOLINT: naming-convention.\n\n // Mapping from STARKpublic key to the Ethereum public key of its owner.\n mapping (uint256 =\u003e address) ethKeys; // NOLINT: uninitialized-state.\n\n // Timelocked state transition and availability verification chain.\n StarkExTypes.ApprovalChainData verifiersChain;\n StarkExTypes.ApprovalChainData availabilityVerifiersChain;\n\n // Batch id of last accepted proof.\n uint256 lastBatchId; //NOLINT: constable-states uninitialized-state.\n\n // Mapping between sub-contract index to sub-contract address.\n mapping(uint256 =\u003eaddress) subContracts; // NOLINT: uninitialized-state.\n\n mapping (uint256 =\u003e bool) permissiveAssetType_DEPRECATED; // NOLINT:naming-convention.\n // ---- END OF MAIN STORAGE AS DEPLOYED IN STARKEX2.0 ----\n\n // Onchain-data version configured for the system.\nuint256 onchainDataVersion; // NOLINT: constable-states uninitialized-state.\n\n // Counter of forced action request inblock. The key is the block number.\n mapping(uint256 =\u003e uint256) forcedRequestsInBlock;\n\n // ForcedAction requests: actionHash=\u003e requestTime.\n mapping(bytes32 =\u003e uint256) forcedActionRequests;\n\n // Mapping for timelocked actions.\n // A actionKey=\u003e activation time.\n mapping (bytes32 =\u003e uint256) actionsTimeLock;\n\n // Reserved storage space for Extensibility.\n // Everyadded MUST be added above the end gap, and the __endGap size must be reduced\n // accordingly.\n // NOLINTNEXTLINE: naming-convention.\nuint256[LAYOUT_LENGTH - 36] private __endGap; // __endGap complements layout to LAYOUT_LENGTH.\n}\n"},"MFreezable.sol":{"content":"/*\n Copyright2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except incompliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required byapplicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under theLicense.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nabstract contract MFreezable {\n /*\n Returns true ifthe exchange is frozen.\n */\n function isFrozen() public view virtual returns (bool); // NOLINT: external-function.\n\n /*\n Forbidscalling the function if the exchange is frozen.\n */\n modifier notFrozen()\n {\n require(!isFrozen(), \"STATE_IS_FROZEN\");\n_;\n }\n\n function validateFreezeRequest(uint256 requestTime) internal virtual;\n\n /*\n Allows calling the function only if theexchange is frozen.\n */\n modifier onlyFrozen()\n {\n require(isFrozen(), \"STATE_NOT_FROZEN\");\n _;\n }\n\n /*\nFreezes the exchange.\n */\n function freeze() internal virtual;\n}\n"},"MGovernance.sol":{"content":"/*\n Copyright 2019,2020 StarkWareIndustries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with theLicense.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law oragreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n//SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nabstract contract MGovernance {\n /*\n Allows calling the function onlyby a Governor.\n */\n modifier onlyGovernance () virtual; // NOLINT incorrect-modifier.\n}\n"},"MKeyGetters.sol":{"content":"/*\n Copyright2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except incompliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required byapplicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under theLicense.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nabstract contract MKeyGetters {\n // NOLINTNEXTLINE: external-function.\n function getEthKey(uint256 starkKey) public view virtual returns (address ethKey);\n\n function isMsgSenderStarkKeyOwner(uint256starkKey) internal view virtual returns (bool);\n\n /*\n Allows calling the function only if starkKey is registered to msg.sender.\n*/\n modifier isSenderStarkKey(uint256 starkKey) virtual; // NOLINT incorrect-modifier.\n}\n"},"MStarkExForcedActionState.sol":{"content":"/*\nCopyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this fileexcept in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unlessrequired by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUTWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n andlimitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nabstract contractMStarkExForcedActionState {\n function fullWithdrawActionHash(uint256 starkKey, uint256 vaultId)\n internal\n pure\nvirtual\n returns(bytes32);\n\n function clearFullWithdrawalRequest(uint256 starkKey, uint256 vaultId)\n internal\n virtual;\n\n // NOLINTNEXTLINE: external-function.\n function getFullWithdrawalRequest(uint256 starkKey, uint256 vaultId)\n public\nview\n virtual\n returns (uint256 res);\n\n function setFullWithdrawalRequest(uint256 starkKey, uint256 vaultId)\ninternal\n virtual;\n}\n"},"MTokenAssetData.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under theApache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of theLicense at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n softwaredistributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nabstract contract MTokenAssetData {\n\n // NOLINTNEXTLINE: external-function.\n function getAssetInfo(uint256assetType)\n public\n view\n virtual\n returns (bytes memory assetInfo);\n\n function extractTokenSelector(bytesmemory assetInfo)\n internal\n pure\n virtual\n returns (bytes4 selector);\n\n function isEther(uint256 assetType)\ninternal\n view\n virtual\n returns (bool);\n\n function isFungibleAssetType(uint256 assetType)\n internal\nview\n virtual\n returns (bool);\n\n function isMintableAssetType(uint256 assetType)\n internal\n view\nvirtual\n returns (bool);\n\n function extractContractAddress(bytes memory assetInfo)\n internal\n pure\nvirtual\n returns (address _contract);\n\n function calculateNftAssetId(uint256 assetType, uint256 tokenId)\n internal\npure\n virtual\n returns(uint256 assetId);\n\n function calculateMintableAssetId(uint256 assetType, bytes memory mintingBlob)\ninternal\n pure\n virtual\n returns(uint256 assetId);\n}\n"},"MTokenQuantization.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except incompliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required byapplicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under theLicense.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nabstract contract MTokenQuantization {\n functionfromQuantized(uint256 presumedAssetType, uint256 quantizedAmount)\n internal\n view\n virtual\n returns (uint256 amount);\n\n // NOLINTNEXTLINE: external-function.\n function getQuantum(uint256 presumedAssetType)\n public\n view\nvirtual\n returns (uint256 quantum);\n\n function toQuantized(uint256 presumedAssetType, uint256 amount)\n internal\nview\n virtual\n returns (uint256 quantizedAmount);\n}\n"},"MTokens.sol":{"content":"/*\n Copyright 2019,2020 StarkWare IndustriesLtd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to inwriting,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, eitherexpress or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nabstract contract MTokens {\n function transferIn(uint256 assetType, uint256quantizedAmount) internal virtual;\n\n function transferInNft(uint256 assetType, uint256 tokenId) internal virtual;\n\n function transferOut(address payable recipient, uint256 assetType, uint256 quantizedAmount)\n internal virtual;\n\n function transferOutNft(address recipient, uint256 assetType, uint256 tokenId) internal virtual;\n\n function transferOutMint(\n uint256 assetType, uint256 quantizedAmount, bytesmemory mintingBlob) internal virtual;\n}\n"},"PerpetualStorage.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensedunder the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain acopy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\nsoftware distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier:Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"MainStorage.sol\";\n\n/*\n Extends MainStorage, holds Perpetual App specific state (storage)variables.\n\n ALL State variables that are common to all applications, reside in MainStorage,\n whereas ALL the Perpetual app specific onesreside here.\n*/\ncontract PerpetualStorage is MainStorage {\n uint256 systemAssetType; // NOLINT: constable-statesuninitialized-state.\n\n bytes32 public globalConfigurationHash; // NOLINT: constable-states uninitialized-state.\n\n mapping(uint256=\u003e bytes32) public configurationHash; // NOLINT: uninitialized-state.\n\n bytes32 sharedStateHash; // NOLINT:constable-states uninitialized-state.\n\n // Configuration apply time-lock.\n // The delay is held in storage (and not constant)\n // Sothat it can be modified during upgrade.\n uint256 public configurationDelay; // NOLINT: constable-states.\n\n // Reserved storagespace for Extensibility.\n // Every added MUST be added above the end gap, and the __endGap size must be reduced\n // accordingly.\n //NOLINTNEXTLINE: naming-convention shadowing-abstract.\n uint256[LAYOUT_LENGTH - 5] private __endGap; // __endGap complements layout toLAYOUT_LENGTH.\n}\n"},"PerpetualTokens.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License,Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\nhttps://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under theLicense is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License forthe specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"Tokens.sol\";\nimport \"PerpetualStorage.sol\";\n\n/**\n Extensin of the Tokens contract for StarkPerpetual.\n\n The change isthat asset registration defines the system asset,\n and permitted only once.\n*/\nabstract contract PerpetualTokens is PerpetualStorage, Tokens{\n event LogSystemAssetType(uint256 assetType);\n\n function registerToken(\n uint256, /* assetType */\n bytes calldata /*assetInfo */\n ) external override {\n revert(\"UNSUPPORTED_FUNCTION\");\n }\n\n function registerToken(\n uint256, /*assetType */\n bytes memory, /* assetInfo */\n uint256 /* quantum */\n ) public override {\n revert(\"UNSUPPORTED_FUNCTION\");\n }\n\n // NOLINTNEXTLINE external-function.\n function getSystemAssetType() public view returns (uint256) {\nreturn systemAssetType;\n }\n\n function registerSystemAssetType(uint256 assetType, bytes calldata assetInfo)\n external\nonlyTokensAdmin\n {\n require(systemAssetType == uint256(0), \"SYSTEM_ASSET_TYPE_ALREADY_SET\");\n systemAssetType = assetType;\n super.registerToken(assetType, assetInfo, 1);\n emit LogSystemAssetType(assetType);\n }\n}\n"},"PerpetualTokensAndRamping.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You maynot use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\"BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governingpermissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport\"PerpetualTokens.sol\";\nimport \"ERC721Receiver.sol\";\nimport \"Freezable.sol\";\nimport \"KeyGetters.sol\";\nimport \"Users.sol\";\nimport\"MainGovernance.sol\";\nimport \"AcceptModifications.sol\";\nimport \"Deposits.sol\";\nimport \"StarkExForcedActionState.sol\";\nimport\"Withdrawals.sol\";\nimport \"SubContractor.sol\";\n\ncontract PerpetualTokensAndRamping is\n ERC721Receiver,\n SubContractor,\nFreezable,\n MainGovernance,\n AcceptModifications,\n StarkExForcedActionState,\n PerpetualTokens,\n KeyGetters,\n Users,\nDeposits,\n Withdrawals\n{\n function initialize(\n bytes calldata /* data */\n ) external override {\n revert(\"NOT_IMPLEMENTED\");\n }\n\n function initializerSize() external view override returns (uint256) {\n return 0;\n }\n\nfunction identify() external pure override returns (string memory) {\n return \"StarkWare_PerpetualTokensAndRamping_2020_1\";\n }\n}\n"},"ProxyStorage.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the\"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License isdistributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specificlanguage governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"GovernanceStorage.sol\";\n\n/*\n Holds the Proxy-specific state variables.\n This contract is inherited by the GovernanceStorage(and indirectly by MainStorage)\n to prevent collision hazard.\n*/\ncontract ProxyStorage is GovernanceStorage {\n\n // Stores the hash of theinitialization vector of the added implementation.\n // Upon upgradeTo the implementation, the initialization vector is verified\n // to beidentical to the one submitted when adding the implementation.\n mapping (address =\u003e bytes32) internal initializationHash;\n\n // Thetime after which we can switch to the implementation.\n mapping (address =\u003e uint256) internal enabledTime;\n\n // A central storage ofthe flags whether implementation has been initialized.\n // Note - it can be used flexibly enough to accommodate multiple levels ofinitialization\n // (i.e. using different key salting schemes for different initialization levels).\n mapping (bytes32 =\u003e bool) internalinitialized;\n}\n"},"StarkExForcedActionState.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the ApacheLicense, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the Licenseat\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed underthe License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the Licensefor the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity^0.6.11;\n\nimport \"ActionHash.sol\";\nimport \"MainStorage.sol\";\nimport \"MStarkExForcedActionState.sol\";\n/*\n StarkExchange specific actionhashses.\n*/\ncontract StarkExForcedActionState is\n MainStorage,\n ActionHash,\n MStarkExForcedActionState\n{\n\n functionfullWithdrawActionHash(uint256 starkKey, uint256 vaultId)\n internal\n pure\n override\n returns(bytes32)\n {\nreturn getActionHash(\"FULL_WITHDRAWAL\", abi.encode(starkKey, vaultId));\n }\n\n /*\n Implemented in the FullWithdrawal contracts.\n*/\n function clearFullWithdrawalRequest(\n uint256 starkKey,\n uint256 vaultId\n )\n internal\n virtual\noverride\n {\n // Reset escape request.\n delete forcedActionRequests[fullWithdrawActionHash(starkKey, vaultId)];\n }\n\nfunction getFullWithdrawalRequest(uint256 starkKey, uint256 vaultId)\n public\n view\n override\n returns (uint256res)\n {\n // Return request value. Expect zero if the request doesn\u0027t exist or has been serviced, and\n // a non-zero valueotherwise.\n res = forcedActionRequests[fullWithdrawActionHash(starkKey, vaultId)];\n }\n\n function setFullWithdrawalRequest(uint256starkKey, uint256 vaultId)\n internal\n override\n {\n // FullWithdrawal is always at premium cost, henec the `true`.\nsetActionHash(fullWithdrawActionHash(starkKey, vaultId), true);\n }\n}\n"},"SubContractor.sol":{"content":"/*\n Copyright 2019,2020StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this file except in compliancewith the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicablelaw or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OFANY KIND, either express or implied.\n See the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"Identity.sol\";\n\ninterface SubContractor is Identity {\n\nfunction initialize(bytes calldata data)\n external;\n\n function initializerSize()\n external view\n returns(uint256);\n}\n"},"TokenAssetData.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0(the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License isdistributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specificlanguage governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"MainStorage.sol\";\nimport \"MTokenAssetData.sol\";\nimport \"LibConstants.sol\";\n\ncontract TokenAssetData is MainStorage,LibConstants, MTokenAssetData {\n bytes4 internal constant ERC20_SELECTOR = bytes4(keccak256(\"ERC20Token(address)\"));\n bytes4 internalconstant ETH_SELECTOR = bytes4(keccak256(\"ETH()\"));\n bytes4 internal constant ERC721_SELECTOR = bytes4(keccak256(\"ERC721Token(address,uint256)\"));\n bytes4 internal constant MINTABLE_ERC20_SELECTOR =\n bytes4(keccak256(\"MintableERC20Token(address)\"));\n bytes4internal constant MINTABLE_ERC721_SELECTOR =\n bytes4(keccak256(\"MintableERC721Token(address,uint256)\"));\n\n // The selector follows the0x20 bytes assetInfo.length field.\n uint256 internal constant SELECTOR_OFFSET = 0x20;\n uint256 internal constant SELECTOR_SIZE = 4;\nuint256 internal constant TOKEN_CONTRACT_ADDRESS_OFFSET = SELECTOR_OFFSET + SELECTOR_SIZE;\n string internal constant NFT_ASSET_ID_PREFIX =\"NFT:\";\n string internal constant MINTABLE_PREFIX = \"MINTABLE:\";\n\n /*\n Extract the tokenSelector from assetInfo.\n\n Workslike bytes4 tokenSelector = abi.decode(assetInfo, (bytes4))\n but does not revert when assetInfo.length \u003c SELECTOR_OFFSET.\n */\nfunction extractTokenSelector(bytes memory assetInfo) internal pure override\n returns (bytes4 selector) {\n assembly {\nselector := and(\n 0xffffffff00000000000000000000000000000000000000000000000000000000,\n mload(add(assetInfo,SELECTOR_OFFSET))\n )\n }\n }\n\n function getAssetInfo(uint256 assetType) public view override\n returns (bytesmemory assetInfo) {\n // Verify that the registration is set and valid.\n require(registeredAssetType[assetType],\"ASSET_TYPE_NOT_REGISTERED\");\n\n // Retrieve registration.\n assetInfo = assetTypeToAssetInfo[assetType];\n }\n\n functionisEther(uint256 assetType) internal view override returns (bool) {\n return extractTokenSelector(getAssetInfo(assetType)) == ETH_SELECTOR;\n}\n\n function isFungibleAssetType(uint256 assetType) internal view override returns (bool) {\n bytes4 tokenSelector =extractTokenSelector(getAssetInfo(assetType));\n return\n tokenSelector == ETH_SELECTOR ||\n tokenSelector ==ERC20_SELECTOR ||\n tokenSelector == MINTABLE_ERC20_SELECTOR;\n }\n\n function isMintableAssetType(uint256 assetType) internalview override returns (bool) {\n bytes4 tokenSelector = extractTokenSelector(getAssetInfo(assetType));\n return\ntokenSelector == MINTABLE_ERC20_SELECTOR ||\n tokenSelector == MINTABLE_ERC721_SELECTOR;\n }\n\n function extractContractAddress(bytes memory assetInfo)\n internal pure override returns (address _contract) {\n uint256 offset = TOKEN_CONTRACT_ADDRESS_OFFSET;\nuint256 res;\n assembly {\n res := mload(add(assetInfo, offset))\n }\n _contract = address(res);\n }\n\nfunction calculateNftAssetId(uint256 assetType, uint256 tokenId)\n internal\n pure\n override\n returns(uint256assetId) {\n assetId = uint256(keccak256(abi.encodePacked(NFT_ASSET_ID_PREFIX, assetType, tokenId))) \u0026\n MASK_250;\n}\n\n function calculateMintableAssetId(uint256 assetType, bytes memory mintingBlob)\n internal\n pure\n override\nreturns(uint256 assetId) {\n uint256 blobHash = uint256(keccak256(mintingBlob));\n assetId = (uint256(keccak256(abi.encodePacked(MINTABLE_PREFIX ,assetType, blobHash))) \u0026\n MASK_240) | STARKEX_MINTABLE_ASSET_ID_FLAG;\n }\n\n}\n"},"TokenQuantization.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You maynot use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\"BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governingpermissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"MainStorage.sol\";\nimport \"MTokenQuantization.sol\";\n\n\ncontract TokenQuantization is MainStorage, MTokenQuantization {\n\n function fromQuantized(uint256 presumedAssetType, uint256 quantizedAmount)\n internal view override returns (uint256 amount) {\n uint256 quantum =getQuantum(presumedAssetType);\n amount = quantizedAmount * quantum;\n require(amount / quantum == quantizedAmount,\"DEQUANTIZATION_OVERFLOW\");\n }\n\n function getQuantum(uint256 presumedAssetType) public view override returns (uint256 quantum) {\nif (!registeredAssetType[presumedAssetType]) {\n // Default quantization, for NFTs etc.\n quantum = 1;\n } else {\n// Retrieve registration.\n quantum = assetTypeToQuantum[presumedAssetType];\n }\n }\n\n function toQuantized(uint256 presumedAssetType, uint256 amount)\n internal view override returns (uint256 quantizedAmount) {\n uint256 quantum =getQuantum(presumedAssetType);\n require(amount % quantum == 0, \"INVALID_AMOUNT\");\n quantizedAmount = amount / quantum;\n}\n}\n"},"Tokens.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the\"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License isdistributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specificlanguage governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"Common.sol\";\nimport \"LibConstants.sol\";\nimport \"MGovernance.sol\";\nimport \"MTokens.sol\";\nimport \"TokenAssetData.sol\";\nimport \"TokenQuantization.sol\";\nimport \"IERC20.sol\";\nimport \"MainStorage.sol\";\n\n/**\n Registration of a new token (:sol:func:`registerToken`) entails defining a new asset type within\n the system, and associating it with an `assetInfo` array of\n bytes and aquantization factor (`quantum`).\n\n The `assetInfo` is a byte array, with a size depending on the token.\n For ETH, assetInfo is 4 bytes long.For ERC20 tokens, it is 36 bytes long.\n\n For each token type, the following constant 4-byte hash is defined, called the `selector`:\n\n |`ETH_SELECTOR = bytes4(keccak256(\"ETH()\"));`\n | `ERC20_SELECTOR = bytes4(keccak256(\"ERC20Token(address)\"));`\n | `ERC721_SELECTOR = bytes4(keccak256(\"ERC721Token(address,uint256)\"));`\n | `MINTABLE_ERC20_SELECTOR = bytes4(keccak256(\"MintableERC20Token(address)\"));`\n |`MINTABLE_ERC721_SELECTOR = bytes4(keccak256(\"MintableERC721Token(address,uint256)\"));`\n\n For each token type, `assetInfo` is defined asfollows:\n\n\n The `quantum` quantization factor defines the multiplicative transformation from the native token\n denomination as a 256bunsigned integer to a 63b unsigned integer representation as used by the\n Stark exchange. Only amounts in the native representation thatrepresent an integer number of\n quanta are allowed in the system.\n\n The asset type is restricted to be the result of a hash of the `assetInfo`and the\n `quantum` masked to 250 bits (to be less than the prime used) according to the following formula:\n\n | ``uint256 assetType = uint256(keccak256(abi.encodePacked(assetInfo, quantum))) \u0026``\n | ``0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;``\n\n Onceregistered, tokens cannot be removed from the system, as their IDs may be used by off-chain\n accounts.\n\n New tokens may only be registered bya Token Administrator. A Token Administrator may be instantly\n appointed or removed by the contract Governor (see :sol:mod:`MainGovernance`).Typically, the\n Token Administrator\u0027s private key should be kept in a cold wallet.\n*/\nabstract contract Tokens is\n MainStorage,\nLibConstants,\n MGovernance,\n TokenQuantization,\n TokenAssetData,\n MTokens\n{\n event LogTokenRegistered(uint256 assetType, bytesassetInfo);\n event LogTokenAdminAdded(address tokenAdmin);\n event LogTokenAdminRemoved(address tokenAdmin);\n\n using Addresses foraddress;\n using Addresses for address payable;\n\n modifier onlyTokensAdmin() {\n require(tokenAdmins[msg.sender],\"ONLY_TOKENS_ADMIN\");\n _;\n }\n\n function registerTokenAdmin(address newAdmin) external onlyGovernance() {\ntokenAdmins[newAdmin] = true;\n emit LogTokenAdminAdded(newAdmin);\n }\n\n function unregisterTokenAdmin(address oldAdmin) externalonlyGovernance() {\n tokenAdmins[oldAdmin] = false;\n emit LogTokenAdminRemoved(oldAdmin);\n }\n\n function isTokenAdmin(address testedAdmin) external view returns (bool) {\n return tokenAdmins[testedAdmin];\n }\n\n\n function registerToken(uint256assetType, bytes calldata assetInfo) external virtual {\n registerToken(assetType, assetInfo, 1);\n }\n\n /*\n Registers a newasset to the system.\n Once added, it can not be removed and there is a limited number\n of slots available.\n */\n functionregisterToken(\n uint256 assetType,\n bytes memory assetInfo,\n uint256 quantum\n ) public onlyTokensAdmin() virtual {\n// Make sure it is not invalid or already registered.\n require(!registeredAssetType[assetType], \"ASSET_ALREADY_REGISTERED\");\nrequire(assetType \u003c K_MODULUS, \"INVALID_ASSET_TYPE\");\n require(quantum \u003e 0, \"INVALID_QUANTUM\");\n require(quantum\u003c= STARKEX_MAX_QUANTUM, \"INVALID_QUANTUM\");\n require(assetInfo.length \u003e= SELECTOR_SIZE, \"INVALID_ASSET_STRING\");\n\n// Require that the assetType is the hash of the assetInfo and quantum truncated to 250 bits.\n uint256 enforcedId = uint256(keccak256(abi.encodePacked(assetInfo, quantum))) \u0026 MASK_250;\n require(assetType == enforcedId, \"INVALID_ASSET_TYPE\");\n\n // Add token tothe in-storage structures.\n registeredAssetType[assetType] = true;\n assetTypeToAssetInfo[assetType] = assetInfo;\nassetTypeToQuantum[assetType] = quantum;\n\n bytes4 tokenSelector = extractTokenSelector(assetInfo);\n\n // Ensure the selector is ofan asset type we know.\n require(\n tokenSelector == ETH_SELECTOR ||\n tokenSelector == ERC20_SELECTOR ||\ntokenSelector == ERC721_SELECTOR ||\n tokenSelector == MINTABLE_ERC20_SELECTOR ||\n tokenSelector ==MINTABLE_ERC721_SELECTOR,\n \"UNSUPPORTED_TOKEN_TYPE\"\n );\n\n if (tokenSelector == ETH_SELECTOR) {\n //Assset info for ETH assetType is only a selector, i.e. 4 bytes length.\n require(assetInfo.length == 4, \"INVALID_ASSET_STRING\");\n} else {\n // Assset info for other asset types are a selector + uint256 concatanation.\n // We pass the address as auint256 (zero padded),\n // thus its length is 0x04 + 0x20 = 0x24.\n require(assetInfo.length == 0x24,\"INVALID_ASSET_STRING\");\n address tokenAddress = extractContractAddress(assetInfo);\n require(tokenAddress.isContract(),\"BAD_TOKEN_ADDRESS\");\n if (tokenSelector == ERC721_SELECTOR || tokenSelector == MINTABLE_ERC721_SELECTOR) {\n require(quantum == 1, \"INVALID_NFT_QUANTUM\");\n }\n }\n\n // Log the registration of a new token.\n emitLogTokenRegistered(assetType, assetInfo);\n }\n\n /*\n Transfers funds from msg.sender to the exchange.\n */\n function transferIn(uint256 assetType, uint256 quantizedAmount) internal override {\n bytes memory assetInfo = getAssetInfo(assetType);\n uint256 amount= fromQuantized(assetType, quantizedAmount);\n\n bytes4 tokenSelector = extractTokenSelector(assetInfo);\n if (tokenSelector ==ERC20_SELECTOR) {\n address tokenAddress = extractContractAddress(assetInfo);\n IERC20 token = IERC20(tokenAddress);\nuint256 exchangeBalanceBefore = token.balanceOf(address(this));\n bytes memory callData = abi.encodeWithSelector(\ntoken.transferFrom.selector, msg.sender, address(this), amount);\n tokenAddress.safeTokenContractCall(callData);\n uint256exchangeBalanceAfter = token.balanceOf(address(this));\n require(exchangeBalanceAfter \u003e= exchangeBalanceBefore, \"OVERFLOW\");\n// NOLINTNEXTLINE(incorrect-equality): strict equality needed.\n require(\n exchangeBalanceAfter ==exchangeBalanceBefore + amount,\n \"INCORRECT_AMOUNT_TRANSFERRED\");\n } else if (tokenSelector == ETH_SELECTOR) {\nrequire(msg.value == amount, \"INCORRECT_DEPOSIT_AMOUNT\");\n } else {\n revert(\"UNSUPPORTED_TOKEN_TYPE\");\n }\n}\n\n function transferInNft(uint256 assetType, uint256 tokenId) internal override {\n bytes memory assetInfo = getAssetInfo(assetType);\n\n bytes4 tokenSelector = extractTokenSelector(assetInfo);\n require(tokenSelector == ERC721_SELECTOR, \"NOT_ERC721_TOKEN\");\naddress tokenAddress = extractContractAddress(assetInfo);\n tokenAddress.safeTokenContractCall(\n abi.encodeWithSignature(\n \"safeTransferFrom(address,address,uint256)\",\n msg.sender,\n address(this),\ntokenId\n )\n );\n }\n\n /*\n Transfers funds from the exchange to recipient.\n */\n function transferOut(\naddress payable recipient,\n uint256 assetType,\n uint256 quantizedAmount\n ) internal override {\n bytes memoryassetInfo = getAssetInfo(assetType);\n uint256 amount = fromQuantized(assetType, quantizedAmount);\n\n bytes4 tokenSelector =extractTokenSelector(assetInfo);\n if (tokenSelector == ERC20_SELECTOR) {\n address tokenAddress = extractContractAddress(assetInfo);\n IERC20 token = IERC20(tokenAddress);\n uint256 exchangeBalanceBefore = token.balanceOf(address(this));\nbytes memory callData = abi.encodeWithSelector(\n token.transfer.selector, recipient, amount);\n tokenAddress.safeTokenContractCall(callData);\n uint256 exchangeBalanceAfter = token.balanceOf(address(this));\n require(exchangeBalanceAfter \u003c= exchangeBalanceBefore, \"UNDERFLOW\");\n // NOLINTNEXTLINE(incorrect-equality): strict equality needed.\nrequire(\n exchangeBalanceAfter == exchangeBalanceBefore - amount,\n \"INCORRECT_AMOUNT_TRANSFERRED\");\n} else if (tokenSelector == ETH_SELECTOR) {\n recipient.performEthTransfer(amount);\n } else {\n revert(\"UNSUPPORTED_TOKEN_TYPE\");\n }\n }\n\n /*\n Transfers NFT from the exchange to recipient.\n */\n function transferOutNft(address recipient, uint256 assetType, uint256 tokenId)\n internal override {\n bytes memory assetInfo = getAssetInfo(assetType);\nbytes4 tokenSelector = extractTokenSelector(assetInfo);\n require(tokenSelector == ERC721_SELECTOR, \"NOT_ERC721_TOKEN\");\naddress tokenAddress = extractContractAddress(assetInfo);\n tokenAddress.safeTokenContractCall(\n abi.encodeWithSignature(\n\"safeTransferFrom(address,address,uint256)\",\n address(this),\n recipient,\n tokenId\n)\n );\n }\n\n function transferOutMint(\n uint256 assetType,\n uint256 quantizedAmount,\n bytes memorymintingBlob) internal override {\n require(isMintableAssetType(assetType), \"NON_MINTABLE_ASSET_TYPE\");\n uint256 amount =fromQuantized(assetType, quantizedAmount);\n address tokenAddress = extractContractAddress(getAssetInfo(assetType));\n tokenAddress.safeTokenContractCall(\n abi.encodeWithSignature(\n \"mintFor(address,uint256,bytes)\",\n msg.sender,amount, mintingBlob)\n );\n }\n}\n"},"Users.sol":{"content":"/*\n Copyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under theApache License, Version 2.0 (the \"License\").\n You may not use this file except in compliance with the License.\n You may obtain a copy of theLicense at\n\n https://www.starkware.co/open-source-license/\n\n Unless required by applicable law or agreed to in writing,\n softwaredistributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions\n and limitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"MainStorage.sol\";\nimport \"LibConstants.sol\";\nimport \"MGovernance.sol\";\nimport \"MKeyGetters.sol\";\n\n/**\n Users of the Stark Exchange are identified within the exchange by their Stark Key which is a\n public key defined over a Stark-friendly elliptic curve that is different from the standard\n Ethereum elliptic curve. These keys may be generated using the same private keyused by the user\n on Ethereum.\n\n The Stark-friendly elliptic curve used is defined as follows:\n\n .. math:: y^2 = (x^3 + \\alpha \\cdot x +\\beta) \\% p\n\n where:\n\n .. math:: \\alpha = 1\n .. math:: \\beta =3141592653589793238462643383279502884197169399375105820974944592307816406665\n .. math:: p =3618502788666131213697322783095070105623107215331596699973092056135872020481\n\n In order to associate exchange users with Ethereum accountaddresses, an Ethereum address must be\n registered with the Stark Key on the exchange contract before any other user operation can take\n place.\n User registration is performed by calling :sol:func:`registerUser` with the selected Stark Key,\n representing an `x` coordinate on the Stark-friendly elliptic curve, and the `y` coordinate of\n the key on the curve (due to the nature of the curve, only two such possible `y`coordinates\n exist).\n\n The registration is accepted if the following holds:\n\n 1. The key registered is not zero and has not been registeredin the past by the user or anyone else.\n 2. The key provided represents a valid point on the Stark-friendly elliptic curve.\n 3. The linkagebetween the provided Ethereum key and the selected Stark Key is signed by the User Admin (typically the exchange operator).\n\n If the above holds, the Stark Key is registered by the contract, mapping it to the Ethereum key.\n This mapping is later used to ensure that withdrawals fromaccounts mapped to the Stark Keys can\n only be performed by users authenticated with the associated Ethereum public keys (see :sol:mod:`Withdrawals`).\n*/\nabstract contract Users is MainStorage, LibConstants, MGovernance, MKeyGetters {\n event LogUserRegistered(address ethKey,uint256 starkKey, address sender);\n event LogUserAdminAdded(address userAdmin);\n event LogUserAdminRemoved(address userAdmin);\n\nfunction isOnCurve(uint256 starkKey) private view returns (bool) {\n uint256 xCubed = mulmod(mulmod(starkKey, starkKey, K_MODULUS), starkKey, K_MODULUS);\n return isQuadraticResidue(addmod(addmod(xCubed, starkKey, K_MODULUS), K_BETA, K_MODULUS));\n }\n\n functionregisterUserAdmin(address newAdmin) external onlyGovernance() {\n userAdmins[newAdmin] = true;\n emit LogUserAdminAdded(newAdmin);\n}\n\n function unregisterUserAdmin(address oldAdmin) external onlyGovernance() {\n userAdmins[oldAdmin] = false;\n emitLogUserAdminRemoved(oldAdmin);\n }\n\n function isUserAdmin(address testedAdmin) public view returns (bool) {\n returnuserAdmins[testedAdmin];\n }\n\n function registerUser(address ethKey, uint256 starkKey, bytes calldata signature) external {\n //Validate keys and availability.\n require(starkKey != 0, \"INVALID_STARK_KEY\");\n require(starkKey \u003c K_MODULUS,\"INVALID_STARK_KEY\");\n require(ethKey != ZERO_ADDRESS, \"INVALID_ETH_ADDRESS\");\n require(ethKeys[starkKey] == ZERO_ADDRESS,\"STARK_KEY_UNAVAILABLE\");\n require(isOnCurve(starkKey), \"INVALID_STARK_KEY\");\n require(signature.length == 65,\"INVALID_SIGNATURE\");\n\n bytes32 signedData = keccak256(abi.encodePacked(\"UserRegistration:\", ethKey, starkKey));\n\n bytesmemory sig = signature;\n uint8 v = uint8(sig[64]);\n bytes32 r;\n bytes32 s;\n\n assembly {\n r := mload(add(sig, 32))\n s := mload(add(sig, 64))\n }\n\n address signer = ecrecover(signedData, v, r, s);\n require(signer!= ZERO_ADDRESS \u0026\u0026 isUserAdmin(signer), \"INVALID_SIGNATURE\");\n\n // Update state.\n ethKeys[starkKey] = ethKey;\n\n// Log new user.\n emit LogUserRegistered(ethKey, starkKey, msg.sender);\n }\n\n function fieldPow(uint256 base, uint256 exponent)internal view returns (uint256) {\n // NOLINTNEXTLINE: low-level-calls reentrancy-events reentrancy-no-eth.\n (bool success, bytesmemory returndata) = address(5).staticcall(\n abi.encode(0x20, 0x20, 0x20, base, exponent, K_MODULUS)\n );\n require(success, string(returndata));\n return abi.decode(returndata, (uint256));\n }\n\n function isQuadraticResidue(uint256 fieldElement)private view returns (bool) {\n return 1 == fieldPow(fieldElement, ((K_MODULUS - 1) / 2));\n }\n}\n"},"Withdrawals.sol":{"content":"/*\nCopyright 2019,2020 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use this fileexcept in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.starkware.co/open-source-license/\n\n Unlessrequired by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUTWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions\n andlimitations under the License.\n*/\n// SPDX-License-Identifier: Apache-2.0.\npragma solidity ^0.6.11;\n\nimport \"MAcceptModifications.sol\";\nimport \"MTokenQuantization.sol\";\nimport \"MTokenAssetData.sol\";\nimport \"MFreezable.sol\";\nimport \"MKeyGetters.sol\";\nimport \"MTokens.sol\";\nimport \"MainStorage.sol\";\n\n/**\n For a user to perform a withdrawal operation from the Stark Exchange during normal operation\n twocalls are required:\n\n 1. A call to an offchain exchange API, requesting a withdrawal from a user account (vault).\n 2. A call to the on-chain:sol:func:`withdraw` function to perform the actual withdrawal of funds transferring them to the users Eth or ERC20 account (depending on the tokentype).\n\n For simplicity, hereafter it is assumed that all tokens are ERC20 tokens but the text below\n applies to Eth in the same manner.\n\nIn the first call mentioned above, anyone can call the API to request the withdrawal of an\n amount from a given vault. Following the request, theexchange may include the withdrawal in a\n STARK proof. The submission of a proof then results in the addition of the amount(s) withdrawn to\n anon-chain pending withdrawals account under the stark key of the vault owner and the appropriate\n asset ID. At the same time, this also impliesthat this amount is deducted from the off-chain\n vault.\n\n Once the amount to be withdrawn has been transfered to the on-chain pendingwithdrawals account,\n the user may perform the second call mentioned above to complete the transfer of funds from the\n Stark Exchange contractto the appropriate ERC20 account. Only a user holding the Eth key\n corresponding to the Stark Key of a pending withdrawals account may performthis operation.\n\n It is possible that for multiple withdrawal calls to the API, a single withdrawal call to the\n contract may retrieve allfunds, as long as they are all for the same asset ID.\n\n The result of the operation, assuming all requirements are met, is that an amount ofERC20 tokens\n in the pending withdrawal account times the quantization factor is transferred to the ERC20\n account of the user.\n\n Awithdrawal request cannot be cancelled. Once funds reach the pending withdrawals account\n on-chain, they cannot be moved back into an off-chainvault before completion of the withdrawal\n to the ERC20 account of the user.\n\n In the event that the exchange reaches a frozen state the usermay perform a withdrawal operation\n via an alternative flow, known as the \"Escape\" flow. In this flow, the API call above is replaced\n withan :sol:func:`escape` call to the on-chain contract (see :sol:mod:`Escapes`) proving the\n ownership of off-chain funds. If such proof is accepted, the user may proceed as above with\n the :sol:func:`withdraw` call to the contract to complete the operation.\n*/\nabstract contract Withdrawalsis\n MainStorage,\n MAcceptModifications,\n MTokenQuantization,\n MTokenAssetData,\n MFreezable,\n MKeyGetters,\n MTokens {\nevent LogWithdrawalPerformed(\n uint256 starkKey,\n uint256 assetType,\n uint256 nonQuantizedAmount,\n uint256quantizedAmount,\n address recipient\n );\n\n event LogNftWithdrawalPerformed(\n uint256 starkKey,\n uint256 assetType,\n uint256 tokenId,\n uint256 assetId,\n address recipient\n );\n\n event LogMintWithdrawalPerformed(\n uint256starkKey,\n uint256 tokenId,\n uint256 nonQuantizedAmount,\n uint256 quantizedAmount,\n uint256 assetId\n );\n\nfunction getWithdrawalBalance(\n uint256 starkKey,\n uint256 assetId\n )\n external\n view\n returns (uint256balance)\n {\n uint256 presumedAssetType = assetId;\n balance = fromQuantized(presumedAssetType,pendingWithdrawals[starkKey][assetId]);\n }\n\n /*\n Allows a user to withdraw accepted funds to a recipient\u0027s account.\n Thisfunction can be called normally while frozen.\n */\n function withdrawTo(\n uint256 starkKey,\n uint256 assetType,\naddress payable recipient)\n external\n isSenderStarkKey(starkKey)\n {\n internalWithdrawTo(starkKey, assetType, recipient);\n }\n\n /*\n Underlying implementation of withdraw \u0026 withdrawTo.\n Checking that the address of the recipient preservesself-custody is the responsibility of the\n calling function. (i.e. that the recipient is either the owner of the assets or that the owner\nhas authorized the withdrawal).\n */\n function internalWithdrawTo(\n uint256 starkKey,\n uint256 assetType,\naddress payable recipient) internal\n {\n require(!isMintableAssetType(assetType), \"MINTABLE_ASSET_TYPE\");\n require(isFungibleAssetType(assetType), \"NON_FUNGIBLE_ASSET_TYPE\");\n uint256 assetId = assetType;\n // Fetch and clear quantized amount.\n uint256 quantizedAmount = pendingWithdrawals[starkKey][assetId];\n pendingWithdrawals[starkKey][assetId] = 0;\n\n //Transfer funds.\n transferOut(recipient, assetType, quantizedAmount);\n emit LogWithdrawalPerformed(\n starkKey,\nassetType,\n fromQuantized(assetType, quantizedAmount),\n quantizedAmount,\n recipient\n );\n }\n\n/*\n Moves funds from the pending withdrawal account to the owner address.\n Note: this function can be called by anyone.\n Canbe called normally while frozen.\n */\n function withdraw(uint256 starkKey, uint256 assetType)\n external\n {\ninternalWithdrawTo(starkKey, assetType, address(uint160(getEthKey(starkKey))));\n }\n\n /*\n Allows a user to withdraw an accepted NFTto a recipient\u0027s account.\n This function can be called normally while frozen.\n */\n function withdrawNftTo(\n uint256starkKey,\n uint256 assetType,\n uint256 tokenId,\n address recipient\n )\n public\n isSenderStarkKey(starkKey)\n // No notFrozen modifier: This function can always be used, even when frozen.\n {\n // Calculate assetId.\nuint256 assetId = calculateNftAssetId(assetType, tokenId);\n require(!isMintableAssetType(assetType), \"MINTABLE_ASSET_TYPE\");\nrequire(!isFungibleAssetType(assetType), \"FUNGIBLE_ASSET_TYPE\");\n if (pendingWithdrawals[starkKey][assetId] \u003e 0) {\nrequire(pendingWithdrawals[starkKey][assetId] == 1, \"ILLEGAL_NFT_BALANCE\");\n pendingWithdrawals[starkKey][assetId] = 0;\n\n// Transfer funds.\n transferOutNft(recipient, assetType, tokenId);\n emit LogNftWithdrawalPerformed(starkKey, assetType,tokenId, assetId, recipient);\n }\n }\n\n /*\n Allows a user to withdraw an accepted NFT to its own account.\n This functioncan be called normally while frozen.\n */\n function withdrawNft(\n uint256 starkKey,\n uint256 assetType,\n uint256tokenId\n )\n external\n // No notFrozen modifier: This function can always be used, even when frozen.\n {\n withdrawNftTo(starkKey, assetType, tokenId, msg.sender);\n }\n\n function withdrawAndMint(\n uint256 starkKey,\n uint256 assetType,\nbytes calldata mintingBlob\n ) external isSenderStarkKey(starkKey) {\n require(registeredAssetType[assetType], \"INVALID_ASSET_TYPE\");\n require(isMintableAssetType(assetType), \"NON_MINTABLE_ASSET_TYPE\");\n uint256 assetId = calculateMintableAssetId(assetType,mintingBlob);\n if (pendingWithdrawals[starkKey][assetId] \u003e 0) {\n uint256 quantizedAmount =pendingWithdrawals[starkKey][assetId];\n pendingWithdrawals[starkKey][assetId] = 0;\n // Transfer funds.\ntransferOutMint(assetType, quantizedAmount, mintingBlob);\n emit LogMintWithdrawalPerformed(\n starkKey, assetType,fromQuantized(assetType, quantizedAmount), quantizedAmount,\n assetId);\n }\n }\n}\n"}}